diff options
author | Yuval Mintz <Yuval.Mintz@qlogic.com> | 2014-12-04 05:52:06 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-12-09 14:29:10 -0500 |
commit | 02dc4025a088ea7ff53fcb35ba9e0f295078a4a0 (patch) | |
tree | 7e80c38e46064c840883a5d1e7176756954b3ebb /drivers/net/ethernet/broadcom/bnx2x | |
parent | 36c71a735ac2c7046ab1c234c734b2dd9035ad4f (diff) |
bnx2x: Use correct fastpath version for VFs.
Our FW can support several fastpath HSI [for backward compatibility] but up
until now VFs were always configured to use latest fastpath HSI [although VF
driver might be older and use an older fastpath HSI].
For linux drivers, the differences are insignificant since driver never
utilized features that were overridden by the HSI change. But for VMs running
other operating systems this might be a problem.
In addition, eventually FW might change fastpath HSI in such a manner that
backward compatibility WILL break unless configured with proper version.
This patch fixes the issue for other operating system VMs, as well as lays
the ground work for forward compatibility in regard to the fastpath HSI.
Signed-off-by: Yuval Mintz <Yuval.Mintz@qlogic.com>
Signed-off-by: Ariel Elior <Ariel.Elior@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom/bnx2x')
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c | 75 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h | 9 |
7 files changed, 88 insertions, 5 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 336ef3cf5773..07c636815127 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -3163,6 +3163,8 @@ static void bnx2x_pf_q_prep_general(struct bnx2x *bp, | |||
3163 | gen_init->mtu = bp->dev->mtu; | 3163 | gen_init->mtu = bp->dev->mtu; |
3164 | 3164 | ||
3165 | gen_init->cos = cos; | 3165 | gen_init->cos = cos; |
3166 | |||
3167 | gen_init->fp_hsi = ETH_FP_HSI_VERSION; | ||
3166 | } | 3168 | } |
3167 | 3169 | ||
3168 | static void bnx2x_pf_rx_q_prep(struct bnx2x *bp, | 3170 | static void bnx2x_pf_rx_q_prep(struct bnx2x *bp, |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 7bc2924a7e24..07cdf9bbffef 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | |||
@@ -4336,7 +4336,7 @@ static void bnx2x_q_fill_init_general_data(struct bnx2x *bp, | |||
4336 | test_bit(BNX2X_Q_FLG_FCOE, flags) ? | 4336 | test_bit(BNX2X_Q_FLG_FCOE, flags) ? |
4337 | LLFC_TRAFFIC_TYPE_FCOE : LLFC_TRAFFIC_TYPE_NW; | 4337 | LLFC_TRAFFIC_TYPE_FCOE : LLFC_TRAFFIC_TYPE_NW; |
4338 | 4338 | ||
4339 | gen_data->fp_hsi_ver = ETH_FP_HSI_VERSION; | 4339 | gen_data->fp_hsi_ver = params->fp_hsi; |
4340 | 4340 | ||
4341 | DP(BNX2X_MSG_SP, "flags: active %d, cos %d, stats en %d\n", | 4341 | DP(BNX2X_MSG_SP, "flags: active %d, cos %d, stats en %d\n", |
4342 | gen_data->activate_flg, gen_data->cos, gen_data->statistics_en_flg); | 4342 | gen_data->activate_flg, gen_data->cos, gen_data->statistics_en_flg); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h index e97275f456c0..86baecb7c60c 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h | |||
@@ -937,6 +937,8 @@ struct bnx2x_general_setup_params { | |||
937 | u8 spcl_id; | 937 | u8 spcl_id; |
938 | u16 mtu; | 938 | u16 mtu; |
939 | u8 cos; | 939 | u8 cos; |
940 | |||
941 | u8 fp_hsi; | ||
940 | }; | 942 | }; |
941 | 943 | ||
942 | struct bnx2x_rxq_setup_params { | 944 | struct bnx2x_rxq_setup_params { |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index c88b20af87df..e5aca2de1871 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | |||
@@ -193,6 +193,7 @@ void bnx2x_vfop_qctor_prep(struct bnx2x *bp, | |||
193 | /* Setup-op general parameters */ | 193 | /* Setup-op general parameters */ |
194 | setup_p->gen_params.spcl_id = vf->sp_cl_id; | 194 | setup_p->gen_params.spcl_id = vf->sp_cl_id; |
195 | setup_p->gen_params.stat_id = vfq_stat_id(vf, q); | 195 | setup_p->gen_params.stat_id = vfq_stat_id(vf, q); |
196 | setup_p->gen_params.fp_hsi = vf->fp_hsi; | ||
196 | 197 | ||
197 | /* Setup-op pause params: | 198 | /* Setup-op pause params: |
198 | * Nothing to do, the pause thresholds are set by default to 0 which | 199 | * Nothing to do, the pause thresholds are set by default to 0 which |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h index 01bafa4ac045..66ee62a0401a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h | |||
@@ -205,6 +205,8 @@ struct bnx2x_virtf { | |||
205 | /* slow-path operations */ | 205 | /* slow-path operations */ |
206 | struct mutex op_mutex; /* one vfop at a time mutex */ | 206 | struct mutex op_mutex; /* one vfop at a time mutex */ |
207 | enum channel_tlvs op_current; | 207 | enum channel_tlvs op_current; |
208 | |||
209 | u8 fp_hsi; | ||
208 | }; | 210 | }; |
209 | 211 | ||
210 | #define BNX2X_NR_VIRTFN(bp) ((bp)->vfdb->sriov.nr_virtfn) | 212 | #define BNX2X_NR_VIRTFN(bp) ((bp)->vfdb->sriov.nr_virtfn) |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c index b1d9c44aa56c..be40eabc5304 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c | |||
@@ -224,6 +224,7 @@ int bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count) | |||
224 | struct vfpf_acquire_tlv *req = &bp->vf2pf_mbox->req.acquire; | 224 | struct vfpf_acquire_tlv *req = &bp->vf2pf_mbox->req.acquire; |
225 | struct pfvf_acquire_resp_tlv *resp = &bp->vf2pf_mbox->resp.acquire_resp; | 225 | struct pfvf_acquire_resp_tlv *resp = &bp->vf2pf_mbox->resp.acquire_resp; |
226 | struct vfpf_port_phys_id_resp_tlv *phys_port_resp; | 226 | struct vfpf_port_phys_id_resp_tlv *phys_port_resp; |
227 | struct vfpf_fp_hsi_resp_tlv *fp_hsi_resp; | ||
227 | u32 vf_id; | 228 | u32 vf_id; |
228 | bool resources_acquired = false; | 229 | bool resources_acquired = false; |
229 | 230 | ||
@@ -237,6 +238,7 @@ int bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count) | |||
237 | 238 | ||
238 | req->vfdev_info.vf_id = vf_id; | 239 | req->vfdev_info.vf_id = vf_id; |
239 | req->vfdev_info.vf_os = 0; | 240 | req->vfdev_info.vf_os = 0; |
241 | req->vfdev_info.fp_hsi_ver = ETH_FP_HSI_VERSION; | ||
240 | 242 | ||
241 | req->resc_request.num_rxqs = rx_count; | 243 | req->resc_request.num_rxqs = rx_count; |
242 | req->resc_request.num_txqs = tx_count; | 244 | req->resc_request.num_txqs = tx_count; |
@@ -316,9 +318,14 @@ int bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count) | |||
316 | memset(&bp->vf2pf_mbox->resp, 0, | 318 | memset(&bp->vf2pf_mbox->resp, 0, |
317 | sizeof(union pfvf_tlvs)); | 319 | sizeof(union pfvf_tlvs)); |
318 | } else { | 320 | } else { |
319 | /* PF reports error */ | 321 | /* Determine reason of PF failure of acquire process */ |
320 | BNX2X_ERR("Failed to get the requested amount of resources: %d. Breaking...\n", | 322 | fp_hsi_resp = bnx2x_search_tlv_list(bp, resp, |
321 | bp->acquire_resp.hdr.status); | 323 | CHANNEL_TLV_FP_HSI_SUPPORT); |
324 | if (fp_hsi_resp && !fp_hsi_resp->is_supported) | ||
325 | BNX2X_ERR("Old hypervisor - doesn't support current fastpath HSI version; Need to downgrade VF driver [or upgrade hypervisor]\n"); | ||
326 | else | ||
327 | BNX2X_ERR("Failed to get the requested amount of resources: %d. Breaking...\n", | ||
328 | bp->acquire_resp.hdr.status); | ||
322 | rc = -EAGAIN; | 329 | rc = -EAGAIN; |
323 | goto out; | 330 | goto out; |
324 | } | 331 | } |
@@ -333,6 +340,25 @@ int bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count) | |||
333 | bp->flags |= HAS_PHYS_PORT_ID; | 340 | bp->flags |= HAS_PHYS_PORT_ID; |
334 | } | 341 | } |
335 | 342 | ||
343 | /* Old Hypevisors might not even support the FP_HSI_SUPPORT TLV. | ||
344 | * If that's the case, we need to make certain required FW was | ||
345 | * supported by such a hypervisor [i.e., v0-v2]. | ||
346 | */ | ||
347 | fp_hsi_resp = bnx2x_search_tlv_list(bp, resp, | ||
348 | CHANNEL_TLV_FP_HSI_SUPPORT); | ||
349 | if (!fp_hsi_resp && (ETH_FP_HSI_VERSION > ETH_FP_HSI_VER_2)) { | ||
350 | BNX2X_ERR("Old hypervisor - need to downgrade VF's driver\n"); | ||
351 | |||
352 | /* Since acquire succeeded on the PF side, we need to send a | ||
353 | * release message in order to allow future probes. | ||
354 | */ | ||
355 | bnx2x_vfpf_finalize(bp, &req->first_tlv); | ||
356 | bnx2x_vfpf_release(bp); | ||
357 | |||
358 | rc = -EINVAL; | ||
359 | goto out; | ||
360 | } | ||
361 | |||
336 | /* get HW info */ | 362 | /* get HW info */ |
337 | bp->common.chip_id |= (bp->acquire_resp.pfdev_info.chip_num & 0xffff); | 363 | bp->common.chip_id |= (bp->acquire_resp.pfdev_info.chip_num & 0xffff); |
338 | bp->link_params.chip_id = bp->common.chip_id; | 364 | bp->link_params.chip_id = bp->common.chip_id; |
@@ -1125,6 +1151,26 @@ static void bnx2x_vf_mbx_resp_phys_port(struct bnx2x *bp, | |||
1125 | *offset += sizeof(struct vfpf_port_phys_id_resp_tlv); | 1151 | *offset += sizeof(struct vfpf_port_phys_id_resp_tlv); |
1126 | } | 1152 | } |
1127 | 1153 | ||
1154 | static void bnx2x_vf_mbx_resp_fp_hsi_ver(struct bnx2x *bp, | ||
1155 | struct bnx2x_virtf *vf, | ||
1156 | void *buffer, | ||
1157 | u16 *offset) | ||
1158 | { | ||
1159 | struct vfpf_fp_hsi_resp_tlv *fp_hsi; | ||
1160 | |||
1161 | bnx2x_add_tlv(bp, buffer, *offset, CHANNEL_TLV_FP_HSI_SUPPORT, | ||
1162 | sizeof(struct vfpf_fp_hsi_resp_tlv)); | ||
1163 | |||
1164 | fp_hsi = (struct vfpf_fp_hsi_resp_tlv *) | ||
1165 | (((u8 *)buffer) + *offset); | ||
1166 | fp_hsi->is_supported = (vf->fp_hsi > ETH_FP_HSI_VERSION) ? 0 : 1; | ||
1167 | |||
1168 | /* Offset should continue representing the offset to the tail | ||
1169 | * of TLV data (outside this function scope) | ||
1170 | */ | ||
1171 | *offset += sizeof(struct vfpf_fp_hsi_resp_tlv); | ||
1172 | } | ||
1173 | |||
1128 | static void bnx2x_vf_mbx_acquire_resp(struct bnx2x *bp, struct bnx2x_virtf *vf, | 1174 | static void bnx2x_vf_mbx_acquire_resp(struct bnx2x *bp, struct bnx2x_virtf *vf, |
1129 | struct bnx2x_vf_mbx *mbx, int vfop_status) | 1175 | struct bnx2x_vf_mbx *mbx, int vfop_status) |
1130 | { | 1176 | { |
@@ -1219,6 +1265,12 @@ static void bnx2x_vf_mbx_acquire_resp(struct bnx2x *bp, struct bnx2x_virtf *vf, | |||
1219 | CHANNEL_TLV_PHYS_PORT_ID)) | 1265 | CHANNEL_TLV_PHYS_PORT_ID)) |
1220 | bnx2x_vf_mbx_resp_phys_port(bp, vf, &mbx->msg->resp, &length); | 1266 | bnx2x_vf_mbx_resp_phys_port(bp, vf, &mbx->msg->resp, &length); |
1221 | 1267 | ||
1268 | /* `New' vfs will want to know if fastpath HSI is supported, since | ||
1269 | * if that's not the case they could print into system log the fact | ||
1270 | * the driver version must be updated. | ||
1271 | */ | ||
1272 | bnx2x_vf_mbx_resp_fp_hsi_ver(bp, vf, &mbx->msg->resp, &length); | ||
1273 | |||
1222 | bnx2x_add_tlv(bp, &mbx->msg->resp, length, CHANNEL_TLV_LIST_END, | 1274 | bnx2x_add_tlv(bp, &mbx->msg->resp, length, CHANNEL_TLV_LIST_END, |
1223 | sizeof(struct channel_list_end_tlv)); | 1275 | sizeof(struct channel_list_end_tlv)); |
1224 | 1276 | ||
@@ -1288,6 +1340,23 @@ static void bnx2x_vf_mbx_acquire(struct bnx2x *bp, struct bnx2x_virtf *vf, | |||
1288 | goto out; | 1340 | goto out; |
1289 | } | 1341 | } |
1290 | 1342 | ||
1343 | /* Verify the VF fastpath HSI can be supported by the loaded FW. | ||
1344 | * Linux vfs should be oblivious to changes between v0 and v2. | ||
1345 | */ | ||
1346 | if (bnx2x_vf_mbx_is_windows_vm(bp, &mbx->msg->req.acquire)) | ||
1347 | vf->fp_hsi = acquire->vfdev_info.fp_hsi_ver; | ||
1348 | else | ||
1349 | vf->fp_hsi = max_t(u8, acquire->vfdev_info.fp_hsi_ver, | ||
1350 | ETH_FP_HSI_VER_2); | ||
1351 | if (vf->fp_hsi > ETH_FP_HSI_VERSION) { | ||
1352 | DP(BNX2X_MSG_IOV, | ||
1353 | "VF [%d] - Can't support acquire request since VF requests a FW version which is too new [%02x > %02x]\n", | ||
1354 | vf->abs_vfid, acquire->vfdev_info.fp_hsi_ver, | ||
1355 | ETH_FP_HSI_VERSION); | ||
1356 | rc = -EINVAL; | ||
1357 | goto out; | ||
1358 | } | ||
1359 | |||
1291 | /* acquire the resources */ | 1360 | /* acquire the resources */ |
1292 | rc = bnx2x_vf_acquire(bp, vf, &acquire->resc_request); | 1361 | rc = bnx2x_vf_acquire(bp, vf, &acquire->resc_request); |
1293 | 1362 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h index 15670c499a20..b86479fc0d2f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h | |||
@@ -124,7 +124,7 @@ struct vfpf_acquire_tlv { | |||
124 | #define VF_OS_UNDEFINED (0 << VF_OS_SHIFT) | 124 | #define VF_OS_UNDEFINED (0 << VF_OS_SHIFT) |
125 | #define VF_OS_WINDOWS (1 << VF_OS_SHIFT) | 125 | #define VF_OS_WINDOWS (1 << VF_OS_SHIFT) |
126 | 126 | ||
127 | u8 padding; | 127 | u8 fp_hsi_ver; |
128 | u8 caps; | 128 | u8 caps; |
129 | #define VF_CAP_SUPPORT_EXT_BULLETIN (1 << 0) | 129 | #define VF_CAP_SUPPORT_EXT_BULLETIN (1 << 0) |
130 | } vfdev_info; | 130 | } vfdev_info; |
@@ -204,6 +204,12 @@ struct vfpf_port_phys_id_resp_tlv { | |||
204 | u8 padding[2]; | 204 | u8 padding[2]; |
205 | }; | 205 | }; |
206 | 206 | ||
207 | struct vfpf_fp_hsi_resp_tlv { | ||
208 | struct channel_tlv tl; | ||
209 | u8 is_supported; | ||
210 | u8 padding[3]; | ||
211 | }; | ||
212 | |||
207 | #define VFPF_INIT_FLG_STATS_COALESCE (1 << 0) /* when set the VFs queues | 213 | #define VFPF_INIT_FLG_STATS_COALESCE (1 << 0) /* when set the VFs queues |
208 | * stats will be coalesced on | 214 | * stats will be coalesced on |
209 | * the leading RSS queue | 215 | * the leading RSS queue |
@@ -448,6 +454,7 @@ enum channel_tlvs { | |||
448 | CHANNEL_TLV_UPDATE_RSS, | 454 | CHANNEL_TLV_UPDATE_RSS, |
449 | CHANNEL_TLV_PHYS_PORT_ID, | 455 | CHANNEL_TLV_PHYS_PORT_ID, |
450 | CHANNEL_TLV_UPDATE_TPA, | 456 | CHANNEL_TLV_UPDATE_TPA, |
457 | CHANNEL_TLV_FP_HSI_SUPPORT, | ||
451 | CHANNEL_TLV_MAX | 458 | CHANNEL_TLV_MAX |
452 | }; | 459 | }; |
453 | 460 | ||