summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/intel/ice/ice_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_common.c')
-rw-r--r--drivers/net/ethernet/intel/ice/ice_common.c126
1 files changed, 49 insertions, 77 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
index 046bc9c65c51..04633103e3e6 100644
--- a/drivers/net/ethernet/intel/ice/ice_common.c
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
@@ -204,42 +204,6 @@ bool ice_is_generic_mac(struct ice_hw *hw)
}
/**
- * ice_is_pf_c827 - check if pf contains c827 phy
- * @hw: pointer to the hw struct
- *
- * Return: true if the device has c827 phy.
- */
-static bool ice_is_pf_c827(struct ice_hw *hw)
-{
- struct ice_aqc_get_link_topo cmd = {};
- u8 node_part_number;
- u16 node_handle;
- int status;
-
- if (hw->mac_type != ICE_MAC_E810)
- return false;
-
- if (hw->device_id != ICE_DEV_ID_E810C_QSFP)
- return true;
-
- cmd.addr.topo_params.node_type_ctx =
- FIELD_PREP(ICE_AQC_LINK_TOPO_NODE_TYPE_M, ICE_AQC_LINK_TOPO_NODE_TYPE_PHY) |
- FIELD_PREP(ICE_AQC_LINK_TOPO_NODE_CTX_M, ICE_AQC_LINK_TOPO_NODE_CTX_PORT);
- cmd.addr.topo_params.index = 0;
-
- status = ice_aq_get_netlist_node(hw, &cmd, &node_part_number,
- &node_handle);
-
- if (status || node_part_number != ICE_AQC_GET_LINK_TOPO_NODE_NR_C827)
- return false;
-
- if (node_handle == E810C_QSFP_C827_0_HANDLE || node_handle == E810C_QSFP_C827_1_HANDLE)
- return true;
-
- return false;
-}
-
-/**
* ice_clear_pf_cfg - Clear PF configuration
* @hw: pointer to the hardware structure
*
@@ -958,30 +922,31 @@ static void ice_get_itr_intrl_gran(struct ice_hw *hw)
}
/**
- * ice_wait_for_fw - wait for full FW readiness
+ * ice_wait_fw_load - wait for PHY firmware loading to complete
* @hw: pointer to the hardware structure
- * @timeout: milliseconds that can elapse before timing out
+ * @timeout: milliseconds that can elapse before timing out, 0 to bypass waiting
*
- * Return: 0 on success, -ETIMEDOUT on timeout.
+ * Return:
+ * * 0 on success
+ * * negative on timeout
*/
-static int ice_wait_for_fw(struct ice_hw *hw, u32 timeout)
+static int ice_wait_fw_load(struct ice_hw *hw, u32 timeout)
{
- int fw_loading;
- u32 elapsed = 0;
+ int fw_loading_reg;
- while (elapsed <= timeout) {
- fw_loading = rd32(hw, GL_MNG_FWSM) & GL_MNG_FWSM_FW_LOADING_M;
+ if (!timeout)
+ return 0;
- /* firmware was not yet loaded, we have to wait more */
- if (fw_loading) {
- elapsed += 100;
- msleep(100);
- continue;
- }
+ fw_loading_reg = rd32(hw, GL_MNG_FWSM) & GL_MNG_FWSM_FW_LOADING_M;
+ /* notify the user only once if PHY FW is still loading */
+ if (fw_loading_reg)
+ dev_info(ice_hw_to_dev(hw), "Link initialization is blocked by PHY FW initialization. Link initialization will continue after PHY FW initialization completes.\n");
+ else
return 0;
- }
- return -ETIMEDOUT;
+ return rd32_poll_timeout(hw, GL_MNG_FWSM, fw_loading_reg,
+ !(fw_loading_reg & GL_MNG_FWSM_FW_LOADING_M),
+ 10000, timeout * 1000);
}
static int __fwlog_send_cmd(void *priv, struct libie_aq_desc *desc, void *buf,
@@ -1086,14 +1051,13 @@ int ice_init_hw(struct ice_hw *hw)
hw->evb_veb = true;
- /* init xarray for identifying scheduling nodes uniquely */
- xa_init_flags(&hw->port_info->sched_node_ids, XA_FLAGS_ALLOC);
+ xa_init_flags(&hw->sched_node_ids, XA_FLAGS_ALLOC);
/* Query the allocated resources for Tx scheduler */
status = ice_sched_query_res_alloc(hw);
if (status) {
ice_debug(hw, ICE_DBG_SCHED, "Failed to get scheduler allocated resources\n");
- goto err_unroll_alloc;
+ goto err_unroll_xarray;
}
ice_sched_get_psm_clk_freq(hw);
@@ -1102,7 +1066,7 @@ int ice_init_hw(struct ice_hw *hw)
if (status)
goto err_unroll_sched;
- pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL);
+ pcaps = kzalloc_obj(*pcaps);
if (!pcaps) {
status = -ENOMEM;
goto err_unroll_sched;
@@ -1138,8 +1102,7 @@ int ice_init_hw(struct ice_hw *hw)
/* Get MAC information */
/* A single port can report up to two (LAN and WoL) addresses */
- mac_buf = kcalloc(2, sizeof(struct ice_aqc_manage_mac_read_resp),
- GFP_KERNEL);
+ mac_buf = kzalloc_objs(struct ice_aqc_manage_mac_read_resp, 2);
if (!mac_buf) {
status = -ENOMEM;
goto err_unroll_fltr_mgmt_struct;
@@ -1162,8 +1125,6 @@ int ice_init_hw(struct ice_hw *hw)
if (status)
goto err_unroll_fltr_mgmt_struct;
- ice_init_dev_hw(hw->back);
-
mutex_init(&hw->tnl_lock);
ice_init_chk_recipe_reuse_support(hw);
@@ -1171,12 +1132,10 @@ int ice_init_hw(struct ice_hw *hw)
* due to necessity of loading FW from an external source.
* This can take even half a minute.
*/
- if (ice_is_pf_c827(hw)) {
- status = ice_wait_for_fw(hw, 30000);
- if (status) {
- dev_err(ice_hw_to_dev(hw), "ice_wait_for_fw timed out");
- goto err_unroll_fltr_mgmt_struct;
- }
+ status = ice_wait_fw_load(hw, 30000);
+ if (status) {
+ dev_err(ice_hw_to_dev(hw), "ice_wait_fw_load timed out");
+ goto err_unroll_fltr_mgmt_struct;
}
hw->lane_num = ice_get_phy_lane_number(hw);
@@ -1186,6 +1145,8 @@ err_unroll_fltr_mgmt_struct:
ice_cleanup_fltr_mgmt_struct(hw);
err_unroll_sched:
ice_sched_cleanup_all(hw);
+err_unroll_xarray:
+ xa_destroy(&hw->sched_node_ids);
err_unroll_alloc:
devm_kfree(ice_hw_to_dev(hw), hw->port_info);
err_unroll_cqinit:
@@ -1226,6 +1187,8 @@ void ice_deinit_hw(struct ice_hw *hw)
/* Clear VSI contexts if not already cleared */
ice_clear_all_vsi_ctx(hw);
+
+ xa_destroy(&hw->sched_node_ids);
}
/**
@@ -1854,6 +1817,7 @@ static bool ice_should_retry_sq_send_cmd(u16 opcode)
case ice_aqc_opc_lldp_stop:
case ice_aqc_opc_lldp_start:
case ice_aqc_opc_lldp_filter_ctrl:
+ case ice_aqc_opc_sff_eeprom:
return true;
}
@@ -1879,6 +1843,7 @@ ice_sq_send_cmd_retry(struct ice_hw *hw, struct ice_ctl_q_info *cq,
{
struct libie_aq_desc desc_cpy;
bool is_cmd_for_retry;
+ u8 *buf_cpy = NULL;
u8 idx = 0;
u16 opcode;
int status;
@@ -1888,8 +1853,11 @@ ice_sq_send_cmd_retry(struct ice_hw *hw, struct ice_ctl_q_info *cq,
memset(&desc_cpy, 0, sizeof(desc_cpy));
if (is_cmd_for_retry) {
- /* All retryable cmds are direct, without buf. */
- WARN_ON(buf);
+ if (buf) {
+ buf_cpy = kmemdup(buf, buf_size, GFP_KERNEL);
+ if (!buf_cpy)
+ return -ENOMEM;
+ }
memcpy(&desc_cpy, desc, sizeof(desc_cpy));
}
@@ -1901,12 +1869,14 @@ ice_sq_send_cmd_retry(struct ice_hw *hw, struct ice_ctl_q_info *cq,
hw->adminq.sq_last_status != LIBIE_AQ_RC_EBUSY)
break;
+ if (buf_cpy)
+ memcpy(buf, buf_cpy, buf_size);
memcpy(desc, &desc_cpy, sizeof(desc_cpy));
-
msleep(ICE_SQ_SEND_DELAY_TIME_MS);
} while (++idx < ICE_SQ_SEND_MAX_EXECUTE);
+ kfree(buf_cpy);
return status;
}
@@ -2251,7 +2221,7 @@ void ice_release_res(struct ice_hw *hw, enum ice_aq_res_ids res)
/* there are some rare cases when trying to release the resource
* results in an admin queue timeout, so handle them correctly
*/
- timeout = jiffies + 10 * ICE_CTL_Q_SQ_CMD_TIMEOUT;
+ timeout = jiffies + 10 * usecs_to_jiffies(ICE_CTL_Q_SQ_CMD_TIMEOUT);
do {
status = ice_aq_release_res(hw, res, 0, NULL);
if (status != -EIO)
@@ -3667,7 +3637,7 @@ int ice_update_link_info(struct ice_port_info *pi)
if (li->link_info & ICE_AQ_MEDIA_AVAILABLE) {
struct ice_aqc_get_phy_caps_data *pcaps __free(kfree) = NULL;
- pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL);
+ pcaps = kzalloc_obj(*pcaps);
if (!pcaps)
return -ENOMEM;
@@ -3915,10 +3885,9 @@ ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool ena_auto_link_update)
if (!pi || !aq_failures)
return -EINVAL;
- *aq_failures = 0;
hw = pi->hw;
- pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL);
+ pcaps = kzalloc_obj(*pcaps);
if (!pcaps)
return -ENOMEM;
@@ -4057,7 +4026,7 @@ ice_cfg_phy_fec(struct ice_port_info *pi, struct ice_aqc_set_phy_cfg_data *cfg,
hw = pi->hw;
- pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL);
+ pcaps = kzalloc_obj(*pcaps);
if (!pcaps)
return -ENOMEM;
@@ -4157,12 +4126,13 @@ int ice_get_link_status(struct ice_port_info *pi, bool *link_up)
* @pi: pointer to the port information structure
* @ena_link: if true: enable link, if false: disable link
* @cd: pointer to command details structure or NULL
+ * @refclk: the new TX reference clock, 0 if no change
*
* Sets up the link and restarts the Auto-Negotiation over the link.
*/
int
ice_aq_set_link_restart_an(struct ice_port_info *pi, bool ena_link,
- struct ice_sq_cd *cd)
+ struct ice_sq_cd *cd, u8 refclk)
{
struct ice_aqc_restart_an *cmd;
struct libie_aq_desc desc;
@@ -4178,6 +4148,8 @@ ice_aq_set_link_restart_an(struct ice_port_info *pi, bool ena_link,
else
cmd->cmd_flags &= ~ICE_AQC_RESTART_AN_LINK_ENABLE;
+ cmd->cmd_flags |= FIELD_PREP(ICE_AQC_RESTART_AN_REFCLK_M, refclk);
+
return ice_aq_send_cmd(pi->hw, &desc, NULL, 0, cd);
}
@@ -4395,7 +4367,7 @@ int ice_get_phy_lane_number(struct ice_hw *hw)
hw->device_id == ICE_DEV_ID_E825C_SGMII)
return hw->pf_id;
- options = kcalloc(ICE_AQC_PORT_OPT_MAX, sizeof(*options), GFP_KERNEL);
+ options = kzalloc_objs(*options, ICE_AQC_PORT_OPT_MAX);
if (!options)
return -ENOMEM;
@@ -6429,7 +6401,7 @@ int ice_lldp_fltr_add_remove(struct ice_hw *hw, struct ice_vsi *vsi, bool add)
struct ice_aqc_lldp_filter_ctrl *cmd;
struct libie_aq_desc desc;
- if (vsi->type != ICE_VSI_PF || !ice_fw_supports_lldp_fltr_ctrl(hw))
+ if (!ice_fw_supports_lldp_fltr_ctrl(hw))
return -EOPNOTSUPP;
cmd = libie_aq_raw(&desc);