age_init() is called from age_watchdog() which is interrupt context, we
can't sleep here or we get a DIAGNOSTIC panic when age_watchdog() fires. More correct bus_dma(9) usage in age_encap() Introduce a age_shutdown() to be called by pmf(9) at shutdown time, to stop the DMA engine. My system would't properly reboot without this. Be consistent in WAIT/NOWAIT use in init routines Use BUS_DMA_COHERENT where appropriate Rework the interrupt routine a bit, and ACK but do not disable interrupts here. There seems to be a race where interrupts would not be properly reenabled after this, leading do watchdog timeouts. With these changes, the on-board age(4) on ftp.fr.netbsd.org seems to be finally working properly.
This commit is contained in:
parent
b00fe7a7a8
commit
89476a0134
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_age.c,v 1.39 2010/07/20 09:17:24 cegger Exp $ */
|
||||
/* $NetBSD: if_age.c,v 1.40 2011/10/25 21:47:38 bouyer Exp $ */
|
||||
/* $OpenBSD: if_age.c,v 1.1 2009/01/16 05:00:34 kevlo Exp $ */
|
||||
|
||||
/*-
|
||||
|
@ -31,7 +31,7 @@
|
|||
/* Driver for Attansic Technology Corp. L1 Gigabit Ethernet. */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_age.c,v 1.39 2010/07/20 09:17:24 cegger Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_age.c,v 1.40 2011/10/25 21:47:38 bouyer Exp $");
|
||||
|
||||
#include "vlan.h"
|
||||
|
||||
|
@ -90,6 +90,7 @@ static int age_init(struct ifnet *);
|
|||
static int age_ioctl(struct ifnet *, u_long, void *);
|
||||
static void age_start(struct ifnet *);
|
||||
static void age_watchdog(struct ifnet *);
|
||||
static bool age_shutdown(device_t, int);
|
||||
static void age_mediastatus(struct ifnet *, struct ifmediareq *);
|
||||
static int age_mediachange(struct ifnet *);
|
||||
|
||||
|
@ -287,7 +288,7 @@ age_attach(device_t parent, device_t self, void *aux)
|
|||
if_attach(ifp);
|
||||
ether_ifattach(ifp, sc->sc_enaddr);
|
||||
|
||||
if (pmf_device_register(self, NULL, age_resume))
|
||||
if (pmf_device_register1(self, NULL, age_resume, age_shutdown))
|
||||
pmf_class_network_register(self, ifp);
|
||||
else
|
||||
aprint_error_dev(self, "couldn't establish power handler\n");
|
||||
|
@ -495,65 +496,61 @@ age_intr(void *arg)
|
|||
cmb = sc->age_rdata.age_cmb_block;
|
||||
if (cmb == NULL) {
|
||||
/* Happens when bringing up the interface
|
||||
* w/o having a carrier. Ack. the interrupt.
|
||||
* w/o having a carrier. Ack the interrupt.
|
||||
*/
|
||||
CSR_WRITE_4(sc, AGE_INTR_STATUS, status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Disable interrupts. */
|
||||
CSR_WRITE_4(sc, AGE_INTR_STATUS, status | INTR_DIS_INT);
|
||||
|
||||
bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_cmb_block_map, 0,
|
||||
sc->age_cdata.age_cmb_block_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
|
||||
status = le32toh(cmb->intr_status);
|
||||
if ((status & AGE_INTRS) == 0)
|
||||
goto back;
|
||||
|
||||
sc->age_tpd_cons = (le32toh(cmb->tpd_cons) & TPD_CONS_MASK) >>
|
||||
TPD_CONS_SHIFT;
|
||||
sc->age_rr_prod = (le32toh(cmb->rprod_cons) & RRD_PROD_MASK) >>
|
||||
RRD_PROD_SHIFT;
|
||||
|
||||
/* Let hardware know CMB was served. */
|
||||
cmb->intr_status = 0;
|
||||
bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_cmb_block_map, 0,
|
||||
sc->age_cdata.age_cmb_block_map->dm_mapsize,
|
||||
BUS_DMASYNC_PREWRITE);
|
||||
BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
|
||||
status = le32toh(cmb->intr_status);
|
||||
/* ACK/reenable interrupts */
|
||||
CSR_WRITE_4(sc, AGE_INTR_STATUS, status);
|
||||
while ((status & AGE_INTRS) != 0) {
|
||||
sc->age_tpd_cons = (le32toh(cmb->tpd_cons) & TPD_CONS_MASK) >>
|
||||
TPD_CONS_SHIFT;
|
||||
sc->age_rr_prod = (le32toh(cmb->rprod_cons) & RRD_PROD_MASK) >>
|
||||
RRD_PROD_SHIFT;
|
||||
|
||||
if (ifp->if_flags & IFF_RUNNING) {
|
||||
if (status & INTR_CMB_RX)
|
||||
age_rxintr(sc, sc->age_rr_prod);
|
||||
/* Let hardware know CMB was served. */
|
||||
cmb->intr_status = 0;
|
||||
bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_cmb_block_map, 0,
|
||||
sc->age_cdata.age_cmb_block_map->dm_mapsize,
|
||||
BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
|
||||
|
||||
if (status & INTR_CMB_TX)
|
||||
age_txintr(sc, sc->age_tpd_cons);
|
||||
if (ifp->if_flags & IFF_RUNNING) {
|
||||
if (status & INTR_CMB_RX)
|
||||
age_rxintr(sc, sc->age_rr_prod);
|
||||
|
||||
if (status & (INTR_DMA_RD_TO_RST | INTR_DMA_WR_TO_RST)) {
|
||||
if (status & INTR_DMA_RD_TO_RST)
|
||||
printf("%s: DMA read error! -- resetting\n",
|
||||
device_xname(sc->sc_dev));
|
||||
if (status & INTR_DMA_WR_TO_RST)
|
||||
printf("%s: DMA write error! -- resetting\n",
|
||||
device_xname(sc->sc_dev));
|
||||
age_init(ifp);
|
||||
}
|
||||
if (status & INTR_CMB_TX)
|
||||
age_txintr(sc, sc->age_tpd_cons);
|
||||
|
||||
if (status & (INTR_DMA_RD_TO_RST | INTR_DMA_WR_TO_RST)) {
|
||||
if (status & INTR_DMA_RD_TO_RST)
|
||||
printf("%s: DMA read error! -- "
|
||||
"resetting\n",
|
||||
device_xname(sc->sc_dev));
|
||||
if (status & INTR_DMA_WR_TO_RST)
|
||||
printf("%s: DMA write error! -- "
|
||||
"resetting\n",
|
||||
device_xname(sc->sc_dev));
|
||||
age_init(ifp);
|
||||
}
|
||||
|
||||
if (!IFQ_IS_EMPTY(&ifp->if_snd))
|
||||
age_start(ifp);
|
||||
|
||||
if (status & INTR_SMB)
|
||||
age_stats_update(sc);
|
||||
if (status & INTR_SMB)
|
||||
age_stats_update(sc);
|
||||
}
|
||||
/* check if more interrupts did came in */
|
||||
bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_cmb_block_map, 0,
|
||||
sc->age_cdata.age_cmb_block_map->dm_mapsize,
|
||||
BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
|
||||
status = le32toh(cmb->intr_status);
|
||||
}
|
||||
|
||||
/* Check whether CMB was updated while serving Tx/Rx/SMB handler. */
|
||||
bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_cmb_block_map, 0,
|
||||
sc->age_cdata.age_cmb_block_map->dm_mapsize,
|
||||
BUS_DMASYNC_POSTREAD);
|
||||
|
||||
back:
|
||||
/* Re-enable interrupts. */
|
||||
CSR_WRITE_4(sc, AGE_INTR_STATUS, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -702,7 +699,7 @@ age_dma_alloc(struct age_softc *sc)
|
|||
/* Allocate DMA'able memory for TX ring */
|
||||
error = bus_dmamem_alloc(sc->sc_dmat, AGE_TX_RING_SZ,
|
||||
ETHER_ALIGN, 0, &sc->age_rdata.age_tx_ring_seg, 1,
|
||||
&nsegs, BUS_DMA_WAITOK);
|
||||
&nsegs, BUS_DMA_NOWAIT);
|
||||
if (error) {
|
||||
printf("%s: could not allocate DMA'able memory for Tx ring, "
|
||||
"error = %i\n", device_xname(sc->sc_dev), error);
|
||||
|
@ -711,7 +708,7 @@ age_dma_alloc(struct age_softc *sc)
|
|||
|
||||
error = bus_dmamem_map(sc->sc_dmat, &sc->age_rdata.age_tx_ring_seg,
|
||||
nsegs, AGE_TX_RING_SZ, (void **)&sc->age_rdata.age_tx_ring,
|
||||
BUS_DMA_NOWAIT);
|
||||
BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
|
||||
if (error)
|
||||
return ENOBUFS;
|
||||
|
||||
|
@ -719,7 +716,7 @@ age_dma_alloc(struct age_softc *sc)
|
|||
|
||||
/* Load the DMA map for Tx ring. */
|
||||
error = bus_dmamap_load(sc->sc_dmat, sc->age_cdata.age_tx_ring_map,
|
||||
sc->age_rdata.age_tx_ring, AGE_TX_RING_SZ, NULL, BUS_DMA_WAITOK);
|
||||
sc->age_rdata.age_tx_ring, AGE_TX_RING_SZ, NULL, BUS_DMA_NOWAIT);
|
||||
if (error) {
|
||||
printf("%s: could not load DMA'able memory for Tx ring, "
|
||||
"error = %i\n", device_xname(sc->sc_dev), error);
|
||||
|
@ -744,7 +741,7 @@ age_dma_alloc(struct age_softc *sc)
|
|||
/* Allocate DMA'able memory for RX ring */
|
||||
error = bus_dmamem_alloc(sc->sc_dmat, AGE_RX_RING_SZ,
|
||||
ETHER_ALIGN, 0, &sc->age_rdata.age_rx_ring_seg, 1,
|
||||
&nsegs, BUS_DMA_WAITOK);
|
||||
&nsegs, BUS_DMA_NOWAIT);
|
||||
if (error) {
|
||||
printf("%s: could not allocate DMA'able memory for Rx ring, "
|
||||
"error = %i.\n", device_xname(sc->sc_dev), error);
|
||||
|
@ -753,7 +750,7 @@ age_dma_alloc(struct age_softc *sc)
|
|||
|
||||
error = bus_dmamem_map(sc->sc_dmat, &sc->age_rdata.age_rx_ring_seg,
|
||||
nsegs, AGE_RX_RING_SZ, (void **)&sc->age_rdata.age_rx_ring,
|
||||
BUS_DMA_NOWAIT);
|
||||
BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
|
||||
if (error)
|
||||
return ENOBUFS;
|
||||
|
||||
|
@ -761,7 +758,7 @@ age_dma_alloc(struct age_softc *sc)
|
|||
|
||||
/* Load the DMA map for Rx ring. */
|
||||
error = bus_dmamap_load(sc->sc_dmat, sc->age_cdata.age_rx_ring_map,
|
||||
sc->age_rdata.age_rx_ring, AGE_RX_RING_SZ, NULL, BUS_DMA_WAITOK);
|
||||
sc->age_rdata.age_rx_ring, AGE_RX_RING_SZ, NULL, BUS_DMA_NOWAIT);
|
||||
if (error) {
|
||||
printf("%s: could not load DMA'able memory for Rx ring, "
|
||||
"error = %i.\n", device_xname(sc->sc_dev), error);
|
||||
|
@ -786,7 +783,7 @@ age_dma_alloc(struct age_softc *sc)
|
|||
/* Allocate DMA'able memory for RX return ring */
|
||||
error = bus_dmamem_alloc(sc->sc_dmat, AGE_RR_RING_SZ,
|
||||
ETHER_ALIGN, 0, &sc->age_rdata.age_rr_ring_seg, 1,
|
||||
&nsegs, BUS_DMA_WAITOK);
|
||||
&nsegs, BUS_DMA_NOWAIT);
|
||||
if (error) {
|
||||
printf("%s: could not allocate DMA'able memory for Rx "
|
||||
"return ring, error = %i.\n",
|
||||
|
@ -796,7 +793,7 @@ age_dma_alloc(struct age_softc *sc)
|
|||
|
||||
error = bus_dmamem_map(sc->sc_dmat, &sc->age_rdata.age_rr_ring_seg,
|
||||
nsegs, AGE_RR_RING_SZ, (void **)&sc->age_rdata.age_rr_ring,
|
||||
BUS_DMA_NOWAIT);
|
||||
BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
|
||||
if (error)
|
||||
return ENOBUFS;
|
||||
|
||||
|
@ -804,7 +801,7 @@ age_dma_alloc(struct age_softc *sc)
|
|||
|
||||
/* Load the DMA map for Rx return ring. */
|
||||
error = bus_dmamap_load(sc->sc_dmat, sc->age_cdata.age_rr_ring_map,
|
||||
sc->age_rdata.age_rr_ring, AGE_RR_RING_SZ, NULL, BUS_DMA_WAITOK);
|
||||
sc->age_rdata.age_rr_ring, AGE_RR_RING_SZ, NULL, BUS_DMA_NOWAIT);
|
||||
if (error) {
|
||||
printf("%s: could not load DMA'able memory for Rx return ring, "
|
||||
"error = %i\n", device_xname(sc->sc_dev), error);
|
||||
|
@ -830,7 +827,7 @@ age_dma_alloc(struct age_softc *sc)
|
|||
/* Allocate DMA'able memory for CMB block */
|
||||
error = bus_dmamem_alloc(sc->sc_dmat, AGE_CMB_BLOCK_SZ,
|
||||
ETHER_ALIGN, 0, &sc->age_rdata.age_cmb_block_seg, 1,
|
||||
&nsegs, BUS_DMA_WAITOK);
|
||||
&nsegs, BUS_DMA_NOWAIT);
|
||||
if (error) {
|
||||
printf("%s: could not allocate DMA'able memory for "
|
||||
"CMB block, error = %i\n", device_xname(sc->sc_dev), error);
|
||||
|
@ -839,7 +836,7 @@ age_dma_alloc(struct age_softc *sc)
|
|||
|
||||
error = bus_dmamem_map(sc->sc_dmat, &sc->age_rdata.age_cmb_block_seg,
|
||||
nsegs, AGE_CMB_BLOCK_SZ, (void **)&sc->age_rdata.age_cmb_block,
|
||||
BUS_DMA_NOWAIT);
|
||||
BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
|
||||
if (error)
|
||||
return ENOBUFS;
|
||||
|
||||
|
@ -848,7 +845,7 @@ age_dma_alloc(struct age_softc *sc)
|
|||
/* Load the DMA map for CMB block. */
|
||||
error = bus_dmamap_load(sc->sc_dmat, sc->age_cdata.age_cmb_block_map,
|
||||
sc->age_rdata.age_cmb_block, AGE_CMB_BLOCK_SZ, NULL,
|
||||
BUS_DMA_WAITOK);
|
||||
BUS_DMA_NOWAIT);
|
||||
if (error) {
|
||||
printf("%s: could not load DMA'able memory for CMB block, "
|
||||
"error = %i\n", device_xname(sc->sc_dev), error);
|
||||
|
@ -874,7 +871,7 @@ age_dma_alloc(struct age_softc *sc)
|
|||
/* Allocate DMA'able memory for SMB block */
|
||||
error = bus_dmamem_alloc(sc->sc_dmat, AGE_SMB_BLOCK_SZ,
|
||||
ETHER_ALIGN, 0, &sc->age_rdata.age_smb_block_seg, 1,
|
||||
&nsegs, BUS_DMA_WAITOK);
|
||||
&nsegs, BUS_DMA_NOWAIT);
|
||||
if (error) {
|
||||
printf("%s: could not allocate DMA'able memory for "
|
||||
"SMB block, error = %i\n", device_xname(sc->sc_dev), error);
|
||||
|
@ -883,7 +880,7 @@ age_dma_alloc(struct age_softc *sc)
|
|||
|
||||
error = bus_dmamem_map(sc->sc_dmat, &sc->age_rdata.age_smb_block_seg,
|
||||
nsegs, AGE_SMB_BLOCK_SZ, (void **)&sc->age_rdata.age_smb_block,
|
||||
BUS_DMA_NOWAIT);
|
||||
BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
|
||||
if (error)
|
||||
return ENOBUFS;
|
||||
|
||||
|
@ -892,7 +889,7 @@ age_dma_alloc(struct age_softc *sc)
|
|||
/* Load the DMA map for SMB block */
|
||||
error = bus_dmamap_load(sc->sc_dmat, sc->age_cdata.age_smb_block_map,
|
||||
sc->age_rdata.age_smb_block, AGE_SMB_BLOCK_SZ, NULL,
|
||||
BUS_DMA_WAITOK);
|
||||
BUS_DMA_NOWAIT);
|
||||
if (error) {
|
||||
printf("%s: could not load DMA'able memory for SMB block, "
|
||||
"error = %i\n", device_xname(sc->sc_dev), error);
|
||||
|
@ -1034,6 +1031,10 @@ age_start(struct ifnet *ifp)
|
|||
|
||||
if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
|
||||
return;
|
||||
if ((sc->age_flags & AGE_FLAG_LINK) == 0)
|
||||
return;
|
||||
if (IFQ_IS_EMPTY(&ifp->if_snd))
|
||||
return;
|
||||
|
||||
enq = 0;
|
||||
for (;;) {
|
||||
|
@ -1086,19 +1087,30 @@ age_watchdog(struct ifnet *ifp)
|
|||
if (sc->age_cdata.age_tx_cnt == 0) {
|
||||
printf("%s: watchdog timeout (missed Tx interrupts) "
|
||||
"-- recovering\n", device_xname(sc->sc_dev));
|
||||
if (!IFQ_IS_EMPTY(&ifp->if_snd))
|
||||
age_start(ifp);
|
||||
age_start(ifp);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("%s: watchdog timeout\n", device_xname(sc->sc_dev));
|
||||
ifp->if_oerrors++;
|
||||
age_init(ifp);
|
||||
|
||||
if (!IFQ_IS_EMPTY(&ifp->if_snd))
|
||||
age_start(ifp);
|
||||
age_start(ifp);
|
||||
}
|
||||
|
||||
static bool
|
||||
age_shutdown(device_t self, int howto)
|
||||
{
|
||||
struct age_softc *sc;
|
||||
struct ifnet *ifp;
|
||||
|
||||
sc = device_private(self);
|
||||
ifp = &sc->sc_ec.ec_if;
|
||||
age_stop(ifp, 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
age_ioctl(struct ifnet *ifp, u_long cmd, void *data)
|
||||
{
|
||||
|
@ -1234,6 +1246,8 @@ age_encap(struct age_softc *sc, struct mbuf **m_head)
|
|||
bus_dmamap_unload(sc->sc_dmat, map);
|
||||
return ENOBUFS;
|
||||
}
|
||||
bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
|
||||
BUS_DMASYNC_PREWRITE);
|
||||
|
||||
m = *m_head;
|
||||
/* Configure Tx IP/TCP/UDP checksum offload. */
|
||||
|
@ -1257,36 +1271,46 @@ age_encap(struct age_softc *sc, struct mbuf **m_head)
|
|||
#endif
|
||||
|
||||
desc = NULL;
|
||||
for (i = 0; i < nsegs; i++) {
|
||||
KASSERT(nsegs > 0);
|
||||
for (i = 0; ; i++) {
|
||||
desc = &sc->age_rdata.age_tx_ring[prod];
|
||||
desc->addr = htole64(map->dm_segs[i].ds_addr);
|
||||
desc->len =
|
||||
htole32(AGE_TX_BYTES(map->dm_segs[i].ds_len) | vtag);
|
||||
desc->flags = htole32(cflags);
|
||||
sc->age_cdata.age_tx_cnt++;
|
||||
if (i == (nsegs - 1))
|
||||
break;
|
||||
|
||||
/* sync this descriptor and go to the next one */
|
||||
bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_tx_ring_map,
|
||||
prod * sizeof(struct tx_desc), sizeof(struct tx_desc),
|
||||
BUS_DMASYNC_PREWRITE);
|
||||
AGE_DESC_INC(prod, AGE_TX_RING_CNT);
|
||||
}
|
||||
|
||||
/* Update producer index. */
|
||||
sc->age_cdata.age_tx_prod = prod;
|
||||
|
||||
/* Set EOP on the last descriptor. */
|
||||
prod = (prod + AGE_TX_RING_CNT - 1) % AGE_TX_RING_CNT;
|
||||
desc = &sc->age_rdata.age_tx_ring[prod];
|
||||
/* Set EOP on the last descriptor and sync it. */
|
||||
desc->flags |= htole32(AGE_TD_EOP);
|
||||
|
||||
/* Swap dmamap of the first and the last. */
|
||||
txd = &sc->age_cdata.age_txdesc[prod];
|
||||
map = txd_last->tx_dmamap;
|
||||
txd_last->tx_dmamap = txd->tx_dmamap;
|
||||
txd->tx_dmamap = map;
|
||||
txd->tx_m = m;
|
||||
|
||||
/* Sync descriptors. */
|
||||
bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
|
||||
bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_tx_ring_map,
|
||||
prod * sizeof(struct tx_desc), sizeof(struct tx_desc),
|
||||
BUS_DMASYNC_PREWRITE);
|
||||
bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_tx_ring_map, 0,
|
||||
sc->age_cdata.age_tx_ring_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
|
||||
|
||||
if (nsegs > 1) {
|
||||
/* Swap dmamap of the first and the last. */
|
||||
txd = &sc->age_cdata.age_txdesc[prod];
|
||||
map = txd_last->tx_dmamap;
|
||||
txd_last->tx_dmamap = txd->tx_dmamap;
|
||||
txd->tx_dmamap = map;
|
||||
txd->tx_m = m;
|
||||
KASSERT(txd_last->tx_m == NULL);
|
||||
} else {
|
||||
KASSERT(txd_last == &sc->age_cdata.age_txdesc[prod]);
|
||||
txd_last->tx_m = m;
|
||||
}
|
||||
|
||||
/* Update producer index. */
|
||||
AGE_DESC_INC(prod, AGE_TX_RING_CNT);
|
||||
sc->age_cdata.age_tx_prod = prod;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1298,8 +1322,13 @@ age_txintr(struct age_softc *sc, int tpd_cons)
|
|||
struct age_txdesc *txd;
|
||||
int cons, prog;
|
||||
|
||||
bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_tx_ring_map, 0,
|
||||
sc->age_cdata.age_tx_ring_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
|
||||
|
||||
if (sc->age_cdata.age_tx_cnt <= 0) {
|
||||
if (ifp->if_timer != 0)
|
||||
printf("timer running without packets\n");
|
||||
if (sc->age_cdata.age_tx_cnt)
|
||||
printf("age_tx_cnt corrupted\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Go through our Tx list and free mbufs for those
|
||||
|
@ -1317,6 +1346,9 @@ age_txintr(struct age_softc *sc, int tpd_cons)
|
|||
* Clear Tx descriptors, it's not required but would
|
||||
* help debugging in case of Tx issues.
|
||||
*/
|
||||
bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_tx_ring_map,
|
||||
cons * sizeof(struct tx_desc), sizeof(struct tx_desc),
|
||||
BUS_DMASYNC_POSTWRITE);
|
||||
txd->tx_desc->addr = 0;
|
||||
txd->tx_desc->len = 0;
|
||||
txd->tx_desc->flags = 0;
|
||||
|
@ -1338,10 +1370,6 @@ age_txintr(struct age_softc *sc, int tpd_cons)
|
|||
*/
|
||||
if (sc->age_cdata.age_tx_cnt == 0)
|
||||
ifp->if_timer = 0;
|
||||
|
||||
bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_tx_ring_map, 0,
|
||||
sc->age_cdata.age_tx_ring_map->dm_mapsize,
|
||||
BUS_DMASYNC_PREWRITE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1951,7 +1979,8 @@ age_stats_update(struct age_softc *sc)
|
|||
stat = &sc->age_stat;
|
||||
|
||||
bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_smb_block_map, 0,
|
||||
sc->age_cdata.age_smb_block_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
|
||||
sc->age_cdata.age_smb_block_map->dm_mapsize,
|
||||
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
|
||||
|
||||
smb = sc->age_rdata.age_smb_block;
|
||||
if (smb->updated == 0)
|
||||
|
@ -2032,7 +2061,8 @@ age_stats_update(struct age_softc *sc)
|
|||
smb->updated = 0;
|
||||
|
||||
bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_smb_block_map, 0,
|
||||
sc->age_cdata.age_smb_block_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
|
||||
sc->age_cdata.age_smb_block_map->dm_mapsize,
|
||||
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2157,7 +2187,8 @@ age_init_cmb_block(struct age_softc *sc)
|
|||
rd = &sc->age_rdata;
|
||||
memset(rd->age_cmb_block, 0, AGE_CMB_BLOCK_SZ);
|
||||
bus_dmamap_sync(sc->sc_dmat, sc->age_cdata.age_cmb_block_map, 0,
|
||||
sc->age_cdata.age_cmb_block_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
|
||||
sc->age_cdata.age_cmb_block_map->dm_mapsize,
|
||||
BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2179,10 +2210,10 @@ age_newbuf(struct age_softc *sc, struct age_rxdesc *rxd, int init)
|
|||
bus_dmamap_t map;
|
||||
int error;
|
||||
|
||||
MGETHDR(m, init ? M_WAITOK : M_DONTWAIT, MT_DATA);
|
||||
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
||||
if (m == NULL)
|
||||
return ENOBUFS;
|
||||
MCLGET(m, init ? M_WAITOK : M_DONTWAIT);
|
||||
MCLGET(m, M_DONTWAIT);
|
||||
if (!(m->m_flags & M_EXT)) {
|
||||
m_freem(m);
|
||||
return ENOBUFS;
|
||||
|
|
Loading…
Reference in New Issue