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:41 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-02 04:45:07 -0500
commitf1929b016c2161c364e45c21788aaae938ae557c (patch)
tree040f0a388de8572f298e163b7859268a25748931 /drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
parent99e9d211a40cdd12bda7f50c2014c2fbb8f386f5 (diff)
bnx2x: Support of PF driver of a VF release request
The 'release' request is the opposite of the 'acquire' request. At release, all the resources allocated to the VF are reclaimed. The release flow applies the close flow if applicable. Note that there are actually two types of release: 1. The VF has been removed, and so issued a 'release' request over the VF <-> PF Channel. 2. The PF is going down and so has to release all of it's VFs. 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.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
index 3dd3a6acdf57..71d0976b14d8 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
@@ -1422,6 +1422,14 @@ bnx2x_iov_static_resc(struct bnx2x *bp, struct vf_pf_resc_request *resc)
1422 /* num_sbs already set */ 1422 /* num_sbs already set */
1423} 1423}
1424 1424
1425/* FLR routines: */
1426static void bnx2x_vf_free_resc(struct bnx2x *bp, struct bnx2x_virtf *vf)
1427{
1428 /* reset the state variables */
1429 bnx2x_iov_static_resc(bp, &vf->alloc_resc);
1430 vf->state = VF_FREE;
1431}
1432
1425/* IOV global initialization routines */ 1433/* IOV global initialization routines */
1426void bnx2x_iov_init_dq(struct bnx2x *bp) 1434void bnx2x_iov_init_dq(struct bnx2x *bp)
1427{ 1435{
@@ -1947,6 +1955,21 @@ int bnx2x_iov_nic_init(struct bnx2x *bp)
1947 return 0; 1955 return 0;
1948} 1956}
1949 1957
1958/* called by bnx2x_chip_cleanup */
1959int bnx2x_iov_chip_cleanup(struct bnx2x *bp)
1960{
1961 int i;
1962
1963 if (!IS_SRIOV(bp))
1964 return 0;
1965
1966 /* release all the VFs */
1967 for_each_vf(bp, i)
1968 bnx2x_vf_release(bp, BP_VF(bp, i), true); /* blocking */
1969
1970 return 0;
1971}
1972
1950/* called by bnx2x_init_hw_func, returns the next ilt line */ 1973/* called by bnx2x_init_hw_func, returns the next ilt line */
1951int bnx2x_iov_init_ilt(struct bnx2x *bp, u16 line) 1974int bnx2x_iov_init_ilt(struct bnx2x *bp, u16 line)
1952{ 1975{
@@ -2566,6 +2589,106 @@ int bnx2x_vfop_close_cmd(struct bnx2x *bp,
2566 return -ENOMEM; 2589 return -ENOMEM;
2567} 2590}
2568 2591
2592/* VF release can be called either: 1. the VF was acquired but
2593 * not enabled 2. the vf was enabled or in the process of being
2594 * enabled
2595 */
2596static void bnx2x_vfop_release(struct bnx2x *bp, struct bnx2x_virtf *vf)
2597{
2598 struct bnx2x_vfop *vfop = bnx2x_vfop_cur(bp, vf);
2599 struct bnx2x_vfop_cmd cmd = {
2600 .done = bnx2x_vfop_release,
2601 .block = false,
2602 };
2603
2604 DP(BNX2X_MSG_IOV, "vfop->rc %d\n", vfop->rc);
2605
2606 if (vfop->rc < 0)
2607 goto op_err;
2608
2609 DP(BNX2X_MSG_IOV, "VF[%d] STATE: %s\n", vf->abs_vfid,
2610 vf->state == VF_FREE ? "Free" :
2611 vf->state == VF_ACQUIRED ? "Acquired" :
2612 vf->state == VF_ENABLED ? "Enabled" :
2613 vf->state == VF_RESET ? "Reset" :
2614 "Unknown");
2615
2616 switch (vf->state) {
2617 case VF_ENABLED:
2618 vfop->rc = bnx2x_vfop_close_cmd(bp, vf, &cmd);
2619 if (vfop->rc)
2620 goto op_err;
2621 return;
2622
2623 case VF_ACQUIRED:
2624 DP(BNX2X_MSG_IOV, "about to free resources\n");
2625 bnx2x_vf_free_resc(bp, vf);
2626 DP(BNX2X_MSG_IOV, "vfop->rc %d\n", vfop->rc);
2627 goto op_done;
2628
2629 case VF_FREE:
2630 case VF_RESET:
2631 /* do nothing */
2632 goto op_done;
2633 default:
2634 bnx2x_vfop_default(vf->state);
2635 }
2636op_err:
2637 BNX2X_ERR("VF[%d] RELEASE error: rc %d\n", vf->abs_vfid, vfop->rc);
2638op_done:
2639 bnx2x_vfop_end(bp, vf, vfop);
2640}
2641
2642int bnx2x_vfop_release_cmd(struct bnx2x *bp,
2643 struct bnx2x_virtf *vf,
2644 struct bnx2x_vfop_cmd *cmd)
2645{
2646 struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf);
2647 if (vfop) {
2648 bnx2x_vfop_opset(-1, /* use vf->state */
2649 bnx2x_vfop_release, cmd->done);
2650 return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_release,
2651 cmd->block);
2652 }
2653 return -ENOMEM;
2654}
2655
2656/* VF release ~ VF close + VF release-resources
2657 * Release is the ultimate SW shutdown and is called whenever an
2658 * irrecoverable error is encountered.
2659 */
2660void bnx2x_vf_release(struct bnx2x *bp, struct bnx2x_virtf *vf, bool block)
2661{
2662 struct bnx2x_vfop_cmd cmd = {
2663 .done = NULL,
2664 .block = block,
2665 };
2666 int rc;
2667 bnx2x_lock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_RELEASE_VF);
2668
2669 rc = bnx2x_vfop_release_cmd(bp, vf, &cmd);
2670 if (rc)
2671 WARN(rc,
2672 "VF[%d] Failed to allocate resources for release op- rc=%d\n",
2673 vf->abs_vfid, rc);
2674}
2675
2676static inline void bnx2x_vf_get_sbdf(struct bnx2x *bp,
2677 struct bnx2x_virtf *vf, u32 *sbdf)
2678{
2679 *sbdf = vf->devfn | (vf->bus << 8);
2680}
2681
2682static inline void bnx2x_vf_get_bars(struct bnx2x *bp, struct bnx2x_virtf *vf,
2683 struct bnx2x_vf_bar_info *bar_info)
2684{
2685 int n;
2686
2687 bar_info->nr_bars = bp->vfdb->sriov.nres;
2688 for (n = 0; n < bar_info->nr_bars; n++)
2689 bar_info->bars[n] = vf->bars[n];
2690}
2691
2569void bnx2x_lock_vf_pf_channel(struct bnx2x *bp, struct bnx2x_virtf *vf, 2692void bnx2x_lock_vf_pf_channel(struct bnx2x *bp, struct bnx2x_virtf *vf,
2570 enum channel_tlvs tlv) 2693 enum channel_tlvs tlv)
2571{ 2694{