diff options
Diffstat (limited to 'sys/dev/mlx5/mlx5_core/mlx5_vport.c')
-rw-r--r-- | sys/dev/mlx5/mlx5_core/mlx5_vport.c | 128 |
1 files changed, 127 insertions, 1 deletions
diff --git a/sys/dev/mlx5/mlx5_core/mlx5_vport.c b/sys/dev/mlx5/mlx5_core/mlx5_vport.c index 803f119..5c8626b 100644 --- a/sys/dev/mlx5/mlx5_core/mlx5_vport.c +++ b/sys/dev/mlx5/mlx5_core/mlx5_vport.c @@ -328,7 +328,8 @@ int mlx5_set_nic_vport_current_mac(struct mlx5_core_dev *mdev, int vport, MLX5_SET(modify_nic_vport_context_in, in, field_select.addresses_list, 1); MLX5_SET(modify_nic_vport_context_in, in, - nic_vport_context.allowed_list_type, 0); + nic_vport_context.allowed_list_type, + MLX5_NIC_VPORT_LIST_TYPE_UC); MLX5_SET(modify_nic_vport_context_in, in, nic_vport_context.allowed_list_size, 1); @@ -345,6 +346,131 @@ int mlx5_set_nic_vport_current_mac(struct mlx5_core_dev *mdev, int vport, return err; } EXPORT_SYMBOL_GPL(mlx5_set_nic_vport_current_mac); + +int mlx5_set_nic_vport_vlan_list(struct mlx5_core_dev *dev, u32 vport, + u16 *vlan_list, int list_len) +{ + void *in, *ctx; + int i, err; + int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) + + MLX5_ST_SZ_BYTES(vlan_layout) * (int)list_len; + + int max_list_size = 1 << MLX5_CAP_GEN_MAX(dev, log_max_vlan_list); + + if (list_len > max_list_size) { + mlx5_core_warn(dev, "Requested list size (%d) > (%d) max_list_size\n", + list_len, max_list_size); + return -ENOSPC; + } + + in = mlx5_vzalloc(inlen); + if (!in) { + mlx5_core_warn(dev, "failed to allocate inbox\n"); + return -ENOMEM; + } + + MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport); + if (vport) + MLX5_SET(modify_nic_vport_context_in, in, + other_vport, 1); + MLX5_SET(modify_nic_vport_context_in, in, + field_select.addresses_list, 1); + + ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in, nic_vport_context); + + MLX5_SET(nic_vport_context, ctx, allowed_list_type, + MLX5_NIC_VPORT_LIST_TYPE_VLAN); + MLX5_SET(nic_vport_context, ctx, allowed_list_size, list_len); + + for (i = 0; i < list_len; i++) { + u8 *vlan_lout = MLX5_ADDR_OF(nic_vport_context, ctx, + current_uc_mac_address[i]); + MLX5_SET(vlan_layout, vlan_lout, vlan, vlan_list[i]); + } + + err = mlx5_modify_nic_vport_context(dev, in, inlen); + + kvfree(in); + return err; +} +EXPORT_SYMBOL_GPL(mlx5_set_nic_vport_vlan_list); + +int mlx5_set_nic_vport_mc_list(struct mlx5_core_dev *mdev, int vport, + u64 *addr_list, size_t addr_list_len) +{ + void *in, *ctx; + int inlen = MLX5_ST_SZ_BYTES(modify_nic_vport_context_in) + + MLX5_ST_SZ_BYTES(mac_address_layout) * (int)addr_list_len; + int err; + size_t i; + int max_list_sz = 1 << MLX5_CAP_GEN_MAX(mdev, log_max_current_mc_list); + + if ((int)addr_list_len > max_list_sz) { + mlx5_core_warn(mdev, "Requested list size (%d) > (%d) max_list_size\n", + (int)addr_list_len, max_list_sz); + return -ENOSPC; + } + + in = mlx5_vzalloc(inlen); + if (!in) { + mlx5_core_warn(mdev, "failed to allocate inbox\n"); + return -ENOMEM; + } + + MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport); + if (vport) + MLX5_SET(modify_nic_vport_context_in, in, + other_vport, 1); + MLX5_SET(modify_nic_vport_context_in, in, + field_select.addresses_list, 1); + + ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in, nic_vport_context); + + MLX5_SET(nic_vport_context, ctx, allowed_list_type, + MLX5_NIC_VPORT_LIST_TYPE_MC); + MLX5_SET(nic_vport_context, ctx, allowed_list_size, addr_list_len); + + for (i = 0; i < addr_list_len; i++) { + u8 *mac_lout = (u8 *)MLX5_ADDR_OF(nic_vport_context, ctx, + current_uc_mac_address[i]); + u8 *mac_ptr = (u8 *)MLX5_ADDR_OF(mac_address_layout, mac_lout, + mac_addr_47_32); + ether_addr_copy(mac_ptr, (u8 *)&addr_list[i]); + } + + err = mlx5_modify_nic_vport_context(mdev, in, inlen); + + kvfree(in); + + return err; +} +EXPORT_SYMBOL_GPL(mlx5_set_nic_vport_mc_list); + +int mlx5_set_nic_vport_promisc(struct mlx5_core_dev *mdev, int vport, + bool promisc_mc, bool promisc_uc, + bool promisc_all) +{ + u8 in[MLX5_ST_SZ_BYTES(modify_nic_vport_context_in)]; + u8 *ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, in, + nic_vport_context); + + memset(in, 0, MLX5_ST_SZ_BYTES(modify_nic_vport_context_in)); + + MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport); + if (vport) + MLX5_SET(modify_nic_vport_context_in, in, + other_vport, 1); + MLX5_SET(modify_nic_vport_context_in, in, field_select.promisc, 1); + if (promisc_mc) + MLX5_SET(nic_vport_context, ctx, promisc_mc, 1); + if (promisc_uc) + MLX5_SET(nic_vport_context, ctx, promisc_uc, 1); + if (promisc_all) + MLX5_SET(nic_vport_context, ctx, promisc_all, 1); + + return mlx5_modify_nic_vport_context(mdev, in, sizeof(in)); +} +EXPORT_SYMBOL_GPL(mlx5_set_nic_vport_promisc); int mlx5_set_nic_vport_permanent_mac(struct mlx5_core_dev *mdev, int vport, u8 *addr) { |