You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -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); \
|
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_vport {
|
||||||
struct mlx5_core_dev *dev;
|
struct mlx5_core_dev *dev;
|
||||||
int vport;
|
int vport;
|
||||||
struct hlist_head uc_list[MLX5_L2_ADDR_HASH_SIZE];
|
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;
|
struct work_struct vport_change_handler;
|
||||||
|
|
||||||
/* This spinlock protects access to vport data, between
|
/* This spinlock protects access to vport data, between
|
||||||
@@ -98,6 +113,7 @@ struct mlx5_vport {
|
|||||||
*/
|
*/
|
||||||
spinlock_t lock; /* vport events sync */
|
spinlock_t lock; /* vport events sync */
|
||||||
bool enabled;
|
bool enabled;
|
||||||
|
u16 enabled_events;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mlx5_l2_table {
|
struct mlx5_l2_table {
|
||||||
@@ -106,17 +122,26 @@ struct mlx5_l2_table {
|
|||||||
unsigned long *bitmap;
|
unsigned long *bitmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mlx5_eswitch_fdb {
|
||||||
|
void *fdb;
|
||||||
|
};
|
||||||
|
|
||||||
struct mlx5_eswitch {
|
struct mlx5_eswitch {
|
||||||
struct mlx5_core_dev *dev;
|
struct mlx5_core_dev *dev;
|
||||||
struct mlx5_l2_table l2_table;
|
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 workqueue_struct *work_queue;
|
||||||
struct mlx5_vport *vports;
|
struct mlx5_vport *vports;
|
||||||
int total_vports;
|
int total_vports;
|
||||||
|
int enabled_vports;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* E-Switch API */
|
/* E-Switch API */
|
||||||
int mlx5_eswitch_init(struct mlx5_core_dev *dev);
|
int mlx5_eswitch_init(struct mlx5_core_dev *dev);
|
||||||
void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw);
|
void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw);
|
||||||
void mlx5_eswitch_vport_event(struct mlx5_eswitch *esw, struct mlx5_eqe *eqe);
|
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__ */
|
#endif /* __MLX5_ESWITCH_H__ */
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
#include <linux/if_link.h>
|
||||||
|
|
||||||
#define DRIVER_NAME "mlx5_core"
|
#define DRIVER_NAME "mlx5_core"
|
||||||
#define DRIVER_VERSION "3.0-1"
|
#define DRIVER_VERSION "3.0-1"
|
||||||
|
|||||||
@@ -33,6 +33,9 @@
|
|||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/mlx5/driver.h>
|
#include <linux/mlx5/driver.h>
|
||||||
#include "mlx5_core.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)
|
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);
|
mlx5_core_cleanup_vfs(dev);
|
||||||
|
|
||||||
if (!num_vfs) {
|
if (!num_vfs) {
|
||||||
|
#ifdef CONFIG_MLX5_CORE_EN
|
||||||
|
mlx5_eswitch_disable_sriov(dev->priv.eswitch);
|
||||||
|
#endif
|
||||||
kfree(sriov->vfs_ctx);
|
kfree(sriov->vfs_ctx);
|
||||||
sriov->vfs_ctx = NULL;
|
sriov->vfs_ctx = NULL;
|
||||||
if (!pci_vfs_assigned(pdev))
|
if (!pci_vfs_assigned(pdev))
|
||||||
pci_disable_sriov(pdev);
|
pci_disable_sriov(pdev);
|
||||||
else
|
else
|
||||||
pr_info("unloading PF driver while leaving orphan VFs\n");
|
pr_info("unloading PF driver while leaving orphan VFs\n");
|
||||||
|
|
||||||
return 0;
|
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);
|
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;
|
return num_vfs;
|
||||||
}
|
}
|
||||||
@@ -199,6 +207,10 @@ int mlx5_sriov_init(struct mlx5_core_dev *dev)
|
|||||||
sriov->enabled_vfs = cur_vfs;
|
sriov->enabled_vfs = cur_vfs;
|
||||||
|
|
||||||
mlx5_core_init_vfs(dev, 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);
|
enable_vfs(dev, cur_vfs);
|
||||||
|
|
||||||
|
|||||||
@@ -1074,6 +1074,12 @@ enum {
|
|||||||
VPORT_STATE_UP = 0x1,
|
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 {
|
enum {
|
||||||
MLX5_L3_PROT_TYPE_IPV4 = 0,
|
MLX5_L3_PROT_TYPE_IPV4 = 0,
|
||||||
MLX5_L3_PROT_TYPE_IPV6 = 1,
|
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)];
|
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,
|
void *mlx5_create_flow_table(struct mlx5_core_dev *dev, u8 level, u8 table_type,
|
||||||
u16 num_groups,
|
u16 num_groups,
|
||||||
struct mlx5_flow_table_group *group);
|
struct mlx5_flow_table_group *group);
|
||||||
|
|||||||
@@ -827,9 +827,10 @@ struct mlx5_ifc_cmd_hca_cap_bits {
|
|||||||
u8 reserved_69[0x220];
|
u8 reserved_69[0x220];
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum mlx5_flow_destination_type {
|
||||||
MLX5_DEST_FORMAT_STRUCT_DESTINATION_TYPE_FLOW_TABLE_ = 0x1,
|
MLX5_FLOW_DESTINATION_TYPE_VPORT = 0x0,
|
||||||
MLX5_DEST_FORMAT_STRUCT_DESTINATION_TYPE_TIR = 0x2,
|
MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE = 0x1,
|
||||||
|
MLX5_FLOW_DESTINATION_TYPE_TIR = 0x2,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mlx5_ifc_dest_format_struct_bits {
|
struct mlx5_ifc_dest_format_struct_bits {
|
||||||
|
|||||||
Reference in New Issue
Block a user