From 88d2b81f4ee8f9ea3798dbe6105beb5609844317 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Tue, 30 Jun 2009 11:43:55 +0000 Subject: ixgbe: Fix SFP log messages We had a wide range of log messages for the same sort of SFP failure. This patch makes them all more similar and less confusing along with converting them to dev_err. Signed-off-by: Don Skidmore Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'drivers/net/ixgbe') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index e756e220db3..30d8c0e41a9 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2701,7 +2701,10 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) */ err = hw->phy.ops.identify(hw); if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { - DPRINTK(PROBE, ERR, "PHY not supported on this NIC %d\n", err); + dev_err(&adapter->pdev->dev, "failed to initialize because " + "an unsupported SFP+ module type was detected.\n" + "Reload the driver after installing a supported " + "module.\n"); ixgbe_down(adapter); return err; } @@ -3720,10 +3723,11 @@ static void ixgbe_sfp_task(struct work_struct *work) goto reschedule; ret = hw->phy.ops.reset(hw); if (ret == IXGBE_ERR_SFP_NOT_SUPPORTED) { - DPRINTK(PROBE, ERR, "failed to initialize because an " - "unsupported SFP+ module type was detected.\n" - "Reload the driver after installing a " - "supported module.\n"); + dev_err(&adapter->pdev->dev, "failed to initialize " + "because an unsupported SFP+ module type " + "was detected.\n" + "Reload the driver after installing a " + "supported module.\n"); unregister_netdev(adapter->netdev); } else { DPRINTK(PROBE, INFO, "detected SFP+: %d\n", @@ -4526,7 +4530,10 @@ static void ixgbe_sfp_config_module_task(struct work_struct *work) adapter->flags |= IXGBE_FLAG_IN_SFP_MOD_TASK; err = hw->phy.ops.identify_sfp(hw); if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { - DPRINTK(PROBE, ERR, "PHY not supported on this NIC %d\n", err); + dev_err(&adapter->pdev->dev, "failed to initialize because " + "an unsupported SFP+ module type was detected.\n" + "Reload the driver after installing a supported " + "module.\n"); ixgbe_down(adapter); return; } @@ -5513,8 +5520,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, round_jiffies(jiffies + (2 * HZ))); err = 0; } else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { - dev_err(&adapter->pdev->dev, "failed to load because an " - "unsupported SFP+ module type was detected.\n"); + dev_err(&adapter->pdev->dev, "failed to initialize because " + "an unsupported SFP+ module type was detected.\n" + "Reload the driver after installing a supported " + "module.\n"); goto err_sw_init; } else if (err) { dev_err(&adapter->pdev->dev, "HW Init failed: %d\n", err); -- cgit v1.2.3 From a380137900fca5c79e6daa9500bdb6ea5649188e Mon Sep 17 00:00:00 2001 From: Mallikarjuna R Chilakala Date: Tue, 30 Jun 2009 11:44:16 +0000 Subject: ixgbe: Fix device capabilities of 82599 single speed fiber NICs. 82599 single speed fiber modules only support 10G/Full. Return proper device capabilities while querrying the adapter and error while changing device advertisement/speed/duplex capabilities. Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_ethtool.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/net/ixgbe') diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 86f4f3e36f2..0f7b6a3a2e6 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -139,7 +139,7 @@ static int ixgbe_get_settings(struct net_device *netdev, ecmd->autoneg = AUTONEG_ENABLE; ecmd->transceiver = XCVR_EXTERNAL; if ((hw->phy.media_type == ixgbe_media_type_copper) || - (hw->mac.type == ixgbe_mac_82599EB)) { + (hw->phy.multispeed_fiber)) { ecmd->supported |= (SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg); @@ -217,7 +217,7 @@ static int ixgbe_set_settings(struct net_device *netdev, s32 err = 0; if ((hw->phy.media_type == ixgbe_media_type_copper) || - (hw->mac.type == ixgbe_mac_82599EB)) { + (hw->phy.multispeed_fiber)) { /* 10000/copper and 1000/copper must autoneg * this function does not support any duplex forcing, but can * limit the advertising of the adapter to only 10000 or 1000 */ @@ -245,6 +245,7 @@ static int ixgbe_set_settings(struct net_device *netdev, } else { /* in this case we currently only support 10Gb/FULL */ if ((ecmd->autoneg == AUTONEG_ENABLE) || + (ecmd->advertising != ADVERTISED_10000baseT_Full) || (ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)) return -EINVAL; } -- cgit v1.2.3 From a1f25324b93ecdab1cbb27d3e9c4cafecb06ceda Mon Sep 17 00:00:00 2001 From: Mallikarjuna R Chilakala Date: Tue, 30 Jun 2009 11:44:36 +0000 Subject: ixgbe: Fix link capabilities during adapter resets Adapter link advertisement capabilities were not persistent during adapter resets. While configuring multispeed fiber link check for phy autoneg_advertised settings before overwriting with default link capabilities Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net/ixgbe') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 30d8c0e41a9..fce2ef49b3a 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -4506,7 +4506,8 @@ static void ixgbe_multispeed_fiber_task(struct work_struct *work) u32 autoneg; adapter->flags |= IXGBE_FLAG_IN_SFP_LINK_TASK; - if (hw->mac.ops.get_link_capabilities) + autoneg = hw->phy.autoneg_advertised; + if ((!autoneg) && (hw->mac.ops.get_link_capabilities)) hw->mac.ops.get_link_capabilities(hw, &autoneg, &hw->mac.autoneg); if (hw->mac.ops.setup_link_speed) -- cgit v1.2.3 From 4f57ca6e17edfc56ddde5c87eb893e47e0d2d343 Mon Sep 17 00:00:00 2001 From: Jesse Brandeburg Date: Tue, 30 Jun 2009 11:44:56 +0000 Subject: ixgbe: fix unmap length bug This patch addresses three WARN_ON statements from DMA-API debug code ixgbe is mapping more than it unmaps, reduce the length of the map call and remove the "used once" local variable. found by Joerg Roedel in 2.6.30, so is a candidate for -stable. in addition, fix missing ->dma = 0 after unmap to prevent double free with pci_unmap_single and lastly, don't unmap (half) pages that aren't mapped. Signed-off-by: Jesse Brandeburg CC: Joerg Roedel Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'drivers/net/ixgbe') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index fce2ef49b3a..5588ef493a3 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -563,7 +563,6 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, union ixgbe_adv_rx_desc *rx_desc; struct ixgbe_rx_buffer *bi; unsigned int i; - unsigned int bufsz = rx_ring->rx_buf_len + NET_IP_ALIGN; i = rx_ring->next_to_use; bi = &rx_ring->rx_buffer_info[i]; @@ -593,7 +592,9 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, if (!bi->skb) { struct sk_buff *skb; - skb = netdev_alloc_skb(adapter->netdev, bufsz); + skb = netdev_alloc_skb(adapter->netdev, + (rx_ring->rx_buf_len + + NET_IP_ALIGN)); if (!skb) { adapter->alloc_rx_buff_failed++; @@ -608,7 +609,8 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, skb_reserve(skb, NET_IP_ALIGN); bi->skb = skb; - bi->dma = pci_map_single(pdev, skb->data, bufsz, + bi->dma = pci_map_single(pdev, skb->data, + rx_ring->rx_buf_len, PCI_DMA_FROMDEVICE); } /* Refresh the desc even if buffer_addrs didn't change because @@ -732,6 +734,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, pci_unmap_single(pdev, rx_buffer_info->dma, rx_ring->rx_buf_len, PCI_DMA_FROMDEVICE); + rx_buffer_info->dma = 0; skb_put(skb, len); } @@ -2815,9 +2818,11 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, } if (!rx_buffer_info->page) continue; - pci_unmap_page(pdev, rx_buffer_info->page_dma, PAGE_SIZE / 2, - PCI_DMA_FROMDEVICE); - rx_buffer_info->page_dma = 0; + if (rx_buffer_info->page_dma) { + pci_unmap_page(pdev, rx_buffer_info->page_dma, + PAGE_SIZE / 2, PCI_DMA_FROMDEVICE); + rx_buffer_info->page_dma = 0; + } put_page(rx_buffer_info->page); rx_buffer_info->page = NULL; rx_buffer_info->page_offset = 0; -- cgit v1.2.3 From 63d6e1d80a8c3118be2ca0f1f21ba883f282060c Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Thu, 2 Jul 2009 12:50:12 +0000 Subject: ixgbe: fix issues with failing to detect insert of unsupported module Several small fixes around negative test case of the insertion of a IXGBE_ERR_NOT_SUPPORTED module. - mdio45_probe call was always failing due to mdio.prtad not being set. The function set to mdio.mdio_read was still working as we just happen to always be at prtad == 0. This will allow us to set the phy_id and phy.type correctly now. - There was timing issue with i2c calls when initiated from a tasklet. A small delay was added to allow the electrical oscillation to calm down. - Logic change in ixgbe_sfp_task that allows NOT_SUPPORTED condition to be recognized. Signed-off-by: Don Skidmore Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 8 ++++++-- drivers/net/ixgbe/ixgbe_phy.c | 3 +++ 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers/net/ixgbe') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 5588ef493a3..aaf482c0d52 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3724,7 +3724,7 @@ static void ixgbe_sfp_task(struct work_struct *work) if ((hw->phy.type == ixgbe_phy_nl) && (hw->phy.sfp_type == ixgbe_sfp_type_not_present)) { s32 ret = hw->phy.ops.identify_sfp(hw); - if (ret) + if (ret == IXGBE_ERR_SFP_NOT_PRESENT) goto reschedule; ret = hw->phy.ops.reset(hw); if (ret == IXGBE_ERR_SFP_NOT_SUPPORTED) { @@ -4534,13 +4534,17 @@ static void ixgbe_sfp_config_module_task(struct work_struct *work) u32 err; adapter->flags |= IXGBE_FLAG_IN_SFP_MOD_TASK; + + /* Time for electrical oscillations to settle down */ + msleep(100); err = hw->phy.ops.identify_sfp(hw); + if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { dev_err(&adapter->pdev->dev, "failed to initialize because " "an unsupported SFP+ module type was detected.\n" "Reload the driver after installing a supported " "module.\n"); - ixgbe_down(adapter); + unregister_netdev(adapter->netdev); return; } hw->mac.ops.setup_sfp(hw); diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index 453e966762f..9ecad17522c 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c @@ -60,6 +60,7 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) if (hw->phy.type == ixgbe_phy_unknown) { for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) { + hw->phy.mdio.prtad = phy_addr; if (mdio45_probe(&hw->phy.mdio, phy_addr) == 0) { ixgbe_get_phy_id(hw); hw->phy.type = @@ -68,6 +69,8 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) break; } } + /* clear value if nothing found */ + hw->phy.mdio.prtad = 0; } else { status = 0; } -- cgit v1.2.3 From 19343de279d28e4ed039c8ad00510d19dc4d6d12 Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Thu, 2 Jul 2009 12:50:31 +0000 Subject: ixgbe: fix regression on some 82598 adapters The change to check the SFP+ module again on open() was causing the XFP (non-SFP+) adapters to be rejected. We only want to try and re-identify the SFP+ module if the original probe found that this device was an SFP+ device. So for this code path (driver loaded with SFP module, module inserted, ifconfig up of the device) the type will be ixgbe_phy_unknown for an unidentified SFP+ module. So we only check if that is the case. This problem also shows up on Copper devices. Signed-off-by: Peter P Waskiewicz Jr Signed-off-by: Don Skidmore Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'drivers/net/ixgbe') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index aaf482c0d52..cf39f5a4703 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2697,19 +2697,23 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) /* * For hot-pluggable SFP+ devices, a new SFP+ module may have - * arrived before interrupts were enabled. We need to kick off - * the SFP+ module setup first, then try to bring up link. + * arrived before interrupts were enabled but after probe. Such + * devices wouldn't have their type identified yet. We need to + * kick off the SFP+ module setup first, then try to bring up link. * If we're not hot-pluggable SFP+, we just need to configure link * and bring it up. */ - err = hw->phy.ops.identify(hw); - if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { - dev_err(&adapter->pdev->dev, "failed to initialize because " - "an unsupported SFP+ module type was detected.\n" - "Reload the driver after installing a supported " - "module.\n"); - ixgbe_down(adapter); - return err; + if (hw->phy.type == ixgbe_phy_unknown) { + err = hw->phy.ops.identify(hw); + if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { + dev_err(&adapter->pdev->dev, "failed to initialize " + "because an unsupported SFP+ module type " + "was detected.\n" + "Reload the driver after installing a " + "supported module.\n"); + ixgbe_down(adapter); + return err; + } } if (ixgbe_is_sfp(hw)) { -- cgit v1.2.3 From 5da43c1a78cbc16518017dfb058da6ec4829781b Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Thu, 2 Jul 2009 12:50:52 +0000 Subject: ixgbe: fix inconsistent SFP/SFP+ failure results. Currently if we loaded the driver, insert an unsupported module, and then attempt to "ifconfig up" the device it will be brought down but the netdev would not be unregistered. This behavior is different than all other code paths. This patch corrects that by down'ing the device and then scheduling the sfp_config_module_task tasklet. The tasklet will detect this condition (like it does with other code paths) and do the unregister_netdev(). I also removed the log message as this condition (an unsupported SFP+ module) will be logged in sfp_config_module_task. Signed-off-by: Don Skidmore Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/net/ixgbe') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index cf39f5a4703..a3061aacffd 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -2706,12 +2706,12 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) if (hw->phy.type == ixgbe_phy_unknown) { err = hw->phy.ops.identify(hw); if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { - dev_err(&adapter->pdev->dev, "failed to initialize " - "because an unsupported SFP+ module type " - "was detected.\n" - "Reload the driver after installing a " - "supported module.\n"); + /* + * Take the device down and schedule the sfp tasklet + * which will unregister_netdev and log it. + */ ixgbe_down(adapter); + schedule_work(&adapter->sfp_config_module_task); return err; } } -- cgit v1.2.3 From e5d57af52464f37dd3c67906a493a6400bc51b43 Mon Sep 17 00:00:00 2001 From: Mallikarjuna R Chilakala Date: Thu, 2 Jul 2009 12:51:10 +0000 Subject: ixgbe: Not allow 8259x unsupported wol options change from ethtool Wake-on-lan is currently only supported by 82599 KX4 devices, in all other cases return a proper value from ixgbe_wol_exclusion function call. Otherwise from ethtool we will be able to change wol options of unsupported 8259x devices. Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_ethtool.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net/ixgbe') diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 0f7b6a3a2e6..2a978008fd6 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -1830,7 +1830,6 @@ static int ixgbe_wol_exclusion(struct ixgbe_adapter *adapter, break; default: wol->supported = 0; - retval = 0; } return retval; -- cgit v1.2.3 From 8faa2a786a5337683109d77ccf880339fdcdb332 Mon Sep 17 00:00:00 2001 From: Yi Zou Date: Thu, 9 Jul 2009 02:29:50 +0000 Subject: ixgbe: Fix coexistence of FCoE and Flow Director in 82599 Fix coexistence of Fiber Channel over Ethernet (FCoE) and Flow Director (FDIR) in 82599 and remove the disabling of FDIR when FCoE is enabled. Currently, FDIR is turned off when FCoE is enabled under the assumption that FCoE is always enabled with DCB being turned on. However, FDIR does not have to be turned off all the time when FCoE is enabled since FCoE can be enabled without DCB being turned on, e.g., use link pause only. This patch makes sure that when DCB is turned on or off, FDIR is turned on or off correspondingly; and when FCoE is enabled, it does not disable FDIR, rather, it will have FDIR set up properly so FCoE and FDIR can coexist regardless of DCB being on or off. Signed-off-by: Yi Zou Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_dcb_nl.c | 6 ++++++ drivers/net/ixgbe/ixgbe_main.c | 19 +++++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) (limited to 'drivers/net/ixgbe') diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index d56890f5c9d..7c5978ad929 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -138,6 +138,10 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) adapter->hw.fc.requested_mode = ixgbe_fc_none; } adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED; + if (adapter->hw.mac.type == ixgbe_mac_82599EB) { + adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; + adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; + } adapter->flags |= IXGBE_FLAG_DCB_ENABLED; ixgbe_init_interrupt_scheme(adapter); if (netif_running(netdev)) @@ -154,6 +158,8 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) adapter->dcb_cfg.pfc_mode_enable = false; adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; adapter->flags |= IXGBE_FLAG_RSS_ENABLED; + if (adapter->hw.mac.type == ixgbe_mac_82599EB) + adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; ixgbe_init_interrupt_scheme(adapter); if (netif_running(netdev)) netdev->netdev_ops->ndo_open(netdev); diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index a3061aacffd..e3442f47f93 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3130,7 +3130,11 @@ static inline bool ixgbe_set_fcoe_queues(struct ixgbe_adapter *adapter) #endif if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { DPRINTK(PROBE, INFO, "FCOE enabled with RSS \n"); - ixgbe_set_rss_queues(adapter); + if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) || + (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) + ixgbe_set_fdir_queues(adapter); + else + ixgbe_set_rss_queues(adapter); } /* adding FCoE rx rings to the end */ f->mask = adapter->num_rx_queues; @@ -3388,7 +3392,12 @@ static inline bool ixgbe_cache_ring_fcoe(struct ixgbe_adapter *adapter) } #endif /* CONFIG_IXGBE_DCB */ if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { - ixgbe_cache_ring_rss(adapter); + if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) || + (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) + ixgbe_cache_ring_fdir(adapter); + else + ixgbe_cache_ring_rss(adapter); + fcoe_i = f->mask; } for (i = 0; i < f->indices; i++, fcoe_i++) @@ -5578,12 +5587,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, netdev->features |= NETIF_F_FCOE_CRC; netdev->features |= NETIF_F_FSO; netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1; - DPRINTK(DRV, INFO, "FCoE enabled, " - "disabling Flow Director\n"); - adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; - adapter->flags &= - ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; - adapter->atr_sample_rate = 0; } else { adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED; } -- cgit v1.2.3 From 86e713a06ab3e5b15a3189485ce33aa21b9e52ca Mon Sep 17 00:00:00 2001 From: Lucy Liu Date: Thu, 16 Jul 2009 13:43:10 +0000 Subject: ixgbe: clear mac address data block in DCB mode This change clears the address data block memory space, which is needed for the 82598 which does not have a SAN MAC. Signed-off-by: Lucy Liu Acked-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_dcb_nl.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net/ixgbe') diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index 7c5978ad929..5b8dab22c6d 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -175,6 +175,8 @@ static void ixgbe_dcbnl_get_perm_hw_addr(struct net_device *netdev, struct ixgbe_adapter *adapter = netdev_priv(netdev); int i, j; + memset(perm_addr, 0xff, MAX_ADDR_LEN); + for (i = 0; i < netdev->addr_len; i++) perm_addr[i] = adapter->hw.mac.perm_addr[i]; -- cgit v1.2.3 From 869f1c54e9aecde1dfd4349832ce9415a596be8e Mon Sep 17 00:00:00 2001 From: Lucy Liu Date: Thu, 16 Jul 2009 13:43:31 +0000 Subject: ixgbe: Remove DPRINTK messages in DCB mode Remove debug DPRINTK in DCB mode netlink interface. Signed-off-by: Lucy Liu Acked-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_dcb_nl.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/net/ixgbe') diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index 5b8dab22c6d..da2c8514b8d 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -106,8 +106,6 @@ static u8 ixgbe_dcbnl_get_state(struct net_device *netdev) { struct ixgbe_adapter *adapter = netdev_priv(netdev); - DPRINTK(DRV, INFO, "Get DCB Admin Mode.\n"); - return !!(adapter->flags & IXGBE_FLAG_DCB_ENABLED); } @@ -116,8 +114,6 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) u8 err = 0; struct ixgbe_adapter *adapter = netdev_priv(netdev); - DPRINTK(DRV, INFO, "Set DCB Admin Mode.\n"); - if (state > 0) { /* Turn on DCB */ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) -- cgit v1.2.3 From 0d5515894fd5b9e9402ef76e9a7e704fd26e0e5f Mon Sep 17 00:00:00 2001 From: Yi Zou Date: Wed, 22 Jul 2009 14:07:12 +0000 Subject: ixgbe: Enable FCoE offload when DCB is enabled for 82599 Currently, FCoE offload feature is turned on when the kernel config has CONFIG_FCOE or CONFIG_FCOE_MODULE set. However, we really want to turn FCoE offload on when there is FCoE traffic passing and turn it off when it's just LAN traffic. Since FCoE depends on a lossless network provided by DCB, this allows us to have FCoE turned on/off when user turns on DCB using dcbtool. Signed-off-by: Yi Zou Acked-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe.h | 1 + drivers/net/ixgbe/ixgbe_dcb_nl.c | 24 ++++++++++++++++++++++++ drivers/net/ixgbe/ixgbe_main.c | 16 ++++++---------- 3 files changed, 31 insertions(+), 10 deletions(-) (limited to 'drivers/net/ixgbe') diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index cd22323cfd2..1b12c7ba275 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -327,6 +327,7 @@ struct ixgbe_adapter { #define IXGBE_FLAG_IN_SFP_MOD_TASK (u32)(1 << 25) #define IXGBE_FLAG_FDIR_HASH_CAPABLE (u32)(1 << 26) #define IXGBE_FLAG_FDIR_PERFECT_CAPABLE (u32)(1 << 27) +#define IXGBE_FLAG_FCOE_CAPABLE (u32)(1 << 28) #define IXGBE_FLAG_FCOE_ENABLED (u32)(1 << 29) u32 flags2; diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index da2c8514b8d..1c726573290 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -139,6 +139,18 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; } adapter->flags |= IXGBE_FLAG_DCB_ENABLED; +#ifdef IXGBE_FCOE + /* Turn on FCoE offload */ + if ((adapter->flags & IXGBE_FLAG_FCOE_CAPABLE) && + (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))) { + adapter->flags |= IXGBE_FLAG_FCOE_ENABLED; + adapter->ring_feature[RING_F_FCOE].indices = + IXGBE_FCRETA_SIZE; + netdev->features |= NETIF_F_FCOE_CRC; + netdev->features |= NETIF_F_FSO; + netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1; + } +#endif /* IXGBE_FCOE */ ixgbe_init_interrupt_scheme(adapter); if (netif_running(netdev)) netdev->netdev_ops->ndo_open(netdev); @@ -156,6 +168,18 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) adapter->flags |= IXGBE_FLAG_RSS_ENABLED; if (adapter->hw.mac.type == ixgbe_mac_82599EB) adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; + +#ifdef IXGBE_FCOE + /* Turn off FCoE offload */ + if (adapter->flags & (IXGBE_FLAG_FCOE_CAPABLE | + IXGBE_FLAG_FCOE_ENABLED)) { + adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED; + adapter->ring_feature[RING_F_FCOE].indices = 0; + netdev->features &= ~NETIF_F_FCOE_CRC; + netdev->features &= ~NETIF_F_FSO; + netdev->fcoe_ddp_xid = 0; + } +#endif /* IXGBE_FCOE */ ixgbe_init_interrupt_scheme(adapter); if (netif_running(netdev)) netdev->netdev_ops->ndo_open(netdev); diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index e3442f47f93..a2119d79ccd 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -3806,8 +3806,9 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) adapter->atr_sample_rate = 20; adapter->fdir_pballoc = 0; #ifdef IXGBE_FCOE - adapter->flags |= IXGBE_FLAG_FCOE_ENABLED; - adapter->ring_feature[RING_F_FCOE].indices = IXGBE_FCRETA_SIZE; + adapter->flags |= IXGBE_FLAG_FCOE_CAPABLE; + adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED; + adapter->ring_feature[RING_F_FCOE].indices = 0; #endif /* IXGBE_FCOE */ } @@ -5580,16 +5581,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, #endif #ifdef IXGBE_FCOE - if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) { + if (adapter->flags & IXGBE_FLAG_FCOE_CAPABLE) { if (hw->mac.ops.get_device_caps) { hw->mac.ops.get_device_caps(hw, &device_caps); - if (!(device_caps & IXGBE_DEVICE_CAPS_FCOE_OFFLOADS)) { - netdev->features |= NETIF_F_FCOE_CRC; - netdev->features |= NETIF_F_FSO; - netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1; - } else { - adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED; - } + if (device_caps & IXGBE_DEVICE_CAPS_FCOE_OFFLOADS) + adapter->flags &= ~IXGBE_FLAG_FCOE_CAPABLE; } } #endif /* IXGBE_FCOE */ -- cgit v1.2.3 From 601278659d5717b4f7a14fbc9f2b9d559bba6aef Mon Sep 17 00:00:00 2001 From: Lucy Liu Date: Wed, 22 Jul 2009 14:07:33 +0000 Subject: ixgbe: Don't priority tag control frames in DCB mode Certain types of control packets (LLDP, LACP, etc.) are not supposed to have a priority tag or vlan tag inserted. Ixgbe driver is currently priority tagging everything (if packet is not on a VLAN interface). This patch modifies DCB mode, so that packets marked with skb priority TC_PRIO_CONTROL are not priority tagged. It also transmits these packets on the highest priority traffic class. Programs (like dcbd) can set the skb priority using a socket option. Or, a tc filter can be configured to set the priority value. Using the value TC_PRIO_CONTROL (7) has the benefit that it is already defined in the kernel, and the bonding LACP code already sets the skb->priority field to this value. Signed-off-by: Lucy Liu Acked-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'drivers/net/ixgbe') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index a2119d79ccd..47a3c6d7056 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -5126,9 +5127,6 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) int count = 0; unsigned int f; - r_idx = skb->queue_mapping; - tx_ring = &adapter->tx_ring[r_idx]; - if (adapter->vlgrp && vlan_tx_tag_present(skb)) { tx_flags |= vlan_tx_tag_get(skb); if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { @@ -5138,11 +5136,19 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT; tx_flags |= IXGBE_TX_FLAGS_VLAN; } else if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { - tx_flags |= (skb->queue_mapping << 13); - tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT; - tx_flags |= IXGBE_TX_FLAGS_VLAN; + if (skb->priority != TC_PRIO_CONTROL) { + tx_flags |= (skb->queue_mapping << 13); + tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT; + tx_flags |= IXGBE_TX_FLAGS_VLAN; + } else { + skb->queue_mapping = + adapter->ring_feature[RING_F_DCB].indices-1; + } } + r_idx = skb->queue_mapping; + tx_ring = &adapter->tx_ring[r_idx]; + if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && (skb->protocol == htons(ETH_P_FCOE))) tx_flags |= IXGBE_TX_FLAGS_FCOE; -- cgit v1.2.3 From ffafa60d496f80c250f2ae0340ae94434c0b0b4d Mon Sep 17 00:00:00 2001 From: Andy Gospodarek Date: Wed, 22 Jul 2009 09:34:00 +0000 Subject: ixgbe: remove unnecessary call to device_init_wakeup Calls to device_init_wakeup should not be necessary in drivers that use device_set_wakeup_enable since pci_pm_init will set the can_wakeup flag for the device when initialized. Signed-off-by: Andy Gospodarek Acked-by: Peter P Waskiewicz Jr Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net/ixgbe') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 47a3c6d7056..68877599f6d 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -5640,7 +5640,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, adapter->wol = 0; break; } - device_init_wakeup(&adapter->pdev->dev, true); device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); /* pick up the PCI bus settings for reporting later */ -- cgit v1.2.3 From 8bae1b2b13beb4cf4c0f119f97640503c2b74b0f Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Thu, 23 Jul 2009 18:00:39 +0000 Subject: ixgbe: fix for 82599 errata marking UDP checksum errors There is an 82599 errata that UDP frames with a zero checksum are incorrectly marked as checksum invalid by the hardware. This was leading to misleading hw_csum_rx_error counts. This patch adds a test around this counter increase for this condition. Signed-off-by: Don Skidmore Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers/net/ixgbe') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 68877599f6d..200454f30f6 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -511,8 +511,11 @@ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector, * @skb: skb currently being received and modified **/ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter, - u32 status_err, struct sk_buff *skb) + union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb) { + u32 status_err = le32_to_cpu(rx_desc->wb.upper.status_error); + skb->ip_summed = CHECKSUM_NONE; /* Rx csum disabled */ @@ -530,6 +533,16 @@ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter, return; if (status_err & IXGBE_RXDADV_ERR_TCPE) { + u16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info; + + /* + * 82599 errata, UDP frames with a 0 checksum can be marked as + * checksum errors. + */ + if ((pkt_info & IXGBE_RXDADV_PKTTYPE_UDP) && + (adapter->hw.mac.type == ixgbe_mac_82599EB)) + return; + adapter->hw_csum_rx_error++; return; } @@ -803,7 +816,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, goto next_desc; } - ixgbe_rx_checksum(adapter, staterr, skb); + ixgbe_rx_checksum(adapter, rx_desc, skb); /* probably a little skewed due to removing CRC */ total_rx_bytes += skb->len; -- cgit v1.2.3 From 8f9a71673d9f397a365f4d18c307e91141b8fe92 Mon Sep 17 00:00:00 2001 From: Peter P Waskiewicz Jr Date: Thu, 30 Jul 2009 12:25:09 +0000 Subject: ixgbe: Fix netpoll to be properly multiqueue aware Our ndo_poll_controller callback is broken for anything but non-multiqueue setups. This fixes that issue. Signed-off-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers/net/ixgbe') diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 200454f30f6..60c4a8bf7d3 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -5360,12 +5360,19 @@ static int ixgbe_del_sanmac_netdev(struct net_device *dev) static void ixgbe_netpoll(struct net_device *netdev) { struct ixgbe_adapter *adapter = netdev_priv(netdev); + int i; - disable_irq(adapter->pdev->irq); adapter->flags |= IXGBE_FLAG_IN_NETPOLL; - ixgbe_intr(adapter->pdev->irq, netdev); + if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { + int num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; + for (i = 0; i < num_q_vectors; i++) { + struct ixgbe_q_vector *q_vector = adapter->q_vector[i]; + ixgbe_msix_clean_many(0, q_vector); + } + } else { + ixgbe_intr(adapter->pdev->irq, netdev); + } adapter->flags &= ~IXGBE_FLAG_IN_NETPOLL; - enable_irq(adapter->pdev->irq); } #endif -- cgit v1.2.3 From 0c19d6af9253f19b41821c29b9c49c2214f19425 Mon Sep 17 00:00:00 2001 From: Peter P Waskiewicz Jr Date: Thu, 30 Jul 2009 12:25:28 +0000 Subject: ixgbe: Fix usage of second flags bitmap when using LRO/RSC A second set of feature flag bits was added, and the hardware RSC engine flags were moved there. However, the code itself didn't make the move completely to use the new bitmap. Signed-off-by: Peter P Waskiewicz Jr Acked-by: Mallikarjuna R Chilakala Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_ethtool.c | 6 +++--- drivers/net/ixgbe/ixgbe_main.c | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/net/ixgbe') diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 2a978008fd6..7ddb50c03f0 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -1999,13 +1999,13 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data) ethtool_op_set_flags(netdev, data); - if (!(adapter->flags & IXGBE_FLAG2_RSC_CAPABLE)) + if (!(adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)) return 0; /* if state changes we need to update adapter->flags and reset */ if ((!!(data & ETH_FLAG_LRO)) != - (!!(adapter->flags & IXGBE_FLAG2_RSC_ENABLED))) { - adapter->flags ^= IXGBE_FLAG2_RSC_ENABLED; + (!!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED))) { + adapter->flags2 ^= IXGBE_FLAG2_RSC_ENABLED; if (netif_running(netdev)) ixgbe_reinit_locked(adapter); else diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 60c4a8bf7d3..110c65ab5cb 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -780,7 +780,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, prefetch(next_rxd); cleaned_count++; - if (adapter->flags & IXGBE_FLAG2_RSC_CAPABLE) + if (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE) rsc_count = ixgbe_get_rsc_count(rx_desc); if (rsc_count) { @@ -2036,7 +2036,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(0), psrtype); } } else { - if (!(adapter->flags & IXGBE_FLAG2_RSC_ENABLED) && + if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) && (netdev->mtu <= ETH_DATA_LEN)) rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE; else @@ -2165,7 +2165,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl); } - if (adapter->flags & IXGBE_FLAG2_RSC_ENABLED) { + if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { /* Enable 82599 HW-RSC */ for (i = 0; i < adapter->num_rx_queues; i++) { j = adapter->rx_ring[i].reg_idx; @@ -3812,8 +3812,8 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82598; } else if (hw->mac.type == ixgbe_mac_82599EB) { adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82599; - adapter->flags |= IXGBE_FLAG2_RSC_CAPABLE; - adapter->flags |= IXGBE_FLAG2_RSC_ENABLED; + adapter->flags2 |= IXGBE_FLAG2_RSC_CAPABLE; + adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED; adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; adapter->ring_feature[RING_F_FDIR].indices = IXGBE_MAX_FDIR_INDICES; @@ -5618,7 +5618,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; - if (adapter->flags & IXGBE_FLAG2_RSC_ENABLED) + if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) netdev->features |= NETIF_F_LRO; /* make sure the EEPROM is good */ -- cgit v1.2.3 From 0a924578bc4a2823a95c151f56975c71f5c156bb Mon Sep 17 00:00:00 2001 From: Peter P Waskiewicz Jr Date: Thu, 30 Jul 2009 12:26:00 +0000 Subject: ixgbe: Fix RSC completion delay causing Rx interrupts to stop When a user disables interrupt throttling with ethtool on 82599 devices, the interrupt timer may not be re-enabled if hardware RSC is running. The RSC completions in hardware don't complete before the next ITR event tries to fire, so the ITR timer never gets re-armed. This patch increases the amount of time between interrupts when throttling is disabled (rx-usecs = 0) when the hardware RSC deature is enabled. Signed-off-by: Peter P Waskiewicz Jr Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe.h | 2 ++ drivers/net/ixgbe/ixgbe_ethtool.c | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/net/ixgbe') diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 1b12c7ba275..e11d83d5852 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -96,6 +96,8 @@ #define IXGBE_TX_FLAGS_VLAN_PRIO_MASK 0x0000e000 #define IXGBE_TX_FLAGS_VLAN_SHIFT 16 +#define IXGBE_MAX_RSC_INT_RATE 162760 + /* wrapper around a pointer to a socket buffer, * so a DMA handle can be stored along with the buffer */ struct ixgbe_tx_buffer { diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 7ddb50c03f0..79144e950a3 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -1975,7 +1975,10 @@ static int ixgbe_set_coalesce(struct net_device *netdev, * any other value means disable eitr, which is best * served by setting the interrupt rate very high */ - adapter->eitr_param = IXGBE_MAX_INT_RATE; + if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) + adapter->eitr_param = IXGBE_MAX_RSC_INT_RATE; + else + adapter->eitr_param = IXGBE_MAX_INT_RATE; adapter->itr_setting = 0; } -- cgit v1.2.3 From 202ff1ec8e53d5dd36e1a5bd4b0a7ed7dbd45087 Mon Sep 17 00:00:00 2001 From: Mallikarjuna R Chilakala Date: Mon, 3 Aug 2009 07:20:38 +0000 Subject: ixgbe: Patch to modify 82598 PCIe completion timeout values The default completion timeout values for 82598 should be in the range of 50us to 50ms, however the hardware default for these parts is 500us to 1ms which is less than the 10ms recommended by the pcie spec. To address this we need to increase the value to either 10ms to 250ms for capability version 1 configuration, or 16ms to 55ms for version 2. Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_82598.c | 67 ++++++++++++++++++++++++++++++++++++++++- drivers/net/ixgbe/ixgbe_type.h | 8 +++++ 2 files changed, 74 insertions(+), 1 deletion(-) (limited to 'drivers/net/ixgbe') diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index b9923047ce1..522c03bc1da 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -49,6 +49,51 @@ static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset, u8 *eeprom_data); +/** + * ixgbe_set_pcie_completion_timeout - set pci-e completion timeout + * @hw: pointer to the HW structure + * + * The defaults for 82598 should be in the range of 50us to 50ms, + * however the hardware default for these parts is 500us to 1ms which is less + * than the 10ms recommended by the pci-e spec. To address this we need to + * increase the value to either 10ms to 250ms for capability version 1 config, + * or 16ms to 55ms for version 2. + **/ +void ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw) +{ + struct ixgbe_adapter *adapter = hw->back; + u32 gcr = IXGBE_READ_REG(hw, IXGBE_GCR); + u16 pcie_devctl2; + + /* only take action if timeout value is defaulted to 0 */ + if (gcr & IXGBE_GCR_CMPL_TMOUT_MASK) + goto out; + + /* + * if capababilities version is type 1 we can write the + * timeout of 10ms to 250ms through the GCR register + */ + if (!(gcr & IXGBE_GCR_CAP_VER2)) { + gcr |= IXGBE_GCR_CMPL_TMOUT_10ms; + goto out; + } + + /* + * for version 2 capabilities we need to write the config space + * directly in order to set the completion timeout value for + * 16ms to 55ms + */ + pci_read_config_word(adapter->pdev, + IXGBE_PCI_DEVICE_CONTROL2, &pcie_devctl2); + pcie_devctl2 |= IXGBE_PCI_DEVICE_CONTROL2_16ms; + pci_write_config_word(adapter->pdev, + IXGBE_PCI_DEVICE_CONTROL2, pcie_devctl2); +out: + /* disable completion timeout resend */ + gcr &= ~IXGBE_GCR_CMPL_TMOUT_RESEND; + IXGBE_WRITE_REG(hw, IXGBE_GCR, gcr); +} + /** * ixgbe_get_pcie_msix_count_82598 - Gets MSI-X vector count * @hw: pointer to hardware structure @@ -152,6 +197,26 @@ out: return ret_val; } +/** + * ixgbe_start_hw_82598 - Prepare hardware for Tx/Rx + * @hw: pointer to hardware structure + * + * Starts the hardware using the generic start_hw function. + * Then set pcie completion timeout + **/ +s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw) +{ + s32 ret_val = 0; + + ret_val = ixgbe_start_hw_generic(hw); + + /* set the completion timeout for interface */ + if (ret_val == 0) + ixgbe_set_pcie_completion_timeout(hw); + + return ret_val; +} + /** * ixgbe_get_link_capabilities_82598 - Determines link capabilities * @hw: pointer to hardware structure @@ -1085,7 +1150,7 @@ out: static struct ixgbe_mac_operations mac_ops_82598 = { .init_hw = &ixgbe_init_hw_generic, .reset_hw = &ixgbe_reset_hw_82598, - .start_hw = &ixgbe_start_hw_generic, + .start_hw = &ixgbe_start_hw_82598, .clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic, .get_media_type = &ixgbe_get_media_type_82598, .get_supported_physical_layer = &ixgbe_get_supported_physical_layer_82598, diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index fa87309dc08..be90eb4575f 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -718,6 +718,12 @@ #define IXGBE_ECC_STATUS_82599 0x110E0 #define IXGBE_BAR_CTRL_82599 0x110F4 +/* PCI Express Control */ +#define IXGBE_GCR_CMPL_TMOUT_MASK 0x0000F000 +#define IXGBE_GCR_CMPL_TMOUT_10ms 0x00001000 +#define IXGBE_GCR_CMPL_TMOUT_RESEND 0x00010000 +#define IXGBE_GCR_CAP_VER2 0x00040000 + /* Time Sync Registers */ #define IXGBE_TSYNCRXCTL 0x05188 /* Rx Time Sync Control register - RW */ #define IXGBE_TSYNCTXCTL 0x08C00 /* Tx Time Sync Control register - RW */ @@ -1521,6 +1527,7 @@ /* PCI Bus Info */ #define IXGBE_PCI_LINK_STATUS 0xB2 +#define IXGBE_PCI_DEVICE_CONTROL2 0xC8 #define IXGBE_PCI_LINK_WIDTH 0x3F0 #define IXGBE_PCI_LINK_WIDTH_1 0x10 #define IXGBE_PCI_LINK_WIDTH_2 0x20 @@ -1531,6 +1538,7 @@ #define IXGBE_PCI_LINK_SPEED_5000 0x2 #define IXGBE_PCI_HEADER_TYPE_REGISTER 0x0E #define IXGBE_PCI_HEADER_TYPE_MULTIFUNC 0x80 +#define IXGBE_PCI_DEVICE_CONTROL2_16ms 0x0005 /* Number of 100 microseconds we wait for PCI Express master disable */ #define IXGBE_PCI_MASTER_DISABLE_TIMEOUT 800 -- cgit v1.2.3