diff options
author | oleg <oleg@FreeBSD.org> | 2006-02-01 14:41:08 +0000 |
---|---|---|
committer | oleg <oleg@FreeBSD.org> | 2006-02-01 14:41:08 +0000 |
commit | 07c68a91e26ee2f1014495097ebfc66a5ac43b50 (patch) | |
tree | 50b212c6e674fa0f68e265e78d86980c3ddfc6df /sys/dev | |
parent | 87dcb0582dceaa1c8094cad61b0dc243a795d726 (diff) | |
download | FreeBSD-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
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/bge/if_bge.c | 30 |
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 */ |