From 9beb0ac17bcfed23feb0a6fac328216568b74bc1 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 12 Sep 2005 10:48:55 -0400 Subject: [PATCH] e1000: support ETHTOOL_GPERMADDR Add support for ETHTOOL_GPERMADDR to e1000. Signed-off-by: John W. Linville Signed-off-by: Jeff Garzik --- drivers/net/e1000/e1000_ethtool.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/e1000/e1000_ethtool.c') diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index f133ff0b0b94..8f3a13420278 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -1739,6 +1739,7 @@ struct ethtool_ops e1000_ethtool_ops = { .phys_id = e1000_phys_id, .get_stats_count = e1000_get_stats_count, .get_ethtool_stats = e1000_get_ethtool_stats, + .get_perm_addr = ethtool_op_get_perm_addr, }; void e1000_set_ethtool_ops(struct net_device *netdev) -- cgit v1.2.2 From 868d5309942927dc86f57009420c5d366ec05daa Mon Sep 17 00:00:00 2001 From: Mallikarjuna R Chilakala Date: Tue, 4 Oct 2005 06:58:59 -0400 Subject: e1000: Support for 82571 and 82572 controllers Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak Signed-off-by: Jeff Garzik --- drivers/net/e1000/e1000_ethtool.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/net/e1000/e1000_ethtool.c') diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index 8f3a13420278..5f9a36bb77f5 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -696,6 +696,11 @@ e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data) * Some bits that get toggled are ignored. */ switch (adapter->hw.mac_type) { + /* there are several bits on newer hardware that are r/w */ + case e1000_82571: + case e1000_82572: + toggle = 0x7FFFF3FF; + break; case e1000_82573: toggle = 0x7FFFF033; break; @@ -1245,6 +1250,8 @@ e1000_set_phy_loopback(struct e1000_adapter *adapter) case e1000_82541_rev_2: case e1000_82547: case e1000_82547_rev_2: + case e1000_82571: + case e1000_82572: case e1000_82573: return e1000_integrated_phy_loopback(adapter); break; @@ -1625,7 +1632,7 @@ e1000_phys_id(struct net_device *netdev, uint32_t data) if(!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ)) data = (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ); - if(adapter->hw.mac_type < e1000_82573) { + if(adapter->hw.mac_type < e1000_82571) { if(!adapter->blink_timer.function) { init_timer(&adapter->blink_timer); adapter->blink_timer.function = e1000_led_blink_callback; -- cgit v1.2.2 From 581d708eb47cccb5f41bc0817e50c9b004011ba8 Mon Sep 17 00:00:00 2001 From: Mallikarjuna R Chilakala Date: Tue, 4 Oct 2005 07:01:55 -0400 Subject: e1000: multi-queue defines/modification to data structures defines/modifies data structures, function prototypes and changes to the driver rendering it capable of handling tx/rx queues Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak Signed-off-by: Jeff Garzik --- drivers/net/e1000/e1000_ethtool.c | 75 ++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 24 deletions(-) (limited to 'drivers/net/e1000/e1000_ethtool.c') diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index 5f9a36bb77f5..6e7e34f59a34 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -39,10 +39,10 @@ extern int e1000_up(struct e1000_adapter *adapter); extern void e1000_down(struct e1000_adapter *adapter); extern void e1000_reset(struct e1000_adapter *adapter); extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx); -extern int e1000_setup_rx_resources(struct e1000_adapter *adapter); -extern int e1000_setup_tx_resources(struct e1000_adapter *adapter); -extern void e1000_free_rx_resources(struct e1000_adapter *adapter); -extern void e1000_free_tx_resources(struct e1000_adapter *adapter); +extern int e1000_setup_all_rx_resources(struct e1000_adapter *adapter); +extern int e1000_setup_all_tx_resources(struct e1000_adapter *adapter); +extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter); +extern void e1000_free_all_tx_resources(struct e1000_adapter *adapter); extern void e1000_update_stats(struct e1000_adapter *adapter); struct e1000_stats { @@ -576,8 +576,8 @@ e1000_get_ringparam(struct net_device *netdev, { struct e1000_adapter *adapter = netdev_priv(netdev); e1000_mac_type mac_type = adapter->hw.mac_type; - struct e1000_desc_ring *txdr = &adapter->tx_ring; - struct e1000_desc_ring *rxdr = &adapter->rx_ring; + struct e1000_tx_ring *txdr = adapter->tx_ring; + struct e1000_rx_ring *rxdr = adapter->rx_ring; ring->rx_max_pending = (mac_type < e1000_82544) ? E1000_MAX_RXD : E1000_MAX_82544_RXD; @@ -597,20 +597,40 @@ e1000_set_ringparam(struct net_device *netdev, { struct e1000_adapter *adapter = netdev_priv(netdev); e1000_mac_type mac_type = adapter->hw.mac_type; - struct e1000_desc_ring *txdr = &adapter->tx_ring; - struct e1000_desc_ring *rxdr = &adapter->rx_ring; - struct e1000_desc_ring tx_old, tx_new, rx_old, rx_new; - int err; + struct e1000_tx_ring *txdr, *tx_old, *tx_new; + struct e1000_rx_ring *rxdr, *rx_old, *rx_new; + int i, err, tx_ring_size, rx_ring_size; + + tx_ring_size = sizeof(struct e1000_tx_ring) * adapter->num_queues; + rx_ring_size = sizeof(struct e1000_rx_ring) * adapter->num_queues; + + if (netif_running(adapter->netdev)) + e1000_down(adapter); tx_old = adapter->tx_ring; rx_old = adapter->rx_ring; + adapter->tx_ring = kmalloc(tx_ring_size, GFP_KERNEL); + if (!adapter->tx_ring) { + err = -ENOMEM; + goto err_setup_rx; + } + memset(adapter->tx_ring, 0, tx_ring_size); + + adapter->rx_ring = kmalloc(rx_ring_size, GFP_KERNEL); + if (!adapter->rx_ring) { + kfree(adapter->tx_ring); + err = -ENOMEM; + goto err_setup_rx; + } + memset(adapter->rx_ring, 0, rx_ring_size); + + txdr = adapter->tx_ring; + rxdr = adapter->rx_ring; + if((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) return -EINVAL; - if(netif_running(adapter->netdev)) - e1000_down(adapter); - rxdr->count = max(ring->rx_pending,(uint32_t)E1000_MIN_RXD); rxdr->count = min(rxdr->count,(uint32_t)(mac_type < e1000_82544 ? E1000_MAX_RXD : E1000_MAX_82544_RXD)); @@ -621,11 +641,16 @@ e1000_set_ringparam(struct net_device *netdev, E1000_MAX_TXD : E1000_MAX_82544_TXD)); E1000_ROUNDUP(txdr->count, REQ_TX_DESCRIPTOR_MULTIPLE); + for (i = 0; i < adapter->num_queues; i++) { + txdr[i].count = txdr->count; + rxdr[i].count = rxdr->count; + } + if(netif_running(adapter->netdev)) { /* Try to get new resources before deleting old */ - if((err = e1000_setup_rx_resources(adapter))) + if ((err = e1000_setup_all_rx_resources(adapter))) goto err_setup_rx; - if((err = e1000_setup_tx_resources(adapter))) + if ((err = e1000_setup_all_tx_resources(adapter))) goto err_setup_tx; /* save the new, restore the old in order to free it, @@ -635,8 +660,10 @@ e1000_set_ringparam(struct net_device *netdev, tx_new = adapter->tx_ring; adapter->rx_ring = rx_old; adapter->tx_ring = tx_old; - e1000_free_rx_resources(adapter); - e1000_free_tx_resources(adapter); + e1000_free_all_rx_resources(adapter); + e1000_free_all_tx_resources(adapter); + kfree(tx_old); + kfree(rx_old); adapter->rx_ring = rx_new; adapter->tx_ring = tx_new; if((err = e1000_up(adapter))) @@ -645,7 +672,7 @@ e1000_set_ringparam(struct net_device *netdev, return 0; err_setup_tx: - e1000_free_rx_resources(adapter); + e1000_free_all_rx_resources(adapter); err_setup_rx: adapter->rx_ring = rx_old; adapter->tx_ring = tx_old; @@ -903,8 +930,8 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data) static void e1000_free_desc_rings(struct e1000_adapter *adapter) { - struct e1000_desc_ring *txdr = &adapter->test_tx_ring; - struct e1000_desc_ring *rxdr = &adapter->test_rx_ring; + struct e1000_tx_ring *txdr = &adapter->test_tx_ring; + struct e1000_rx_ring *rxdr = &adapter->test_rx_ring; struct pci_dev *pdev = adapter->pdev; int i; @@ -946,8 +973,8 @@ e1000_free_desc_rings(struct e1000_adapter *adapter) static int e1000_setup_desc_rings(struct e1000_adapter *adapter) { - struct e1000_desc_ring *txdr = &adapter->test_tx_ring; - struct e1000_desc_ring *rxdr = &adapter->test_rx_ring; + struct e1000_tx_ring *txdr = &adapter->test_tx_ring; + struct e1000_rx_ring *rxdr = &adapter->test_rx_ring; struct pci_dev *pdev = adapter->pdev; uint32_t rctl; int size, i, ret_val; @@ -1347,8 +1374,8 @@ e1000_check_lbtest_frame(struct sk_buff *skb, unsigned int frame_size) static int 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 e1000_tx_ring *txdr = &adapter->test_tx_ring; + struct e1000_rx_ring *rxdr = &adapter->test_rx_ring; struct pci_dev *pdev = adapter->pdev; int i, j, k, l, lc, good_cnt, ret_val=0; unsigned long time; -- cgit v1.2.2 From e4c811c9d2f2728ce15440c99b3b44b72799b43f Mon Sep 17 00:00:00 2001 From: Mallikarjuna R Chilakala Date: Tue, 4 Oct 2005 07:05:44 -0400 Subject: e1000: Fixes for packet split related issues Fixes for packet split related issues * On platforms where PAGE_SIZE > 4K, driver will use only required number of pages compared to always using 3 pages. * Packet split won't be used if the PAGE_SIZE is > 16K * Adds a statistics counter to splits. * Setting the non Null ptr to zero sized buffers to solve packet split receive descriptor error * When the no of pages needed is calculated, the header buffer is not included for a given MTU. Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak Signed-off-by: Jeff Garzik --- drivers/net/e1000/e1000_ethtool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net/e1000/e1000_ethtool.c') diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index 6e7e34f59a34..183b583df1d7 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -91,7 +91,8 @@ static const struct e1000_stats e1000_gstrings_stats[] = { { "tx_flow_control_xoff", E1000_STAT(stats.xofftxc) }, { "rx_long_byte_count", E1000_STAT(stats.gorcl) }, { "rx_csum_offload_good", E1000_STAT(hw_csum_good) }, - { "rx_csum_offload_errors", E1000_STAT(hw_csum_err) } + { "rx_csum_offload_errors", E1000_STAT(hw_csum_err) }, + { "rx_header_split", E1000_STAT(rx_hdr_split) }, }; #define E1000_STATS_LEN \ sizeof(e1000_gstrings_stats) / sizeof(struct e1000_stats) -- cgit v1.2.2 From 352c9f854cb197581d7135d1276742fd76b53c25 Mon Sep 17 00:00:00 2001 From: Mallikarjuna R Chilakala Date: Tue, 4 Oct 2005 07:07:24 -0400 Subject: e1000: Added msleep_interruptible delay added msleep_interruptible delay right before returning from diag_test to allow the phy to recover from reset Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak Signed-off-by: Jeff Garzik --- drivers/net/e1000/e1000_ethtool.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/e1000/e1000_ethtool.c') diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index 183b583df1d7..ee66947e5043 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -1544,6 +1544,7 @@ e1000_diag_test(struct net_device *netdev, data[2] = 0; data[3] = 0; } + msleep_interruptible(4 * 1000); } static void -- cgit v1.2.2 From a7990ba60adc46a808c737443393fdfecdc82593 Mon Sep 17 00:00:00 2001 From: Mallikarjuna R Chilakala Date: Tue, 4 Oct 2005 07:08:19 -0400 Subject: e1000: Flush shadow RAM Flush shadow RAM to save updates to ASF related bits for 82573 controllers. These bits are past the first 63 words of NVM. Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak Signed-off-by: Jeff Garzik --- drivers/net/e1000/e1000_ethtool.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/net/e1000/e1000_ethtool.c') diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index ee66947e5043..6b9acc7f94a3 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -547,8 +547,10 @@ e1000_set_eeprom(struct net_device *netdev, ret_val = e1000_write_eeprom(hw, first_word, last_word - first_word + 1, eeprom_buff); - /* Update the checksum over the first part of the EEPROM if needed */ - if((ret_val == 0) && first_word <= EEPROM_CHECKSUM_REG) + /* Update the checksum over the first part of the EEPROM if needed + * and flush shadow RAM for 82573 conrollers */ + if((ret_val == 0) && ((first_word <= EEPROM_CHECKSUM_REG) || + (hw->mac_type == e1000_82573))) e1000_update_eeprom_checksum(hw); kfree(eeprom_buff); -- cgit v1.2.2