Commit 0a862b43 authored by Catherine Sullivan's avatar Catherine Sullivan Committed by Jeff Kirsher

i40e/i40evf: Add module_types and update_link_info

Add a module_types variable to the link_info struct to save the module
information from get_phy_capabilities. This information can be used to
determine which speeds the module supports.

Also add a new function update_link_info which updates the module_types
parameter and then calls get_link_info. This function should be called
in place of get_link_info so that the module_types variable stays
up-to-date with the rest of the link information.

The EAS table does not reflect the values that are actually returned,
so instead, basing these values on the Ethernet compliance codes
specified in table 33 of SFF-8436 as these have been accurate.

Use the new variable in ethtool to differentiate between a 10G/1G dual
speed fiber module and a 10G only module.

Change-ID: Ib7585cce321319c10ce15180054c41a6cbd41389
Signed-off-by: default avatarCatherine Sullivan <catherine.sullivan@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent d72c95ea
...@@ -1717,14 +1717,14 @@ enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures, ...@@ -1717,14 +1717,14 @@ enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
*aq_failures |= I40E_SET_FC_AQ_FAIL_SET; *aq_failures |= I40E_SET_FC_AQ_FAIL_SET;
} }
/* Update the link info */ /* Update the link info */
status = i40e_aq_get_link_info(hw, true, NULL, NULL); status = i40e_update_link_info(hw);
if (status) { if (status) {
/* Wait a little bit (on 40G cards it sometimes takes a really /* Wait a little bit (on 40G cards it sometimes takes a really
* long time for link to come back from the atomic reset) * long time for link to come back from the atomic reset)
* and try once more * and try once more
*/ */
msleep(1000); msleep(1000);
status = i40e_aq_get_link_info(hw, true, NULL, NULL); status = i40e_update_link_info(hw);
} }
if (status) if (status)
*aq_failures |= I40E_SET_FC_AQ_FAIL_UPDATE; *aq_failures |= I40E_SET_FC_AQ_FAIL_UPDATE;
...@@ -2247,7 +2247,7 @@ i40e_status i40e_get_link_status(struct i40e_hw *hw, bool *link_up) ...@@ -2247,7 +2247,7 @@ i40e_status i40e_get_link_status(struct i40e_hw *hw, bool *link_up)
i40e_status status = 0; i40e_status status = 0;
if (hw->phy.get_link_info) { if (hw->phy.get_link_info) {
status = i40e_aq_get_link_info(hw, true, NULL, NULL); status = i40e_update_link_info(hw);
if (status) if (status)
i40e_debug(hw, I40E_DEBUG_LINK, "get link failed: status %d\n", i40e_debug(hw, I40E_DEBUG_LINK, "get link failed: status %d\n",
...@@ -2259,6 +2259,30 @@ i40e_status i40e_get_link_status(struct i40e_hw *hw, bool *link_up) ...@@ -2259,6 +2259,30 @@ i40e_status i40e_get_link_status(struct i40e_hw *hw, bool *link_up)
return status; return status;
} }
/**
* i40e_updatelink_status - update status of the HW network link
* @hw: pointer to the hw struct
**/
i40e_status i40e_update_link_info(struct i40e_hw *hw)
{
struct i40e_aq_get_phy_abilities_resp abilities;
i40e_status status = 0;
status = i40e_aq_get_link_info(hw, true, NULL, NULL);
if (status)
return status;
status = i40e_aq_get_phy_capabilities(hw, false, false, &abilities,
NULL);
if (status)
return status;
memcpy(hw->phy.link_info.module_type, &abilities.module_type,
sizeof(hw->phy.link_info.module_type));
return status;
}
/** /**
* i40e_aq_add_veb - Insert a VEB between the VSI and the MAC * i40e_aq_add_veb - Insert a VEB between the VSI and the MAC
* @hw: pointer to the hw struct * @hw: pointer to the hw struct
......
...@@ -307,12 +307,18 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw, ...@@ -307,12 +307,18 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw,
case I40E_PHY_TYPE_10GBASE_LR: case I40E_PHY_TYPE_10GBASE_LR:
case I40E_PHY_TYPE_1000BASE_SX: case I40E_PHY_TYPE_1000BASE_SX:
case I40E_PHY_TYPE_1000BASE_LX: case I40E_PHY_TYPE_1000BASE_LX:
ecmd->supported = SUPPORTED_10000baseT_Full | ecmd->supported = SUPPORTED_10000baseT_Full;
SUPPORTED_1000baseT_Full; if (hw_link_info->module_type[2] &
I40E_MODULE_TYPE_1000BASE_SX ||
hw_link_info->module_type[2] &
I40E_MODULE_TYPE_1000BASE_LX) {
ecmd->supported |= SUPPORTED_1000baseT_Full;
if (hw_link_info->requested_speeds &
I40E_LINK_SPEED_1GB)
ecmd->advertising |= ADVERTISED_1000baseT_Full;
}
if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB) if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB)
ecmd->advertising |= ADVERTISED_10000baseT_Full; ecmd->advertising |= ADVERTISED_10000baseT_Full;
if (hw_link_info->requested_speeds & I40E_LINK_SPEED_1GB)
ecmd->advertising |= ADVERTISED_1000baseT_Full;
break; break;
case I40E_PHY_TYPE_1000BASE_KX: case I40E_PHY_TYPE_1000BASE_KX:
ecmd->supported = SUPPORTED_Autoneg | ecmd->supported = SUPPORTED_Autoneg |
...@@ -704,7 +710,7 @@ static int i40e_set_settings(struct net_device *netdev, ...@@ -704,7 +710,7 @@ static int i40e_set_settings(struct net_device *netdev,
return -EAGAIN; return -EAGAIN;
} }
status = i40e_aq_get_link_info(hw, true, NULL, NULL); status = i40e_update_link_info(hw);
if (status) if (status)
netdev_info(netdev, "Updating link info failed with err %s aq_err %s\n", netdev_info(netdev, "Updating link info failed with err %s aq_err %s\n",
i40e_stat_str(hw, status), i40e_stat_str(hw, status),
......
...@@ -9728,7 +9728,7 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit) ...@@ -9728,7 +9728,7 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit)
i40e_config_rss(pf); i40e_config_rss(pf);
/* fill in link information and enable LSE reporting */ /* fill in link information and enable LSE reporting */
i40e_aq_get_link_info(&pf->hw, true, NULL, NULL); i40e_update_link_info(&pf->hw);
i40e_link_event(pf); i40e_link_event(pf);
/* Initialize user-specific link properties */ /* Initialize user-specific link properties */
......
...@@ -259,6 +259,7 @@ i40e_status i40e_pf_reset(struct i40e_hw *hw); ...@@ -259,6 +259,7 @@ i40e_status i40e_pf_reset(struct i40e_hw *hw);
void i40e_clear_hw(struct i40e_hw *hw); void i40e_clear_hw(struct i40e_hw *hw);
void i40e_clear_pxe_mode(struct i40e_hw *hw); void i40e_clear_pxe_mode(struct i40e_hw *hw);
i40e_status i40e_get_link_status(struct i40e_hw *hw, bool *link_up); i40e_status i40e_get_link_status(struct i40e_hw *hw, bool *link_up);
i40e_status i40e_update_link_info(struct i40e_hw *hw);
i40e_status i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr); i40e_status i40e_get_mac_addr(struct i40e_hw *hw, u8 *mac_addr);
i40e_status i40e_read_bw_from_alt_ram(struct i40e_hw *hw, i40e_status i40e_read_bw_from_alt_ram(struct i40e_hw *hw,
u32 *max_bw, u32 *min_bw, bool *min_valid, u32 *max_bw, u32 *min_bw, bool *min_valid,
......
...@@ -167,6 +167,24 @@ struct i40e_link_status { ...@@ -167,6 +167,24 @@ struct i40e_link_status {
bool crc_enable; bool crc_enable;
u8 pacing; u8 pacing;
u8 requested_speeds; u8 requested_speeds;
u8 module_type[3];
/* 1st byte: module identifier */
#define I40E_MODULE_TYPE_SFP 0x03
#define I40E_MODULE_TYPE_QSFP 0x0D
/* 2nd byte: ethernet compliance codes for 10/40G */
#define I40E_MODULE_TYPE_40G_ACTIVE 0x01
#define I40E_MODULE_TYPE_40G_LR4 0x02
#define I40E_MODULE_TYPE_40G_SR4 0x04
#define I40E_MODULE_TYPE_40G_CR4 0x08
#define I40E_MODULE_TYPE_10G_BASE_SR 0x10
#define I40E_MODULE_TYPE_10G_BASE_LR 0x20
#define I40E_MODULE_TYPE_10G_BASE_LRM 0x40
#define I40E_MODULE_TYPE_10G_BASE_ER 0x80
/* 3rd byte: ethernet compliance codes for 1G */
#define I40E_MODULE_TYPE_1000BASE_SX 0x01
#define I40E_MODULE_TYPE_1000BASE_LX 0x02
#define I40E_MODULE_TYPE_1000BASE_CX 0x04
#define I40E_MODULE_TYPE_1000BASE_T 0x08
}; };
struct i40e_phy_info { struct i40e_phy_info {
......
...@@ -167,6 +167,24 @@ struct i40e_link_status { ...@@ -167,6 +167,24 @@ struct i40e_link_status {
bool crc_enable; bool crc_enable;
u8 pacing; u8 pacing;
u8 requested_speeds; u8 requested_speeds;
u8 module_type[3];
/* 1st byte: module identifier */
#define I40E_MODULE_TYPE_SFP 0x03
#define I40E_MODULE_TYPE_QSFP 0x0D
/* 2nd byte: ethernet compliance codes for 10/40G */
#define I40E_MODULE_TYPE_40G_ACTIVE 0x01
#define I40E_MODULE_TYPE_40G_LR4 0x02
#define I40E_MODULE_TYPE_40G_SR4 0x04
#define I40E_MODULE_TYPE_40G_CR4 0x08
#define I40E_MODULE_TYPE_10G_BASE_SR 0x10
#define I40E_MODULE_TYPE_10G_BASE_LR 0x20
#define I40E_MODULE_TYPE_10G_BASE_LRM 0x40
#define I40E_MODULE_TYPE_10G_BASE_ER 0x80
/* 3rd byte: ethernet compliance codes for 1G */
#define I40E_MODULE_TYPE_1000BASE_SX 0x01
#define I40E_MODULE_TYPE_1000BASE_LX 0x02
#define I40E_MODULE_TYPE_1000BASE_CX 0x04
#define I40E_MODULE_TYPE_1000BASE_T 0x08
}; };
struct i40e_phy_info { struct i40e_phy_info {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment