aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuval Mintz <Yuval.Mintz@qlogic.com>2014-04-24 12:29:53 -0400
committerDavid S. Miller <davem@davemloft.net>2014-04-26 12:15:27 -0400
commit1a3d94240bc5e969e7e8cef661fbad24296ba36f (patch)
tree5ce6fccec942f80313703c7171e2938f85b5dbf9
parente2a367f8e3c2afd5cfd5f0892844c74960ecc031 (diff)
bnx2x: Fix vlan credit issues for VFs
Starting with commit 2dc33bbc "bnx2x: Remove the sriov VFOP mechanism", the bnx2x started enforcing vlan credits for all vlan configurations. This exposed 2 issues: - Vlan credits are not returned once a VF is removed; this causes a leak of credits, and eventually will lead to VFs with no vlan credits. - A vlan credit must be set aside for the Hypervisor to use, and should not be visible to the VF. Although linux VFs at the moment do not support vlan configuration [from the VF side] which causes them to be resilient to this sort of issue, Windows VF over linux hypervisors might fail to load as the vlan credits become depleted. 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>
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c44
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h2
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c2
3 files changed, 37 insertions, 11 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
index 046c9cca0072..eefe8f528309 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
@@ -427,7 +427,9 @@ static int bnx2x_vf_mac_vlan_config(struct bnx2x *bp,
427 if (filter->add && filter->type == BNX2X_VF_FILTER_VLAN && 427 if (filter->add && filter->type == BNX2X_VF_FILTER_VLAN &&
428 (atomic_read(&bnx2x_vfq(vf, qid, vlan_count)) >= 428 (atomic_read(&bnx2x_vfq(vf, qid, vlan_count)) >=
429 vf_vlan_rules_cnt(vf))) { 429 vf_vlan_rules_cnt(vf))) {
430 BNX2X_ERR("No credits for vlan\n"); 430 BNX2X_ERR("No credits for vlan [%d >= %d]\n",
431 atomic_read(&bnx2x_vfq(vf, qid, vlan_count)),
432 vf_vlan_rules_cnt(vf));
431 return -ENOMEM; 433 return -ENOMEM;
432 } 434 }
433 435
@@ -837,6 +839,29 @@ int bnx2x_vf_flr_clnup_epilog(struct bnx2x *bp, u8 abs_vfid)
837 return 0; 839 return 0;
838} 840}
839 841
842static void bnx2x_iov_re_set_vlan_filters(struct bnx2x *bp,
843 struct bnx2x_virtf *vf,
844 int new)
845{
846 int num = vf_vlan_rules_cnt(vf);
847 int diff = new - num;
848 bool rc = true;
849
850 DP(BNX2X_MSG_IOV, "vf[%d] - %d vlan filter credits [previously %d]\n",
851 vf->abs_vfid, new, num);
852
853 if (diff > 0)
854 rc = bp->vlans_pool.get(&bp->vlans_pool, diff);
855 else if (diff < 0)
856 rc = bp->vlans_pool.put(&bp->vlans_pool, -diff);
857
858 if (rc)
859 vf_vlan_rules_cnt(vf) = new;
860 else
861 DP(BNX2X_MSG_IOV, "vf[%d] - Failed to configure vlan filter credits change\n",
862 vf->abs_vfid);
863}
864
840/* must be called after the number of PF queues and the number of VFs are 865/* must be called after the number of PF queues and the number of VFs are
841 * both known 866 * both known
842 */ 867 */
@@ -854,9 +879,11 @@ bnx2x_iov_static_resc(struct bnx2x *bp, struct bnx2x_virtf *vf)
854 resc->num_mac_filters = 1; 879 resc->num_mac_filters = 1;
855 880
856 /* divvy up vlan rules */ 881 /* divvy up vlan rules */
882 bnx2x_iov_re_set_vlan_filters(bp, vf, 0);
857 vlan_count = bp->vlans_pool.check(&bp->vlans_pool); 883 vlan_count = bp->vlans_pool.check(&bp->vlans_pool);
858 vlan_count = 1 << ilog2(vlan_count); 884 vlan_count = 1 << ilog2(vlan_count);
859 resc->num_vlan_filters = vlan_count / BNX2X_NR_VIRTFN(bp); 885 bnx2x_iov_re_set_vlan_filters(bp, vf,
886 vlan_count / BNX2X_NR_VIRTFN(bp));
860 887
861 /* no real limitation */ 888 /* no real limitation */
862 resc->num_mc_filters = 0; 889 resc->num_mc_filters = 0;
@@ -1478,10 +1505,6 @@ int bnx2x_iov_nic_init(struct bnx2x *bp)
1478 bnx2x_iov_static_resc(bp, vf); 1505 bnx2x_iov_static_resc(bp, vf);
1479 1506
1480 /* queues are initialized during VF-ACQUIRE */ 1507 /* queues are initialized during VF-ACQUIRE */
1481
1482 /* reserve the vf vlan credit */
1483 bp->vlans_pool.get(&bp->vlans_pool, vf_vlan_rules_cnt(vf));
1484
1485 vf->filter_state = 0; 1508 vf->filter_state = 0;
1486 vf->sp_cl_id = bnx2x_fp(bp, 0, cl_id); 1509 vf->sp_cl_id = bnx2x_fp(bp, 0, cl_id);
1487 1510
@@ -1912,11 +1935,12 @@ int bnx2x_vf_chk_avail_resc(struct bnx2x *bp, struct bnx2x_virtf *vf,
1912 u8 rxq_cnt = vf_rxq_count(vf) ? : bnx2x_vf_max_queue_cnt(bp, vf); 1935 u8 rxq_cnt = vf_rxq_count(vf) ? : bnx2x_vf_max_queue_cnt(bp, vf);
1913 u8 txq_cnt = vf_txq_count(vf) ? : bnx2x_vf_max_queue_cnt(bp, vf); 1936 u8 txq_cnt = vf_txq_count(vf) ? : bnx2x_vf_max_queue_cnt(bp, vf);
1914 1937
1938 /* Save a vlan filter for the Hypervisor */
1915 return ((req_resc->num_rxqs <= rxq_cnt) && 1939 return ((req_resc->num_rxqs <= rxq_cnt) &&
1916 (req_resc->num_txqs <= txq_cnt) && 1940 (req_resc->num_txqs <= txq_cnt) &&
1917 (req_resc->num_sbs <= vf_sb_count(vf)) && 1941 (req_resc->num_sbs <= vf_sb_count(vf)) &&
1918 (req_resc->num_mac_filters <= vf_mac_rules_cnt(vf)) && 1942 (req_resc->num_mac_filters <= vf_mac_rules_cnt(vf)) &&
1919 (req_resc->num_vlan_filters <= vf_vlan_rules_cnt(vf))); 1943 (req_resc->num_vlan_filters <= vf_vlan_rules_visible_cnt(vf)));
1920} 1944}
1921 1945
1922/* CORE VF API */ 1946/* CORE VF API */
@@ -1972,14 +1996,14 @@ int bnx2x_vf_acquire(struct bnx2x *bp, struct bnx2x_virtf *vf,
1972 vf_txq_count(vf) = resc->num_txqs ? : bnx2x_vf_max_queue_cnt(bp, vf); 1996 vf_txq_count(vf) = resc->num_txqs ? : bnx2x_vf_max_queue_cnt(bp, vf);
1973 if (resc->num_mac_filters) 1997 if (resc->num_mac_filters)
1974 vf_mac_rules_cnt(vf) = resc->num_mac_filters; 1998 vf_mac_rules_cnt(vf) = resc->num_mac_filters;
1975 if (resc->num_vlan_filters) 1999 /* Add an additional vlan filter credit for the hypervisor */
1976 vf_vlan_rules_cnt(vf) = resc->num_vlan_filters; 2000 bnx2x_iov_re_set_vlan_filters(bp, vf, resc->num_vlan_filters + 1);
1977 2001
1978 DP(BNX2X_MSG_IOV, 2002 DP(BNX2X_MSG_IOV,
1979 "Fulfilling vf request: sb count %d, tx_count %d, rx_count %d, mac_rules_count %d, vlan_rules_count %d\n", 2003 "Fulfilling vf request: sb count %d, tx_count %d, rx_count %d, mac_rules_count %d, vlan_rules_count %d\n",
1980 vf_sb_count(vf), vf_rxq_count(vf), 2004 vf_sb_count(vf), vf_rxq_count(vf),
1981 vf_txq_count(vf), vf_mac_rules_cnt(vf), 2005 vf_txq_count(vf), vf_mac_rules_cnt(vf),
1982 vf_vlan_rules_cnt(vf)); 2006 vf_vlan_rules_visible_cnt(vf));
1983 2007
1984 /* Initialize the queues */ 2008 /* Initialize the queues */
1985 if (!vf->vfqs) { 2009 if (!vf->vfqs) {
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
index bb16c4b5c2af..6929adba52f9 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
@@ -159,6 +159,8 @@ struct bnx2x_virtf {
159#define vf_mac_rules_cnt(vf) ((vf)->alloc_resc.num_mac_filters) 159#define vf_mac_rules_cnt(vf) ((vf)->alloc_resc.num_mac_filters)
160#define vf_vlan_rules_cnt(vf) ((vf)->alloc_resc.num_vlan_filters) 160#define vf_vlan_rules_cnt(vf) ((vf)->alloc_resc.num_vlan_filters)
161#define vf_mc_rules_cnt(vf) ((vf)->alloc_resc.num_mc_filters) 161#define vf_mc_rules_cnt(vf) ((vf)->alloc_resc.num_mc_filters)
162 /* Hide a single vlan filter credit for the hypervisor */
163#define vf_vlan_rules_visible_cnt(vf) (vf_vlan_rules_cnt(vf) - 1)
162 164
163 u8 sb_count; /* actual number of SBs */ 165 u8 sb_count; /* actual number of SBs */
164 u8 igu_base_id; /* base igu status block id */ 166 u8 igu_base_id; /* base igu status block id */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
index 0622884596b2..0c067e8564dd 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
@@ -1163,7 +1163,7 @@ static void bnx2x_vf_mbx_acquire_resp(struct bnx2x *bp, struct bnx2x_virtf *vf,
1163 bnx2x_vf_max_queue_cnt(bp, vf); 1163 bnx2x_vf_max_queue_cnt(bp, vf);
1164 resc->num_sbs = vf_sb_count(vf); 1164 resc->num_sbs = vf_sb_count(vf);
1165 resc->num_mac_filters = vf_mac_rules_cnt(vf); 1165 resc->num_mac_filters = vf_mac_rules_cnt(vf);
1166 resc->num_vlan_filters = vf_vlan_rules_cnt(vf); 1166 resc->num_vlan_filters = vf_vlan_rules_visible_cnt(vf);
1167 resc->num_mc_filters = 0; 1167 resc->num_mc_filters = 0;
1168 1168
1169 if (status == PFVF_STATUS_SUCCESS) { 1169 if (status == PFVF_STATUS_SUCCESS) {