diff options
Diffstat (limited to 'drivers/net/e1000/e1000_ethtool.c')
-rw-r--r-- | drivers/net/e1000/e1000_ethtool.c | 105 |
1 files changed, 69 insertions, 36 deletions
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index 0a2ca7c73a41..237247f74df4 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | 3 | ||
4 | Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. | 4 | Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms of the GNU General Public License as published by the Free | 7 | under the terms of the GNU General Public License as published by the Free |
@@ -69,6 +69,7 @@ static const struct e1000_stats e1000_gstrings_stats[] = { | |||
69 | { "rx_crc_errors", E1000_STAT(net_stats.rx_crc_errors) }, | 69 | { "rx_crc_errors", E1000_STAT(net_stats.rx_crc_errors) }, |
70 | { "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) }, | 70 | { "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) }, |
71 | { "rx_fifo_errors", E1000_STAT(net_stats.rx_fifo_errors) }, | 71 | { "rx_fifo_errors", E1000_STAT(net_stats.rx_fifo_errors) }, |
72 | { "rx_no_buffer_count", E1000_STAT(stats.rnbc) }, | ||
72 | { "rx_missed_errors", E1000_STAT(net_stats.rx_missed_errors) }, | 73 | { "rx_missed_errors", E1000_STAT(net_stats.rx_missed_errors) }, |
73 | { "tx_aborted_errors", E1000_STAT(net_stats.tx_aborted_errors) }, | 74 | { "tx_aborted_errors", E1000_STAT(net_stats.tx_aborted_errors) }, |
74 | { "tx_carrier_errors", E1000_STAT(net_stats.tx_carrier_errors) }, | 75 | { "tx_carrier_errors", E1000_STAT(net_stats.tx_carrier_errors) }, |
@@ -593,7 +594,7 @@ e1000_set_ringparam(struct net_device *netdev, | |||
593 | tx_old = adapter->tx_ring; | 594 | tx_old = adapter->tx_ring; |
594 | rx_old = adapter->rx_ring; | 595 | rx_old = adapter->rx_ring; |
595 | 596 | ||
596 | if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) | 597 | if((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) |
597 | return -EINVAL; | 598 | return -EINVAL; |
598 | 599 | ||
599 | if(netif_running(adapter->netdev)) | 600 | if(netif_running(adapter->netdev)) |
@@ -784,8 +785,8 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data) | |||
784 | /* Hook up test interrupt handler just for this test */ | 785 | /* Hook up test interrupt handler just for this test */ |
785 | if(!request_irq(irq, &e1000_test_intr, 0, netdev->name, netdev)) { | 786 | if(!request_irq(irq, &e1000_test_intr, 0, netdev->name, netdev)) { |
786 | shared_int = FALSE; | 787 | shared_int = FALSE; |
787 | } else if(request_irq(irq, &e1000_test_intr, SA_SHIRQ, | 788 | } else if(request_irq(irq, &e1000_test_intr, SA_SHIRQ, |
788 | netdev->name, netdev)){ | 789 | netdev->name, netdev)){ |
789 | *data = 1; | 790 | *data = 1; |
790 | return -1; | 791 | return -1; |
791 | } | 792 | } |
@@ -842,10 +843,8 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data) | |||
842 | * test failed. | 843 | * test failed. |
843 | */ | 844 | */ |
844 | adapter->test_icr = 0; | 845 | adapter->test_icr = 0; |
845 | E1000_WRITE_REG(&adapter->hw, IMC, | 846 | E1000_WRITE_REG(&adapter->hw, IMC, ~mask & 0x00007FFF); |
846 | (~mask & 0x00007FFF)); | 847 | E1000_WRITE_REG(&adapter->hw, ICS, ~mask & 0x00007FFF); |
847 | E1000_WRITE_REG(&adapter->hw, ICS, | ||
848 | (~mask & 0x00007FFF)); | ||
849 | msec_delay(10); | 848 | msec_delay(10); |
850 | 849 | ||
851 | if(adapter->test_icr) { | 850 | if(adapter->test_icr) { |
@@ -919,7 +918,8 @@ e1000_setup_desc_rings(struct e1000_adapter *adapter) | |||
919 | 918 | ||
920 | /* Setup Tx descriptor ring and Tx buffers */ | 919 | /* Setup Tx descriptor ring and Tx buffers */ |
921 | 920 | ||
922 | txdr->count = 80; | 921 | if(!txdr->count) |
922 | txdr->count = E1000_DEFAULT_TXD; | ||
923 | 923 | ||
924 | size = txdr->count * sizeof(struct e1000_buffer); | 924 | size = txdr->count * sizeof(struct e1000_buffer); |
925 | if(!(txdr->buffer_info = kmalloc(size, GFP_KERNEL))) { | 925 | if(!(txdr->buffer_info = kmalloc(size, GFP_KERNEL))) { |
@@ -974,7 +974,8 @@ e1000_setup_desc_rings(struct e1000_adapter *adapter) | |||
974 | 974 | ||
975 | /* Setup Rx descriptor ring and Rx buffers */ | 975 | /* Setup Rx descriptor ring and Rx buffers */ |
976 | 976 | ||
977 | rxdr->count = 80; | 977 | if(!rxdr->count) |
978 | rxdr->count = E1000_DEFAULT_RXD; | ||
978 | 979 | ||
979 | size = rxdr->count * sizeof(struct e1000_buffer); | 980 | size = rxdr->count * sizeof(struct e1000_buffer); |
980 | if(!(rxdr->buffer_info = kmalloc(size, GFP_KERNEL))) { | 981 | if(!(rxdr->buffer_info = kmalloc(size, GFP_KERNEL))) { |
@@ -1008,7 +1009,7 @@ e1000_setup_desc_rings(struct e1000_adapter *adapter) | |||
1008 | struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rxdr, i); | 1009 | struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rxdr, i); |
1009 | struct sk_buff *skb; | 1010 | struct sk_buff *skb; |
1010 | 1011 | ||
1011 | if(!(skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN, | 1012 | if(!(skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN, |
1012 | GFP_KERNEL))) { | 1013 | GFP_KERNEL))) { |
1013 | ret_val = 6; | 1014 | ret_val = 6; |
1014 | goto err_nomem; | 1015 | goto err_nomem; |
@@ -1310,31 +1311,62 @@ e1000_run_loopback_test(struct e1000_adapter *adapter) | |||
1310 | struct e1000_desc_ring *txdr = &adapter->test_tx_ring; | 1311 | struct e1000_desc_ring *txdr = &adapter->test_tx_ring; |
1311 | struct e1000_desc_ring *rxdr = &adapter->test_rx_ring; | 1312 | struct e1000_desc_ring *rxdr = &adapter->test_rx_ring; |
1312 | struct pci_dev *pdev = adapter->pdev; | 1313 | struct pci_dev *pdev = adapter->pdev; |
1313 | int i, ret_val; | 1314 | int i, j, k, l, lc, good_cnt, ret_val=0; |
1315 | unsigned long time; | ||
1314 | 1316 | ||
1315 | E1000_WRITE_REG(&adapter->hw, RDT, rxdr->count - 1); | 1317 | E1000_WRITE_REG(&adapter->hw, RDT, rxdr->count - 1); |
1316 | 1318 | ||
1317 | for(i = 0; i < 64; i++) { | 1319 | /* Calculate the loop count based on the largest descriptor ring |
1318 | e1000_create_lbtest_frame(txdr->buffer_info[i].skb, 1024); | 1320 | * The idea is to wrap the largest ring a number of times using 64 |
1319 | pci_dma_sync_single_for_device(pdev, txdr->buffer_info[i].dma, | 1321 | * send/receive pairs during each loop |
1320 | txdr->buffer_info[i].length, | 1322 | */ |
1321 | PCI_DMA_TODEVICE); | ||
1322 | } | ||
1323 | E1000_WRITE_REG(&adapter->hw, TDT, i); | ||
1324 | |||
1325 | msec_delay(200); | ||
1326 | |||
1327 | i = 0; | ||
1328 | do { | ||
1329 | pci_dma_sync_single_for_cpu(pdev, rxdr->buffer_info[i].dma, | ||
1330 | rxdr->buffer_info[i].length, | ||
1331 | PCI_DMA_FROMDEVICE); | ||
1332 | |||
1333 | ret_val = e1000_check_lbtest_frame(rxdr->buffer_info[i].skb, | ||
1334 | 1024); | ||
1335 | i++; | ||
1336 | } while (ret_val != 0 && i < 64); | ||
1337 | 1323 | ||
1324 | if(rxdr->count <= txdr->count) | ||
1325 | lc = ((txdr->count / 64) * 2) + 1; | ||
1326 | else | ||
1327 | lc = ((rxdr->count / 64) * 2) + 1; | ||
1328 | |||
1329 | k = l = 0; | ||
1330 | for(j = 0; j <= lc; j++) { /* loop count loop */ | ||
1331 | for(i = 0; i < 64; i++) { /* send the packets */ | ||
1332 | e1000_create_lbtest_frame(txdr->buffer_info[i].skb, | ||
1333 | 1024); | ||
1334 | pci_dma_sync_single_for_device(pdev, | ||
1335 | txdr->buffer_info[k].dma, | ||
1336 | txdr->buffer_info[k].length, | ||
1337 | PCI_DMA_TODEVICE); | ||
1338 | if(unlikely(++k == txdr->count)) k = 0; | ||
1339 | } | ||
1340 | E1000_WRITE_REG(&adapter->hw, TDT, k); | ||
1341 | msec_delay(200); | ||
1342 | time = jiffies; /* set the start time for the receive */ | ||
1343 | good_cnt = 0; | ||
1344 | do { /* receive the sent packets */ | ||
1345 | pci_dma_sync_single_for_cpu(pdev, | ||
1346 | rxdr->buffer_info[l].dma, | ||
1347 | rxdr->buffer_info[l].length, | ||
1348 | PCI_DMA_FROMDEVICE); | ||
1349 | |||
1350 | ret_val = e1000_check_lbtest_frame( | ||
1351 | rxdr->buffer_info[l].skb, | ||
1352 | 1024); | ||
1353 | if(!ret_val) | ||
1354 | good_cnt++; | ||
1355 | if(unlikely(++l == rxdr->count)) l = 0; | ||
1356 | /* time + 20 msecs (200 msecs on 2.4) is more than | ||
1357 | * enough time to complete the receives, if it's | ||
1358 | * exceeded, break and error off | ||
1359 | */ | ||
1360 | } while (good_cnt < 64 && jiffies < (time + 20)); | ||
1361 | if(good_cnt != 64) { | ||
1362 | ret_val = 13; /* ret_val is the same as mis-compare */ | ||
1363 | break; | ||
1364 | } | ||
1365 | if(jiffies >= (time + 2)) { | ||
1366 | ret_val = 14; /* error code for time out error */ | ||
1367 | break; | ||
1368 | } | ||
1369 | } /* end loop count loop */ | ||
1338 | return ret_val; | 1370 | return ret_val; |
1339 | } | 1371 | } |
1340 | 1372 | ||
@@ -1354,13 +1386,12 @@ static int | |||
1354 | e1000_link_test(struct e1000_adapter *adapter, uint64_t *data) | 1386 | e1000_link_test(struct e1000_adapter *adapter, uint64_t *data) |
1355 | { | 1387 | { |
1356 | *data = 0; | 1388 | *data = 0; |
1357 | |||
1358 | if (adapter->hw.media_type == e1000_media_type_internal_serdes) { | 1389 | if (adapter->hw.media_type == e1000_media_type_internal_serdes) { |
1359 | int i = 0; | 1390 | int i = 0; |
1360 | adapter->hw.serdes_link_down = TRUE; | 1391 | adapter->hw.serdes_link_down = TRUE; |
1361 | 1392 | ||
1362 | /* on some blade server designs link establishment */ | 1393 | /* On some blade server designs, link establishment |
1363 | /* could take as long as 2-3 minutes. */ | 1394 | * could take as long as 2-3 minutes */ |
1364 | do { | 1395 | do { |
1365 | e1000_check_for_link(&adapter->hw); | 1396 | e1000_check_for_link(&adapter->hw); |
1366 | if (adapter->hw.serdes_link_down == FALSE) | 1397 | if (adapter->hw.serdes_link_down == FALSE) |
@@ -1368,9 +1399,11 @@ e1000_link_test(struct e1000_adapter *adapter, uint64_t *data) | |||
1368 | msec_delay(20); | 1399 | msec_delay(20); |
1369 | } while (i++ < 3750); | 1400 | } while (i++ < 3750); |
1370 | 1401 | ||
1371 | *data = 1; | 1402 | *data = 1; |
1372 | } else { | 1403 | } else { |
1373 | e1000_check_for_link(&adapter->hw); | 1404 | e1000_check_for_link(&adapter->hw); |
1405 | if(adapter->hw.autoneg) /* if auto_neg is set wait for it */ | ||
1406 | msec_delay(4000); | ||
1374 | 1407 | ||
1375 | if(!(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) { | 1408 | if(!(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) { |
1376 | *data = 1; | 1409 | *data = 1; |