|
@@ -427,7 +427,9 @@ static int bnx2x_vf_mac_vlan_config(struct bnx2x *bp,
|
|
|
if (filter->add && filter->type == BNX2X_VF_FILTER_VLAN &&
|
|
|
(atomic_read(&bnx2x_vfq(vf, qid, vlan_count)) >=
|
|
|
vf_vlan_rules_cnt(vf))) {
|
|
|
- BNX2X_ERR("No credits for vlan\n");
|
|
|
+ BNX2X_ERR("No credits for vlan [%d >= %d]\n",
|
|
|
+ atomic_read(&bnx2x_vfq(vf, qid, vlan_count)),
|
|
|
+ vf_vlan_rules_cnt(vf));
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
|
|
@@ -610,6 +612,7 @@ int bnx2x_vf_mcast(struct bnx2x *bp, struct bnx2x_virtf *vf,
|
|
|
}
|
|
|
|
|
|
/* add new mcasts */
|
|
|
+ mcast.mcast_list_len = mc_num;
|
|
|
rc = bnx2x_config_mcast(bp, &mcast, BNX2X_MCAST_CMD_ADD);
|
|
|
if (rc)
|
|
|
BNX2X_ERR("Faled to add multicasts\n");
|
|
@@ -837,6 +840,29 @@ int bnx2x_vf_flr_clnup_epilog(struct bnx2x *bp, u8 abs_vfid)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static void bnx2x_iov_re_set_vlan_filters(struct bnx2x *bp,
|
|
|
+ struct bnx2x_virtf *vf,
|
|
|
+ int new)
|
|
|
+{
|
|
|
+ int num = vf_vlan_rules_cnt(vf);
|
|
|
+ int diff = new - num;
|
|
|
+ bool rc = true;
|
|
|
+
|
|
|
+ DP(BNX2X_MSG_IOV, "vf[%d] - %d vlan filter credits [previously %d]\n",
|
|
|
+ vf->abs_vfid, new, num);
|
|
|
+
|
|
|
+ if (diff > 0)
|
|
|
+ rc = bp->vlans_pool.get(&bp->vlans_pool, diff);
|
|
|
+ else if (diff < 0)
|
|
|
+ rc = bp->vlans_pool.put(&bp->vlans_pool, -diff);
|
|
|
+
|
|
|
+ if (rc)
|
|
|
+ vf_vlan_rules_cnt(vf) = new;
|
|
|
+ else
|
|
|
+ DP(BNX2X_MSG_IOV, "vf[%d] - Failed to configure vlan filter credits change\n",
|
|
|
+ vf->abs_vfid);
|
|
|
+}
|
|
|
+
|
|
|
/* must be called after the number of PF queues and the number of VFs are
|
|
|
* both known
|
|
|
*/
|
|
@@ -854,9 +880,11 @@ bnx2x_iov_static_resc(struct bnx2x *bp, struct bnx2x_virtf *vf)
|
|
|
resc->num_mac_filters = 1;
|
|
|
|
|
|
/* divvy up vlan rules */
|
|
|
+ bnx2x_iov_re_set_vlan_filters(bp, vf, 0);
|
|
|
vlan_count = bp->vlans_pool.check(&bp->vlans_pool);
|
|
|
vlan_count = 1 << ilog2(vlan_count);
|
|
|
- resc->num_vlan_filters = vlan_count / BNX2X_NR_VIRTFN(bp);
|
|
|
+ bnx2x_iov_re_set_vlan_filters(bp, vf,
|
|
|
+ vlan_count / BNX2X_NR_VIRTFN(bp));
|
|
|
|
|
|
/* no real limitation */
|
|
|
resc->num_mc_filters = 0;
|
|
@@ -1478,10 +1506,6 @@ int bnx2x_iov_nic_init(struct bnx2x *bp)
|
|
|
bnx2x_iov_static_resc(bp, vf);
|
|
|
|
|
|
/* queues are initialized during VF-ACQUIRE */
|
|
|
-
|
|
|
- /* reserve the vf vlan credit */
|
|
|
- bp->vlans_pool.get(&bp->vlans_pool, vf_vlan_rules_cnt(vf));
|
|
|
-
|
|
|
vf->filter_state = 0;
|
|
|
vf->sp_cl_id = bnx2x_fp(bp, 0, cl_id);
|
|
|
|
|
@@ -1912,11 +1936,12 @@ int bnx2x_vf_chk_avail_resc(struct bnx2x *bp, struct bnx2x_virtf *vf,
|
|
|
u8 rxq_cnt = vf_rxq_count(vf) ? : bnx2x_vf_max_queue_cnt(bp, vf);
|
|
|
u8 txq_cnt = vf_txq_count(vf) ? : bnx2x_vf_max_queue_cnt(bp, vf);
|
|
|
|
|
|
+ /* Save a vlan filter for the Hypervisor */
|
|
|
return ((req_resc->num_rxqs <= rxq_cnt) &&
|
|
|
(req_resc->num_txqs <= txq_cnt) &&
|
|
|
(req_resc->num_sbs <= vf_sb_count(vf)) &&
|
|
|
(req_resc->num_mac_filters <= vf_mac_rules_cnt(vf)) &&
|
|
|
- (req_resc->num_vlan_filters <= vf_vlan_rules_cnt(vf)));
|
|
|
+ (req_resc->num_vlan_filters <= vf_vlan_rules_visible_cnt(vf)));
|
|
|
}
|
|
|
|
|
|
/* CORE VF API */
|
|
@@ -1972,14 +1997,14 @@ int bnx2x_vf_acquire(struct bnx2x *bp, struct bnx2x_virtf *vf,
|
|
|
vf_txq_count(vf) = resc->num_txqs ? : bnx2x_vf_max_queue_cnt(bp, vf);
|
|
|
if (resc->num_mac_filters)
|
|
|
vf_mac_rules_cnt(vf) = resc->num_mac_filters;
|
|
|
- if (resc->num_vlan_filters)
|
|
|
- vf_vlan_rules_cnt(vf) = resc->num_vlan_filters;
|
|
|
+ /* Add an additional vlan filter credit for the hypervisor */
|
|
|
+ bnx2x_iov_re_set_vlan_filters(bp, vf, resc->num_vlan_filters + 1);
|
|
|
|
|
|
DP(BNX2X_MSG_IOV,
|
|
|
"Fulfilling vf request: sb count %d, tx_count %d, rx_count %d, mac_rules_count %d, vlan_rules_count %d\n",
|
|
|
vf_sb_count(vf), vf_rxq_count(vf),
|
|
|
vf_txq_count(vf), vf_mac_rules_cnt(vf),
|
|
|
- vf_vlan_rules_cnt(vf));
|
|
|
+ vf_vlan_rules_visible_cnt(vf));
|
|
|
|
|
|
/* Initialize the queues */
|
|
|
if (!vf->vfqs) {
|
|
@@ -2896,6 +2921,14 @@ void __iomem *bnx2x_vf_doorbells(struct bnx2x *bp)
|
|
|
return bp->regview + PXP_VF_ADDR_DB_START;
|
|
|
}
|
|
|
|
|
|
+void bnx2x_vf_pci_dealloc(struct bnx2x *bp)
|
|
|
+{
|
|
|
+ BNX2X_PCI_FREE(bp->vf2pf_mbox, bp->vf2pf_mbox_mapping,
|
|
|
+ sizeof(struct bnx2x_vf_mbx_msg));
|
|
|
+ BNX2X_PCI_FREE(bp->vf2pf_mbox, bp->pf2vf_bulletin_mapping,
|
|
|
+ sizeof(union pf_vf_bulletin));
|
|
|
+}
|
|
|
+
|
|
|
int bnx2x_vf_pci_alloc(struct bnx2x *bp)
|
|
|
{
|
|
|
mutex_init(&bp->vf2pf_mutex);
|
|
@@ -2915,10 +2948,7 @@ int bnx2x_vf_pci_alloc(struct bnx2x *bp)
|
|
|
return 0;
|
|
|
|
|
|
alloc_mem_err:
|
|
|
- BNX2X_PCI_FREE(bp->vf2pf_mbox, bp->vf2pf_mbox_mapping,
|
|
|
- sizeof(struct bnx2x_vf_mbx_msg));
|
|
|
- BNX2X_PCI_FREE(bp->vf2pf_mbox, bp->pf2vf_bulletin_mapping,
|
|
|
- sizeof(union pf_vf_bulletin));
|
|
|
+ bnx2x_vf_pci_dealloc(bp);
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
|