aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000/e1000_ethtool.c
diff options
context:
space:
mode:
authorMalli Chilakala <mallikarjuna.chilakala@intel.com>2005-04-28 22:38:30 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-05-12 20:48:52 -0400
commite4eff7291c977308989b24fdfc7215a501302e6a (patch)
treec773bc7d11aaf8acf8928c801afc34561818bc53 /drivers/net/e1000/e1000_ethtool.c
parent88d7bd8cb9eb8d64bf7997600b0d64f7834047c5 (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.c81
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;