Skip to content

Commit ea78ce4

Browse files
pgreenwaanguy11
authored andcommitted
ice: add link lenient and default override support
Adds functions to check for link override firmware support and get the override settings for a port. The previously supported/default link mode was strict mode. In strict mode link is configured based on get PHY capabilities PHY types with media. Lenient mode is now the default link mode. In lenient mode the link is configured based on get PHY capabilities PHY types without media. This allows the user to configure link that the media does not report. Limit the minimum supported link mode to 25G for devices that support 100G, and 1G for devices that support less than 100G. Default override is only supported in lenient mode. If default override is supported and enabled, then default override values are used for configuring speed and FEC. Default override provide persistent link settings in the NVM. Signed-off-by: Paul Greenwalt <[email protected]> Signed-off-by: Evan Swanson <[email protected]> Tested-by: Andrew Bowers <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent 1a3571b commit ea78ce4

File tree

9 files changed

+628
-216
lines changed

9 files changed

+628
-216
lines changed

drivers/net/ethernet/intel/ice/ice.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ enum ice_state {
222222
__ICE_OICR_INTR_DIS, /* Global OICR interrupt disabled */
223223
__ICE_MDD_VF_PRINT_PENDING, /* set when MDD event handle */
224224
__ICE_VF_RESETS_DISABLED, /* disable resets during ice_remove */
225+
__ICE_LINK_DEFAULT_OVERRIDE_PENDING,
225226
__ICE_PHY_INIT_COMPLETE,
226227
__ICE_STATE_NBITS /* must be last */
227228
};
@@ -364,6 +365,7 @@ enum ice_pf_flags {
364365
ICE_FLAG_LEGACY_RX,
365366
ICE_FLAG_VF_TRUE_PROMISC_ENA,
366367
ICE_FLAG_MDD_AUTO_RESET_VF,
368+
ICE_FLAG_LINK_LENIENT_MODE_ENA,
367369
ICE_PF_FLAGS_NBITS /* must be last */
368370
};
369371

@@ -441,6 +443,7 @@ struct ice_pf {
441443

442444
__le64 nvm_phy_type_lo; /* NVM PHY type low */
443445
__le64 nvm_phy_type_hi; /* NVM PHY type high */
446+
struct ice_link_default_override_tlv link_dflt_override;
444447
};
445448

