summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoroleg <oleg@FreeBSD.org>2006-02-01 14:41:08 +0000
committeroleg <oleg@FreeBSD.org>2006-02-01 14:41:08 +0000
commit07c68a91e26ee2f1014495097ebfc66a5ac43b50 (patch)
tree50b212c6e674fa0f68e265e78d86980c3ddfc6df
parent87dcb0582dceaa1c8094cad61b0dc243a795d726 (diff)
downloadFreeBSD-src-07c68a91e26ee2f1014495097ebfc66a5ac43b50.zip
FreeBSD-src-07c68a91e26ee2f1014495097ebfc66a5ac43b50.tar.gz
Since bge_rxeof() & bge_txeof() depends on status block data it should be
synchronized on every call of bge_poll_locked(). Suggested by: Mihail Balikov <mihail.balikov AT interbgc DOT com> Approved by: glebius (mentor) MFC after: 3 days
-rw-r--r--sys/dev/bge/if_bge.c30
1 files changed, 16 insertions, 14 deletions
diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index 54be9b5..e95805c 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -2732,31 +2732,33 @@ static void
bge_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count)
{
struct bge_softc *sc = ifp->if_softc;
+ uint32_t statusword;
BGE_LOCK_ASSERT(sc);
- sc->rxcycles = count;
- bge_rxeof(sc);
- bge_txeof(sc);
- if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
- bge_start_locked(ifp);
+ bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
+ sc->bge_cdata.bge_status_map, BUS_DMASYNC_POSTREAD);
- if (cmd == POLL_AND_CHECK_STATUS) {
- uint32_t statusword;
+ statusword = atomic_readandclear_32(&sc->bge_ldata.bge_status_block->bge_status);
- bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
- sc->bge_cdata.bge_status_map, BUS_DMASYNC_POSTREAD);
+ bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
+ sc->bge_cdata.bge_status_map, BUS_DMASYNC_PREREAD);
- statusword = atomic_readandclear_32(&sc->bge_ldata.bge_status_block->bge_status);
+ /* Note link event. It will be processed by POLL_AND_CHECK_STATUS cmd */
+ if (statusword & BGE_STATFLAG_LINKSTATE_CHANGED)
+ sc->bge_link_evt++;
+ if (cmd == POLL_AND_CHECK_STATUS)
if ((sc->bge_asicrev == BGE_ASICREV_BCM5700 &&
sc->bge_chipid != BGE_CHIPID_BCM5700_B1) ||
- statusword & BGE_STATFLAG_LINKSTATE_CHANGED)
+ sc->bge_link_evt || sc->bge_tbi)
bge_link_upd(sc);
- bus_dmamap_sync(sc->bge_cdata.bge_status_tag,
- sc->bge_cdata.bge_status_map, BUS_DMASYNC_PREREAD);
- }
+ sc->rxcycles = count;
+ bge_rxeof(sc);
+ bge_txeof(sc);
+ if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
+ bge_start_locked(ifp);
}
#endif /* DEVICE_POLLING */
OpenPOWER on IntegriCloud