aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAriel Elior <ariele@broadcom.com>2013-01-01 00:22:40 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-02 04:45:07 -0500
commit99e9d211a40cdd12bda7f50c2014c2fbb8f386f5 (patch)
tree9e869e321d5940014a575154e1f86338e1ddb9bd /drivers
parent463a68a7734db3975c0d1c748f5fde713eb9a5b9 (diff)
bnx2x: Support of PF driver of a VF close request
The 'close' command is the opposite of an init request. Here the queues of the VF are closed (if any are opened) and released. This flow applies the 'q_teardown' flow on all the queues. The VF state is changed by this request. Interrupts are disabled for the VF when closed. 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')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c97
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h4
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c18
3 files changed, 119 insertions, 0 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
index 9fd43c079045..3dd3a6acdf57 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
@@ -139,6 +139,11 @@ enum bnx2x_vfop_mcast_state {
139 BNX2X_VFOP_MCAST_CHK_DONE 139 BNX2X_VFOP_MCAST_CHK_DONE
140}; 140};
141 141
142enum bnx2x_vfop_close_state {
143 BNX2X_VFOP_CLOSE_QUEUES,
144 BNX2X_VFOP_CLOSE_HW
145};
146
142enum bnx2x_vfop_rxmode_state { 147enum bnx2x_vfop_rxmode_state {
143 BNX2X_VFOP_RXMODE_CONFIG, 148 BNX2X_VFOP_RXMODE_CONFIG,
144 BNX2X_VFOP_RXMODE_DONE 149 BNX2X_VFOP_RXMODE_DONE
@@ -2300,6 +2305,28 @@ static void bnx2x_vf_qtbl_set_q(struct bnx2x *bp, u8 abs_vfid, u8 qid,
2300 REG_WR(bp, reg, val); 2305 REG_WR(bp, reg, val);
2301} 2306}
2302 2307
2308static void bnx2x_vf_clr_qtbl(struct bnx2x *bp, struct bnx2x_virtf *vf)
2309{
2310 int i;
2311
2312 for_each_vfq(vf, i)
2313 bnx2x_vf_qtbl_set_q(bp, vf->abs_vfid,
2314 vfq_qzone_id(vf, vfq_get(vf, i)), false);
2315}
2316
2317static void bnx2x_vf_igu_disable(struct bnx2x *bp, struct bnx2x_virtf *vf)
2318{
2319 u32 val;
2320
2321 /* clear the VF configuration - pretend */
2322 bnx2x_pretend_func(bp, HW_VF_HANDLE(bp, vf->abs_vfid));
2323 val = REG_RD(bp, IGU_REG_VF_CONFIGURATION);
2324 val &= ~(IGU_VF_CONF_MSI_MSIX_EN | IGU_VF_CONF_SINGLE_ISR_EN |
2325 IGU_VF_CONF_FUNC_EN | IGU_VF_CONF_PARENT_MASK);
2326 REG_WR(bp, IGU_REG_VF_CONFIGURATION, val);
2327 bnx2x_pretend_func(bp, BP_ABS_FUNC(bp));
2328}
2329
2303u8 bnx2x_vf_max_queue_cnt(struct bnx2x *bp, struct bnx2x_virtf *vf) 2330u8 bnx2x_vf_max_queue_cnt(struct bnx2x *bp, struct bnx2x_virtf *vf)
2304{ 2331{
2305 return min_t(u8, min_t(u8, vf_sb_count(vf), BNX2X_CIDS_PER_VF), 2332 return min_t(u8, min_t(u8, vf_sb_count(vf), BNX2X_CIDS_PER_VF),
@@ -2469,6 +2496,76 @@ int bnx2x_vf_init(struct bnx2x *bp, struct bnx2x_virtf *vf, dma_addr_t *sb_map)
2469 return 0; 2496 return 0;
2470} 2497}
2471 2498
2499/* VFOP close (teardown the queues, delete mcasts and close HW) */
2500static void bnx2x_vfop_close(struct bnx2x *bp, struct bnx2x_virtf *vf)
2501{
2502 struct bnx2x_vfop *vfop = bnx2x_vfop_cur(bp, vf);
2503 struct bnx2x_vfop_args_qx *qx = &vfop->args.qx;
2504 enum bnx2x_vfop_close_state state = vfop->state;
2505 struct bnx2x_vfop_cmd cmd = {
2506 .done = bnx2x_vfop_close,
2507 .block = false,
2508 };
2509
2510 if (vfop->rc < 0)
2511 goto op_err;
2512
2513 DP(BNX2X_MSG_IOV, "vf[%d] STATE: %d\n", vf->abs_vfid, state);
2514
2515 switch (state) {
2516 case BNX2X_VFOP_CLOSE_QUEUES:
2517
2518 if (++(qx->qid) < vf_rxq_count(vf)) {
2519 vfop->rc = bnx2x_vfop_qdown_cmd(bp, vf, &cmd, qx->qid);
2520 if (vfop->rc)
2521 goto op_err;
2522 return;
2523 }
2524
2525 /* remove multicasts */
2526 vfop->state = BNX2X_VFOP_CLOSE_HW;
2527 vfop->rc = bnx2x_vfop_mcast_cmd(bp, vf, &cmd, NULL, 0, false);
2528 if (vfop->rc)
2529 goto op_err;
2530 return;
2531
2532 case BNX2X_VFOP_CLOSE_HW:
2533
2534 /* disable the interrupts */
2535 DP(BNX2X_MSG_IOV, "disabling igu\n");
2536 bnx2x_vf_igu_disable(bp, vf);
2537
2538 /* disable the VF */
2539 DP(BNX2X_MSG_IOV, "clearing qtbl\n");
2540 bnx2x_vf_clr_qtbl(bp, vf);
2541
2542 goto op_done;
2543 default:
2544 bnx2x_vfop_default(state);
2545 }
2546op_err:
2547 BNX2X_ERR("VF[%d] CLOSE error: rc %d\n", vf->abs_vfid, vfop->rc);
2548op_done:
2549 vf->state = VF_ACQUIRED;
2550 DP(BNX2X_MSG_IOV, "set state to acquired\n");
2551 bnx2x_vfop_end(bp, vf, vfop);
2552}
2553
2554int bnx2x_vfop_close_cmd(struct bnx2x *bp,
2555 struct bnx2x_virtf *vf,
2556 struct bnx2x_vfop_cmd *cmd)
2557{
2558 struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf);
2559 if (vfop) {
2560 vfop->args.qx.qid = -1; /* loop */
2561 bnx2x_vfop_opset(BNX2X_VFOP_CLOSE_QUEUES,
2562 bnx2x_vfop_close, cmd->done);
2563 return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_close,
2564 cmd->block);
2565 }
2566 return -ENOMEM;
2567}
2568
2472void bnx2x_lock_vf_pf_channel(struct bnx2x *bp, struct bnx2x_virtf *vf, 2569void bnx2x_lock_vf_pf_channel(struct bnx2x *bp, struct bnx2x_virtf *vf,
2473 enum channel_tlvs tlv) 2570 enum channel_tlvs tlv)
2474{ 2571{
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
index 9f0099c543e0..d2a65d66c325 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
@@ -657,6 +657,10 @@ int bnx2x_vfop_rxmode_cmd(struct bnx2x *bp,
657 struct bnx2x_vfop_cmd *cmd, 657 struct bnx2x_vfop_cmd *cmd,
658 int qid, unsigned long accept_flags); 658 int qid, unsigned long accept_flags);
659 659
660int bnx2x_vfop_close_cmd(struct bnx2x *bp,
661 struct bnx2x_virtf *vf,
662 struct bnx2x_vfop_cmd *cmd);
663
660int bnx2x_vf_idx_by_abs_fid(struct bnx2x *bp, u16 abs_vfid); 664int bnx2x_vf_idx_by_abs_fid(struct bnx2x *bp, u16 abs_vfid);
661u8 bnx2x_vf_max_queue_cnt(struct bnx2x *bp, struct bnx2x_virtf *vf); 665u8 bnx2x_vf_max_queue_cnt(struct bnx2x *bp, struct bnx2x_virtf *vf);
662/* VF FLR helpers */ 666/* VF FLR helpers */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
index af30eb4a37bf..73368aa28e26 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
@@ -804,6 +804,21 @@ static void bnx2x_vf_mbx_teardown_q(struct bnx2x *bp, struct bnx2x_virtf *vf,
804 bnx2x_vf_mbx_resp(bp, vf); 804 bnx2x_vf_mbx_resp(bp, vf);
805} 805}
806 806
807static void bnx2x_vf_mbx_close_vf(struct bnx2x *bp, struct bnx2x_virtf *vf,
808 struct bnx2x_vf_mbx *mbx)
809{
810 struct bnx2x_vfop_cmd cmd = {
811 .done = bnx2x_vf_mbx_resp,
812 .block = false,
813 };
814
815 DP(BNX2X_MSG_IOV, "VF[%d] VF_CLOSE\n", vf->abs_vfid);
816
817 vf->op_rc = bnx2x_vfop_close_cmd(bp, vf, &cmd);
818 if (vf->op_rc)
819 bnx2x_vf_mbx_resp(bp, vf);
820}
821
807/* dispatch request */ 822/* dispatch request */
808static void bnx2x_vf_mbx_request(struct bnx2x *bp, struct bnx2x_virtf *vf, 823static void bnx2x_vf_mbx_request(struct bnx2x *bp, struct bnx2x_virtf *vf,
809 struct bnx2x_vf_mbx *mbx) 824 struct bnx2x_vf_mbx *mbx)
@@ -834,6 +849,9 @@ static void bnx2x_vf_mbx_request(struct bnx2x *bp, struct bnx2x_virtf *vf,
834 case CHANNEL_TLV_TEARDOWN_Q: 849 case CHANNEL_TLV_TEARDOWN_Q:
835 bnx2x_vf_mbx_teardown_q(bp, vf, mbx); 850 bnx2x_vf_mbx_teardown_q(bp, vf, mbx);
836 break; 851 break;
852 case CHANNEL_TLV_CLOSE:
853 bnx2x_vf_mbx_close_vf(bp, vf, mbx);
854 break;
837 } 855 }
838 856
839 } else { 857 } else {