Add SR-IOV guest support to the mlx5en driver.
This patch adds the missing pieces needed for device setup using the mlx5en driver inside a virtual machine which is providing hardware access through SR-IOV. Sponsored by: Mellanox Technologies MFC after: 1 week
This commit is contained in:
parent
d8571d3ea3
commit
76a5241f2c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=301545
@ -33,6 +33,7 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/cache.h>
|
||||
#include <linux/rbtree.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/semaphore.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
@ -471,6 +471,241 @@ int mlx5_set_nic_vport_promisc(struct mlx5_core_dev *mdev, int vport,
|
||||
return mlx5_modify_nic_vport_context(mdev, in, sizeof(in));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mlx5_set_nic_vport_promisc);
|
||||
|
||||
int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
|
||||
u32 vport,
|
||||
enum mlx5_list_type list_type,
|
||||
u8 addr_list[][ETH_ALEN],
|
||||
int *list_size)
|
||||
{
|
||||
u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)];
|
||||
void *nic_vport_ctx;
|
||||
int max_list_size;
|
||||
int req_list_size;
|
||||
u8 *mac_addr;
|
||||
int out_sz;
|
||||
void *out;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
req_list_size = *list_size;
|
||||
|
||||
max_list_size = (list_type == MLX5_NIC_VPORT_LIST_TYPE_UC) ?
|
||||
1 << MLX5_CAP_GEN_MAX(dev, log_max_current_uc_list) :
|
||||
1 << MLX5_CAP_GEN_MAX(dev, log_max_current_mc_list);
|
||||
|
||||
if (req_list_size > max_list_size) {
|
||||
mlx5_core_warn(dev, "Requested list size (%d) > (%d) max_list_size\n",
|
||||
req_list_size, max_list_size);
|
||||
req_list_size = max_list_size;
|
||||
}
|
||||
|
||||
out_sz = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) +
|
||||
req_list_size * MLX5_ST_SZ_BYTES(mac_address_layout);
|
||||
|
||||
memset(in, 0, sizeof(in));
|
||||
out = kzalloc(out_sz, GFP_KERNEL);
|
||||
if (!out)
|
||||
return -ENOMEM;
|
||||
|
||||
MLX5_SET(query_nic_vport_context_in, in, opcode,
|
||||
MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT);
|
||||
MLX5_SET(query_nic_vport_context_in, in, allowed_list_type, list_type);
|
||||
MLX5_SET(query_nic_vport_context_in, in, vport_number, vport);
|
||||
|
||||
if (vport)
|
||||
MLX5_SET(query_nic_vport_context_in, in, other_vport, 1);
|
||||
|
||||
err = mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, out_sz);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
nic_vport_ctx = MLX5_ADDR_OF(query_nic_vport_context_out, out,
|
||||
nic_vport_context);
|
||||
req_list_size = MLX5_GET(nic_vport_context, nic_vport_ctx,
|
||||
allowed_list_size);
|
||||
|
||||
*list_size = req_list_size;
|
||||
for (i = 0; i < req_list_size; i++) {
|
||||
mac_addr = MLX5_ADDR_OF(nic_vport_context,
|
||||
nic_vport_ctx,
|
||||
current_uc_mac_address[i]) + 2;
|
||||
ether_addr_copy(addr_list[i], mac_addr);
|
||||
}
|
||||
out:
|
||||
kfree(out);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_mac_list);
|
||||
|
||||
int mlx5_modify_nic_vport_mac_list(struct mlx5_core_dev *dev,
|
||||
enum mlx5_list_type list_type,
|
||||
u8 addr_list[][ETH_ALEN],
|
||||
int list_size)
|
||||
{
|
||||
u32 out[MLX5_ST_SZ_DW(modify_nic_vport_context_out)];
|
||||
void *nic_vport_ctx;
|
||||
int max_list_size;
|
||||
int in_sz;
|
||||
void *in;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
max_list_size = list_type == MLX5_NIC_VPORT_LIST_TYPE_UC ?
|
||||
1 << MLX5_CAP_GEN(dev, log_max_current_uc_list) :
|
||||
1 << MLX5_CAP_GEN(dev, log_max_current_mc_list);
|
||||
|
||||
if (list_size > max_list_size)
|
||||
return -ENOSPC;
|
||||
|
||||
in_sz = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) +
|
||||
list_size * MLX5_ST_SZ_BYTES(mac_address_layout);
|
||||
|
||||
memset(out, 0, sizeof(out));
|
||||
in = kzalloc(in_sz, GFP_KERNEL);
|
||||
if (!in)
|
||||
return -ENOMEM;
|
||||
|
||||
MLX5_SET(modify_nic_vport_context_in, in, opcode,
|
||||
MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT);
|
||||
MLX5_SET(modify_nic_vport_context_in, in,
|
||||
field_select.addresses_list, 1);
|
||||
|
||||
nic_vport_ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in,
|
||||
nic_vport_context);
|
||||
|
||||
MLX5_SET(nic_vport_context, nic_vport_ctx,
|
||||
allowed_list_type, list_type);
|
||||
MLX5_SET(nic_vport_context, nic_vport_ctx,
|
||||
allowed_list_size, list_size);
|
||||
|
||||
for (i = 0; i < list_size; i++) {
|
||||
u8 *curr_mac = MLX5_ADDR_OF(nic_vport_context,
|
||||
nic_vport_ctx,
|
||||
current_uc_mac_address[i]) + 2;
|
||||
ether_addr_copy(curr_mac, addr_list[i]);
|
||||
}
|
||||
|
||||
err = mlx5_cmd_exec_check_status(dev, in, in_sz, out, sizeof(out));
|
||||
kfree(in);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_mac_list);
|
||||
|
||||
int mlx5_query_nic_vport_vlan_list(struct mlx5_core_dev *dev,
|
||||
u32 vport,
|
||||
u16 *vlan_list,
|
||||
int *list_size)
|
||||
{
|
||||
u32 in[MLX5_ST_SZ_DW(query_nic_vport_context_in)];
|
||||
void *nic_vport_ctx;
|
||||
int max_list_size;
|
||||
int req_list_size;
|
||||
int out_sz;
|
||||
void *out;
|
||||
void *vlan_addr;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
req_list_size = *list_size;
|
||||
|
||||
max_list_size = 1 << MLX5_CAP_GEN_MAX(dev, log_max_vlan_list);
|
||||
|
||||
if (req_list_size > max_list_size) {
|
||||
mlx5_core_warn(dev, "Requested list size (%d) > (%d) max_list_size\n",
|
||||
req_list_size, max_list_size);
|
||||
req_list_size = max_list_size;
|
||||
}
|
||||
|
||||
out_sz = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) +
|
||||
req_list_size * MLX5_ST_SZ_BYTES(vlan_layout);
|
||||
|
||||
memset(in, 0, sizeof(in));
|
||||
out = kzalloc(out_sz, GFP_KERNEL);
|
||||
if (!out)
|
||||
return -ENOMEM;
|
||||
|
||||
MLX5_SET(query_nic_vport_context_in, in, opcode,
|
||||
MLX5_CMD_OP_QUERY_NIC_VPORT_CONTEXT);
|
||||
MLX5_SET(query_nic_vport_context_in, in, allowed_list_type,
|
||||
MLX5_NIC_VPORT_CONTEXT_ALLOWED_LIST_TYPE_VLAN_LIST);
|
||||
MLX5_SET(query_nic_vport_context_in, in, vport_number, vport);
|
||||
|
||||
if (vport)
|
||||
MLX5_SET(query_nic_vport_context_in, in, other_vport, 1);
|
||||
|
||||
err = mlx5_cmd_exec_check_status(dev, in, sizeof(in), out, out_sz);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
nic_vport_ctx = MLX5_ADDR_OF(query_nic_vport_context_out, out,
|
||||
nic_vport_context);
|
||||
req_list_size = MLX5_GET(nic_vport_context, nic_vport_ctx,
|
||||
allowed_list_size);
|
||||
|
||||
*list_size = req_list_size;
|
||||
for (i = 0; i < req_list_size; i++) {
|
||||
vlan_addr = MLX5_ADDR_OF(nic_vport_context, nic_vport_ctx,
|
||||
current_uc_mac_address[i]);
|
||||
vlan_list[i] = MLX5_GET(vlan_layout, vlan_addr, vlan);
|
||||
}
|
||||
out:
|
||||
kfree(out);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_vlan_list);
|
||||
|
||||
int mlx5_modify_nic_vport_vlans(struct mlx5_core_dev *dev,
|
||||
u16 vlans[],
|
||||
int list_size)
|
||||
{
|
||||
u32 out[MLX5_ST_SZ_DW(modify_nic_vport_context_out)];
|
||||
void *nic_vport_ctx;
|
||||
int max_list_size;
|
||||
int in_sz;
|
||||
void *in;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
max_list_size = 1 << MLX5_CAP_GEN(dev, log_max_vlan_list);
|
||||
|
||||
if (list_size > max_list_size)
|
||||
return -ENOSPC;
|
||||
|
||||
in_sz = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) +
|
||||
list_size * MLX5_ST_SZ_BYTES(vlan_layout);
|
||||
|
||||
memset(out, 0, sizeof(out));
|
||||
in = kzalloc(in_sz, GFP_KERNEL);
|
||||
if (!in)
|
||||
return -ENOMEM;
|
||||
|
||||
MLX5_SET(modify_nic_vport_context_in, in, opcode,
|
||||
MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT);
|
||||
MLX5_SET(modify_nic_vport_context_in, in,
|
||||
field_select.addresses_list, 1);
|
||||
|
||||
nic_vport_ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in,
|
||||
nic_vport_context);
|
||||
|
||||
MLX5_SET(nic_vport_context, nic_vport_ctx,
|
||||
allowed_list_type, MLX5_NIC_VPORT_LIST_TYPE_VLAN);
|
||||
MLX5_SET(nic_vport_context, nic_vport_ctx,
|
||||
allowed_list_size, list_size);
|
||||
|
||||
for (i = 0; i < list_size; i++) {
|
||||
void *vlan_addr = MLX5_ADDR_OF(nic_vport_context,
|
||||
nic_vport_ctx,
|
||||
current_uc_mac_address[i]);
|
||||
MLX5_SET(vlan_layout, vlan_addr, vlan, vlans[i]);
|
||||
}
|
||||
|
||||
err = mlx5_cmd_exec_check_status(dev, in, in_sz, out, sizeof(out));
|
||||
kfree(in);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_vlans);
|
||||
|
||||
int mlx5_set_nic_vport_permanent_mac(struct mlx5_core_dev *mdev, int vport,
|
||||
u8 *addr)
|
||||
{
|
||||
@ -785,6 +1020,129 @@ int mlx5_set_eswitch_cvlan_info(struct mlx5_core_dev *mdev, u8 vport,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mlx5_set_eswitch_cvlan_info);
|
||||
|
||||
int mlx5_arm_vport_context_events(struct mlx5_core_dev *mdev,
|
||||
u8 vport,
|
||||
u32 events_mask)
|
||||
{
|
||||
u32 *in;
|
||||
u32 inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
|
||||
void *nic_vport_ctx;
|
||||
int err;
|
||||
|
||||
in = mlx5_vzalloc(inlen);
|
||||
if (!in)
|
||||
return -ENOMEM;
|
||||
|
||||
MLX5_SET(modify_nic_vport_context_in,
|
||||
in,
|
||||
opcode,
|
||||
MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT);
|
||||
MLX5_SET(modify_nic_vport_context_in,
|
||||
in,
|
||||
field_select.change_event,
|
||||
1);
|
||||
MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
|
||||
if (vport)
|
||||
MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1);
|
||||
nic_vport_ctx = MLX5_ADDR_OF(modify_nic_vport_context_in,
|
||||
in,
|
||||
nic_vport_context);
|
||||
|
||||
MLX5_SET(nic_vport_context, nic_vport_ctx, arm_change_event, 1);
|
||||
|
||||
if (events_mask & MLX5_UC_ADDR_CHANGE)
|
||||
MLX5_SET(nic_vport_context,
|
||||
nic_vport_ctx,
|
||||
event_on_uc_address_change,
|
||||
1);
|
||||
if (events_mask & MLX5_MC_ADDR_CHANGE)
|
||||
MLX5_SET(nic_vport_context,
|
||||
nic_vport_ctx,
|
||||
event_on_mc_address_change,
|
||||
1);
|
||||
if (events_mask & MLX5_VLAN_CHANGE)
|
||||
MLX5_SET(nic_vport_context,
|
||||
nic_vport_ctx,
|
||||
event_on_vlan_change,
|
||||
1);
|
||||
if (events_mask & MLX5_PROMISC_CHANGE)
|
||||
MLX5_SET(nic_vport_context,
|
||||
nic_vport_ctx,
|
||||
event_on_promisc_change,
|
||||
1);
|
||||
if (events_mask & MLX5_MTU_CHANGE)
|
||||
MLX5_SET(nic_vport_context,
|
||||
nic_vport_ctx,
|
||||
event_on_mtu,
|
||||
1);
|
||||
|
||||
err = mlx5_modify_nic_vport_context(mdev, in, inlen);
|
||||
|
||||
kvfree(in);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mlx5_arm_vport_context_events);
|
||||
|
||||
int mlx5_query_vport_promisc(struct mlx5_core_dev *mdev,
|
||||
u32 vport,
|
||||
u8 *promisc_uc,
|
||||
u8 *promisc_mc,
|
||||
u8 *promisc_all)
|
||||
{
|
||||
u32 *out;
|
||||
int outlen = MLX5_ST_SZ_BYTES(query_nic_vport_context_out);
|
||||
int err;
|
||||
|
||||
out = kzalloc(outlen, GFP_KERNEL);
|
||||
if (!out)
|
||||
return -ENOMEM;
|
||||
|
||||
err = mlx5_query_nic_vport_context(mdev, vport, out, outlen);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
*promisc_uc = MLX5_GET(query_nic_vport_context_out, out,
|
||||
nic_vport_context.promisc_uc);
|
||||
*promisc_mc = MLX5_GET(query_nic_vport_context_out, out,
|
||||
nic_vport_context.promisc_mc);
|
||||
*promisc_all = MLX5_GET(query_nic_vport_context_out, out,
|
||||
nic_vport_context.promisc_all);
|
||||
|
||||
out:
|
||||
kfree(out);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mlx5_query_nic_vport_promisc);
|
||||
|
||||
int mlx5_modify_nic_vport_promisc(struct mlx5_core_dev *mdev,
|
||||
int promisc_uc,
|
||||
int promisc_mc,
|
||||
int promisc_all)
|
||||
{
|
||||
void *in;
|
||||
int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in);
|
||||
int err;
|
||||
|
||||
in = mlx5_vzalloc(inlen);
|
||||
if (!in) {
|
||||
mlx5_core_err(mdev, "failed to allocate inbox\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
MLX5_SET(modify_nic_vport_context_in, in, field_select.promisc, 1);
|
||||
MLX5_SET(modify_nic_vport_context_in, in,
|
||||
nic_vport_context.promisc_uc, promisc_uc);
|
||||
MLX5_SET(modify_nic_vport_context_in, in,
|
||||
nic_vport_context.promisc_mc, promisc_mc);
|
||||
MLX5_SET(modify_nic_vport_context_in, in,
|
||||
nic_vport_context.promisc_all, promisc_all);
|
||||
|
||||
err = mlx5_modify_nic_vport_context(mdev, in, inlen);
|
||||
kvfree(in);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mlx5_modify_nic_vport_promisc);
|
||||
|
||||
int mlx5_query_vport_counter(struct mlx5_core_dev *dev,
|
||||
u8 port_num, u16 vport_num,
|
||||
void *out, int out_size)
|
||||
|
@ -390,6 +390,49 @@ mlx5e_add_eth_addr_rule(struct mlx5e_priv *priv,
|
||||
return (err);
|
||||
}
|
||||
|
||||
static int mlx5e_vport_context_update_vlans(struct mlx5e_priv *priv)
|
||||
{
|
||||
struct ifnet *ifp = priv->ifp;
|
||||
int max_list_size;
|
||||
int list_size;
|
||||
u16 *vlans;
|
||||
int vlan;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
list_size = 0;
|
||||
for_each_set_bit(vlan, priv->vlan.active_vlans, VLAN_N_VID)
|
||||
list_size++;
|
||||
|
||||
max_list_size = 1 << MLX5_CAP_GEN(priv->mdev, log_max_vlan_list);
|
||||
|
||||
if (list_size > max_list_size) {
|
||||
if_printf(ifp,
|
||||
"ifnet vlans list size (%d) > (%d) max vport list size, some vlans will be dropped\n",
|
||||
list_size, max_list_size);
|
||||
list_size = max_list_size;
|
||||
}
|
||||
|
||||
vlans = kcalloc(list_size, sizeof(*vlans), GFP_KERNEL);
|
||||
if (!vlans)
|
||||
return -ENOMEM;
|
||||
|
||||
i = 0;
|
||||
for_each_set_bit(vlan, priv->vlan.active_vlans, VLAN_N_VID) {
|
||||
if (i >= list_size)
|
||||
break;
|
||||
vlans[i++] = vlan;
|
||||
}
|
||||
|
||||
err = mlx5_modify_nic_vport_vlans(priv->mdev, vlans, list_size);
|
||||
if (err)
|
||||
if_printf(ifp, "Failed to modify vport vlans list err(%d)\n",
|
||||
err);
|
||||
|
||||
kfree(vlans);
|
||||
return err;
|
||||
}
|
||||
|
||||
enum mlx5e_vlan_rule_type {
|
||||
MLX5E_VLAN_RULE_TYPE_UNTAGGED,
|
||||
MLX5E_VLAN_RULE_TYPE_ANY_VID,
|
||||
@ -448,6 +491,7 @@ mlx5e_add_vlan_rule(struct mlx5e_priv *priv,
|
||||
outer_headers.first_vid);
|
||||
MLX5_SET(fte_match_param, match_value, outer_headers.first_vid,
|
||||
vid);
|
||||
mlx5e_vport_context_update_vlans(priv);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -478,6 +522,7 @@ mlx5e_del_vlan_rule(struct mlx5e_priv *priv,
|
||||
case MLX5E_VLAN_RULE_TYPE_MATCH_VID:
|
||||
mlx5_del_flow_table_entry(priv->ft.vlan,
|
||||
priv->vlan.active_vlans_ft_ix[vid]);
|
||||
mlx5e_vport_context_update_vlans(priv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -628,6 +673,91 @@ mlx5e_sync_ifp_addr(struct mlx5e_priv *priv)
|
||||
if_maddr_runlock(ifp);
|
||||
}
|
||||
|
||||
static void mlx5e_fill_addr_array(struct mlx5e_priv *priv, int list_type,
|
||||
u8 addr_array[][ETH_ALEN], int size)
|
||||
{
|
||||
bool is_uc = (list_type == MLX5_NIC_VPORT_LIST_TYPE_UC);
|
||||
struct ifnet *ifp = priv->ifp;
|
||||
struct mlx5e_eth_addr_hash_node *hn;
|
||||
struct mlx5e_eth_addr_hash_head *addr_list;
|
||||
struct mlx5e_eth_addr_hash_node *tmp;
|
||||
int i = 0;
|
||||
int hi;
|
||||
|
||||
addr_list = is_uc ? priv->eth_addr.if_uc : priv->eth_addr.if_mc;
|
||||
|
||||
if (is_uc) /* Make sure our own address is pushed first */
|
||||
ether_addr_copy(addr_array[i++], IF_LLADDR(ifp));
|
||||
else if (priv->eth_addr.broadcast_enabled)
|
||||
ether_addr_copy(addr_array[i++], ifp->if_broadcastaddr);
|
||||
|
||||
mlx5e_for_each_hash_node(hn, tmp, addr_list, hi) {
|
||||
if (ether_addr_equal(IF_LLADDR(ifp), hn->ai.addr))
|
||||
continue;
|
||||
if (i >= size)
|
||||
break;
|
||||
ether_addr_copy(addr_array[i++], hn->ai.addr);
|
||||
}
|
||||
}
|
||||
|
||||
static void mlx5e_vport_context_update_addr_list(struct mlx5e_priv *priv,
|
||||
int list_type)
|
||||
{
|
||||
bool is_uc = (list_type == MLX5_NIC_VPORT_LIST_TYPE_UC);
|
||||
struct mlx5e_eth_addr_hash_node *hn;
|
||||
u8 (*addr_array)[ETH_ALEN] = NULL;
|
||||
struct mlx5e_eth_addr_hash_head *addr_list;
|
||||
struct mlx5e_eth_addr_hash_node *tmp;
|
||||
int max_size;
|
||||
int size;
|
||||
int err;
|
||||
int hi;
|
||||
|
||||
size = is_uc ? 0 : (priv->eth_addr.broadcast_enabled ? 1 : 0);
|
||||
max_size = is_uc ?
|
||||
1 << MLX5_CAP_GEN(priv->mdev, log_max_current_uc_list) :
|
||||
1 << MLX5_CAP_GEN(priv->mdev, log_max_current_mc_list);
|
||||
|
||||
addr_list = is_uc ? priv->eth_addr.if_uc : priv->eth_addr.if_mc;
|
||||
mlx5e_for_each_hash_node(hn, tmp, addr_list, hi)
|
||||
size++;
|
||||
|
||||
if (size > max_size) {
|
||||
if_printf(priv->ifp,
|
||||
"ifp %s list size (%d) > (%d) max vport list size, some addresses will be dropped\n",
|
||||
is_uc ? "UC" : "MC", size, max_size);
|
||||
size = max_size;
|
||||
}
|
||||
|
||||
if (size) {
|
||||
addr_array = kcalloc(size, ETH_ALEN, GFP_KERNEL);
|
||||
if (!addr_array) {
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
mlx5e_fill_addr_array(priv, list_type, addr_array, size);
|
||||
}
|
||||
|
||||
err = mlx5_modify_nic_vport_mac_list(priv->mdev, list_type, addr_array, size);
|
||||
out:
|
||||
if (err)
|
||||
if_printf(priv->ifp,
|
||||
"Failed to modify vport %s list err(%d)\n",
|
||||
is_uc ? "UC" : "MC", err);
|
||||
kfree(addr_array);
|
||||
}
|
||||
|
||||
static void mlx5e_vport_context_update(struct mlx5e_priv *priv)
|
||||
{
|
||||
struct mlx5e_eth_addr_db *ea = &priv->eth_addr;
|
||||
|
||||
mlx5e_vport_context_update_addr_list(priv, MLX5_NIC_VPORT_LIST_TYPE_UC);
|
||||
mlx5e_vport_context_update_addr_list(priv, MLX5_NIC_VPORT_LIST_TYPE_MC);
|
||||
mlx5_modify_nic_vport_promisc(priv->mdev, 0,
|
||||
ea->allmulti_enabled,
|
||||
ea->promisc_enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
mlx5e_apply_ifp_addr(struct mlx5e_priv *priv)
|
||||
{
|
||||
@ -701,6 +831,8 @@ mlx5e_set_rx_mode_core(struct mlx5e_priv *priv)
|
||||
ea->promisc_enabled = promisc_enabled;
|
||||
ea->allmulti_enabled = allmulti_enabled;
|
||||
ea->broadcast_enabled = broadcast_enabled;
|
||||
|
||||
mlx5e_vport_context_update(priv);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -3001,6 +3001,13 @@ mlx5e_create_ifp(struct mlx5_core_dev *mdev)
|
||||
}
|
||||
mlx5_query_nic_vport_mac_address(priv->mdev, 0, dev_addr);
|
||||
|
||||
/* check if we should generate a random MAC address */
|
||||
if (MLX5_CAP_GEN(priv->mdev, vport_group_manager) == 0 &&
|
||||
is_zero_ether_addr(dev_addr)) {
|
||||
random_ether_addr(dev_addr);
|
||||
if_printf(ifp, "Assigned random MAC address\n");
|
||||
}
|
||||
|
||||
/* set default MTU */
|
||||
mlx5e_set_dev_port_mtu(ifp, ifp->if_mtu);
|
||||
|
||||
|
@ -38,6 +38,18 @@ int mlx5_vport_query_out_of_rx_buffer(struct mlx5_core_dev *mdev,
|
||||
u32 *out_of_rx_buffer);
|
||||
|
||||
u8 mlx5_query_vport_state(struct mlx5_core_dev *mdev, u8 opmod);
|
||||
int mlx5_arm_vport_context_events(struct mlx5_core_dev *mdev,
|
||||
u8 vport,
|
||||
u32 events_mask);
|
||||
int mlx5_query_vport_promisc(struct mlx5_core_dev *mdev,
|
||||
u32 vport,
|
||||
u8 *promisc_uc,
|
||||
u8 *promisc_mc,
|
||||
u8 *promisc_all);
|
||||
int mlx5_modify_nic_vport_promisc(struct mlx5_core_dev *mdev,
|
||||
int promisc_uc,
|
||||
int promisc_mc,
|
||||
int promisc_all);
|
||||
int mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev,
|
||||
u32 vport, u8 *addr);
|
||||
int mlx5_set_nic_vport_current_mac(struct mlx5_core_dev *mdev, int vport,
|
||||
@ -49,6 +61,22 @@ int mlx5_set_nic_vport_mc_list(struct mlx5_core_dev *mdev, int vport,
|
||||
int mlx5_set_nic_vport_promisc(struct mlx5_core_dev *mdev, int vport,
|
||||
bool promisc_mc, bool promisc_uc,
|
||||
bool promisc_all);
|
||||
int mlx5_query_nic_vport_mac_list(struct mlx5_core_dev *dev,
|
||||
u32 vport,
|
||||
enum mlx5_list_type list_type,
|
||||
u8 addr_list[][ETH_ALEN],
|
||||
int *list_size);
|
||||
int mlx5_modify_nic_vport_mac_list(struct mlx5_core_dev *dev,
|
||||
enum mlx5_list_type list_type,
|
||||
u8 addr_list[][ETH_ALEN],
|
||||
int list_size);
|
||||
int mlx5_query_nic_vport_vlan_list(struct mlx5_core_dev *dev,
|
||||
u32 vport,
|
||||
u16 *vlan_list,
|
||||
int *list_size);
|
||||
int mlx5_modify_nic_vport_vlans(struct mlx5_core_dev *dev,
|
||||
u16 vlans[],
|
||||
int list_size);
|
||||
int mlx5_set_nic_vport_permanent_mac(struct mlx5_core_dev *mdev, int vport,
|
||||
u8 *addr);
|
||||
int mlx5_nic_vport_enable_roce(struct mlx5_core_dev *mdev);
|
||||
|
Loading…
Reference in New Issue
Block a user