From b20a774495671f037e7160ea2ce8789af6b61533 Mon Sep 17 00:00:00 2001 From: David Ertman Date: Tue, 25 Mar 2014 04:27:55 +0000 Subject: [PATCH 01/13] e1000e: Fix no connectivity when driver loaded with cable out In commit da1e2046e5, the flow for enabling/disabling an Si errata workaround (e1000_lv_jumbo_workaround_ich8lan) was changed to fix a problem with iAMT connections dropping on interface down with jumbo frames set. Part of this change was to move the function call disabling the workaround to e1000e_down() from the e1000_setup_rctl() function. The mechanic for disabling of this workaround involves writing several MAC and PHY registers back to hardware defaults. After this commit, when the driver is loaded with the cable out, the PHY registers are not programmed with the correct default values. This causes the device to be capable of transmitting packets, but is unable to recieve them until this workaround is called. The flow of e1000e's open code relies upon calling the above workaround to expicitly program these registers either with jumbo frame appropriate settings or h/w defaults on 82579 and newer hardware. Fix this issue by adding logic to e1000_setup_rctl() that not only calls e1000_lv_jumbo_workaround_ich8lan() when jumbo frames are set, to enable the workaround, but also calls this function to explicitly disable the workaround in the case that jumbo frames are not set. Signed-off-by: Dave Ertman Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/netdev.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index f1cce5928e20..dce377b59b2c 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -2991,11 +2991,21 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) u32 rctl, rfctl; u32 pages = 0; - /* Workaround Si errata on PCHx - configure jumbo frame flow */ - if ((hw->mac.type >= e1000_pch2lan) && - (adapter->netdev->mtu > ETH_DATA_LEN) && - e1000_lv_jumbo_workaround_ich8lan(hw, true)) - e_dbg("failed to enable jumbo frame workaround mode\n"); + /* Workaround Si errata on PCHx - configure jumbo frame flow. + * If jumbo frames not set, program related MAC/PHY registers + * to h/w defaults + */ + if (hw->mac.type >= e1000_pch2lan) { + s32 ret_val; + + if (adapter->netdev->mtu > ETH_DATA_LEN) + ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, true); + else + ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, false); + + if (ret_val) + e_dbg("failed to enable|disable jumbo frame workaround mode\n"); + } /* Program MC offset vector base */ rctl = er32(RCTL); From 181e7d5d7bd7747e882e3ca89ecbf0fc3e72d0da Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Sat, 15 Mar 2014 14:55:11 +0000 Subject: [PATCH 02/13] ixgbe: remove redundant if clause from PTP work ptp_tx_skb is always set before work is scheduled, work is cancelled before ptp_tx_skb is set to NULL. PTP work cannot ever see ptp_tx_skb set to NULL. Signed-off-by: Jakub Kicinski Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index 44ac9aef6a8d..8b527d79d429 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c @@ -512,10 +512,6 @@ static void ixgbe_ptp_tx_hwtstamp_work(struct work_struct *work) IXGBE_PTP_TX_TIMEOUT); u32 tsynctxctl; - /* we have to have a valid skb */ - if (!adapter->ptp_tx_skb) - return; - if (timeout) { dev_kfree_skb_any(adapter->ptp_tx_skb); adapter->ptp_tx_skb = NULL; From ff29a86ec9143ff1aa1901ae60f06f4980981df4 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Sat, 15 Mar 2014 14:55:16 +0000 Subject: [PATCH 03/13] ixgbe: never generate both software and hardware timestamps skb_tx_timestamp() does not report software time stamp if SKBTX_IN_PROGRESS is set. According to timestamping.txt software time stamps are a fallback and should not be generated if hardware time stamp is provided. Move call to skb_tx_timestamp() after setting SKBTX_IN_PROGRESS. Signed-off-by: Jakub Kicinski Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 9e5a36612432..24538cb0f856 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -7042,8 +7042,6 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, tx_flags |= IXGBE_TX_FLAGS_SW_VLAN; } - skb_tx_timestamp(skb); - if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; tx_flags |= IXGBE_TX_FLAGS_TSTAMP; @@ -7054,6 +7052,8 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, schedule_work(&adapter->ptp_tx_work); } + skb_tx_timestamp(skb); + #ifdef CONFIG_PCI_IOV /* * Use the l2switch_enable flag - would be false if the DMA From 151b260c624d47b2c78b2f887e4f791c09c73c17 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Sat, 15 Mar 2014 14:55:21 +0000 Subject: [PATCH 04/13] ixgbe: fix race conditions on queuing skb for HW time stamp ixgbe has a single set of TX time stamping resources per NIC. Use a simple bit lock to avoid race conditions and leaking skbs when multiple TX rings try to claim time stamping. Signed-off-by: Jakub Kicinski Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 + drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 +++- drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 2fff0fc4e6e8..26d27aae9793 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -812,6 +812,7 @@ enum ixgbe_state_t { __IXGBE_SERVICE_SCHED, __IXGBE_IN_SFP_INIT, __IXGBE_PTP_RUNNING, + __IXGBE_PTP_TX_IN_PROGRESS, }; struct ixgbe_cb { diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 24538cb0f856..c4b930c0ce7f 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -7042,7 +7042,9 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, tx_flags |= IXGBE_TX_FLAGS_SW_VLAN; } - if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && + !test_and_set_bit_lock(__IXGBE_PTP_TX_IN_PROGRESS, + &adapter->state))) { skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; tx_flags |= IXGBE_TX_FLAGS_TSTAMP; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index 8b527d79d429..63515a6f67fa 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c @@ -493,6 +493,7 @@ static void ixgbe_ptp_tx_hwtstamp(struct ixgbe_adapter *adapter) dev_kfree_skb_any(adapter->ptp_tx_skb); adapter->ptp_tx_skb = NULL; + clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, &adapter->state); } /** @@ -515,6 +516,7 @@ static void ixgbe_ptp_tx_hwtstamp_work(struct work_struct *work) if (timeout) { dev_kfree_skb_any(adapter->ptp_tx_skb); adapter->ptp_tx_skb = NULL; + clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, &adapter->state); e_warn(drv, "clearing Tx Timestamp hang"); return; } @@ -925,6 +927,7 @@ void ixgbe_ptp_stop(struct ixgbe_adapter *adapter) if (adapter->ptp_tx_skb) { dev_kfree_skb_any(adapter->ptp_tx_skb); adapter->ptp_tx_skb = NULL; + clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, &adapter->state); } if (adapter->ptp_clock) { From 6425f0f353b91c2edad65a7e7d1362d1787d26fd Mon Sep 17 00:00:00 2001 From: Jean Sacren Date: Tue, 11 Mar 2014 05:57:56 +0000 Subject: [PATCH 05/13] ixgbe: fix ixgbe_check_reset_blocked() declaration The commit c97506ab0e22 ("ixgbe: Add check for FW veto bit") introduced the new function ixgbe_check_reset_blocked() with a minor issue in declaration. Fix the declaration by changing the type specifier to bool as the definition returns a boolean value. Additionally all ixgbe_check_reset_blocked() callers are expected to return a boolean value. Signed-off-by: Jean Sacren Acked-by: Don Skidmore Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c | 2 +- drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c index ad51c12cb26a..23f765263f12 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c @@ -107,7 +107,7 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) * have this bit just return false since the link can not be blocked * via this method. **/ -s32 ixgbe_check_reset_blocked(struct ixgbe_hw *hw) +bool ixgbe_check_reset_blocked(struct ixgbe_hw *hw) { u32 mmngc; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h index 4a456c974ef2..0bb047f751c2 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h @@ -128,7 +128,7 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw, s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, bool *autoneg); -s32 ixgbe_check_reset_blocked(struct ixgbe_hw *hw); +bool ixgbe_check_reset_blocked(struct ixgbe_hw *hw); /* PHY specific */ s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, From 32c74949b4e37f80ab74d9b497ffb3749cfcb85a Mon Sep 17 00:00:00 2001 From: Mark Rustad Date: Tue, 18 Mar 2014 07:03:35 +0000 Subject: [PATCH 06/13] ixgbevf: Change ixgbe_read_reg to ixgbevf_read_reg Change the ixgbe_read_reg function name to ixgbevf_read_reg to avoid a namespace clash with the ixgbe driver. This will allow ixgbe to take its register read function out-of-line to reduce memory footprint. Signed-off-by: Mark Rustad Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbevf/ethtool.c | 8 ++++---- drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 4 ++-- drivers/net/ethernet/intel/ixgbevf/vf.h | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbevf/ethtool.c b/drivers/net/ethernet/intel/ixgbevf/ethtool.c index b2d002394e5d..1baecb60f065 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ethtool.c +++ b/drivers/net/ethernet/intel/ixgbevf/ethtool.c @@ -540,10 +540,10 @@ static bool reg_pattern_test(struct ixgbevf_adapter *adapter, u64 *data, return true; } for (pat = 0; pat < ARRAY_SIZE(register_test_patterns); pat++) { - before = ixgbe_read_reg(&adapter->hw, reg); + before = ixgbevf_read_reg(&adapter->hw, reg); ixgbe_write_reg(&adapter->hw, reg, register_test_patterns[pat] & write); - val = ixgbe_read_reg(&adapter->hw, reg); + val = ixgbevf_read_reg(&adapter->hw, reg); if (val != (register_test_patterns[pat] & write & mask)) { hw_dbg(&adapter->hw, "pattern test reg %04X failed: got 0x%08X expected 0x%08X\n", @@ -567,9 +567,9 @@ static bool reg_set_and_check(struct ixgbevf_adapter *adapter, u64 *data, *data = 1; return true; } - before = ixgbe_read_reg(&adapter->hw, reg); + before = ixgbevf_read_reg(&adapter->hw, reg); ixgbe_write_reg(&adapter->hw, reg, write & mask); - val = ixgbe_read_reg(&adapter->hw, reg); + val = ixgbevf_read_reg(&adapter->hw, reg); if ((write & mask) != (val & mask)) { pr_err("set/check reg %04X test failed: got 0x%08X expected 0x%08X\n", reg, (val & mask), write & mask); diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index a50e892a5d21..5d9375981713 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -124,12 +124,12 @@ static void ixgbevf_check_remove(struct ixgbe_hw *hw, u32 reg) ixgbevf_remove_adapter(hw); return; } - value = ixgbe_read_reg(hw, IXGBE_VFSTATUS); + value = ixgbevf_read_reg(hw, IXGBE_VFSTATUS); if (value == IXGBE_FAILED_READ_REG) ixgbevf_remove_adapter(hw); } -u32 ixgbe_read_reg(struct ixgbe_hw *hw, u32 reg) +u32 ixgbevf_read_reg(struct ixgbe_hw *hw, u32 reg) { u8 __iomem *reg_addr = ACCESS_ONCE(hw->hw_addr); u32 value; diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.h b/drivers/net/ethernet/intel/ixgbevf/vf.h index 096d33a59def..3061d1890471 100644 --- a/drivers/net/ethernet/intel/ixgbevf/vf.h +++ b/drivers/net/ethernet/intel/ixgbevf/vf.h @@ -186,8 +186,8 @@ static inline void ixgbe_write_reg(struct ixgbe_hw *hw, u32 reg, u32 value) } #define IXGBE_WRITE_REG(h, r, v) ixgbe_write_reg(h, r, v) -u32 ixgbe_read_reg(struct ixgbe_hw *hw, u32 reg); -#define IXGBE_READ_REG(h, r) ixgbe_read_reg(h, r) +u32 ixgbevf_read_reg(struct ixgbe_hw *hw, u32 reg); +#define IXGBE_READ_REG(h, r) ixgbevf_read_reg(h, r) static inline void ixgbe_write_reg_array(struct ixgbe_hw *hw, u32 reg, u32 offset, u32 value) @@ -199,7 +199,7 @@ static inline void ixgbe_write_reg_array(struct ixgbe_hw *hw, u32 reg, static inline u32 ixgbe_read_reg_array(struct ixgbe_hw *hw, u32 reg, u32 offset) { - return ixgbe_read_reg(hw, reg + (offset << 2)); + return ixgbevf_read_reg(hw, reg + (offset << 2)); } #define IXGBE_READ_REG_ARRAY(h, r, o) ixgbe_read_reg_array(h, r, o) From 21d3efdc2d47fa0e7d34329e55471e26fbf37fd7 Mon Sep 17 00:00:00 2001 From: Jean Sacren Date: Mon, 17 Mar 2014 18:14:39 +0000 Subject: [PATCH 07/13] i40e: fix function kernel doc description The commit c7d05ca89f8e ("i40e: driver ethtool core") introduced the new function i40e_add_del_fdir_sctpv4() with the kernel doc description a little bit off. The trivial error was copied over to a different file by the commit 17a73f6b1401 ("i40e: Flow Director sideband accounting") most recently. Fix the kernel doc with the correct description for clarity. Cc: Jesse Brandeburg Cc: Joseph Gasparakis Signed-off-by: Jean Sacren Tested-by: Kavindya Deegala Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index a329aacb392f..0f5d96ad281d 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -299,7 +299,7 @@ static int i40e_add_del_fdir_tcpv4(struct i40e_vsi *vsi, * @raw_packet: the pre-allocated packet buffer for FDir * @add: true adds a filter, false removes it * - * Returns 0 if the filters were successfully added or removed + * Always returns -EOPNOTSUPP **/ static int i40e_add_del_fdir_sctpv4(struct i40e_vsi *vsi, struct i40e_fdir_filter *fd_data, From e3e3bfdd1d2ad4ac2020e681f3cb1e172f343810 Mon Sep 17 00:00:00 2001 From: Jean Sacren Date: Tue, 25 Mar 2014 04:30:27 +0000 Subject: [PATCH 08/13] i40e/i40evf: fix error checking path The commit 6494294f277fd ("i40e/i40evf: Use dma_set_mask_and_coherent") uses dma_set_mask_and_coherent() to replace dma_set_coherent_mask() for the benefit of return error. The conversion brings some confusion in error checking as whether against DMA_BIT_MASK(64) or DMA_BIT_MASK(32). For one, if error is zero, the check will be against DMA_BIT_MASK(64) twice. Fix this error checking by binding the check to the pertinent one. Cc: Mitch Williams Signed-off-by: Jean Sacren Tested-by: Kavindya Deegala Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 11 ++++++----- drivers/net/ethernet/intel/i40evf/i40evf_main.c | 11 ++++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index a1ec793b93db..861b722c2672 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -8091,12 +8091,13 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* set up for high or low dma */ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); - if (err) - err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); if (err) { - dev_err(&pdev->dev, - "DMA configuration failed: 0x%x\n", err); - goto err_dma; + err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + if (err) { + dev_err(&pdev->dev, + "DMA configuration failed: 0x%x\n", err); + goto err_dma; + } } /* set up pci connections */ diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c index 51c84c19d2be..e35e66ffa782 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c @@ -2191,12 +2191,13 @@ static int i40evf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return err; err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); - if (err) - err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); if (err) { - dev_err(&pdev->dev, - "DMA configuration failed: 0x%x\n", err); - goto err_dma; + err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + if (err) { + dev_err(&pdev->dev, + "DMA configuration failed: 0x%x\n", err); + goto err_dma; + } } err = pci_request_regions(pdev, i40evf_driver_name); From b58f2f72797cf45f0e6867f671ff42128b84834b Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 25 Mar 2014 04:30:32 +0000 Subject: [PATCH 09/13] i40e/i40evf: Remove addressof casts to same type Using addressof then casting to the original type is pointless, so remove these unnecessary casts. Done via coccinelle script: $ cat typecast.cocci @@ type T; T foo; @@ - (T *)&foo + &foo Signed-off-by: Joe Perches Tested-by: Kavindya Deegala Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_common.c | 4 ++-- drivers/net/ethernet/intel/i40evf/i40e_common.c | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index bb948dd92474..922cdcc45c54 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -1775,9 +1775,9 @@ static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff, cap = (struct i40e_aqc_list_capabilities_element_resp *) buff; if (list_type_opc == i40e_aqc_opc_list_dev_capabilities) - p = (struct i40e_hw_capabilities *)&hw->dev_caps; + p = &hw->dev_caps; else if (list_type_opc == i40e_aqc_opc_list_func_capabilities) - p = (struct i40e_hw_capabilities *)&hw->func_caps; + p = &hw->func_caps; else return; diff --git a/drivers/net/ethernet/intel/i40evf/i40e_common.c b/drivers/net/ethernet/intel/i40evf/i40e_common.c index c688a0fc5c29..ae084378faab 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_common.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_common.c @@ -565,8 +565,7 @@ i40e_status i40e_aq_send_msg_to_pf(struct i40e_hw *hw, details.async = true; cmd_details = &details; } - status = i40evf_asq_send_command(hw, (struct i40e_aq_desc *)&desc, msg, - msglen, cmd_details); + status = i40evf_asq_send_command(hw, &desc, msg, msglen, cmd_details); return status; } From 3dbb7fd24794e39e503bc7844dae03c17d821326 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 25 Mar 2014 04:30:38 +0000 Subject: [PATCH 10/13] i40e: Remove casts of pointer to same type Casting a pointer to a pointer of the same type is pointless, so remove these unnecessary casts. Done via coccinelle script: $ cat typecast_2.cocci @@ type T; T *foo; @@ - (T *)foo + foo Signed-off-by: Joe Perches Tested-by: Kavindya Deegala Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index aa123f43fb8e..03d99cbc5c25 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -396,7 +396,7 @@ static int i40e_get_eeprom(struct net_device *netdev, ret_val = i40e_aq_read_nvm(hw, 0x0, eeprom->offset + (I40E_NVM_SECTOR_SIZE * i), len, - (u8 *)eeprom_buff + (I40E_NVM_SECTOR_SIZE * i), + eeprom_buff + (I40E_NVM_SECTOR_SIZE * i), last, NULL); if (ret_val) { dev_info(&pf->pdev->dev, @@ -408,7 +408,7 @@ static int i40e_get_eeprom(struct net_device *netdev, release_nvm: i40e_release_nvm(hw); - memcpy(bytes, (u8 *)eeprom_buff, eeprom->len); + memcpy(bytes, eeprom_buff, eeprom->len); free_buff: kfree(eeprom_buff); return ret_val; From 75009b3a88cd8f56315eb4ced296ee2f060cf946 Mon Sep 17 00:00:00 2001 From: Peter Senna Tschudin Date: Thu, 20 Mar 2014 03:31:08 +0000 Subject: [PATCH 11/13] INTEL-IGB: Convert iounmap to pci_iounmap Use pci_iounmap instead of iounmap when the virtual mapping was done with pci_iomap. A simplified version of the semantic patch that finds this issue is as follows: (http://coccinelle.lip6.fr/) // @r@ expression addr; @@ addr = pci_iomap(...) @rr@ expression r.addr; @@ * iounmap(addr) // Signed-off-by: Peter Senna Tschudin Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/igb/igb_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 55fc5596e2d0..30198185d19a 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -2652,7 +2652,7 @@ err_eeprom: iounmap(hw->flash_address); err_sw_init: igb_clear_interrupt_scheme(adapter); - iounmap(hw->hw_addr); + pci_iounmap(pdev, hw->hw_addr); err_ioremap: free_netdev(netdev); err_alloc_etherdev: @@ -2819,7 +2819,7 @@ static void igb_remove(struct pci_dev *pdev) igb_disable_sriov(pdev); #endif - iounmap(hw->hw_addr); + pci_iounmap(pdev, hw->hw_addr); if (hw->flash_address) iounmap(hw->flash_address); pci_release_selected_regions(pdev, From 41c62843eb6a0ea3e2f1e06ca3ec7b2f64452f7b Mon Sep 17 00:00:00 2001 From: Mark Rustad Date: Wed, 12 Mar 2014 00:38:35 +0000 Subject: [PATCH 12/13] ixgbe: Fix rcu warnings induced by LER Resolve some rcu warnings produced when LER actions take place. This appears to be due to not holding the rtnl lock when calling ixgbe_down, so hold the lock. Also avoid disabling the device when it is already disabled. This check is necessary because the callback can be called more than once in some cases. Signed-off-by: Mark Rustad Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbe/ixgbe.h | 1 + drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 23 +++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 26d27aae9793..55c53a1cbb62 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -808,6 +808,7 @@ enum ixgbe_state_t { __IXGBE_TESTING, __IXGBE_RESETTING, __IXGBE_DOWN, + __IXGBE_DISABLED, __IXGBE_REMOVING, __IXGBE_SERVICE_SCHED, __IXGBE_IN_SFP_INIT, diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index c4b930c0ce7f..8436c651b735 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -5566,6 +5566,8 @@ static int ixgbe_resume(struct pci_dev *pdev) e_dev_err("Cannot enable PCI device from suspend\n"); return err; } + smp_mb__before_clear_bit(); + clear_bit(__IXGBE_DISABLED, &adapter->state); pci_set_master(pdev); pci_wake_from_d3(pdev, false); @@ -5663,7 +5665,8 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake) ixgbe_release_hw_control(adapter); - pci_disable_device(pdev); + if (!test_and_set_bit(__IXGBE_DISABLED, &adapter->state)) + pci_disable_device(pdev); return 0; } @@ -8313,7 +8316,8 @@ err_alloc_etherdev: pci_select_bars(pdev, IORESOURCE_MEM)); err_pci_reg: err_dma: - pci_disable_device(pdev); + if (!test_and_set_bit(__IXGBE_DISABLED, &adapter->state)) + pci_disable_device(pdev); return err; } @@ -8382,7 +8386,8 @@ static void ixgbe_remove(struct pci_dev *pdev) pci_disable_pcie_error_reporting(pdev); - pci_disable_device(pdev); + if (!test_and_set_bit(__IXGBE_DISABLED, &adapter->state)) + pci_disable_device(pdev); } /** @@ -8489,14 +8494,20 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev, skip_bad_vf_detection: #endif /* CONFIG_PCI_IOV */ + rtnl_lock(); netif_device_detach(netdev); - if (state == pci_channel_io_perm_failure) + if (state == pci_channel_io_perm_failure) { + rtnl_unlock(); return PCI_ERS_RESULT_DISCONNECT; + } if (netif_running(netdev)) ixgbe_down(adapter); - pci_disable_device(pdev); + + if (!test_and_set_bit(__IXGBE_DISABLED, &adapter->state)) + pci_disable_device(pdev); + rtnl_unlock(); /* Request a slot reset. */ return PCI_ERS_RESULT_NEED_RESET; @@ -8518,6 +8529,8 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev) e_err(probe, "Cannot re-enable PCI device after reset.\n"); result = PCI_ERS_RESULT_DISCONNECT; } else { + smp_mb__before_clear_bit(); + clear_bit(__IXGBE_DISABLED, &adapter->state); adapter->hw.hw_addr = adapter->io_addr; pci_set_master(pdev); pci_restore_state(pdev); From bc0c715167c68ac2e737e221a80fc2a413f48155 Mon Sep 17 00:00:00 2001 From: Mark Rustad Date: Wed, 12 Mar 2014 00:38:45 +0000 Subject: [PATCH 13/13] ixgbevf: Fix rcu warnings induced by LER Resolve some rcu warnings produced when LER actions take place. This appears to be due to not holding the rtnl lock when calling ixgbe_down, so hold the lock. Also avoid disabling the device when it is already disabled. This check is necessary because the callback can be called more than once in some cases. Signed-off-by: Mark Rustad Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 1 + .../net/ethernet/intel/ixgbevf/ixgbevf_main.c | 22 ++++++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h index a08bd7c46766..e7e7d695816b 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h @@ -419,6 +419,7 @@ enum ixbgevf_state_t { __IXGBEVF_TESTING, __IXGBEVF_RESETTING, __IXGBEVF_DOWN, + __IXGBEVF_DISABLED, __IXGBEVF_REMOVING, }; diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 5d9375981713..4ba139b2d25a 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -3329,7 +3329,8 @@ static int ixgbevf_suspend(struct pci_dev *pdev, pm_message_t state) return retval; #endif - pci_disable_device(pdev); + if (!test_and_set_bit(__IXGBEVF_DISABLED, &adapter->state)) + pci_disable_device(pdev); return 0; } @@ -3353,6 +3354,8 @@ static int ixgbevf_resume(struct pci_dev *pdev) dev_err(&pdev->dev, "Cannot enable PCI device from suspend\n"); return err; } + smp_mb__before_clear_bit(); + clear_bit(__IXGBEVF_DISABLED, &adapter->state); pci_set_master(pdev); ixgbevf_reset(adapter); @@ -3607,7 +3610,8 @@ err_alloc_etherdev: pci_release_regions(pdev); err_pci_reg: err_dma: - pci_disable_device(pdev); + if (!test_and_set_bit(__IXGBEVF_DISABLED, &adapter->state)) + pci_disable_device(pdev); return err; } @@ -3645,7 +3649,8 @@ static void ixgbevf_remove(struct pci_dev *pdev) free_netdev(netdev); - pci_disable_device(pdev); + if (!test_and_set_bit(__IXGBEVF_DISABLED, &adapter->state)) + pci_disable_device(pdev); } /** @@ -3662,15 +3667,20 @@ static pci_ers_result_t ixgbevf_io_error_detected(struct pci_dev *pdev, struct net_device *netdev = pci_get_drvdata(pdev); struct ixgbevf_adapter *adapter = netdev_priv(netdev); + rtnl_lock(); netif_device_detach(netdev); - if (state == pci_channel_io_perm_failure) + if (state == pci_channel_io_perm_failure) { + rtnl_unlock(); return PCI_ERS_RESULT_DISCONNECT; + } if (netif_running(netdev)) ixgbevf_down(adapter); - pci_disable_device(pdev); + if (!test_and_set_bit(__IXGBEVF_DISABLED, &adapter->state)) + pci_disable_device(pdev); + rtnl_unlock(); /* Request a slot slot reset. */ return PCI_ERS_RESULT_NEED_RESET; @@ -3694,6 +3704,8 @@ static pci_ers_result_t ixgbevf_io_slot_reset(struct pci_dev *pdev) return PCI_ERS_RESULT_DISCONNECT; } + smp_mb__before_clear_bit(); + clear_bit(__IXGBEVF_DISABLED, &adapter->state); pci_set_master(pdev); ixgbevf_reset(adapter);