Skip to content

Commit 1fe614d

Browse files
Yuval Mintzdavem330
authored andcommitted
qed: Relax VF firmware requirements
Current driver require an exact match between VF and PF storm firmware; Any difference would fail the VF acquire message, causing the VF probe to be aborted. While there's still dependencies between the two, the recent FW submission has relaxed the match requirement - instead of an exact match, there's now a 'fastpath' HSI major/minor scheme, where VFs and PFs that match in their major number can co-exist even if their minor is different. In order to accomadate this change some changes in the vf-start init flow had to be made, as the VF start ramrod now has to be sent only after PF learns which fastpath HSI its VF is requiring. Signed-off-by: Yuval Mintz <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 3bcb846 commit 1fe614d

File tree

4 files changed

+116
-50
lines changed

4 files changed

+116
-50
lines changed

drivers/net/ethernet/qlogic/qed/qed_sriov.c

Lines changed: 83 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,18 @@
2121
#include "qed_vf.h"
2222

2323
/* IOV ramrods */
24-
static int qed_sp_vf_start(struct qed_hwfn *p_hwfn,
25-
u32 concrete_vfid, u16 opaque_vfid)
24+
static int qed_sp_vf_start(struct qed_hwfn *p_hwfn, struct qed_vf_info *p_vf)
2625
{
2726
struct vf_start_ramrod_data *p_ramrod = NULL;
2827
struct qed_spq_entry *p_ent = NULL;
2928
struct qed_sp_init_data init_data;
3029
int rc = -EINVAL;
30+
u8 fp_minor;
3131

3232
/* Get SPQ entry */
3333
memset(&init_data, 0, sizeof(init_data));
3434
init_data.cid = qed_spq_get_cid(p_hwfn);
35-
init_data.opaque_fid = opaque_vfid;
35+
init_data.opaque_fid = p_vf->opaque_fid;
3636
init_data.comp_mode = QED_SPQ_MODE_EBLOCK;
3737

3838
rc = qed_sp_init_request(p_hwfn, &p_ent,
@@ -43,12 +43,39 @@ static int qed_sp_vf_start(struct qed_hwfn *p_hwfn,
4343

4444
p_ramrod = &p_ent->ramrod.vf_start;
4545

46-
p_ramrod->vf_id = GET_FIELD(concrete_vfid, PXP_CONCRETE_FID_VFID);
47-
p_ramrod->opaque_fid = cpu_to_le16(opaque_vfid);
46+
p_ramrod->vf_id = GET_FIELD(p_vf->concrete_fid, PXP_CONCRETE_FID_VFID);
47+
p_ramrod->opaque_fid = cpu_to_le16(p_vf->opaque_fid);
48+
49+
switch (p_hwfn->hw_info.personality) {
50+
case QED_PCI_ETH:
51+
p_ramrod->personality = PERSONALITY_ETH;
52+
break;
53+
case QED_PCI_ETH_ROCE:
54+
p_ramrod->personality = PERSONALITY_RDMA_AND_ETH;
55+
break;
56+
default:
57+
DP_NOTICE(p_hwfn, "Unknown VF personality %d\n",
58+
p_hwfn->hw_info.personality);
59+
return -EINVAL;
60+
}
61+
62+
fp_minor = p_vf->acquire.vfdev_info.eth_fp_hsi_minor;
63+
if (fp_minor > ETH_HSI_VER_MINOR) {
64+
DP_VERBOSE(p_hwfn,
65+
QED_MSG_IOV,
66+
"VF [%d] - Requested fp hsi %02x.%02x which is slightly newer than PF's %02x.%02x; Configuring PFs version\n",
67+
p_vf->abs_vf_id,
68+
ETH_HSI_VER_MAJOR,
69+
fp_minor, ETH_HSI_VER_MAJOR, ETH_HSI_VER_MINOR);
70+
fp_minor = ETH_HSI_VER_MINOR;
71+
}
4872

49-
p_ramrod->personality = PERSONALITY_ETH;
5073
p_ramrod->hsi_fp_ver.major_ver_arr[ETH_VER_KEY] = ETH_HSI_VER_MAJOR;
51-
p_ramrod->hsi_fp_ver.minor_ver_arr[ETH_VER_KEY] = ETH_HSI_VER_MINOR;
74+
p_ramrod->hsi_fp_ver.minor_ver_arr[ETH_VER_KEY] = fp_minor;
75+
76+
DP_VERBOSE(p_hwfn, QED_MSG_IOV,
77+
"VF[%d] - Starting using HSI %02x.%02x\n",
78+
p_vf->abs_vf_id, ETH_HSI_VER_MAJOR, fp_minor);
5279

5380
return qed_spq_post(p_hwfn, p_ent, NULL);
5481
}
@@ -600,17 +627,6 @@ static int qed_iov_enable_vf_access(struct qed_hwfn *p_hwfn,
600627
/* unpretend */
601628
qed_fid_pretend(p_hwfn, p_ptt, (u16) p_hwfn->hw_info.concrete_fid);
602629

603-
if (vf->state != VF_STOPPED) {
604-
DP_NOTICE(p_hwfn, "VF[%02x] is already started\n",
605-
vf->abs_vf_id);
606-
return -EINVAL;
607-
}
608-
609-
/* Start VF */
610-
rc = qed_sp_vf_start(p_hwfn, vf->concrete_fid, vf->opaque_fid);
611-
if (rc)
612-
DP_NOTICE(p_hwfn, "Failed to start VF[%02x]\n", vf->abs_vf_id);
613-
614630
vf->state = VF_FREE;
615631

616632
return rc;
@@ -854,7 +870,6 @@ static int qed_iov_release_hw_for_vf(struct qed_hwfn *p_hwfn,
854870
struct qed_mcp_link_params params;
855871
struct qed_mcp_link_state link;
856872
struct qed_vf_info *vf = NULL;
857-
int rc = 0;
858873

859874
vf = qed_iov_get_vf_info(p_hwfn, rel_vf_id, true);
860875
if (!vf) {
@@ -876,18 +891,8 @@ static int qed_iov_release_hw_for_vf(struct qed_hwfn *p_hwfn,
876891
memcpy(&caps, qed_mcp_get_link_capabilities(p_hwfn), sizeof(caps));
877892
qed_iov_set_link(p_hwfn, rel_vf_id, &params, &link, &caps);
878893

879-
if (vf->state != VF_STOPPED) {
880-
/* Stopping the VF */
881-
rc = qed_sp_vf_stop(p_hwfn, vf->concrete_fid, vf->opaque_fid);
882-
883-
if (rc != 0) {
884-
DP_ERR(p_hwfn, "qed_sp_vf_stop returned error %d\n",
885-
rc);
886-
return rc;
887-
}
888-
889-
vf->state = VF_STOPPED;
890-
}
894+
/* Forget the VF's acquisition message */
895+
memset(&vf->acquire, 0, sizeof(vf->acquire));
891896

892897
/* disablng interrupts and resetting permission table was done during
893898
* vf-close, however, we could get here without going through vf_close
@@ -1132,6 +1137,7 @@ static void qed_iov_vf_cleanup(struct qed_hwfn *p_hwfn,
11321137
p_vf->vf_queues[i].rxq_active = 0;
11331138

11341139
memset(&p_vf->shadow_config, 0, sizeof(p_vf->shadow_config));
1140+
memset(&p_vf->acquire, 0, sizeof(p_vf->acquire));
11351141
qed_iov_clean_vf(p_hwfn, p_vf->relative_vf_id);
11361142
}
11371143

@@ -1143,25 +1149,27 @@ static void qed_iov_vf_mbx_acquire(struct qed_hwfn *p_hwfn,
11431149
struct pfvf_acquire_resp_tlv *resp = &mbx->reply_virt->acquire_resp;
11441150
struct pf_vf_pfdev_info *pfdev_info = &resp->pfdev_info;
11451151
struct vfpf_acquire_tlv *req = &mbx->req_virt->acquire;
1146-
u8 i, vfpf_status = PFVF_STATUS_SUCCESS;
1152+
u8 i, vfpf_status = PFVF_STATUS_NOT_SUPPORTED;
11471153
struct pf_vf_resc *resc = &resp->resc;
1154+
int rc;
1155+
1156+
memset(resp, 0, sizeof(*resp));
11481157

11491158
/* Validate FW compatibility */
1150-
if (req->vfdev_info.fw_major != FW_MAJOR_VERSION ||
1151-
req->vfdev_info.fw_minor != FW_MINOR_VERSION ||
1152-
req->vfdev_info.fw_revision != FW_REVISION_VERSION ||
1153-
req->vfdev_info.fw_engineering != FW_ENGINEERING_VERSION) {
1159+
if (req->vfdev_info.eth_fp_hsi_major != ETH_HSI_VER_MAJOR) {
11541160
DP_INFO(p_hwfn,
1155-
"VF[%d] is running an incompatible driver [VF needs FW %02x:%02x:%02x:%02x but Hypervisor is using %02x:%02x:%02x:%02x]\n",
1161+
"VF[%d] needs fastpath HSI %02x.%02x, which is incompatible with loaded FW's faspath HSI %02x.%02x\n",
11561162
vf->abs_vf_id,
1157-
req->vfdev_info.fw_major,
1158-
req->vfdev_info.fw_minor,
1159-
req->vfdev_info.fw_revision,
1160-
req->vfdev_info.fw_engineering,
1161-
FW_MAJOR_VERSION,
1162-
FW_MINOR_VERSION,
1163-
FW_REVISION_VERSION, FW_ENGINEERING_VERSION);
1164-
vfpf_status = PFVF_STATUS_NOT_SUPPORTED;
1163+
req->vfdev_info.eth_fp_hsi_major,
1164+
req->vfdev_info.eth_fp_hsi_minor,
1165+
ETH_HSI_VER_MAJOR, ETH_HSI_VER_MINOR);
1166+
1167+
/* Write the PF version so that VF would know which version
1168+
* is supported.
1169+
*/
1170+
pfdev_info->major_fp_hsi = ETH_HSI_VER_MAJOR;
1171+
pfdev_info->minor_fp_hsi = ETH_HSI_VER_MINOR;
1172+
11651173
goto out;
11661174
}
11671175

@@ -1171,11 +1179,11 @@ static void qed_iov_vf_mbx_acquire(struct qed_hwfn *p_hwfn,
11711179
DP_INFO(p_hwfn,
11721180
"VF[%d] is running an old driver that doesn't support 100g\n",
11731181
vf->abs_vf_id);
1174-
vfpf_status = PFVF_STATUS_NOT_SUPPORTED;
11751182
goto out;
11761183
}
11771184

1178-
memset(resp, 0, sizeof(*resp));
1185+
/* Store the acquire message */
1186+
memcpy(&vf->acquire, req, sizeof(vf->acquire));
11791187

11801188
/* Fill in vf info stuff */
11811189
vf->opaque_fid = req->vfdev_info.opaque_fid;
@@ -1223,6 +1231,9 @@ static void qed_iov_vf_mbx_acquire(struct qed_hwfn *p_hwfn,
12231231
pfdev_info->fw_minor = FW_MINOR_VERSION;
12241232
pfdev_info->fw_rev = FW_REVISION_VERSION;
12251233
pfdev_info->fw_eng = FW_ENGINEERING_VERSION;
1234+
pfdev_info->minor_fp_hsi = min_t(u8,
1235+
ETH_HSI_VER_MINOR,
1236+
req->vfdev_info.eth_fp_hsi_minor);
12261237
pfdev_info->os_type = VFPF_ACQUIRE_OS_LINUX;
12271238
qed_mcp_get_mfw_ver(p_hwfn, p_ptt, &pfdev_info->mfw_ver, NULL);
12281239

@@ -1253,6 +1264,14 @@ static void qed_iov_vf_mbx_acquire(struct qed_hwfn *p_hwfn,
12531264
*/
12541265
resc->num_mc_filters = req->resc_request.num_mc_filters;
12551266

1267+
/* Start the VF in FW */
1268+
rc = qed_sp_vf_start(p_hwfn, vf);
1269+
if (rc) {
1270+
DP_NOTICE(p_hwfn, "Failed to start VF[%02x]\n", vf->abs_vf_id);
1271+
vfpf_status = PFVF_STATUS_FAILURE;
1272+
goto out;
1273+
}
1274+
12561275
/* Fill agreed size of bulletin board in response */
12571276
resp->bulletin_size = vf->bulletin.size;
12581277
qed_iov_post_vf_bulletin(p_hwfn, vf->relative_vf_id, p_ptt);
@@ -2360,11 +2379,27 @@ static void qed_iov_vf_mbx_release(struct qed_hwfn *p_hwfn,
23602379
struct qed_vf_info *p_vf)
23612380
{
23622381
u16 length = sizeof(struct pfvf_def_resp_tlv);
2382+
u8 status = PFVF_STATUS_SUCCESS;
2383+
int rc = 0;
23632384

23642385
qed_iov_vf_cleanup(p_hwfn, p_vf);
23652386

2387+
if (p_vf->state != VF_STOPPED && p_vf->state != VF_FREE) {
2388+
/* Stopping the VF */
2389+
rc = qed_sp_vf_stop(p_hwfn, p_vf->concrete_fid,
2390+
p_vf->opaque_fid);
2391+
2392+
if (rc) {
2393+
DP_ERR(p_hwfn, "qed_sp_vf_stop returned error %d\n",
2394+
rc);
2395+
status = PFVF_STATUS_FAILURE;
2396+
}
2397+
2398+
p_vf->state = VF_STOPPED;
2399+
}
2400+
23662401
qed_iov_prepare_resp(p_hwfn, p_ptt, p_vf, CHANNEL_TLV_RELEASE,
2367-
length, PFVF_STATUS_SUCCESS);
2402+
length, status);
23682403
}
23692404

23702405
static int

drivers/net/ethernet/qlogic/qed/qed_sriov.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ struct qed_vf_info {
131131
struct qed_bulletin bulletin;
132132
dma_addr_t vf_bulletin;
133133

134+
/* PF saves a copy of the last VF acquire message */
135+
struct vfpf_acquire_tlv acquire;
136+
134137
u32 concrete_fid;
135138
u16 opaque_fid;
136139
u16 mtu;

drivers/net/ethernet/qlogic/qed/qed_vf.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ static int qed_vf_pf_acquire(struct qed_hwfn *p_hwfn)
147147
req->vfdev_info.fw_minor = FW_MINOR_VERSION;
148148
req->vfdev_info.fw_revision = FW_REVISION_VERSION;
149149
req->vfdev_info.fw_engineering = FW_ENGINEERING_VERSION;
150+
req->vfdev_info.eth_fp_hsi_major = ETH_HSI_VER_MAJOR;
151+
req->vfdev_info.eth_fp_hsi_minor = ETH_HSI_VER_MINOR;
150152

151153
/* Fill capability field with any non-deprecated config we support */
152154
req->vfdev_info.capabilities |= VFPF_ACQUIRE_CAP_100G;
@@ -200,6 +202,16 @@ static int qed_vf_pf_acquire(struct qed_hwfn *p_hwfn)
200202

201203
/* Clear response buffer */
202204
memset(p_iov->pf2vf_reply, 0, sizeof(union pfvf_tlvs));
205+
} else if ((resp->hdr.status == PFVF_STATUS_NOT_SUPPORTED) &&
206+
pfdev_info->major_fp_hsi &&
207+
(pfdev_info->major_fp_hsi != ETH_HSI_VER_MAJOR)) {
208+
DP_NOTICE(p_hwfn,
209+
"PF uses an incompatible fastpath HSI %02x.%02x [VF requires %02x.%02x]. Please change to a VF driver using %02x.xx.\n",
210+
pfdev_info->major_fp_hsi,
211+
pfdev_info->minor_fp_hsi,
212+
ETH_HSI_VER_MAJOR,
213+
ETH_HSI_VER_MINOR, pfdev_info->major_fp_hsi);
214+
return -EINVAL;
203215
} else {
204216
DP_ERR(p_hwfn,
205217
"PF returned error %d to VF acquisition request\n",
@@ -225,6 +237,13 @@ static int qed_vf_pf_acquire(struct qed_hwfn *p_hwfn)
225237
}
226238
}
227239

240+
if (ETH_HSI_VER_MINOR &&
241+
(resp->pfdev_info.minor_fp_hsi < ETH_HSI_VER_MINOR)) {
242+
DP_INFO(p_hwfn,
243+
"PF is using older fastpath HSI; %02x.%02x is configured\n",
244+
ETH_HSI_VER_MAJOR, resp->pfdev_info.minor_fp_hsi);
245+
}
246+
228247
return 0;
229248
}
230249

drivers/net/ethernet/qlogic/qed/qed_vf.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,9 @@ struct vfpf_acquire_tlv {
9696
u32 driver_version;
9797
u16 opaque_fid; /* ME register value */
9898
u8 os_type; /* VFPF_ACQUIRE_OS_* value */
99-
u8 padding[5];
99+
u8 eth_fp_hsi_major;
100+
u8 eth_fp_hsi_minor;
101+
u8 padding[3];
100102
} vfdev_info;
101103

102104
struct vf_pf_resc_request resc_request;
@@ -171,7 +173,14 @@ struct pfvf_acquire_resp_tlv {
171173
struct pfvf_stats_info stats_info;
172174

173175
u8 port_mac[ETH_ALEN];
174-
u8 padding2[2];
176+
177+
/* It's possible PF had to configure an older fastpath HSI
178+
* [in case VF is newer than PF]. This is communicated back
179+
* to the VF. It can also be used in case of error due to
180+
* non-matching versions to shed light in VF about failure.
181+
*/
182+
u8 major_fp_hsi;
183+
u8 minor_fp_hsi;
175184
} pfdev_info;
176185

177186
struct pf_vf_resc {

0 commit comments

Comments
 (0)