446449
struct ice_netdev_priv {

drivers/net/ethernet/intel/ice/ice_adminq_cmd.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -983,7 +983,8 @@ struct ice_aqc_get_phy_caps_data {
983983
#define ICE_AQC_PHY_FEC_25G_RS_CLAUSE91_EN BIT(6)
984984
#define ICE_AQC_PHY_FEC_25G_KR_CLAUSE74_EN BIT(7)
985985
#define ICE_AQC_PHY_FEC_MASK ICE_M(0xdf, 0)
986-
u8 rsvd1; /* Byte 35 reserved */
986+
u8 module_compliance_enforcement;
987+
#define ICE_AQC_MOD_ENFORCE_STRICT_MODE BIT(0)
987988
u8 extended_compliance_code;
988989
#define ICE_MODULE_TYPE_TOTAL_BYTE 3
989990
u8 module_type[ICE_MODULE_TYPE_TOTAL_BYTE];
@@ -1036,7 +1037,7 @@ struct ice_aqc_set_phy_cfg_data {
10361037
__le16 eee_cap; /* Value from ice_aqc_get_phy_caps */
10371038
__le16 eeer_value;
10381039
u8 link_fec_opt; /* Use defines from ice_aqc_get_phy_caps */
1039-
u8 rsvd1;
1040+
u8 module_compliance_enforcement;
10401041
};
10411042

10421043
/* Set MAC Config command data structure (direct 0x0603) */

drivers/net/ethernet/intel/ice/ice_common.c

Lines changed: 166 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,40 @@ static enum ice_status ice_set_mac_type(struct ice_hw *hw)
2020
if (hw->vendor_id != PCI_VENDOR_ID_INTEL)
2121
return ICE_ERR_DEVICE_NOT_SUPPORTED;
2222

23-
hw->mac_type = ICE_MAC_GENERIC;
23+
switch (hw->device_id) {
24+
case ICE_DEV_ID_E810C_BACKPLANE:
25+
case ICE_DEV_ID_E810C_QSFP:
26+
case ICE_DEV_ID_E810C_SFP:
27+
case ICE_DEV_ID_E810_XXV_SFP:
28+
hw->mac_type = ICE_MAC_E810;
29+
break;
30+
case ICE_DEV_ID_E823C_10G_BASE_T:
31+
case ICE_DEV_ID_E823C_BACKPLANE:
32+
case ICE_DEV_ID_E823C_QSFP:
33+
case ICE_DEV_ID_E823C_SFP:
34+
case ICE_DEV_ID_E823C_SGMII:
35+
case ICE_DEV_ID_E822C_10G_BASE_T:
36+
case ICE_DEV_ID_E822C_BACKPLANE:
37+
case ICE_DEV_ID_E822C_QSFP:
38+
case ICE_DEV_ID_E822C_SFP:
39+
case ICE_DEV_ID_E822C_SGMII:
40+
case ICE_DEV_ID_E822L_10G_BASE_T:
41+
case ICE_DEV_ID_E822L_BACKPLANE:
42+
case ICE_DEV_ID_E822L_SFP:
43+
case ICE_DEV_ID_E822L_SGMII:
44+
case ICE_DEV_ID_E823L_10G_BASE_T:
45+
case ICE_DEV_ID_E823L_1GBE:
46+
case ICE_DEV_ID_E823L_BACKPLANE:
47+
case ICE_DEV_ID_E823L_QSFP:
48+
case ICE_DEV_ID_E823L_SFP:
49+
hw->mac_type = ICE_MAC_GENERIC;
50+
break;
51+
default:
52+
hw->mac_type = ICE_MAC_UNKNOWN;
53+
break;
54+
}
55+
56+
ice_debug(hw, ICE_DBG_INIT, "mac_type: %d\n", hw->mac_type);
2457
return 0;
2558
}
2659

@@ -2675,7 +2708,7 @@ ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool ena_auto_link_update)
26752708
goto out;
26762709
}
26772710

2678-
ice_copy_phy_caps_to_cfg(pcaps, &cfg);
2711+
ice_copy_phy_caps_to_cfg(pi, pcaps, &cfg);
26792712

