Commit 3a3534ec authored by Yuval Mintz's avatar Yuval Mintz Committed by David S. Miller

bnx2x: Revise IOV vlan/mac validation

There are several places in IOV related flows where PF needs to determine
whether a VF slowpath elements have already been configured (i.e., this
affect its ability to configure/remove classifications for the VF).

This patch changes the conditions for the validation and performs a cleaner
validation (e.g., by replacing several validations with a single one).
Signed-off-by: default avatarYuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: default avatarAriel Elior <ariele@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 14a94ebd
...@@ -4158,16 +4158,6 @@ void bnx2x_init_rss_config_obj(struct bnx2x *bp, ...@@ -4158,16 +4158,6 @@ void bnx2x_init_rss_config_obj(struct bnx2x *bp,
rss_obj->config_rss = bnx2x_setup_rss; rss_obj->config_rss = bnx2x_setup_rss;
} }
int validate_vlan_mac(struct bnx2x *bp,
struct bnx2x_vlan_mac_obj *vlan_mac)
{
if (!vlan_mac->get_n_elements) {
BNX2X_ERR("vlan mac object was not intialized\n");
return -EINVAL;
}
return 0;
}
/********************** Queue state object ***********************************/ /********************** Queue state object ***********************************/
/** /**
......
...@@ -1422,6 +1422,4 @@ int bnx2x_config_rss(struct bnx2x *bp, ...@@ -1422,6 +1422,4 @@ int bnx2x_config_rss(struct bnx2x *bp,
void bnx2x_get_rss_ind_table(struct bnx2x_rss_config_obj *rss_obj, void bnx2x_get_rss_ind_table(struct bnx2x_rss_config_obj *rss_obj,
u8 *ind_table); u8 *ind_table);
int validate_vlan_mac(struct bnx2x *bp,
struct bnx2x_vlan_mac_obj *vlan_mac);
#endif /* BNX2X_SP_VERBS */ #endif /* BNX2X_SP_VERBS */
...@@ -102,6 +102,21 @@ static void bnx2x_vf_igu_ack_sb(struct bnx2x *bp, struct bnx2x_virtf *vf, ...@@ -102,6 +102,21 @@ static void bnx2x_vf_igu_ack_sb(struct bnx2x *bp, struct bnx2x_virtf *vf,
mmiowb(); mmiowb();
barrier(); barrier();
} }
static bool bnx2x_validate_vf_sp_objs(struct bnx2x *bp,
struct bnx2x_virtf *vf,
bool print_err)
{
if (!bnx2x_leading_vfq(vf, sp_initialized)) {
if (print_err)
BNX2X_ERR("Slowpath objects not yet initialized!\n");
else
DP(BNX2X_MSG_IOV, "Slowpath objects not yet initialized!\n");
return false;
}
return true;
}
/* VFOP - VF slow-path operation support */ /* VFOP - VF slow-path operation support */
#define BNX2X_VFOP_FILTER_ADD_CNT_MAX 0x10000 #define BNX2X_VFOP_FILTER_ADD_CNT_MAX 0x10000
...@@ -721,7 +736,6 @@ static int bnx2x_vfop_mac_delall_cmd(struct bnx2x *bp, ...@@ -721,7 +736,6 @@ static int bnx2x_vfop_mac_delall_cmd(struct bnx2x *bp,
int qid, bool drv_only) int qid, bool drv_only)
{ {
struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf); struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf);
int rc;
if (vfop) { if (vfop) {
struct bnx2x_vfop_args_filters filters = { struct bnx2x_vfop_args_filters filters = {
...@@ -741,9 +755,6 @@ static int bnx2x_vfop_mac_delall_cmd(struct bnx2x *bp, ...@@ -741,9 +755,6 @@ static int bnx2x_vfop_mac_delall_cmd(struct bnx2x *bp,
bnx2x_vfop_mac_prep_ramrod(ramrod, &flags); bnx2x_vfop_mac_prep_ramrod(ramrod, &flags);
/* set object */ /* set object */
rc = validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, mac_obj));
if (rc)
return rc;
ramrod->vlan_mac_obj = &bnx2x_vfq(vf, qid, mac_obj); ramrod->vlan_mac_obj = &bnx2x_vfq(vf, qid, mac_obj);
/* set extra args */ /* set extra args */
...@@ -763,9 +774,12 @@ int bnx2x_vfop_mac_list_cmd(struct bnx2x *bp, ...@@ -763,9 +774,12 @@ int bnx2x_vfop_mac_list_cmd(struct bnx2x *bp,
struct bnx2x_vfop_filters *macs, struct bnx2x_vfop_filters *macs,
int qid, bool drv_only) int qid, bool drv_only)
{ {
struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf); struct bnx2x_vfop *vfop;
int rc;
if (!bnx2x_validate_vf_sp_objs(bp, vf, true))
return -EINVAL;
vfop = bnx2x_vfop_add(bp, vf);
if (vfop) { if (vfop) {
struct bnx2x_vfop_args_filters filters = { struct bnx2x_vfop_args_filters filters = {
.multi_filter = macs, .multi_filter = macs,
...@@ -787,9 +801,6 @@ int bnx2x_vfop_mac_list_cmd(struct bnx2x *bp, ...@@ -787,9 +801,6 @@ int bnx2x_vfop_mac_list_cmd(struct bnx2x *bp,
bnx2x_vfop_mac_prep_ramrod(ramrod, &flags); bnx2x_vfop_mac_prep_ramrod(ramrod, &flags);
/* set object */ /* set object */
rc = validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, mac_obj));
if (rc)
return rc;
ramrod->vlan_mac_obj = &bnx2x_vfq(vf, qid, mac_obj); ramrod->vlan_mac_obj = &bnx2x_vfq(vf, qid, mac_obj);
/* set extra args */ /* set extra args */
...@@ -809,9 +820,12 @@ static int bnx2x_vfop_vlan_set_cmd(struct bnx2x *bp, ...@@ -809,9 +820,12 @@ static int bnx2x_vfop_vlan_set_cmd(struct bnx2x *bp,
struct bnx2x_vfop_cmd *cmd, struct bnx2x_vfop_cmd *cmd,
int qid, u16 vid, bool add) int qid, u16 vid, bool add)
{ {
struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf); struct bnx2x_vfop *vfop;
int rc;
if (!bnx2x_validate_vf_sp_objs(bp, vf, true))
return -EINVAL;
vfop = bnx2x_vfop_add(bp, vf);
if (vfop) { if (vfop) {
struct bnx2x_vfop_args_filters filters = { struct bnx2x_vfop_args_filters filters = {
.multi_filter = NULL, /* single command */ .multi_filter = NULL, /* single command */
...@@ -831,9 +845,6 @@ static int bnx2x_vfop_vlan_set_cmd(struct bnx2x *bp, ...@@ -831,9 +845,6 @@ static int bnx2x_vfop_vlan_set_cmd(struct bnx2x *bp,
ramrod->user_req.u.vlan.vlan = vid; ramrod->user_req.u.vlan.vlan = vid;
/* set object */ /* set object */
rc = validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, vlan_obj));
if (rc)
return rc;
ramrod->vlan_mac_obj = &bnx2x_vfq(vf, qid, vlan_obj); ramrod->vlan_mac_obj = &bnx2x_vfq(vf, qid, vlan_obj);
/* set extra args */ /* set extra args */
...@@ -853,7 +864,6 @@ static int bnx2x_vfop_vlan_delall_cmd(struct bnx2x *bp, ...@@ -853,7 +864,6 @@ static int bnx2x_vfop_vlan_delall_cmd(struct bnx2x *bp,
int qid, bool drv_only) int qid, bool drv_only)
{ {
struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf); struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf);
int rc;
if (vfop) { if (vfop) {
struct bnx2x_vfop_args_filters filters = { struct bnx2x_vfop_args_filters filters = {
...@@ -873,9 +883,6 @@ static int bnx2x_vfop_vlan_delall_cmd(struct bnx2x *bp, ...@@ -873,9 +883,6 @@ static int bnx2x_vfop_vlan_delall_cmd(struct bnx2x *bp,
bnx2x_vfop_vlan_mac_prep_ramrod(ramrod, &flags); bnx2x_vfop_vlan_mac_prep_ramrod(ramrod, &flags);
/* set object */ /* set object */
rc = validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, vlan_obj));
if (rc)
return rc;
ramrod->vlan_mac_obj = &bnx2x_vfq(vf, qid, vlan_obj); ramrod->vlan_mac_obj = &bnx2x_vfq(vf, qid, vlan_obj);
/* set extra args */ /* set extra args */
...@@ -895,9 +902,12 @@ int bnx2x_vfop_vlan_list_cmd(struct bnx2x *bp, ...@@ -895,9 +902,12 @@ int bnx2x_vfop_vlan_list_cmd(struct bnx2x *bp,
struct bnx2x_vfop_filters *vlans, struct bnx2x_vfop_filters *vlans,
int qid, bool drv_only) int qid, bool drv_only)
{ {
struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf); struct bnx2x_vfop *vfop;
int rc;
if (!bnx2x_validate_vf_sp_objs(bp, vf, true))
return -EINVAL;
vfop = bnx2x_vfop_add(bp, vf);
if (vfop) { if (vfop) {
struct bnx2x_vfop_args_filters filters = { struct bnx2x_vfop_args_filters filters = {
.multi_filter = vlans, .multi_filter = vlans,
...@@ -916,9 +926,6 @@ int bnx2x_vfop_vlan_list_cmd(struct bnx2x *bp, ...@@ -916,9 +926,6 @@ int bnx2x_vfop_vlan_list_cmd(struct bnx2x *bp,
bnx2x_vfop_vlan_mac_prep_ramrod(ramrod, &flags); bnx2x_vfop_vlan_mac_prep_ramrod(ramrod, &flags);
/* set object */ /* set object */
rc = validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, vlan_obj));
if (rc)
return rc;
ramrod->vlan_mac_obj = &bnx2x_vfq(vf, qid, vlan_obj); ramrod->vlan_mac_obj = &bnx2x_vfq(vf, qid, vlan_obj);
/* set extra args */ /* set extra args */
...@@ -1030,35 +1037,21 @@ static void bnx2x_vfop_qflr(struct bnx2x *bp, struct bnx2x_virtf *vf) ...@@ -1030,35 +1037,21 @@ static void bnx2x_vfop_qflr(struct bnx2x *bp, struct bnx2x_virtf *vf)
/* vlan-clear-all: driver-only, don't consume credit */ /* vlan-clear-all: driver-only, don't consume credit */
vfop->state = BNX2X_VFOP_QFLR_CLR_MAC; vfop->state = BNX2X_VFOP_QFLR_CLR_MAC;
if (!validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, vlan_obj))) {
/* the vlan_mac vfop will re-schedule us */ /* the vlan_mac vfop will re-schedule us */
vfop->rc = bnx2x_vfop_vlan_delall_cmd(bp, vf, &cmd, vfop->rc = bnx2x_vfop_vlan_delall_cmd(bp, vf, &cmd, qid, true);
qid, true);
if (vfop->rc) if (vfop->rc)
goto op_err; goto op_err;
return; return;
} else {
/* need to reschedule ourselves */
bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT);
}
case BNX2X_VFOP_QFLR_CLR_MAC: case BNX2X_VFOP_QFLR_CLR_MAC:
/* mac-clear-all: driver only consume credit */ /* mac-clear-all: driver only consume credit */
vfop->state = BNX2X_VFOP_QFLR_TERMINATE; vfop->state = BNX2X_VFOP_QFLR_TERMINATE;
if (!validate_vlan_mac(bp, &bnx2x_vfq(vf, qid, mac_obj))) {
/* the vlan_mac vfop will re-schedule us */ /* the vlan_mac vfop will re-schedule us */
vfop->rc = bnx2x_vfop_mac_delall_cmd(bp, vf, &cmd, vfop->rc = bnx2x_vfop_mac_delall_cmd(bp, vf, &cmd, qid, true);
qid, true);
if (vfop->rc) if (vfop->rc)
goto op_err; goto op_err;
return; return;
} else {
/* need to reschedule ourselves */
bnx2x_vfop_finalize(vf, vfop->rc, VFOP_CONT);
}
case BNX2X_VFOP_QFLR_TERMINATE: case BNX2X_VFOP_QFLR_TERMINATE:
qstate = &vfop->op_p->qctor.qstate; qstate = &vfop->op_p->qctor.qstate;
memset(qstate , 0, sizeof(*qstate)); memset(qstate , 0, sizeof(*qstate));
...@@ -1100,8 +1093,13 @@ static int bnx2x_vfop_qflr_cmd(struct bnx2x *bp, ...@@ -1100,8 +1093,13 @@ static int bnx2x_vfop_qflr_cmd(struct bnx2x *bp,
if (vfop) { if (vfop) {
vfop->args.qx.qid = qid; vfop->args.qx.qid = qid;
if ((qid == LEADING_IDX) &&
bnx2x_validate_vf_sp_objs(bp, vf, false))
bnx2x_vfop_opset(BNX2X_VFOP_QFLR_CLR_VLAN, bnx2x_vfop_opset(BNX2X_VFOP_QFLR_CLR_VLAN,
bnx2x_vfop_qflr, cmd->done); bnx2x_vfop_qflr, cmd->done);
else
bnx2x_vfop_opset(BNX2X_VFOP_QFLR_TERMINATE,
bnx2x_vfop_qflr, cmd->done);
return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_qflr, return bnx2x_vfop_transition(bp, vf, bnx2x_vfop_qflr,
cmd->block); cmd->block);
} }
...@@ -1315,7 +1313,10 @@ static void bnx2x_vfop_qdown(struct bnx2x *bp, struct bnx2x_virtf *vf) ...@@ -1315,7 +1313,10 @@ static void bnx2x_vfop_qdown(struct bnx2x *bp, struct bnx2x_virtf *vf)
switch (state) { switch (state) {
case BNX2X_VFOP_QTEARDOWN_RXMODE: case BNX2X_VFOP_QTEARDOWN_RXMODE:
/* Drop all */ /* Drop all */
if (bnx2x_validate_vf_sp_objs(bp, vf, true))
vfop->state = BNX2X_VFOP_QTEARDOWN_CLR_VLAN; vfop->state = BNX2X_VFOP_QTEARDOWN_CLR_VLAN;
else
vfop->state = BNX2X_VFOP_QTEARDOWN_QDTOR;
vfop->rc = bnx2x_vfop_rxmode_cmd(bp, vf, &cmd, qid, 0); vfop->rc = bnx2x_vfop_rxmode_cmd(bp, vf, &cmd, qid, 0);
if (vfop->rc) if (vfop->rc)
goto op_err; goto op_err;
...@@ -2171,6 +2172,9 @@ static void bnx2x_vfq_init(struct bnx2x *bp, struct bnx2x_virtf *vf, ...@@ -2171,6 +2172,9 @@ static void bnx2x_vfq_init(struct bnx2x *bp, struct bnx2x_virtf *vf,
bnx2x_vf_sp_map(bp, vf, q_data), bnx2x_vf_sp_map(bp, vf, q_data),
q_type); q_type);
/* sp indication is set only when vlan/mac/etc. are initialized */
q->sp_initialized = false;
DP(BNX2X_MSG_IOV, DP(BNX2X_MSG_IOV,
"initialized vf %d's queue object. func id set to %d. cid set to 0x%x\n", "initialized vf %d's queue object. func id set to %d. cid set to 0x%x\n",
vf->abs_vfid, q->sp_obj.func_id, q->cid); vf->abs_vfid, q->sp_obj.func_id, q->cid);
...@@ -3478,13 +3482,13 @@ int bnx2x_get_vf_config(struct net_device *dev, int vfidx, ...@@ -3478,13 +3482,13 @@ int bnx2x_get_vf_config(struct net_device *dev, int vfidx,
ivi->spoofchk = 1; /*always enabled */ ivi->spoofchk = 1; /*always enabled */
if (vf->state == VF_ENABLED) { if (vf->state == VF_ENABLED) {
/* mac and vlan are in vlan_mac objects */ /* mac and vlan are in vlan_mac objects */
if (validate_vlan_mac(bp, &bnx2x_leading_vfq(vf, mac_obj))) if (bnx2x_validate_vf_sp_objs(bp, vf, false)) {
mac_obj->get_n_elements(bp, mac_obj, 1, (u8 *)&ivi->mac, mac_obj->get_n_elements(bp, mac_obj, 1, (u8 *)&ivi->mac,
0, ETH_ALEN); 0, ETH_ALEN);
if (validate_vlan_mac(bp, &bnx2x_leading_vfq(vf, vlan_obj)))
vlan_obj->get_n_elements(bp, vlan_obj, 1, vlan_obj->get_n_elements(bp, vlan_obj, 1,
(u8 *)&ivi->vlan, 0, (u8 *)&ivi->vlan, 0,
VLAN_HLEN); VLAN_HLEN);
}
} else { } else {
/* mac */ /* mac */
if (bulletin->valid_bitmap & (1 << MAC_ADDR_VALID)) if (bulletin->valid_bitmap & (1 << MAC_ADDR_VALID))
...@@ -3558,17 +3562,17 @@ int bnx2x_set_vf_mac(struct net_device *dev, int vfidx, u8 *mac) ...@@ -3558,17 +3562,17 @@ int bnx2x_set_vf_mac(struct net_device *dev, int vfidx, u8 *mac)
q_logical_state == BNX2X_Q_LOGICAL_STATE_ACTIVE) { q_logical_state == BNX2X_Q_LOGICAL_STATE_ACTIVE) {
/* configure the mac in device on this vf's queue */ /* configure the mac in device on this vf's queue */
unsigned long ramrod_flags = 0; unsigned long ramrod_flags = 0;
struct bnx2x_vlan_mac_obj *mac_obj = struct bnx2x_vlan_mac_obj *mac_obj;
&bnx2x_leading_vfq(vf, mac_obj);
rc = validate_vlan_mac(bp, &bnx2x_leading_vfq(vf, mac_obj)); /* User should be able to see failure reason in system logs */
if (rc) if (!bnx2x_validate_vf_sp_objs(bp, vf, true))
return rc; return -EINVAL;
/* must lock vfpf channel to protect against vf flows */ /* must lock vfpf channel to protect against vf flows */
bnx2x_lock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_SET_MAC); bnx2x_lock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_SET_MAC);
/* remove existing eth macs */ /* remove existing eth macs */
mac_obj = &bnx2x_leading_vfq(vf, mac_obj);
rc = bnx2x_del_all_macs(bp, mac_obj, BNX2X_ETH_MAC, true); rc = bnx2x_del_all_macs(bp, mac_obj, BNX2X_ETH_MAC, true);
if (rc) { if (rc) {
BNX2X_ERR("failed to delete eth macs\n"); BNX2X_ERR("failed to delete eth macs\n");
...@@ -3642,17 +3646,16 @@ int bnx2x_set_vf_vlan(struct net_device *dev, int vfidx, u16 vlan, u8 qos) ...@@ -3642,17 +3646,16 @@ int bnx2x_set_vf_vlan(struct net_device *dev, int vfidx, u16 vlan, u8 qos)
BNX2X_Q_LOGICAL_STATE_ACTIVE) BNX2X_Q_LOGICAL_STATE_ACTIVE)
return rc; return rc;
/* configure the vlan in device on this vf's queue */ /* User should be able to see error in system logs */
vlan_obj = &bnx2x_leading_vfq(vf, vlan_obj); if (!bnx2x_validate_vf_sp_objs(bp, vf, true))
rc = validate_vlan_mac(bp, &bnx2x_leading_vfq(vf, mac_obj)); return -EINVAL;
if (rc)
return rc;
/* must lock vfpf channel to protect against vf flows */ /* must lock vfpf channel to protect against vf flows */
bnx2x_lock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_SET_VLAN); bnx2x_lock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_SET_VLAN);
/* remove existing vlans */ /* remove existing vlans */
__set_bit(RAMROD_COMP_WAIT, &ramrod_flags); __set_bit(RAMROD_COMP_WAIT, &ramrod_flags);
vlan_obj = &bnx2x_leading_vfq(vf, vlan_obj);
rc = vlan_obj->delete_all(bp, vlan_obj, &vlan_mac_flags, rc = vlan_obj->delete_all(bp, vlan_obj, &vlan_mac_flags,
&ramrod_flags); &ramrod_flags);
if (rc) { if (rc) {
......
...@@ -83,6 +83,7 @@ struct bnx2x_vf_queue { ...@@ -83,6 +83,7 @@ struct bnx2x_vf_queue {
u16 index; u16 index;
u16 sb_idx; u16 sb_idx;
bool is_leading; bool is_leading;
bool sp_initialized;
}; };
/* struct bnx2x_vfop_qctor_params - prepare queue construction parameters: /* struct bnx2x_vfop_qctor_params - prepare queue construction parameters:
......
...@@ -548,6 +548,7 @@ static void bnx2x_leading_vfq_init(struct bnx2x *bp, struct bnx2x_virtf *vf, ...@@ -548,6 +548,7 @@ static void bnx2x_leading_vfq_init(struct bnx2x *bp, struct bnx2x_virtf *vf,
vf->leading_rss = cl_id; vf->leading_rss = cl_id;
q->is_leading = true; q->is_leading = true;
q->sp_initialized = true;
} }
/* ask the pf to open a queue for the vf */ /* ask the pf to open a queue for the vf */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment