Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/dc/if_dc.c
Show First 20 Lines • Show All 3,237 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
#ifdef DEVICE_POLLING | #ifdef DEVICE_POLLING | ||||
static poll_handler_t dc_poll; | static poll_handler_t dc_poll; | ||||
static int | static int | ||||
dc_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) | dc_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) | ||||
{ | { | ||||
struct epoch_tracker et; | |||||
struct dc_softc *sc = ifp->if_softc; | struct dc_softc *sc = ifp->if_softc; | ||||
int rx_npkts = 0; | int rx_npkts = 0; | ||||
DC_LOCK(sc); | DC_LOCK(sc); | ||||
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { | if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { | ||||
DC_UNLOCK(sc); | DC_UNLOCK(sc); | ||||
return (rx_npkts); | return (rx_npkts); | ||||
} | } | ||||
sc->rxcycles = count; | sc->rxcycles = count; | ||||
NET_EPOCH_ENTER(et); | |||||
rx_npkts = dc_rxeof(sc); | rx_npkts = dc_rxeof(sc); | ||||
NET_EPOCH_EXIT(et); | |||||
dc_txeof(sc); | dc_txeof(sc); | ||||
if (!IFQ_IS_EMPTY(&ifp->if_snd) && | if (!IFQ_IS_EMPTY(&ifp->if_snd) && | ||||
!(ifp->if_drv_flags & IFF_DRV_OACTIVE)) | !(ifp->if_drv_flags & IFF_DRV_OACTIVE)) | ||||
dc_start_locked(ifp); | dc_start_locked(ifp); | ||||
if (cmd == POLL_AND_CHECK_STATUS) { /* also check status register */ | if (cmd == POLL_AND_CHECK_STATUS) { /* also check status register */ | ||||
uint32_t status; | uint32_t status; | ||||
status = CSR_READ_4(sc, DC_ISR); | status = CSR_READ_4(sc, DC_ISR); | ||||
status &= (DC_ISR_RX_WATDOGTIMEO | DC_ISR_RX_NOBUF | | status &= (DC_ISR_RX_WATDOGTIMEO | DC_ISR_RX_NOBUF | | ||||
DC_ISR_TX_NOBUF | DC_ISR_TX_IDLE | DC_ISR_TX_UNDERRUN | | DC_ISR_TX_NOBUF | DC_ISR_TX_IDLE | DC_ISR_TX_UNDERRUN | | ||||
DC_ISR_BUS_ERR); | DC_ISR_BUS_ERR); | ||||
if (!status) { | if (!status) { | ||||
DC_UNLOCK(sc); | DC_UNLOCK(sc); | ||||
return (rx_npkts); | return (rx_npkts); | ||||
} | } | ||||
/* ack what we have */ | /* ack what we have */ | ||||
CSR_WRITE_4(sc, DC_ISR, status); | CSR_WRITE_4(sc, DC_ISR, status); | ||||
if (status & (DC_ISR_RX_WATDOGTIMEO | DC_ISR_RX_NOBUF)) { | if (status & (DC_ISR_RX_WATDOGTIMEO | DC_ISR_RX_NOBUF)) { | ||||
uint32_t r = CSR_READ_4(sc, DC_FRAMESDISCARDED); | uint32_t r = CSR_READ_4(sc, DC_FRAMESDISCARDED); | ||||
if_inc_counter(ifp, IFCOUNTER_IERRORS, (r & 0xffff) + ((r >> 17) & 0x7ff)); | if_inc_counter(ifp, IFCOUNTER_IERRORS, (r & 0xffff) + ((r >> 17) & 0x7ff)); | ||||
if (dc_rx_resync(sc)) | if (dc_rx_resync(sc)) { | ||||
NET_EPOCH_ENTER(et); | |||||
dc_rxeof(sc); | dc_rxeof(sc); | ||||
NET_EPOCH_EXIT(et); | |||||
} | } | ||||
} | |||||
/* restart transmit unit if necessary */ | /* restart transmit unit if necessary */ | ||||
if (status & DC_ISR_TX_IDLE && sc->dc_cdata.dc_tx_cnt) | if (status & DC_ISR_TX_IDLE && sc->dc_cdata.dc_tx_cnt) | ||||
CSR_WRITE_4(sc, DC_TXSTART, 0xFFFFFFFF); | CSR_WRITE_4(sc, DC_TXSTART, 0xFFFFFFFF); | ||||
if (status & DC_ISR_TX_UNDERRUN) | if (status & DC_ISR_TX_UNDERRUN) | ||||
dc_tx_underrun(sc); | dc_tx_underrun(sc); | ||||
if (status & DC_ISR_BUS_ERR) { | if (status & DC_ISR_BUS_ERR) { | ||||
if_printf(ifp, "%s: bus error\n", __func__); | if_printf(ifp, "%s: bus error\n", __func__); | ||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING; | ifp->if_drv_flags &= ~IFF_DRV_RUNNING; | ||||
dc_init_locked(sc); | dc_init_locked(sc); | ||||
} | } | ||||
} | } | ||||
DC_UNLOCK(sc); | DC_UNLOCK(sc); | ||||
return (rx_npkts); | return (rx_npkts); | ||||
} | } | ||||
#endif /* DEVICE_POLLING */ | #endif /* DEVICE_POLLING */ | ||||
static void | static void | ||||
dc_intr(void *arg) | dc_intr(void *arg) | ||||
{ | { | ||||
struct epoch_tracker et; | |||||
struct dc_softc *sc; | struct dc_softc *sc; | ||||
struct ifnet *ifp; | struct ifnet *ifp; | ||||
uint32_t r, status; | uint32_t r, status; | ||||
int n; | int n; | ||||
sc = arg; | sc = arg; | ||||
if (sc->suspended) | if (sc->suspended) | ||||
Show All 17 Lines | #endif | ||||
for (n = 16; n > 0; n--) { | for (n = 16; n > 0; n--) { | ||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) | if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) | ||||
break; | break; | ||||
/* Ack interrupts. */ | /* Ack interrupts. */ | ||||
CSR_WRITE_4(sc, DC_ISR, status); | CSR_WRITE_4(sc, DC_ISR, status); | ||||
if (status & DC_ISR_RX_OK) { | if (status & DC_ISR_RX_OK) { | ||||
NET_EPOCH_ENTER(et); | |||||
if (dc_rxeof(sc) == 0) { | if (dc_rxeof(sc) == 0) { | ||||
while (dc_rx_resync(sc)) | while (dc_rx_resync(sc)) | ||||
dc_rxeof(sc); | dc_rxeof(sc); | ||||
} | } | ||||
NET_EPOCH_EXIT(et); | |||||
} | } | ||||
if (status & (DC_ISR_TX_OK | DC_ISR_TX_NOBUF)) | if (status & (DC_ISR_TX_OK | DC_ISR_TX_NOBUF)) | ||||
dc_txeof(sc); | dc_txeof(sc); | ||||
if (status & DC_ISR_TX_IDLE) { | if (status & DC_ISR_TX_IDLE) { | ||||
dc_txeof(sc); | dc_txeof(sc); | ||||
if (sc->dc_cdata.dc_tx_cnt) { | if (sc->dc_cdata.dc_tx_cnt) { | ||||
DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_TX_ON); | DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_TX_ON); | ||||
CSR_WRITE_4(sc, DC_TXSTART, 0xFFFFFFFF); | CSR_WRITE_4(sc, DC_TXSTART, 0xFFFFFFFF); | ||||
} | } | ||||
} | } | ||||
if (status & DC_ISR_TX_UNDERRUN) | if (status & DC_ISR_TX_UNDERRUN) | ||||
dc_tx_underrun(sc); | dc_tx_underrun(sc); | ||||
if ((status & DC_ISR_RX_WATDOGTIMEO) | if ((status & DC_ISR_RX_WATDOGTIMEO) | ||||
|| (status & DC_ISR_RX_NOBUF)) { | || (status & DC_ISR_RX_NOBUF)) { | ||||
r = CSR_READ_4(sc, DC_FRAMESDISCARDED); | r = CSR_READ_4(sc, DC_FRAMESDISCARDED); | ||||
if_inc_counter(ifp, IFCOUNTER_IERRORS, (r & 0xffff) + ((r >> 17) & 0x7ff)); | if_inc_counter(ifp, IFCOUNTER_IERRORS, (r & 0xffff) + ((r >> 17) & 0x7ff)); | ||||
NET_EPOCH_ENTER(et); | |||||
if (dc_rxeof(sc) == 0) { | if (dc_rxeof(sc) == 0) { | ||||
while (dc_rx_resync(sc)) | while (dc_rx_resync(sc)) | ||||
dc_rxeof(sc); | dc_rxeof(sc); | ||||
} | } | ||||
NET_EPOCH_EXIT(et); | |||||
} | } | ||||
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) | if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) | ||||
dc_start_locked(ifp); | dc_start_locked(ifp); | ||||
if (status & DC_ISR_BUS_ERR) { | if (status & DC_ISR_BUS_ERR) { | ||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING; | ifp->if_drv_flags &= ~IFF_DRV_RUNNING; | ||||
dc_init_locked(sc); | dc_init_locked(sc); | ||||
▲ Show 20 Lines • Show All 784 Lines • Show Last 20 Lines |