mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-06 09:17:25 +00:00
- Hook into the existing stat timer to drive the transmit watchdog instead
of using if_watchdog and if_timer. - Reorder detach to call ether_ifdetach() before anything else in tl(4) and wb(4).
This commit is contained in:
parent
7cf545d0a1
commit
e55bc0154d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=199560
@ -137,7 +137,7 @@ static int lge_ioctl(struct ifnet *, u_long, caddr_t);
|
||||
static void lge_init(void *);
|
||||
static void lge_init_locked(struct lge_softc *);
|
||||
static void lge_stop(struct lge_softc *);
|
||||
static void lge_watchdog(struct ifnet *);
|
||||
static void lge_watchdog(struct lge_softc *);
|
||||
static int lge_shutdown(device_t);
|
||||
static int lge_ifmedia_upd(struct ifnet *);
|
||||
static void lge_ifmedia_upd_locked(struct ifnet *);
|
||||
@ -544,7 +544,6 @@ lge_attach(dev)
|
||||
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
|
||||
ifp->if_ioctl = lge_ioctl;
|
||||
ifp->if_start = lge_start;
|
||||
ifp->if_watchdog = lge_watchdog;
|
||||
ifp->if_init = lge_init;
|
||||
ifp->if_snd.ifq_maxlen = LGE_TX_LIST_CNT - 1;
|
||||
ifp->if_capabilities = IFCAP_RXCSUM;
|
||||
@ -1000,7 +999,7 @@ lge_txeof(sc)
|
||||
ifp = sc->lge_ifp;
|
||||
|
||||
/* Clear the timeout timer. */
|
||||
ifp->if_timer = 0;
|
||||
sc->lge_timer = 0;
|
||||
|
||||
/*
|
||||
* Go through our tx list and free mbufs for those
|
||||
@ -1021,7 +1020,7 @@ lge_txeof(sc)
|
||||
|
||||
txdone--;
|
||||
LGE_INC(idx, LGE_TX_LIST_CNT);
|
||||
ifp->if_timer = 0;
|
||||
sc->lge_timer = 0;
|
||||
}
|
||||
|
||||
sc->lge_cdata.lge_tx_cons = idx;
|
||||
@ -1064,6 +1063,8 @@ lge_tick(xsc)
|
||||
}
|
||||
}
|
||||
|
||||
if (sc->lge_timer != 0 && --sc->lge_timer == 0)
|
||||
lge_watchdog(sc);
|
||||
callout_reset(&sc->lge_stat_callout, hz, lge_tick, sc);
|
||||
|
||||
return;
|
||||
@ -1236,7 +1237,7 @@ lge_start_locked(ifp)
|
||||
/*
|
||||
* Set a timeout in case the chip goes out to lunch.
|
||||
*/
|
||||
ifp->if_timer = 5;
|
||||
sc->lge_timer = 5;
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1506,14 +1507,14 @@ lge_ioctl(ifp, command, data)
|
||||
}
|
||||
|
||||
static void
|
||||
lge_watchdog(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
lge_watchdog(sc)
|
||||
struct lge_softc *sc;
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
|
||||
sc = ifp->if_softc;
|
||||
LGE_LOCK_ASSERT(sc);
|
||||
ifp = sc->lge_ifp;
|
||||
|
||||
LGE_LOCK(sc);
|
||||
ifp->if_oerrors++;
|
||||
if_printf(ifp, "watchdog timeout\n");
|
||||
|
||||
@ -1524,9 +1525,6 @@ lge_watchdog(ifp)
|
||||
|
||||
if (ifp->if_snd.ifq_head != NULL)
|
||||
lge_start_locked(ifp);
|
||||
LGE_UNLOCK(sc);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1542,7 +1540,7 @@ lge_stop(sc)
|
||||
|
||||
LGE_LOCK_ASSERT(sc);
|
||||
ifp = sc->lge_ifp;
|
||||
ifp->if_timer = 0;
|
||||
sc->lge_timer = 0;
|
||||
callout_stop(&sc->lge_stat_callout);
|
||||
CSR_WRITE_4(sc, LGE_IMR, LGE_IMR_INTR_ENB);
|
||||
|
||||
|
@ -534,6 +534,7 @@ struct lge_softc {
|
||||
u_int8_t lge_link;
|
||||
u_int8_t lge_pcs;
|
||||
int lge_if_flags;
|
||||
int lge_timer;
|
||||
struct lge_list_data *lge_ldata;
|
||||
struct lge_ring_data lge_cdata;
|
||||
struct callout lge_stat_callout;
|
||||
|
@ -140,7 +140,7 @@ static int nve_ioctl(struct ifnet *, u_long, caddr_t);
|
||||
static void nve_intr(void *);
|
||||
static void nve_tick(void *);
|
||||
static void nve_setmulti(struct nve_softc *);
|
||||
static void nve_watchdog(struct ifnet *);
|
||||
static void nve_watchdog(struct nve_softc *);
|
||||
static void nve_update_stats(struct nve_softc *);
|
||||
|
||||
static int nve_ifmedia_upd(struct ifnet *);
|
||||
@ -540,8 +540,6 @@ nve_attach(device_t dev)
|
||||
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
|
||||
ifp->if_ioctl = nve_ioctl;
|
||||
ifp->if_start = nve_ifstart;
|
||||
ifp->if_watchdog = nve_watchdog;
|
||||
ifp->if_timer = 0;
|
||||
ifp->if_init = nve_init;
|
||||
ifp->if_mtu = ETHERMTU;
|
||||
ifp->if_baudrate = IF_Mbps(100);
|
||||
@ -709,7 +707,7 @@ nve_stop(struct nve_softc *sc)
|
||||
DEBUGOUT(NVE_DEBUG_RUNNING, "nve: nve_stop - entry\n");
|
||||
|
||||
ifp = sc->ifp;
|
||||
ifp->if_timer = 0;
|
||||
sc->tx_timer = 0;
|
||||
|
||||
/* Cancel tick timer */
|
||||
callout_stop(&sc->stat_callout);
|
||||
@ -983,7 +981,7 @@ nve_ifstart_locked(struct ifnet *ifp)
|
||||
return;
|
||||
}
|
||||
/* Set watchdog timer. */
|
||||
ifp->if_timer = 8;
|
||||
sc->tx_timer = 8;
|
||||
|
||||
/* Copy packet to BPF tap */
|
||||
BPF_MTAP(ifp, m0);
|
||||
@ -1095,7 +1093,7 @@ nve_intr(void *arg)
|
||||
|
||||
/* If no pending packets we don't need a timeout */
|
||||
if (sc->pending_txs == 0)
|
||||
sc->ifp->if_timer = 0;
|
||||
sc->tx_timer = 0;
|
||||
NVE_UNLOCK(sc);
|
||||
|
||||
DEBUGOUT(NVE_DEBUG_INTERRUPT, "nve: nve_intr - exit\n");
|
||||
@ -1236,6 +1234,9 @@ nve_tick(void *xsc)
|
||||
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
|
||||
nve_ifstart_locked(ifp);
|
||||
}
|
||||
|
||||
if (sc->tx_timer > 0 && --sc->tx_timer == 0)
|
||||
nve_watchdog(sc);
|
||||
callout_reset(&sc->stat_callout, hz, nve_tick, sc);
|
||||
|
||||
return;
|
||||
@ -1307,12 +1308,13 @@ nve_miibus_writereg(device_t dev, int phy, int reg, int data)
|
||||
|
||||
/* Watchdog timer to prevent PHY lockups */
|
||||
static void
|
||||
nve_watchdog(struct ifnet *ifp)
|
||||
nve_watchdog(struct nve_softc *sc)
|
||||
{
|
||||
struct nve_softc *sc = ifp->if_softc;
|
||||
struct ifnet *ifp;
|
||||
int pending_txs_start;
|
||||
|
||||
NVE_LOCK(sc);
|
||||
NVE_LOCK_ASSERT(sc);
|
||||
ifp = sc->ifp;
|
||||
|
||||
/*
|
||||
* The nvidia driver blob defers tx completion notifications.
|
||||
@ -1328,24 +1330,18 @@ nve_watchdog(struct ifnet *ifp)
|
||||
sc->hwapi->pfnDisableInterrupts(sc->hwapi->pADCX);
|
||||
sc->hwapi->pfnHandleInterrupt(sc->hwapi->pADCX);
|
||||
sc->hwapi->pfnEnableInterrupts(sc->hwapi->pADCX);
|
||||
if (sc->pending_txs < pending_txs_start) {
|
||||
NVE_UNLOCK(sc);
|
||||
if (sc->pending_txs < pending_txs_start)
|
||||
return;
|
||||
}
|
||||
|
||||
device_printf(sc->dev, "device timeout (%d)\n", sc->pending_txs);
|
||||
|
||||
sc->tx_errors++;
|
||||
|
||||
nve_stop(sc);
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
nve_init_locked(sc);
|
||||
|
||||
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
|
||||
nve_ifstart_locked(ifp);
|
||||
NVE_UNLOCK(sc);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* --- Start of NVOSAPI interface --- */
|
||||
|
@ -138,6 +138,7 @@ struct nve_softc {
|
||||
device_t miibus;
|
||||
device_t dev;
|
||||
struct callout stat_callout;
|
||||
int tx_timer;
|
||||
|
||||
void *sc_ih;
|
||||
bus_space_tag_t sc_st;
|
||||
|
@ -143,7 +143,7 @@ static int pcn_ioctl(struct ifnet *, u_long, caddr_t);
|
||||
static void pcn_init(void *);
|
||||
static void pcn_init_locked(struct pcn_softc *);
|
||||
static void pcn_stop(struct pcn_softc *);
|
||||
static void pcn_watchdog(struct ifnet *);
|
||||
static void pcn_watchdog(struct pcn_softc *);
|
||||
static int pcn_shutdown(device_t);
|
||||
static int pcn_ifmedia_upd(struct ifnet *);
|
||||
static void pcn_ifmedia_sts(struct ifnet *, struct ifmediareq *);
|
||||
@ -630,7 +630,6 @@ pcn_attach(dev)
|
||||
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
|
||||
ifp->if_ioctl = pcn_ioctl;
|
||||
ifp->if_start = pcn_start;
|
||||
ifp->if_watchdog = pcn_watchdog;
|
||||
ifp->if_init = pcn_init;
|
||||
ifp->if_snd.ifq_maxlen = PCN_TX_LIST_CNT - 1;
|
||||
|
||||
@ -948,7 +947,7 @@ pcn_txeof(sc)
|
||||
sc->pcn_cdata.pcn_tx_cons = idx;
|
||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
||||
}
|
||||
ifp->if_timer = (sc->pcn_cdata.pcn_tx_cnt == 0) ? 0 : 5;
|
||||
sc->pcn_timer = (sc->pcn_cdata.pcn_tx_cnt == 0) ? 0 : 5;
|
||||
|
||||
return;
|
||||
}
|
||||
@ -980,6 +979,8 @@ pcn_tick(xsc)
|
||||
pcn_start_locked(ifp);
|
||||
}
|
||||
|
||||
if (sc->pcn_timer > 0 && --sc->pcn_timer == 0)
|
||||
pcn_watchdog(sc);
|
||||
callout_reset(&sc->pcn_stat_callout, hz, pcn_tick, sc);
|
||||
|
||||
return;
|
||||
@ -1147,7 +1148,7 @@ pcn_start_locked(ifp)
|
||||
/*
|
||||
* Set a timeout in case the chip goes out to lunch.
|
||||
*/
|
||||
ifp->if_timer = 5;
|
||||
sc->pcn_timer = 5;
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1429,14 +1430,12 @@ pcn_ioctl(ifp, command, data)
|
||||
}
|
||||
|
||||
static void
|
||||
pcn_watchdog(ifp)
|
||||
struct ifnet *ifp;
|
||||
pcn_watchdog(struct pcn_softc *sc)
|
||||
{
|
||||
struct pcn_softc *sc;
|
||||
struct ifnet *ifp;
|
||||
|
||||
sc = ifp->if_softc;
|
||||
|
||||
PCN_LOCK(sc);
|
||||
PCN_LOCK_ASSERT(sc);
|
||||
ifp = sc->pcn_ifp;
|
||||
|
||||
ifp->if_oerrors++;
|
||||
if_printf(ifp, "watchdog timeout\n");
|
||||
@ -1447,10 +1446,6 @@ pcn_watchdog(ifp)
|
||||
|
||||
if (ifp->if_snd.ifq_head != NULL)
|
||||
pcn_start_locked(ifp);
|
||||
|
||||
PCN_UNLOCK(sc);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1465,7 +1460,7 @@ pcn_stop(struct pcn_softc *sc)
|
||||
|
||||
PCN_LOCK_ASSERT(sc);
|
||||
ifp = sc->pcn_ifp;
|
||||
ifp->if_timer = 0;
|
||||
sc->pcn_timer = 0;
|
||||
|
||||
callout_stop(&sc->pcn_stat_callout);
|
||||
|
||||
|
@ -465,6 +465,7 @@ struct pcn_softc {
|
||||
struct pcn_ring_data pcn_cdata;
|
||||
struct callout pcn_stat_callout;
|
||||
struct mtx pcn_mtx;
|
||||
int pcn_timer;
|
||||
};
|
||||
|
||||
#define PCN_LOCK(_sc) mtx_lock(&(_sc)->pcn_mtx)
|
||||
|
@ -281,7 +281,7 @@ static int tl_ioctl(struct ifnet *, u_long, caddr_t);
|
||||
static void tl_init(void *);
|
||||
static void tl_init_locked(struct tl_softc *);
|
||||
static void tl_stop(struct tl_softc *);
|
||||
static void tl_watchdog(struct ifnet *);
|
||||
static void tl_watchdog(struct tl_softc *);
|
||||
static int tl_shutdown(device_t);
|
||||
static int tl_ifmedia_upd(struct ifnet *);
|
||||
static void tl_ifmedia_sts(struct ifnet *, struct ifmediareq *);
|
||||
@ -1260,7 +1260,6 @@ tl_attach(dev)
|
||||
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
|
||||
ifp->if_ioctl = tl_ioctl;
|
||||
ifp->if_start = tl_start;
|
||||
ifp->if_watchdog = tl_watchdog;
|
||||
ifp->if_init = tl_init;
|
||||
ifp->if_mtu = ETHERMTU;
|
||||
ifp->if_snd.ifq_maxlen = TL_TX_LIST_CNT - 1;
|
||||
@ -1337,11 +1336,11 @@ tl_detach(dev)
|
||||
|
||||
/* These should only be active if attach succeeded */
|
||||
if (device_is_attached(dev)) {
|
||||
ether_ifdetach(ifp);
|
||||
TL_LOCK(sc);
|
||||
tl_stop(sc);
|
||||
TL_UNLOCK(sc);
|
||||
callout_drain(&sc->tl_stat_callout);
|
||||
ether_ifdetach(ifp);
|
||||
}
|
||||
if (sc->tl_miibus)
|
||||
device_delete_child(dev, sc->tl_miibus);
|
||||
@ -1635,7 +1634,7 @@ tl_intvec_txeoc(xsc, type)
|
||||
ifp = sc->tl_ifp;
|
||||
|
||||
/* Clear the timeout timer. */
|
||||
ifp->if_timer = 0;
|
||||
sc->tl_timer = 0;
|
||||
|
||||
if (sc->tl_cdata.tl_tx_head == NULL) {
|
||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
||||
@ -1821,6 +1820,9 @@ tl_stats_update(xsc)
|
||||
}
|
||||
}
|
||||
|
||||
if (sc->tl_timer > 0 && --sc->tl_timer == 0)
|
||||
tl_watchdog(sc);
|
||||
|
||||
callout_reset(&sc->tl_stat_callout, hz, tl_stats_update, sc);
|
||||
|
||||
if (!sc->tl_bitrate) {
|
||||
@ -2029,7 +2031,7 @@ tl_start_locked(ifp)
|
||||
/*
|
||||
* Set a timeout in case the chip goes out to lunch.
|
||||
*/
|
||||
ifp->if_timer = 5;
|
||||
sc->tl_timer = 5;
|
||||
|
||||
return;
|
||||
}
|
||||
@ -2254,21 +2256,20 @@ tl_ioctl(ifp, command, data)
|
||||
}
|
||||
|
||||
static void
|
||||
tl_watchdog(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
tl_watchdog(sc)
|
||||
struct tl_softc *sc;
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
|
||||
sc = ifp->if_softc;
|
||||
TL_LOCK_ASSERT(sc);
|
||||
ifp = sc->tl_ifp;
|
||||
|
||||
if_printf(ifp, "device timeout\n");
|
||||
|
||||
TL_LOCK(sc);
|
||||
ifp->if_oerrors++;
|
||||
|
||||
tl_softreset(sc, 1);
|
||||
tl_init_locked(sc);
|
||||
TL_UNLOCK(sc);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -125,6 +125,7 @@ struct tl_softc {
|
||||
int tl_if_flags;
|
||||
struct callout tl_stat_callout;
|
||||
struct mtx tl_mtx;
|
||||
int tl_timer;
|
||||
};
|
||||
|
||||
#define TL_LOCK(_sc) mtx_lock(&(_sc)->tl_mtx)
|
||||
|
@ -158,7 +158,7 @@ static int wb_ioctl(struct ifnet *, u_long, caddr_t);
|
||||
static void wb_init(void *);
|
||||
static void wb_init_locked(struct wb_softc *);
|
||||
static void wb_stop(struct wb_softc *);
|
||||
static void wb_watchdog(struct ifnet *);
|
||||
static void wb_watchdog(struct wb_softc *);
|
||||
static int wb_shutdown(device_t);
|
||||
static int wb_ifmedia_upd(struct ifnet *);
|
||||
static void wb_ifmedia_sts(struct ifnet *, struct ifmediareq *);
|
||||
@ -849,7 +849,6 @@ wb_attach(dev)
|
||||
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
|
||||
ifp->if_ioctl = wb_ioctl;
|
||||
ifp->if_start = wb_start;
|
||||
ifp->if_watchdog = wb_watchdog;
|
||||
ifp->if_init = wb_init;
|
||||
ifp->if_snd.ifq_maxlen = WB_TX_LIST_CNT - 1;
|
||||
|
||||
@ -907,11 +906,11 @@ wb_detach(dev)
|
||||
* This should only be done if attach succeeded.
|
||||
*/
|
||||
if (device_is_attached(dev)) {
|
||||
ether_ifdetach(ifp);
|
||||
WB_LOCK(sc);
|
||||
wb_stop(sc);
|
||||
WB_UNLOCK(sc);
|
||||
callout_drain(&sc->wb_stat_callout);
|
||||
ether_ifdetach(ifp);
|
||||
}
|
||||
if (sc->wb_miibus)
|
||||
device_delete_child(dev, sc->wb_miibus);
|
||||
@ -1157,7 +1156,7 @@ wb_txeof(sc)
|
||||
ifp = sc->wb_ifp;
|
||||
|
||||
/* Clear the timeout timer. */
|
||||
ifp->if_timer = 0;
|
||||
sc->wb_timer = 0;
|
||||
|
||||
if (sc->wb_cdata.wb_tx_head == NULL)
|
||||
return;
|
||||
@ -1212,7 +1211,7 @@ wb_txeoc(sc)
|
||||
|
||||
ifp = sc->wb_ifp;
|
||||
|
||||
ifp->if_timer = 0;
|
||||
sc->wb_timer = 0;
|
||||
|
||||
if (sc->wb_cdata.wb_tx_head == NULL) {
|
||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
||||
@ -1220,7 +1219,7 @@ wb_txeoc(sc)
|
||||
} else {
|
||||
if (WB_TXOWN(sc->wb_cdata.wb_tx_head) == WB_UNSENT) {
|
||||
WB_TXOWN(sc->wb_cdata.wb_tx_head) = WB_TXSTAT_OWN;
|
||||
ifp->if_timer = 5;
|
||||
sc->wb_timer = 5;
|
||||
CSR_WRITE_4(sc, WB_TXSTART, 0xFFFFFFFF);
|
||||
}
|
||||
}
|
||||
@ -1329,6 +1328,8 @@ wb_tick(xsc)
|
||||
|
||||
mii_tick(mii);
|
||||
|
||||
if (sc->wb_timer > 0 && --sc->wb_timer == 0)
|
||||
wb_watchdog(sc);
|
||||
callout_reset(&sc->wb_stat_callout, hz, wb_tick, sc);
|
||||
|
||||
return;
|
||||
@ -1529,7 +1530,7 @@ wb_start_locked(ifp)
|
||||
/*
|
||||
* Set a timeout in case the chip goes out to lunch.
|
||||
*/
|
||||
ifp->if_timer = 5;
|
||||
sc->wb_timer = 5;
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1748,14 +1749,13 @@ wb_ioctl(ifp, command, data)
|
||||
}
|
||||
|
||||
static void
|
||||
wb_watchdog(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
wb_watchdog(sc)
|
||||
struct wb_softc *sc;
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
|
||||
sc = ifp->if_softc;
|
||||
|
||||
WB_LOCK(sc);
|
||||
WB_LOCK_ASSERT(sc);
|
||||
ifp = sc->wb_ifp;
|
||||
ifp->if_oerrors++;
|
||||
if_printf(ifp, "watchdog timeout\n");
|
||||
#ifdef foo
|
||||
@ -1768,7 +1768,6 @@ wb_watchdog(ifp)
|
||||
|
||||
if (ifp->if_snd.ifq_head != NULL)
|
||||
wb_start_locked(ifp);
|
||||
WB_UNLOCK(sc);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1786,7 +1785,7 @@ wb_stop(sc)
|
||||
|
||||
WB_LOCK_ASSERT(sc);
|
||||
ifp = sc->wb_ifp;
|
||||
ifp->if_timer = 0;
|
||||
sc->wb_timer = 0;
|
||||
|
||||
callout_stop(&sc->wb_stat_callout);
|
||||
|
||||
|
@ -372,6 +372,7 @@ struct wb_softc {
|
||||
u_int8_t wb_type;
|
||||
u_int16_t wb_txthresh;
|
||||
int wb_cachesize;
|
||||
int wb_timer;
|
||||
caddr_t wb_ldata_ptr;
|
||||
struct wb_list_data *wb_ldata;
|
||||
struct wb_chain_data wb_cdata;
|
||||
|
Loading…
Reference in New Issue
Block a user