- Use callout_init_mtx() instead of callout_init(..., CALLOUT_MPSAFE).
- Add a missing callout_drain() to detach. - Hook into the stats timer and use that to drive the transmit watchdog instead of using if_watchdog. - Run the stats timer every second to match other drivers instead of every other second. - Remove dubious callout handling that stopped the timer only to start it again while holding the driver lock without dropping it in between the stop and the start.
This commit is contained in:
parent
4ba3c79b59
commit
00a2480413
@ -97,7 +97,7 @@ static void ixgb_intr(void *);
|
||||
static void ixgb_start(struct ifnet *);
|
||||
static void ixgb_start_locked(struct ifnet *);
|
||||
static int ixgb_ioctl(struct ifnet *, IOCTL_CMD_TYPE, caddr_t);
|
||||
static void ixgb_watchdog(struct ifnet *);
|
||||
static void ixgb_watchdog(struct adapter *);
|
||||
static void ixgb_init(void *);
|
||||
static void ixgb_init_locked(struct adapter *);
|
||||
static void ixgb_stop(void *);
|
||||
@ -274,7 +274,7 @@ ixgb_attach(device_t dev)
|
||||
(void *)adapter, 0,
|
||||
ixgb_sysctl_stats, "I", "Statistics");
|
||||
|
||||
callout_init(&adapter->timer, CALLOUT_MPSAFE);
|
||||
callout_init_mtx(&adapter->timer, &adapter->mtx, 0);
|
||||
|
||||
/* Determine hardware revision */
|
||||
ixgb_identify_hardware(adapter);
|
||||
@ -382,13 +382,14 @@ ixgb_detach(device_t dev)
|
||||
IXGB_UNLOCK(adapter);
|
||||
|
||||
#if __FreeBSD_version < 500000
|
||||
ether_ifdetach(adapter->ifp, ETHER_BPF_SUPPORTED);
|
||||
ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);
|
||||
#else
|
||||
ether_ifdetach(adapter->ifp);
|
||||
ether_ifdetach(ifp);
|
||||
#endif
|
||||
callout_drain(&adapter->timer);
|
||||
ixgb_free_pci_resources(adapter);
|
||||
#if __FreeBSD_version >= 500000
|
||||
if_free(adapter->ifp);
|
||||
if_free(ifp);
|
||||
#endif
|
||||
|
||||
/* Free Transmit Descriptor ring */
|
||||
@ -409,9 +410,6 @@ ixgb_detach(device_t dev)
|
||||
if (adapter->prev != NULL)
|
||||
adapter->prev->next = adapter->next;
|
||||
|
||||
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
|
||||
ifp->if_timer = 0;
|
||||
|
||||
IXGB_LOCK_DESTROY(adapter);
|
||||
return (0);
|
||||
}
|
||||
@ -473,7 +471,7 @@ ixgb_start_locked(struct ifnet * ifp)
|
||||
ETHER_BPF_MTAP(ifp, m_head);
|
||||
#endif
|
||||
/* Set timeout in case hardware has problems transmitting */
|
||||
ifp->if_timer = IXGB_TX_TIMEOUT;
|
||||
adapter->tx_timer = IXGB_TX_TIMEOUT;
|
||||
|
||||
}
|
||||
return;
|
||||
@ -610,26 +608,24 @@ ixgb_ioctl(struct ifnet * ifp, IOCTL_CMD_TYPE command, caddr_t data)
|
||||
**********************************************************************/
|
||||
|
||||
static void
|
||||
ixgb_watchdog(struct ifnet * ifp)
|
||||
ixgb_watchdog(struct adapter *adapter)
|
||||
{
|
||||
struct adapter *adapter;
|
||||
adapter = ifp->if_softc;
|
||||
struct ifnet *ifp;
|
||||
|
||||
ifp = adapter->ifp;
|
||||
|
||||
/*
|
||||
* If we are in this routine because of pause frames, then don't
|
||||
* reset the hardware.
|
||||
*/
|
||||
if (IXGB_READ_REG(&adapter->hw, STATUS) & IXGB_STATUS_TXOFF) {
|
||||
ifp->if_timer = IXGB_TX_TIMEOUT;
|
||||
adapter->tx_timer = IXGB_TX_TIMEOUT;
|
||||
return;
|
||||
}
|
||||
if_printf(ifp, "watchdog timeout -- resetting\n");
|
||||
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
|
||||
|
||||
ixgb_stop(adapter);
|
||||
ixgb_init(adapter);
|
||||
ixgb_init_locked(adapter);
|
||||
|
||||
|
||||
ifp->if_oerrors++;
|
||||
@ -713,7 +709,7 @@ ixgb_init_locked(struct adapter *adapter)
|
||||
temp_reg |= IXGB_CTRL0_JFE;
|
||||
IXGB_WRITE_REG(&adapter->hw, CTRL0, temp_reg);
|
||||
}
|
||||
callout_reset(&adapter->timer, 2 * hz, ixgb_local_timer, adapter);
|
||||
callout_reset(&adapter->timer, hz, ixgb_local_timer, adapter);
|
||||
ixgb_clear_hw_cntrs(&adapter->hw);
|
||||
#ifdef DEVICE_POLLING
|
||||
/*
|
||||
@ -753,11 +749,8 @@ ixgb_poll_locked(struct ifnet * ifp, enum poll_cmd cmd, int count)
|
||||
if (cmd == POLL_AND_CHECK_STATUS) {
|
||||
reg_icr = IXGB_READ_REG(&adapter->hw, ICR);
|
||||
if (reg_icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC)) {
|
||||
callout_stop(&adapter->timer);
|
||||
ixgb_check_for_link(&adapter->hw);
|
||||
ixgb_print_link_status(adapter);
|
||||
callout_reset(&adapter->timer, 2 * hz, ixgb_local_timer,
|
||||
adapter);
|
||||
}
|
||||
}
|
||||
rx_npkts = ixgb_process_receive_interrupts(adapter, count);
|
||||
@ -830,11 +823,8 @@ ixgb_intr(void *arg)
|
||||
|
||||
/* Link status change */
|
||||
if (reg_icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC)) {
|
||||
callout_stop(&adapter->timer);
|
||||
ixgb_check_for_link(&adapter->hw);
|
||||
ixgb_print_link_status(adapter);
|
||||
callout_reset(&adapter->timer, 2 * hz, ixgb_local_timer,
|
||||
adapter);
|
||||
}
|
||||
while (loop_cnt > 0) {
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
|
||||
@ -1123,7 +1113,7 @@ ixgb_local_timer(void *arg)
|
||||
struct adapter *adapter = arg;
|
||||
ifp = adapter->ifp;
|
||||
|
||||
IXGB_LOCK(adapter);
|
||||
IXGB_LOCK_ASSERT(adapter);
|
||||
|
||||
ixgb_check_for_link(&adapter->hw);
|
||||
ixgb_print_link_status(adapter);
|
||||
@ -1131,10 +1121,9 @@ ixgb_local_timer(void *arg)
|
||||
if (ixgb_display_debug_stats && ifp->if_drv_flags & IFF_DRV_RUNNING) {
|
||||
ixgb_print_hw_stats(adapter);
|
||||
}
|
||||
callout_reset(&adapter->timer, 2 * hz, ixgb_local_timer, adapter);
|
||||
|
||||
IXGB_UNLOCK(adapter);
|
||||
return;
|
||||
if (adapter->tx_timer != 0 && --adapter->tx_timer == 0)
|
||||
ixgb_watchdog(adapter);
|
||||
callout_reset(&adapter->timer, hz, ixgb_local_timer, adapter);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1183,9 +1172,9 @@ ixgb_stop(void *arg)
|
||||
ixgb_free_transmit_structures(adapter);
|
||||
ixgb_free_receive_structures(adapter);
|
||||
|
||||
|
||||
/* Tell the stack that the interface is no longer active */
|
||||
ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
|
||||
adapter->tx_timer = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1352,7 +1341,6 @@ ixgb_setup_interface(device_t dev, struct adapter * adapter)
|
||||
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
|
||||
ifp->if_ioctl = ixgb_ioctl;
|
||||
ifp->if_start = ixgb_start;
|
||||
ifp->if_watchdog = ixgb_watchdog;
|
||||
ifp->if_snd.ifq_maxlen = adapter->num_tx_desc - 1;
|
||||
|
||||
#if __FreeBSD_version < 500000
|
||||
@ -1755,9 +1743,9 @@ ixgb_clean_transmit_interrupts(struct adapter * adapter)
|
||||
|
||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
||||
if (num_avail == adapter->num_tx_desc)
|
||||
ifp->if_timer = 0;
|
||||
adapter->tx_timer = 0;
|
||||
else if (num_avail == adapter->num_tx_desc_avail)
|
||||
ifp->if_timer = IXGB_TX_TIMEOUT;
|
||||
adapter->tx_timer = IXGB_TX_TIMEOUT;
|
||||
}
|
||||
adapter->num_tx_desc_avail = num_avail;
|
||||
return;
|
||||
|
@ -284,6 +284,7 @@ struct adapter {
|
||||
struct ifmedia media;
|
||||
struct callout timer;
|
||||
int io_rid;
|
||||
int tx_timer;
|
||||
struct mtx mtx;
|
||||
|
||||
/* Info about the board itself */
|
||||
|
Loading…
Reference in New Issue
Block a user