net/mlx5: Introduce access functions to modify/query vport mac lists
authorSaeed Mahameed <saeedm@mellanox.com>
Tue, 1 Dec 2015 16:03:12 +0000 (18:03 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 3 Dec 2015 17:08:44 +0000 (12:08 -0500)
Those functions are needed to notify the upcoming L2 table and SR-IOV
E-Switch(FDB) manager(PF), of the NIC vport (vf) UC/MC mac lists
changes.

preperation for ethernet sriov and l2 table management.

Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlx5/core/vport.c
include/linux/mlx5/device.h
include/linux/mlx5/vport.h

index 442916e98724873a11b77c8f34cc832e87a4f64c..986d0d364df7dc44bc12fdb186adc3ac189fdd3d 100644 (file)
@@ -150,6 +150,125 @@ int mlx5_modify_nic_vport_mac_address(struct mlx5_core_dev *mdev,
 }
 EXPORT_SYMBOL(mlx5_modify_nic_vport_mac_address);
 
+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;
+       int out_sz;
+       void *out;
+       int err;
+       int i;
+
+       req_list_size = *list_size;
+
+       max_list_size = list_type == MLX5_NVPRT_LIST_TYPE_UC ?
+               1 << MLX5_CAP_GEN(dev, log_max_current_uc_list) :
+               1 << MLX5_CAP_GEN(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++) {
+               u8 *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_NVPRT_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_hca_vport_gid(struct mlx5_core_dev *dev, u8 other_vport,
                             u8 port_num, u16  vf_num, u16 gid_index,
                             union ib_gid *gid)
index 0b473cbfa7ef10c875c1eed802c2a7dd74f415d4..0d2f0435a9f0613331cc9de55c37ad3323dc6fde 100644 (file)
@@ -1102,6 +1102,12 @@ enum {
        MLX5_FLOW_CONTEXT_DEST_TYPE_TIR         = 2,
 };
 
+enum mlx5_list_type {
+       MLX5_NVPRT_LIST_TYPE_UC   = 0x0,
+       MLX5_NVPRT_LIST_TYPE_MC   = 0x1,
+       MLX5_NVPRT_LIST_TYPE_VLAN = 0x2,
+};
+
 enum {
        MLX5_RQC_RQ_TYPE_MEMORY_RQ_INLINE = 0x0,
        MLX5_RQC_RQ_TYPE_MEMORY_RQ_RPM    = 0x1,
index 43e82d9f54638cb8b2b6e7e68be8a45c248a93a7..00bbec8d9527e70cad7a6d4c6c5dcd0d3c552d25 100644 (file)
@@ -34,6 +34,7 @@
 #define __MLX5_VPORT_H__
 
 #include <linux/mlx5/driver.h>
+#include <linux/mlx5/device.h>
 
 u8 mlx5_query_vport_state(struct mlx5_core_dev *mdev, u8 opmod);
 int mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev,
@@ -54,5 +55,14 @@ int mlx5_query_hca_vport_system_image_guid(struct mlx5_core_dev *dev,
                                           u64 *sys_image_guid);
 int mlx5_query_hca_vport_node_guid(struct mlx5_core_dev *dev,
                                   u64 *node_guid);
+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);
 
 #endif /* __MLX5_VPORT_H__ */