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:
parent
36f5f2fb30
commit
b8f915ab24
File diff suppressed because it is too large
Load Diff
@ -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,13 +69,15 @@ 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);
|
||||
}
|
||||
|
||||
device_set_desc(dev, "Altera Triple-Speed Ethernet MegaCore");
|
||||
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
static int
|
||||
atse_attach_fdt(device_t dev)
|
||||
{
|
||||
@ -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,93 +112,17 @@ 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;
|
||||
|
||||
return (0);
|
||||
|
||||
err:
|
||||
if (error) {
|
||||
/* Cleanup. */
|
||||
atse_detach_resources(dev);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static device_method_t atse_methods_fdt[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, atse_probe_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 */
|
||||
|
@ -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,73 +126,16 @@ 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;
|
||||
|
||||
return (0);
|
||||
|
||||
err:
|
||||
if (error) {
|
||||
/* Cleanup. */
|
||||
atse_detach_resources(dev);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static device_method_t atse_methods_nexus[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, atse_probe_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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 {
|
||||
|
@ -41,6 +41,13 @@ device uart
|
||||
device miibus
|
||||
options DEVICE_POLLING
|
||||
|
||||
#
|
||||
# DMA support
|
||||
#
|
||||
device xdma
|
||||
device altera_softdma
|
||||
device altera_msgdma
|
||||
|
||||
#
|
||||
# USB support
|
||||
#
|
||||
|
Loading…
Reference in New Issue
Block a user