Merge branch 'bnx2x'
Yuval Mintz says: ==================== bnx2x: Bug fixes patch series Most of what this parch series contains is SR-IOV related bug fixes. Additionally, it contains some small fixes for legacy devices/modes. Please consider applying these patches to `net'. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
723a6c7a29
7 changed files with 204 additions and 128 deletions
|
@ -1250,7 +1250,10 @@ struct bnx2x_slowpath {
|
||||||
* Therefore, if they would have been defined in the same union,
|
* Therefore, if they would have been defined in the same union,
|
||||||
* data can get corrupted.
|
* data can get corrupted.
|
||||||
*/
|
*/
|
||||||
struct afex_vif_list_ramrod_data func_afex_rdata;
|
union {
|
||||||
|
struct afex_vif_list_ramrod_data viflist_data;
|
||||||
|
struct function_update_data func_update;
|
||||||
|
} func_afex_rdata;
|
||||||
|
|
||||||
/* used by dmae command executer */
|
/* used by dmae command executer */
|
||||||
struct dmae_command dmae[MAX_DMAE_C];
|
struct dmae_command dmae[MAX_DMAE_C];
|
||||||
|
@ -2499,4 +2502,6 @@ void bnx2x_set_local_cmng(struct bnx2x *bp);
|
||||||
#define MCPR_SCRATCH_BASE(bp) \
|
#define MCPR_SCRATCH_BASE(bp) \
|
||||||
(CHIP_IS_E1x(bp) ? MCP_REG_MCPR_SCRATCH : MCP_A_REG_MCPR_SCRATCH)
|
(CHIP_IS_E1x(bp) ? MCP_REG_MCPR_SCRATCH : MCP_A_REG_MCPR_SCRATCH)
|
||||||
|
|
||||||
|
#define E1H_MAX_MF_SB_COUNT (HC_SB_MAX_SB_E1X/(E1HVN_MAX * PORT_MAX))
|
||||||
|
|
||||||
#endif /* bnx2x.h */
|
#endif /* bnx2x.h */
|
||||||
|
|
|
@ -11447,9 +11447,9 @@ static int bnx2x_get_hwinfo(struct bnx2x *bp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* adjust igu_sb_cnt to MF for E1x */
|
/* adjust igu_sb_cnt to MF for E1H */
|
||||||
if (CHIP_IS_E1x(bp) && IS_MF(bp))
|
if (CHIP_IS_E1H(bp) && IS_MF(bp))
|
||||||
bp->igu_sb_cnt /= E1HVN_MAX;
|
bp->igu_sb_cnt = min_t(u8, bp->igu_sb_cnt, E1H_MAX_MF_SB_COUNT);
|
||||||
|
|
||||||
/* port info */
|
/* port info */
|
||||||
bnx2x_get_port_hwinfo(bp);
|
bnx2x_get_port_hwinfo(bp);
|
||||||
|
|
|
@ -2038,6 +2038,7 @@ static int bnx2x_vlan_mac_del_all(struct bnx2x *bp,
|
||||||
struct bnx2x_vlan_mac_ramrod_params p;
|
struct bnx2x_vlan_mac_ramrod_params p;
|
||||||
struct bnx2x_exe_queue_obj *exeq = &o->exe_queue;
|
struct bnx2x_exe_queue_obj *exeq = &o->exe_queue;
|
||||||
struct bnx2x_exeq_elem *exeq_pos, *exeq_pos_n;
|
struct bnx2x_exeq_elem *exeq_pos, *exeq_pos_n;
|
||||||
|
unsigned long flags;
|
||||||
int read_lock;
|
int read_lock;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
|
@ -2046,8 +2047,9 @@ static int bnx2x_vlan_mac_del_all(struct bnx2x *bp,
|
||||||
spin_lock_bh(&exeq->lock);
|
spin_lock_bh(&exeq->lock);
|
||||||
|
|
||||||
list_for_each_entry_safe(exeq_pos, exeq_pos_n, &exeq->exe_queue, link) {
|
list_for_each_entry_safe(exeq_pos, exeq_pos_n, &exeq->exe_queue, link) {
|
||||||
if (exeq_pos->cmd_data.vlan_mac.vlan_mac_flags ==
|
flags = exeq_pos->cmd_data.vlan_mac.vlan_mac_flags;
|
||||||
*vlan_mac_flags) {
|
if (BNX2X_VLAN_MAC_CMP_FLAGS(flags) ==
|
||||||
|
BNX2X_VLAN_MAC_CMP_FLAGS(*vlan_mac_flags)) {
|
||||||
rc = exeq->remove(bp, exeq->owner, exeq_pos);
|
rc = exeq->remove(bp, exeq->owner, exeq_pos);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
BNX2X_ERR("Failed to remove command\n");
|
BNX2X_ERR("Failed to remove command\n");
|
||||||
|
@ -2080,7 +2082,9 @@ static int bnx2x_vlan_mac_del_all(struct bnx2x *bp,
|
||||||
return read_lock;
|
return read_lock;
|
||||||
|
|
||||||
list_for_each_entry(pos, &o->head, link) {
|
list_for_each_entry(pos, &o->head, link) {
|
||||||
if (pos->vlan_mac_flags == *vlan_mac_flags) {
|
flags = pos->vlan_mac_flags;
|
||||||
|
if (BNX2X_VLAN_MAC_CMP_FLAGS(flags) ==
|
||||||
|
BNX2X_VLAN_MAC_CMP_FLAGS(*vlan_mac_flags)) {
|
||||||
p.user_req.vlan_mac_flags = pos->vlan_mac_flags;
|
p.user_req.vlan_mac_flags = pos->vlan_mac_flags;
|
||||||
memcpy(&p.user_req.u, &pos->u, sizeof(pos->u));
|
memcpy(&p.user_req.u, &pos->u, sizeof(pos->u));
|
||||||
rc = bnx2x_config_vlan_mac(bp, &p);
|
rc = bnx2x_config_vlan_mac(bp, &p);
|
||||||
|
@ -4382,8 +4386,11 @@ int bnx2x_config_rss(struct bnx2x *bp,
|
||||||
struct bnx2x_raw_obj *r = &o->raw;
|
struct bnx2x_raw_obj *r = &o->raw;
|
||||||
|
|
||||||
/* Do nothing if only driver cleanup was requested */
|
/* Do nothing if only driver cleanup was requested */
|
||||||
if (test_bit(RAMROD_DRV_CLR_ONLY, &p->ramrod_flags))
|
if (test_bit(RAMROD_DRV_CLR_ONLY, &p->ramrod_flags)) {
|
||||||
|
DP(BNX2X_MSG_SP, "Not configuring RSS ramrod_flags=%lx\n",
|
||||||
|
p->ramrod_flags);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
r->set_pending(r);
|
r->set_pending(r);
|
||||||
|
|
||||||
|
|
|
@ -266,6 +266,13 @@ enum {
|
||||||
BNX2X_DONT_CONSUME_CAM_CREDIT,
|
BNX2X_DONT_CONSUME_CAM_CREDIT,
|
||||||
BNX2X_DONT_CONSUME_CAM_CREDIT_DEST,
|
BNX2X_DONT_CONSUME_CAM_CREDIT_DEST,
|
||||||
};
|
};
|
||||||
|
/* When looking for matching filters, some flags are not interesting */
|
||||||
|
#define BNX2X_VLAN_MAC_CMP_MASK (1 << BNX2X_UC_LIST_MAC | \
|
||||||
|
1 << BNX2X_ETH_MAC | \
|
||||||
|
1 << BNX2X_ISCSI_ETH_MAC | \
|
||||||
|
1 << BNX2X_NETQ_ETH_MAC)
|
||||||
|
#define BNX2X_VLAN_MAC_CMP_FLAGS(flags) \
|
||||||
|
((flags) & BNX2X_VLAN_MAC_CMP_MASK)
|
||||||
|
|
||||||
struct bnx2x_vlan_mac_ramrod_params {
|
struct bnx2x_vlan_mac_ramrod_params {
|
||||||
/* Object to run the command from */
|
/* Object to run the command from */
|
||||||
|
|
|
@ -1209,6 +1209,11 @@ static void bnx2x_vfop_rxmode(struct bnx2x *bp, struct bnx2x_virtf *vf)
|
||||||
/* next state */
|
/* next state */
|
||||||
vfop->state = BNX2X_VFOP_RXMODE_DONE;
|
vfop->state = BNX2X_VFOP_RXMODE_DONE;
|
||||||
|
|
||||||
|
/* record the accept flags in vfdb so hypervisor can modify them
|
||||||
|
* if necessary
|
||||||
|
*/
|
||||||
|
bnx2x_vfq(vf, ramrod->cl_id - vf->igu_base_id, accept_flags) =
|
||||||
|
ramrod->rx_accept_flags;
|
||||||
vfop->rc = bnx2x_config_rx_mode(bp, ramrod);
|
vfop->rc = bnx2x_config_rx_mode(bp, ramrod);
|
||||||
bnx2x_vfop_finalize(vf, vfop->rc, VFOP_DONE);
|
bnx2x_vfop_finalize(vf, vfop->rc, VFOP_DONE);
|
||||||
op_err:
|
op_err:
|
||||||
|
@ -1224,39 +1229,43 @@ op_pending:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void bnx2x_vf_prep_rx_mode(struct bnx2x *bp, u8 qid,
|
||||||
|
struct bnx2x_rx_mode_ramrod_params *ramrod,
|
||||||
|
struct bnx2x_virtf *vf,
|
||||||
|
unsigned long accept_flags)
|
||||||
|
{
|
||||||
|
struct bnx2x_vf_queue *vfq = vfq_get(vf, qid);
|
||||||
|
|
||||||
|
memset(ramrod, 0, sizeof(*ramrod));
|
||||||
|
ramrod->cid = vfq->cid;
|
||||||
|
ramrod->cl_id = vfq_cl_id(vf, vfq);
|
||||||
|
ramrod->rx_mode_obj = &bp->rx_mode_obj;
|
||||||
|
ramrod->func_id = FW_VF_HANDLE(vf->abs_vfid);
|
||||||
|
ramrod->rx_accept_flags = accept_flags;
|
||||||
|
ramrod->tx_accept_flags = accept_flags;
|
||||||
|
ramrod->pstate = &vf->filter_state;
|
||||||
|
ramrod->state = BNX2X_FILTER_RX_MODE_PENDING;
|
||||||
|
|
||||||
|
set_bit(BNX2X_FILTER_RX_MODE_PENDING, &vf->filter_state);
|
||||||
|
set_bit(RAMROD_RX, &ramrod->ramrod_flags);
|
||||||
|
set_bit(RAMROD_TX, &ramrod->ramrod_flags);
|
||||||
|
|
||||||
|
ramrod->rdata = bnx2x_vf_sp(bp, vf, rx_mode_rdata.e2);
|
||||||
|
ramrod->rdata_mapping = bnx2x_vf_sp_map(bp, vf, rx_mode_rdata.e2);
|
||||||
|
}
|
||||||
|
|
||||||
int bnx2x_vfop_rxmode_cmd(struct bnx2x *bp,
|
int bnx2x_vfop_rxmode_cmd(struct bnx2x *bp,
|
||||||
struct bnx2x_virtf *vf,
|
struct bnx2x_virtf *vf,
|
||||||
struct bnx2x_vfop_cmd *cmd,
|
struct bnx2x_vfop_cmd *cmd,
|
||||||
int qid, unsigned long accept_flags)
|
int qid, unsigned long accept_flags)
|
||||||
{
|
{
|
||||||
struct bnx2x_vf_queue *vfq = vfq_get(vf, qid);
|
|
||||||
struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf);
|
struct bnx2x_vfop *vfop = bnx2x_vfop_add(bp, vf);
|
||||||
|
|
||||||
if (vfop) {
|
if (vfop) {
|
||||||
struct bnx2x_rx_mode_ramrod_params *ramrod =
|
struct bnx2x_rx_mode_ramrod_params *ramrod =
|
||||||
&vf->op_params.rx_mode;
|
&vf->op_params.rx_mode;
|
||||||
|
|
||||||
memset(ramrod, 0, sizeof(*ramrod));
|
bnx2x_vf_prep_rx_mode(bp, qid, ramrod, vf, accept_flags);
|
||||||
|
|
||||||
/* Prepare ramrod parameters */
|
|
||||||
ramrod->cid = vfq->cid;
|
|
||||||
ramrod->cl_id = vfq_cl_id(vf, vfq);
|
|
||||||
ramrod->rx_mode_obj = &bp->rx_mode_obj;
|
|
||||||
ramrod->func_id = FW_VF_HANDLE(vf->abs_vfid);
|
|
||||||
|
|
||||||
ramrod->rx_accept_flags = accept_flags;
|
|
||||||
ramrod->tx_accept_flags = accept_flags;
|
|
||||||
ramrod->pstate = &vf->filter_state;
|
|
||||||
ramrod->state = BNX2X_FILTER_RX_MODE_PENDING;
|
|
||||||
|
|
||||||
set_bit(BNX2X_FILTER_RX_MODE_PENDING, &vf->filter_state);
|
|
||||||
set_bit(RAMROD_RX, &ramrod->ramrod_flags);
|
|
||||||
set_bit(RAMROD_TX, &ramrod->ramrod_flags);
|
|
||||||
|
|
||||||
ramrod->rdata =
|
|
||||||
bnx2x_vf_sp(bp, vf, rx_mode_rdata.e2);
|
|
||||||
ramrod->rdata_mapping =
|
|
||||||
bnx2x_vf_sp_map(bp, vf, rx_mode_rdata.e2);
|
|
||||||
|
|
||||||
bnx2x_vfop_opset(BNX2X_VFOP_RXMODE_CONFIG,
|
bnx2x_vfop_opset(BNX2X_VFOP_RXMODE_CONFIG,
|
||||||
bnx2x_vfop_rxmode, cmd->done);
|
bnx2x_vfop_rxmode, cmd->done);
|
||||||
|
@ -3202,13 +3211,16 @@ int bnx2x_enable_sriov(struct bnx2x *bp)
|
||||||
bnx2x_iov_static_resc(bp, vf);
|
bnx2x_iov_static_resc(bp, vf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* prepare msix vectors in VF configuration space */
|
/* prepare msix vectors in VF configuration space - the value in the
|
||||||
|
* PCI configuration space should be the index of the last entry,
|
||||||
|
* namely one less than the actual size of the table
|
||||||
|
*/
|
||||||
for (vf_idx = first_vf; vf_idx < first_vf + req_vfs; vf_idx++) {
|
for (vf_idx = first_vf; vf_idx < first_vf + req_vfs; vf_idx++) {
|
||||||
bnx2x_pretend_func(bp, HW_VF_HANDLE(bp, vf_idx));
|
bnx2x_pretend_func(bp, HW_VF_HANDLE(bp, vf_idx));
|
||||||
REG_WR(bp, PCICFG_OFFSET + GRC_CONFIG_REG_VF_MSIX_CONTROL,
|
REG_WR(bp, PCICFG_OFFSET + GRC_CONFIG_REG_VF_MSIX_CONTROL,
|
||||||
num_vf_queues);
|
num_vf_queues - 1);
|
||||||
DP(BNX2X_MSG_IOV, "set msix vec num in VF %d cfg space to %d\n",
|
DP(BNX2X_MSG_IOV, "set msix vec num in VF %d cfg space to %d\n",
|
||||||
vf_idx, num_vf_queues);
|
vf_idx, num_vf_queues - 1);
|
||||||
}
|
}
|
||||||
bnx2x_pretend_func(bp, BP_ABS_FUNC(bp));
|
bnx2x_pretend_func(bp, BP_ABS_FUNC(bp));
|
||||||
|
|
||||||
|
@ -3436,10 +3448,18 @@ out:
|
||||||
|
|
||||||
int bnx2x_set_vf_vlan(struct net_device *dev, int vfidx, u16 vlan, u8 qos)
|
int bnx2x_set_vf_vlan(struct net_device *dev, int vfidx, u16 vlan, u8 qos)
|
||||||
{
|
{
|
||||||
struct bnx2x *bp = netdev_priv(dev);
|
struct bnx2x_queue_state_params q_params = {NULL};
|
||||||
int rc, q_logical_state;
|
struct bnx2x_vlan_mac_ramrod_params ramrod_param;
|
||||||
struct bnx2x_virtf *vf = NULL;
|
struct bnx2x_queue_update_params *update_params;
|
||||||
struct pf_vf_bulletin_content *bulletin = NULL;
|
struct pf_vf_bulletin_content *bulletin = NULL;
|
||||||
|
struct bnx2x_rx_mode_ramrod_params rx_ramrod;
|
||||||
|
struct bnx2x *bp = netdev_priv(dev);
|
||||||
|
struct bnx2x_vlan_mac_obj *vlan_obj;
|
||||||
|
unsigned long vlan_mac_flags = 0;
|
||||||
|
unsigned long ramrod_flags = 0;
|
||||||
|
struct bnx2x_virtf *vf = NULL;
|
||||||
|
unsigned long accept_flags;
|
||||||
|
int rc;
|
||||||
|
|
||||||
/* sanity and init */
|
/* sanity and init */
|
||||||
rc = bnx2x_vf_ndo_prep(bp, vfidx, &vf, &bulletin);
|
rc = bnx2x_vf_ndo_prep(bp, vfidx, &vf, &bulletin);
|
||||||
|
@ -3457,104 +3477,118 @@ int bnx2x_set_vf_vlan(struct net_device *dev, int vfidx, u16 vlan, u8 qos)
|
||||||
/* update PF's copy of the VF's bulletin. No point in posting the vlan
|
/* update PF's copy of the VF's bulletin. No point in posting the vlan
|
||||||
* to the VF since it doesn't have anything to do with it. But it useful
|
* to the VF since it doesn't have anything to do with it. But it useful
|
||||||
* to store it here in case the VF is not up yet and we can only
|
* to store it here in case the VF is not up yet and we can only
|
||||||
* configure the vlan later when it does.
|
* configure the vlan later when it does. Treat vlan id 0 as remove the
|
||||||
|
* Host tag.
|
||||||
*/
|
*/
|
||||||
bulletin->valid_bitmap |= 1 << VLAN_VALID;
|
if (vlan > 0)
|
||||||
|
bulletin->valid_bitmap |= 1 << VLAN_VALID;
|
||||||
|
else
|
||||||
|
bulletin->valid_bitmap &= ~(1 << VLAN_VALID);
|
||||||
bulletin->vlan = vlan;
|
bulletin->vlan = vlan;
|
||||||
|
|
||||||
/* is vf initialized and queue set up? */
|
/* is vf initialized and queue set up? */
|
||||||
q_logical_state =
|
if (vf->state != VF_ENABLED ||
|
||||||
bnx2x_get_q_logical_state(bp, &bnx2x_leading_vfq(vf, sp_obj));
|
bnx2x_get_q_logical_state(bp, &bnx2x_leading_vfq(vf, sp_obj)) !=
|
||||||
if (vf->state == VF_ENABLED &&
|
BNX2X_Q_LOGICAL_STATE_ACTIVE)
|
||||||
q_logical_state == BNX2X_Q_LOGICAL_STATE_ACTIVE) {
|
return rc;
|
||||||
/* configure the vlan in device on this vf's queue */
|
|
||||||
unsigned long ramrod_flags = 0;
|
|
||||||
unsigned long vlan_mac_flags = 0;
|
|
||||||
struct bnx2x_vlan_mac_obj *vlan_obj =
|
|
||||||
&bnx2x_leading_vfq(vf, vlan_obj);
|
|
||||||
struct bnx2x_vlan_mac_ramrod_params ramrod_param;
|
|
||||||
struct bnx2x_queue_state_params q_params = {NULL};
|
|
||||||
struct bnx2x_queue_update_params *update_params;
|
|
||||||
|
|
||||||
rc = validate_vlan_mac(bp, &bnx2x_leading_vfq(vf, mac_obj));
|
/* configure the vlan in device on this vf's queue */
|
||||||
if (rc)
|
vlan_obj = &bnx2x_leading_vfq(vf, vlan_obj);
|
||||||
return rc;
|
rc = validate_vlan_mac(bp, &bnx2x_leading_vfq(vf, mac_obj));
|
||||||
memset(&ramrod_param, 0, sizeof(ramrod_param));
|
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);
|
||||||
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) {
|
||||||
BNX2X_ERR("failed to delete vlans\n");
|
BNX2X_ERR("failed to delete vlans\n");
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
|
|
||||||
/* send queue update ramrod to configure default vlan and silent
|
|
||||||
* vlan removal
|
|
||||||
*/
|
|
||||||
__set_bit(RAMROD_COMP_WAIT, &q_params.ramrod_flags);
|
|
||||||
q_params.cmd = BNX2X_Q_CMD_UPDATE;
|
|
||||||
q_params.q_obj = &bnx2x_leading_vfq(vf, sp_obj);
|
|
||||||
update_params = &q_params.params.update;
|
|
||||||
__set_bit(BNX2X_Q_UPDATE_DEF_VLAN_EN_CHNG,
|
|
||||||
&update_params->update_flags);
|
|
||||||
__set_bit(BNX2X_Q_UPDATE_SILENT_VLAN_REM_CHNG,
|
|
||||||
&update_params->update_flags);
|
|
||||||
|
|
||||||
if (vlan == 0) {
|
|
||||||
/* if vlan is 0 then we want to leave the VF traffic
|
|
||||||
* untagged, and leave the incoming traffic untouched
|
|
||||||
* (i.e. do not remove any vlan tags).
|
|
||||||
*/
|
|
||||||
__clear_bit(BNX2X_Q_UPDATE_DEF_VLAN_EN,
|
|
||||||
&update_params->update_flags);
|
|
||||||
__clear_bit(BNX2X_Q_UPDATE_SILENT_VLAN_REM,
|
|
||||||
&update_params->update_flags);
|
|
||||||
} else {
|
|
||||||
/* configure the new vlan to device */
|
|
||||||
__set_bit(RAMROD_COMP_WAIT, &ramrod_flags);
|
|
||||||
ramrod_param.vlan_mac_obj = vlan_obj;
|
|
||||||
ramrod_param.ramrod_flags = ramrod_flags;
|
|
||||||
ramrod_param.user_req.u.vlan.vlan = vlan;
|
|
||||||
ramrod_param.user_req.cmd = BNX2X_VLAN_MAC_ADD;
|
|
||||||
rc = bnx2x_config_vlan_mac(bp, &ramrod_param);
|
|
||||||
if (rc) {
|
|
||||||
BNX2X_ERR("failed to configure vlan\n");
|
|
||||||
rc = -EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* configure default vlan to vf queue and set silent
|
|
||||||
* vlan removal (the vf remains unaware of this vlan).
|
|
||||||
*/
|
|
||||||
update_params = &q_params.params.update;
|
|
||||||
__set_bit(BNX2X_Q_UPDATE_DEF_VLAN_EN,
|
|
||||||
&update_params->update_flags);
|
|
||||||
__set_bit(BNX2X_Q_UPDATE_SILENT_VLAN_REM,
|
|
||||||
&update_params->update_flags);
|
|
||||||
update_params->def_vlan = vlan;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update the Queue state */
|
|
||||||
rc = bnx2x_queue_state_change(bp, &q_params);
|
|
||||||
if (rc) {
|
|
||||||
BNX2X_ERR("Failed to configure default VLAN\n");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clear the flag indicating that this VF needs its vlan
|
|
||||||
* (will only be set if the HV configured the Vlan before vf was
|
|
||||||
* up and we were called because the VF came up later
|
|
||||||
*/
|
|
||||||
out:
|
|
||||||
vf->cfg_flags &= ~VF_CFG_VLAN;
|
|
||||||
bnx2x_unlock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_SET_VLAN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* need to remove/add the VF's accept_any_vlan bit */
|
||||||
|
accept_flags = bnx2x_leading_vfq(vf, accept_flags);
|
||||||
|
if (vlan)
|
||||||
|
clear_bit(BNX2X_ACCEPT_ANY_VLAN, &accept_flags);
|
||||||
|
else
|
||||||
|
set_bit(BNX2X_ACCEPT_ANY_VLAN, &accept_flags);
|
||||||
|
|
||||||
|
bnx2x_vf_prep_rx_mode(bp, LEADING_IDX, &rx_ramrod, vf,
|
||||||
|
accept_flags);
|
||||||
|
bnx2x_leading_vfq(vf, accept_flags) = accept_flags;
|
||||||
|
bnx2x_config_rx_mode(bp, &rx_ramrod);
|
||||||
|
|
||||||
|
/* configure the new vlan to device */
|
||||||
|
memset(&ramrod_param, 0, sizeof(ramrod_param));
|
||||||
|
__set_bit(RAMROD_COMP_WAIT, &ramrod_flags);
|
||||||
|
ramrod_param.vlan_mac_obj = vlan_obj;
|
||||||
|
ramrod_param.ramrod_flags = ramrod_flags;
|
||||||
|
set_bit(BNX2X_DONT_CONSUME_CAM_CREDIT,
|
||||||
|
&ramrod_param.user_req.vlan_mac_flags);
|
||||||
|
ramrod_param.user_req.u.vlan.vlan = vlan;
|
||||||
|
ramrod_param.user_req.cmd = BNX2X_VLAN_MAC_ADD;
|
||||||
|
rc = bnx2x_config_vlan_mac(bp, &ramrod_param);
|
||||||
|
if (rc) {
|
||||||
|
BNX2X_ERR("failed to configure vlan\n");
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* send queue update ramrod to configure default vlan and silent
|
||||||
|
* vlan removal
|
||||||
|
*/
|
||||||
|
__set_bit(RAMROD_COMP_WAIT, &q_params.ramrod_flags);
|
||||||
|
q_params.cmd = BNX2X_Q_CMD_UPDATE;
|
||||||
|
q_params.q_obj = &bnx2x_leading_vfq(vf, sp_obj);
|
||||||
|
update_params = &q_params.params.update;
|
||||||
|
__set_bit(BNX2X_Q_UPDATE_DEF_VLAN_EN_CHNG,
|
||||||
|
&update_params->update_flags);
|
||||||
|
__set_bit(BNX2X_Q_UPDATE_SILENT_VLAN_REM_CHNG,
|
||||||
|
&update_params->update_flags);
|
||||||
|
if (vlan == 0) {
|
||||||
|
/* if vlan is 0 then we want to leave the VF traffic
|
||||||
|
* untagged, and leave the incoming traffic untouched
|
||||||
|
* (i.e. do not remove any vlan tags).
|
||||||
|
*/
|
||||||
|
__clear_bit(BNX2X_Q_UPDATE_DEF_VLAN_EN,
|
||||||
|
&update_params->update_flags);
|
||||||
|
__clear_bit(BNX2X_Q_UPDATE_SILENT_VLAN_REM,
|
||||||
|
&update_params->update_flags);
|
||||||
|
} else {
|
||||||
|
/* configure default vlan to vf queue and set silent
|
||||||
|
* vlan removal (the vf remains unaware of this vlan).
|
||||||
|
*/
|
||||||
|
__set_bit(BNX2X_Q_UPDATE_DEF_VLAN_EN,
|
||||||
|
&update_params->update_flags);
|
||||||
|
__set_bit(BNX2X_Q_UPDATE_SILENT_VLAN_REM,
|
||||||
|
&update_params->update_flags);
|
||||||
|
update_params->def_vlan = vlan;
|
||||||
|
update_params->silent_removal_value =
|
||||||
|
vlan & VLAN_VID_MASK;
|
||||||
|
update_params->silent_removal_mask = VLAN_VID_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update the Queue state */
|
||||||
|
rc = bnx2x_queue_state_change(bp, &q_params);
|
||||||
|
if (rc) {
|
||||||
|
BNX2X_ERR("Failed to configure default VLAN\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* clear the flag indicating that this VF needs its vlan
|
||||||
|
* (will only be set if the HV configured the Vlan before vf was
|
||||||
|
* up and we were called because the VF came up later
|
||||||
|
*/
|
||||||
|
out:
|
||||||
|
vf->cfg_flags &= ~VF_CFG_VLAN;
|
||||||
|
bnx2x_unlock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_SET_VLAN);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,7 @@ struct bnx2x_vf_queue {
|
||||||
/* VLANs object */
|
/* VLANs object */
|
||||||
struct bnx2x_vlan_mac_obj vlan_obj;
|
struct bnx2x_vlan_mac_obj vlan_obj;
|
||||||
atomic_t vlan_count; /* 0 means vlan-0 is set ~ untagged */
|
atomic_t vlan_count; /* 0 means vlan-0 is set ~ untagged */
|
||||||
|
unsigned long accept_flags; /* last accept flags configured */
|
||||||
|
|
||||||
/* Queue Slow-path State object */
|
/* Queue Slow-path State object */
|
||||||
struct bnx2x_queue_sp_obj sp_obj;
|
struct bnx2x_queue_sp_obj sp_obj;
|
||||||
|
|
|
@ -1598,6 +1598,8 @@ static void bnx2x_vfop_mbx_qfilters(struct bnx2x *bp, struct bnx2x_virtf *vf)
|
||||||
|
|
||||||
if (msg->flags & VFPF_SET_Q_FILTERS_RX_MASK_CHANGED) {
|
if (msg->flags & VFPF_SET_Q_FILTERS_RX_MASK_CHANGED) {
|
||||||
unsigned long accept = 0;
|
unsigned long accept = 0;
|
||||||
|
struct pf_vf_bulletin_content *bulletin =
|
||||||
|
BP_VF_BULLETIN(bp, vf->index);
|
||||||
|
|
||||||
/* covert VF-PF if mask to bnx2x accept flags */
|
/* covert VF-PF if mask to bnx2x accept flags */
|
||||||
if (msg->rx_mask & VFPF_RX_MASK_ACCEPT_MATCHED_UNICAST)
|
if (msg->rx_mask & VFPF_RX_MASK_ACCEPT_MATCHED_UNICAST)
|
||||||
|
@ -1617,9 +1619,11 @@ static void bnx2x_vfop_mbx_qfilters(struct bnx2x *bp, struct bnx2x_virtf *vf)
|
||||||
__set_bit(BNX2X_ACCEPT_BROADCAST, &accept);
|
__set_bit(BNX2X_ACCEPT_BROADCAST, &accept);
|
||||||
|
|
||||||
/* A packet arriving the vf's mac should be accepted
|
/* A packet arriving the vf's mac should be accepted
|
||||||
* with any vlan
|
* with any vlan, unless a vlan has already been
|
||||||
|
* configured.
|
||||||
*/
|
*/
|
||||||
__set_bit(BNX2X_ACCEPT_ANY_VLAN, &accept);
|
if (!(bulletin->valid_bitmap & (1 << VLAN_VALID)))
|
||||||
|
__set_bit(BNX2X_ACCEPT_ANY_VLAN, &accept);
|
||||||
|
|
||||||
/* set rx-mode */
|
/* set rx-mode */
|
||||||
rc = bnx2x_vfop_rxmode_cmd(bp, vf, &cmd,
|
rc = bnx2x_vfop_rxmode_cmd(bp, vf, &cmd,
|
||||||
|
@ -1710,6 +1714,21 @@ static void bnx2x_vf_mbx_set_q_filters(struct bnx2x *bp,
|
||||||
goto response;
|
goto response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* if vlan was set by hypervisor we don't allow guest to config vlan */
|
||||||
|
if (bulletin->valid_bitmap & 1 << VLAN_VALID) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* search for vlan filters */
|
||||||
|
for (i = 0; i < filters->n_mac_vlan_filters; i++) {
|
||||||
|
if (filters->filters[i].flags &
|
||||||
|
VFPF_Q_FILTER_VLAN_TAG_VALID) {
|
||||||
|
BNX2X_ERR("VF[%d] attempted to configure vlan but one was already set by Hypervisor. Aborting request\n",
|
||||||
|
vf->abs_vfid);
|
||||||
|
vf->op_rc = -EPERM;
|
||||||
|
goto response;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* verify vf_qid */
|
/* verify vf_qid */
|
||||||
if (filters->vf_qid > vf_rxq_count(vf))
|
if (filters->vf_qid > vf_rxq_count(vf))
|
||||||
|
@ -1805,6 +1824,9 @@ static void bnx2x_vf_mbx_update_rss(struct bnx2x *bp, struct bnx2x_virtf *vf,
|
||||||
vf_op_params->rss_result_mask = rss_tlv->rss_result_mask;
|
vf_op_params->rss_result_mask = rss_tlv->rss_result_mask;
|
||||||
|
|
||||||
/* flags handled individually for backward/forward compatability */
|
/* flags handled individually for backward/forward compatability */
|
||||||
|
vf_op_params->rss_flags = 0;
|
||||||
|
vf_op_params->ramrod_flags = 0;
|
||||||
|
|
||||||
if (rss_tlv->rss_flags & VFPF_RSS_MODE_DISABLED)
|
if (rss_tlv->rss_flags & VFPF_RSS_MODE_DISABLED)
|
||||||
__set_bit(BNX2X_RSS_MODE_DISABLED, &vf_op_params->rss_flags);
|
__set_bit(BNX2X_RSS_MODE_DISABLED, &vf_op_params->rss_flags);
|
||||||
if (rss_tlv->rss_flags & VFPF_RSS_MODE_REGULAR)
|
if (rss_tlv->rss_flags & VFPF_RSS_MODE_REGULAR)
|
||||||
|
|
Loading…
Add table
Reference in a new issue