Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/altera/atse/if_atse_fdt.c
Show First 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | |||||
#include <net/ethernet.h> | #include <net/ethernet.h> | ||||
#include <net/if.h> | #include <net/if.h> | ||||
#include <net/if_media.h> | #include <net/if_media.h> | ||||
#include <net/if_var.h> | #include <net/if_var.h> | ||||
#include <dev/mii/mii.h> | #include <dev/mii/mii.h> | ||||
#include <dev/mii/miivar.h> | #include <dev/mii/miivar.h> | ||||
#include <dev/fdt/fdt_common.h> | #include <dev/fdt/fdt_common.h> | ||||
#include <dev/ofw/openfirm.h> | #include <dev/ofw/openfirm.h> | ||||
#include <dev/ofw/ofw_bus.h> | #include <dev/ofw/ofw_bus.h> | ||||
#include <dev/ofw/ofw_bus_subr.h> | #include <dev/ofw/ofw_bus_subr.h> | ||||
#include <dev/altera/atse/if_atsereg.h> | #include <dev/altera/atse/if_atsereg.h> | ||||
/* "device miibus" required. See GENERIC if you get errors here. */ | /* "device miibus" required. See GENERIC if you get errors here. */ | ||||
#include "miibus_if.h" | #include "miibus_if.h" | ||||
static int | static int | ||||
atse_probe_fdt(device_t dev) | atse_probe_fdt(device_t dev) | ||||
{ | { | ||||
if (!ofw_bus_status_okay(dev)) | if (!ofw_bus_status_okay(dev)) | ||||
return (ENXIO); | return (ENXIO); | ||||
if (ofw_bus_is_compatible(dev, "altera,atse")) { | if (!ofw_bus_is_compatible(dev, "altera,atse")) { | ||||
return (ENXIO); | |||||
} | |||||
device_set_desc(dev, "Altera Triple-Speed Ethernet MegaCore"); | device_set_desc(dev, "Altera Triple-Speed Ethernet MegaCore"); | ||||
return (BUS_PROBE_DEFAULT); | return (BUS_PROBE_DEFAULT); | ||||
} | } | ||||
return (ENXIO); | |||||
} | |||||
static int | static int | ||||
atse_attach_fdt(device_t dev) | atse_attach_fdt(device_t dev) | ||||
{ | { | ||||
struct atse_softc *sc; | struct atse_softc *sc; | ||||
int error; | int error; | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
sc->atse_dev = dev; | sc->atse_dev = dev; | ||||
sc->atse_unit = device_get_unit(dev); | sc->atse_unit = device_get_unit(dev); | ||||
/* | /* | ||||
* FDT has the list of our resources. Given we are using multiple | * FDT has the list of our resources. Given we are using multiple | ||||
* memory regions and possibly multiple interrupts, we need to attach | * memory regions and possibly multiple interrupts, we need to attach | ||||
* them in the order specified in .dts: | * them in the order specified in .dts: | ||||
* MAC, RX and RXC FIFO, TX and TXC FIFO; RX INTR, TX INTR. | * MAC, RX and RXC FIFO, TX and TXC FIFO; RX INTR, TX INTR. | ||||
*/ | */ | ||||
/* MAC: Avalon-MM, atse management register region. */ | /* MAC: Avalon-MM, atse management register region. */ | ||||
sc->atse_mem_rid = 0; | sc->atse_mem_rid = 0; | ||||
sc->atse_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, | sc->atse_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, | ||||
&sc->atse_mem_rid, RF_ACTIVE); | &sc->atse_mem_rid, RF_ACTIVE); | ||||
if (sc->atse_mem_res == NULL) { | if (sc->atse_mem_res == NULL) { | ||||
device_printf(dev, "failed to map memory for ctrl region\n"); | device_printf(dev, "failed to map memory for ctrl region\n"); | ||||
error = ENXIO; | /* Cleanup. */ | ||||
goto err; | atse_detach_resources(dev); | ||||
return (ENXIO); | |||||
} | } | ||||
if (bootverbose) | if (bootverbose) | ||||
device_printf(sc->atse_dev, "MAC ctrl region at mem %p-%p\n", | device_printf(sc->atse_dev, "MAC ctrl region at mem %p-%p\n", | ||||
(void *)rman_get_start(sc->atse_mem_res), | (void *)rman_get_start(sc->atse_mem_res), | ||||
(void *)(rman_get_start(sc->atse_mem_res) + | (void *)(rman_get_start(sc->atse_mem_res) + | ||||
rman_get_size(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); | error = atse_attach(dev); | ||||
if (error) | if (error) { | ||||
goto err; | |||||
return (0); | |||||
err: | |||||
/* Cleanup. */ | /* Cleanup. */ | ||||
atse_detach_resources(dev); | atse_detach_resources(dev); | ||||
return (error); | return (error); | ||||
} | } | ||||
return (0); | |||||
} | |||||
static device_method_t atse_methods_fdt[] = { | static device_method_t atse_methods_fdt[] = { | ||||
/* Device interface */ | /* Device interface */ | ||||
DEVMETHOD(device_probe, atse_probe_fdt), | DEVMETHOD(device_probe, atse_probe_fdt), | ||||
DEVMETHOD(device_attach, atse_attach_fdt), | DEVMETHOD(device_attach, atse_attach_fdt), | ||||
DEVMETHOD(device_detach, atse_detach_dev), | DEVMETHOD(device_detach, atse_detach_dev), | ||||
/* MII interface */ | /* MII interface */ | ||||
DEVMETHOD(miibus_readreg, atse_miibus_readreg), | DEVMETHOD(miibus_readreg, atse_miibus_readreg), | ||||
DEVMETHOD(miibus_writereg, atse_miibus_writereg), | DEVMETHOD(miibus_writereg, atse_miibus_writereg), | ||||
DEVMETHOD(miibus_statchg, atse_miibus_statchg), | DEVMETHOD(miibus_statchg, atse_miibus_statchg), | ||||
DEVMETHOD_END | DEVMETHOD_END | ||||
}; | }; | ||||
static driver_t atse_driver_fdt = { | static driver_t atse_driver_fdt = { | ||||
"atse", | "atse", | ||||
atse_methods_fdt, | atse_methods_fdt, | ||||
sizeof(struct atse_softc) | sizeof(struct atse_softc) | ||||
}; | }; | ||||
DRIVER_MODULE(atse, simplebus, atse_driver_fdt, atse_devclass, 0, 0); | DRIVER_MODULE(atse, simplebus, atse_driver_fdt, atse_devclass, 0, 0); | ||||
DRIVER_MODULE(miibus, atse, miibus_driver, miibus_devclass, 0, 0); | DRIVER_MODULE(miibus, atse, miibus_driver, miibus_devclass, 0, 0); | ||||
/* end */ |