Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/ice/ice_common.c
Show First 20 Lines • Show All 183 Lines • ▼ Show 20 Lines | ice_aq_get_phy_caps(struct ice_port_info *pi, bool qual_mods, u8 report_mode, | ||||
struct ice_hw *hw; | struct ice_hw *hw; | ||||
cmd = &desc.params.get_phy; | cmd = &desc.params.get_phy; | ||||
if (!pcaps || (report_mode & ~ICE_AQC_REPORT_MODE_M) || !pi) | if (!pcaps || (report_mode & ~ICE_AQC_REPORT_MODE_M) || !pi) | ||||
return ICE_ERR_PARAM; | return ICE_ERR_PARAM; | ||||
hw = pi->hw; | hw = pi->hw; | ||||
if (report_mode == ICE_AQC_REPORT_DFLT_CFG && | |||||
!ice_fw_supports_report_dflt_cfg(hw)) | |||||
return ICE_ERR_PARAM; | |||||
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_phy_caps); | ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_phy_caps); | ||||
if (qual_mods) | if (qual_mods) | ||||
cmd->param0 |= CPU_TO_LE16(ICE_AQC_GET_PHY_RQM); | cmd->param0 |= CPU_TO_LE16(ICE_AQC_GET_PHY_RQM); | ||||
cmd->param0 |= CPU_TO_LE16(report_mode); | cmd->param0 |= CPU_TO_LE16(report_mode); | ||||
status = ice_aq_send_cmd(hw, &desc, pcaps, pcaps_size, cd); | status = ice_aq_send_cmd(hw, &desc, pcaps, pcaps_size, cd); | ||||
Show All 17 Lines | ice_debug(hw, ICE_DBG_LINK, " extended_compliance_code = 0x%x\n", | ||||
pcaps->extended_compliance_code); | pcaps->extended_compliance_code); | ||||
ice_debug(hw, ICE_DBG_LINK, " module_type[0] = 0x%x\n", | ice_debug(hw, ICE_DBG_LINK, " module_type[0] = 0x%x\n", | ||||
pcaps->module_type[0]); | pcaps->module_type[0]); | ||||
ice_debug(hw, ICE_DBG_LINK, " module_type[1] = 0x%x\n", | ice_debug(hw, ICE_DBG_LINK, " module_type[1] = 0x%x\n", | ||||
pcaps->module_type[1]); | pcaps->module_type[1]); | ||||
ice_debug(hw, ICE_DBG_LINK, " module_type[2] = 0x%x\n", | ice_debug(hw, ICE_DBG_LINK, " module_type[2] = 0x%x\n", | ||||
pcaps->module_type[2]); | pcaps->module_type[2]); | ||||
if (status == ICE_SUCCESS && report_mode == ICE_AQC_REPORT_TOPO_CAP) { | if (status == ICE_SUCCESS && report_mode == ICE_AQC_REPORT_TOPO_CAP_MEDIA) { | ||||
pi->phy.phy_type_low = LE64_TO_CPU(pcaps->phy_type_low); | pi->phy.phy_type_low = LE64_TO_CPU(pcaps->phy_type_low); | ||||
pi->phy.phy_type_high = LE64_TO_CPU(pcaps->phy_type_high); | pi->phy.phy_type_high = LE64_TO_CPU(pcaps->phy_type_high); | ||||
ice_memcpy(pi->phy.link_info.module_type, &pcaps->module_type, | ice_memcpy(pi->phy.link_info.module_type, &pcaps->module_type, | ||||
sizeof(pi->phy.link_info.module_type), | sizeof(pi->phy.link_info.module_type), | ||||
ICE_NONDMA_TO_NONDMA); | ICE_NONDMA_TO_NONDMA); | ||||
} | } | ||||
return status; | return status; | ||||
▲ Show 20 Lines • Show All 215 Lines • ▼ Show 20 Lines | ice_aq_get_link_info(struct ice_port_info *pi, bool ena_lse, | ||||
*li_old = *li; | *li_old = *li; | ||||
/* update current link status information */ | /* update current link status information */ | ||||
li->link_speed = LE16_TO_CPU(link_data.link_speed); | li->link_speed = LE16_TO_CPU(link_data.link_speed); | ||||
li->phy_type_low = LE64_TO_CPU(link_data.phy_type_low); | li->phy_type_low = LE64_TO_CPU(link_data.phy_type_low); | ||||
li->phy_type_high = LE64_TO_CPU(link_data.phy_type_high); | li->phy_type_high = LE64_TO_CPU(link_data.phy_type_high); | ||||
*hw_media_type = ice_get_media_type(pi); | *hw_media_type = ice_get_media_type(pi); | ||||
li->link_info = link_data.link_info; | li->link_info = link_data.link_info; | ||||
li->link_cfg_err = link_data.link_cfg_err; | |||||
li->an_info = link_data.an_info; | li->an_info = link_data.an_info; | ||||
li->ext_info = link_data.ext_info; | li->ext_info = link_data.ext_info; | ||||
li->max_frame_size = LE16_TO_CPU(link_data.max_frame_size); | li->max_frame_size = LE16_TO_CPU(link_data.max_frame_size); | ||||
li->fec_info = link_data.cfg & ICE_AQ_FEC_MASK; | li->fec_info = link_data.cfg & ICE_AQ_FEC_MASK; | ||||
li->topo_media_conflict = link_data.topo_media_conflict; | li->topo_media_conflict = link_data.topo_media_conflict; | ||||
li->pacing = link_data.cfg & (ICE_AQ_CFG_PACING_M | | li->pacing = link_data.cfg & (ICE_AQ_CFG_PACING_M | | ||||
ICE_AQ_CFG_PACING_TYPE_M); | ICE_AQ_CFG_PACING_TYPE_M); | ||||
▲ Show 20 Lines • Show All 333 Lines • ▼ Show 20 Lines | pcaps = (struct ice_aqc_get_phy_caps_data *) | ||||
ice_malloc(hw, sizeof(*pcaps)); | ice_malloc(hw, sizeof(*pcaps)); | ||||
if (!pcaps) { | if (!pcaps) { | ||||
status = ICE_ERR_NO_MEMORY; | status = ICE_ERR_NO_MEMORY; | ||||
goto err_unroll_sched; | goto err_unroll_sched; | ||||
} | } | ||||
/* Initialize port_info struct with PHY capabilities */ | /* Initialize port_info struct with PHY capabilities */ | ||||
status = ice_aq_get_phy_caps(hw->port_info, false, | status = ice_aq_get_phy_caps(hw->port_info, false, | ||||
ICE_AQC_REPORT_TOPO_CAP, pcaps, NULL); | ICE_AQC_REPORT_TOPO_CAP_MEDIA, pcaps, NULL); | ||||
ice_free(hw, pcaps); | ice_free(hw, pcaps); | ||||
if (status) | if (status) | ||||
ice_debug(hw, ICE_DBG_PHY, "Get PHY capabilities failed, continuing anyway\n"); | ice_warn(hw, "Get PHY capabilities failed status = %d, continuing anyway\n", | ||||
status); | |||||
/* Initialize port_info struct with link information */ | /* Initialize port_info struct with link information */ | ||||
status = ice_aq_get_link_info(hw->port_info, false, NULL, NULL); | status = ice_aq_get_link_info(hw->port_info, false, NULL, NULL); | ||||
if (status) | if (status) | ||||
goto err_unroll_sched; | goto err_unroll_sched; | ||||
/* need a valid SW entry point to build a Tx tree */ | /* need a valid SW entry point to build a Tx tree */ | ||||
if (!hw->sw_entry_point_layer) { | if (!hw->sw_entry_point_layer) { | ||||
ice_debug(hw, ICE_DBG_SCHED, "invalid sw entry point\n"); | ice_debug(hw, ICE_DBG_SCHED, "invalid sw entry point\n"); | ||||
Show All 28 Lines | enum ice_status ice_init_hw(struct ice_hw *hw) | ||||
status = ice_aq_set_mac_cfg(hw, ICE_AQ_SET_MAC_FRAME_SIZE_MAX, NULL); | status = ice_aq_set_mac_cfg(hw, ICE_AQ_SET_MAC_FRAME_SIZE_MAX, NULL); | ||||
if (status) | if (status) | ||||
goto err_unroll_fltr_mgmt_struct; | goto err_unroll_fltr_mgmt_struct; | ||||
status = ice_init_hw_tbls(hw); | status = ice_init_hw_tbls(hw); | ||||
if (status) | if (status) | ||||
goto err_unroll_fltr_mgmt_struct; | goto err_unroll_fltr_mgmt_struct; | ||||
ice_init_lock(&hw->tnl_lock); | ice_init_lock(&hw->tnl_lock); | ||||
ice_init_vlan_mode_ops(hw); | |||||
return ICE_SUCCESS; | return ICE_SUCCESS; | ||||
err_unroll_fltr_mgmt_struct: | err_unroll_fltr_mgmt_struct: | ||||
ice_cleanup_fltr_mgmt_struct(hw); | ice_cleanup_fltr_mgmt_struct(hw); | ||||
err_unroll_sched: | err_unroll_sched: | ||||
ice_sched_cleanup_all(hw); | ice_sched_cleanup_all(hw); | ||||
err_unroll_alloc: | err_unroll_alloc: | ||||
ice_free(hw, hw->port_info); | ice_free(hw, hw->port_info); | ||||
▲ Show 20 Lines • Show All 495 Lines • ▼ Show 20 Lines | for (i = 0; i < ICE_TX_DRBELL_Q_CTX_SIZE_DWORDS; i++) | ||||
wr32(hw, QTX_COMM_DBLQ_CNTX(i, tx_drbell_q_index), 0); | wr32(hw, QTX_COMM_DBLQ_CNTX(i, tx_drbell_q_index), 0); | ||||
return ICE_SUCCESS; | return ICE_SUCCESS; | ||||
} | } | ||||
/* FW Admin Queue command wrappers */ | /* FW Admin Queue command wrappers */ | ||||
/** | /** | ||||
* ice_should_retry_sq_send_cmd | |||||
* @opcode: AQ opcode | |||||
* | |||||
* Decide if we should retry the send command routine for the ATQ, depending | |||||
* on the opcode. | |||||
*/ | |||||
static bool ice_should_retry_sq_send_cmd(u16 opcode) | |||||
{ | |||||
switch (opcode) { | |||||
case ice_aqc_opc_dnl_get_status: | |||||
case ice_aqc_opc_dnl_run: | |||||
case ice_aqc_opc_dnl_call: | |||||
case ice_aqc_opc_dnl_read_sto: | |||||
case ice_aqc_opc_dnl_write_sto: | |||||
case ice_aqc_opc_dnl_set_breakpoints: | |||||
case ice_aqc_opc_dnl_read_log: | |||||
case ice_aqc_opc_get_link_topo: | |||||
case ice_aqc_opc_done_alt_write: | |||||
case ice_aqc_opc_lldp_stop: | |||||
case ice_aqc_opc_lldp_start: | |||||
case ice_aqc_opc_lldp_filter_ctrl: | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
/** | |||||
* ice_sq_send_cmd_retry - send command to Control Queue (ATQ) | |||||
* @hw: pointer to the HW struct | |||||
* @cq: pointer to the specific Control queue | |||||
* @desc: prefilled descriptor describing the command | |||||
* @buf: buffer to use for indirect commands (or NULL for direct commands) | |||||
* @buf_size: size of buffer for indirect commands (or 0 for direct commands) | |||||
* @cd: pointer to command details structure | |||||
* | |||||
* Retry sending the FW Admin Queue command, multiple times, to the FW Admin | |||||
* Queue if the EBUSY AQ error is returned. | |||||
*/ | |||||
static enum ice_status | |||||
ice_sq_send_cmd_retry(struct ice_hw *hw, struct ice_ctl_q_info *cq, | |||||
struct ice_aq_desc *desc, void *buf, u16 buf_size, | |||||
struct ice_sq_cd *cd) | |||||
{ | |||||
struct ice_aq_desc desc_cpy; | |||||
enum ice_status status; | |||||
bool is_cmd_for_retry; | |||||
u8 *buf_cpy = NULL; | |||||
u8 idx = 0; | |||||
u16 opcode; | |||||
opcode = LE16_TO_CPU(desc->opcode); | |||||
is_cmd_for_retry = ice_should_retry_sq_send_cmd(opcode); | |||||
ice_memset(&desc_cpy, 0, sizeof(desc_cpy), ICE_NONDMA_MEM); | |||||
if (is_cmd_for_retry) { | |||||
if (buf) { | |||||
buf_cpy = (u8 *)ice_malloc(hw, buf_size); | |||||
if (!buf_cpy) | |||||
return ICE_ERR_NO_MEMORY; | |||||
} | |||||
ice_memcpy(&desc_cpy, desc, sizeof(desc_cpy), | |||||
ICE_NONDMA_TO_NONDMA); | |||||
} | |||||
do { | |||||
status = ice_sq_send_cmd(hw, cq, desc, buf, buf_size, cd); | |||||
if (!is_cmd_for_retry || status == ICE_SUCCESS || | |||||
hw->adminq.sq_last_status != ICE_AQ_RC_EBUSY) | |||||
break; | |||||
if (buf_cpy) | |||||
ice_memcpy(buf, buf_cpy, buf_size, | |||||
ICE_NONDMA_TO_NONDMA); | |||||
ice_memcpy(desc, &desc_cpy, sizeof(desc_cpy), | |||||
ICE_NONDMA_TO_NONDMA); | |||||
ice_msec_delay(ICE_SQ_SEND_DELAY_TIME_MS, false); | |||||
} while (++idx < ICE_SQ_SEND_MAX_EXECUTE); | |||||
if (buf_cpy) | |||||
ice_free(hw, buf_cpy); | |||||
return status; | |||||
} | |||||
/** | |||||
* ice_aq_send_cmd - send FW Admin Queue command to FW Admin Queue | * ice_aq_send_cmd - send FW Admin Queue command to FW Admin Queue | ||||
* @hw: pointer to the HW struct | * @hw: pointer to the HW struct | ||||
* @desc: descriptor describing the command | * @desc: descriptor describing the command | ||||
* @buf: buffer to use for indirect commands (NULL for direct commands) | * @buf: buffer to use for indirect commands (NULL for direct commands) | ||||
* @buf_size: size of buffer for indirect commands (0 for direct commands) | * @buf_size: size of buffer for indirect commands (0 for direct commands) | ||||
* @cd: pointer to command details structure | * @cd: pointer to command details structure | ||||
* | * | ||||
* Helper function to send FW Admin Queue commands to the FW Admin Queue. | * Helper function to send FW Admin Queue commands to the FW Admin Queue. | ||||
*/ | */ | ||||
enum ice_status | enum ice_status | ||||
ice_aq_send_cmd(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf, | ice_aq_send_cmd(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf, | ||||
u16 buf_size, struct ice_sq_cd *cd) | u16 buf_size, struct ice_sq_cd *cd) | ||||
{ | { | ||||
return ice_sq_send_cmd(hw, &hw->adminq, desc, buf, buf_size, cd); | return ice_sq_send_cmd_retry(hw, &hw->adminq, desc, buf, buf_size, cd); | ||||
} | } | ||||
/** | /** | ||||
* ice_aq_get_fw_ver | * ice_aq_get_fw_ver | ||||
* @hw: pointer to the HW struct | * @hw: pointer to the HW struct | ||||
* @cd: pointer to command details structure or NULL | * @cd: pointer to command details structure or NULL | ||||
* | * | ||||
* Get the firmware version (0x0001) from the admin queue commands | * Get the firmware version (0x0001) from the admin queue commands | ||||
▲ Show 20 Lines • Show All 423 Lines • ▼ Show 20 Lines | #define ICE_CAPS_VALID_FUNCS_M 0xFF | ||||
return max / funcs; | return max / funcs; | ||||
} | } | ||||
/** | /** | ||||
* ice_print_led_caps - print LED capabilities | * ice_print_led_caps - print LED capabilities | ||||
* @hw: pointer to the ice_hw instance | * @hw: pointer to the ice_hw instance | ||||
* @caps: pointer to common caps instance | * @caps: pointer to common caps instance | ||||
* @prefix: string to prefix when printing | * @prefix: string to prefix when printing | ||||
* @debug: set to indicate debug print | * @dbg: set to indicate debug print | ||||
*/ | */ | ||||
static void | static void | ||||
ice_print_led_caps(struct ice_hw *hw, struct ice_hw_common_caps *caps, | ice_print_led_caps(struct ice_hw *hw, struct ice_hw_common_caps *caps, | ||||
char const *prefix, bool debug) | char const *prefix, bool dbg) | ||||
{ | { | ||||
u8 i; | u8 i; | ||||
if (debug) | if (dbg) | ||||
ice_debug(hw, ICE_DBG_INIT, "%s: led_pin_num = %d\n", prefix, | ice_debug(hw, ICE_DBG_INIT, "%s: led_pin_num = %d\n", prefix, | ||||
caps->led_pin_num); | caps->led_pin_num); | ||||
else | else | ||||
ice_info(hw, "%s: led_pin_num = %d\n", prefix, | ice_info(hw, "%s: led_pin_num = %d\n", prefix, | ||||
caps->led_pin_num); | caps->led_pin_num); | ||||
for (i = 0; i < ICE_MAX_SUPPORTED_GPIO_LED; i++) { | for (i = 0; i < ICE_MAX_SUPPORTED_GPIO_LED; i++) { | ||||
if (!caps->led[i]) | if (!caps->led[i]) | ||||
continue; | continue; | ||||
if (debug) | if (dbg) | ||||
ice_debug(hw, ICE_DBG_INIT, "%s: led[%d] = %d\n", | ice_debug(hw, ICE_DBG_INIT, "%s: led[%d] = %d\n", | ||||
prefix, i, caps->led[i]); | prefix, i, caps->led[i]); | ||||
else | else | ||||
ice_info(hw, "%s: led[%d] = %d\n", prefix, i, | ice_info(hw, "%s: led[%d] = %d\n", prefix, i, | ||||
caps->led[i]); | caps->led[i]); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* ice_print_sdp_caps - print SDP capabilities | * ice_print_sdp_caps - print SDP capabilities | ||||
* @hw: pointer to the ice_hw instance | * @hw: pointer to the ice_hw instance | ||||
* @caps: pointer to common caps instance | * @caps: pointer to common caps instance | ||||
* @prefix: string to prefix when printing | * @prefix: string to prefix when printing | ||||
* @debug: set to indicate debug print | * @dbg: set to indicate debug print | ||||
*/ | */ | ||||
static void | static void | ||||
ice_print_sdp_caps(struct ice_hw *hw, struct ice_hw_common_caps *caps, | ice_print_sdp_caps(struct ice_hw *hw, struct ice_hw_common_caps *caps, | ||||
char const *prefix, bool debug) | char const *prefix, bool dbg) | ||||
{ | { | ||||
u8 i; | u8 i; | ||||
if (debug) | if (dbg) | ||||
ice_debug(hw, ICE_DBG_INIT, "%s: sdp_pin_num = %d\n", prefix, | ice_debug(hw, ICE_DBG_INIT, "%s: sdp_pin_num = %d\n", prefix, | ||||
caps->sdp_pin_num); | caps->sdp_pin_num); | ||||
else | else | ||||
ice_info(hw, "%s: sdp_pin_num = %d\n", prefix, | ice_info(hw, "%s: sdp_pin_num = %d\n", prefix, | ||||
caps->sdp_pin_num); | caps->sdp_pin_num); | ||||
for (i = 0; i < ICE_MAX_SUPPORTED_GPIO_SDP; i++) { | for (i = 0; i < ICE_MAX_SUPPORTED_GPIO_SDP; i++) { | ||||
if (!caps->sdp[i]) | if (!caps->sdp[i]) | ||||
continue; | continue; | ||||
if (debug) | if (dbg) | ||||
ice_debug(hw, ICE_DBG_INIT, "%s: sdp[%d] = %d\n", | ice_debug(hw, ICE_DBG_INIT, "%s: sdp[%d] = %d\n", | ||||
prefix, i, caps->sdp[i]); | prefix, i, caps->sdp[i]); | ||||
else | else | ||||
ice_info(hw, "%s: sdp[%d] = %d\n", prefix, | ice_info(hw, "%s: sdp[%d] = %d\n", prefix, | ||||
i, caps->sdp[i]); | i, caps->sdp[i]); | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 939 Lines • ▼ Show 20 Lines | if (li->link_info & ICE_AQ_MEDIA_AVAILABLE) { | ||||
struct ice_hw *hw; | struct ice_hw *hw; | ||||
hw = pi->hw; | hw = pi->hw; | ||||
pcaps = (struct ice_aqc_get_phy_caps_data *) | pcaps = (struct ice_aqc_get_phy_caps_data *) | ||||
ice_malloc(hw, sizeof(*pcaps)); | ice_malloc(hw, sizeof(*pcaps)); | ||||
if (!pcaps) | if (!pcaps) | ||||
return ICE_ERR_NO_MEMORY; | return ICE_ERR_NO_MEMORY; | ||||
status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_TOPO_CAP, | status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_TOPO_CAP_MEDIA, | ||||
pcaps, NULL); | pcaps, NULL); | ||||
if (status == ICE_SUCCESS) | if (status == ICE_SUCCESS) | ||||
ice_memcpy(li->module_type, &pcaps->module_type, | ice_memcpy(li->module_type, &pcaps->module_type, | ||||
sizeof(li->module_type), | sizeof(li->module_type), | ||||
ICE_NONDMA_TO_NONDMA); | ICE_NONDMA_TO_NONDMA); | ||||
ice_free(hw, pcaps); | ice_free(hw, pcaps); | ||||
▲ Show 20 Lines • Show All 91 Lines • ▼ Show 20 Lines | |||||
ice_cfg_phy_fc(struct ice_port_info *pi, struct ice_aqc_set_phy_cfg_data *cfg, | ice_cfg_phy_fc(struct ice_port_info *pi, struct ice_aqc_set_phy_cfg_data *cfg, | ||||
enum ice_fc_mode req_mode) | enum ice_fc_mode req_mode) | ||||
{ | { | ||||
struct ice_phy_cache_mode_data cache_data; | struct ice_phy_cache_mode_data cache_data; | ||||
u8 pause_mask = 0x0; | u8 pause_mask = 0x0; | ||||
if (!pi || !cfg) | if (!pi || !cfg) | ||||
return ICE_ERR_BAD_PTR; | return ICE_ERR_BAD_PTR; | ||||
switch (req_mode) { | switch (req_mode) { | ||||
case ICE_FC_AUTO: | case ICE_FC_AUTO: | ||||
{ | { | ||||
struct ice_aqc_get_phy_caps_data *pcaps; | struct ice_aqc_get_phy_caps_data *pcaps; | ||||
enum ice_status status; | enum ice_status status; | ||||
pcaps = (struct ice_aqc_get_phy_caps_data *) | pcaps = (struct ice_aqc_get_phy_caps_data *) | ||||
ice_malloc(pi->hw, sizeof(*pcaps)); | ice_malloc(pi->hw, sizeof(*pcaps)); | ||||
if (!pcaps) | if (!pcaps) | ||||
return ICE_ERR_NO_MEMORY; | return ICE_ERR_NO_MEMORY; | ||||
/* Query the value of FC that both the NIC and attached media | /* Query the value of FC that both the NIC and attached media | ||||
* can do. | * can do. | ||||
*/ | */ | ||||
status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_TOPO_CAP, | status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_TOPO_CAP_MEDIA, | ||||
pcaps, NULL); | pcaps, NULL); | ||||
if (status) { | if (status) { | ||||
ice_free(pi->hw, pcaps); | ice_free(pi->hw, pcaps); | ||||
return status; | return status; | ||||
} | } | ||||
pause_mask |= pcaps->caps & ICE_AQC_PHY_EN_TX_LINK_PAUSE; | pause_mask |= pcaps->caps & ICE_AQC_PHY_EN_TX_LINK_PAUSE; | ||||
pause_mask |= pcaps->caps & ICE_AQC_PHY_EN_RX_LINK_PAUSE; | pause_mask |= pcaps->caps & ICE_AQC_PHY_EN_RX_LINK_PAUSE; | ||||
▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool ena_auto_link_update) | ||||
hw = pi->hw; | hw = pi->hw; | ||||
pcaps = (struct ice_aqc_get_phy_caps_data *) | pcaps = (struct ice_aqc_get_phy_caps_data *) | ||||
ice_malloc(hw, sizeof(*pcaps)); | ice_malloc(hw, sizeof(*pcaps)); | ||||
if (!pcaps) | if (!pcaps) | ||||
return ICE_ERR_NO_MEMORY; | return ICE_ERR_NO_MEMORY; | ||||
/* Get the current PHY config */ | /* Get the current PHY config */ | ||||
status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_SW_CFG, pcaps, | status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_ACTIVE_CFG, | ||||
NULL); | pcaps, NULL); | ||||
if (status) { | if (status) { | ||||
*aq_failures = ICE_SET_FC_AQ_FAIL_GET; | *aq_failures = ICE_SET_FC_AQ_FAIL_GET; | ||||
goto out; | goto out; | ||||
} | } | ||||
ice_copy_phy_caps_to_cfg(pi, pcaps, &cfg); | ice_copy_phy_caps_to_cfg(pi, pcaps, &cfg); | ||||
/* Configure the set PHY data */ | /* Configure the set PHY data */ | ||||
▲ Show 20 Lines • Show All 100 Lines • ▼ Show 20 Lines | ice_copy_phy_caps_to_cfg(struct ice_port_info *pi, | ||||
cfg->phy_type_high = caps->phy_type_high; | cfg->phy_type_high = caps->phy_type_high; | ||||
cfg->caps = caps->caps; | cfg->caps = caps->caps; | ||||
cfg->low_power_ctrl_an = caps->low_power_ctrl_an; | cfg->low_power_ctrl_an = caps->low_power_ctrl_an; | ||||
cfg->eee_cap = caps->eee_cap; | cfg->eee_cap = caps->eee_cap; | ||||
cfg->eeer_value = caps->eeer_value; | cfg->eeer_value = caps->eeer_value; | ||||
cfg->link_fec_opt = caps->link_fec_options; | cfg->link_fec_opt = caps->link_fec_options; | ||||
cfg->module_compliance_enforcement = | cfg->module_compliance_enforcement = | ||||
caps->module_compliance_enforcement; | caps->module_compliance_enforcement; | ||||
if (ice_fw_supports_link_override(pi->hw)) { | |||||
struct ice_link_default_override_tlv tlv; | |||||
if (ice_get_link_default_override(&tlv, pi)) | |||||
return; | |||||
if (tlv.options & ICE_LINK_OVERRIDE_STRICT_MODE) | |||||
cfg->module_compliance_enforcement |= | |||||
ICE_LINK_OVERRIDE_STRICT_MODE; | |||||
} | } | ||||
} | |||||
/** | /** | ||||
* ice_cfg_phy_fec - Configure PHY FEC data based on FEC mode | * ice_cfg_phy_fec - Configure PHY FEC data based on FEC mode | ||||
* @pi: port information structure | * @pi: port information structure | ||||
* @cfg: PHY configuration data to set FEC mode | * @cfg: PHY configuration data to set FEC mode | ||||
* @fec: FEC mode to configure | * @fec: FEC mode to configure | ||||
*/ | */ | ||||
enum ice_status | enum ice_status | ||||
Show All 9 Lines | ice_cfg_phy_fec(struct ice_port_info *pi, struct ice_aqc_set_phy_cfg_data *cfg, | ||||
hw = pi->hw; | hw = pi->hw; | ||||
pcaps = (struct ice_aqc_get_phy_caps_data *) | pcaps = (struct ice_aqc_get_phy_caps_data *) | ||||
ice_malloc(hw, sizeof(*pcaps)); | ice_malloc(hw, sizeof(*pcaps)); | ||||
if (!pcaps) | if (!pcaps) | ||||
return ICE_ERR_NO_MEMORY; | return ICE_ERR_NO_MEMORY; | ||||
status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_TOPO_CAP, pcaps, | status = ice_aq_get_phy_caps(pi, false, | ||||
NULL); | (ice_fw_supports_report_dflt_cfg(hw) ? | ||||
ICE_AQC_REPORT_DFLT_CFG : | |||||
ICE_AQC_REPORT_TOPO_CAP_MEDIA), pcaps, NULL); | |||||
if (status) | if (status) | ||||
goto out; | goto out; | ||||
cfg->caps |= (pcaps->caps & ICE_AQC_PHY_EN_AUTO_FEC); | cfg->caps |= (pcaps->caps & ICE_AQC_PHY_EN_AUTO_FEC); | ||||
cfg->link_fec_opt = pcaps->link_fec_options; | cfg->link_fec_opt = pcaps->link_fec_options; | ||||
switch (fec) { | switch (fec) { | ||||
case ICE_FEC_BASER: | case ICE_FEC_BASER: | ||||
Show All 22 Lines | case ICE_FEC_AUTO: | ||||
cfg->caps &= ICE_AQC_PHY_CAPS_MASK; | cfg->caps &= ICE_AQC_PHY_CAPS_MASK; | ||||
cfg->link_fec_opt |= pcaps->link_fec_options; | cfg->link_fec_opt |= pcaps->link_fec_options; | ||||
break; | break; | ||||
default: | default: | ||||
status = ICE_ERR_PARAM; | status = ICE_ERR_PARAM; | ||||
break; | break; | ||||
} | } | ||||
if (fec == ICE_FEC_AUTO && ice_fw_supports_link_override(pi->hw)) { | if (fec == ICE_FEC_AUTO && ice_fw_supports_link_override(pi->hw) && | ||||
!ice_fw_supports_report_dflt_cfg(pi->hw)) { | |||||
struct ice_link_default_override_tlv tlv; | struct ice_link_default_override_tlv tlv; | ||||
if (ice_get_link_default_override(&tlv, pi)) | if (ice_get_link_default_override(&tlv, pi)) | ||||
goto out; | goto out; | ||||
if (!(tlv.options & ICE_LINK_OVERRIDE_STRICT_MODE) && | if (!(tlv.options & ICE_LINK_OVERRIDE_STRICT_MODE) && | ||||
(tlv.options & ICE_LINK_OVERRIDE_EN)) | (tlv.options & ICE_LINK_OVERRIDE_EN)) | ||||
cfg->link_fec_opt = tlv.fec_options; | cfg->link_fec_opt = tlv.fec_options; | ||||
▲ Show 20 Lines • Show All 1,939 Lines • ▼ Show 20 Lines | if (caps->caps & ICE_AQC_PHY_AN_MODE || | ||||
ICE_AQC_PHY_AN_EN_CLAUSE73 | | ICE_AQC_PHY_AN_EN_CLAUSE73 | | ||||
ICE_AQC_PHY_AN_EN_CLAUSE37)) | ICE_AQC_PHY_AN_EN_CLAUSE37)) | ||||
return true; | return true; | ||||
return false; | return false; | ||||
} | } | ||||
/** | /** | ||||
* ice_is_fw_health_report_supported | |||||
* @hw: pointer to the hardware structure | |||||
* | |||||
* Return true if firmware supports health status reports, | |||||
* false otherwise | |||||
*/ | |||||
bool ice_is_fw_health_report_supported(struct ice_hw *hw) | |||||
{ | |||||
if (hw->api_maj_ver > ICE_FW_API_HEALTH_REPORT_MAJ) | |||||
return true; | |||||
if (hw->api_maj_ver == ICE_FW_API_HEALTH_REPORT_MAJ) { | |||||
if (hw->api_min_ver > ICE_FW_API_HEALTH_REPORT_MIN) | |||||
return true; | |||||
if (hw->api_min_ver == ICE_FW_API_HEALTH_REPORT_MIN && | |||||
hw->api_patch >= ICE_FW_API_HEALTH_REPORT_PATCH) | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
/** | |||||
* ice_aq_set_health_status_config - Configure FW health events | |||||
* @hw: pointer to the HW struct | |||||
* @event_source: type of diagnostic events to enable | |||||
* @cd: pointer to command details structure or NULL | |||||
* | |||||
* Configure the health status event types that the firmware will send to this | |||||
* PF. The supported event types are: PF-specific, all PFs, and global | |||||
*/ | |||||
enum ice_status | |||||
ice_aq_set_health_status_config(struct ice_hw *hw, u8 event_source, | |||||
struct ice_sq_cd *cd) | |||||
{ | |||||
struct ice_aqc_set_health_status_config *cmd; | |||||
struct ice_aq_desc desc; | |||||
cmd = &desc.params.set_health_status_config; | |||||
ice_fill_dflt_direct_cmd_desc(&desc, | |||||
ice_aqc_opc_set_health_status_config); | |||||
cmd->event_source = event_source; | |||||
return ice_aq_send_cmd(hw, &desc, NULL, 0, cd); | |||||
} | |||||
/** | |||||
* ice_aq_get_port_options | |||||
* @hw: pointer to the hw struct | |||||
* @options: buffer for the resultant port options | |||||
* @option_count: input - size of the buffer in port options structures, | |||||
* output - number of returned port options | |||||
* @lport: logical port to call the command with (optional) | |||||
* @lport_valid: when false, FW uses port owned by the PF instead of lport, | |||||
* when PF owns more than 1 port it must be true | |||||
* @active_option_idx: index of active port option in returned buffer | |||||
* @active_option_valid: active option in returned buffer is valid | |||||
* | |||||
* Calls Get Port Options AQC (0x06ea) and verifies result. | |||||
*/ | |||||
enum ice_status | |||||
ice_aq_get_port_options(struct ice_hw *hw, | |||||
struct ice_aqc_get_port_options_elem *options, | |||||
u8 *option_count, u8 lport, bool lport_valid, | |||||
u8 *active_option_idx, bool *active_option_valid) | |||||
{ | |||||
struct ice_aqc_get_port_options *cmd; | |||||
struct ice_aq_desc desc; | |||||
enum ice_status status; | |||||
u8 pmd_count; | |||||
u8 max_speed; | |||||
u8 i; | |||||
ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); | |||||
/* options buffer shall be able to hold max returned options */ | |||||
if (*option_count < ICE_AQC_PORT_OPT_COUNT_M) | |||||
return ICE_ERR_PARAM; | |||||
cmd = &desc.params.get_port_options; | |||||
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_port_options); | |||||
if (lport_valid) | |||||
cmd->lport_num = lport; | |||||
cmd->lport_num_valid = lport_valid; | |||||
status = ice_aq_send_cmd(hw, &desc, options, | |||||
*option_count * sizeof(*options), NULL); | |||||
if (status != ICE_SUCCESS) | |||||
return status; | |||||
/* verify direct FW response & set output parameters */ | |||||
*option_count = cmd->port_options_count & ICE_AQC_PORT_OPT_COUNT_M; | |||||
ice_debug(hw, ICE_DBG_PHY, "options: %x\n", *option_count); | |||||
*active_option_valid = cmd->port_options & ICE_AQC_PORT_OPT_VALID; | |||||
if (*active_option_valid) { | |||||
*active_option_idx = cmd->port_options & | |||||
ICE_AQC_PORT_OPT_ACTIVE_M; | |||||
if (*active_option_idx > (*option_count - 1)) | |||||
return ICE_ERR_OUT_OF_RANGE; | |||||
ice_debug(hw, ICE_DBG_PHY, "active idx: %x\n", | |||||
*active_option_idx); | |||||
} | |||||
/* verify indirect FW response & mask output options fields */ | |||||
for (i = 0; i < *option_count; i++) { | |||||
options[i].pmd &= ICE_AQC_PORT_OPT_PMD_COUNT_M; | |||||
options[i].max_lane_speed &= ICE_AQC_PORT_OPT_MAX_LANE_M; | |||||
pmd_count = options[i].pmd; | |||||
max_speed = options[i].max_lane_speed; | |||||
ice_debug(hw, ICE_DBG_PHY, "pmds: %x max speed: %x\n", | |||||
pmd_count, max_speed); | |||||
/* check only entries containing valid max pmd speed values, | |||||
* other reserved values may be returned, when logical port | |||||
* used is unrelated to specific option | |||||
*/ | |||||
if (max_speed <= ICE_AQC_PORT_OPT_MAX_LANE_100G) { | |||||
if (pmd_count > ICE_MAX_PORT_PER_PCI_DEV) | |||||
return ICE_ERR_OUT_OF_RANGE; | |||||
if (pmd_count > 2 && | |||||
max_speed > ICE_AQC_PORT_OPT_MAX_LANE_25G) | |||||
return ICE_ERR_CFG; | |||||
if (pmd_count > 7 && | |||||
max_speed > ICE_AQC_PORT_OPT_MAX_LANE_10G) | |||||
return ICE_ERR_CFG; | |||||
} | |||||
} | |||||
return ICE_SUCCESS; | |||||
} | |||||
/** | |||||
* ice_aq_set_lldp_mib - Set the LLDP MIB | * ice_aq_set_lldp_mib - Set the LLDP MIB | ||||
* @hw: pointer to the HW struct | * @hw: pointer to the HW struct | ||||
* @mib_type: Local, Remote or both Local and Remote MIBs | * @mib_type: Local, Remote or both Local and Remote MIBs | ||||
* @buf: pointer to the caller-supplied buffer to store the MIB block | * @buf: pointer to the caller-supplied buffer to store the MIB block | ||||
* @buf_size: size of the buffer (in bytes) | * @buf_size: size of the buffer (in bytes) | ||||
* @cd: pointer to command details structure or NULL | * @cd: pointer to command details structure or NULL | ||||
* | * | ||||
* Set the LLDP MIB. (0x0A08) | * Set the LLDP MIB. (0x0A08) | ||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | ice_lldp_fltr_add_remove(struct ice_hw *hw, u16 vsi_num, bool add) | ||||
if (add) | if (add) | ||||
cmd->cmd_flags = ICE_AQC_LLDP_FILTER_ACTION_ADD; | cmd->cmd_flags = ICE_AQC_LLDP_FILTER_ACTION_ADD; | ||||
else | else | ||||
cmd->cmd_flags = ICE_AQC_LLDP_FILTER_ACTION_DELETE; | cmd->cmd_flags = ICE_AQC_LLDP_FILTER_ACTION_DELETE; | ||||
cmd->vsi_num = CPU_TO_LE16(vsi_num); | cmd->vsi_num = CPU_TO_LE16(vsi_num); | ||||
return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL); | return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL); | ||||
} | |||||
/** | |||||
* ice_fw_supports_report_dflt_cfg | |||||
* @hw: pointer to the hardware structure | |||||
* | |||||
* Checks if the firmware supports report default configuration | |||||
*/ | |||||
bool ice_fw_supports_report_dflt_cfg(struct ice_hw *hw) | |||||
{ | |||||
if (hw->api_maj_ver == ICE_FW_API_REPORT_DFLT_CFG_MAJ) { | |||||
if (hw->api_min_ver > ICE_FW_API_REPORT_DFLT_CFG_MIN) | |||||
return true; | |||||
if (hw->api_min_ver == ICE_FW_API_REPORT_DFLT_CFG_MIN && | |||||
hw->api_patch >= ICE_FW_API_REPORT_DFLT_CFG_PATCH) | |||||
return true; | |||||
} else if (hw->api_maj_ver > ICE_FW_API_REPORT_DFLT_CFG_MAJ) { | |||||
return true; | |||||
} | |||||
return false; | |||||
} | } |