From 7c510e4b730a92cecf94ada45c989d8be0200d47 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 27 Oct 2008 17:47:26 -0700 Subject: net: convert more to %pM A number of places still use %02x:...:%02x because it's in debug statements or for no real reason. Make a few of them use %pM. Signed-off-by: Johannes Berg Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/net/igb/igb_main.c') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 1f397cd99414..3b42665ef1d4 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1275,16 +1275,14 @@ static int __devinit igb_probe(struct pci_dev *pdev, dev_info(&pdev->dev, "Intel(R) Gigabit Ethernet Network Connection\n"); /* print bus type/speed/width info */ - dev_info(&pdev->dev, - "%s: (PCIe:%s:%s) %02x:%02x:%02x:%02x:%02x:%02x\n", + dev_info(&pdev->dev, "%s: (PCIe:%s:%s) %pM\n", netdev->name, ((hw->bus.speed == e1000_bus_speed_2500) ? "2.5Gb/s" : "unknown"), ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" : (hw->bus.width == e1000_bus_width_pcie_x1) ? "Width x1" : "unknown"), - netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2], - netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]); + netdev->dev_addr); igb_read_part_num(hw, &part_num); dev_info(&pdev->dev, "%s: PBA No: %06x-%03x\n", netdev->name, -- cgit v1.2.3 From babcda74e9d96bb58fd9c6c5112dbdbff169e695 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 3 Nov 2008 21:11:17 -0800 Subject: drivers/net: Kill now superfluous ->last_rx stores. The generic packet receive code takes care of setting netdev->last_rx when necessary, for the sake of the bonding ARP monitor. Drivers need not do it any more. Some cases had to be skipped over because the drivers were making use of the ->last_rx value themselves. Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/net/igb/igb_main.c') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 3b42665ef1d4..89ffc0757e01 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -3940,8 +3940,6 @@ send_up: igb_receive_skb(rx_ring, staterr, rx_desc, skb); - netdev->last_rx = jiffies; - next_desc: rx_desc->wb.upper.status_error = 0; -- cgit v1.2.3 From 2e5c69228ef52b8fe6b3d38caf45f03b22fda7bd Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 19 Nov 2008 22:20:44 -0800 Subject: igb: convert to net_device_ops Convert to new network device ops interface. Compile tested only. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'drivers/net/igb/igb_main.c') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 5f954b01e21a..1026ef402d47 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -950,6 +950,24 @@ static int igb_is_need_ioport(struct pci_dev *pdev) } } +static const struct net_device_ops igb_netdev_ops = { + .ndo_open = igb_open, + .ndo_stop = igb_close, + .ndo_get_stats = igb_get_stats, + .ndo_set_multicast_list = igb_set_multi, + .ndo_set_mac_address = igb_set_mac, + .ndo_change_mtu = igb_change_mtu, + .ndo_do_ioctl = igb_ioctl, + .ndo_tx_timeout = igb_tx_timeout, + .ndo_validate_addr = eth_validate_addr, + .ndo_vlan_rx_register = igb_vlan_rx_register, + .ndo_vlan_rx_add_vid = igb_vlan_rx_add_vid, + .ndo_vlan_rx_kill_vid = igb_vlan_rx_kill_vid, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = igb_netpoll, +#endif +}; + /** * igb_probe - Device Initialization Routine * @pdev: PCI device information struct @@ -1059,22 +1077,9 @@ static int __devinit igb_probe(struct pci_dev *pdev, if (!adapter->hw.hw_addr) goto err_ioremap; - netdev->open = &igb_open; - netdev->stop = &igb_close; - netdev->get_stats = &igb_get_stats; - netdev->set_multicast_list = &igb_set_multi; - netdev->set_mac_address = &igb_set_mac; - netdev->change_mtu = &igb_change_mtu; - netdev->do_ioctl = &igb_ioctl; + netdev->netdev_ops = &igb_netdev_ops; igb_set_ethtool_ops(netdev); - netdev->tx_timeout = &igb_tx_timeout; netdev->watchdog_timeo = 5 * HZ; - netdev->vlan_rx_register = igb_vlan_rx_register; - netdev->vlan_rx_add_vid = igb_vlan_rx_add_vid; - netdev->vlan_rx_kill_vid = igb_vlan_rx_kill_vid; -#ifdef CONFIG_NET_POLL_CONTROLLER - netdev->poll_controller = igb_netpoll; -#endif netdev->hard_start_xmit = &igb_xmit_frame_adv; strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1); -- cgit v1.2.3 From b2d565365e02947699a8e3d594275662a8d00646 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 20 Nov 2008 00:47:34 -0800 Subject: igb: simplify swap in clean_rx_irq if using packet split This update replaces the xchg calls that were added with a pair of assignments as there is no need for the xchg calls and they were found to cause issues on some architectures. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/net/igb/igb_main.c') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 1026ef402d47..0d33378edc63 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -3926,8 +3926,10 @@ send_up: next_buffer = &rx_ring->buffer_info[i]; if (!(staterr & E1000_RXD_STAT_EOP)) { - buffer_info->skb = xchg(&next_buffer->skb, skb); - buffer_info->dma = xchg(&next_buffer->dma, 0); + buffer_info->skb = next_buffer->skb; + buffer_info->dma = next_buffer->dma; + next_buffer->skb = skb; + next_buffer->dma = 0; goto next_desc; } -- cgit v1.2.3 From 68fd991020fdf51bc94327d288ae4ae5d0b8dced Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 20 Nov 2008 00:48:10 -0800 Subject: igb: Fix tx/rx_ring_count parameters for igb on suspend/resume/ring resize When suspending the device the ring structure is freed which causes it to loose track of the count. To resolve this we need to move the ring count outside of the ring structure and store it in the adapter struct. In addition to resolving the suspend/resume issue this patch also addresses issues seen in the event of memory allocation errors causing uneven ring sizes on multiple queues. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/net/igb/igb_main.c') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 0d33378edc63..ceb0a0458796 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -76,8 +76,6 @@ static int igb_setup_all_tx_resources(struct igb_adapter *); static int igb_setup_all_rx_resources(struct igb_adapter *); static void igb_free_all_tx_resources(struct igb_adapter *); static void igb_free_all_rx_resources(struct igb_adapter *); -static void igb_free_tx_resources(struct igb_ring *); -static void igb_free_rx_resources(struct igb_ring *); void igb_update_stats(struct igb_adapter *); static int igb_probe(struct pci_dev *, const struct pci_device_id *); static void __devexit igb_remove(struct pci_dev *pdev); @@ -259,11 +257,13 @@ static int igb_alloc_queues(struct igb_adapter *adapter) for (i = 0; i < adapter->num_tx_queues; i++) { struct igb_ring *ring = &(adapter->tx_ring[i]); + ring->count = adapter->tx_ring_count; ring->adapter = adapter; ring->queue_index = i; } for (i = 0; i < adapter->num_rx_queues; i++) { struct igb_ring *ring = &(adapter->rx_ring[i]); + ring->count = adapter->rx_ring_count; ring->adapter = adapter; ring->queue_index = i; ring->itr_register = E1000_ITR; @@ -1400,6 +1400,8 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter) pci_read_config_word(pdev, PCI_COMMAND, &hw->bus.pci_cmd_word); + adapter->tx_ring_count = IGB_DEFAULT_TXD; + adapter->rx_ring_count = IGB_DEFAULT_RXD; adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE; adapter->rx_ps_hdr_size = 0; /* disable packet split */ adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; @@ -1988,7 +1990,7 @@ static void igb_configure_rx(struct igb_adapter *adapter) * * Free all transmit software resources **/ -static void igb_free_tx_resources(struct igb_ring *tx_ring) +void igb_free_tx_resources(struct igb_ring *tx_ring) { struct pci_dev *pdev = tx_ring->adapter->pdev; @@ -2088,7 +2090,7 @@ static void igb_clean_all_tx_rings(struct igb_adapter *adapter) * * Free all receive software resources **/ -static void igb_free_rx_resources(struct igb_ring *rx_ring) +void igb_free_rx_resources(struct igb_ring *rx_ring) { struct pci_dev *pdev = rx_ring->adapter->pdev; -- cgit v1.2.3 From 008298231abbeb91bc7be9e8b078607b816d1a4a Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 20 Nov 2008 20:14:53 -0800 Subject: netdev: add more functions to netdevice ops This patch moves neigh_setup and hard_start_xmit into the network device ops structure. For bisection, fix all the previously converted drivers as well. Bonding driver took the biggest hit on this. Added a prefetch of the hard_start_xmit in the fast path to try and reduce any impact this would have. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/igb/igb_main.c') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index ceb0a0458796..eca5684d5655 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -953,6 +953,7 @@ static int igb_is_need_ioport(struct pci_dev *pdev) static const struct net_device_ops igb_netdev_ops = { .ndo_open = igb_open, .ndo_stop = igb_close, + .ndo_start_xmit = igb_xmit_frame_adv, .ndo_get_stats = igb_get_stats, .ndo_set_multicast_list = igb_set_multi, .ndo_set_mac_address = igb_set_mac, @@ -1080,7 +1081,6 @@ static int __devinit igb_probe(struct pci_dev *pdev, netdev->netdev_ops = &igb_netdev_ops; igb_set_ethtool_ops(netdev); netdev->watchdog_timeo = 5 * HZ; - netdev->hard_start_xmit = &igb_xmit_frame_adv; strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1); -- cgit v1.2.3 From f5f4cf08467db10de061a1b90037a56a360d3554 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 21 Nov 2008 21:30:24 -0800 Subject: igb: do not use phy ops in ethtool test cleanup for non-copper parts Currently the igb driver is experiencing a panic due to a null function pointer being used during the cleanup of the ethtool looback test on fiber/serdes parts. This patch prevents that and adds a check prior to calling any phy function. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'drivers/net/igb/igb_main.c') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index eca5684d5655..b64c41a44dfc 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -931,8 +931,7 @@ void igb_reset(struct igb_adapter *adapter) wr32(E1000_VET, ETHERNET_IEEE_VLAN_TYPE); igb_reset_adaptive(&adapter->hw); - if (adapter->hw.phy.ops.get_phy_info) - adapter->hw.phy.ops.get_phy_info(&adapter->hw); + igb_get_phy_info(&adapter->hw); } /** @@ -1305,7 +1304,7 @@ err_register: igb_release_hw_control(adapter); err_eeprom: if (!igb_check_reset_block(hw)) - hw->phy.ops.reset_phy(hw); + igb_reset_phy(hw); if (hw->flash_address) iounmap(hw->flash_address); @@ -1365,9 +1364,8 @@ static void __devexit igb_remove(struct pci_dev *pdev) unregister_netdev(netdev); - if (adapter->hw.phy.ops.reset_phy && - !igb_check_reset_block(&adapter->hw)) - adapter->hw.phy.ops.reset_phy(&adapter->hw); + if (!igb_check_reset_block(&adapter->hw)) + igb_reset_phy(&adapter->hw); igb_remove_device(&adapter->hw); igb_reset_interrupt_capability(adapter); @@ -2283,8 +2281,7 @@ static void igb_set_multi(struct net_device *netdev) static void igb_update_phy_info(unsigned long data) { struct igb_adapter *adapter = (struct igb_adapter *) data; - if (adapter->hw.phy.ops.get_phy_info) - adapter->hw.phy.ops.get_phy_info(&adapter->hw); + igb_get_phy_info(&adapter->hw); } /** @@ -3258,7 +3255,7 @@ void igb_update_stats(struct igb_adapter *adapter) /* Phy Stats */ if (hw->phy.media_type == e1000_media_type_copper) { if ((adapter->link_speed == SPEED_1000) && - (!hw->phy.ops.read_phy_reg(hw, PHY_1000T_STATUS, + (!igb_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) { phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK; adapter->phy_stats.idle_errors += phy_tmp; @@ -4111,9 +4108,8 @@ static int igb_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) case SIOCGMIIREG: if (!capable(CAP_NET_ADMIN)) return -EPERM; - if (adapter->hw.phy.ops.read_phy_reg(&adapter->hw, - data->reg_num - & 0x1F, &data->val_out)) + if (igb_read_phy_reg(&adapter->hw, data->reg_num & 0x1F, + &data->val_out)) return -EIO; break; case SIOCSMIIREG: -- cgit v1.2.3 From 9b07f3d3157487e6467dfa4640f7fb9446165494 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 25 Nov 2008 01:03:26 -0800 Subject: igb: remove unneeded bit refrence when enabling jumbo frames There is a reference to a Buffer Size extention bit that is unneded by 82575/82576 hardware. Since it is not needed it should be removed from the code. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) (limited to 'drivers/net/igb/igb_main.c') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index b64c41a44dfc..ae65fae4333d 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1791,37 +1791,29 @@ static void igb_setup_rctl(struct igb_adapter *adapter) */ rctl |= E1000_RCTL_SECRC; - rctl &= ~E1000_RCTL_SBP; + /* + * disable store bad packets, long packet enable, and clear size bits. + */ + rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_LPE | E1000_RCTL_SZ_256); - if (adapter->netdev->mtu <= ETH_DATA_LEN) - rctl &= ~E1000_RCTL_LPE; - else - rctl |= E1000_RCTL_LPE; - if (adapter->rx_buffer_len <= IGB_RXBUFFER_2048) { + if (adapter->netdev->mtu <= ETH_DATA_LEN) { /* Setup buffer sizes */ - rctl &= ~E1000_RCTL_SZ_4096; - rctl |= E1000_RCTL_BSEX; switch (adapter->rx_buffer_len) { case IGB_RXBUFFER_256: rctl |= E1000_RCTL_SZ_256; - rctl &= ~E1000_RCTL_BSEX; break; case IGB_RXBUFFER_512: rctl |= E1000_RCTL_SZ_512; - rctl &= ~E1000_RCTL_BSEX; break; case IGB_RXBUFFER_1024: rctl |= E1000_RCTL_SZ_1024; - rctl &= ~E1000_RCTL_BSEX; break; - case IGB_RXBUFFER_2048: default: rctl |= E1000_RCTL_SZ_2048; - rctl &= ~E1000_RCTL_BSEX; break; } } else { - rctl &= ~E1000_RCTL_BSEX; + rctl |= E1000_RCTL_LPE; srrctl = adapter->rx_buffer_len >> E1000_SRRCTL_BSIZEPKT_SHIFT; } -- cgit v1.2.3 From 69d728baf620839d1a3c874eecac316729f89de4 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Tue, 25 Nov 2008 01:04:03 -0800 Subject: igb: loopback bits not correctly cleared from RCTL register This change forces the bits to 0 by using an &= operation with an inverted mask of all options instead of using an |= with a value of 0. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/igb/igb_main.c') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index ae65fae4333d..ab37ab03a45c 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1779,9 +1779,9 @@ static void igb_setup_rctl(struct igb_adapter *adapter) rctl = rd32(E1000_RCTL); rctl &= ~(3 << E1000_RCTL_MO_SHIFT); + rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC); - rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | - E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF | + rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_RDMTS_HALF | (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT); /* -- cgit v1.2.3 From 527d47c11149afb5dd59eaca57d5b4d816ac4f20 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 27 Nov 2008 00:21:39 -0800 Subject: igb: link up/down messages must follow a specific format The system log messages created on a link status change need to follow a specific format to work with tools some customers use. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/net/igb/igb_main.c') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index d7daf12ab07d..648f5a29d490 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -2324,9 +2324,10 @@ static void igb_watchdog_task(struct work_struct *work) &adapter->link_duplex); ctrl = rd32(E1000_CTRL); - dev_info(&adapter->pdev->dev, - "NIC Link is Up %d Mbps %s, " + /* Links status message must follow this format */ + printk(KERN_INFO "igb: %s NIC Link is Up %d Mbps %s, " "Flow Control: %s\n", + netdev->name, adapter->link_speed, adapter->link_duplex == FULL_DUPLEX ? "Full Duplex" : "Half Duplex", @@ -2361,7 +2362,9 @@ static void igb_watchdog_task(struct work_struct *work) if (netif_carrier_ok(netdev)) { adapter->link_speed = 0; adapter->link_duplex = 0; - dev_info(&adapter->pdev->dev, "NIC Link is Down\n"); + /* Links status message must follow this format */ + printk(KERN_INFO "igb: %s NIC Link is Down\n", + netdev->name); netif_carrier_off(netdev); netif_tx_stop_all_queues(netdev); if (!test_bit(__IGB_DOWN, &adapter->state)) -- cgit v1.2.3 From 40a914fa72abdb9193ecad7dd82e48d952ab9d24 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 27 Nov 2008 00:24:37 -0800 Subject: igb: Add support for pci-e Advanced Error Reporting Add the calls necessary to enable advanced error reporting for igb on systems with AER enabled. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'drivers/net/igb/igb_main.c') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 648f5a29d490..a08921e9cbe6 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -42,6 +42,7 @@ #include #include #include +#include #ifdef CONFIG_IGB_DCA #include #endif @@ -1049,6 +1050,8 @@ static int __devinit igb_probe(struct pci_dev *pdev, if (err) goto err_pci_reg; + pci_enable_pcie_error_reporting(pdev); + pci_set_master(pdev); pci_save_state(pdev); @@ -1379,6 +1382,8 @@ static void __devexit igb_remove(struct pci_dev *pdev) free_netdev(netdev); + pci_disable_pcie_error_reporting(pdev); + pci_disable_device(pdev); } @@ -4470,27 +4475,33 @@ static pci_ers_result_t igb_io_slot_reset(struct pci_dev *pdev) struct net_device *netdev = pci_get_drvdata(pdev); struct igb_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; + pci_ers_result_t result; int err; if (adapter->need_ioport) err = pci_enable_device(pdev); else err = pci_enable_device_mem(pdev); + if (err) { dev_err(&pdev->dev, "Cannot re-enable PCI device after reset.\n"); - return PCI_ERS_RESULT_DISCONNECT; - } - pci_set_master(pdev); - pci_restore_state(pdev); + result = PCI_ERS_RESULT_DISCONNECT; + } else { + pci_set_master(pdev); + pci_restore_state(pdev); - pci_enable_wake(pdev, PCI_D3hot, 0); - pci_enable_wake(pdev, PCI_D3cold, 0); + pci_enable_wake(pdev, PCI_D3hot, 0); + pci_enable_wake(pdev, PCI_D3cold, 0); - igb_reset(adapter); - wr32(E1000_WUS, ~0); + igb_reset(adapter); + wr32(E1000_WUS, ~0); + result = PCI_ERS_RESULT_RECOVERED; + } - return PCI_ERS_RESULT_RECOVERED; + pci_cleanup_aer_uncorrect_error_status(pdev); + + return result; } /** @@ -4518,7 +4529,6 @@ static void igb_io_resume(struct pci_dev *pdev) /* let the f/w know that the h/w is now under the control of the * driver. */ igb_get_hw_control(adapter); - } /* igb_main.c */ -- cgit v1.2.3 From cb7b48f671f9c7582993a6c0ff6e989078048561 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 5 Dec 2008 15:08:03 -0800 Subject: igb/e1000e: Naming interrupt vectors Change interrupt vector naming to match recent changes from Robert Olsson. Signed-off-by: Alexander Duyck Acked-by: Bruce Allan Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/igb/igb_main.c') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index a08921e9cbe6..c49b8d8f80f2 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -446,7 +446,7 @@ static int igb_request_msix(struct igb_adapter *adapter) for (i = 0; i < adapter->num_tx_queues; i++) { struct igb_ring *ring = &(adapter->tx_ring[i]); - sprintf(ring->name, "%s-tx%d", netdev->name, i); + sprintf(ring->name, "%s-tx-%d", netdev->name, i); err = request_irq(adapter->msix_entries[vector].vector, &igb_msix_tx, 0, ring->name, &(adapter->tx_ring[i])); @@ -459,7 +459,7 @@ static int igb_request_msix(struct igb_adapter *adapter) for (i = 0; i < adapter->num_rx_queues; i++) { struct igb_ring *ring = &(adapter->rx_ring[i]); if (strlen(netdev->name) < (IFNAMSIZ - 5)) - sprintf(ring->name, "%s-rx%d", netdev->name, i); + sprintf(ring->name, "%s-rx-%d", netdev->name, i); else memcpy(ring->name, netdev->name, IFNAMSIZ); err = request_irq(adapter->msix_entries[vector].vector, -- cgit v1.2.3 From b4557be23dc959f38eed21d359ec7164e42bcbd6 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 10 Dec 2008 01:08:59 -0800 Subject: igb: update handling of RCTL for smaller buffer sizes As we begin to move into virtualization the use of a global value for buffer sizes becomes undesirable. This change makes it so only 256 and 512 byte buffers require use of the RCTL register. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) (limited to 'drivers/net/igb/igb_main.c') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index c49b8d8f80f2..dad742f8d23a 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1801,25 +1801,21 @@ static void igb_setup_rctl(struct igb_adapter *adapter) */ rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_LPE | E1000_RCTL_SZ_256); - if (adapter->netdev->mtu <= ETH_DATA_LEN) { - /* Setup buffer sizes */ - switch (adapter->rx_buffer_len) { - case IGB_RXBUFFER_256: - rctl |= E1000_RCTL_SZ_256; - break; - case IGB_RXBUFFER_512: - rctl |= E1000_RCTL_SZ_512; - break; - case IGB_RXBUFFER_1024: - rctl |= E1000_RCTL_SZ_1024; - break; - default: - rctl |= E1000_RCTL_SZ_2048; - break; - } - } else { + if (adapter->netdev->mtu > ETH_DATA_LEN) rctl |= E1000_RCTL_LPE; - srrctl = adapter->rx_buffer_len >> E1000_SRRCTL_BSIZEPKT_SHIFT; + + /* Setup buffer sizes */ + switch (adapter->rx_buffer_len) { + case IGB_RXBUFFER_256: + rctl |= E1000_RCTL_SZ_256; + break; + case IGB_RXBUFFER_512: + rctl |= E1000_RCTL_SZ_512; + break; + default: + srrctl = ALIGN(adapter->rx_buffer_len, 1024) + >> E1000_SRRCTL_BSIZEPKT_SHIFT; + break; } /* 82575 and greater support packet-split where the protocol -- cgit v1.2.3 From ea943d41a8770857d50029fdc8fd111635c21a1f Mon Sep 17 00:00:00 2001 From: Jeff Kirsher Date: Thu, 11 Dec 2008 20:34:19 -0800 Subject: igb: fixup AER with proper error handling Based on Peter Waskiewicz patch for ixgbe. Add error handling based on Hemminger's recommendation. Signed-off-by: Jeff Kirsher Acked-by: Peter P Waskiewicz Jr Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'drivers/net/igb/igb_main.c') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index dad742f8d23a..25df7c931064 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1050,7 +1050,12 @@ static int __devinit igb_probe(struct pci_dev *pdev, if (err) goto err_pci_reg; - pci_enable_pcie_error_reporting(pdev); + err = pci_enable_pcie_error_reporting(pdev); + if (err) { + dev_err(&pdev->dev, "pci_enable_pcie_error_reporting failed " + "0x%x\n", err); + /* non-fatal, continue */ + } pci_set_master(pdev); pci_save_state(pdev); @@ -1343,6 +1348,7 @@ static void __devexit igb_remove(struct pci_dev *pdev) #ifdef CONFIG_IGB_DCA struct e1000_hw *hw = &adapter->hw; #endif + int err; /* flush_scheduled work may reschedule our watchdog task, so * explicitly disable watchdog tasks from being rescheduled */ @@ -1382,7 +1388,10 @@ static void __devexit igb_remove(struct pci_dev *pdev) free_netdev(netdev); - pci_disable_pcie_error_reporting(pdev); + err = pci_disable_pcie_error_reporting(pdev); + if (err) + dev_err(&pdev->dev, + "pci_disable_pcie_error_reporting failed 0x%x\n", err); pci_disable_device(pdev); } @@ -4495,7 +4504,12 @@ static pci_ers_result_t igb_io_slot_reset(struct pci_dev *pdev) result = PCI_ERS_RESULT_RECOVERED; } - pci_cleanup_aer_uncorrect_error_status(pdev); + err = pci_cleanup_aer_uncorrect_error_status(pdev); + if (err) { + dev_err(&pdev->dev, "pci_cleanup_aer_uncorrect_error_status " + "failed 0x%0x\n", err); + /* non-fatal, continue */ + } return result; } -- cgit v1.2.3 From 908a7a16b852ffd618a9127be8d62432182d81b4 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Mon, 22 Dec 2008 20:43:12 -0800 Subject: net: Remove unused netdev arg from some NAPI interfaces. When the napi api was changed to separate its 1:1 binding to the net_device struct, the netif_rx_[prep|schedule|complete] api failed to remove the now vestigual net_device structure parameter. This patch cleans up that api by properly removing it.. Signed-off-by: Neil Horman Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/net/igb/igb_main.c') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 25df7c931064..6a40d9486daf 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -3347,8 +3347,8 @@ static irqreturn_t igb_msix_rx(int irq, void *data) igb_write_itr(rx_ring); - if (netif_rx_schedule_prep(adapter->netdev, &rx_ring->napi)) - __netif_rx_schedule(adapter->netdev, &rx_ring->napi); + if (netif_rx_schedule_prep(&rx_ring->napi)) + __netif_rx_schedule(&rx_ring->napi); #ifdef CONFIG_IGB_DCA if (adapter->flags & IGB_FLAG_DCA_ENABLED) @@ -3500,7 +3500,7 @@ static irqreturn_t igb_intr_msi(int irq, void *data) mod_timer(&adapter->watchdog_timer, jiffies + 1); } - netif_rx_schedule(netdev, &adapter->rx_ring[0].napi); + netif_rx_schedule(&adapter->rx_ring[0].napi); return IRQ_HANDLED; } @@ -3538,7 +3538,7 @@ static irqreturn_t igb_intr(int irq, void *data) mod_timer(&adapter->watchdog_timer, jiffies + 1); } - netif_rx_schedule(netdev, &adapter->rx_ring[0].napi); + netif_rx_schedule(&adapter->rx_ring[0].napi); return IRQ_HANDLED; } @@ -3573,7 +3573,7 @@ static int igb_poll(struct napi_struct *napi, int budget) !netif_running(netdev)) { if (adapter->itr_setting & 3) igb_set_itr(adapter); - netif_rx_complete(netdev, napi); + netif_rx_complete(napi); if (!test_bit(__IGB_DOWN, &adapter->state)) igb_irq_enable(adapter); return 0; @@ -3599,7 +3599,7 @@ static int igb_clean_rx_ring_msix(struct napi_struct *napi, int budget) /* If not enough Rx work done, exit the polling mode */ if ((work_done == 0) || !netif_running(netdev)) { - netif_rx_complete(netdev, napi); + netif_rx_complete(napi); if (adapter->itr_setting & 3) { if (adapter->num_rx_queues == 1) -- cgit v1.2.3 From 0e014cb16234c3797aa518d46fe7e1fe91ebcca9 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 26 Dec 2008 01:33:18 -0800 Subject: igb: defeature tx head writeback This patch removes tx head writeback as it was found to not provide a significant improvement in tx performance and on some systems has been seen to cause a performance degredation due to partial cache line writes. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 85 ++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 49 deletions(-) (limited to 'drivers/net/igb/igb_main.c') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 6a40d9486daf..4962cdfc507c 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -1575,8 +1575,7 @@ int igb_setup_tx_resources(struct igb_adapter *adapter, memset(tx_ring->buffer_info, 0, size); /* round up to nearest 4K */ - tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc) - + sizeof(u32); + tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc); tx_ring->size = ALIGN(tx_ring->size, 4096); tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size, @@ -1635,7 +1634,7 @@ static int igb_setup_all_tx_resources(struct igb_adapter *adapter) **/ static void igb_configure_tx(struct igb_adapter *adapter) { - u64 tdba, tdwba; + u64 tdba; struct e1000_hw *hw = &adapter->hw; u32 tctl; u32 txdctl, txctrl; @@ -1651,12 +1650,6 @@ static void igb_configure_tx(struct igb_adapter *adapter) tdba & 0x00000000ffffffffULL); wr32(E1000_TDBAH(i), tdba >> 32); - tdwba = ring->dma + ring->count * sizeof(struct e1000_tx_desc); - tdwba |= 1; /* enable head wb */ - wr32(E1000_TDWBAL(i), - tdwba & 0x00000000ffffffffULL); - wr32(E1000_TDWBAH(i), tdwba >> 32); - ring->head = E1000_TDH(i); ring->tail = E1000_TDT(i); writel(0, hw->hw_addr + ring->tail); @@ -2710,6 +2703,7 @@ static inline int igb_tso_adv(struct igb_adapter *adapter, context_desc->seqnum_seed = 0; buffer_info->time_stamp = jiffies; + buffer_info->next_to_watch = i; buffer_info->dma = 0; i++; if (i == tx_ring->count) @@ -2773,6 +2767,7 @@ static inline bool igb_tx_csum_adv(struct igb_adapter *adapter, cpu_to_le32(tx_ring->queue_index << 4); buffer_info->time_stamp = jiffies; + buffer_info->next_to_watch = i; buffer_info->dma = 0; i++; @@ -2791,8 +2786,8 @@ static inline bool igb_tx_csum_adv(struct igb_adapter *adapter, #define IGB_MAX_DATA_PER_TXD (1<length = len; /* set time_stamp *before* dma to help avoid a possible race */ buffer_info->time_stamp = jiffies; + buffer_info->next_to_watch = i; buffer_info->dma = pci_map_single(adapter->pdev, skb->data, len, PCI_DMA_TODEVICE); count++; @@ -2823,6 +2819,7 @@ static inline int igb_tx_map_adv(struct igb_adapter *adapter, BUG_ON(len >= IGB_MAX_DATA_PER_TXD); buffer_info->length = len; buffer_info->time_stamp = jiffies; + buffer_info->next_to_watch = i; buffer_info->dma = pci_map_page(adapter->pdev, frag->page, frag->page_offset, @@ -2835,8 +2832,9 @@ static inline int igb_tx_map_adv(struct igb_adapter *adapter, i = 0; } - i = (i == 0) ? tx_ring->count - 1 : i - 1; + i = ((i == 0) ? tx_ring->count - 1 : i - 1); tx_ring->buffer_info[i].skb = skb; + tx_ring->buffer_info[first].next_to_watch = i; return count; } @@ -2943,6 +2941,7 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb, struct igb_ring *tx_ring) { struct igb_adapter *adapter = netdev_priv(netdev); + unsigned int first; unsigned int tx_flags = 0; unsigned int len; u8 hdr_len = 0; @@ -2979,6 +2978,8 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb, if (skb->protocol == htons(ETH_P_IP)) tx_flags |= IGB_TX_FLAGS_IPV4; + first = tx_ring->next_to_use; + tso = skb_is_gso(skb) ? igb_tso_adv(adapter, tx_ring, skb, tx_flags, &hdr_len) : 0; @@ -2994,7 +2995,7 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb, tx_flags |= IGB_TX_FLAGS_CSUM; igb_tx_queue_adv(adapter, tx_ring, tx_flags, - igb_tx_map_adv(adapter, tx_ring, skb), + igb_tx_map_adv(adapter, tx_ring, skb, first), skb->len, hdr_len); netdev->trans_start = jiffies; @@ -3617,12 +3618,6 @@ static int igb_clean_rx_ring_msix(struct napi_struct *napi, int budget) return 1; } -static inline u32 get_head(struct igb_ring *tx_ring) -{ - void *end = (struct e1000_tx_desc *)tx_ring->desc + tx_ring->count; - return le32_to_cpu(*(volatile __le32 *)end); -} - /** * igb_clean_tx_irq - Reclaim resources after transmit completes * @adapter: board private structure @@ -3631,24 +3626,25 @@ static inline u32 get_head(struct igb_ring *tx_ring) static bool igb_clean_tx_irq(struct igb_ring *tx_ring) { struct igb_adapter *adapter = tx_ring->adapter; - struct e1000_hw *hw = &adapter->hw; struct net_device *netdev = adapter->netdev; - struct e1000_tx_desc *tx_desc; + struct e1000_hw *hw = &adapter->hw; struct igb_buffer *buffer_info; struct sk_buff *skb; - unsigned int i; - u32 head, oldhead; - unsigned int count = 0; + union e1000_adv_tx_desc *tx_desc, *eop_desc; unsigned int total_bytes = 0, total_packets = 0; - bool retval = true; + unsigned int i, eop, count = 0; + bool cleaned = false; - rmb(); - head = get_head(tx_ring); i = tx_ring->next_to_clean; - while (1) { - while (i != head) { - tx_desc = E1000_TX_DESC(*tx_ring, i); + eop = tx_ring->buffer_info[i].next_to_watch; + eop_desc = E1000_TX_DESC_ADV(*tx_ring, eop); + + while ((eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)) && + (count < tx_ring->count)) { + for (cleaned = false; !cleaned; count++) { + tx_desc = E1000_TX_DESC_ADV(*tx_ring, i); buffer_info = &tx_ring->buffer_info[i]; + cleaned = (i == eop); skb = buffer_info->skb; if (skb) { @@ -3663,25 +3659,17 @@ static bool igb_clean_tx_irq(struct igb_ring *tx_ring) } igb_unmap_and_free_tx_resource(adapter, buffer_info); + tx_desc->wb.status = 0; i++; if (i == tx_ring->count) i = 0; - - count++; - if (count == IGB_MAX_TX_CLEAN) { - retval = false; - goto done_cleaning; - } } - oldhead = head; - rmb(); - head = get_head(tx_ring); - if (head == oldhead) - goto done_cleaning; - } /* while (1) */ - -done_cleaning: + + eop = tx_ring->buffer_info[i].next_to_watch; + eop_desc = E1000_TX_DESC_ADV(*tx_ring, eop); + } + tx_ring->next_to_clean = i; if (unlikely(count && @@ -3708,7 +3696,6 @@ done_cleaning: && !(rd32(E1000_STATUS) & E1000_STATUS_TXOFF)) { - tx_desc = E1000_TX_DESC(*tx_ring, i); /* detected Tx unit hang */ dev_err(&adapter->pdev->dev, "Detected Tx Unit Hang\n" @@ -3717,9 +3704,9 @@ done_cleaning: " TDT <%x>\n" " next_to_use <%x>\n" " next_to_clean <%x>\n" - " head (WB) <%x>\n" "buffer_info[next_to_clean]\n" " time_stamp <%lx>\n" + " next_to_watch <%x>\n" " jiffies <%lx>\n" " desc.status <%x>\n", tx_ring->queue_index, @@ -3727,10 +3714,10 @@ done_cleaning: readl(adapter->hw.hw_addr + tx_ring->tail), tx_ring->next_to_use, tx_ring->next_to_clean, - head, tx_ring->buffer_info[i].time_stamp, + eop, jiffies, - tx_desc->upper.fields.status); + eop_desc->wb.status); netif_stop_subqueue(netdev, tx_ring->queue_index); } } @@ -3740,7 +3727,7 @@ done_cleaning: tx_ring->tx_stats.packets += total_packets; adapter->net_stats.tx_bytes += total_bytes; adapter->net_stats.tx_packets += total_packets; - return retval; + return (count < tx_ring->count); } #ifdef CONFIG_IGB_LRO -- cgit v1.2.3 From 26bc19ecf6c077c926827c25631340fd2e8fb16e Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 26 Dec 2008 01:34:11 -0800 Subject: igb: re-order queues to support cleaner use of ivar on 82576 The 82576 adapter orders the queues in pairs when virtualization is in use. The queue ordering previously conflicted with the ordering when sr-iov was enabled. This new ordering allows a PF to allocate 2 queues without using any VF resources. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 115 ++++++++++++++++++++++++++++++--------------- 1 file changed, 77 insertions(+), 38 deletions(-) (limited to 'drivers/net/igb/igb_main.c') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 4962cdfc507c..9331e5212461 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -231,6 +231,40 @@ static void __exit igb_exit_module(void) module_exit(igb_exit_module); +#define Q_IDX_82576(i) (((i & 0x1) << 3) + (i >> 1)) +/** + * igb_cache_ring_register - Descriptor ring to register mapping + * @adapter: board private structure to initialize + * + * Once we know the feature-set enabled for the device, we'll cache + * the register offset the descriptor ring is assigned to. + **/ +static void igb_cache_ring_register(struct igb_adapter *adapter) +{ + int i; + + switch (adapter->hw.mac.type) { + case e1000_82576: + /* The queues are allocated for virtualization such that VF 0 + * is allocated queues 0 and 8, VF 1 queues 1 and 9, etc. + * In order to avoid collision we start at the first free queue + * and continue consuming queues in the same sequence + */ + for (i = 0; i < adapter->num_rx_queues; i++) + adapter->rx_ring[i].reg_idx = Q_IDX_82576(i); + for (i = 0; i < adapter->num_tx_queues; i++) + adapter->tx_ring[i].reg_idx = Q_IDX_82576(i); + break; + case e1000_82575: + default: + for (i = 0; i < adapter->num_rx_queues; i++) + adapter->rx_ring[i].reg_idx = i; + for (i = 0; i < adapter->num_tx_queues; i++) + adapter->tx_ring[i].reg_idx = i; + break; + } +} + /** * igb_alloc_queues - Allocate memory for all rings * @adapter: board private structure to initialize @@ -272,6 +306,8 @@ static int igb_alloc_queues(struct igb_adapter *adapter) /* set a default napi handler for each rx_ring */ netif_napi_add(adapter->netdev, &ring->napi, igb_poll, 64); } + + igb_cache_ring_register(adapter); return 0; } @@ -312,36 +348,36 @@ static void igb_assign_vector(struct igb_adapter *adapter, int rx_queue, array_wr32(E1000_MSIXBM(0), msix_vector, msixbm); break; case e1000_82576: - /* The 82576 uses a table-based method for assigning vectors. + /* 82576 uses a table-based method for assigning vectors. Each queue has a single entry in the table to which we write a vector number along with a "valid" bit. Sadly, the layout of the table is somewhat counterintuitive. */ if (rx_queue > IGB_N0_QUEUE) { - index = (rx_queue & 0x7); + index = (rx_queue >> 1); ivar = array_rd32(E1000_IVAR0, index); - if (rx_queue < 8) { - /* vector goes into low byte of register */ - ivar = ivar & 0xFFFFFF00; - ivar |= msix_vector | E1000_IVAR_VALID; - } else { + if (rx_queue & 0x1) { /* vector goes into third byte of register */ ivar = ivar & 0xFF00FFFF; ivar |= (msix_vector | E1000_IVAR_VALID) << 16; + } else { + /* vector goes into low byte of register */ + ivar = ivar & 0xFFFFFF00; + ivar |= msix_vector | E1000_IVAR_VALID; } adapter->rx_ring[rx_queue].eims_value= 1 << msix_vector; array_wr32(E1000_IVAR0, index, ivar); } if (tx_queue > IGB_N0_QUEUE) { - index = (tx_queue & 0x7); + index = (tx_queue >> 1); ivar = array_rd32(E1000_IVAR0, index); - if (tx_queue < 8) { - /* vector goes into second byte of register */ - ivar = ivar & 0xFFFF00FF; - ivar |= (msix_vector | E1000_IVAR_VALID) << 8; - } else { + if (tx_queue & 0x1) { /* vector goes into high byte of register */ ivar = ivar & 0x00FFFFFF; ivar |= (msix_vector | E1000_IVAR_VALID) << 24; + } else { + /* vector goes into second byte of register */ + ivar = ivar & 0xFFFF00FF; + ivar |= (msix_vector | E1000_IVAR_VALID) << 8; } adapter->tx_ring[tx_queue].eims_value= 1 << msix_vector; array_wr32(E1000_IVAR0, index, ivar); @@ -1638,33 +1674,33 @@ static void igb_configure_tx(struct igb_adapter *adapter) struct e1000_hw *hw = &adapter->hw; u32 tctl; u32 txdctl, txctrl; - int i; + int i, j; for (i = 0; i < adapter->num_tx_queues; i++) { struct igb_ring *ring = &(adapter->tx_ring[i]); - - wr32(E1000_TDLEN(i), + j = ring->reg_idx; + wr32(E1000_TDLEN(j), ring->count * sizeof(struct e1000_tx_desc)); tdba = ring->dma; - wr32(E1000_TDBAL(i), + wr32(E1000_TDBAL(j), tdba & 0x00000000ffffffffULL); - wr32(E1000_TDBAH(i), tdba >> 32); + wr32(E1000_TDBAH(j), tdba >> 32); - ring->head = E1000_TDH(i); - ring->tail = E1000_TDT(i); + ring->head = E1000_TDH(j); + ring->tail = E1000_TDT(j); writel(0, hw->hw_addr + ring->tail); writel(0, hw->hw_addr + ring->head); - txdctl = rd32(E1000_TXDCTL(i)); + txdctl = rd32(E1000_TXDCTL(j)); txdctl |= E1000_TXDCTL_QUEUE_ENABLE; - wr32(E1000_TXDCTL(i), txdctl); + wr32(E1000_TXDCTL(j), txdctl); /* Turn off Relaxed Ordering on head write-backs. The * writebacks MUST be delivered in order or it will * completely screw up our bookeeping. */ - txctrl = rd32(E1000_DCA_TXCTRL(i)); + txctrl = rd32(E1000_DCA_TXCTRL(j)); txctrl &= ~E1000_DCA_TXCTRL_TX_WB_RO_EN; - wr32(E1000_DCA_TXCTRL(i), txctrl); + wr32(E1000_DCA_TXCTRL(j), txctrl); } @@ -1781,7 +1817,7 @@ static void igb_setup_rctl(struct igb_adapter *adapter) struct e1000_hw *hw = &adapter->hw; u32 rctl; u32 srrctl = 0; - int i; + int i, j; rctl = rd32(E1000_RCTL); @@ -1839,8 +1875,10 @@ static void igb_setup_rctl(struct igb_adapter *adapter) srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF; } - for (i = 0; i < adapter->num_rx_queues; i++) - wr32(E1000_SRRCTL(i), srrctl); + for (i = 0; i < adapter->num_rx_queues; i++) { + j = adapter->rx_ring[i].reg_idx; + wr32(E1000_SRRCTL(j), srrctl); + } wr32(E1000_RCTL, rctl); } @@ -1857,7 +1895,7 @@ static void igb_configure_rx(struct igb_adapter *adapter) struct e1000_hw *hw = &adapter->hw; u32 rctl, rxcsum; u32 rxdctl; - int i; + int i, j; /* disable receives while setting up the descriptors */ rctl = rd32(E1000_RCTL); @@ -1872,25 +1910,26 @@ static void igb_configure_rx(struct igb_adapter *adapter) * the Base and Length of the Rx Descriptor Ring */ for (i = 0; i < adapter->num_rx_queues; i++) { struct igb_ring *ring = &(adapter->rx_ring[i]); + j = ring->reg_idx; rdba = ring->dma; - wr32(E1000_RDBAL(i), + wr32(E1000_RDBAL(j), rdba & 0x00000000ffffffffULL); - wr32(E1000_RDBAH(i), rdba >> 32); - wr32(E1000_RDLEN(i), + wr32(E1000_RDBAH(j), rdba >> 32); + wr32(E1000_RDLEN(j), ring->count * sizeof(union e1000_adv_rx_desc)); - ring->head = E1000_RDH(i); - ring->tail = E1000_RDT(i); + ring->head = E1000_RDH(j); + ring->tail = E1000_RDT(j); writel(0, hw->hw_addr + ring->tail); writel(0, hw->hw_addr + ring->head); - rxdctl = rd32(E1000_RXDCTL(i)); + rxdctl = rd32(E1000_RXDCTL(j)); rxdctl |= E1000_RXDCTL_QUEUE_ENABLE; rxdctl &= 0xFFF00000; rxdctl |= IGB_RX_PTHRESH; rxdctl |= IGB_RX_HTHRESH << 8; rxdctl |= IGB_RX_WTHRESH << 16; - wr32(E1000_RXDCTL(i), rxdctl); + wr32(E1000_RXDCTL(j), rxdctl); #ifdef CONFIG_IGB_LRO /* Intitial LRO Settings */ ring->lro_mgr.max_aggr = MAX_LRO_AGGR; @@ -1920,7 +1959,7 @@ static void igb_configure_rx(struct igb_adapter *adapter) shift = 6; for (j = 0; j < (32 * 4); j++) { reta.bytes[j & 3] = - (j % adapter->num_rx_queues) << shift; + adapter->rx_ring[(j % adapter->num_rx_queues)].reg_idx << shift; if ((j & 3) == 3) writel(reta.dword, hw->hw_addr + E1000_RETA(0) + (j & ~3)); @@ -3365,7 +3404,7 @@ static void igb_update_rx_dca(struct igb_ring *rx_ring) struct igb_adapter *adapter = rx_ring->adapter; struct e1000_hw *hw = &adapter->hw; int cpu = get_cpu(); - int q = rx_ring - adapter->rx_ring; + int q = rx_ring->reg_idx; if (rx_ring->cpu != cpu) { dca_rxctrl = rd32(E1000_DCA_RXCTRL(q)); @@ -3392,7 +3431,7 @@ static void igb_update_tx_dca(struct igb_ring *tx_ring) struct igb_adapter *adapter = tx_ring->adapter; struct e1000_hw *hw = &adapter->hw; int cpu = get_cpu(); - int q = tx_ring - adapter->tx_ring; + int q = tx_ring->reg_idx; if (tx_ring->cpu != cpu) { dca_txctrl = rd32(E1000_DCA_TXCTRL(q)); -- cgit v1.2.3 From 8d25332081d87491e3b12fa130539fe9e2ba4a94 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 26 Dec 2008 15:13:55 -0800 Subject: igb: Fix build warning when DCA is disabled. Signed-off-by: David S. Miller --- drivers/net/igb/igb_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/net/igb/igb_main.c') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 9331e5212461..022794e579c7 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -3379,7 +3379,6 @@ static void igb_write_itr(struct igb_ring *ring) static irqreturn_t igb_msix_rx(int irq, void *data) { struct igb_ring *rx_ring = data; - struct igb_adapter *adapter = rx_ring->adapter; /* Write the ITR value calculated at the end of the * previous interrupt. @@ -3391,7 +3390,7 @@ static irqreturn_t igb_msix_rx(int irq, void *data) __netif_rx_schedule(&rx_ring->napi); #ifdef CONFIG_IGB_DCA - if (adapter->flags & IGB_FLAG_DCA_ENABLED) + if (rx_ring->adapter->flags & IGB_FLAG_DCA_ENABLED) igb_update_rx_dca(rx_ring); #endif return IRQ_HANDLED; -- cgit v1.2.3