diff options
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 */ |