21
21
#include "qed_vf.h"
22
22
23
23
/* 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 )
26
25
{
27
26
struct vf_start_ramrod_data * p_ramrod = NULL ;
28
27
struct qed_spq_entry * p_ent = NULL ;
29
28
struct qed_sp_init_data init_data ;
30
29
int rc = - EINVAL ;
30
+ u8 fp_minor ;
31
31
32
32
/* Get SPQ entry */
33
33
memset (& init_data , 0 , sizeof (init_data ));
34
34
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 ;
36
36
init_data .comp_mode = QED_SPQ_MODE_EBLOCK ;
37
37
38
38
rc = qed_sp_init_request (p_hwfn , & p_ent ,
@@ -43,12 +43,39 @@ static int qed_sp_vf_start(struct qed_hwfn *p_hwfn,
43
43
44
44
p_ramrod = & p_ent -> ramrod .vf_start ;
45
45
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
+ }
48
72
49
- p_ramrod -> personality = PERSONALITY_ETH ;
50
73
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 );
52
79
53
80
return qed_spq_post (p_hwfn , p_ent , NULL );
54
81
}
@@ -600,17 +627,6 @@ static int qed_iov_enable_vf_access(struct qed_hwfn *p_hwfn,
600
627
/* unpretend */
601
628
qed_fid_pretend (p_hwfn , p_ptt , (u16 ) p_hwfn -> hw_info .concrete_fid );
602
629
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
-
614
630
vf -> state = VF_FREE ;
615
631
616
632
return rc ;
@@ -854,7 +870,6 @@ static int qed_iov_release_hw_for_vf(struct qed_hwfn *p_hwfn,
854
870
struct qed_mcp_link_params params ;
855
871
struct qed_mcp_link_state link ;
856
872
struct qed_vf_info * vf = NULL ;
857
- int rc = 0 ;
858
873
859
874
vf = qed_iov_get_vf_info (p_hwfn , rel_vf_id , true);
860
875
if (!vf ) {
@@ -876,18 +891,8 @@ static int qed_iov_release_hw_for_vf(struct qed_hwfn *p_hwfn,
876
891
memcpy (& caps , qed_mcp_get_link_capabilities (p_hwfn ), sizeof (caps ));
877
892
qed_iov_set_link (p_hwfn , rel_vf_id , & params , & link , & caps );
878
893
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 ));
891
896
892
897
/* disablng interrupts and resetting permission table was done during
893
898
* 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,
1132
1137
p_vf -> vf_queues [i ].rxq_active = 0 ;
1133
1138
1134
1139
memset (& p_vf -> shadow_config , 0 , sizeof (p_vf -> shadow_config ));
1140
+ memset (& p_vf -> acquire , 0 , sizeof (p_vf -> acquire ));
1135
1141
qed_iov_clean_vf (p_hwfn , p_vf -> relative_vf_id );
1136
1142
}
1137
1143
@@ -1143,25 +1149,27 @@ static void qed_iov_vf_mbx_acquire(struct qed_hwfn *p_hwfn,
1143
1149
struct pfvf_acquire_resp_tlv * resp = & mbx -> reply_virt -> acquire_resp ;
1144
1150
struct pf_vf_pfdev_info * pfdev_info = & resp -> pfdev_info ;
1145
1151
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 ;
1147
1153
struct pf_vf_resc * resc = & resp -> resc ;
1154
+ int rc ;
1155
+
1156
+ memset (resp , 0 , sizeof (* resp ));
1148
1157
1149
1158
/* 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 ) {
1154
1160
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" ,
1156
1162
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
+
1165
1173
goto out ;
1166
1174
}
1167
1175
@@ -1171,11 +1179,11 @@ static void qed_iov_vf_mbx_acquire(struct qed_hwfn *p_hwfn,
1171
1179
DP_INFO (p_hwfn ,
1172
1180
"VF[%d] is running an old driver that doesn't support 100g\n" ,
1173
1181
vf -> abs_vf_id );
1174
- vfpf_status = PFVF_STATUS_NOT_SUPPORTED ;
1175
1182
goto out ;
1176
1183
}
1177
1184
1178
- memset (resp , 0 , sizeof (* resp ));
1185
+ /* Store the acquire message */
1186
+ memcpy (& vf -> acquire , req , sizeof (vf -> acquire ));
1179
1187
1180
1188
/* Fill in vf info stuff */
1181
1189
vf -> opaque_fid = req -> vfdev_info .opaque_fid ;
@@ -1223,6 +1231,9 @@ static void qed_iov_vf_mbx_acquire(struct qed_hwfn *p_hwfn,
1223
1231
pfdev_info -> fw_minor = FW_MINOR_VERSION ;
1224
1232
pfdev_info -> fw_rev = FW_REVISION_VERSION ;
1225
1233
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 );
1226
1237
pfdev_info -> os_type = VFPF_ACQUIRE_OS_LINUX ;
1227
1238
qed_mcp_get_mfw_ver (p_hwfn , p_ptt , & pfdev_info -> mfw_ver , NULL );
1228
1239
@@ -1253,6 +1264,14 @@ static void qed_iov_vf_mbx_acquire(struct qed_hwfn *p_hwfn,
1253
1264
*/
1254
1265
resc -> num_mc_filters = req -> resc_request .num_mc_filters ;
1255
1266
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
+
1256
1275
/* Fill agreed size of bulletin board in response */
1257
1276
resp -> bulletin_size = vf -> bulletin .size ;
1258
1277
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,
2360
2379
struct qed_vf_info * p_vf )
2361
2380
{
2362
2381
u16 length = sizeof (struct pfvf_def_resp_tlv );
2382
+ u8 status = PFVF_STATUS_SUCCESS ;
2383
+ int rc = 0 ;
2363
2384
2364
2385
qed_iov_vf_cleanup (p_hwfn , p_vf );
2365
2386
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
+
2366
2401
qed_iov_prepare_resp (p_hwfn , p_ptt , p_vf , CHANNEL_TLV_RELEASE ,
2367
- length , PFVF_STATUS_SUCCESS );
2402
+ length , status );
2368
2403
}
2369
2404
2370
2405
static int
0 commit comments