Loading drivers/net/e1000/e1000.h +33 −4 Original line number Diff line number Diff line /******************************************************************************* Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Loading Loading @@ -112,6 +112,8 @@ struct e1000_adapter; #define E1000_MAX_82544_RXD 4096 /* Supported Rx Buffer Sizes */ #define E1000_RXBUFFER_128 128 /* Used for packet split */ #define E1000_RXBUFFER_256 256 /* Used for packet split */ #define E1000_RXBUFFER_2048 2048 #define E1000_RXBUFFER_4096 4096 #define E1000_RXBUFFER_8192 8192 Loading @@ -138,7 +140,7 @@ struct e1000_adapter; #define E1000_RX_BUFFER_WRITE 16 /* Must be power of 2 */ #define AUTO_ALL_MODES 0 #define E1000_EEPROM_82544_APM 0x0004 #define E1000_EEPROM_82544_APM 0x0400 #define E1000_EEPROM_APME 0x0400 #ifndef E1000_MASTER_SLAVE Loading @@ -146,6 +148,10 @@ struct e1000_adapter; #define E1000_MASTER_SLAVE e1000_ms_hw_default #endif #define E1000_MNG_VLAN_NONE -1 /* Number of packet split data buffers (not including the header buffer) */ #define PS_PAGE_BUFFERS MAX_PS_BUFFERS-1 /* only works for sizes that are powers of 2 */ #define E1000_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1))) Loading @@ -159,6 +165,9 @@ struct e1000_buffer { uint16_t next_to_watch; }; struct e1000_ps_page { struct page *ps_page[MAX_PS_BUFFERS]; }; struct e1000_ps_page_dma { uint64_t ps_page_dma[MAX_PS_BUFFERS]; }; struct e1000_desc_ring { /* pointer to the descriptor ring memory */ void *desc; Loading @@ -174,12 +183,19 @@ struct e1000_desc_ring { unsigned int next_to_clean; /* array of buffer information structs */ struct e1000_buffer *buffer_info; /* arrays of page information for packet split */ struct e1000_ps_page *ps_page; struct e1000_ps_page_dma *ps_page_dma; }; #define E1000_DESC_UNUSED(R) \ ((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \ (R)->next_to_clean - (R)->next_to_use - 1) #define E1000_RX_DESC_PS(R, i) \ (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) #define E1000_RX_DESC_EXT(R, i) \ (&(((union e1000_rx_desc_extended *)((R).desc))[i])) #define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i])) #define E1000_RX_DESC(R, i) E1000_GET_DESC(R, i, e1000_rx_desc) #define E1000_TX_DESC(R, i) E1000_GET_DESC(R, i, e1000_tx_desc) Loading @@ -192,6 +208,7 @@ struct e1000_adapter { struct timer_list watchdog_timer; struct timer_list phy_info_timer; struct vlan_group *vlgrp; uint16_t mng_vlan_id; uint32_t bd_number; uint32_t rx_buffer_len; uint32_t part_num; Loading Loading @@ -228,14 +245,23 @@ struct e1000_adapter { boolean_t detect_tx_hung; /* RX */ #ifdef CONFIG_E1000_NAPI boolean_t (*clean_rx) (struct e1000_adapter *adapter, int *work_done, int work_to_do); #else boolean_t (*clean_rx) (struct e1000_adapter *adapter); #endif void (*alloc_rx_buf) (struct e1000_adapter *adapter); struct e1000_desc_ring rx_ring; uint64_t hw_csum_err; uint64_t hw_csum_good; uint32_t rx_int_delay; uint32_t rx_abs_int_delay; boolean_t rx_csum; boolean_t rx_ps; uint32_t gorcl; uint64_t gorcl_old; uint16_t rx_ps_bsize0; /* Interrupt Throttle Rate */ uint32_t itr; Loading @@ -257,5 +283,8 @@ struct e1000_adapter { int msg_enable; #ifdef CONFIG_PCI_MSI boolean_t have_msi; #endif }; #endif /* _E1000_H_ */ drivers/net/e1000/e1000_ethtool.c +69 −36 Original line number Diff line number Diff line /******************************************************************************* Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Loading Loading @@ -69,6 +69,7 @@ static const struct e1000_stats e1000_gstrings_stats[] = { { "rx_crc_errors", E1000_STAT(net_stats.rx_crc_errors) }, { "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) }, { "rx_fifo_errors", E1000_STAT(net_stats.rx_fifo_errors) }, { "rx_no_buffer_count", E1000_STAT(stats.rnbc) }, { "rx_missed_errors", E1000_STAT(net_stats.rx_missed_errors) }, { "tx_aborted_errors", E1000_STAT(net_stats.tx_aborted_errors) }, { "tx_carrier_errors", E1000_STAT(net_stats.tx_carrier_errors) }, Loading Loading @@ -842,10 +843,8 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data) * test failed. */ adapter->test_icr = 0; E1000_WRITE_REG(&adapter->hw, IMC, (~mask & 0x00007FFF)); E1000_WRITE_REG(&adapter->hw, ICS, (~mask & 0x00007FFF)); E1000_WRITE_REG(&adapter->hw, IMC, ~mask & 0x00007FFF); E1000_WRITE_REG(&adapter->hw, ICS, ~mask & 0x00007FFF); msec_delay(10); if(adapter->test_icr) { Loading Loading @@ -919,7 +918,8 @@ e1000_setup_desc_rings(struct e1000_adapter *adapter) /* Setup Tx descriptor ring and Tx buffers */ txdr->count = 80; if(!txdr->count) txdr->count = E1000_DEFAULT_TXD; size = txdr->count * sizeof(struct e1000_buffer); if(!(txdr->buffer_info = kmalloc(size, GFP_KERNEL))) { Loading Loading @@ -974,7 +974,8 @@ e1000_setup_desc_rings(struct e1000_adapter *adapter) /* Setup Rx descriptor ring and Rx buffers */ rxdr->count = 80; if(!rxdr->count) rxdr->count = E1000_DEFAULT_RXD; size = rxdr->count * sizeof(struct e1000_buffer); if(!(rxdr->buffer_info = kmalloc(size, GFP_KERNEL))) { Loading Loading @@ -1310,31 +1311,62 @@ e1000_run_loopback_test(struct e1000_adapter *adapter) struct e1000_desc_ring *txdr = &adapter->test_tx_ring; struct e1000_desc_ring *rxdr = &adapter->test_rx_ring; struct pci_dev *pdev = adapter->pdev; int i, ret_val; int i, j, k, l, lc, good_cnt, ret_val=0; unsigned long time; E1000_WRITE_REG(&adapter->hw, RDT, rxdr->count - 1); for(i = 0; i < 64; i++) { e1000_create_lbtest_frame(txdr->buffer_info[i].skb, 1024); pci_dma_sync_single_for_device(pdev, txdr->buffer_info[i].dma, txdr->buffer_info[i].length, /* Calculate the loop count based on the largest descriptor ring * The idea is to wrap the largest ring a number of times using 64 * send/receive pairs during each loop */ if(rxdr->count <= txdr->count) lc = ((txdr->count / 64) * 2) + 1; else lc = ((rxdr->count / 64) * 2) + 1; k = l = 0; for(j = 0; j <= lc; j++) { /* loop count loop */ for(i = 0; i < 64; i++) { /* send the packets */ e1000_create_lbtest_frame(txdr->buffer_info[i].skb, 1024); pci_dma_sync_single_for_device(pdev, txdr->buffer_info[k].dma, txdr->buffer_info[k].length, PCI_DMA_TODEVICE); if(unlikely(++k == txdr->count)) k = 0; } E1000_WRITE_REG(&adapter->hw, TDT, i); E1000_WRITE_REG(&adapter->hw, TDT, k); msec_delay(200); i = 0; do { pci_dma_sync_single_for_cpu(pdev, rxdr->buffer_info[i].dma, rxdr->buffer_info[i].length, time = jiffies; /* set the start time for the receive */ good_cnt = 0; do { /* receive the sent packets */ pci_dma_sync_single_for_cpu(pdev, rxdr->buffer_info[l].dma, rxdr->buffer_info[l].length, PCI_DMA_FROMDEVICE); ret_val = e1000_check_lbtest_frame(rxdr->buffer_info[i].skb, ret_val = e1000_check_lbtest_frame( rxdr->buffer_info[l].skb, 1024); i++; } while (ret_val != 0 && i < 64); if(!ret_val) good_cnt++; if(unlikely(++l == rxdr->count)) l = 0; /* time + 20 msecs (200 msecs on 2.4) is more than * enough time to complete the receives, if it's * exceeded, break and error off */ } while (good_cnt < 64 && jiffies < (time + 20)); if(good_cnt != 64) { ret_val = 13; /* ret_val is the same as mis-compare */ break; } if(jiffies >= (time + 2)) { ret_val = 14; /* error code for time out error */ break; } } /* end loop count loop */ return ret_val; } Loading @@ -1354,13 +1386,12 @@ static int e1000_link_test(struct e1000_adapter *adapter, uint64_t *data) { *data = 0; if (adapter->hw.media_type == e1000_media_type_internal_serdes) { int i = 0; adapter->hw.serdes_link_down = TRUE; /* on some blade server designs link establishment */ /* could take as long as 2-3 minutes. */ /* On some blade server designs, link establishment * could take as long as 2-3 minutes */ do { e1000_check_for_link(&adapter->hw); if (adapter->hw.serdes_link_down == FALSE) Loading @@ -1371,6 +1402,8 @@ e1000_link_test(struct e1000_adapter *adapter, uint64_t *data) *data = 1; } else { e1000_check_for_link(&adapter->hw); if(adapter->hw.autoneg) /* if auto_neg is set wait for it */ msec_delay(4000); if(!(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) { *data = 1; Loading Loading
drivers/net/e1000/e1000.h +33 −4 Original line number Diff line number Diff line /******************************************************************************* Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Loading Loading @@ -112,6 +112,8 @@ struct e1000_adapter; #define E1000_MAX_82544_RXD 4096 /* Supported Rx Buffer Sizes */ #define E1000_RXBUFFER_128 128 /* Used for packet split */ #define E1000_RXBUFFER_256 256 /* Used for packet split */ #define E1000_RXBUFFER_2048 2048 #define E1000_RXBUFFER_4096 4096 #define E1000_RXBUFFER_8192 8192 Loading @@ -138,7 +140,7 @@ struct e1000_adapter; #define E1000_RX_BUFFER_WRITE 16 /* Must be power of 2 */ #define AUTO_ALL_MODES 0 #define E1000_EEPROM_82544_APM 0x0004 #define E1000_EEPROM_82544_APM 0x0400 #define E1000_EEPROM_APME 0x0400 #ifndef E1000_MASTER_SLAVE Loading @@ -146,6 +148,10 @@ struct e1000_adapter; #define E1000_MASTER_SLAVE e1000_ms_hw_default #endif #define E1000_MNG_VLAN_NONE -1 /* Number of packet split data buffers (not including the header buffer) */ #define PS_PAGE_BUFFERS MAX_PS_BUFFERS-1 /* only works for sizes that are powers of 2 */ #define E1000_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1))) Loading @@ -159,6 +165,9 @@ struct e1000_buffer { uint16_t next_to_watch; }; struct e1000_ps_page { struct page *ps_page[MAX_PS_BUFFERS]; }; struct e1000_ps_page_dma { uint64_t ps_page_dma[MAX_PS_BUFFERS]; }; struct e1000_desc_ring { /* pointer to the descriptor ring memory */ void *desc; Loading @@ -174,12 +183,19 @@ struct e1000_desc_ring { unsigned int next_to_clean; /* array of buffer information structs */ struct e1000_buffer *buffer_info; /* arrays of page information for packet split */ struct e1000_ps_page *ps_page; struct e1000_ps_page_dma *ps_page_dma; }; #define E1000_DESC_UNUSED(R) \ ((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \ (R)->next_to_clean - (R)->next_to_use - 1) #define E1000_RX_DESC_PS(R, i) \ (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) #define E1000_RX_DESC_EXT(R, i) \ (&(((union e1000_rx_desc_extended *)((R).desc))[i])) #define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i])) #define E1000_RX_DESC(R, i) E1000_GET_DESC(R, i, e1000_rx_desc) #define E1000_TX_DESC(R, i) E1000_GET_DESC(R, i, e1000_tx_desc) Loading @@ -192,6 +208,7 @@ struct e1000_adapter { struct timer_list watchdog_timer; struct timer_list phy_info_timer; struct vlan_group *vlgrp; uint16_t mng_vlan_id; uint32_t bd_number; uint32_t rx_buffer_len; uint32_t part_num; Loading Loading @@ -228,14 +245,23 @@ struct e1000_adapter { boolean_t detect_tx_hung; /* RX */ #ifdef CONFIG_E1000_NAPI boolean_t (*clean_rx) (struct e1000_adapter *adapter, int *work_done, int work_to_do); #else boolean_t (*clean_rx) (struct e1000_adapter *adapter); #endif void (*alloc_rx_buf) (struct e1000_adapter *adapter); struct e1000_desc_ring rx_ring; uint64_t hw_csum_err; uint64_t hw_csum_good; uint32_t rx_int_delay; uint32_t rx_abs_int_delay; boolean_t rx_csum; boolean_t rx_ps; uint32_t gorcl; uint64_t gorcl_old; uint16_t rx_ps_bsize0; /* Interrupt Throttle Rate */ uint32_t itr; Loading @@ -257,5 +283,8 @@ struct e1000_adapter { int msg_enable; #ifdef CONFIG_PCI_MSI boolean_t have_msi; #endif }; #endif /* _E1000_H_ */
drivers/net/e1000/e1000_ethtool.c +69 −36 Original line number Diff line number Diff line /******************************************************************************* Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Loading Loading @@ -69,6 +69,7 @@ static const struct e1000_stats e1000_gstrings_stats[] = { { "rx_crc_errors", E1000_STAT(net_stats.rx_crc_errors) }, { "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) }, { "rx_fifo_errors", E1000_STAT(net_stats.rx_fifo_errors) }, { "rx_no_buffer_count", E1000_STAT(stats.rnbc) }, { "rx_missed_errors", E1000_STAT(net_stats.rx_missed_errors) }, { "tx_aborted_errors", E1000_STAT(net_stats.tx_aborted_errors) }, { "tx_carrier_errors", E1000_STAT(net_stats.tx_carrier_errors) }, Loading Loading @@ -842,10 +843,8 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data) * test failed. */ adapter->test_icr = 0; E1000_WRITE_REG(&adapter->hw, IMC, (~mask & 0x00007FFF)); E1000_WRITE_REG(&adapter->hw, ICS, (~mask & 0x00007FFF)); E1000_WRITE_REG(&adapter->hw, IMC, ~mask & 0x00007FFF); E1000_WRITE_REG(&adapter->hw, ICS, ~mask & 0x00007FFF); msec_delay(10); if(adapter->test_icr) { Loading Loading @@ -919,7 +918,8 @@ e1000_setup_desc_rings(struct e1000_adapter *adapter) /* Setup Tx descriptor ring and Tx buffers */ txdr->count = 80; if(!txdr->count) txdr->count = E1000_DEFAULT_TXD; size = txdr->count * sizeof(struct e1000_buffer); if(!(txdr->buffer_info = kmalloc(size, GFP_KERNEL))) { Loading Loading @@ -974,7 +974,8 @@ e1000_setup_desc_rings(struct e1000_adapter *adapter) /* Setup Rx descriptor ring and Rx buffers */ rxdr->count = 80; if(!rxdr->count) rxdr->count = E1000_DEFAULT_RXD; size = rxdr->count * sizeof(struct e1000_buffer); if(!(rxdr->buffer_info = kmalloc(size, GFP_KERNEL))) { Loading Loading @@ -1310,31 +1311,62 @@ e1000_run_loopback_test(struct e1000_adapter *adapter) struct e1000_desc_ring *txdr = &adapter->test_tx_ring; struct e1000_desc_ring *rxdr = &adapter->test_rx_ring; struct pci_dev *pdev = adapter->pdev; int i, ret_val; int i, j, k, l, lc, good_cnt, ret_val=0; unsigned long time; E1000_WRITE_REG(&adapter->hw, RDT, rxdr->count - 1); for(i = 0; i < 64; i++) { e1000_create_lbtest_frame(txdr->buffer_info[i].skb, 1024); pci_dma_sync_single_for_device(pdev, txdr->buffer_info[i].dma, txdr->buffer_info[i].length, /* Calculate the loop count based on the largest descriptor ring * The idea is to wrap the largest ring a number of times using 64 * send/receive pairs during each loop */ if(rxdr->count <= txdr->count) lc = ((txdr->count / 64) * 2) + 1; else lc = ((rxdr->count / 64) * 2) + 1; k = l = 0; for(j = 0; j <= lc; j++) { /* loop count loop */ for(i = 0; i < 64; i++) { /* send the packets */ e1000_create_lbtest_frame(txdr->buffer_info[i].skb, 1024); pci_dma_sync_single_for_device(pdev, txdr->buffer_info[k].dma, txdr->buffer_info[k].length, PCI_DMA_TODEVICE); if(unlikely(++k == txdr->count)) k = 0; } E1000_WRITE_REG(&adapter->hw, TDT, i); E1000_WRITE_REG(&adapter->hw, TDT, k); msec_delay(200); i = 0; do { pci_dma_sync_single_for_cpu(pdev, rxdr->buffer_info[i].dma, rxdr->buffer_info[i].length, time = jiffies; /* set the start time for the receive */ good_cnt = 0; do { /* receive the sent packets */ pci_dma_sync_single_for_cpu(pdev, rxdr->buffer_info[l].dma, rxdr->buffer_info[l].length, PCI_DMA_FROMDEVICE); ret_val = e1000_check_lbtest_frame(rxdr->buffer_info[i].skb, ret_val = e1000_check_lbtest_frame( rxdr->buffer_info[l].skb, 1024); i++; } while (ret_val != 0 && i < 64); if(!ret_val) good_cnt++; if(unlikely(++l == rxdr->count)) l = 0; /* time + 20 msecs (200 msecs on 2.4) is more than * enough time to complete the receives, if it's * exceeded, break and error off */ } while (good_cnt < 64 && jiffies < (time + 20)); if(good_cnt != 64) { ret_val = 13; /* ret_val is the same as mis-compare */ break; } if(jiffies >= (time + 2)) { ret_val = 14; /* error code for time out error */ break; } } /* end loop count loop */ return ret_val; } Loading @@ -1354,13 +1386,12 @@ static int e1000_link_test(struct e1000_adapter *adapter, uint64_t *data) { *data = 0; if (adapter->hw.media_type == e1000_media_type_internal_serdes) { int i = 0; adapter->hw.serdes_link_down = TRUE; /* on some blade server designs link establishment */ /* could take as long as 2-3 minutes. */ /* On some blade server designs, link establishment * could take as long as 2-3 minutes */ do { e1000_check_for_link(&adapter->hw); if (adapter->hw.serdes_link_down == FALSE) Loading @@ -1371,6 +1402,8 @@ e1000_link_test(struct e1000_adapter *adapter, uint64_t *data) *data = 1; } else { e1000_check_for_link(&adapter->hw); if(adapter->hw.autoneg) /* if auto_neg is set wait for it */ msec_delay(4000); if(!(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) { *data = 1; Loading