aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/ixgb
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2009-11-19 18:37:55 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2009-11-19 18:37:55 +0000
commit770c8c790f8c66c12860dc3b4ccb01a045205023 (patch)
tree7e7a57abe694b590735dd900170a9b74407c5192 /sys/dev/ixgb
parent73e7361eac26b60fde75b5746e5395ffe7580da6 (diff)
downloadsrc-770c8c790f8c66c12860dc3b4ccb01a045205023.tar.gz
src-770c8c790f8c66c12860dc3b4ccb01a045205023.zip
- 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.
Notes
Notes: svn path=/head/; revision=199539
Diffstat (limited to 'sys/dev/ixgb')
-rw-r--r--sys/dev/ixgb/if_ixgb.c54
-rw-r--r--sys/dev/ixgb/if_ixgb.h1
2 files changed, 22 insertions, 33 deletions
diff --git a/sys/dev/ixgb/if_ixgb.c b/sys/dev/ixgb/if_ixgb.c
index 21d0bf02aa03..990f791dfbd6 100644
--- a/sys/dev/ixgb/if_ixgb.c
+++ b/sys/dev/ixgb/if_ixgb.c
@@ -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 @@ out:
**********************************************************************/
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;
diff --git a/sys/dev/ixgb/if_ixgb.h b/sys/dev/ixgb/if_ixgb.h
index cef9b55e08c1..9e5355a25dd7 100644
--- a/sys/dev/ixgb/if_ixgb.h
+++ b/sys/dev/ixgb/if_ixgb.h
@@ -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 */