aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAviv Heller <avivh@mellanox.com>2016-05-09 05:57:05 -0400
committerLeon Romanovsky <leon@kernel.org>2016-08-18 11:49:56 -0400
commitaaff1bea16bb7f259a263c3ae4633d092e2da799 (patch)
tree6c4f82ed6a6abac3f8c95eaf020dbca0ebee5b66
parentedb31b1686751f605eb02a6dcf5ef29c5d485a8e (diff)
net/mlx5: LAG demux flow table support
Add interfaces to allow the creation and destruction of a LAG demux flow table. It is a special flow table used during LAG for redirecting non user-mode packets from PF0 to PF1 root ft, if a packet was received on phys port two. Signed-off-by: Aviv Heller <avivh@mellanox.com> Reviewed-by: Maor Gottlieb <maorg@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com> Signed-off-by: Leon Romanovsky <leon@kernel.org>
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c56
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.h1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fs_core.c31
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/fs_core.h6
-rw-r--r--include/linux/mlx5/fs.h3
5 files changed, 75 insertions, 22 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c
index 7aaefa9aaf1c..7a0415e6d339 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c
@@ -58,6 +58,7 @@ int mlx5_cmd_update_root_ft(struct mlx5_core_dev *dev,
58 58
59int mlx5_cmd_create_flow_table(struct mlx5_core_dev *dev, 59int mlx5_cmd_create_flow_table(struct mlx5_core_dev *dev,
60 u16 vport, 60 u16 vport,
61 enum fs_flow_table_op_mod op_mod,
61 enum fs_flow_table_type type, unsigned int level, 62 enum fs_flow_table_type type, unsigned int level,
62 unsigned int log_size, struct mlx5_flow_table 63 unsigned int log_size, struct mlx5_flow_table
63 *next_ft, unsigned int *table_id) 64 *next_ft, unsigned int *table_id)
@@ -69,10 +70,6 @@ int mlx5_cmd_create_flow_table(struct mlx5_core_dev *dev,
69 MLX5_SET(create_flow_table_in, in, opcode, 70 MLX5_SET(create_flow_table_in, in, opcode,
70 MLX5_CMD_OP_CREATE_FLOW_TABLE); 71 MLX5_CMD_OP_CREATE_FLOW_TABLE);
71 72
72 if (next_ft) {
73 MLX5_SET(create_flow_table_in, in, table_miss_mode, 1);
74 MLX5_SET(create_flow_table_in, in, table_miss_id, next_ft->id);
75 }
76 MLX5_SET(create_flow_table_in, in, table_type, type); 73 MLX5_SET(create_flow_table_in, in, table_type, type);
77 MLX5_SET(create_flow_table_in, in, level, level); 74 MLX5_SET(create_flow_table_in, in, level, level);
78 MLX5_SET(create_flow_table_in, in, log_size, log_size); 75 MLX5_SET(create_flow_table_in, in, log_size, log_size);
@@ -81,6 +78,22 @@ int mlx5_cmd_create_flow_table(struct mlx5_core_dev *dev,
81 MLX5_SET(create_flow_table_in, in, other_vport, 1); 78 MLX5_SET(create_flow_table_in, in, other_vport, 1);
82 } 79 }
83 80
81 switch (op_mod) {
82 case FS_FT_OP_MOD_NORMAL:
83 if (next_ft) {
84 MLX5_SET(create_flow_table_in, in, table_miss_mode, 1);
85 MLX5_SET(create_flow_table_in, in, table_miss_id, next_ft->id);
86 }
87 break;
88
89 case FS_FT_OP_MOD_LAG_DEMUX:
90 MLX5_SET(create_flow_table_in, in, op_mod, 0x1);
91 if (next_ft)
92 MLX5_SET(create_flow_table_in, in, lag_master_next_table_id,
93 next_ft->id);
94 break;
95 }
96
84 err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); 97 err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
85 if (!err) 98 if (!err)
86 *table_id = MLX5_GET(create_flow_table_out, out, 99 *table_id = MLX5_GET(create_flow_table_out, out,
@@ -117,17 +130,32 @@ int mlx5_cmd_modify_flow_table(struct mlx5_core_dev *dev,
117 MLX5_CMD_OP_MODIFY_FLOW_TABLE); 130 MLX5_CMD_OP_MODIFY_FLOW_TABLE);
118 MLX5_SET(modify_flow_table_in, in, table_type, ft->type); 131 MLX5_SET(modify_flow_table_in, in, table_type, ft->type);
119 MLX5_SET(modify_flow_table_in, in, table_id, ft->id); 132 MLX5_SET(modify_flow_table_in, in, table_id, ft->id);
120 if (ft->vport) { 133
121 MLX5_SET(modify_flow_table_in, in, vport_number, ft->vport); 134 if (ft->op_mod == FS_FT_OP_MOD_LAG_DEMUX) {
122 MLX5_SET(modify_flow_table_in, in, other_vport, 1); 135 MLX5_SET(modify_flow_table_in, in, modify_field_select,
123 } 136 MLX5_MODIFY_FLOW_TABLE_LAG_NEXT_TABLE_ID);
124 MLX5_SET(modify_flow_table_in, in, modify_field_select, 137 if (next_ft) {
125 MLX5_MODIFY_FLOW_TABLE_MISS_TABLE_ID); 138 MLX5_SET(modify_flow_table_in, in,
126 if (next_ft) { 139 lag_master_next_table_id, next_ft->id);
127 MLX5_SET(modify_flow_table_in, in, table_miss_mode, 1); 140 } else {
128 MLX5_SET(modify_flow_table_in, in, table_miss_id, next_ft->id); 141 MLX5_SET(modify_flow_table_in, in,
142 lag_master_next_table_id, 0);
143 }
129 } else { 144 } else {
130 MLX5_SET(modify_flow_table_in, in, table_miss_mode, 0); 145 if (ft->vport) {
146 MLX5_SET(modify_flow_table_in, in, vport_number,
147 ft->vport);
148 MLX5_SET(modify_flow_table_in, in, other_vport, 1);
149 }
150 MLX5_SET(modify_flow_table_in, in, modify_field_select,
151 MLX5_MODIFY_FLOW_TABLE_MISS_TABLE_ID);
152 if (next_ft) {
153 MLX5_SET(modify_flow_table_in, in, table_miss_mode, 1);
154 MLX5_SET(modify_flow_table_in, in, table_miss_id,
155 next_ft->id);
156 } else {
157 MLX5_SET(modify_flow_table_in, in, table_miss_mode, 0);
158 }
131 } 159 }
132 160
133 return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out)); 161 return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.h b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.h
index ac52fdfb5096..c5bc4686c832 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.h
@@ -35,6 +35,7 @@
35 35
36int mlx5_cmd_create_flow_table(struct mlx5_core_dev *dev, 36int mlx5_cmd_create_flow_table(struct mlx5_core_dev *dev,
37 u16 vport, 37 u16 vport,
38 enum fs_flow_table_op_mod op_mod,
38 enum fs_flow_table_type type, unsigned int level, 39 enum fs_flow_table_type type, unsigned int level,
39 unsigned int log_size, struct mlx5_flow_table 40 unsigned int log_size, struct mlx5_flow_table
40 *next_ft, unsigned int *table_id); 41 *next_ft, unsigned int *table_id);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
index 243efc5a8bd1..eabd73482c86 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
@@ -477,7 +477,8 @@ static struct mlx5_flow_group *alloc_flow_group(u32 *create_fg_in)
477} 477}
478 478
479static struct mlx5_flow_table *alloc_flow_table(int level, u16 vport, int max_fte, 479static struct mlx5_flow_table *alloc_flow_table(int level, u16 vport, int max_fte,
480 enum fs_flow_table_type table_type) 480 enum fs_flow_table_type table_type,
481 enum fs_flow_table_op_mod op_mod)
481{ 482{
482 struct mlx5_flow_table *ft; 483 struct mlx5_flow_table *ft;
483 484
@@ -487,6 +488,7 @@ static struct mlx5_flow_table *alloc_flow_table(int level, u16 vport, int max_ft
487 488
488 ft->level = level; 489 ft->level = level;
489 ft->node.type = FS_TYPE_FLOW_TABLE; 490 ft->node.type = FS_TYPE_FLOW_TABLE;
491 ft->op_mod = op_mod;
490 ft->type = table_type; 492 ft->type = table_type;
491 ft->vport = vport; 493 ft->vport = vport;
492 ft->max_fte = max_fte; 494 ft->max_fte = max_fte;
@@ -724,6 +726,7 @@ static void list_add_flow_table(struct mlx5_flow_table *ft,
724} 726}
725 727
726static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespace *ns, 728static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespace *ns,
729 enum fs_flow_table_op_mod op_mod,
727 u16 vport, int prio, 730 u16 vport, int prio,
728 int max_fte, u32 level) 731 int max_fte, u32 level)
729{ 732{
@@ -756,18 +759,19 @@ static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespa
756 level += fs_prio->start_level; 759 level += fs_prio->start_level;
757 ft = alloc_flow_table(level, 760 ft = alloc_flow_table(level,
758 vport, 761 vport,
759 roundup_pow_of_two(max_fte), 762 max_fte ? roundup_pow_of_two(max_fte) : 0,
760 root->table_type); 763 root->table_type,
764 op_mod);
761 if (!ft) { 765 if (!ft) {
762 err = -ENOMEM; 766 err = -ENOMEM;
763 goto unlock_root; 767 goto unlock_root;
764 } 768 }
765 769
766 tree_init_node(&ft->node, 1, del_flow_table); 770 tree_init_node(&ft->node, 1, del_flow_table);
767 log_table_sz = ilog2(ft->max_fte); 771 log_table_sz = ft->max_fte ? ilog2(ft->max_fte) : 0;
768 next_ft = find_next_chained_ft(fs_prio); 772 next_ft = find_next_chained_ft(fs_prio);
769 err = mlx5_cmd_create_flow_table(root->dev, ft->vport, ft->type, ft->level, 773 err = mlx5_cmd_create_flow_table(root->dev, ft->vport, ft->op_mod, ft->type,
770 log_table_sz, next_ft, &ft->id); 774 ft->level, log_table_sz, next_ft, &ft->id);
771 if (err) 775 if (err)
772 goto free_ft; 776 goto free_ft;
773 777
@@ -794,16 +798,27 @@ struct mlx5_flow_table *mlx5_create_flow_table(struct mlx5_flow_namespace *ns,
794 int prio, int max_fte, 798 int prio, int max_fte,
795 u32 level) 799 u32 level)
796{ 800{
797 return __mlx5_create_flow_table(ns, 0, prio, max_fte, level); 801 return __mlx5_create_flow_table(ns, FS_FT_OP_MOD_NORMAL, 0, prio,
802 max_fte, level);
798} 803}
799 804
800struct mlx5_flow_table *mlx5_create_vport_flow_table(struct mlx5_flow_namespace *ns, 805struct mlx5_flow_table *mlx5_create_vport_flow_table(struct mlx5_flow_namespace *ns,
801 int prio, int max_fte, 806 int prio, int max_fte,
802 u32 level, u16 vport) 807 u32 level, u16 vport)
803{ 808{
804 return __mlx5_create_flow_table(ns, vport, prio, max_fte, level); 809 return __mlx5_create_flow_table(ns, FS_FT_OP_MOD_NORMAL, vport, prio,
810 max_fte, level);
805} 811}
806 812
813struct mlx5_flow_table *mlx5_create_lag_demux_flow_table(
814 struct mlx5_flow_namespace *ns,
815 int prio, u32 level)
816{
817 return __mlx5_create_flow_table(ns, FS_FT_OP_MOD_LAG_DEMUX, 0, prio, 0,
818 level);
819}
820EXPORT_SYMBOL(mlx5_create_lag_demux_flow_table);
821
807struct mlx5_flow_table *mlx5_create_auto_grouped_flow_table(struct mlx5_flow_namespace *ns, 822struct mlx5_flow_table *mlx5_create_auto_grouped_flow_table(struct mlx5_flow_namespace *ns,
808 int prio, 823 int prio,
809 int num_flow_table_entries, 824 int num_flow_table_entries,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h
index 9cffb6aeb4e9..23e46e35413f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.h
@@ -51,6 +51,11 @@ enum fs_flow_table_type {
51 FS_FT_FDB = 0X4, 51 FS_FT_FDB = 0X4,
52}; 52};
53 53
54enum fs_flow_table_op_mod {
55 FS_FT_OP_MOD_NORMAL,
56 FS_FT_OP_MOD_LAG_DEMUX,
57};
58
54enum fs_fte_status { 59enum fs_fte_status {
55 FS_FTE_STATUS_EXISTING = 1UL << 0, 60 FS_FTE_STATUS_EXISTING = 1UL << 0,
56}; 61};
@@ -93,6 +98,7 @@ struct mlx5_flow_table {
93 unsigned int max_fte; 98 unsigned int max_fte;
94 unsigned int level; 99 unsigned int level;
95 enum fs_flow_table_type type; 100 enum fs_flow_table_type type;
101 enum fs_flow_table_op_mod op_mod;
96 struct { 102 struct {
97 bool active; 103 bool active;
98 unsigned int required_groups; 104 unsigned int required_groups;
diff --git a/include/linux/mlx5/fs.h b/include/linux/mlx5/fs.h
index e036d6030867..7edfe0b8f1ec 100644
--- a/include/linux/mlx5/fs.h
+++ b/include/linux/mlx5/fs.h
@@ -106,6 +106,9 @@ mlx5_create_vport_flow_table(struct mlx5_flow_namespace *ns,
106 int prio, 106 int prio,
107 int num_flow_table_entries, 107 int num_flow_table_entries,
108 u32 level, u16 vport); 108 u32 level, u16 vport);
109struct mlx5_flow_table *mlx5_create_lag_demux_flow_table(
110 struct mlx5_flow_namespace *ns,
111 int prio, u32 level);
109int mlx5_destroy_flow_table(struct mlx5_flow_table *ft); 112int mlx5_destroy_flow_table(struct mlx5_flow_table *ft);
110 113
111/* inbox should be set with the following values: 114/* inbox should be set with the following values: