FreeBSD/sys/dev/e1000/if_em.c
/*********************************************************************
 *  Timer routine
 *
 *  This routine checks for link status and updates statistics.
 *
 **********************************************************************/
Timer routine
This routine checks for link status and updates statistics.
Timer routine This routine checks for link status and updates statistics .
static void
em_local_timer(void *arg)
{
	struct adapter	*adapter = arg;
	if_t ifp = adapter->ifp;
	struct tx_ring	*txr = adapter->tx_rings;
	struct rx_ring	*rxr = adapter->rx_rings;
	u32		trigger = 0;
	EM_CORE_LOCK_ASSERT(adapter);
	em_update_link_status(adapter);
	em_update_stats_counters(adapter);
	if ((adapter->hw.mac.type == e1000_82571) &&
	    e1000_get_laa_state_82571(&adapter->hw))
		e1000_rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
	if (adapter->msix_mem) {
		for (int i = 0; i < adapter->num_queues; i++, rxr++)
			trigger |= rxr->ims;
		rxr = adapter->rx_rings;
	} else
		trigger = E1000_ICS_RXDMT0;
	for (int i = 0; i < adapter->num_queues; i++, txr++) {
		if (txr->busy == EM_TX_HUNG)
			goto hung;
		if (txr->busy >= EM_TX_MAXTRIES)
			txr->busy = EM_TX_HUNG;
		if (txr->tx_avail <= EM_MAX_SCATTER)
			taskqueue_enqueue(txr->tq, &txr->tx_task);
	}
	callout_reset(&adapter->timer, hz, em_local_timer, adapter);
#ifndef DEVICE_POLLING
	E1000_WRITE_REG(&adapter->hw, E1000_ICS, trigger);
#endif
	return;
hung:
	device_printf(adapter->dev, "Watchdog timeout Queue[%d]-- resetting\n",
			txr->me);
	em_print_debug_info(adapter);
	if_setdrvflagbits(ifp, 0, IFF_DRV_RUNNING);
	adapter->watchdog_events++;
	em_init_locked(adapter);
}
static void em_local_timer ( void * arg ) { struct adapter * adapter = arg ; if_t ifp = adapter -> ifp ; struct tx_ring * txr = adapter -> tx_rings ; struct rx_ring * rxr = adapter -> rx_rings ; u32 trigger = 0 ; EM_CORE_LOCK_ASSERT ( adapter ) ; em_update_link_status ( adapter ) ; em_update_stats_counters ( adapter ) ; if ( ( adapter -> hw . mac . type == e1000_82571 ) && e1000_get_laa_state_82571 ( & adapter -> hw ) ) e1000_rar_set ( & adapter -> hw , adapter -> hw . mac . addr , 0 ) ; if ( adapter -> msix_mem ) { for ( int i = 0 ; i < adapter -> num_queues ; i ++ , rxr ++ ) trigger |= rxr -> ims ; rxr = adapter -> rx_rings ; } else trigger = E1000_ICS_RXDMT0 ; for ( int i = 0 ; i < adapter -> num_queues ; i ++ , txr ++ ) { if ( txr -> busy == EM_TX_HUNG ) goto hung ; if ( txr -> busy >= EM_TX_MAXTRIES ) txr -> busy = EM_TX_HUNG ; if ( txr -> tx_avail <= EM_MAX_SCATTER ) taskqueue_enqueue ( txr -> tq , & txr -> tx_task ) ; } callout_reset ( & adapter -> timer , hz , em_local_timer , adapter ) ; #ifndef DEVICE_POLLING E1000_WRITE_REG ( & adapter -> hw , E1000_ICS , trigger ) ; #endif return ; hung : device_printf ( adapter -> dev , " \n " , txr -> me ) ; em_print_debug_info ( adapter ) ; if_setdrvflagbits ( ifp , 0 , IFF_DRV_RUNNING ) ; adapter -> watchdog_events ++ ; em_init_locked ( adapter ) ; }
Timer routine
  This routine checks for link status and updates statistics.
Timer routine This routine checks for link status and updates statistics .
/* Reset LAA into RAR[0] on 82571 */ /* Mask to use in the irq trigger */ /*
	** Check on the state of the TX queue(s), this 
	** can be done without the lock because its RO
	** and the HUNG state will be static if set.
	*/ /* Schedule a TX tasklet if needed */ /* Trigger an RX interrupt to guarantee mbuf refresh */ /* Looks like we're hung */