mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-10 15:54:39 +08:00
bnx2x: Add iproute2 support for vfs
This patch adds support for iproute2 callbacks allowing querying a physical function as to its child virtual functions, and setting the macs and vlans of said virtual functions. Signed-off-by: Ariel Elior <ariele@broadcom.com> Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
3786b9426d
commit
3ec9f9ca79
@ -1214,6 +1214,7 @@ enum {
|
||||
BNX2X_SP_RTNL_ENABLE_SRIOV,
|
||||
BNX2X_SP_RTNL_VFPF_MCAST,
|
||||
BNX2X_SP_RTNL_VFPF_STORM_RX_MODE,
|
||||
BNX2X_SP_RTNL_HYPERVISOR_VLAN,
|
||||
};
|
||||
|
||||
|
||||
|
@ -496,7 +496,10 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev);
|
||||
/* setup_tc callback */
|
||||
int bnx2x_setup_tc(struct net_device *dev, u8 num_tc);
|
||||
|
||||
int bnx2x_get_vf_config(struct net_device *dev, int vf,
|
||||
struct ifla_vf_info *ivi);
|
||||
int bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac);
|
||||
int bnx2x_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos);
|
||||
|
||||
/* select_queue callback */
|
||||
u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb);
|
||||
|
@ -75,8 +75,6 @@
|
||||
#define FW_FILE_NAME_E1H "bnx2x/bnx2x-e1h-" FW_FILE_VERSION ".fw"
|
||||
#define FW_FILE_NAME_E2 "bnx2x/bnx2x-e2-" FW_FILE_VERSION ".fw"
|
||||
|
||||
#define MAC_LEADING_ZERO_CNT (ALIGN(ETH_ALEN, sizeof(u32)) - ETH_ALEN)
|
||||
|
||||
/* Time in jiffies before concluding the transmitter is hung */
|
||||
#define TX_TIMEOUT (5*HZ)
|
||||
|
||||
@ -3227,16 +3225,29 @@ static void bnx2x_drv_info_ether_stat(struct bnx2x *bp)
|
||||
{
|
||||
struct eth_stats_info *ether_stat =
|
||||
&bp->slowpath->drv_info_to_mcp.ether_stat;
|
||||
struct bnx2x_vlan_mac_obj *mac_obj =
|
||||
&bp->sp_objs->mac_obj;
|
||||
int i;
|
||||
|
||||
strlcpy(ether_stat->version, DRV_MODULE_VERSION,
|
||||
ETH_STAT_INFO_VERSION_LEN);
|
||||
|
||||
bp->sp_objs[0].mac_obj.get_n_elements(bp, &bp->sp_objs[0].mac_obj,
|
||||
DRV_INFO_ETH_STAT_NUM_MACS_REQUIRED,
|
||||
ether_stat->mac_local);
|
||||
|
||||
/* get DRV_INFO_ETH_STAT_NUM_MACS_REQUIRED macs, placing them in the
|
||||
* mac_local field in ether_stat struct. The base address is offset by 2
|
||||
* bytes to account for the field being 8 bytes but a mac address is
|
||||
* only 6 bytes. Likewise, the stride for the get_n_elements function is
|
||||
* 2 bytes to compensate from the 6 bytes of a mac to the 8 bytes
|
||||
* allocated by the ether_stat struct, so the macs will land in their
|
||||
* proper positions.
|
||||
*/
|
||||
for (i = 0; i < DRV_INFO_ETH_STAT_NUM_MACS_REQUIRED; i++)
|
||||
memset(ether_stat->mac_local + i, 0,
|
||||
sizeof(ether_stat->mac_local[0]));
|
||||
mac_obj->get_n_elements(bp, &bp->sp_objs[0].mac_obj,
|
||||
DRV_INFO_ETH_STAT_NUM_MACS_REQUIRED,
|
||||
ether_stat->mac_local + MAC_PAD, MAC_PAD,
|
||||
ETH_ALEN);
|
||||
ether_stat->mtu_size = bp->dev->mtu;
|
||||
|
||||
if (bp->dev->features & NETIF_F_RXCSUM)
|
||||
ether_stat->feature_flags |= FEATURE_ETH_CHKSUM_OFFLOAD_MASK;
|
||||
if (bp->dev->features & NETIF_F_TSO)
|
||||
@ -3258,8 +3269,7 @@ static void bnx2x_drv_info_fcoe_stat(struct bnx2x *bp)
|
||||
if (!CNIC_LOADED(bp))
|
||||
return;
|
||||
|
||||
memcpy(fcoe_stat->mac_local + MAC_LEADING_ZERO_CNT,
|
||||
bp->fip_mac, ETH_ALEN);
|
||||
memcpy(fcoe_stat->mac_local + MAC_PAD, bp->fip_mac, ETH_ALEN);
|
||||
|
||||
fcoe_stat->qos_priority =
|
||||
app->traffic_type_priority[LLFC_TRAFFIC_TYPE_FCOE];
|
||||
@ -3361,8 +3371,8 @@ static void bnx2x_drv_info_iscsi_stat(struct bnx2x *bp)
|
||||
if (!CNIC_LOADED(bp))
|
||||
return;
|
||||
|
||||
memcpy(iscsi_stat->mac_local + MAC_LEADING_ZERO_CNT,
|
||||
bp->cnic_eth_dev.iscsi_mac, ETH_ALEN);
|
||||
memcpy(iscsi_stat->mac_local + MAC_PAD, bp->cnic_eth_dev.iscsi_mac,
|
||||
ETH_ALEN);
|
||||
|
||||
iscsi_stat->qos_priority =
|
||||
app->traffic_type_priority[LLFC_TRAFFIC_TYPE_ISCSI];
|
||||
@ -9525,6 +9535,10 @@ sp_rtnl_not_reset:
|
||||
bnx2x_vfpf_storm_rx_mode(bp);
|
||||
}
|
||||
|
||||
if (test_and_clear_bit(BNX2X_SP_RTNL_HYPERVISOR_VLAN,
|
||||
&bp->sp_rtnl_state))
|
||||
bnx2x_pf_set_vfs_vlan(bp);
|
||||
|
||||
/* work which needs rtnl lock not-taken (as it takes the lock itself and
|
||||
* can be called from other contexts as well)
|
||||
*/
|
||||
@ -11798,6 +11812,8 @@ static const struct net_device_ops bnx2x_netdev_ops = {
|
||||
.ndo_setup_tc = bnx2x_setup_tc,
|
||||
#ifdef CONFIG_BNX2X_SRIOV
|
||||
.ndo_set_vf_mac = bnx2x_set_vf_mac,
|
||||
.ndo_set_vf_vlan = bnx2x_set_vf_vlan,
|
||||
.ndo_get_vf_config = bnx2x_get_vf_config,
|
||||
#endif
|
||||
#ifdef NETDEV_FCOE_WWNN
|
||||
.ndo_fcoe_get_wwn = bnx2x_fcoe_get_wwn,
|
||||
|
@ -30,8 +30,6 @@
|
||||
|
||||
#define BNX2X_MAX_EMUL_MULTI 16
|
||||
|
||||
#define MAC_LEADING_ZERO_CNT (ALIGN(ETH_ALEN, sizeof(u32)) - ETH_ALEN)
|
||||
|
||||
/**** Exe Queue interfaces ****/
|
||||
|
||||
/**
|
||||
@ -444,30 +442,21 @@ static bool bnx2x_put_credit_vlan_mac(struct bnx2x_vlan_mac_obj *o)
|
||||
}
|
||||
|
||||
static int bnx2x_get_n_elements(struct bnx2x *bp, struct bnx2x_vlan_mac_obj *o,
|
||||
int n, u8 *buf)
|
||||
int n, u8 *base, u8 stride, u8 size)
|
||||
{
|
||||
struct bnx2x_vlan_mac_registry_elem *pos;
|
||||
u8 *next = buf;
|
||||
u8 *next = base;
|
||||
int counter = 0;
|
||||
|
||||
/* traverse list */
|
||||
list_for_each_entry(pos, &o->head, link) {
|
||||
if (counter < n) {
|
||||
/* place leading zeroes in buffer */
|
||||
memset(next, 0, MAC_LEADING_ZERO_CNT);
|
||||
|
||||
/* place mac after leading zeroes*/
|
||||
memcpy(next + MAC_LEADING_ZERO_CNT, pos->u.mac.mac,
|
||||
ETH_ALEN);
|
||||
|
||||
/* calculate address of next element and
|
||||
* advance counter
|
||||
*/
|
||||
memcpy(next, &pos->u, size);
|
||||
counter++;
|
||||
next = buf + counter * ALIGN(ETH_ALEN, sizeof(u32));
|
||||
DP(BNX2X_MSG_SP, "copied element number %d to address %p element was:\n",
|
||||
counter, next);
|
||||
next += stride + size;
|
||||
|
||||
DP(BNX2X_MSG_SP, "copied element number %d to address %p element was %pM\n",
|
||||
counter, next, pos->u.mac.mac);
|
||||
}
|
||||
}
|
||||
return counter * ETH_ALEN;
|
||||
@ -2013,6 +2002,7 @@ void bnx2x_init_vlan_obj(struct bnx2x *bp,
|
||||
vlan_obj->check_move = bnx2x_check_move;
|
||||
vlan_obj->ramrod_cmd =
|
||||
RAMROD_CMD_ID_ETH_CLASSIFICATION_RULES;
|
||||
vlan_obj->get_n_elements = bnx2x_get_n_elements;
|
||||
|
||||
/* Exe Queue */
|
||||
bnx2x_exe_queue_init(bp,
|
||||
|
@ -313,8 +313,9 @@ struct bnx2x_vlan_mac_obj {
|
||||
*
|
||||
* @return number of copied bytes
|
||||
*/
|
||||
int (*get_n_elements)(struct bnx2x *bp, struct bnx2x_vlan_mac_obj *o,
|
||||
int n, u8 *buf);
|
||||
int (*get_n_elements)(struct bnx2x *bp,
|
||||
struct bnx2x_vlan_mac_obj *o, int n, u8 *base,
|
||||
u8 stride, u8 size);
|
||||
|
||||
/**
|
||||
* Checks if ADD-ramrod with the given params may be performed.
|
||||
@ -842,6 +843,7 @@ enum bnx2x_q_type {
|
||||
#define BNX2X_MULTI_TX_COS_E3B0 3
|
||||
#define BNX2X_MULTI_TX_COS 3 /* Maximum possible */
|
||||
|
||||
#define MAC_PAD (ALIGN(ETH_ALEN, sizeof(u32)) - ETH_ALEN)
|
||||
|
||||
struct bnx2x_queue_init_params {
|
||||
struct {
|
||||
|
@ -20,7 +20,9 @@
|
||||
#include "bnx2x.h"
|
||||
#include "bnx2x_init.h"
|
||||
#include "bnx2x_cmn.h"
|
||||
#include "bnx2x_sp.h"
|
||||
#include <linux/crc32.h>
|
||||
#include <linux/if_vlan.h>
|
||||
|
||||
/* General service functions */
|
||||
static void storm_memset_vf_to_pf(struct bnx2x *bp, u16 abs_fid,
|
||||
@ -958,6 +960,12 @@ op_err:
|
||||
BNX2X_ERR("QSETUP[%d:%d] error: rc %d\n", vf->abs_vfid, qid, vfop->rc);
|
||||
op_done:
|
||||
case BNX2X_VFOP_QSETUP_DONE:
|
||||
vf->cfg_flags |= VF_CFG_VLAN;
|
||||
smp_mb__before_clear_bit();
|
||||
set_bit(BNX2X_SP_RTNL_HYPERVISOR_VLAN,
|
||||
&bp->sp_rtnl_state);
|
||||
smp_mb__after_clear_bit();
|
||||
schedule_delayed_work(&bp->sp_rtnl_task, 0);
|
||||
bnx2x_vfop_end(bp, vf, vfop);
|
||||
return;
|
||||
default:
|
||||
@ -3029,6 +3037,88 @@ void bnx2x_enable_sriov(struct bnx2x *bp)
|
||||
DP(BNX2X_MSG_IOV, "sriov enabled\n");
|
||||
}
|
||||
|
||||
void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp)
|
||||
{
|
||||
int vfidx;
|
||||
struct pf_vf_bulletin_content *bulletin;
|
||||
|
||||
DP(BNX2X_MSG_IOV, "configuring vlan for VFs from sp-task\n");
|
||||
for_each_vf(bp, vfidx) {
|
||||
bulletin = BP_VF_BULLETIN(bp, vfidx);
|
||||
if (BP_VF(bp, vfidx)->cfg_flags & VF_CFG_VLAN)
|
||||
bnx2x_set_vf_vlan(bp->dev, vfidx, bulletin->vlan, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static int bnx2x_vf_ndo_sanity(struct bnx2x *bp, int vfidx,
|
||||
struct bnx2x_virtf *vf)
|
||||
{
|
||||
if (!IS_SRIOV(bp)) {
|
||||
BNX2X_ERR("vf ndo called though sriov is disabled\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (vfidx >= BNX2X_NR_VIRTFN(bp)) {
|
||||
BNX2X_ERR("vf ndo called for uninitialized VF. vfidx was %d BNX2X_NR_VIRTFN was %d\n",
|
||||
vfidx, BNX2X_NR_VIRTFN(bp));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!vf) {
|
||||
BNX2X_ERR("vf ndo called but vf was null. vfidx was %d\n",
|
||||
vfidx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bnx2x_get_vf_config(struct net_device *dev, int vfidx,
|
||||
struct ifla_vf_info *ivi)
|
||||
{
|
||||
struct bnx2x *bp = netdev_priv(dev);
|
||||
struct bnx2x_virtf *vf = BP_VF(bp, vfidx);
|
||||
struct bnx2x_vlan_mac_obj *mac_obj = &bnx2x_vfq(vf, 0, mac_obj);
|
||||
struct bnx2x_vlan_mac_obj *vlan_obj = &bnx2x_vfq(vf, 0, vlan_obj);
|
||||
struct pf_vf_bulletin_content *bulletin = BP_VF_BULLETIN(bp, vfidx);
|
||||
int rc;
|
||||
|
||||
/* sanity */
|
||||
rc = bnx2x_vf_ndo_sanity(bp, vfidx, vf);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
ivi->vf = vfidx;
|
||||
ivi->qos = 0;
|
||||
ivi->tx_rate = 10000; /* always 10G. TBA take from link struct */
|
||||
ivi->spoofchk = 1; /*always enabled */
|
||||
if (vf->state == VF_ENABLED) {
|
||||
/* mac and vlan are in vlan_mac objects */
|
||||
mac_obj->get_n_elements(bp, mac_obj, 1, (u8 *)&ivi->mac,
|
||||
0, ETH_ALEN);
|
||||
vlan_obj->get_n_elements(bp, vlan_obj, 1, (u8 *)&ivi->vlan,
|
||||
0, VLAN_HLEN);
|
||||
} else {
|
||||
/* mac */
|
||||
if (bulletin->valid_bitmap & (1 << MAC_ADDR_VALID))
|
||||
/* mac configured by ndo so its in bulletin board */
|
||||
memcpy(&ivi->mac, bulletin->mac, ETH_ALEN);
|
||||
else
|
||||
/* funtion has not been loaded yet. Show mac as 0s */
|
||||
memset(&ivi->mac, 0, ETH_ALEN);
|
||||
|
||||
/* vlan */
|
||||
if (bulletin->valid_bitmap & (1 << VLAN_VALID))
|
||||
/* vlan configured by ndo so its in bulletin board */
|
||||
memcpy(&ivi->vlan, &bulletin->vlan, VLAN_HLEN);
|
||||
else
|
||||
/* funtion has not been loaded yet. Show vlans as 0s */
|
||||
memset(&ivi->vlan, 0, VLAN_HLEN);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* New mac for VF. Consider these cases:
|
||||
* 1. VF hasn't been acquired yet - save the mac in local bulletin board and
|
||||
* supply at acquire.
|
||||
@ -3044,23 +3134,19 @@ void bnx2x_enable_sriov(struct bnx2x *bp)
|
||||
* VF to configure any mac for itself except for this mac. In case of a race
|
||||
* where the VF fails to see the new post on its bulletin board before sending a
|
||||
* mac configuration request, the PF will simply fail the request and VF can try
|
||||
* again after consulting its bulletin board
|
||||
* again after consulting its bulletin board.
|
||||
*/
|
||||
int bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac)
|
||||
int bnx2x_set_vf_mac(struct net_device *dev, int vfidx, u8 *mac)
|
||||
{
|
||||
struct bnx2x *bp = netdev_priv(dev);
|
||||
int rc, q_logical_state, vfidx = queue;
|
||||
int rc, q_logical_state;
|
||||
struct bnx2x_virtf *vf = BP_VF(bp, vfidx);
|
||||
struct pf_vf_bulletin_content *bulletin = BP_VF_BULLETIN(bp, vfidx);
|
||||
|
||||
/* if SRIOV is disabled there is nothing to do (and somewhere, someone
|
||||
* has erred).
|
||||
*/
|
||||
if (!IS_SRIOV(bp)) {
|
||||
BNX2X_ERR("bnx2x_set_vf_mac called though sriov is disabled\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* sanity */
|
||||
rc = bnx2x_vf_ndo_sanity(bp, vfidx, vf);
|
||||
if (rc)
|
||||
return rc;
|
||||
if (!is_valid_ether_addr(mac)) {
|
||||
BNX2X_ERR("mac address invalid\n");
|
||||
return -EINVAL;
|
||||
@ -3085,7 +3171,7 @@ int bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac)
|
||||
if (vf->state == VF_ENABLED &&
|
||||
q_logical_state == BNX2X_Q_LOGICAL_STATE_ACTIVE) {
|
||||
/* configure the mac in device on this vf's queue */
|
||||
unsigned long flags = 0;
|
||||
unsigned long ramrod_flags = 0;
|
||||
struct bnx2x_vlan_mac_obj *mac_obj = &bnx2x_vfq(vf, 0, mac_obj);
|
||||
|
||||
/* must lock vfpf channel to protect against vf flows */
|
||||
@ -3106,14 +3192,133 @@ int bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac)
|
||||
}
|
||||
|
||||
/* configure the new mac to device */
|
||||
__set_bit(RAMROD_COMP_WAIT, &flags);
|
||||
__set_bit(RAMROD_COMP_WAIT, &ramrod_flags);
|
||||
bnx2x_set_mac_one(bp, (u8 *)&bulletin->mac, mac_obj, true,
|
||||
BNX2X_ETH_MAC, &flags);
|
||||
BNX2X_ETH_MAC, &ramrod_flags);
|
||||
|
||||
bnx2x_unlock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_SET_MAC);
|
||||
}
|
||||
|
||||
return rc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bnx2x_set_vf_vlan(struct net_device *dev, int vfidx, u16 vlan, u8 qos)
|
||||
{
|
||||
struct bnx2x *bp = netdev_priv(dev);
|
||||
int rc, q_logical_state;
|
||||
struct bnx2x_virtf *vf = BP_VF(bp, vfidx);
|
||||
struct pf_vf_bulletin_content *bulletin = BP_VF_BULLETIN(bp, vfidx);
|
||||
|
||||
/* sanity */
|
||||
rc = bnx2x_vf_ndo_sanity(bp, vfidx, vf);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (vlan > 4095) {
|
||||
BNX2X_ERR("illegal vlan value %d\n", vlan);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DP(BNX2X_MSG_IOV, "configuring VF %d with VLAN %d qos %d\n",
|
||||
vfidx, vlan, 0);
|
||||
|
||||
/* 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 store it here in case the VF is not up yet and we can only
|
||||
* configure the vlan later when it does.
|
||||
*/
|
||||
bulletin->valid_bitmap |= 1 << VLAN_VALID;
|
||||
bulletin->vlan = vlan;
|
||||
|
||||
/* is vf initialized and queue set up? */
|
||||
q_logical_state =
|
||||
bnx2x_get_q_logical_state(bp, &bnx2x_vfq(vf, 0, sp_obj));
|
||||
if (vf->state == VF_ENABLED &&
|
||||
q_logical_state == BNX2X_Q_LOGICAL_STATE_ACTIVE) {
|
||||
/* 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_vfq(vf, 0, 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;
|
||||
|
||||
memset(&ramrod_param, 0, sizeof(ramrod_param));
|
||||
|
||||
/* must lock vfpf channel to protect against vf flows */
|
||||
bnx2x_lock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_SET_VLAN);
|
||||
|
||||
/* remove existing vlans */
|
||||
__set_bit(RAMROD_COMP_WAIT, &ramrod_flags);
|
||||
rc = vlan_obj->delete_all(bp, vlan_obj, &vlan_mac_flags,
|
||||
&ramrod_flags);
|
||||
if (rc) {
|
||||
BNX2X_ERR("failed to delete vlans\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* 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_vfq(vf, 0, 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");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* 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");
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* clear the flag indicating that this VF needs its vlan
|
||||
* (will only be set if the HV configured th Vlan before vf was
|
||||
* and we were called because the VF came up later
|
||||
*/
|
||||
vf->cfg_flags &= ~VF_CFG_VLAN;
|
||||
|
||||
bnx2x_unlock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_SET_VLAN);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* crc is the first field in the bulletin board. compute the crc over the
|
||||
@ -3165,6 +3370,10 @@ enum sample_bulletin_result bnx2x_sample_bulletin(struct bnx2x *bp)
|
||||
memcpy(bp->dev->dev_addr, bulletin.mac, ETH_ALEN);
|
||||
}
|
||||
|
||||
/* the vlan in bulletin board is valid and is new */
|
||||
if (bulletin.valid_bitmap & 1 << VLAN_VALID)
|
||||
memcpy(&bulletin.vlan, &bp->old_bulletin.vlan, VLAN_HLEN);
|
||||
|
||||
/* copy new bulletin board to bp */
|
||||
bp->old_bulletin = bulletin;
|
||||
|
||||
|
@ -193,6 +193,7 @@ struct bnx2x_virtf {
|
||||
#define VF_CFG_TPA 0x0004
|
||||
#define VF_CFG_INT_SIMD 0x0008
|
||||
#define VF_CACHE_LINE 0x0010
|
||||
#define VF_CFG_VLAN 0x0020
|
||||
|
||||
u8 state;
|
||||
#define VF_FREE 0 /* VF ready to be acquired holds no resc */
|
||||
@ -757,6 +758,7 @@ static inline int bnx2x_vf_headroom(struct bnx2x *bp)
|
||||
{
|
||||
return bp->vfdb->sriov.nr_virtfn * BNX2X_CLIENTS_PER_VF;
|
||||
}
|
||||
void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp);
|
||||
|
||||
#else /* CONFIG_BNX2X_SRIOV */
|
||||
|
||||
@ -804,6 +806,7 @@ static inline enum sample_bulletin_result bnx2x_sample_bulletin(struct bnx2x *bp
|
||||
|
||||
static inline int bnx2x_vf_map_doorbells(struct bnx2x *bp) {return 0; }
|
||||
static inline int bnx2x_vf_pci_alloc(struct bnx2x *bp) {return 0; }
|
||||
static inline void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp) {}
|
||||
|
||||
#endif /* CONFIG_BNX2X_SRIOV */
|
||||
#endif /* bnx2x_sriov.h */
|
||||
|
@ -328,9 +328,15 @@ struct pf_vf_bulletin_content {
|
||||
#define MAC_ADDR_VALID 0 /* alert the vf that a new mac address
|
||||
* is available for it
|
||||
*/
|
||||
#define VLAN_VALID 1 /* when set, the vf should not access
|
||||
* the vfpf channel
|
||||
*/
|
||||
|
||||
u8 mac[ETH_ALEN];
|
||||
u8 padding[2];
|
||||
u8 mac_padding[2];
|
||||
|
||||
u16 vlan;
|
||||
u8 vlan_padding[6];
|
||||
};
|
||||
|
||||
union pf_vf_bulletin {
|
||||
@ -353,6 +359,7 @@ enum channel_tlvs {
|
||||
CHANNEL_TLV_LIST_END,
|
||||
CHANNEL_TLV_FLR,
|
||||
CHANNEL_TLV_PF_SET_MAC,
|
||||
CHANNEL_TLV_PF_SET_VLAN,
|
||||
CHANNEL_TLV_MAX
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user