diff options
Diffstat (limited to 'drivers/net/netxen/netxen_nic_main.c')
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 121 |
1 files changed, 120 insertions, 1 deletions
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 4d32f3cc2fbd..2d0963f4d194 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -904,7 +904,7 @@ request_msi: | |||
904 | goto err_out_disable_msi; | 904 | goto err_out_disable_msi; |
905 | 905 | ||
906 | init_timer(&adapter->watchdog_timer); | 906 | init_timer(&adapter->watchdog_timer); |
907 | adapter->ahw.xg_linkup = 0; | 907 | adapter->ahw.linkup = 0; |
908 | adapter->watchdog_timer.function = &netxen_watchdog; | 908 | adapter->watchdog_timer.function = &netxen_watchdog; |
909 | adapter->watchdog_timer.data = (unsigned long)adapter; | 909 | adapter->watchdog_timer.data = (unsigned long)adapter; |
910 | INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); | 910 | INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); |
@@ -1335,6 +1335,80 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1335 | return NETDEV_TX_OK; | 1335 | return NETDEV_TX_OK; |
1336 | } | 1336 | } |
1337 | 1337 | ||
1338 | static int netxen_nic_check_temp(struct netxen_adapter *adapter) | ||
1339 | { | ||
1340 | struct net_device *netdev = adapter->netdev; | ||
1341 | uint32_t temp, temp_state, temp_val; | ||
1342 | int rv = 0; | ||
1343 | |||
1344 | temp = adapter->pci_read_normalize(adapter, CRB_TEMP_STATE); | ||
1345 | |||
1346 | temp_state = nx_get_temp_state(temp); | ||
1347 | temp_val = nx_get_temp_val(temp); | ||
1348 | |||
1349 | if (temp_state == NX_TEMP_PANIC) { | ||
1350 | printk(KERN_ALERT | ||
1351 | "%s: Device temperature %d degrees C exceeds" | ||
1352 | " maximum allowed. Hardware has been shut down.\n", | ||
1353 | netxen_nic_driver_name, temp_val); | ||
1354 | |||
1355 | netif_carrier_off(netdev); | ||
1356 | netif_stop_queue(netdev); | ||
1357 | rv = 1; | ||
1358 | } else if (temp_state == NX_TEMP_WARN) { | ||
1359 | if (adapter->temp == NX_TEMP_NORMAL) { | ||
1360 | printk(KERN_ALERT | ||
1361 | "%s: Device temperature %d degrees C " | ||
1362 | "exceeds operating range." | ||
1363 | " Immediate action needed.\n", | ||
1364 | netxen_nic_driver_name, temp_val); | ||
1365 | } | ||
1366 | } else { | ||
1367 | if (adapter->temp == NX_TEMP_WARN) { | ||
1368 | printk(KERN_INFO | ||
1369 | "%s: Device temperature is now %d degrees C" | ||
1370 | " in normal range.\n", netxen_nic_driver_name, | ||
1371 | temp_val); | ||
1372 | } | ||
1373 | } | ||
1374 | adapter->temp = temp_state; | ||
1375 | return rv; | ||
1376 | } | ||
1377 | |||
1378 | static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter) | ||
1379 | { | ||
1380 | struct net_device *netdev = adapter->netdev; | ||
1381 | u32 val, port, linkup; | ||
1382 | |||
1383 | port = adapter->physical_port; | ||
1384 | |||
1385 | val = adapter->pci_read_normalize(adapter, CRB_XG_STATE); | ||
1386 | if (adapter->ahw.board_type == NETXEN_NIC_GBE) | ||
1387 | linkup = (val >> port) & 1; | ||
1388 | else { | ||
1389 | val = (val >> port*8) & 0xff; | ||
1390 | linkup = (val == XG_LINK_UP); | ||
1391 | } | ||
1392 | |||
1393 | if (adapter->ahw.linkup && !linkup) { | ||
1394 | printk(KERN_INFO "%s: %s NIC Link is down\n", | ||
1395 | netxen_nic_driver_name, netdev->name); | ||
1396 | adapter->ahw.linkup = 0; | ||
1397 | if (netif_running(netdev)) { | ||
1398 | netif_carrier_off(netdev); | ||
1399 | netif_stop_queue(netdev); | ||
1400 | } | ||
1401 | } else if (!adapter->ahw.linkup && linkup) { | ||
1402 | printk(KERN_INFO "%s: %s NIC Link is up\n", | ||
1403 | netxen_nic_driver_name, netdev->name); | ||
1404 | adapter->ahw.linkup = 1; | ||
1405 | if (netif_running(netdev)) { | ||
1406 | netif_carrier_on(netdev); | ||
1407 | netif_wake_queue(netdev); | ||
1408 | } | ||
1409 | } | ||
1410 | } | ||
1411 | |||
1338 | static void netxen_watchdog(unsigned long v) | 1412 | static void netxen_watchdog(unsigned long v) |
1339 | { | 1413 | { |
1340 | struct netxen_adapter *adapter = (struct netxen_adapter *)v; | 1414 | struct netxen_adapter *adapter = (struct netxen_adapter *)v; |
@@ -1342,6 +1416,19 @@ static void netxen_watchdog(unsigned long v) | |||
1342 | SCHEDULE_WORK(&adapter->watchdog_task); | 1416 | SCHEDULE_WORK(&adapter->watchdog_task); |
1343 | } | 1417 | } |
1344 | 1418 | ||
1419 | void netxen_watchdog_task(struct work_struct *work) | ||
1420 | { | ||
1421 | struct netxen_adapter *adapter = | ||
1422 | container_of(work, struct netxen_adapter, watchdog_task); | ||
1423 | |||
1424 | if ((adapter->portnum == 0) && netxen_nic_check_temp(adapter)) | ||
1425 | return; | ||
1426 | |||
1427 | netxen_nic_handle_phy_intr(adapter); | ||
1428 | |||
1429 | mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); | ||
1430 | } | ||
1431 | |||
1345 | static void netxen_tx_timeout(struct net_device *netdev) | 1432 | static void netxen_tx_timeout(struct net_device *netdev) |
1346 | { | 1433 | { |
1347 | struct netxen_adapter *adapter = (struct netxen_adapter *) | 1434 | struct netxen_adapter *adapter = (struct netxen_adapter *) |
@@ -1367,6 +1454,38 @@ static void netxen_tx_timeout_task(struct work_struct *work) | |||
1367 | netif_wake_queue(adapter->netdev); | 1454 | netif_wake_queue(adapter->netdev); |
1368 | } | 1455 | } |
1369 | 1456 | ||
1457 | /* | ||
1458 | * netxen_nic_get_stats - Get System Network Statistics | ||
1459 | * @netdev: network interface device structure | ||
1460 | */ | ||
1461 | struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) | ||
1462 | { | ||
1463 | struct netxen_adapter *adapter = netdev_priv(netdev); | ||
1464 | struct net_device_stats *stats = &adapter->net_stats; | ||
1465 | |||
1466 | memset(stats, 0, sizeof(*stats)); | ||
1467 | |||
1468 | /* total packets received */ | ||
1469 | stats->rx_packets = adapter->stats.no_rcv; | ||
1470 | /* total packets transmitted */ | ||
1471 | stats->tx_packets = adapter->stats.xmitedframes + | ||
1472 | adapter->stats.xmitfinished; | ||
1473 | /* total bytes received */ | ||
1474 | stats->rx_bytes = adapter->stats.rxbytes; | ||
1475 | /* total bytes transmitted */ | ||
1476 | stats->tx_bytes = adapter->stats.txbytes; | ||
1477 | /* bad packets received */ | ||
1478 | stats->rx_errors = adapter->stats.rcvdbadskb; | ||
1479 | /* packet transmit problems */ | ||
1480 | stats->tx_errors = adapter->stats.nocmddescriptor; | ||
1481 | /* no space in linux buffers */ | ||
1482 | stats->rx_dropped = adapter->stats.rxdropped; | ||
1483 | /* no space available in linux */ | ||
1484 | stats->tx_dropped = adapter->stats.txdropped; | ||
1485 | |||
1486 | return stats; | ||
1487 | } | ||
1488 | |||
1370 | static inline void | 1489 | static inline void |
1371 | netxen_handle_int(struct netxen_adapter *adapter) | 1490 | netxen_handle_int(struct netxen_adapter *adapter) |
1372 | { | 1491 | { |