aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
diff options
context:
space:
mode:
authorAriel Elior <ariele@broadcom.com>2013-01-01 00:22:35 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-02 04:45:06 -0500
commitb93288d5e7efc57628c59fe3f1844fb87982b409 (patch)
treebf97f3de00393a948d3d4a27f0c9ce267b2daa7b /drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
parent8ca5e17e58c953b9a9dbd4974c554b25c6d70b1a (diff)
bnx2x: Support of PF driver of a VF init request
The VF driver will send an 'init' request as part of its nic load flow. This message is used by the VF to publish the GPA's of its status blocks, slow path ring and statistics buffer. The PF driver notes all this down in the VF database, and also uses this message to transfer the VF to VF_INIT state internally. Signed-off-by: Ariel Elior <ariele@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c159
1 files changed, 159 insertions, 0 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
index de42f665c1fa..14e49bc455df 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
@@ -66,6 +66,41 @@ struct bnx2x_virtf *bnx2x_vf_by_abs_fid(struct bnx2x *bp, u16 abs_vfid)
66 return (idx < BNX2X_NR_VIRTFN(bp)) ? BP_VF(bp, idx) : NULL; 66 return (idx < BNX2X_NR_VIRTFN(bp)) ? BP_VF(bp, idx) : NULL;
67} 67}
68 68
69static void bnx2x_vf_igu_ack_sb(struct bnx2x *bp, struct bnx2x_virtf *vf,
70 u8 igu_sb_id, u8 segment, u16 index, u8 op,
71 u8 update)
72{
73 /* acking a VF sb through the PF - use the GRC */
74 u32 ctl;
75 u32 igu_addr_data = IGU_REG_COMMAND_REG_32LSB_DATA;
76 u32 igu_addr_ctl = IGU_REG_COMMAND_REG_CTRL;
77 u32 func_encode = vf->abs_vfid;
78 u32 addr_encode = IGU_CMD_E2_PROD_UPD_BASE + igu_sb_id;
79 struct igu_regular cmd_data = {0};
80
81 cmd_data.sb_id_and_flags =
82 ((index << IGU_REGULAR_SB_INDEX_SHIFT) |
83 (segment << IGU_REGULAR_SEGMENT_ACCESS_SHIFT) |
84 (update << IGU_REGULAR_BUPDATE_SHIFT) |
85 (op << IGU_REGULAR_ENABLE_INT_SHIFT));
86
87 ctl = addr_encode << IGU_CTRL_REG_ADDRESS_SHIFT |
88 func_encode << IGU_CTRL_REG_FID_SHIFT |
89 IGU_CTRL_CMD_TYPE_WR << IGU_CTRL_REG_TYPE_SHIFT;
90
91 DP(NETIF_MSG_HW, "write 0x%08x to IGU(via GRC) addr 0x%x\n",
92 cmd_data.sb_id_and_flags, igu_addr_data);
93 REG_WR(bp, igu_addr_data, cmd_data.sb_id_and_flags);
94 mmiowb();
95 barrier();
96
97 DP(NETIF_MSG_HW, "write 0x%08x to IGU(via GRC) addr 0x%x\n",
98 ctl, igu_addr_ctl);
99 REG_WR(bp, igu_addr_ctl, ctl);
100 mmiowb();
101 barrier();
102}
103
69static int bnx2x_ari_enabled(struct pci_dev *dev) 104static int bnx2x_ari_enabled(struct pci_dev *dev)
70{ 105{
71 return dev->bus->self && dev->bus->self->ari_enabled; 106 return dev->bus->self && dev->bus->self->ari_enabled;
@@ -364,6 +399,52 @@ static void bnx2x_vf_pglue_clear_err(struct bnx2x *bp, u8 abs_vfid)
364 REG_WR(bp, was_err_reg, 1 << (abs_vfid & 0x1f)); 399 REG_WR(bp, was_err_reg, 1 << (abs_vfid & 0x1f));
365} 400}
366 401
402static void bnx2x_vf_igu_reset(struct bnx2x *bp, struct bnx2x_virtf *vf)
403{
404 int i;
405 u32 val;
406
407 /* Set VF masks and configuration - pretend */
408 bnx2x_pretend_func(bp, HW_VF_HANDLE(bp, vf->abs_vfid));
409
410 REG_WR(bp, IGU_REG_SB_INT_BEFORE_MASK_LSB, 0);
411 REG_WR(bp, IGU_REG_SB_INT_BEFORE_MASK_MSB, 0);
412 REG_WR(bp, IGU_REG_SB_MASK_LSB, 0);
413 REG_WR(bp, IGU_REG_SB_MASK_MSB, 0);
414 REG_WR(bp, IGU_REG_PBA_STATUS_LSB, 0);
415 REG_WR(bp, IGU_REG_PBA_STATUS_MSB, 0);
416
417 val = REG_RD(bp, IGU_REG_VF_CONFIGURATION);
418 val |= (IGU_VF_CONF_FUNC_EN | IGU_VF_CONF_MSI_MSIX_EN);
419 if (vf->cfg_flags & VF_CFG_INT_SIMD)
420 val |= IGU_VF_CONF_SINGLE_ISR_EN;
421 val &= ~IGU_VF_CONF_PARENT_MASK;
422 val |= BP_FUNC(bp) << IGU_VF_CONF_PARENT_SHIFT; /* parent PF */
423 REG_WR(bp, IGU_REG_VF_CONFIGURATION, val);
424
425 DP(BNX2X_MSG_IOV,
426 "value in IGU_REG_VF_CONFIGURATION of vf %d after write %x\n",
427 vf->abs_vfid, REG_RD(bp, IGU_REG_VF_CONFIGURATION));
428
429 bnx2x_pretend_func(bp, BP_ABS_FUNC(bp));
430
431 /* iterate over all queues, clear sb consumer */
432 for (i = 0; i < vf_sb_count(vf); i++) {
433 u8 igu_sb_id = vf_igu_sb(vf, i);
434
435 /* zero prod memory */
436 REG_WR(bp, IGU_REG_PROD_CONS_MEMORY + igu_sb_id * 4, 0);
437
438 /* clear sb state machine */
439 bnx2x_igu_clear_sb_gen(bp, vf->abs_vfid, igu_sb_id,
440 false /* VF */);
441
442 /* disable + update */
443 bnx2x_vf_igu_ack_sb(bp, vf, igu_sb_id, USTORM_ID, 0,
444 IGU_INT_DISABLE, 1);
445 }
446}
447
367void bnx2x_vf_enable_access(struct bnx2x *bp, u8 abs_vfid) 448void bnx2x_vf_enable_access(struct bnx2x *bp, u8 abs_vfid)
368{ 449{
369 /* set the VF-PF association in the FW */ 450 /* set the VF-PF association in the FW */
@@ -381,6 +462,17 @@ void bnx2x_vf_enable_access(struct bnx2x *bp, u8 abs_vfid)
381 bnx2x_pretend_func(bp, BP_ABS_FUNC(bp)); 462 bnx2x_pretend_func(bp, BP_ABS_FUNC(bp));
382} 463}
383 464
465static void bnx2x_vf_enable_traffic(struct bnx2x *bp, struct bnx2x_virtf *vf)
466{
467 /* Reset vf in IGU interrupts are still disabled */
468 bnx2x_vf_igu_reset(bp, vf);
469
470 /* pretend to enable the vf with the PBF */
471 bnx2x_pretend_func(bp, HW_VF_HANDLE(bp, vf->abs_vfid));
472 REG_WR(bp, PBF_REG_DISABLE_VF, 0);
473 bnx2x_pretend_func(bp, BP_ABS_FUNC(bp));
474}
475
384static u8 bnx2x_vf_is_pcie_pending(struct bnx2x *bp, u8 abs_vfid) 476static u8 bnx2x_vf_is_pcie_pending(struct bnx2x *bp, u8 abs_vfid)
385{ 477{
386 struct pci_dev *dev; 478 struct pci_dev *dev;
@@ -997,6 +1089,14 @@ void bnx2x_iov_sp_task(struct bnx2x *bp)
997 } 1089 }
998 } 1090 }
999} 1091}
1092static void bnx2x_vf_qtbl_set_q(struct bnx2x *bp, u8 abs_vfid, u8 qid,
1093 u8 enable)
1094{
1095 u32 reg = PXP_REG_HST_ZONE_PERMISSION_TABLE + qid * 4;
1096 u32 val = enable ? (abs_vfid | (1 << 6)) : 0;
1097
1098 REG_WR(bp, reg, val);
1099}
1000 1100
1001u8 bnx2x_vf_max_queue_cnt(struct bnx2x *bp, struct bnx2x_virtf *vf) 1101u8 bnx2x_vf_max_queue_cnt(struct bnx2x *bp, struct bnx2x_virtf *vf)
1002{ 1102{
@@ -1108,6 +1208,65 @@ int bnx2x_vf_acquire(struct bnx2x *bp, struct bnx2x_virtf *vf,
1108 return 0; 1208 return 0;
1109} 1209}
1110 1210
1211int bnx2x_vf_init(struct bnx2x *bp, struct bnx2x_virtf *vf, dma_addr_t *sb_map)
1212{
1213 struct bnx2x_func_init_params func_init = {0};
1214 u16 flags = 0;
1215 int i;
1216
1217 /* the sb resources are initialized at this point, do the
1218 * FW/HW initializations
1219 */
1220 for_each_vf_sb(vf, i)
1221 bnx2x_init_sb(bp, (dma_addr_t)sb_map[i], vf->abs_vfid, true,
1222 vf_igu_sb(vf, i), vf_igu_sb(vf, i));
1223
1224 /* Sanity checks */
1225 if (vf->state != VF_ACQUIRED) {
1226 DP(BNX2X_MSG_IOV, "VF[%d] is not in VF_ACQUIRED, but %d\n",
1227 vf->abs_vfid, vf->state);
1228 return -EINVAL;
1229 }
1230 /* FLR cleanup epilogue */
1231 if (bnx2x_vf_flr_clnup_epilog(bp, vf->abs_vfid))
1232 return -EBUSY;
1233
1234 /* reset IGU VF statistics: MSIX */
1235 REG_WR(bp, IGU_REG_STATISTIC_NUM_MESSAGE_SENT + vf->abs_vfid * 4 , 0);
1236
1237 /* vf init */
1238 if (vf->cfg_flags & VF_CFG_STATS)
1239 flags |= (FUNC_FLG_STATS | FUNC_FLG_SPQ);
1240
1241 if (vf->cfg_flags & VF_CFG_TPA)
1242 flags |= FUNC_FLG_TPA;
1243
1244 if (is_vf_multi(vf))
1245 flags |= FUNC_FLG_RSS;
1246
1247 /* function setup */
1248 func_init.func_flgs = flags;
1249 func_init.pf_id = BP_FUNC(bp);
1250 func_init.func_id = FW_VF_HANDLE(vf->abs_vfid);
1251 func_init.fw_stat_map = vf->fw_stat_map;
1252 func_init.spq_map = vf->spq_map;
1253 func_init.spq_prod = 0;
1254 bnx2x_func_init(bp, &func_init);
1255
1256 /* Enable the vf */
1257 bnx2x_vf_enable_access(bp, vf->abs_vfid);
1258 bnx2x_vf_enable_traffic(bp, vf);
1259
1260 /* queue protection table */
1261 for_each_vfq(vf, i)
1262 bnx2x_vf_qtbl_set_q(bp, vf->abs_vfid,
1263 vfq_qzone_id(vf, vfq_get(vf, i)), true);
1264
1265 vf->state = VF_ENABLED;
1266
1267 return 0;
1268}
1269
1111void bnx2x_lock_vf_pf_channel(struct bnx2x *bp, struct bnx2x_virtf *vf, 1270void bnx2x_lock_vf_pf_channel(struct bnx2x *bp, struct bnx2x_virtf *vf,
1112 enum channel_tlvs tlv) 1271 enum channel_tlvs tlv)
1113{ 1272{