Merge tag 'tty-6.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
[platform/kernel/linux-rpi.git] / drivers / net / ethernet / mellanox / mlx5 / core / en_fs.c
1 /*
2  * Copyright (c) 2015, Mellanox Technologies. All rights reserved.
3  *
4  * This software is available to you under a choice of one of two
5  * licenses.  You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL) Version 2, available from the file
7  * COPYING in the main directory of this source tree, or the
8  * OpenIB.org BSD license below:
9  *
10  *     Redistribution and use in source and binary forms, with or
11  *     without modification, are permitted provided that the following
12  *     conditions are met:
13  *
14  *      - Redistributions of source code must retain the above
15  *        copyright notice, this list of conditions and the following
16  *        disclaimer.
17  *
18  *      - Redistributions in binary form must reproduce the above
19  *        copyright notice, this list of conditions and the following
20  *        disclaimer in the documentation and/or other materials
21  *        provided with the distribution.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  */
32
33 #include <linux/list.h>
34 #include <linux/ip.h>
35 #include <linux/ipv6.h>
36 #include <linux/tcp.h>
37 #include <linux/mlx5/fs.h>
38 #include <linux/mlx5/mpfs.h>
39 #include "en.h"
40 #include "en_tc.h"
41 #include "lib/mpfs.h"
42 #include "en/ptp.h"
43
44 static int mlx5e_add_l2_flow_rule(struct mlx5e_flow_steering *fs,
45                                   struct mlx5e_l2_rule *ai, int type);
46 static void mlx5e_del_l2_flow_rule(struct mlx5e_flow_steering *fs,
47                                    struct mlx5e_l2_rule *ai);
48
49 enum {
50         MLX5E_FULLMATCH = 0,
51         MLX5E_ALLMULTI  = 1,
52 };
53
54 enum {
55         MLX5E_UC        = 0,
56         MLX5E_MC_IPV4   = 1,
57         MLX5E_MC_IPV6   = 2,
58         MLX5E_MC_OTHER  = 3,
59 };
60
61 enum {
62         MLX5E_ACTION_NONE = 0,
63         MLX5E_ACTION_ADD  = 1,
64         MLX5E_ACTION_DEL  = 2,
65 };
66
67 struct mlx5e_l2_hash_node {
68         struct hlist_node          hlist;
69         u8                         action;
70         struct mlx5e_l2_rule ai;
71         bool   mpfs;
72 };
73
74 static inline int mlx5e_hash_l2(const u8 *addr)
75 {
76         return addr[5];
77 }
78
79 static void mlx5e_add_l2_to_hash(struct hlist_head *hash, const u8 *addr)
80 {
81         struct mlx5e_l2_hash_node *hn;
82         int ix = mlx5e_hash_l2(addr);
83         int found = 0;
84
85         hlist_for_each_entry(hn, &hash[ix], hlist)
86                 if (ether_addr_equal_64bits(hn->ai.addr, addr)) {
87                         found = 1;
88                         break;
89                 }
90
91         if (found) {
92                 hn->action = MLX5E_ACTION_NONE;
93                 return;
94         }
95
96         hn = kzalloc(sizeof(*hn), GFP_ATOMIC);
97         if (!hn)
98                 return;
99
100         ether_addr_copy(hn->ai.addr, addr);
101         hn->action = MLX5E_ACTION_ADD;
102
103         hlist_add_head(&hn->hlist, &hash[ix]);
104 }
105
106 static void mlx5e_del_l2_from_hash(struct mlx5e_l2_hash_node *hn)
107 {
108         hlist_del(&hn->hlist);
109         kfree(hn);
110 }
111
112 struct mlx5e_vlan_table {
113         struct mlx5e_flow_table         ft;
114         DECLARE_BITMAP(active_cvlans, VLAN_N_VID);
115         DECLARE_BITMAP(active_svlans, VLAN_N_VID);
116         struct mlx5_flow_handle *active_cvlans_rule[VLAN_N_VID];
117         struct mlx5_flow_handle *active_svlans_rule[VLAN_N_VID];
118         struct mlx5_flow_handle *untagged_rule;
119         struct mlx5_flow_handle *any_cvlan_rule;
120         struct mlx5_flow_handle *any_svlan_rule;
121         struct mlx5_flow_handle *trap_rule;
122         bool                    cvlan_filter_disabled;
123 };
124
125 unsigned long *mlx5e_vlan_get_active_svlans(struct mlx5e_vlan_table *vlan)
126 {
127         return vlan->active_svlans;
128 }
129
130 struct mlx5_flow_table *mlx5e_vlan_get_flowtable(struct mlx5e_vlan_table *vlan)
131 {
132         return vlan->ft.t;
133 }
134
135 static int mlx5e_vport_context_update_vlans(struct mlx5e_flow_steering *fs)
136 {
137         int max_list_size;
138         int list_size;
139         u16 *vlans;
140         int vlan;
141         int err;
142         int i;
143
144         list_size = 0;
145         for_each_set_bit(vlan, fs->vlan->active_cvlans, VLAN_N_VID)
146                 list_size++;
147
148         max_list_size = 1 << MLX5_CAP_GEN(fs->mdev, log_max_vlan_list);
149
150         if (list_size > max_list_size) {
151                 mlx5_core_warn(fs->mdev,
152                                "netdev vlans list size (%d) > (%d) max vport list size, some vlans will be dropped\n",
153                                list_size, max_list_size);
154                 list_size = max_list_size;
155         }
156
157         vlans = kvcalloc(list_size, sizeof(*vlans), GFP_KERNEL);
158         if (!vlans)
159                 return -ENOMEM;
160
161         i = 0;
162         for_each_set_bit(vlan, fs->vlan->active_cvlans, VLAN_N_VID) {
163                 if (i >= list_size)
164                         break;
165                 vlans[i++] = vlan;
166         }
167
168         err = mlx5_modify_nic_vport_vlans(fs->mdev, vlans, list_size);
169         if (err)
170                 mlx5_core_err(fs->mdev, "Failed to modify vport vlans list err(%d)\n",
171                               err);
172
173         kvfree(vlans);
174         return err;
175 }
176
177 enum mlx5e_vlan_rule_type {
178         MLX5E_VLAN_RULE_TYPE_UNTAGGED,
179         MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID,
180         MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID,
181         MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID,
182         MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID,
183 };
184
185 static int __mlx5e_add_vlan_rule(struct mlx5e_flow_steering *fs,
186                                  enum mlx5e_vlan_rule_type rule_type,
187                                  u16 vid, struct mlx5_flow_spec *spec)
188 {
189         struct mlx5_flow_table *ft = fs->vlan->ft.t;
190         struct mlx5_flow_destination dest = {};
191         struct mlx5_flow_handle **rule_p;
192         MLX5_DECLARE_FLOW_ACT(flow_act);
193         int err = 0;
194
195         dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
196         dest.ft = fs->l2.ft.t;
197
198         spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
199
200         switch (rule_type) {
201         case MLX5E_VLAN_RULE_TYPE_UNTAGGED:
202                 /* cvlan_tag enabled in match criteria and
203                  * disabled in match value means both S & C tags
204                  * don't exist (untagged of both)
205                  */
206                 rule_p = &fs->vlan->untagged_rule;
207                 MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
208                                  outer_headers.cvlan_tag);
209                 break;
210         case MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID:
211                 rule_p = &fs->vlan->any_cvlan_rule;
212                 MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
213                                  outer_headers.cvlan_tag);
214                 MLX5_SET(fte_match_param, spec->match_value, outer_headers.cvlan_tag, 1);
215                 break;
216         case MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID:
217                 rule_p = &fs->vlan->any_svlan_rule;
218                 MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
219                                  outer_headers.svlan_tag);
220                 MLX5_SET(fte_match_param, spec->match_value, outer_headers.svlan_tag, 1);
221                 break;
222         case MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID:
223                 rule_p = &fs->vlan->active_svlans_rule[vid];
224                 MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
225                                  outer_headers.svlan_tag);
226                 MLX5_SET(fte_match_param, spec->match_value, outer_headers.svlan_tag, 1);
227                 MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
228                                  outer_headers.first_vid);
229                 MLX5_SET(fte_match_param, spec->match_value, outer_headers.first_vid,
230                          vid);
231                 break;
232         default: /* MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID */
233                 rule_p = &fs->vlan->active_cvlans_rule[vid];
234                 MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
235                                  outer_headers.cvlan_tag);
236                 MLX5_SET(fte_match_param, spec->match_value, outer_headers.cvlan_tag, 1);
237                 MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
238                                  outer_headers.first_vid);
239                 MLX5_SET(fte_match_param, spec->match_value, outer_headers.first_vid,
240                          vid);
241                 break;
242         }
243
244         if (WARN_ONCE(*rule_p, "VLAN rule already exists type %d", rule_type))
245                 return 0;
246
247         *rule_p = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1);
248
249         if (IS_ERR(*rule_p)) {
250                 err = PTR_ERR(*rule_p);
251                 *rule_p = NULL;
252                 mlx5_core_err(fs->mdev, "%s: add rule failed\n", __func__);
253         }
254
255         return err;
256 }
257
258 static int mlx5e_add_vlan_rule(struct mlx5e_flow_steering *fs,
259                                enum mlx5e_vlan_rule_type rule_type, u16 vid)
260 {
261         struct mlx5_flow_spec *spec;
262         int err = 0;
263
264         spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
265         if (!spec)
266                 return -ENOMEM;
267
268         if (rule_type == MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID)
269                 mlx5e_vport_context_update_vlans(fs);
270
271         err = __mlx5e_add_vlan_rule(fs, rule_type, vid, spec);
272
273         kvfree(spec);
274
275         return err;
276 }
277
278 static void mlx5e_fs_del_vlan_rule(struct mlx5e_flow_steering *fs,
279                                    enum mlx5e_vlan_rule_type rule_type, u16 vid)
280 {
281         switch (rule_type) {
282         case MLX5E_VLAN_RULE_TYPE_UNTAGGED:
283                 if (fs->vlan->untagged_rule) {
284                         mlx5_del_flow_rules(fs->vlan->untagged_rule);
285                         fs->vlan->untagged_rule = NULL;
286                 }
287                 break;
288         case MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID:
289                 if (fs->vlan->any_cvlan_rule) {
290                         mlx5_del_flow_rules(fs->vlan->any_cvlan_rule);
291                         fs->vlan->any_cvlan_rule = NULL;
292                 }
293                 break;
294         case MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID:
295                 if (fs->vlan->any_svlan_rule) {
296                         mlx5_del_flow_rules(fs->vlan->any_svlan_rule);
297                         fs->vlan->any_svlan_rule = NULL;
298                 }
299                 break;
300         case MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID:
301                 if (fs->vlan->active_svlans_rule[vid]) {
302                         mlx5_del_flow_rules(fs->vlan->active_svlans_rule[vid]);
303                         fs->vlan->active_svlans_rule[vid] = NULL;
304                 }
305                 break;
306         case MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID:
307                 if (fs->vlan->active_cvlans_rule[vid]) {
308                         mlx5_del_flow_rules(fs->vlan->active_cvlans_rule[vid]);
309                         fs->vlan->active_cvlans_rule[vid] = NULL;
310                 }
311                 mlx5e_vport_context_update_vlans(fs);
312                 break;
313         }
314 }
315
316 static void mlx5e_fs_del_any_vid_rules(struct mlx5e_flow_steering *fs)
317 {
318         mlx5e_fs_del_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 0);
319         mlx5e_fs_del_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID, 0);
320 }
321
322 static int mlx5e_fs_add_any_vid_rules(struct mlx5e_flow_steering *fs)
323 {
324         int err;
325
326         err = mlx5e_add_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 0);
327         if (err)
328                 return err;
329
330         return mlx5e_add_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID, 0);
331 }
332
333 static struct mlx5_flow_handle *
334 mlx5e_add_trap_rule(struct mlx5_flow_table *ft, int trap_id, int tir_num)
335 {
336         struct mlx5_flow_destination dest = {};
337         MLX5_DECLARE_FLOW_ACT(flow_act);
338         struct mlx5_flow_handle *rule;
339         struct mlx5_flow_spec *spec;
340
341         spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
342         if (!spec)
343                 return ERR_PTR(-ENOMEM);
344         spec->flow_context.flags |= FLOW_CONTEXT_HAS_TAG;
345         spec->flow_context.flow_tag = trap_id;
346         dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
347         dest.tir_num = tir_num;
348
349         rule = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1);
350         kvfree(spec);
351         return rule;
352 }
353
354 int mlx5e_add_vlan_trap(struct mlx5e_priv *priv, int trap_id, int tir_num)
355 {
356         struct mlx5_flow_table *ft = priv->fs->vlan->ft.t;
357         struct mlx5_flow_handle *rule;
358         int err;
359
360         rule = mlx5e_add_trap_rule(ft, trap_id, tir_num);
361         if (IS_ERR(rule)) {
362                 err = PTR_ERR(rule);
363                 priv->fs->vlan->trap_rule = NULL;
364                 mlx5_core_err(priv->fs->mdev, "%s: add VLAN trap rule failed, err %d\n",
365                               __func__, err);
366                 return err;
367         }
368         priv->fs->vlan->trap_rule = rule;
369         return 0;
370 }
371
372 void mlx5e_remove_vlan_trap(struct mlx5e_priv *priv)
373 {
374         if (priv->fs->vlan->trap_rule) {
375                 mlx5_del_flow_rules(priv->fs->vlan->trap_rule);
376                 priv->fs->vlan->trap_rule = NULL;
377         }
378 }
379
380 int mlx5e_add_mac_trap(struct mlx5e_priv *priv, int trap_id, int tir_num)
381 {
382         struct mlx5_flow_table *ft = priv->fs->l2.ft.t;
383         struct mlx5_flow_handle *rule;
384         int err;
385
386         rule = mlx5e_add_trap_rule(ft, trap_id, tir_num);
387         if (IS_ERR(rule)) {
388                 err = PTR_ERR(rule);
389                 priv->fs->l2.trap_rule = NULL;
390                 mlx5_core_err(priv->fs->mdev, "%s: add MAC trap rule failed, err %d\n",
391                               __func__, err);
392                 return err;
393         }
394         priv->fs->l2.trap_rule = rule;
395         return 0;
396 }
397
398 void mlx5e_remove_mac_trap(struct mlx5e_priv *priv)
399 {
400         if (priv->fs->l2.trap_rule) {
401                 mlx5_del_flow_rules(priv->fs->l2.trap_rule);
402                 priv->fs->l2.trap_rule = NULL;
403         }
404 }
405
406 void mlx5e_enable_cvlan_filter(struct mlx5e_priv *priv)
407 {
408         if (!priv->fs->vlan->cvlan_filter_disabled)
409                 return;
410
411         priv->fs->vlan->cvlan_filter_disabled = false;
412         if (priv->netdev->flags & IFF_PROMISC)
413                 return;
414         mlx5e_fs_del_vlan_rule(priv->fs, MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 0);
415 }
416
417 void mlx5e_disable_cvlan_filter(struct mlx5e_priv *priv)
418 {
419         if (priv->fs->vlan->cvlan_filter_disabled)
420                 return;
421
422         priv->fs->vlan->cvlan_filter_disabled = true;
423         if (priv->netdev->flags & IFF_PROMISC)
424                 return;
425         mlx5e_add_vlan_rule(priv->fs, MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 0);
426 }
427
428 static int mlx5e_vlan_rx_add_cvid(struct mlx5e_flow_steering *fs, u16 vid)
429 {
430         int err;
431
432         set_bit(vid, fs->vlan->active_cvlans);
433
434         err = mlx5e_add_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID, vid);
435         if (err)
436                 clear_bit(vid, fs->vlan->active_cvlans);
437
438         return err;
439 }
440
441 static int mlx5e_vlan_rx_add_svid(struct mlx5e_flow_steering *fs,
442                                   struct net_device *netdev, u16 vid)
443 {
444         int err;
445
446         set_bit(vid, fs->vlan->active_svlans);
447
448         err = mlx5e_add_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID, vid);
449         if (err) {
450                 clear_bit(vid, fs->vlan->active_svlans);
451                 return err;
452         }
453
454         /* Need to fix some features.. */
455         netdev_update_features(netdev);
456         return err;
457 }
458
459 int mlx5e_fs_vlan_rx_add_vid(struct mlx5e_flow_steering *fs,
460                              struct net_device *netdev,
461                              __be16 proto, u16 vid)
462 {
463
464         if (!fs->vlan) {
465                 mlx5_core_err(fs->mdev, "Vlan doesn't exist\n");
466                 return -EINVAL;
467         }
468
469         if (be16_to_cpu(proto) == ETH_P_8021Q)
470                 return mlx5e_vlan_rx_add_cvid(fs, vid);
471         else if (be16_to_cpu(proto) == ETH_P_8021AD)
472                 return mlx5e_vlan_rx_add_svid(fs, netdev, vid);
473
474         return -EOPNOTSUPP;
475 }
476
477 int mlx5e_fs_vlan_rx_kill_vid(struct mlx5e_flow_steering *fs,
478                               struct net_device *netdev,
479                               __be16 proto, u16 vid)
480 {
481         if (!fs->vlan) {
482                 mlx5_core_err(fs->mdev, "Vlan doesn't exist\n");
483                 return -EINVAL;
484         }
485
486         if (be16_to_cpu(proto) == ETH_P_8021Q) {
487                 clear_bit(vid, fs->vlan->active_cvlans);
488                 mlx5e_fs_del_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID, vid);
489         } else if (be16_to_cpu(proto) == ETH_P_8021AD) {
490                 clear_bit(vid, fs->vlan->active_svlans);
491                 mlx5e_fs_del_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID, vid);
492                 netdev_update_features(netdev);
493         }
494
495         return 0;
496 }
497
498 static void mlx5e_fs_add_vlan_rules(struct mlx5e_flow_steering *fs)
499 {
500         int i;
501
502         mlx5e_add_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_UNTAGGED, 0);
503
504         for_each_set_bit(i, fs->vlan->active_cvlans, VLAN_N_VID) {
505                 mlx5e_add_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID, i);
506         }
507
508         for_each_set_bit(i, fs->vlan->active_svlans, VLAN_N_VID)
509                 mlx5e_add_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID, i);
510
511         if (fs->vlan->cvlan_filter_disabled)
512                 mlx5e_fs_add_any_vid_rules(fs);
513 }
514
515 static void mlx5e_del_vlan_rules(struct mlx5e_priv *priv)
516 {
517         int i;
518
519         mlx5e_fs_del_vlan_rule(priv->fs, MLX5E_VLAN_RULE_TYPE_UNTAGGED, 0);
520
521         for_each_set_bit(i, priv->fs->vlan->active_cvlans, VLAN_N_VID) {
522                 mlx5e_fs_del_vlan_rule(priv->fs, MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID, i);
523         }
524
525         for_each_set_bit(i, priv->fs->vlan->active_svlans, VLAN_N_VID)
526                 mlx5e_fs_del_vlan_rule(priv->fs, MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID, i);
527
528         WARN_ON_ONCE(priv->fs->state_destroy);
529
530         mlx5e_remove_vlan_trap(priv);
531
532         /* must be called after DESTROY bit is set and
533          * set_rx_mode is called and flushed
534          */
535         if (priv->fs->vlan->cvlan_filter_disabled)
536                 mlx5e_fs_del_any_vid_rules(priv->fs);
537 }
538
539 #define mlx5e_for_each_hash_node(hn, tmp, hash, i) \
540         for (i = 0; i < MLX5E_L2_ADDR_HASH_SIZE; i++) \
541                 hlist_for_each_entry_safe(hn, tmp, &hash[i], hlist)
542
543 static void mlx5e_execute_l2_action(struct mlx5e_flow_steering *fs,
544                                     struct mlx5e_l2_hash_node *hn)
545 {
546         u8 action = hn->action;
547         u8 mac_addr[ETH_ALEN];
548         int l2_err = 0;
549
550         ether_addr_copy(mac_addr, hn->ai.addr);
551
552         switch (action) {
553         case MLX5E_ACTION_ADD:
554                 mlx5e_add_l2_flow_rule(fs, &hn->ai, MLX5E_FULLMATCH);
555                 if (!is_multicast_ether_addr(mac_addr)) {
556                         l2_err = mlx5_mpfs_add_mac(fs->mdev, mac_addr);
557                         hn->mpfs = !l2_err;
558                 }
559                 hn->action = MLX5E_ACTION_NONE;
560                 break;
561
562         case MLX5E_ACTION_DEL:
563                 if (!is_multicast_ether_addr(mac_addr) && hn->mpfs)
564                         l2_err = mlx5_mpfs_del_mac(fs->mdev, mac_addr);
565                 mlx5e_del_l2_flow_rule(fs, &hn->ai);
566                 mlx5e_del_l2_from_hash(hn);
567                 break;
568         }
569
570         if (l2_err)
571                 mlx5_core_warn(fs->mdev, "MPFS, failed to %s mac %pM, err(%d)\n",
572                                action == MLX5E_ACTION_ADD ? "add" : "del", mac_addr, l2_err);
573 }
574
575 static void mlx5e_sync_netdev_addr(struct mlx5e_flow_steering *fs,
576                                    struct net_device *netdev)
577 {
578         struct netdev_hw_addr *ha;
579
580         netif_addr_lock_bh(netdev);
581
582         mlx5e_add_l2_to_hash(fs->l2.netdev_uc, netdev->dev_addr);
583         netdev_for_each_uc_addr(ha, netdev)
584                 mlx5e_add_l2_to_hash(fs->l2.netdev_uc, ha->addr);
585
586         netdev_for_each_mc_addr(ha, netdev)
587                 mlx5e_add_l2_to_hash(fs->l2.netdev_mc, ha->addr);
588
589         netif_addr_unlock_bh(netdev);
590 }
591
592 static void mlx5e_fill_addr_array(struct mlx5e_flow_steering *fs, int list_type,
593                                   struct net_device *ndev,
594                                   u8 addr_array[][ETH_ALEN], int size)
595 {
596         bool is_uc = (list_type == MLX5_NVPRT_LIST_TYPE_UC);
597         struct mlx5e_l2_hash_node *hn;
598         struct hlist_head *addr_list;
599         struct hlist_node *tmp;
600         int i = 0;
601         int hi;
602
603         addr_list = is_uc ? fs->l2.netdev_uc : fs->l2.netdev_mc;
604
605         if (is_uc) /* Make sure our own address is pushed first */
606                 ether_addr_copy(addr_array[i++], ndev->dev_addr);
607         else if (fs->l2.broadcast_enabled)
608                 ether_addr_copy(addr_array[i++], ndev->broadcast);
609
610         mlx5e_for_each_hash_node(hn, tmp, addr_list, hi) {
611                 if (ether_addr_equal(ndev->dev_addr, hn->ai.addr))
612                         continue;
613                 if (i >= size)
614                         break;
615                 ether_addr_copy(addr_array[i++], hn->ai.addr);
616         }
617 }
618
619 static void mlx5e_vport_context_update_addr_list(struct mlx5e_flow_steering *fs,
620                                                  struct net_device *netdev,
621                                                  int list_type)
622 {
623         bool is_uc = (list_type == MLX5_NVPRT_LIST_TYPE_UC);
624         struct mlx5e_l2_hash_node *hn;
625         u8 (*addr_array)[ETH_ALEN] = NULL;
626         struct hlist_head *addr_list;
627         struct hlist_node *tmp;
628         int max_size;
629         int size;
630         int err;
631         int hi;
632
633         size = is_uc ? 0 : (fs->l2.broadcast_enabled ? 1 : 0);
634         max_size = is_uc ?
635                 1 << MLX5_CAP_GEN(fs->mdev, log_max_current_uc_list) :
636                 1 << MLX5_CAP_GEN(fs->mdev, log_max_current_mc_list);
637
638         addr_list = is_uc ? fs->l2.netdev_uc : fs->l2.netdev_mc;
639         mlx5e_for_each_hash_node(hn, tmp, addr_list, hi)
640                 size++;
641
642         if (size > max_size) {
643                 mlx5_core_warn(fs->mdev,
644                                "mdev %s list size (%d) > (%d) max vport list size, some addresses will be dropped\n",
645                               is_uc ? "UC" : "MC", size, max_size);
646                 size = max_size;
647         }
648
649         if (size) {
650                 addr_array = kcalloc(size, ETH_ALEN, GFP_KERNEL);
651                 if (!addr_array) {
652                         err = -ENOMEM;
653                         goto out;
654                 }
655                 mlx5e_fill_addr_array(fs, list_type, netdev, addr_array, size);
656         }
657
658         err = mlx5_modify_nic_vport_mac_list(fs->mdev, list_type, addr_array, size);
659 out:
660         if (err)
661                 mlx5_core_err(fs->mdev,
662                               "Failed to modify vport %s list err(%d)\n",
663                               is_uc ? "UC" : "MC", err);
664         kfree(addr_array);
665 }
666
667 static void mlx5e_vport_context_update(struct mlx5e_flow_steering *fs,
668                                        struct net_device *netdev)
669 {
670         struct mlx5e_l2_table *ea = &fs->l2;
671
672         mlx5e_vport_context_update_addr_list(fs, netdev, MLX5_NVPRT_LIST_TYPE_UC);
673         mlx5e_vport_context_update_addr_list(fs, netdev, MLX5_NVPRT_LIST_TYPE_MC);
674         mlx5_modify_nic_vport_promisc(fs->mdev, 0,
675                                       ea->allmulti_enabled,
676                                       ea->promisc_enabled);
677 }
678
679 static void mlx5e_apply_netdev_addr(struct mlx5e_flow_steering *fs)
680 {
681         struct mlx5e_l2_hash_node *hn;
682         struct hlist_node *tmp;
683         int i;
684
685         mlx5e_for_each_hash_node(hn, tmp, fs->l2.netdev_uc, i)
686                 mlx5e_execute_l2_action(fs, hn);
687
688         mlx5e_for_each_hash_node(hn, tmp, fs->l2.netdev_mc, i)
689                 mlx5e_execute_l2_action(fs, hn);
690 }
691
692 static void mlx5e_handle_netdev_addr(struct mlx5e_flow_steering *fs,
693                                      struct net_device *netdev)
694 {
695         struct mlx5e_l2_hash_node *hn;
696         struct hlist_node *tmp;
697         int i;
698
699         mlx5e_for_each_hash_node(hn, tmp, fs->l2.netdev_uc, i)
700                 hn->action = MLX5E_ACTION_DEL;
701         mlx5e_for_each_hash_node(hn, tmp, fs->l2.netdev_mc, i)
702                 hn->action = MLX5E_ACTION_DEL;
703
704         if (fs->state_destroy)
705                 mlx5e_sync_netdev_addr(fs, netdev);
706
707         mlx5e_apply_netdev_addr(fs);
708 }
709
710 #define MLX5E_PROMISC_GROUP0_SIZE BIT(0)
711 #define MLX5E_PROMISC_TABLE_SIZE MLX5E_PROMISC_GROUP0_SIZE
712
713 static int mlx5e_add_promisc_rule(struct mlx5e_flow_steering *fs)
714 {
715         struct mlx5_flow_table *ft = fs->promisc.ft.t;
716         struct mlx5_flow_destination dest = {};
717         struct mlx5_flow_handle **rule_p;
718         MLX5_DECLARE_FLOW_ACT(flow_act);
719         struct mlx5_flow_spec *spec;
720         int err = 0;
721
722         spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
723         if (!spec)
724                 return -ENOMEM;
725         dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
726         dest.ft = mlx5_get_ttc_flow_table(fs->ttc);
727
728         rule_p = &fs->promisc.rule;
729         *rule_p = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1);
730         if (IS_ERR(*rule_p)) {
731                 err = PTR_ERR(*rule_p);
732                 *rule_p = NULL;
733                 mlx5_core_err(fs->mdev, "%s: add promiscuous rule failed\n", __func__);
734         }
735         kvfree(spec);
736         return err;
737 }
738
739 static int mlx5e_create_promisc_table(struct mlx5e_flow_steering *fs)
740 {
741         struct mlx5e_flow_table *ft = &fs->promisc.ft;
742         struct mlx5_flow_table_attr ft_attr = {};
743         int err;
744
745         ft_attr.max_fte = MLX5E_PROMISC_TABLE_SIZE;
746         ft_attr.autogroup.max_num_groups = 1;
747         ft_attr.level = MLX5E_PROMISC_FT_LEVEL;
748         ft_attr.prio = MLX5E_NIC_PRIO;
749
750         ft->t = mlx5_create_auto_grouped_flow_table(fs->ns, &ft_attr);
751         if (IS_ERR(ft->t)) {
752                 err = PTR_ERR(ft->t);
753                 mlx5_core_err(fs->mdev, "fail to create promisc table err=%d\n", err);
754                 return err;
755         }
756
757         err = mlx5e_add_promisc_rule(fs);
758         if (err)
759                 goto err_destroy_promisc_table;
760
761         return 0;
762
763 err_destroy_promisc_table:
764         mlx5_destroy_flow_table(ft->t);
765         ft->t = NULL;
766
767         return err;
768 }
769
770 static void mlx5e_del_promisc_rule(struct mlx5e_flow_steering *fs)
771 {
772         if (WARN(!fs->promisc.rule, "Trying to remove non-existing promiscuous rule"))
773                 return;
774         mlx5_del_flow_rules(fs->promisc.rule);
775         fs->promisc.rule = NULL;
776 }
777
778 static void mlx5e_destroy_promisc_table(struct mlx5e_flow_steering *fs)
779 {
780         if (WARN(!fs->promisc.ft.t, "Trying to remove non-existing promiscuous table"))
781                 return;
782         mlx5e_del_promisc_rule(fs);
783         mlx5_destroy_flow_table(fs->promisc.ft.t);
784         fs->promisc.ft.t = NULL;
785 }
786
787 void mlx5e_fs_set_rx_mode_work(struct mlx5e_flow_steering *fs,
788                                struct net_device *netdev)
789 {
790         struct mlx5e_l2_table *ea = &fs->l2;
791
792         bool rx_mode_enable  = fs->state_destroy;
793         bool promisc_enabled   = rx_mode_enable && (netdev->flags & IFF_PROMISC);
794         bool allmulti_enabled  = rx_mode_enable && (netdev->flags & IFF_ALLMULTI);
795         bool broadcast_enabled = rx_mode_enable;
796
797         bool enable_promisc    = !ea->promisc_enabled   &&  promisc_enabled;
798         bool disable_promisc   =  ea->promisc_enabled   && !promisc_enabled;
799         bool enable_allmulti   = !ea->allmulti_enabled  &&  allmulti_enabled;
800         bool disable_allmulti  =  ea->allmulti_enabled  && !allmulti_enabled;
801         bool enable_broadcast  = !ea->broadcast_enabled &&  broadcast_enabled;
802         bool disable_broadcast =  ea->broadcast_enabled && !broadcast_enabled;
803         int err;
804
805         if (enable_promisc) {
806                 err = mlx5e_create_promisc_table(fs);
807                 if (err)
808                         enable_promisc = false;
809                 if (!fs->vlan_strip_disable && !err)
810                         mlx5_core_warn_once(fs->mdev,
811                                             "S-tagged traffic will be dropped while C-tag vlan stripping is enabled\n");
812         }
813         if (enable_allmulti)
814                 mlx5e_add_l2_flow_rule(fs, &ea->allmulti, MLX5E_ALLMULTI);
815         if (enable_broadcast)
816                 mlx5e_add_l2_flow_rule(fs, &ea->broadcast, MLX5E_FULLMATCH);
817
818         mlx5e_handle_netdev_addr(fs, netdev);
819
820         if (disable_broadcast)
821                 mlx5e_del_l2_flow_rule(fs, &ea->broadcast);
822         if (disable_allmulti)
823                 mlx5e_del_l2_flow_rule(fs, &ea->allmulti);
824         if (disable_promisc)
825                 mlx5e_destroy_promisc_table(fs);
826
827         ea->promisc_enabled   = promisc_enabled;
828         ea->allmulti_enabled  = allmulti_enabled;
829         ea->broadcast_enabled = broadcast_enabled;
830
831         mlx5e_vport_context_update(fs, netdev);
832 }
833
834 static void mlx5e_destroy_groups(struct mlx5e_flow_table *ft)
835 {
836         int i;
837
838         for (i = ft->num_groups - 1; i >= 0; i--) {
839                 if (!IS_ERR_OR_NULL(ft->g[i]))
840                         mlx5_destroy_flow_group(ft->g[i]);
841                 ft->g[i] = NULL;
842         }
843         ft->num_groups = 0;
844 }
845
846 void mlx5e_fs_init_l2_addr(struct mlx5e_flow_steering *fs, struct net_device *netdev)
847 {
848         ether_addr_copy(fs->l2.broadcast.addr, netdev->broadcast);
849 }
850
851 void mlx5e_destroy_flow_table(struct mlx5e_flow_table *ft)
852 {
853         mlx5e_destroy_groups(ft);
854         kfree(ft->g);
855         mlx5_destroy_flow_table(ft->t);
856         ft->t = NULL;
857 }
858
859 static void mlx5e_set_inner_ttc_params(struct mlx5e_priv *priv,
860                                        struct ttc_params *ttc_params)
861 {
862         struct mlx5_flow_table_attr *ft_attr = &ttc_params->ft_attr;
863         int tt;
864
865         memset(ttc_params, 0, sizeof(*ttc_params));
866         ttc_params->ns = mlx5_get_flow_namespace(priv->fs->mdev,
867                                                  MLX5_FLOW_NAMESPACE_KERNEL);
868         ft_attr->level = MLX5E_INNER_TTC_FT_LEVEL;
869         ft_attr->prio = MLX5E_NIC_PRIO;
870
871         for (tt = 0; tt < MLX5_NUM_TT; tt++) {
872                 ttc_params->dests[tt].type = MLX5_FLOW_DESTINATION_TYPE_TIR;
873                 ttc_params->dests[tt].tir_num =
874                         tt == MLX5_TT_ANY ?
875                                 mlx5e_rx_res_get_tirn_direct(priv->rx_res, 0) :
876                                 mlx5e_rx_res_get_tirn_rss_inner(priv->rx_res,
877                                                                 tt);
878         }
879 }
880
881 void mlx5e_set_ttc_params(struct mlx5e_priv *priv,
882                           struct ttc_params *ttc_params, bool tunnel)
883
884 {
885         struct mlx5_flow_table_attr *ft_attr = &ttc_params->ft_attr;
886         int tt;
887
888         memset(ttc_params, 0, sizeof(*ttc_params));
889         ttc_params->ns = mlx5_get_flow_namespace(priv->fs->mdev,
890                                                  MLX5_FLOW_NAMESPACE_KERNEL);
891         ft_attr->level = MLX5E_TTC_FT_LEVEL;
892         ft_attr->prio = MLX5E_NIC_PRIO;
893
894         for (tt = 0; tt < MLX5_NUM_TT; tt++) {
895                 ttc_params->dests[tt].type = MLX5_FLOW_DESTINATION_TYPE_TIR;
896                 ttc_params->dests[tt].tir_num =
897                         tt == MLX5_TT_ANY ?
898                                 mlx5e_rx_res_get_tirn_direct(priv->rx_res, 0) :
899                                 mlx5e_rx_res_get_tirn_rss(priv->rx_res, tt);
900         }
901
902         ttc_params->inner_ttc = tunnel;
903         if (!tunnel || !mlx5_tunnel_inner_ft_supported(priv->fs->mdev))
904                 return;
905
906         for (tt = 0; tt < MLX5_NUM_TUNNEL_TT; tt++) {
907                 ttc_params->tunnel_dests[tt].type =
908                         MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
909                 ttc_params->tunnel_dests[tt].ft =
910                         mlx5_get_ttc_flow_table(priv->fs->inner_ttc);
911         }
912 }
913
914 static void mlx5e_del_l2_flow_rule(struct mlx5e_flow_steering *fs,
915                                    struct mlx5e_l2_rule *ai)
916 {
917         if (!IS_ERR_OR_NULL(ai->rule)) {
918                 mlx5_del_flow_rules(ai->rule);
919                 ai->rule = NULL;
920         }
921 }
922
923 static int mlx5e_add_l2_flow_rule(struct mlx5e_flow_steering *fs,
924                                   struct mlx5e_l2_rule *ai, int type)
925 {
926         struct mlx5_flow_table *ft = fs->l2.ft.t;
927         struct mlx5_flow_destination dest = {};
928         MLX5_DECLARE_FLOW_ACT(flow_act);
929         struct mlx5_flow_spec *spec;
930         int err = 0;
931         u8 *mc_dmac;
932         u8 *mv_dmac;
933
934         spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
935         if (!spec)
936                 return -ENOMEM;
937
938         mc_dmac = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
939                                outer_headers.dmac_47_16);
940         mv_dmac = MLX5_ADDR_OF(fte_match_param, spec->match_value,
941                                outer_headers.dmac_47_16);
942
943         dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
944         dest.ft = mlx5_get_ttc_flow_table(fs->ttc);
945
946         switch (type) {
947         case MLX5E_FULLMATCH:
948                 spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
949                 eth_broadcast_addr(mc_dmac);
950                 ether_addr_copy(mv_dmac, ai->addr);
951                 break;
952
953         case MLX5E_ALLMULTI:
954                 spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
955                 mc_dmac[0] = 0x01;
956                 mv_dmac[0] = 0x01;
957                 break;
958         }
959
960         ai->rule = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1);
961         if (IS_ERR(ai->rule)) {
962                 mlx5_core_err(fs->mdev, "%s: add l2 rule(mac:%pM) failed\n",
963                               __func__, mv_dmac);
964                 err = PTR_ERR(ai->rule);
965                 ai->rule = NULL;
966         }
967
968         kvfree(spec);
969
970         return err;
971 }
972
973 #define MLX5E_NUM_L2_GROUPS        3
974 #define MLX5E_L2_GROUP1_SIZE       BIT(15)
975 #define MLX5E_L2_GROUP2_SIZE       BIT(0)
976 #define MLX5E_L2_GROUP_TRAP_SIZE   BIT(0) /* must be last */
977 #define MLX5E_L2_TABLE_SIZE        (MLX5E_L2_GROUP1_SIZE +\
978                                     MLX5E_L2_GROUP2_SIZE +\
979                                     MLX5E_L2_GROUP_TRAP_SIZE)
980 static int mlx5e_create_l2_table_groups(struct mlx5e_l2_table *l2_table)
981 {
982         int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
983         struct mlx5e_flow_table *ft = &l2_table->ft;
984         int ix = 0;
985         u8 *mc_dmac;
986         u32 *in;
987         int err;
988         u8 *mc;
989
990         ft->g = kcalloc(MLX5E_NUM_L2_GROUPS, sizeof(*ft->g), GFP_KERNEL);
991         if (!ft->g)
992                 return -ENOMEM;
993         in = kvzalloc(inlen, GFP_KERNEL);
994         if (!in) {
995                 kfree(ft->g);
996                 return -ENOMEM;
997         }
998
999         mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria);
1000         mc_dmac = MLX5_ADDR_OF(fte_match_param, mc,
1001                                outer_headers.dmac_47_16);
1002         /* Flow Group for full match */
1003         eth_broadcast_addr(mc_dmac);
1004         MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS);
1005         MLX5_SET_CFG(in, start_flow_index, ix);
1006         ix += MLX5E_L2_GROUP1_SIZE;
1007         MLX5_SET_CFG(in, end_flow_index, ix - 1);
1008         ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
1009         if (IS_ERR(ft->g[ft->num_groups]))
1010                 goto err_destroy_groups;
1011         ft->num_groups++;
1012
1013         /* Flow Group for allmulti */
1014         eth_zero_addr(mc_dmac);
1015         mc_dmac[0] = 0x01;
1016         MLX5_SET_CFG(in, start_flow_index, ix);
1017         ix += MLX5E_L2_GROUP2_SIZE;
1018         MLX5_SET_CFG(in, end_flow_index, ix - 1);
1019         ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
1020         if (IS_ERR(ft->g[ft->num_groups]))
1021                 goto err_destroy_groups;
1022         ft->num_groups++;
1023
1024         /* Flow Group for l2 traps */
1025         memset(in, 0, inlen);
1026         MLX5_SET_CFG(in, start_flow_index, ix);
1027         ix += MLX5E_L2_GROUP_TRAP_SIZE;
1028         MLX5_SET_CFG(in, end_flow_index, ix - 1);
1029         ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
1030         if (IS_ERR(ft->g[ft->num_groups]))
1031                 goto err_destroy_groups;
1032         ft->num_groups++;
1033
1034         kvfree(in);
1035         return 0;
1036
1037 err_destroy_groups:
1038         err = PTR_ERR(ft->g[ft->num_groups]);
1039         ft->g[ft->num_groups] = NULL;
1040         mlx5e_destroy_groups(ft);
1041         kvfree(in);
1042         kfree(ft->g);
1043
1044         return err;
1045 }
1046
1047 static void mlx5e_destroy_l2_table(struct mlx5e_priv *priv)
1048 {
1049         mlx5e_destroy_flow_table(&priv->fs->l2.ft);
1050 }
1051
1052 static int mlx5e_create_l2_table(struct mlx5e_priv *priv)
1053 {
1054         struct mlx5e_l2_table *l2_table = &priv->fs->l2;
1055         struct mlx5e_flow_table *ft = &l2_table->ft;
1056         struct mlx5_flow_table_attr ft_attr = {};
1057         int err;
1058
1059         ft->num_groups = 0;
1060
1061         ft_attr.max_fte = MLX5E_L2_TABLE_SIZE;
1062         ft_attr.level = MLX5E_L2_FT_LEVEL;
1063         ft_attr.prio = MLX5E_NIC_PRIO;
1064
1065         ft->t = mlx5_create_flow_table(priv->fs->ns, &ft_attr);
1066         if (IS_ERR(ft->t)) {
1067                 err = PTR_ERR(ft->t);
1068                 ft->t = NULL;
1069                 return err;
1070         }
1071
1072         err = mlx5e_create_l2_table_groups(l2_table);
1073         if (err)
1074                 goto err_destroy_flow_table;
1075
1076         return 0;
1077
1078 err_destroy_flow_table:
1079         mlx5_destroy_flow_table(ft->t);
1080         ft->t = NULL;
1081
1082         return err;
1083 }
1084
1085 #define MLX5E_NUM_VLAN_GROUPS   5
1086 #define MLX5E_VLAN_GROUP0_SIZE  BIT(12)
1087 #define MLX5E_VLAN_GROUP1_SIZE  BIT(12)
1088 #define MLX5E_VLAN_GROUP2_SIZE  BIT(1)
1089 #define MLX5E_VLAN_GROUP3_SIZE  BIT(0)
1090 #define MLX5E_VLAN_GROUP_TRAP_SIZE BIT(0) /* must be last */
1091 #define MLX5E_VLAN_TABLE_SIZE   (MLX5E_VLAN_GROUP0_SIZE +\
1092                                  MLX5E_VLAN_GROUP1_SIZE +\
1093                                  MLX5E_VLAN_GROUP2_SIZE +\
1094                                  MLX5E_VLAN_GROUP3_SIZE +\
1095                                  MLX5E_VLAN_GROUP_TRAP_SIZE)
1096
1097 static int __mlx5e_create_vlan_table_groups(struct mlx5e_flow_table *ft, u32 *in,
1098                                             int inlen)
1099 {
1100         int err;
1101         int ix = 0;
1102         u8 *mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria);
1103
1104         memset(in, 0, inlen);
1105         MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS);
1106         MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.cvlan_tag);
1107         MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.first_vid);
1108         MLX5_SET_CFG(in, start_flow_index, ix);
1109         ix += MLX5E_VLAN_GROUP0_SIZE;
1110         MLX5_SET_CFG(in, end_flow_index, ix - 1);
1111         ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
1112         if (IS_ERR(ft->g[ft->num_groups]))
1113                 goto err_destroy_groups;
1114         ft->num_groups++;
1115
1116         memset(in, 0, inlen);
1117         MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS);
1118         MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.svlan_tag);
1119         MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.first_vid);
1120         MLX5_SET_CFG(in, start_flow_index, ix);
1121         ix += MLX5E_VLAN_GROUP1_SIZE;
1122         MLX5_SET_CFG(in, end_flow_index, ix - 1);
1123         ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
1124         if (IS_ERR(ft->g[ft->num_groups]))
1125                 goto err_destroy_groups;
1126         ft->num_groups++;
1127
1128         memset(in, 0, inlen);
1129         MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS);
1130         MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.cvlan_tag);
1131         MLX5_SET_CFG(in, start_flow_index, ix);
1132         ix += MLX5E_VLAN_GROUP2_SIZE;
1133         MLX5_SET_CFG(in, end_flow_index, ix - 1);
1134         ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
1135         if (IS_ERR(ft->g[ft->num_groups]))
1136                 goto err_destroy_groups;
1137         ft->num_groups++;
1138
1139         memset(in, 0, inlen);
1140         MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS);
1141         MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.svlan_tag);
1142         MLX5_SET_CFG(in, start_flow_index, ix);
1143         ix += MLX5E_VLAN_GROUP3_SIZE;
1144         MLX5_SET_CFG(in, end_flow_index, ix - 1);
1145         ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
1146         if (IS_ERR(ft->g[ft->num_groups]))
1147                 goto err_destroy_groups;
1148         ft->num_groups++;
1149
1150         memset(in, 0, inlen);
1151         MLX5_SET_CFG(in, start_flow_index, ix);
1152         ix += MLX5E_VLAN_GROUP_TRAP_SIZE;
1153         MLX5_SET_CFG(in, end_flow_index, ix - 1);
1154         ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
1155         if (IS_ERR(ft->g[ft->num_groups]))
1156                 goto err_destroy_groups;
1157         ft->num_groups++;
1158
1159         return 0;
1160
1161 err_destroy_groups:
1162         err = PTR_ERR(ft->g[ft->num_groups]);
1163         ft->g[ft->num_groups] = NULL;
1164         mlx5e_destroy_groups(ft);
1165
1166         return err;
1167 }
1168
1169 static int mlx5e_create_vlan_table_groups(struct mlx5e_flow_table *ft)
1170 {
1171         u32 *in;
1172         int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
1173         int err;
1174
1175         in = kvzalloc(inlen, GFP_KERNEL);
1176         if (!in)
1177                 return -ENOMEM;
1178
1179         err = __mlx5e_create_vlan_table_groups(ft, in, inlen);
1180
1181         kvfree(in);
1182         return err;
1183 }
1184
1185 static int mlx5e_fs_create_vlan_table(struct mlx5e_flow_steering *fs)
1186 {
1187         struct mlx5_flow_table_attr ft_attr = {};
1188         struct mlx5e_flow_table *ft;
1189         int err;
1190
1191         ft = &fs->vlan->ft;
1192         ft->num_groups = 0;
1193
1194         ft_attr.max_fte = MLX5E_VLAN_TABLE_SIZE;
1195         ft_attr.level = MLX5E_VLAN_FT_LEVEL;
1196         ft_attr.prio = MLX5E_NIC_PRIO;
1197
1198         ft->t = mlx5_create_flow_table(fs->ns, &ft_attr);
1199         if (IS_ERR(ft->t))
1200                 return PTR_ERR(ft->t);
1201
1202         ft->g = kcalloc(MLX5E_NUM_VLAN_GROUPS, sizeof(*ft->g), GFP_KERNEL);
1203         if (!ft->g) {
1204                 err = -ENOMEM;
1205                 goto err_destroy_vlan_table;
1206         }
1207
1208         err = mlx5e_create_vlan_table_groups(ft);
1209         if (err)
1210                 goto err_free_g;
1211
1212         mlx5e_fs_add_vlan_rules(fs);
1213
1214         return 0;
1215
1216 err_free_g:
1217         kfree(ft->g);
1218 err_destroy_vlan_table:
1219         mlx5_destroy_flow_table(ft->t);
1220
1221         return err;
1222 }
1223
1224 static void mlx5e_destroy_vlan_table(struct mlx5e_priv *priv)
1225 {
1226         mlx5e_del_vlan_rules(priv);
1227         mlx5e_destroy_flow_table(&priv->fs->vlan->ft);
1228 }
1229
1230 static void mlx5e_destroy_inner_ttc_table(struct mlx5e_priv *priv)
1231 {
1232         if (!mlx5_tunnel_inner_ft_supported(priv->fs->mdev))
1233                 return;
1234         mlx5_destroy_ttc_table(priv->fs->inner_ttc);
1235 }
1236
1237 void mlx5e_destroy_ttc_table(struct mlx5e_priv *priv)
1238 {
1239         mlx5_destroy_ttc_table(priv->fs->ttc);
1240 }
1241
1242 static int mlx5e_create_inner_ttc_table(struct mlx5e_priv *priv)
1243 {
1244         struct ttc_params ttc_params = {};
1245
1246         if (!mlx5_tunnel_inner_ft_supported(priv->fs->mdev))
1247                 return 0;
1248
1249         mlx5e_set_inner_ttc_params(priv, &ttc_params);
1250         priv->fs->inner_ttc = mlx5_create_inner_ttc_table(priv->fs->mdev,
1251                                                           &ttc_params);
1252         if (IS_ERR(priv->fs->inner_ttc))
1253                 return PTR_ERR(priv->fs->inner_ttc);
1254         return 0;
1255 }
1256
1257 int mlx5e_create_ttc_table(struct mlx5e_priv *priv)
1258 {
1259         struct ttc_params ttc_params = {};
1260
1261         mlx5e_set_ttc_params(priv, &ttc_params, true);
1262         priv->fs->ttc = mlx5_create_ttc_table(priv->fs->mdev, &ttc_params);
1263         if (IS_ERR(priv->fs->ttc))
1264                 return PTR_ERR(priv->fs->ttc);
1265         return 0;
1266 }
1267
1268 int mlx5e_create_flow_steering(struct mlx5e_priv *priv)
1269 {
1270         int err;
1271
1272         priv->fs->ns = mlx5_get_flow_namespace(priv->fs->mdev,
1273                                                MLX5_FLOW_NAMESPACE_KERNEL);
1274
1275         if (!priv->fs->ns)
1276                 return -EOPNOTSUPP;
1277
1278         err = mlx5e_arfs_create_tables(priv);
1279         if (err) {
1280                 mlx5_core_err(priv->fs->mdev, "Failed to create arfs tables, err=%d\n",
1281                               err);
1282                 priv->netdev->hw_features &= ~NETIF_F_NTUPLE;
1283         }
1284
1285         err = mlx5e_create_inner_ttc_table(priv);
1286         if (err) {
1287                 mlx5_core_err(priv->fs->mdev,
1288                               "Failed to create inner ttc table, err=%d\n", err);
1289                 goto err_destroy_arfs_tables;
1290         }
1291
1292         err = mlx5e_create_ttc_table(priv);
1293         if (err) {
1294                 mlx5_core_err(priv->fs->mdev, "Failed to create ttc table, err=%d\n",
1295                               err);
1296                 goto err_destroy_inner_ttc_table;
1297         }
1298
1299         err = mlx5e_create_l2_table(priv);
1300         if (err) {
1301                 mlx5_core_err(priv->fs->mdev, "Failed to create l2 table, err=%d\n",
1302                               err);
1303                 goto err_destroy_ttc_table;
1304         }
1305
1306         err = mlx5e_fs_create_vlan_table(priv->fs);
1307         if (err) {
1308                 mlx5_core_err(priv->fs->mdev, "Failed to create vlan table, err=%d\n",
1309                               err);
1310                 goto err_destroy_l2_table;
1311         }
1312
1313         err = mlx5e_ptp_alloc_rx_fs(priv);
1314         if (err)
1315                 goto err_destory_vlan_table;
1316
1317         mlx5e_ethtool_init_steering(priv);
1318
1319         return 0;
1320
1321 err_destory_vlan_table:
1322         mlx5e_destroy_vlan_table(priv);
1323 err_destroy_l2_table:
1324         mlx5e_destroy_l2_table(priv);
1325 err_destroy_ttc_table:
1326         mlx5e_destroy_ttc_table(priv);
1327 err_destroy_inner_ttc_table:
1328         mlx5e_destroy_inner_ttc_table(priv);
1329 err_destroy_arfs_tables:
1330         mlx5e_arfs_destroy_tables(priv);
1331
1332         return err;
1333 }
1334
1335 void mlx5e_destroy_flow_steering(struct mlx5e_priv *priv)
1336 {
1337         mlx5e_ptp_free_rx_fs(priv);
1338         mlx5e_destroy_vlan_table(priv);
1339         mlx5e_destroy_l2_table(priv);
1340         mlx5e_destroy_ttc_table(priv);
1341         mlx5e_destroy_inner_ttc_table(priv);
1342         mlx5e_arfs_destroy_tables(priv);
1343         mlx5e_ethtool_cleanup_steering(priv);
1344 }
1345
1346 static int mlx5e_fs_vlan_alloc(struct mlx5e_flow_steering *fs)
1347 {
1348         fs->vlan = kvzalloc(sizeof(*fs->vlan), GFP_KERNEL);
1349         if (!fs->vlan)
1350                 return -ENOMEM;
1351         return 0;
1352 }
1353
1354 static void mlx5e_fs_vlan_free(struct mlx5e_flow_steering *fs)
1355 {
1356         kvfree(fs->vlan);
1357 }
1358
1359 static int mlx5e_fs_tc_alloc(struct mlx5e_flow_steering *fs)
1360 {
1361         fs->tc = mlx5e_tc_table_alloc();
1362         if (IS_ERR(fs->tc))
1363                 return -ENOMEM;
1364         return 0;
1365 }
1366
1367 static void mlx5e_fs_tc_free(struct mlx5e_flow_steering *fs)
1368 {
1369         mlx5e_tc_table_free(fs->tc);
1370 }
1371
1372 struct mlx5e_flow_steering *mlx5e_fs_init(const struct mlx5e_profile *profile,
1373                                           struct mlx5_core_dev *mdev,
1374                                           bool state_destroy)
1375 {
1376         struct mlx5e_flow_steering *fs;
1377         int err;
1378
1379         fs = kvzalloc(sizeof(*fs), GFP_KERNEL);
1380         if (!fs)
1381                 goto err;
1382
1383         fs->mdev = mdev;
1384         fs->state_destroy = state_destroy;
1385         if (mlx5e_profile_feature_cap(profile, FS_VLAN)) {
1386                 err = mlx5e_fs_vlan_alloc(fs);
1387                 if (err)
1388                         goto err_free_fs;
1389         }
1390
1391         if (mlx5e_profile_feature_cap(profile, FS_TC)) {
1392                 err = mlx5e_fs_tc_alloc(fs);
1393                 if (err)
1394                         goto err_free_vlan;
1395         }
1396
1397         return fs;
1398
1399 err_free_vlan:
1400         mlx5e_fs_vlan_free(fs);
1401 err_free_fs:
1402         kvfree(fs);
1403 err:
1404         return NULL;
1405 }
1406
1407 void mlx5e_fs_cleanup(struct mlx5e_flow_steering *fs)
1408 {
1409         mlx5e_fs_tc_free(fs);
1410         mlx5e_fs_vlan_free(fs);
1411         kvfree(fs);
1412 }