- 论坛徽章:
- 5
|
负载过大时,e1000_watchdog 反复 UP、DOWN 的问题
- static void
- e1000_watchdog(unsigned long data)
- {
- struct e1000_adapter *adapter = (struct e1000_adapter *) data;
- struct net_device *netdev = adapter->;netdev;
- struct e1000_desc_ring *txdr = &adapter->;tx_ring;
- unsigned int i;
- uint32_t link;
- e1000_check_for_link(&adapter->;hw);
- if((adapter->;hw.media_type == e1000_media_type_internal_serdes) &&
- !(E1000_READ_REG(&adapter->;hw, TXCW) & E1000_TXCW_ANE))
- link = !adapter->;hw.serdes_link_down;
- else
- link = E1000_READ_REG(&adapter->;hw, STATUS) & E1000_STATUS_LU;
- if(link) {
- if(!netif_carrier_ok(netdev)) {
- e1000_get_speed_and_duplex(&adapter->;hw,
- &adapter->;link_speed,
- &adapter->;link_duplex);
- DPRINTK(LINK, INFO, "NIC Link is Up %d Mbps %s\n",
- adapter->;link_speed,
- adapter->;link_duplex == FULL_DUPLEX ?
- "Full Duplex" : "Half Duplex");
- netif_carrier_on(netdev);
- netif_wake_queue(netdev);
- mod_timer(&adapter->;phy_info_timer, jiffies + 2 * HZ);
- adapter->;smartspeed = 0;
- }
- } else {
- if(netif_carrier_ok(netdev)) {
- adapter->;link_speed = 0;
- adapter->;link_duplex = 0;
- DPRINTK(LINK, INFO, "NIC Link is Down\n");
- netif_carrier_off(netdev);
- netif_stop_queue(netdev);
- mod_timer(&adapter->;phy_info_timer, jiffies + 2 * HZ);
- }
- e1000_smartspeed(adapter);
- }
- e1000_update_stats(adapter);
- adapter->;hw.tx_packet_delta = adapter->;stats.tpt - adapter->;tpt_old;
- adapter->;tpt_old = adapter->;stats.tpt;
- adapter->;hw.collision_delta = adapter->;stats.colc - adapter->;colc_old;
- adapter->;colc_old = adapter->;stats.colc;
-
- adapter->;gorcl = adapter->;stats.gorcl - adapter->;gorcl_old;
- adapter->;gorcl_old = adapter->;stats.gorcl;
- adapter->;gotcl = adapter->;stats.gotcl - adapter->;gotcl_old;
- adapter->;gotcl_old = adapter->;stats.gotcl;
- e1000_update_adaptive(&adapter->;hw);
- if(!netif_carrier_ok(netdev)) {
- if(E1000_DESC_UNUSED(txdr) + 1 < txdr->;count) {
- /* We've lost link, so the controller stops DMA,
- * but we've got queued Tx work that's never going
- * to get done, so reset controller to flush Tx.
- * (Do the reset outside of interrupt context). */
- schedule_work(&adapter->;tx_timeout_task);
- }
- }
- /* Dynamic mode for Interrupt Throttle Rate (ITR) */
- if(adapter->;hw.mac_type >;= e1000_82540 && adapter->;itr == 1) {
- /* Symmetric Tx/Rx gets a reduced ITR=2000; Total
- * asymmetrical Tx or Rx gets ITR=8000; everyone
- * else is between 2000-8000. */
- uint32_t goc = (adapter->;gotcl + adapter->;gorcl) / 10000;
- uint32_t dif = (adapter->;gotcl >; adapter->;gorcl ?
- adapter->;gotcl - adapter->;gorcl :
- adapter->;gorcl - adapter->;gotcl) / 10000;
- uint32_t itr = goc >; 0 ? (dif * 6000 / goc + 2000) : 8000;
- E1000_WRITE_REG(&adapter->;hw, ITR, 1000000000 / (itr * 256));
- }
- /* Cause software interrupt to ensure rx ring is cleaned */
- E1000_WRITE_REG(&adapter->;hw, ICS, E1000_ICS_RXDMT0);
- /* Early detection of hung controller */
- i = txdr->;next_to_clean;
- if(txdr->;buffer_info[i].dma &&
- time_after(jiffies, txdr->;buffer_info[i].time_stamp + HZ) &&
- !(E1000_READ_REG(&adapter->;hw, STATUS) & E1000_STATUS_TXOFF))
- netif_stop_queue(netdev);
- /* Reset the timer */
- mod_timer(&adapter->;watchdog_timer, jiffies + 2 * HZ);
- }
复制代码
[ 本帖最后由 platinum 于 2005-11-3 14:24 编辑 ] |
|