|
@@ -476,12 +476,12 @@ int qed_iov_hw_info(struct qed_hwfn *p_hwfn)
|
|
static bool qed_iov_pf_sanity_check(struct qed_hwfn *p_hwfn, int vfid)
|
|
static bool qed_iov_pf_sanity_check(struct qed_hwfn *p_hwfn, int vfid)
|
|
{
|
|
{
|
|
/* Check PF supports sriov */
|
|
/* Check PF supports sriov */
|
|
- if (!IS_QED_SRIOV(p_hwfn->cdev) || !IS_PF_SRIOV_ALLOC(p_hwfn))
|
|
|
|
|
|
+ if (IS_VF(p_hwfn->cdev) || !IS_QED_SRIOV(p_hwfn->cdev) ||
|
|
|
|
+ !IS_PF_SRIOV_ALLOC(p_hwfn))
|
|
return false;
|
|
return false;
|
|
|
|
|
|
/* Check VF validity */
|
|
/* Check VF validity */
|
|
- if (IS_VF(p_hwfn->cdev) || !IS_QED_SRIOV(p_hwfn->cdev) ||
|
|
|
|
- !IS_PF_SRIOV_ALLOC(p_hwfn))
|
|
|
|
|
|
+ if (!qed_iov_is_valid_vfid(p_hwfn, vfid, true))
|
|
return false;
|
|
return false;
|
|
|
|
|
|
return true;
|
|
return true;
|
|
@@ -526,7 +526,6 @@ static void qed_iov_vf_pglue_clear_err(struct qed_hwfn *p_hwfn,
|
|
static void qed_iov_vf_igu_reset(struct qed_hwfn *p_hwfn,
|
|
static void qed_iov_vf_igu_reset(struct qed_hwfn *p_hwfn,
|
|
struct qed_ptt *p_ptt, struct qed_vf_info *vf)
|
|
struct qed_ptt *p_ptt, struct qed_vf_info *vf)
|
|
{
|
|
{
|
|
- u16 igu_sb_id;
|
|
|
|
int i;
|
|
int i;
|
|
|
|
|
|
/* Set VF masks and configuration - pretend */
|
|
/* Set VF masks and configuration - pretend */
|
|
@@ -534,23 +533,14 @@ static void qed_iov_vf_igu_reset(struct qed_hwfn *p_hwfn,
|
|
|
|
|
|
qed_wr(p_hwfn, p_ptt, IGU_REG_STATISTIC_NUM_VF_MSG_SENT, 0);
|
|
qed_wr(p_hwfn, p_ptt, IGU_REG_STATISTIC_NUM_VF_MSG_SENT, 0);
|
|
|
|
|
|
- DP_VERBOSE(p_hwfn, QED_MSG_IOV,
|
|
|
|
- "value in VF_CONFIGURATION of vf %d after write %x\n",
|
|
|
|
- vf->abs_vf_id,
|
|
|
|
- qed_rd(p_hwfn, p_ptt, IGU_REG_VF_CONFIGURATION));
|
|
|
|
-
|
|
|
|
/* unpretend */
|
|
/* unpretend */
|
|
qed_fid_pretend(p_hwfn, p_ptt, (u16) p_hwfn->hw_info.concrete_fid);
|
|
qed_fid_pretend(p_hwfn, p_ptt, (u16) p_hwfn->hw_info.concrete_fid);
|
|
|
|
|
|
/* iterate over all queues, clear sb consumer */
|
|
/* iterate over all queues, clear sb consumer */
|
|
- for (i = 0; i < vf->num_sbs; i++) {
|
|
|
|
- igu_sb_id = vf->igu_sbs[i];
|
|
|
|
- /* Set then clear... */
|
|
|
|
- qed_int_igu_cleanup_sb(p_hwfn, p_ptt, igu_sb_id, 1,
|
|
|
|
- vf->opaque_fid);
|
|
|
|
- qed_int_igu_cleanup_sb(p_hwfn, p_ptt, igu_sb_id, 0,
|
|
|
|
- vf->opaque_fid);
|
|
|
|
- }
|
|
|
|
|
|
+ for (i = 0; i < vf->num_sbs; i++)
|
|
|
|
+ qed_int_igu_init_pure_rt_single(p_hwfn, p_ptt,
|
|
|
|
+ vf->igu_sbs[i],
|
|
|
|
+ vf->opaque_fid, true);
|
|
}
|
|
}
|
|
|
|
|
|
static void qed_iov_vf_igu_set_int(struct qed_hwfn *p_hwfn,
|
|
static void qed_iov_vf_igu_set_int(struct qed_hwfn *p_hwfn,
|
|
@@ -591,6 +581,8 @@ static int qed_iov_enable_vf_access(struct qed_hwfn *p_hwfn,
|
|
|
|
|
|
qed_iov_vf_pglue_clear_err(p_hwfn, p_ptt, QED_VF_ABS_ID(p_hwfn, vf));
|
|
qed_iov_vf_pglue_clear_err(p_hwfn, p_ptt, QED_VF_ABS_ID(p_hwfn, vf));
|
|
|
|
|
|
|
|
+ qed_iov_vf_igu_reset(p_hwfn, p_ptt, vf);
|
|
|
|
+
|
|
rc = qed_mcp_config_vf_msix(p_hwfn, p_ptt, vf->abs_vf_id, vf->num_sbs);
|
|
rc = qed_mcp_config_vf_msix(p_hwfn, p_ptt, vf->abs_vf_id, vf->num_sbs);
|
|
if (rc)
|
|
if (rc)
|
|
return rc;
|
|
return rc;
|
|
@@ -814,9 +806,51 @@ static int qed_iov_init_hw_for_vf(struct qed_hwfn *p_hwfn,
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void qed_iov_set_link(struct qed_hwfn *p_hwfn,
|
|
|
|
+ u16 vfid,
|
|
|
|
+ struct qed_mcp_link_params *params,
|
|
|
|
+ struct qed_mcp_link_state *link,
|
|
|
|
+ struct qed_mcp_link_capabilities *p_caps)
|
|
|
|
+{
|
|
|
|
+ struct qed_vf_info *p_vf = qed_iov_get_vf_info(p_hwfn,
|
|
|
|
+ vfid,
|
|
|
|
+ false);
|
|
|
|
+ struct qed_bulletin_content *p_bulletin;
|
|
|
|
+
|
|
|
|
+ if (!p_vf)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ p_bulletin = p_vf->bulletin.p_virt;
|
|
|
|
+ p_bulletin->req_autoneg = params->speed.autoneg;
|
|
|
|
+ p_bulletin->req_adv_speed = params->speed.advertised_speeds;
|
|
|
|
+ p_bulletin->req_forced_speed = params->speed.forced_speed;
|
|
|
|
+ p_bulletin->req_autoneg_pause = params->pause.autoneg;
|
|
|
|
+ p_bulletin->req_forced_rx = params->pause.forced_rx;
|
|
|
|
+ p_bulletin->req_forced_tx = params->pause.forced_tx;
|
|
|
|
+ p_bulletin->req_loopback = params->loopback_mode;
|
|
|
|
+
|
|
|
|
+ p_bulletin->link_up = link->link_up;
|
|
|
|
+ p_bulletin->speed = link->speed;
|
|
|
|
+ p_bulletin->full_duplex = link->full_duplex;
|
|
|
|
+ p_bulletin->autoneg = link->an;
|
|
|
|
+ p_bulletin->autoneg_complete = link->an_complete;
|
|
|
|
+ p_bulletin->parallel_detection = link->parallel_detection;
|
|
|
|
+ p_bulletin->pfc_enabled = link->pfc_enabled;
|
|
|
|
+ p_bulletin->partner_adv_speed = link->partner_adv_speed;
|
|
|
|
+ p_bulletin->partner_tx_flow_ctrl_en = link->partner_tx_flow_ctrl_en;
|
|
|
|
+ p_bulletin->partner_rx_flow_ctrl_en = link->partner_rx_flow_ctrl_en;
|
|
|
|
+ p_bulletin->partner_adv_pause = link->partner_adv_pause;
|
|
|
|
+ p_bulletin->sfp_tx_fault = link->sfp_tx_fault;
|
|
|
|
+
|
|
|
|
+ p_bulletin->capability_speed = p_caps->speed_capabilities;
|
|
|
|
+}
|
|
|
|
+
|
|
static int qed_iov_release_hw_for_vf(struct qed_hwfn *p_hwfn,
|
|
static int qed_iov_release_hw_for_vf(struct qed_hwfn *p_hwfn,
|
|
struct qed_ptt *p_ptt, u16 rel_vf_id)
|
|
struct qed_ptt *p_ptt, u16 rel_vf_id)
|
|
{
|
|
{
|
|
|
|
+ struct qed_mcp_link_capabilities caps;
|
|
|
|
+ struct qed_mcp_link_params params;
|
|
|
|
+ struct qed_mcp_link_state link;
|
|
struct qed_vf_info *vf = NULL;
|
|
struct qed_vf_info *vf = NULL;
|
|
int rc = 0;
|
|
int rc = 0;
|
|
|
|
|
|
@@ -831,6 +865,15 @@ static int qed_iov_release_hw_for_vf(struct qed_hwfn *p_hwfn,
|
|
|
|
|
|
memset(&vf->p_vf_info, 0, sizeof(vf->p_vf_info));
|
|
memset(&vf->p_vf_info, 0, sizeof(vf->p_vf_info));
|
|
|
|
|
|
|
|
+ /* Get the link configuration back in bulletin so
|
|
|
|
+ * that when VFs are re-enabled they get the actual
|
|
|
|
+ * link configuration.
|
|
|
|
+ */
|
|
|
|
+ memcpy(¶ms, qed_mcp_get_link_params(p_hwfn), sizeof(params));
|
|
|
|
+ memcpy(&link, qed_mcp_get_link_state(p_hwfn), sizeof(link));
|
|
|
|
+ memcpy(&caps, qed_mcp_get_link_capabilities(p_hwfn), sizeof(caps));
|
|
|
|
+ qed_iov_set_link(p_hwfn, rel_vf_id, ¶ms, &link, &caps);
|
|
|
|
+
|
|
if (vf->state != VF_STOPPED) {
|
|
if (vf->state != VF_STOPPED) {
|
|
/* Stopping the VF */
|
|
/* Stopping the VF */
|
|
rc = qed_sp_vf_stop(p_hwfn, vf->concrete_fid, vf->opaque_fid);
|
|
rc = qed_sp_vf_stop(p_hwfn, vf->concrete_fid, vf->opaque_fid);
|
|
@@ -2550,45 +2593,6 @@ int qed_iov_mark_vf_flr(struct qed_hwfn *p_hwfn, u32 *p_disabled_vfs)
|
|
return found;
|
|
return found;
|
|
}
|
|
}
|
|
|
|
|
|
-void qed_iov_set_link(struct qed_hwfn *p_hwfn,
|
|
|
|
- u16 vfid,
|
|
|
|
- struct qed_mcp_link_params *params,
|
|
|
|
- struct qed_mcp_link_state *link,
|
|
|
|
- struct qed_mcp_link_capabilities *p_caps)
|
|
|
|
-{
|
|
|
|
- struct qed_vf_info *p_vf = qed_iov_get_vf_info(p_hwfn,
|
|
|
|
- vfid,
|
|
|
|
- false);
|
|
|
|
- struct qed_bulletin_content *p_bulletin;
|
|
|
|
-
|
|
|
|
- if (!p_vf)
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
- p_bulletin = p_vf->bulletin.p_virt;
|
|
|
|
- p_bulletin->req_autoneg = params->speed.autoneg;
|
|
|
|
- p_bulletin->req_adv_speed = params->speed.advertised_speeds;
|
|
|
|
- p_bulletin->req_forced_speed = params->speed.forced_speed;
|
|
|
|
- p_bulletin->req_autoneg_pause = params->pause.autoneg;
|
|
|
|
- p_bulletin->req_forced_rx = params->pause.forced_rx;
|
|
|
|
- p_bulletin->req_forced_tx = params->pause.forced_tx;
|
|
|
|
- p_bulletin->req_loopback = params->loopback_mode;
|
|
|
|
-
|
|
|
|
- p_bulletin->link_up = link->link_up;
|
|
|
|
- p_bulletin->speed = link->speed;
|
|
|
|
- p_bulletin->full_duplex = link->full_duplex;
|
|
|
|
- p_bulletin->autoneg = link->an;
|
|
|
|
- p_bulletin->autoneg_complete = link->an_complete;
|
|
|
|
- p_bulletin->parallel_detection = link->parallel_detection;
|
|
|
|
- p_bulletin->pfc_enabled = link->pfc_enabled;
|
|
|
|
- p_bulletin->partner_adv_speed = link->partner_adv_speed;
|
|
|
|
- p_bulletin->partner_tx_flow_ctrl_en = link->partner_tx_flow_ctrl_en;
|
|
|
|
- p_bulletin->partner_rx_flow_ctrl_en = link->partner_rx_flow_ctrl_en;
|
|
|
|
- p_bulletin->partner_adv_pause = link->partner_adv_pause;
|
|
|
|
- p_bulletin->sfp_tx_fault = link->sfp_tx_fault;
|
|
|
|
-
|
|
|
|
- p_bulletin->capability_speed = p_caps->speed_capabilities;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static void qed_iov_get_link(struct qed_hwfn *p_hwfn,
|
|
static void qed_iov_get_link(struct qed_hwfn *p_hwfn,
|
|
u16 vfid,
|
|
u16 vfid,
|
|
struct qed_mcp_link_params *p_params,
|
|
struct qed_mcp_link_params *p_params,
|
|
@@ -3095,6 +3099,9 @@ static int qed_sriov_enable(struct qed_dev *cdev, int num)
|
|
goto err;
|
|
goto err;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (IS_MF_DEFAULT(hwfn))
|
|
|
|
+ limit = MAX_NUM_VFS_BB / hwfn->num_funcs_on_engine;
|
|
|
|
+
|
|
memset(&sb_cnt_info, 0, sizeof(sb_cnt_info));
|
|
memset(&sb_cnt_info, 0, sizeof(sb_cnt_info));
|
|
qed_int_get_num_sbs(hwfn, &sb_cnt_info);
|
|
qed_int_get_num_sbs(hwfn, &sb_cnt_info);
|
|
num_sbs = min_t(int, sb_cnt_info.sb_free_blk, limit);
|
|
num_sbs = min_t(int, sb_cnt_info.sb_free_blk, limit);
|