aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
diff options
context:
space:
mode:
authorAriel Elior <ariele@broadcom.com>2013-01-01 00:22:43 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-02 04:45:07 -0500
commitabc5a021ba645cd162205209bd5664a0d4b866a6 (patch)
tree8dafb2e16c204c01f7387f454d32c40ae8c2e00f /drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
parentd16132cef8a72ff7563aff95f03bf505779fe3e6 (diff)
bnx2x: Support PF <-> VF Bulletin Board
The PF <-> VF Bulletin Board is a simple interface between the PF and the VF. The main reason for the Bulletin Board is to allow the PF to be the initiator. The VF publishes at 'acquire' stage the GPA of a Bulletin Board structure it has allocated. The PF notes this GPA in the VF database. The VF samples the Bulletin Board periodically for new messages. The latest version of the BB is always used. 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_vfpf.c')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
index ba8b95d016b0..b410b9fff209 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
@@ -297,6 +297,10 @@ static void bnx2x_vf_mbx_acquire_resp(struct bnx2x *bp, struct bnx2x_virtf *vf,
297 resc->num_mc_filters = 0; 297 resc->num_mc_filters = 0;
298 298
299 if (status == PFVF_STATUS_SUCCESS) { 299 if (status == PFVF_STATUS_SUCCESS) {
300 /* fill in the allocated resources */
301 struct pf_vf_bulletin_content *bulletin =
302 BP_VF_BULLETIN(bp, vf->index);
303
300 for_each_vfq(vf, i) 304 for_each_vfq(vf, i)
301 resc->hw_qid[i] = 305 resc->hw_qid[i] =
302 vfq_qzone_id(vf, vfq_get(vf, i)); 306 vfq_qzone_id(vf, vfq_get(vf, i));
@@ -305,6 +309,12 @@ static void bnx2x_vf_mbx_acquire_resp(struct bnx2x *bp, struct bnx2x_virtf *vf,
305 resc->hw_sbs[i].hw_sb_id = vf_igu_sb(vf, i); 309 resc->hw_sbs[i].hw_sb_id = vf_igu_sb(vf, i);
306 resc->hw_sbs[i].sb_qid = vf_hc_qzone(vf, i); 310 resc->hw_sbs[i].sb_qid = vf_hc_qzone(vf, i);
307 } 311 }
312
313 /* if a mac has been set for this vf, supply it */
314 if (bulletin->valid_bitmap & 1 << MAC_ADDR_VALID) {
315 memcpy(resc->current_mac_addr, bulletin->mac,
316 ETH_ALEN);
317 }
308 } 318 }
309 } 319 }
310 320
@@ -356,6 +366,9 @@ static void bnx2x_vf_mbx_acquire(struct bnx2x *bp, struct bnx2x_virtf *vf,
356 /* acquire the resources */ 366 /* acquire the resources */
357 rc = bnx2x_vf_acquire(bp, vf, &acquire->resc_request); 367 rc = bnx2x_vf_acquire(bp, vf, &acquire->resc_request);
358 368
369 /* store address of vf's bulletin board */
370 vf->bulletin_map = acquire->bulletin_addr;
371
359 /* response */ 372 /* response */
360 bnx2x_vf_mbx_acquire_resp(bp, vf, mbx, rc); 373 bnx2x_vf_mbx_acquire_resp(bp, vf, mbx, rc);
361} 374}
@@ -766,11 +779,37 @@ static void bnx2x_vf_mbx_set_q_filters(struct bnx2x *bp,
766 struct bnx2x_vf_mbx *mbx) 779 struct bnx2x_vf_mbx *mbx)
767{ 780{
768 struct vfpf_set_q_filters_tlv *filters = &mbx->msg->req.set_q_filters; 781 struct vfpf_set_q_filters_tlv *filters = &mbx->msg->req.set_q_filters;
782 struct pf_vf_bulletin_content *bulletin = BP_VF_BULLETIN(bp, vf->index);
769 struct bnx2x_vfop_cmd cmd = { 783 struct bnx2x_vfop_cmd cmd = {
770 .done = bnx2x_vf_mbx_resp, 784 .done = bnx2x_vf_mbx_resp,
771 .block = false, 785 .block = false,
772 }; 786 };
773 787
788 /* if a mac was already set for this VF via the set vf mac ndo, we only
789 * accept mac configurations of that mac. Why accept them at all?
790 * because PF may have been unable to configure the mac at the time
791 * since queue was not set up.
792 */
793 if (bulletin->valid_bitmap & 1 << MAC_ADDR_VALID) {
794 /* once a mac was set by ndo can only accept a single mac... */
795 if (filters->n_mac_vlan_filters > 1) {
796 BNX2X_ERR("VF[%d] requested the addition of multiple macs after set_vf_mac ndo was called\n",
797 vf->abs_vfid);
798 vf->op_rc = -EPERM;
799 goto response;
800 }
801
802 /* ...and only the mac set by the ndo */
803 if (filters->n_mac_vlan_filters == 1 &&
804 memcmp(filters->filters->mac, bulletin->mac, ETH_ALEN)) {
805 BNX2X_ERR("VF[%d] requested the addition of a mac address not matching the one configured by set_vf_mac ndo\n",
806 vf->abs_vfid);
807
808 vf->op_rc = -EPERM;
809 goto response;
810 }
811 }
812
774 /* verify vf_qid */ 813 /* verify vf_qid */
775 if (filters->vf_qid > vf_rxq_count(vf)) 814 if (filters->vf_qid > vf_rxq_count(vf))
776 goto response; 815 goto response;
@@ -968,3 +1007,29 @@ mbx_error:
968mbx_done: 1007mbx_done:
969 return; 1008 return;
970} 1009}
1010
1011/* propagate local bulletin board to vf */
1012int bnx2x_post_vf_bulletin(struct bnx2x *bp, int vf)
1013{
1014 struct pf_vf_bulletin_content *bulletin = BP_VF_BULLETIN(bp, vf);
1015 dma_addr_t pf_addr = BP_VF_BULLETIN_DMA(bp)->mapping +
1016 vf * BULLETIN_CONTENT_SIZE;
1017 dma_addr_t vf_addr = bnx2x_vf(bp, vf, bulletin_map);
1018 u32 len = BULLETIN_CONTENT_SIZE;
1019 int rc;
1020
1021 /* can only update vf after init took place */
1022 if (bnx2x_vf(bp, vf, state) != VF_ENABLED &&
1023 bnx2x_vf(bp, vf, state) != VF_ACQUIRED)
1024 return 0;
1025
1026 /* increment bulletin board version and compute crc */
1027 bulletin->version++;
1028 bulletin->crc = bnx2x_crc_vf_bulletin(bp, bulletin);
1029
1030 /* propagate bulletin board via dmae to vm memory */
1031 rc = bnx2x_copy32_vf_dmae(bp, false, pf_addr,
1032 bnx2x_vf(bp, vf, abs_vfid), U64_HI(vf_addr),
1033 U64_LO(vf_addr), len/4);
1034 return rc;
1035}