26802713
/* Configure the set PHY data */
26812714
status = ice_cfg_phy_fc(pi, &cfg, pi->fc.req_mode);
@@ -2757,17 +2790,19 @@ ice_phy_caps_equals_cfg(struct ice_aqc_get_phy_caps_data *phy_caps,
27572790

27582791
/**
27592792
* ice_copy_phy_caps_to_cfg - Copy PHY ability data to configuration data
2793+
* @pi: port information structure
27602794
* @caps: PHY ability structure to copy date from
27612795
* @cfg: PHY configuration structure to copy data to
27622796
*
27632797
* Helper function to copy AQC PHY get ability data to PHY set configuration
27642798
* data structure
27652799
*/
27662800
void
2767-
ice_copy_phy_caps_to_cfg(struct ice_aqc_get_phy_caps_data *caps,
2801+
ice_copy_phy_caps_to_cfg(struct ice_port_info *pi,
2802+
struct ice_aqc_get_phy_caps_data *caps,
27682803
struct ice_aqc_set_phy_cfg_data *cfg)
27692804
{
2770-
if (!caps || !cfg)
2805+
if (!pi || !caps || !cfg)
27712806
return;
27722807

27732808
memset(cfg, 0, sizeof(*cfg));
@@ -2778,6 +2813,19 @@ ice_copy_phy_caps_to_cfg(struct ice_aqc_get_phy_caps_data *caps,
27782813
cfg->eee_cap = caps->eee_cap;
27792814
cfg->eeer_value = caps->eeer_value;
27802815
cfg->link_fec_opt = caps->link_fec_options;
2816+
cfg->module_compliance_enforcement =
2817+
caps->module_compliance_enforcement;
2818+
2819+
if (ice_fw_supports_link_override(pi->hw)) {
2820+
struct ice_link_default_override_tlv tlv;
2821+
2822+
if (ice_get_link_default_override(&tlv, pi))
2823+
return;
2824+
2825+
if (tlv.options & ICE_LINK_OVERRIDE_STRICT_MODE)
2826+
cfg->module_compliance_enforcement |=
2827+
ICE_LINK_OVERRIDE_STRICT_MODE;
2828+
}
27812829
}
27822830

27832831
/**
@@ -2840,6 +2888,17 @@ ice_cfg_phy_fec(struct ice_port_info *pi, struct ice_aqc_set_phy_cfg_data *cfg,
28402888
break;
28412889
}
28422890

2891+
if (fec == ICE_FEC_AUTO && ice_fw_supports_link_override(pi->hw)) {
2892+
struct ice_link_default_override_tlv tlv;
2893+
2894+
if (ice_get_link_default_override(&tlv, pi))
2895+
goto out;
2896+
2897+
if (!(tlv.options & ICE_LINK_OVERRIDE_STRICT_MODE) &&
2898+
(tlv.options & ICE_LINK_OVERRIDE_EN))
2899+
cfg->link_fec_opt = tlv.fec_options;
2900+
}
2901+
28432902
out:
28442903
kfree(pcaps);
28452904

@@ -4043,3 +4102,106 @@ ice_sched_query_elem(struct ice_hw *hw, u32 node_teid,
40434102
ice_debug(hw, ICE_DBG_SCHED, "query element failed\n");
40444103
return status;
40454104
}
4105+
4106+
/**
4107+
* ice_fw_supports_link_override
4108+
* @hw: pointer to the hardware structure
4109+
*
4110+
* Checks if the firmware supports link override
4111+
*/
4112+
bool ice_fw_supports_link_override(struct ice_hw *hw)
4113+
{
4114+
/* Currently, only supported for E810 devices */
4115+
if (hw->mac_type != ICE_MAC_E810)
4116+
return false;
4117+
4118+
if (hw->api_maj_ver == ICE_FW_API_LINK_OVERRIDE_MAJ) {
4119+
if (hw->api_min_ver > ICE_FW_API_LINK_OVERRIDE_MIN)
4120+
return true;
4121+
if (hw->api_min_ver == ICE_FW_API_LINK_OVERRIDE_MIN &&
4122+
hw->api_patch >= ICE_FW_API_LINK_OVERRIDE_PATCH)
4123+
return true;
4124+
} else if (hw->api_maj_ver > ICE_FW_API_LINK_OVERRIDE_MAJ) {
4125+
return true;
4126+
}
4127+
4128+
return false;
4129+
}
4130+
4131+
/**
4132+
* ice_get_link_default_override
4133+
* @ldo: pointer to the link default override struct
4134+
* @pi: pointer to the port info struct
4135+
*
4136+
* Gets the link default override for a port
4137+
*/
4138+
enum ice_status
4139+
ice_get_link_default_override(struct ice_link_default_override_tlv *ldo,
4140+
struct ice_port_info *pi)
4141+
{
4142+
u16 i, tlv, tlv_len, tlv_start, buf, offset;
4143+
struct ice_hw *hw = pi->hw;
4144+
enum ice_status status;
4145+
4146+
status = ice_get_pfa_module_tlv(hw, &tlv, &tlv_len,
4147+
ICE_SR_LINK_DEFAULT_OVERRIDE_PTR);
4148+
if (status) {
4149+
ice_debug(hw, ICE_DBG_INIT,
4150+
"Failed to read link override TLV.\n");
4151+
return status;
4152+
}
4153+
4154+
/* Each port has its own config; calculate for our port */
4155+
tlv_start = tlv + pi->lport * ICE_SR_PFA_LINK_OVERRIDE_WORDS +
4156+
ICE_SR_PFA_LINK_OVERRIDE_OFFSET;
4157+
4158+
/* link options first */
4159+
status = ice_read_sr_word(hw, tlv_start, &buf);
4160+
if (status) {
4161+
ice_debug(hw, ICE_DBG_INIT,
4162+
"Failed to read override link options.\n");
4163+
return status;
4164+
}
4165+
ldo->options = buf & ICE_LINK_OVERRIDE_OPT_M;
4166+
ldo->phy_config = (buf & ICE_LINK_OVERRIDE_PHY_CFG_M) >>
4167+
ICE_LINK_OVERRIDE_PHY_CFG_S;
4168+
4169+
/* link PHY config */
4170+
offset = tlv_start + ICE_SR_PFA_LINK_OVERRIDE_FEC_OFFSET;
4171+
status = ice_read_sr_word(hw, offset, &buf);
4172+
if (status) {
4173+
ice_debug(hw, ICE_DBG_INIT,
4174+
"Failed to read override phy config.\n");
4175+
return status;
4176+
}
4177+
ldo->fec_options = buf & ICE_LINK_OVERRIDE_FEC_OPT_M;
4178+
4179+
/* PHY types low */
4180+
offset = tlv_start + ICE_SR_PFA_LINK_OVERRIDE_PHY_OFFSET;
4181+
for (i = 0; i < ICE_SR_PFA_LINK_OVERRIDE_PHY_WORDS; i++) {
4182+
status = ice_read_sr_word(hw, (offset + i), &buf);
4183+
if (status) {
4184+
ice_debug(hw, ICE_DBG_INIT,
4185+
"Failed to read override link options.\n");
4186+
return status;
4187+
}
4188+
/* shift 16 bits at a time to fill 64 bits */
4189+
ldo->phy_type_low |= ((u64)buf << (i * 16));
4190+
}
4191+
4192+
/* PHY types high */
4193+
offset = tlv_start + ICE_SR_PFA_LINK_OVERRIDE_PHY_OFFSET +
4194+
ICE_SR_PFA_LINK_OVERRIDE_PHY_WORDS;
4195+
for (i = 0; i < ICE_SR_PFA_LINK_OVERRIDE_PHY_WORDS; i++) {
4196+
status = ice_read_sr_word(hw, (offset + i), &buf);
4197+
if (status) {
4198+
ice_debug(hw, ICE_DBG_INIT,
4199+
"Failed to read override link options.\n");
4200+
return status;
4201+
}
4202+
/* shift 16 bits at a time to fill 64 bits */
4203+
ldo->phy_type_high |= ((u64)buf << (i * 16));
4204+
}
4205+
4206+
return status;
4207+
}

drivers/net/ethernet/intel/ice/ice_common.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ enum ice_status ice_clear_pf_cfg(struct ice_hw *hw);
100100
enum ice_status
101101
ice_aq_set_phy_cfg(struct ice_hw *hw, struct ice_port_info *pi,
102102
struct ice_aqc_set_phy_cfg_data *cfg, struct ice_sq_cd *cd);
103+
bool ice_fw_supports_link_override(struct ice_hw *hw);
104+
enum ice_status
105+
ice_get_link_default_override(struct ice_link_default_override_tlv *ldo,
106+
struct ice_port_info *pi);
107+
103108
enum ice_fc_mode ice_caps_to_fc_mode(u8 caps);
104109
enum ice_fec_mode ice_caps_to_fec_mode(u8 caps, u8 fec_options);
105110
enum ice_status
@@ -112,7 +117,8 @@ bool
112117
ice_phy_caps_equals_cfg(struct ice_aqc_get_phy_caps_data *caps,
113118
struct ice_aqc_set_phy_cfg_data *cfg);
114119
void
115-
ice_copy_phy_caps_to_cfg(struct ice_aqc_get_phy_caps_data *caps,
120+
ice_copy_phy_caps_to_cfg(struct ice_port_info *pi,
121+
struct ice_aqc_get_phy_caps_data *caps,
116122
struct ice_aqc_set_phy_cfg_data *cfg);
117123
enum ice_status
118124
ice_cfg_phy_fec(struct ice_port_info *pi, struct ice_aqc_set_phy_cfg_data *cfg,

0 commit comments

Comments
 (0)