aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Brandeburg <jesse.brandeburg@intel.com>2015-08-26 15:14:19 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2015-10-07 17:23:09 -0400
commita72a5abcb37beac163704efba6a3d33ebca4d90a (patch)
tree7922bf1bc1bcffb8ffc96353f684f295eb2d1b65
parentdd38c583aea07c508caeaf979c64e267584ee067 (diff)
i40e: fix bug in return from get_link_status and avoid spurious link messages
Previously, the driver could call this function and have only true/false returned, but false could mean multiple things like failure to read or link was down. This change allows the caller to get all return values in the call chain bubbled back to the source, which keeps information about failures from being lost. Also, in some unlikely scenarios, the firmware can become slow to respond to admin queue (AQ) queries for link state. Should the AQ time out, the driver can detect the state and avoid a link change when there may have been none. Change-ID: Ib2ac38407b7880750fb891b392fa77457fe6c21c Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_common.c15
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_ethtool.c11
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_main.c12
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_prototype.h2
4 files changed, 29 insertions, 11 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
index 7a70abcafbbb..2839ea53234d 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
@@ -2235,27 +2235,28 @@ i40e_status i40e_aq_send_driver_version(struct i40e_hw *hw,
2235/** 2235/**
2236 * i40e_get_link_status - get status of the HW network link 2236 * i40e_get_link_status - get status of the HW network link
2237 * @hw: pointer to the hw struct 2237 * @hw: pointer to the hw struct
2238 * @link_up: pointer to bool (true/false = linkup/linkdown)
2238 * 2239 *
2239 * Returns true if link is up, false if link is down. 2240 * Variable link_up true if link is up, false if link is down.
2241 * The variable link_up is invalid if returned value of status != 0
2240 * 2242 *
2241 * Side effect: LinkStatusEvent reporting becomes enabled 2243 * Side effect: LinkStatusEvent reporting becomes enabled
2242 **/ 2244 **/
2243bool i40e_get_link_status(struct i40e_hw *hw) 2245i40e_status i40e_get_link_status(struct i40e_hw *hw, bool *link_up)
2244{ 2246{
2245 i40e_status status = 0; 2247 i40e_status status = 0;
2246 bool link_status = false;
2247 2248
2248 if (hw->phy.get_link_info) { 2249 if (hw->phy.get_link_info) {
2249 status = i40e_aq_get_link_info(hw, true, NULL, NULL); 2250 status = i40e_aq_get_link_info(hw, true, NULL, NULL);
2250 2251
2251 if (status) 2252 if (status)
2252 goto i40e_get_link_status_exit; 2253 i40e_debug(hw, I40E_DEBUG_LINK, "get link failed: status %d\n",
2254 status);
2253 } 2255 }
2254 2256
2255 link_status = hw->phy.link_info.link_info & I40E_AQ_LINK_UP; 2257 *link_up = hw->phy.link_info.link_info & I40E_AQ_LINK_UP;
2256 2258
2257i40e_get_link_status_exit: 2259 return status;
2258 return link_status;
2259} 2260}
2260 2261
2261/** 2262/**
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index 930369c4882b..1fa38f6e0e19 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -1516,9 +1516,18 @@ static int i40e_link_test(struct net_device *netdev, u64 *data)
1516{ 1516{
1517 struct i40e_netdev_priv *np = netdev_priv(netdev); 1517 struct i40e_netdev_priv *np = netdev_priv(netdev);
1518 struct i40e_pf *pf = np->vsi->back; 1518 struct i40e_pf *pf = np->vsi->back;
1519 i40e_status status;
1520 bool link_up = false;
1519 1521
1520 netif_info(pf, hw, netdev, "link test\n"); 1522 netif_info(pf, hw, netdev, "link test\n");
1521 if (i40e_get_link_status(&pf->hw)) 1523 status = i40e_get_link_status(&pf->hw, &link_up);
1524 if (status) {
1525 netif_err(pf, drv, netdev, "link query timed out, please retry test\n");
1526 *data = 1;
1527 return *data;
1528 }
1529
1530 if (link_up)
1522 *data = 0; 1531 *data = 0;
1523 else 1532 else
1524 *data = 1; 1533 *data = 1;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 1fa1ebab9e92..f205e18a8530 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -5836,15 +5836,23 @@ static void i40e_veb_link_event(struct i40e_veb *veb, bool link_up)
5836 **/ 5836 **/
5837static void i40e_link_event(struct i40e_pf *pf) 5837static void i40e_link_event(struct i40e_pf *pf)
5838{ 5838{
5839 bool new_link, old_link;
5840 struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi]; 5839 struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
5841 u8 new_link_speed, old_link_speed; 5840 u8 new_link_speed, old_link_speed;
5841 i40e_status status;
5842 bool new_link, old_link;
5842 5843
5843 /* set this to force the get_link_status call to refresh state */ 5844 /* set this to force the get_link_status call to refresh state */
5844 pf->hw.phy.get_link_info = true; 5845 pf->hw.phy.get_link_info = true;
5845 5846
5846 old_link = (pf->hw.phy.link_info_old.link_info & I40E_AQ_LINK_UP); 5847 old_link = (pf->hw.phy.link_info_old.link_info & I40E_AQ_LINK_UP);
5847 new_link = i40e_get_link_status(&pf->hw); 5848
5849 status = i40e_get_link_status(&pf->hw, &new_link);
5850 if (status) {
5851 dev_dbg(&pf->pdev->dev, "couldn't get link state, status: %d\n",
5852 status);
5853 return;
5854 }
5855
5848 old_link_speed = pf->hw.phy.link_info_old.link_speed; 5856 old_link_speed = pf->hw.phy.link_info_old.link_speed;
5849 new_link_speed = pf->hw.phy.link_info.link_speed; 5857 new_link_speed = pf->hw.phy.link_info.link_speed;
5850 5858
diff --git a/drivers/net/ethernet/intel/i40e/i40e_prototype.h b/drivers/net/ethernet/intel/i40e/i40e_prototype.h
index dcb72a8ee8e5..e51e1567837c 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_prototype.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_prototype.h
@@ -258,7 +258,7 @@ i40e_status i40e_init_shared_code(struct i40e_hw *hw);
258i40e_status i40e_pf_reset(struct i40e_hw *hw); 258i40e_status i40e_pf_reset(struct i40e_hw *hw);
259void i40e_clear_hw(struct i40e_hw *hw); 259void i40e_clear_hw(struct i40e_hw *hw);
260void i40e_clear_pxe_mode(struct i40e_hw *hw); 260void i40e_clear_pxe_mode(struct i40e_hw *hw);
261bool i40e_get_link_status(struct i40e_hw *hw); 261i40e_status i40e_get_link_status(struct i40e_hw *hw, bool *link_up);
262i40e_status i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr); 262i40e_status i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr);
263i40e_status i40e_read_bw_from_alt_ram(struct i40e_hw *hw, 263i40e_status i40e_read_bw_from_alt_ram(struct i40e_hw *hw,
264 u32 *max_bw, u32 *min_bw, bool *min_valid, 264 u32 *max_bw, u32 *min_bw, bool *min_valid,