version 1.668, 2020/02/18 04:07:14 |
version 1.669, 2020/03/15 23:04:50 |
Line 759 static void wm_init_sysctls(struct wm_so |
|
Line 759 static void wm_init_sysctls(struct wm_so |
|
static void wm_unset_stopping_flags(struct wm_softc *); |
static void wm_unset_stopping_flags(struct wm_softc *); |
static void wm_set_stopping_flags(struct wm_softc *); |
static void wm_set_stopping_flags(struct wm_softc *); |
static void wm_stop(struct ifnet *, int); |
static void wm_stop(struct ifnet *, int); |
static void wm_stop_locked(struct ifnet *, int); |
static void wm_stop_locked(struct ifnet *, bool, bool); |
static void wm_dump_mbuf_chain(struct wm_softc *, struct mbuf *); |
static void wm_dump_mbuf_chain(struct wm_softc *, struct mbuf *); |
static void wm_82547_txfifo_stall(void *); |
static void wm_82547_txfifo_stall(void *); |
static int wm_82547_txfifo_bugchk(struct wm_softc *, struct mbuf *); |
static int wm_82547_txfifo_bugchk(struct wm_softc *, struct mbuf *); |
Line 1832 wm_attach(device_t parent, device_t self |
|
Line 1832 wm_attach(device_t parent, device_t self |
|
|
|
sc->sc_dev = self; |
sc->sc_dev = self; |
callout_init(&sc->sc_tick_ch, CALLOUT_FLAGS); |
callout_init(&sc->sc_tick_ch, CALLOUT_FLAGS); |
|
callout_setfunc(&sc->sc_tick_ch, wm_tick, sc); |
sc->sc_core_stopping = false; |
sc->sc_core_stopping = false; |
|
|
wmp = wm_lookup(pa); |
wmp = wm_lookup(pa); |
|
|
snprintb(buf, sizeof(buf), WM_FLAGS, sc->sc_flags); |
snprintb(buf, sizeof(buf), WM_FLAGS, sc->sc_flags); |
aprint_verbose_dev(sc->sc_dev, "%s\n", buf); |
aprint_verbose_dev(sc->sc_dev, "%s\n", buf); |
|
|
|
#ifdef WM_MPSAFE |
|
sc->sc_core_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET); |
|
#else |
|
sc->sc_core_lock = NULL; |
|
#endif |
|
|
/* Initialize the media structures accordingly. */ |
/* Initialize the media structures accordingly. */ |
if (sc->sc_mediatype == WM_MEDIATYPE_COPPER) |
if (sc->sc_mediatype == WM_MEDIATYPE_COPPER) |
wm_gmii_mediainit(sc, wmp->wmp_product); |
wm_gmii_mediainit(sc, wmp->wmp_product); |
|
|
sc->sc_rx_process_limit = WM_RX_PROCESS_LIMIT_DEFAULT; |
sc->sc_rx_process_limit = WM_RX_PROCESS_LIMIT_DEFAULT; |
sc->sc_rx_intr_process_limit = WM_RX_INTR_PROCESS_LIMIT_DEFAULT; |
sc->sc_rx_intr_process_limit = WM_RX_INTR_PROCESS_LIMIT_DEFAULT; |
|
|
#ifdef WM_MPSAFE |
|
sc->sc_core_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET); |
|
#else |
|
sc->sc_core_lock = NULL; |
|
#endif |
|
|
|
/* Attach the interface. */ |
/* Attach the interface. */ |
error = if_initialize(ifp); |
error = if_initialize(ifp); |
if (error != 0) { |
if (error != 0) { |
Line 3102 wm_detach(device_t self, int flags __unu |
|
Line 3103 wm_detach(device_t self, int flags __unu |
|
|
|
mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY); |
mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY); |
|
|
/* Delete all remaining media. */ |
|
ifmedia_delete_instance(&sc->sc_mii.mii_media, IFM_INST_ANY); |
|
|
|
ether_ifdetach(ifp); |
ether_ifdetach(ifp); |
if_detach(ifp); |
if_detach(ifp); |
if_percpuq_destroy(sc->sc_ipq); |
if_percpuq_destroy(sc->sc_ipq); |
|
|
|
/* Delete all remaining media. */ |
|
ifmedia_fini(&sc->sc_mii.mii_media); |
|
|
/* Unload RX dmamaps and free mbufs */ |
/* Unload RX dmamaps and free mbufs */ |
for (i = 0; i < sc->sc_nqueues; i++) { |
for (i = 0; i < sc->sc_nqueues; i++) { |
struct wm_rxqueue *rxq = &sc->sc_queue[i].wmq_rxq; |
struct wm_rxqueue *rxq = &sc->sc_queue[i].wmq_rxq; |
Line 3379 wm_tick(void *arg) |
|
Line 3380 wm_tick(void *arg) |
|
|
|
wm_watchdog(ifp); |
wm_watchdog(ifp); |
|
|
callout_reset(&sc->sc_tick_ch, hz, wm_tick, sc); |
callout_schedule(&sc->sc_tick_ch, hz); |
} |
} |
|
|
static int |
static int |
Line 5844 wm_init_locked(struct ifnet *ifp) |
|
Line 5845 wm_init_locked(struct ifnet *ifp) |
|
#endif /* __NO_STRICT_ALIGNMENT */ |
#endif /* __NO_STRICT_ALIGNMENT */ |
|
|
/* Cancel any pending I/O. */ |
/* Cancel any pending I/O. */ |
wm_stop_locked(ifp, 0); |
wm_stop_locked(ifp, false, false); |
|
|
/* Update statistics before reset */ |
/* Update statistics before reset */ |
if_statadd2(ifp, if_collisions, CSR_READ(sc, WMREG_COLC), |
if_statadd2(ifp, if_collisions, CSR_READ(sc, WMREG_COLC), |
Line 6378 wm_init_locked(struct ifnet *ifp) |
|
Line 6379 wm_init_locked(struct ifnet *ifp) |
|
wm_unset_stopping_flags(sc); |
wm_unset_stopping_flags(sc); |
|
|
/* Start the one second link check clock. */ |
/* Start the one second link check clock. */ |
callout_reset(&sc->sc_tick_ch, hz, wm_tick, sc); |
callout_schedule(&sc->sc_tick_ch, hz); |
|
|
/* ...all done! */ |
/* ...all done! */ |
ifp->if_flags |= IFF_RUNNING; |
ifp->if_flags |= IFF_RUNNING; |
Line 6404 wm_stop(struct ifnet *ifp, int disable) |
|
Line 6405 wm_stop(struct ifnet *ifp, int disable) |
|
{ |
{ |
struct wm_softc *sc = ifp->if_softc; |
struct wm_softc *sc = ifp->if_softc; |
|
|
|
ASSERT_SLEEPABLE(); |
|
|
WM_CORE_LOCK(sc); |
WM_CORE_LOCK(sc); |
wm_stop_locked(ifp, disable); |
wm_stop_locked(ifp, disable ? true : false, true); |
WM_CORE_UNLOCK(sc); |
WM_CORE_UNLOCK(sc); |
|
|
/* |
/* |
Line 6420 wm_stop(struct ifnet *ifp, int disable) |
|
Line 6423 wm_stop(struct ifnet *ifp, int disable) |
|
} |
} |
|
|
static void |
static void |
wm_stop_locked(struct ifnet *ifp, int disable) |
wm_stop_locked(struct ifnet *ifp, bool disable, bool wait) |
{ |
{ |
struct wm_softc *sc = ifp->if_softc; |
struct wm_softc *sc = ifp->if_softc; |
struct wm_txsoft *txs; |
struct wm_txsoft *txs; |
Line 6432 wm_stop_locked(struct ifnet *ifp, int di |
|
Line 6435 wm_stop_locked(struct ifnet *ifp, int di |
|
|
|
wm_set_stopping_flags(sc); |
wm_set_stopping_flags(sc); |
|
|
/* Stop the one second clock. */ |
|
callout_stop(&sc->sc_tick_ch); |
|
|
|
/* Stop the 82547 Tx FIFO stall check timer. */ |
|
if (sc->sc_type == WM_T_82547) |
|
callout_stop(&sc->sc_txfifo_ch); |
|
|
|
if (sc->sc_flags & WM_F_HAS_MII) { |
if (sc->sc_flags & WM_F_HAS_MII) { |
/* Down the MII. */ |
/* Down the MII. */ |
mii_down(&sc->sc_mii); |
mii_down(&sc->sc_mii); |
Line 6470 wm_stop_locked(struct ifnet *ifp, int di |
|
Line 6466 wm_stop_locked(struct ifnet *ifp, int di |
|
CSR_WRITE(sc, WMREG_EIAC_82574, 0); |
CSR_WRITE(sc, WMREG_EIAC_82574, 0); |
} |
} |
|
|
|
/* |
|
* Stop callouts after interrupts are disabled; if we have |
|
* to wait for them, we will be releasing the CORE_LOCK |
|
* briefly, which will unblock interrupts on the current CPU. |
|
*/ |
|
|
|
/* Stop the one second clock. */ |
|
if (wait) |
|
callout_halt(&sc->sc_tick_ch, sc->sc_core_lock); |
|
else |
|
callout_stop(&sc->sc_tick_ch); |
|
|
|
/* Stop the 82547 Tx FIFO stall check timer. */ |
|
if (sc->sc_type == WM_T_82547) { |
|
if (wait) |
|
callout_halt(&sc->sc_txfifo_ch, sc->sc_core_lock); |
|
else |
|
callout_stop(&sc->sc_txfifo_ch); |
|
} |
|
|
/* Release any queued transmit buffers. */ |
/* Release any queued transmit buffers. */ |
for (qidx = 0; qidx < sc->sc_nqueues; qidx++) { |
for (qidx = 0; qidx < sc->sc_nqueues; qidx++) { |
struct wm_queue *wmq = &sc->sc_queue[qidx]; |
struct wm_queue *wmq = &sc->sc_queue[qidx]; |
Line 10423 wm_gmii_mediainit(struct wm_softc *sc, p |
|
Line 10439 wm_gmii_mediainit(struct wm_softc *sc, p |
|
wm_gmii_reset(sc); |
wm_gmii_reset(sc); |
|
|
sc->sc_ethercom.ec_mii = &sc->sc_mii; |
sc->sc_ethercom.ec_mii = &sc->sc_mii; |
ifmedia_init(&mii->mii_media, IFM_IMASK, wm_gmii_mediachange, |
ifmedia_init_with_lock(&mii->mii_media, IFM_IMASK, wm_gmii_mediachange, |
wm_gmii_mediastatus); |
wm_gmii_mediastatus, sc->sc_core_lock); |
|
|
if ((sc->sc_type == WM_T_82575) || (sc->sc_type == WM_T_82576) |
if ((sc->sc_type == WM_T_82575) || (sc->sc_type == WM_T_82576) |
|| (sc->sc_type == WM_T_82580) |
|| (sc->sc_type == WM_T_82580) |
Line 11970 wm_tbi_mediainit(struct wm_softc *sc) |
|
Line 11986 wm_tbi_mediainit(struct wm_softc *sc) |
|
sc->sc_ethercom.ec_mii = &sc->sc_mii; |
sc->sc_ethercom.ec_mii = &sc->sc_mii; |
|
|
if (((sc->sc_type >= WM_T_82575) && (sc->sc_type <= WM_T_I211)) |
if (((sc->sc_type >= WM_T_82575) && (sc->sc_type <= WM_T_I211)) |
&& (sc->sc_mediatype == WM_MEDIATYPE_SERDES)) |
&& (sc->sc_mediatype == WM_MEDIATYPE_SERDES)) { |
ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, |
ifmedia_init_with_lock(&sc->sc_mii.mii_media, IFM_IMASK, |
wm_serdes_mediachange, wm_serdes_mediastatus); |
wm_serdes_mediachange, wm_serdes_mediastatus, |
else |
sc->sc_core_lock); |
ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, |
} else { |
wm_tbi_mediachange, wm_tbi_mediastatus); |
ifmedia_init_with_lock(&sc->sc_mii.mii_media, IFM_IMASK, |
|
wm_tbi_mediachange, wm_tbi_mediastatus, sc->sc_core_lock); |
|
} |
|
|
/* |
/* |
* SWD Pins: |
* SWD Pins: |