mirror of
https://github.com/ukui/kernel.git
synced 2026-03-09 10:07:04 -07:00
net/mlx5: E-Switch, Add SR-IOV (FDB) support
Enabling E-Switch SRIOV for nvfs+1 vports. Create E-Switch FDB for L2 UC/MC mac steering between VFs/PF and external vport (Uplink). FDB contains forwarding rules such as: UC MAC0 -> vport0(PF). UC MAC1 -> vport1. UC MAC2 -> vport2. MC MACX -> vport0, vport2, Uplink. MC MACY -> vport1, Uplink. For unmatched traffic FDB has the following default rules: Unmached Traffic (src vport != Uplink) -> Uplink. Unmached Traffic (src vport == Uplink) -> vport0(PF). FDB rules population: Each NIC vport (VF) will notify E-Switch manager of its UC/MC vport context changes via modify vport context command, which will be translated to an event that will be handled by E-Switch manager (PF) which will update FDB table accordingly. 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>
This commit is contained in:
committed by
David S. Miller
parent
495716b191
commit
81848731ff
File diff suppressed because it is too large
Load Diff
@@ -86,10 +86,25 @@ struct l2addr_node {
|
||||
kfree(ptr); \
|
||||
})
|
||||
|
||||
struct mlx5_flow_rule {
|
||||
void *ft;
|
||||
u32 fi;
|
||||
u8 match_criteria_enable;
|
||||
u32 *match_criteria;
|
||||
u32 *match_value;
|
||||
u32 action;
|
||||
u32 flow_tag;
|
||||
bool valid;
|
||||
atomic_t refcount;
|
||||
struct mutex mutex; /* protect flow rule updates */
|
||||
struct list_head dest_list;
|
||||
};
|
||||
|
||||
struct mlx5_vport {
|
||||
struct mlx5_core_dev *dev;
|
||||
int vport;
|
||||
struct hlist_head uc_list[MLX5_L2_ADDR_HASH_SIZE];
|
||||
struct hlist_head mc_list[MLX5_L2_ADDR_HASH_SIZE];
|
||||
struct work_struct vport_change_handler;
|
||||
|
||||
/* This spinlock protects access to vport data, between
|
||||
@@ -98,6 +113,7 @@ struct mlx5_vport {
|
||||
*/
|
||||
spinlock_t lock; /* vport events sync */
|
||||
bool enabled;
|
||||
u16 enabled_events;
|
||||
};
|
||||
|
||||
struct mlx5_l2_table {
|
||||
@@ -106,17 +122,26 @@ struct mlx5_l2_table {
|
||||
unsigned long *bitmap;
|
||||
};
|
||||
|
||||
struct mlx5_eswitch_fdb {
|
||||
void *fdb;
|
||||
};
|
||||
|
||||
struct mlx5_eswitch {
|
||||
struct mlx5_core_dev *dev;
|
||||
struct mlx5_l2_table l2_table;
|
||||
struct mlx5_eswitch_fdb fdb_table;
|
||||
struct hlist_head mc_table[MLX5_L2_ADDR_HASH_SIZE];
|
||||
struct workqueue_struct *work_queue;
|
||||
struct mlx5_vport *vports;
|
||||
int total_vports;
|
||||
int enabled_vports;
|
||||
};
|
||||
|
||||
/* E-Switch API */
|
||||
int mlx5_eswitch_init(struct mlx5_core_dev *dev);
|
||||
void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw);
|
||||
void mlx5_eswitch_vport_event(struct mlx5_eswitch *esw, struct mlx5_eqe *eqe);
|
||||
int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs);
|
||||
void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw);
|
||||
|
||||
#endif /* __MLX5_ESWITCH_H__ */
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/if_link.h>
|
||||
|
||||
#define DRIVER_NAME "mlx5_core"
|
||||
#define DRIVER_VERSION "3.0-1"
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/mlx5/driver.h>
|
||||
#include "mlx5_core.h"
|
||||
#ifdef CONFIG_MLX5_CORE_EN
|
||||
#include "eswitch.h"
|
||||
#endif
|
||||
|
||||
static void enable_vfs(struct mlx5_core_dev *dev, int num_vfs)
|
||||
{
|
||||
@@ -144,13 +147,15 @@ int mlx5_core_sriov_configure(struct pci_dev *pdev, int num_vfs)
|
||||
mlx5_core_cleanup_vfs(dev);
|
||||
|
||||
if (!num_vfs) {
|
||||
#ifdef CONFIG_MLX5_CORE_EN
|
||||
mlx5_eswitch_disable_sriov(dev->priv.eswitch);
|
||||
#endif
|
||||
kfree(sriov->vfs_ctx);
|
||||
sriov->vfs_ctx = NULL;
|
||||
if (!pci_vfs_assigned(pdev))
|
||||
pci_disable_sriov(pdev);
|
||||
else
|
||||
pr_info("unloading PF driver while leaving orphan VFs\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -161,6 +166,9 @@ int mlx5_core_sriov_configure(struct pci_dev *pdev, int num_vfs)
|
||||
}
|
||||
|
||||
mlx5_core_init_vfs(dev, num_vfs);
|
||||
#ifdef CONFIG_MLX5_CORE_EN
|
||||
mlx5_eswitch_enable_sriov(dev->priv.eswitch, num_vfs);
|
||||
#endif
|
||||
|
||||
return num_vfs;
|
||||
}
|
||||
@@ -199,6 +207,10 @@ int mlx5_sriov_init(struct mlx5_core_dev *dev)
|
||||
sriov->enabled_vfs = cur_vfs;
|
||||
|
||||
mlx5_core_init_vfs(dev, cur_vfs);
|
||||
#ifdef CONFIG_MLX5_CORE_EN
|
||||
if (cur_vfs)
|
||||
mlx5_eswitch_enable_sriov(dev->priv.eswitch, cur_vfs);
|
||||
#endif
|
||||
|
||||
enable_vfs(dev, cur_vfs);
|
||||
|
||||
|
||||
@@ -1074,6 +1074,12 @@ enum {
|
||||
VPORT_STATE_UP = 0x1,
|
||||
};
|
||||
|
||||
enum {
|
||||
MLX5_ESW_VPORT_ADMIN_STATE_DOWN = 0x0,
|
||||
MLX5_ESW_VPORT_ADMIN_STATE_UP = 0x1,
|
||||
MLX5_ESW_VPORT_ADMIN_STATE_AUTO = 0x2,
|
||||
};
|
||||
|
||||
enum {
|
||||
MLX5_L3_PROT_TYPE_IPV4 = 0,
|
||||
MLX5_L3_PROT_TYPE_IPV6 = 1,
|
||||
|
||||
@@ -41,6 +41,15 @@ struct mlx5_flow_table_group {
|
||||
u32 match_criteria[MLX5_ST_SZ_DW(fte_match_param)];
|
||||
};
|
||||
|
||||
struct mlx5_flow_destination {
|
||||
enum mlx5_flow_destination_type type;
|
||||
union {
|
||||
u32 tir_num;
|
||||
void *ft;
|
||||
u32 vport_num;
|
||||
};
|
||||
};
|
||||
|
||||
void *mlx5_create_flow_table(struct mlx5_core_dev *dev, u8 level, u8 table_type,
|
||||
u16 num_groups,
|
||||
struct mlx5_flow_table_group *group);
|
||||
|
||||
@@ -827,9 +827,10 @@ struct mlx5_ifc_cmd_hca_cap_bits {
|
||||
u8 reserved_69[0x220];
|
||||
};
|
||||
|
||||
enum {
|
||||
MLX5_DEST_FORMAT_STRUCT_DESTINATION_TYPE_FLOW_TABLE_ = 0x1,
|
||||
MLX5_DEST_FORMAT_STRUCT_DESTINATION_TYPE_TIR = 0x2,
|
||||
enum mlx5_flow_destination_type {
|
||||
MLX5_FLOW_DESTINATION_TYPE_VPORT = 0x0,
|
||||
MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE = 0x1,
|
||||
MLX5_FLOW_DESTINATION_TYPE_TIR = 0x2,
|
||||
};
|
||||
|
||||
struct mlx5_ifc_dest_format_struct_bits {
|
||||
|
||||
Reference in New Issue
Block a user