summaryrefslogtreecommitdiffstats
path: root/sys/dev/bge
diff options
context:
space:
mode:
authoryongari <yongari@FreeBSD.org>2010-03-12 18:18:04 +0000
committeryongari <yongari@FreeBSD.org>2010-03-12 18:18:04 +0000
commit3f77820f8328644608cb1384fe50cab8d88f1944 (patch)
treeb0917ba376b3192fcdb476a942600fb8b305c19f /sys/dev/bge
parent231ed98ffa4a2fb26ed372b63defdf137e03c061 (diff)
downloadFreeBSD-src-3f77820f8328644608cb1384fe50cab8d88f1944.zip
FreeBSD-src-3f77820f8328644608cb1384fe50cab8d88f1944.tar.gz
Reorder interrupt handler a bit such that producer/consumer
index of status block is read first before acknowledging the interrupts. Otherwise bge(4) may get stale status block as acknowledging an interrupt may yield another status block update. Reviewed by: marius
Diffstat (limited to 'sys/dev/bge')
-rw-r--r--sys/dev/bge/if_bge.c32
1 files changed, 16 insertions, 16 deletions
diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index b21fd72..679d202 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -3654,6 +3654,22 @@ bge_intr(void *xsc)
#endif
/*
+ * Do the mandatory PCI flush as well as get the link status.
+ */
+ statusword = CSR_READ_4(sc, BGE_MAC_STS) & BGE_MACSTAT_LINK_CHANGED;
+
+ /* Make sure the descriptor ring indexes are coherent. */
+ bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
+ sc->bge_cdata.bge_status_map,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ rx_prod = sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx;
+ tx_cons = sc->bge_ldata.bge_status_block->bge_idx[0].bge_tx_cons_idx;
+ sc->bge_ldata.bge_status_block->bge_status = 0;
+ bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
+ sc->bge_cdata.bge_status_map,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
+ /*
* Ack the interrupt by writing something to BGE_MBX_IRQ0_LO. Don't
* disable interrupts by writing nonzero like we used to, since with
* our current organization this just gives complications and
@@ -3675,22 +3691,6 @@ bge_intr(void *xsc)
*/
bge_writembx(sc, BGE_MBX_IRQ0_LO, 0);
- /*
- * Do the mandatory PCI flush as well as get the link status.
- */
- statusword = CSR_READ_4(sc, BGE_MAC_STS) & BGE_MACSTAT_LINK_CHANGED;
-
- /* Make sure the descriptor ring indexes are coherent. */
- bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
- sc->bge_cdata.bge_status_map,
- BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
- rx_prod = sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx;
- tx_cons = sc->bge_ldata.bge_status_block->bge_idx[0].bge_tx_cons_idx;
- sc->bge_ldata.bge_status_block->bge_status = 0;
- bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
- sc->bge_cdata.bge_status_map,
- BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
-
if ((sc->bge_asicrev == BGE_ASICREV_BCM5700 &&
sc->bge_chipid != BGE_CHIPID_BCM5700_B2) ||
statusword || sc->bge_link_evt)
OpenPOWER on IntegriCloud