diff options
author | Malli Chilakala <mallikarjuna.chilakala@intel.com> | 2005-04-28 22:38:30 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-05-12 20:48:52 -0400 |
commit | e4eff7291c977308989b24fdfc7215a501302e6a (patch) | |
tree | c773bc7d11aaf8acf8928c801afc34561818bc53 /drivers/net/e1000/e1000_ethtool.c | |
parent | 88d7bd8cb9eb8d64bf7997600b0d64f7834047c5 (diff) |
[PATCH] e1000: made loopback test robust
Added enhanced functionality to the loopback diags to wrap the descriptor rings.
Signed-off-by: Mallikarjuna R Chilakala <mallikarjuna.chilakala@intel.com>
Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan@intel.com>
Signed-off-by: John Ronciak <john.ronciak@intel.com>
diff -up net-drivers-2.6/drivers/net/e1000/e1000_ethtool.c net-drivers-2.6/drivers/net/e1000.new/e1000_ethtool.c
Diffstat (limited to 'drivers/net/e1000/e1000_ethtool.c')
-rw-r--r-- | drivers/net/e1000/e1000_ethtool.c | 81 |
1 files changed, 58 insertions, 23 deletions
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index 0a2ca7c73a41..fae585453463 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c | |||
@@ -919,7 +919,8 @@ e1000_setup_desc_rings(struct e1000_adapter *adapter) | |||
919 | 919 | ||
920 | /* Setup Tx descriptor ring and Tx buffers */ | 920 | /* Setup Tx descriptor ring and Tx buffers */ |
921 | 921 | ||
922 | txdr->count = 80; | 922 | if(!txdr->count) |
923 | txdr->count = E1000_DEFAULT_TXD; | ||
923 | 924 | ||
924 | size = txdr->count * sizeof(struct e1000_buffer); | 925 | size = txdr->count * sizeof(struct e1000_buffer); |
925 | if(!(txdr->buffer_info = kmalloc(size, GFP_KERNEL))) { | 926 | if(!(txdr->buffer_info = kmalloc(size, GFP_KERNEL))) { |
@@ -974,7 +975,8 @@ e1000_setup_desc_rings(struct e1000_adapter *adapter) | |||
974 | 975 | ||
975 | /* Setup Rx descriptor ring and Rx buffers */ | 976 | /* Setup Rx descriptor ring and Rx buffers */ |
976 | 977 | ||
977 | rxdr->count = 80; | 978 | if(!rxdr->count) |
979 | rxdr->count = E1000_DEFAULT_RXD; | ||
978 | 980 | ||
979 | size = rxdr->count * sizeof(struct e1000_buffer); | 981 | size = rxdr->count * sizeof(struct e1000_buffer); |
980 | if(!(rxdr->buffer_info = kmalloc(size, GFP_KERNEL))) { | 982 | if(!(rxdr->buffer_info = kmalloc(size, GFP_KERNEL))) { |
@@ -1310,31 +1312,62 @@ e1000_run_loopback_test(struct e1000_adapter *adapter) | |||
1310 | struct e1000_desc_ring *txdr = &adapter->test_tx_ring; | 1312 | struct e1000_desc_ring *txdr = &adapter->test_tx_ring; |
1311 | struct e1000_desc_ring *rxdr = &adapter->test_rx_ring; | 1313 | struct e1000_desc_ring *rxdr = &adapter->test_rx_ring; |
1312 | struct pci_dev *pdev = adapter->pdev; | 1314 | struct pci_dev *pdev = adapter->pdev; |
1313 | int i, ret_val; | 1315 | int i, j, k, l, lc, good_cnt, ret_val=0; |
1316 | unsigned long time; | ||
1314 | 1317 | ||
1315 | E1000_WRITE_REG(&adapter->hw, RDT, rxdr->count - 1); | 1318 | E1000_WRITE_REG(&adapter->hw, RDT, rxdr->count - 1); |
1316 | 1319 | ||
1317 | for(i = 0; i < 64; i++) { | 1320 | /* Calculate the loop count based on the largest descriptor ring |
1318 | e1000_create_lbtest_frame(txdr->buffer_info[i].skb, 1024); | 1321 | * 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, | 1322 | * send/receive pairs during each loop |
1320 | txdr->buffer_info[i].length, | 1323 | */ |
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 | 1324 | ||
1325 | if(rxdr->count <= txdr->count) | ||
1326 | lc = ((txdr->count / 64) * 2) + 1; | ||
1327 | else | ||
1328 | lc = ((rxdr->count / 64) * 2) + 1; | ||
1329 | |||
1330 | k = l = 0; | ||
1331 | for(j = 0; j <= lc; j++) { /* loop count loop */ | ||
1332 | for(i = 0; i < 64; i++) { /* send the packets */ | ||
1333 | e1000_create_lbtest_frame(txdr->buffer_info[i].skb, | ||
1334 | 1024); | ||
1335 | pci_dma_sync_single_for_device(pdev, | ||
1336 | txdr->buffer_info[k].dma, | ||
1337 | txdr->buffer_info[k].length, | ||
1338 | PCI_DMA_TODEVICE); | ||
1339 | if(unlikely(++k == txdr->count)) k = 0; | ||
1340 | } | ||
1341 | E1000_WRITE_REG(&adapter->hw, TDT, k); | ||
1342 | msec_delay(200); | ||
1343 | time = jiffies; /* set the start time for the receive */ | ||
1344 | good_cnt = 0; | ||
1345 | do { /* receive the sent packets */ | ||
1346 | pci_dma_sync_single_for_cpu(pdev, | ||
1347 | rxdr->buffer_info[l].dma, | ||
1348 | rxdr->buffer_info[l].length, | ||
1349 | PCI_DMA_FROMDEVICE); | ||
1350 | |||
1351 | ret_val = e1000_check_lbtest_frame( | ||
1352 | rxdr->buffer_info[l].skb, | ||
1353 | 1024); | ||
1354 | if(!ret_val) | ||
1355 | good_cnt++; | ||
1356 | if(unlikely(++l == rxdr->count)) l = 0; | ||
1357 | /* time + 20 msecs (200 msecs on 2.4) is more than | ||
1358 | * enough time to complete the receives, if it's | ||
1359 | * exceeded, break and error off | ||
1360 | */ | ||
1361 | } while (good_cnt < 64 && jiffies < (time + 20)); | ||
1362 | if(good_cnt != 64) { | ||
1363 | ret_val = 13; /* ret_val is the same as mis-compare */ | ||
1364 | break; | ||
1365 | } | ||
1366 | if(jiffies >= (time + 2)) { | ||
1367 | ret_val = 14; /* error code for time out error */ | ||
1368 | break; | ||
1369 | } | ||
1370 | } /* end loop count loop */ | ||
1338 | return ret_val; | 1371 | return ret_val; |
1339 | } | 1372 | } |
1340 | 1373 | ||
@@ -1371,6 +1404,8 @@ e1000_link_test(struct e1000_adapter *adapter, uint64_t *data) | |||
1371 | *data = 1; | 1404 | *data = 1; |
1372 | } else { | 1405 | } else { |
1373 | e1000_check_for_link(&adapter->hw); | 1406 | e1000_check_for_link(&adapter->hw); |
1407 | if(adapter->hw.autoneg) /* if auto_neg is set wait for it */ | ||
1408 | msec_delay(4000); | ||
1374 | 1409 | ||
1375 | if(!(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) { | 1410 | if(!(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) { |
1376 | *data = 1; | 1411 | *data = 1; |