Convert atse(4) driver for Altera Triple-Speed Ethernet MegaCore to use

xdma(4) interface.

This allows us to switch between Altera mSGDMA or SoftDMA engines used by
atse(4) device.

This also makes atse(4) driver become 25% smaller.

Sponsored by:	DARPA, AFRL
Differential Revision:	https://reviews.freebsd.org/D9618
This commit is contained in:
Ruslan Bukin 2018-04-13 15:59:24 +00:00
parent 36f5f2fb30
commit b8f915ab24
6 changed files with 409 additions and 1090 deletions

File diff suppressed because it is too large Load Diff

View File

@ -52,7 +52,6 @@ __FBSDID("$FreeBSD$");
#include <dev/mii/mii.h>
#include <dev/mii/miivar.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
@ -70,11 +69,13 @@ atse_probe_fdt(device_t dev)
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (ofw_bus_is_compatible(dev, "altera,atse")) {
device_set_desc(dev, "Altera Triple-Speed Ethernet MegaCore");
return (BUS_PROBE_DEFAULT);
if (!ofw_bus_is_compatible(dev, "altera,atse")) {
return (ENXIO);
}
return (ENXIO);
device_set_desc(dev, "Altera Triple-Speed Ethernet MegaCore");
return (BUS_PROBE_DEFAULT);
}
static int
@ -100,8 +101,10 @@ atse_attach_fdt(device_t dev)
&sc->atse_mem_rid, RF_ACTIVE);
if (sc->atse_mem_res == NULL) {
device_printf(dev, "failed to map memory for ctrl region\n");
error = ENXIO;
goto err;
/* Cleanup. */
atse_detach_resources(dev);
return (ENXIO);
}
if (bootverbose)
device_printf(sc->atse_dev, "MAC ctrl region at mem %p-%p\n",
@ -109,91 +112,15 @@ atse_attach_fdt(device_t dev)
(void *)(rman_get_start(sc->atse_mem_res) +
rman_get_size(sc->atse_mem_res)));
/*
* RX and RXC FIFO memory regions.
* 0x00: 2 * 32bit FIFO data,
* 0x20: 8 * 32bit FIFO ctrl, Avalon-ST Sink to Avalon-MM R-Slave.
*/
sc->atse_rx_mem_rid = 1;
sc->atse_rx_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&sc->atse_rx_mem_rid, RF_ACTIVE);
if (sc->atse_rx_mem_res == NULL) {
device_printf(dev, "failed to map memory for RX FIFO\n");
error = ENXIO;
goto err;
}
if (bootverbose)
device_printf(sc->atse_dev, "RX FIFO at mem %p-%p\n",
(void *)rman_get_start(sc->atse_rx_mem_res),
(void *)(rman_get_start(sc->atse_rx_mem_res) +
rman_get_size(sc->atse_rx_mem_res)));
sc->atse_rxc_mem_rid = 2;
sc->atse_rxc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&sc->atse_rxc_mem_rid, RF_ACTIVE);
if (sc->atse_rxc_mem_res == NULL) {
device_printf(dev, "failed to map memory for RXC FIFO\n");
error = ENXIO;
goto err;
}
if (bootverbose)
device_printf(sc->atse_dev, "RXC FIFO at mem %p-%p\n",
(void *)rman_get_start(sc->atse_rxc_mem_res),
(void *)(rman_get_start(sc->atse_rxc_mem_res) +
rman_get_size(sc->atse_rxc_mem_res)));
/*
* TX and TXC FIFO memory regions.
* 0x00: 2 * 32bit FIFO data,
* 0x20: 8 * 32bit FIFO ctrl, Avalon-MM W-Slave to Avalon-ST Source.
*/
sc->atse_tx_mem_rid = 3;
sc->atse_tx_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&sc->atse_tx_mem_rid, RF_ACTIVE);
if (sc->atse_tx_mem_res == NULL) {
device_printf(dev, "failed to map memory for TX FIFO\n");
error = ENXIO;
goto err;
}
if (bootverbose)
device_printf(sc->atse_dev, "TX FIFO at mem %p-%p\n",
(void *)rman_get_start(sc->atse_tx_mem_res),
(void *)(rman_get_start(sc->atse_tx_mem_res) +
rman_get_size(sc->atse_tx_mem_res)));
sc->atse_txc_mem_rid = 4;
sc->atse_txc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&sc->atse_txc_mem_rid, RF_ACTIVE);
if (sc->atse_txc_mem_res == NULL) {
device_printf(dev, "failed to map memory for TXC FIFO\n");
error = ENXIO;
goto err;
}
if (bootverbose)
device_printf(sc->atse_dev, "TXC FIFO at mem %p-%p\n",
(void *)rman_get_start(sc->atse_txc_mem_res),
(void *)(rman_get_start(sc->atse_txc_mem_res) +
rman_get_size(sc->atse_txc_mem_res)));
/* (Optional) RX and TX IRQ. */
sc->atse_rx_irq_rid = 0;
sc->atse_rx_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
&sc->atse_rx_irq_rid, RF_ACTIVE | RF_SHAREABLE);
sc->atse_tx_irq_rid = 1;
sc->atse_tx_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
&sc->atse_tx_irq_rid, RF_ACTIVE | RF_SHAREABLE);
error = atse_attach(dev);
if (error)
goto err;
if (error) {
/* Cleanup. */
atse_detach_resources(dev);
return (error);
}
return (0);
err:
/* Cleanup. */
atse_detach_resources(dev);
return (error);
}
static device_method_t atse_methods_fdt[] = {
@ -218,5 +145,3 @@ static driver_t atse_driver_fdt = {
DRIVER_MODULE(atse, simplebus, atse_driver_fdt, atse_devclass, 0, 0);
DRIVER_MODULE(miibus, atse, miibus_driver, miibus_devclass, 0, 0);
/* end */

View File

@ -66,7 +66,7 @@ MODULE_DEPEND(atse, miibus, 1, 1, 1);
* Device routines for interacting with nexus (probe, attach, detach) & helpers.
* XXX We should add suspend/resume later.
*/
static int
static int __unused
atse_resource_int(device_t dev, const char *resname, int *v)
{
int error;
@ -82,7 +82,7 @@ atse_resource_int(device_t dev, const char *resname, int *v)
return (0);
}
static int
static int __unused
atse_resource_long(device_t dev, const char *resname, long *v)
{
int error;
@ -101,37 +101,9 @@ atse_resource_long(device_t dev, const char *resname, long *v)
static int
atse_probe_nexus(device_t dev)
{
struct resource *res;
long l;
int error, rid;
/*
* It is almost impossible to properly probe this device. We must
* rely on hints being set correctly. So try to get hints and
* one memory mapping. Must cleanup and do again in attach but
* should not probe successfully if not able to attach later.
*/
error = atse_resource_int(dev, "rx_irq", &rid);
error += atse_resource_long(dev, "rx_maddr", &l);
error += atse_resource_long(dev, "rx_msize", &l);
error += atse_resource_long(dev, "rxc_maddr", &l);
error += atse_resource_long(dev, "rxc_msize", &l);
error += atse_resource_int(dev, "tx_irq", &rid);
error += atse_resource_long(dev, "tx_maddr", &l);
error += atse_resource_long(dev, "tx_msize", &l);
error += atse_resource_long(dev, "txc_maddr", &l);
error += atse_resource_long(dev, "txc_msize", &l);
if (error != 0)
return (ENXIO);
rid = 0;
res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
if (res == NULL)
return (ENXIO);
bus_release_resource(dev, SYS_RES_MEMORY, rid, res);
/* Success. */
device_set_desc(dev, "Altera Triple-Speed Ethernet MegaCore");
return (BUS_PROBE_NOWILDCARD);
}
@ -145,20 +117,6 @@ atse_attach_nexus(device_t dev)
sc->atse_dev = dev;
sc->atse_unit = device_get_unit(dev);
/* Get RX and TX IRQ and FIFO information from hints. */
error = atse_resource_int(dev, "rx_irq", &sc->atse_rx_irq);
error += atse_resource_long(dev, "rx_maddr", &sc->atse_rx_maddr);
error += atse_resource_long(dev, "rx_msize", &sc->atse_rx_msize);
error += atse_resource_long(dev, "rxc_maddr", &sc->atse_rxc_maddr);
error += atse_resource_long(dev, "rxc_msize", &sc->atse_rxc_msize);
error += atse_resource_int(dev, "tx_irq", &sc->atse_tx_irq);
error += atse_resource_long(dev, "tx_maddr", &sc->atse_tx_maddr);
error += atse_resource_long(dev, "tx_msize", &sc->atse_tx_msize);
error += atse_resource_long(dev, "txc_maddr", &sc->atse_txc_maddr);
error += atse_resource_long(dev, "txc_msize", &sc->atse_txc_msize);
if (error != 0)
return (error);
/* Avalon-MM, atse management register region. */
sc->atse_mem_rid = 0;
sc->atse_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
@ -168,71 +126,14 @@ atse_attach_nexus(device_t dev)
return (ENXIO);
}
/*
* (Optional) RX IRQ and memory mapped regions.
* 0x00: 2 * 32bit FIFO data,
* 0x20: 8 * 32bit FIFO ctrl, Avalon-ST Sink to Avalon-MM R-Slave.
*/
sc->atse_rx_irq_rid = 0;
sc->atse_rx_irq_res = bus_alloc_resource(dev, SYS_RES_IRQ,
&sc->atse_rx_irq_rid, sc->atse_rx_irq, sc->atse_rx_irq, 1,
RF_ACTIVE | RF_SHAREABLE);
sc->atse_rx_mem_rid = 0;
sc->atse_rx_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
&sc->atse_rx_mem_rid, sc->atse_rx_maddr, sc->atse_rx_maddr +
sc->atse_rx_msize, sc->atse_rx_msize, RF_ACTIVE);
if (sc->atse_rx_mem_res == NULL) {
device_printf(dev, "failed to map memory for RX\n");
goto err;
}
sc->atse_rxc_mem_rid = 0;
sc->atse_rxc_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
&sc->atse_rxc_mem_rid, sc->atse_rxc_maddr, sc->atse_rxc_maddr +
sc->atse_rxc_msize, sc->atse_rxc_msize, RF_ACTIVE);
if (sc->atse_rxc_mem_res == NULL) {
device_printf(dev, "failed to map memory for RX control\n");
goto err;
}
/*
* (Optional) TX IRQ and memory mapped regions.
* 0x00: 2 * 32bit FIFO data,
* 0x20: 8 * 32bit FIFO ctrl, Avalon-MM W-Slave to Avalon-ST Source.
*/
sc->atse_tx_irq_rid = 0;
sc->atse_tx_irq_res = bus_alloc_resource(dev, SYS_RES_IRQ,
&sc->atse_tx_irq_rid, sc->atse_tx_irq, sc->atse_tx_irq, 1,
RF_ACTIVE | RF_SHAREABLE);
sc->atse_tx_mem_rid = 0;
sc->atse_tx_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
&sc->atse_tx_mem_rid, sc->atse_tx_maddr, sc->atse_tx_maddr +
sc->atse_tx_msize, sc->atse_tx_msize, RF_ACTIVE);
if (sc->atse_tx_mem_res == NULL) {
device_printf(dev, "failed to map memory for TX\n");
goto err;
}
sc->atse_txc_mem_rid = 0;
sc->atse_txc_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
&sc->atse_txc_mem_rid, sc->atse_txc_maddr, sc->atse_txc_maddr +
sc->atse_txc_msize, sc->atse_txc_msize, RF_ACTIVE);
if (sc->atse_txc_mem_res == NULL) {
device_printf(dev, "failed to map memory for TX control\n");
goto err;
}
error = atse_attach(dev);
if (error)
goto err;
if (error) {
/* Cleanup. */
atse_detach_resources(dev);
return (error);
}
return (0);
err:
/* Cleanup. */
atse_detach_resources(dev);
return (error);
}
static device_method_t atse_methods_nexus[] = {
@ -257,5 +158,3 @@ static driver_t atse_driver_nexus = {
DRIVER_MODULE(atse, nexus, atse_driver_nexus, atse_devclass, 0, 0);
DRIVER_MODULE(miibus, atse, miibus_driver, miibus_devclass, 0, 0);
/* end */

View File

@ -35,6 +35,8 @@
#ifndef _DEV_IF_ATSEREG_H
#define _DEV_IF_ATSEREG_H
#include <dev/xdma/xdma.h>
#define ATSE_VENDOR 0x6af7
#define ATSE_DEVICE 0x00bd
@ -407,40 +409,13 @@ static char *fifo_memory_block[] = {
struct atse_softc {
struct ifnet *atse_ifp;
struct mbuf *atse_rx_m;
struct mbuf *atse_tx_m;
uint8_t *atse_tx_buf;
struct resource *atse_mem_res;
struct resource *atse_rx_irq_res;
struct resource *atse_rx_mem_res;
struct resource *atse_rxc_mem_res;
struct resource *atse_tx_irq_res;
struct resource *atse_tx_mem_res;
struct resource *atse_txc_mem_res;
device_t atse_miibus;
device_t atse_dev;
int atse_unit;
int atse_mem_rid;
int atse_rx_irq_rid;
int atse_rx_mem_rid;
int atse_rxc_mem_rid;
int atse_tx_irq_rid;
int atse_tx_mem_rid;
int atse_txc_mem_rid;
int atse_phy_addr;
int atse_if_flags;
int atse_rx_irq;
int atse_tx_irq;
u_long atse_rx_maddr;
u_long atse_rx_msize;
u_long atse_tx_maddr;
u_long atse_tx_msize;
u_long atse_rxc_maddr;
u_long atse_rxc_msize;
u_long atse_txc_maddr;
u_long atse_txc_msize;
void *atse_rx_intrhand;
void *atse_tx_intrhand;
bus_addr_t atse_bmcr0;
bus_addr_t atse_bmcr1;
uint32_t atse_flags;
@ -454,10 +429,6 @@ struct atse_softc {
#define ATSE_ETH_ADDR_SUPP3 0x08
#define ATSE_ETH_ADDR_SUPP4 0x10
#define ATSE_ETH_ADDR_ALL 0x1f
uint16_t atse_watchdog_timer;
uint16_t atse_tx_m_offset;
uint16_t atse_tx_buf_len;
uint16_t atse_rx_buf_len;
int16_t atse_rx_cycles; /* POLLING */
#define RX_CYCLES_IN_INTR 5
uint32_t atse_rx_err[6];
@ -470,6 +441,20 @@ struct atse_softc {
#define ATSE_RX_ERR_MAX 6
struct callout atse_tick;
struct mtx atse_mtx;
device_t dev;
/* xDMA */
xdma_controller_t *xdma_tx;
xdma_channel_t *xchan_tx;
void *ih_tx;
int txcount;
xdma_controller_t *xdma_rx;
xdma_channel_t *xchan_rx;
void *ih_rx;
struct buf_ring *br;
struct mtx br_mtx;
};
@ -484,5 +469,3 @@ void atse_miibus_statchg(device_t);
extern devclass_t atse_devclass;
#endif /* _DEV_IF_ATSEREG_H */
/* end */

View File

@ -265,30 +265,31 @@
#dma-cells = <3>;
};
ethernet@80007000 {
compatible = "altera,atse";
reg = <0x80007000 0x400>; /* mac */
dmas = <&msgdma0 0 0 0xffffffff>,
<&msgdma1 1 1 0xffffffff>;
dma-names = "tx", "rx";
status = "disabled";
};
ethernet@7f007000 {
compatible = "altera,atse";
// MAC, RX+RXC, TX+TXC.
reg = <0x7f007000 0x400
0x7f007500 0x8
0x7f007520 0x20
0x7f007400 0x8
0x7f007420 0x20>;
// RX, TX
interrupts = <1 2>;
interrupt-parent = <&beripic0>;
reg = <0x7f007000 0x400>; /* mac */
dmas = <&softdma0 0 0 0xffffffff>,
<&softdma1 1 1 0xffffffff>;
dma-names = "tx", "rx";
status = "okay";
};
ethernet@7f005000 {
compatible = "altera,atse";
// MAC, RX+RXC, TX+TXC.
reg = <0x7f005000 0x400
0x7f005500 0x8
0x7f005520 0x20
0x7f005400 0x8
0x7f005420 0x20>;
// RX, TX
interrupts = <11 12>;
interrupt-parent = <&beripic0>;
reg = <0x7f005000 0x400>;
dmas = <&softdma2 0 0 0xffffffff>,
<&softdma3 1 1 0xffffffff>;
dma-names = "tx", "rx";
status = "disabled";
};
touchscreen@70400000 {

View File

@ -41,6 +41,13 @@ device uart
device miibus
options DEVICE_POLLING
#
# DMA support
#
device xdma
device altera_softdma
device altera_msgdma
#
# USB support
#