linux/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
<<
>>
Prefs
   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_rep.h"
  41#include "lib/mpfs.h"
  42#include "en/ptp.h"
  43
  44static int mlx5e_add_l2_flow_rule(struct mlx5e_priv *priv,
  45                                  struct mlx5e_l2_rule *ai, int type);
  46static void mlx5e_del_l2_flow_rule(struct mlx5e_priv *priv,
  47                                   struct mlx5e_l2_rule *ai);
  48
  49enum {
  50        MLX5E_FULLMATCH = 0,
  51        MLX5E_ALLMULTI  = 1,
  52};
  53
  54enum {
  55        MLX5E_UC        = 0,
  56        MLX5E_MC_IPV4   = 1,
  57        MLX5E_MC_IPV6   = 2,
  58        MLX5E_MC_OTHER  = 3,
  59};
  60
  61enum {
  62        MLX5E_ACTION_NONE = 0,
  63        MLX5E_ACTION_ADD  = 1,
  64        MLX5E_ACTION_DEL  = 2,
  65};
  66
  67struct mlx5e_l2_hash_node {
  68        struct hlist_node          hlist;
  69        u8                         action;
  70        struct mlx5e_l2_rule ai;
  71        bool   mpfs;
  72};
  73
  74static inline int mlx5e_hash_l2(u8 *addr)
  75{
  76        return addr[5];
  77}
  78
  79static void mlx5e_add_l2_to_hash(struct hlist_head *hash, 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
 106static void mlx5e_del_l2_from_hash(struct mlx5e_l2_hash_node *hn)
 107{
 108        hlist_del(&hn->hlist);
 109        kfree(hn);
 110}
 111
 112struct 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
 125unsigned long *mlx5e_vlan_get_active_svlans(struct mlx5e_vlan_table *vlan)
 126{
 127        return vlan->active_svlans;
 128}
 129
 130struct mlx5_flow_table *mlx5e_vlan_get_flowtable(struct mlx5e_vlan_table *vlan)
 131{
 132        return vlan->ft.t;
 133}
 134
 135static int mlx5e_vport_context_update_vlans(struct mlx5e_priv *priv)
 136{
 137        struct net_device *ndev = priv->netdev;
 138        int max_list_size;
 139        int list_size;
 140        u16 *vlans;
 141        int vlan;
 142        int err;
 143        int i;
 144
 145        list_size = 0;
 146        for_each_set_bit(vlan, priv->fs.vlan->active_cvlans, VLAN_N_VID)
 147                list_size++;
 148
 149        max_list_size = 1 << MLX5_CAP_GEN(priv->mdev, log_max_vlan_list);
 150
 151        if (list_size > max_list_size) {
 152                netdev_warn(ndev,
 153                            "netdev vlans list size (%d) > (%d) max vport list size, some vlans will be dropped\n",
 154                            list_size, max_list_size);
 155                list_size = max_list_size;
 156        }
 157
 158        vlans = kcalloc(list_size, sizeof(*vlans), GFP_KERNEL);
 159        if (!vlans)
 160                return -ENOMEM;
 161
 162        i = 0;
 163        for_each_set_bit(vlan, priv->fs.vlan->active_cvlans, VLAN_N_VID) {
 164                if (i >= list_size)
 165                        break;
 166                vlans[i++] = vlan;
 167        }
 168
 169        err = mlx5_modify_nic_vport_vlans(priv->mdev, vlans, list_size);
 170        if (err)
 171                netdev_err(ndev, "Failed to modify vport vlans list err(%d)\n",
 172                           err);
 173
 174        kfree(vlans);
 175        return err;
 176}
 177
 178enum mlx5e_vlan_rule_type {
 179        MLX5E_VLAN_RULE_TYPE_UNTAGGED,
 180        MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID,
 181        MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID,
 182        MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID,
 183        MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID,
 184};
 185
 186static int __mlx5e_add_vlan_rule(struct mlx5e_priv *priv,
 187                                 enum mlx5e_vlan_rule_type rule_type,
 188                                 u16 vid, struct mlx5_flow_spec *spec)
 189{
 190        struct mlx5_flow_table *ft = priv->fs.vlan->ft.t;
 191        struct mlx5_flow_destination dest = {};
 192        struct mlx5_flow_handle **rule_p;
 193        MLX5_DECLARE_FLOW_ACT(flow_act);
 194        int err = 0;
 195
 196        dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
 197        dest.ft = priv->fs.l2.ft.t;
 198
 199        spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
 200
 201        switch (rule_type) {
 202        case MLX5E_VLAN_RULE_TYPE_UNTAGGED:
 203                /* cvlan_tag enabled in match criteria and
 204                 * disabled in match value means both S & C tags
 205                 * don't exist (untagged of both)
 206                 */
 207                rule_p = &priv->fs.vlan->untagged_rule;
 208                MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
 209                                 outer_headers.cvlan_tag);
 210                break;
 211        case MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID:
 212                rule_p = &priv->fs.vlan->any_cvlan_rule;
 213                MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
 214                                 outer_headers.cvlan_tag);
 215                MLX5_SET(fte_match_param, spec->match_value, outer_headers.cvlan_tag, 1);
 216                break;
 217        case MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID:
 218                rule_p = &priv->fs.vlan->any_svlan_rule;
 219                MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
 220                                 outer_headers.svlan_tag);
 221                MLX5_SET(fte_match_param, spec->match_value, outer_headers.svlan_tag, 1);
 222                break;
 223        case MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID:
 224                rule_p = &priv->fs.vlan->active_svlans_rule[vid];
 225                MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
 226                                 outer_headers.svlan_tag);
 227                MLX5_SET(fte_match_param, spec->match_value, outer_headers.svlan_tag, 1);
 228                MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
 229                                 outer_headers.first_vid);
 230                MLX5_SET(fte_match_param, spec->match_value, outer_headers.first_vid,
 231                         vid);
 232                break;
 233        default: /* MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID */
 234                rule_p = &priv->fs.vlan->active_cvlans_rule[vid];
 235                MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
 236                                 outer_headers.cvlan_tag);
 237                MLX5_SET(fte_match_param, spec->match_value, outer_headers.cvlan_tag, 1);
 238                MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
 239                                 outer_headers.first_vid);
 240                MLX5_SET(fte_match_param, spec->match_value, outer_headers.first_vid,
 241                         vid);
 242                break;
 243        }
 244
 245        if (WARN_ONCE(*rule_p, "VLAN rule already exists type %d", rule_type))
 246                return 0;
 247
 248        *rule_p = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1);
 249
 250        if (IS_ERR(*rule_p)) {
 251                err = PTR_ERR(*rule_p);
 252                *rule_p = NULL;
 253                netdev_err(priv->netdev, "%s: add rule failed\n", __func__);
 254        }
 255
 256        return err;
 257}
 258
 259static int mlx5e_add_vlan_rule(struct mlx5e_priv *priv,
 260                               enum mlx5e_vlan_rule_type rule_type, u16 vid)
 261{
 262        struct mlx5_flow_spec *spec;
 263        int err = 0;
 264
 265        spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
 266        if (!spec)
 267                return -ENOMEM;
 268
 269        if (rule_type == MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID)
 270                mlx5e_vport_context_update_vlans(priv);
 271
 272        err = __mlx5e_add_vlan_rule(priv, rule_type, vid, spec);
 273
 274        kvfree(spec);
 275
 276        return err;
 277}
 278
 279static void mlx5e_del_vlan_rule(struct mlx5e_priv *priv,
 280                                enum mlx5e_vlan_rule_type rule_type, u16 vid)
 281{
 282        switch (rule_type) {
 283        case MLX5E_VLAN_RULE_TYPE_UNTAGGED:
 284                if (priv->fs.vlan->untagged_rule) {
 285                        mlx5_del_flow_rules(priv->fs.vlan->untagged_rule);
 286                        priv->fs.vlan->untagged_rule = NULL;
 287                }
 288                break;
 289        case MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID:
 290                if (priv->fs.vlan->any_cvlan_rule) {
 291                        mlx5_del_flow_rules(priv->fs.vlan->any_cvlan_rule);
 292                        priv->fs.vlan->any_cvlan_rule = NULL;
 293                }
 294                break;
 295        case MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID:
 296                if (priv->fs.vlan->any_svlan_rule) {
 297                        mlx5_del_flow_rules(priv->fs.vlan->any_svlan_rule);
 298                        priv->fs.vlan->any_svlan_rule = NULL;
 299                }
 300                break;
 301        case MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID:
 302                if (priv->fs.vlan->active_svlans_rule[vid]) {
 303                        mlx5_del_flow_rules(priv->fs.vlan->active_svlans_rule[vid]);
 304                        priv->fs.vlan->active_svlans_rule[vid] = NULL;
 305                }
 306                break;
 307        case MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID:
 308                if (priv->fs.vlan->active_cvlans_rule[vid]) {
 309                        mlx5_del_flow_rules(priv->fs.vlan->active_cvlans_rule[vid]);
 310                        priv->fs.vlan->active_cvlans_rule[vid] = NULL;
 311                }
 312                mlx5e_vport_context_update_vlans(priv);
 313                break;
 314        }
 315}
 316
 317static void mlx5e_del_any_vid_rules(struct mlx5e_priv *priv)
 318{
 319        mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 0);
 320        mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID, 0);
 321}
 322
 323static int mlx5e_add_any_vid_rules(struct mlx5e_priv *priv)
 324{
 325        int err;
 326
 327        err = mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 0);
 328        if (err)
 329                return err;
 330
 331        return mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID, 0);
 332}
 333
 334static struct mlx5_flow_handle *
 335mlx5e_add_trap_rule(struct mlx5_flow_table *ft, int trap_id, int tir_num)
 336{
 337        struct mlx5_flow_destination dest = {};
 338        MLX5_DECLARE_FLOW_ACT(flow_act);
 339        struct mlx5_flow_handle *rule;
 340        struct mlx5_flow_spec *spec;
 341
 342        spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
 343        if (!spec)
 344                return ERR_PTR(-ENOMEM);
 345        spec->flow_context.flags |= FLOW_CONTEXT_HAS_TAG;
 346        spec->flow_context.flow_tag = trap_id;
 347        dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
 348        dest.tir_num = tir_num;
 349
 350        rule = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1);
 351        kvfree(spec);
 352        return rule;
 353}
 354
 355int mlx5e_add_vlan_trap(struct mlx5e_priv *priv, int trap_id, int tir_num)
 356{
 357        struct mlx5_flow_table *ft = priv->fs.vlan->ft.t;
 358        struct mlx5_flow_handle *rule;
 359        int err;
 360
 361        rule = mlx5e_add_trap_rule(ft, trap_id, tir_num);
 362        if (IS_ERR(rule)) {
 363                err = PTR_ERR(rule);
 364                priv->fs.vlan->trap_rule = NULL;
 365                netdev_err(priv->netdev, "%s: add VLAN trap rule failed, err %d\n",
 366                           __func__, err);
 367                return err;
 368        }
 369        priv->fs.vlan->trap_rule = rule;
 370        return 0;
 371}
 372
 373void mlx5e_remove_vlan_trap(struct mlx5e_priv *priv)
 374{
 375        if (priv->fs.vlan->trap_rule) {
 376                mlx5_del_flow_rules(priv->fs.vlan->trap_rule);
 377                priv->fs.vlan->trap_rule = NULL;
 378        }
 379}
 380
 381int mlx5e_add_mac_trap(struct mlx5e_priv *priv, int trap_id, int tir_num)
 382{
 383        struct mlx5_flow_table *ft = priv->fs.l2.ft.t;
 384        struct mlx5_flow_handle *rule;
 385        int err;
 386
 387        rule = mlx5e_add_trap_rule(ft, trap_id, tir_num);
 388        if (IS_ERR(rule)) {
 389                err = PTR_ERR(rule);
 390                priv->fs.l2.trap_rule = NULL;
 391                netdev_err(priv->netdev, "%s: add MAC trap rule failed, err %d\n",
 392                           __func__, err);
 393                return err;
 394        }
 395        priv->fs.l2.trap_rule = rule;
 396        return 0;
 397}
 398
 399void mlx5e_remove_mac_trap(struct mlx5e_priv *priv)
 400{
 401        if (priv->fs.l2.trap_rule) {
 402                mlx5_del_flow_rules(priv->fs.l2.trap_rule);
 403                priv->fs.l2.trap_rule = NULL;
 404        }
 405}
 406
 407void mlx5e_enable_cvlan_filter(struct mlx5e_priv *priv)
 408{
 409        if (!priv->fs.vlan->cvlan_filter_disabled)
 410                return;
 411
 412        priv->fs.vlan->cvlan_filter_disabled = false;
 413        if (priv->netdev->flags & IFF_PROMISC)
 414                return;
 415        mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 0);
 416}
 417
 418void mlx5e_disable_cvlan_filter(struct mlx5e_priv *priv)
 419{
 420        if (priv->fs.vlan->cvlan_filter_disabled)
 421                return;
 422
 423        priv->fs.vlan->cvlan_filter_disabled = true;
 424        if (priv->netdev->flags & IFF_PROMISC)
 425                return;
 426        mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 0);
 427}
 428
 429static int mlx5e_vlan_rx_add_cvid(struct mlx5e_priv *priv, u16 vid)
 430{
 431        int err;
 432
 433        set_bit(vid, priv->fs.vlan->active_cvlans);
 434
 435        err = mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID, vid);
 436        if (err)
 437                clear_bit(vid, priv->fs.vlan->active_cvlans);
 438
 439        return err;
 440}
 441
 442static int mlx5e_vlan_rx_add_svid(struct mlx5e_priv *priv, u16 vid)
 443{
 444        struct net_device *netdev = priv->netdev;
 445        int err;
 446
 447        set_bit(vid, priv->fs.vlan->active_svlans);
 448
 449        err = mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID, vid);
 450        if (err) {
 451                clear_bit(vid, priv->fs.vlan->active_svlans);
 452                return err;
 453        }
 454
 455        /* Need to fix some features.. */
 456        netdev_update_features(netdev);
 457        return err;
 458}
 459
 460int mlx5e_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid)
 461{
 462        struct mlx5e_priv *priv = netdev_priv(dev);
 463
 464        if (mlx5e_is_uplink_rep(priv))
 465                return 0; /* no vlan table for uplink rep */
 466
 467        if (be16_to_cpu(proto) == ETH_P_8021Q)
 468                return mlx5e_vlan_rx_add_cvid(priv, vid);
 469        else if (be16_to_cpu(proto) == ETH_P_8021AD)
 470                return mlx5e_vlan_rx_add_svid(priv, vid);
 471
 472        return -EOPNOTSUPP;
 473}
 474
 475int mlx5e_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid)
 476{
 477        struct mlx5e_priv *priv = netdev_priv(dev);
 478
 479        if (mlx5e_is_uplink_rep(priv))
 480                return 0; /* no vlan table for uplink rep */
 481
 482        if (be16_to_cpu(proto) == ETH_P_8021Q) {
 483                clear_bit(vid, priv->fs.vlan->active_cvlans);
 484                mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID, vid);
 485        } else if (be16_to_cpu(proto) == ETH_P_8021AD) {
 486                clear_bit(vid, priv->fs.vlan->active_svlans);
 487                mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID, vid);
 488                netdev_update_features(dev);
 489        }
 490
 491        return 0;
 492}
 493
 494static void mlx5e_add_vlan_rules(struct mlx5e_priv *priv)
 495{
 496        int i;
 497
 498        mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_UNTAGGED, 0);
 499
 500        for_each_set_bit(i, priv->fs.vlan->active_cvlans, VLAN_N_VID) {
 501                mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID, i);
 502        }
 503
 504        for_each_set_bit(i, priv->fs.vlan->active_svlans, VLAN_N_VID)
 505                mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID, i);
 506
 507        if (priv->fs.vlan->cvlan_filter_disabled)
 508                mlx5e_add_any_vid_rules(priv);
 509}
 510
 511static void mlx5e_del_vlan_rules(struct mlx5e_priv *priv)
 512{
 513        int i;
 514
 515        mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_UNTAGGED, 0);
 516
 517        for_each_set_bit(i, priv->fs.vlan->active_cvlans, VLAN_N_VID) {
 518                mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID, i);
 519        }
 520
 521        for_each_set_bit(i, priv->fs.vlan->active_svlans, VLAN_N_VID)
 522                mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID, i);
 523
 524        WARN_ON_ONCE(!(test_bit(MLX5E_STATE_DESTROYING, &priv->state)));
 525
 526        mlx5e_remove_vlan_trap(priv);
 527
 528        /* must be called after DESTROY bit is set and
 529         * set_rx_mode is called and flushed
 530         */
 531        if (priv->fs.vlan->cvlan_filter_disabled)
 532                mlx5e_del_any_vid_rules(priv);
 533}
 534
 535#define mlx5e_for_each_hash_node(hn, tmp, hash, i) \
 536        for (i = 0; i < MLX5E_L2_ADDR_HASH_SIZE; i++) \
 537                hlist_for_each_entry_safe(hn, tmp, &hash[i], hlist)
 538
 539static void mlx5e_execute_l2_action(struct mlx5e_priv *priv,
 540                                    struct mlx5e_l2_hash_node *hn)
 541{
 542        u8 action = hn->action;
 543        u8 mac_addr[ETH_ALEN];
 544        int l2_err = 0;
 545
 546        ether_addr_copy(mac_addr, hn->ai.addr);
 547
 548        switch (action) {
 549        case MLX5E_ACTION_ADD:
 550                mlx5e_add_l2_flow_rule(priv, &hn->ai, MLX5E_FULLMATCH);
 551                if (!is_multicast_ether_addr(mac_addr)) {
 552                        l2_err = mlx5_mpfs_add_mac(priv->mdev, mac_addr);
 553                        hn->mpfs = !l2_err;
 554                }
 555                hn->action = MLX5E_ACTION_NONE;
 556                break;
 557
 558        case MLX5E_ACTION_DEL:
 559                if (!is_multicast_ether_addr(mac_addr) && hn->mpfs)
 560                        l2_err = mlx5_mpfs_del_mac(priv->mdev, mac_addr);
 561                mlx5e_del_l2_flow_rule(priv, &hn->ai);
 562                mlx5e_del_l2_from_hash(hn);
 563                break;
 564        }
 565
 566        if (l2_err)
 567                netdev_warn(priv->netdev, "MPFS, failed to %s mac %pM, err(%d)\n",
 568                            action == MLX5E_ACTION_ADD ? "add" : "del", mac_addr, l2_err);
 569}
 570
 571static void mlx5e_sync_netdev_addr(struct mlx5e_priv *priv)
 572{
 573        struct net_device *netdev = priv->netdev;
 574        struct netdev_hw_addr *ha;
 575
 576        netif_addr_lock_bh(netdev);
 577
 578        mlx5e_add_l2_to_hash(priv->fs.l2.netdev_uc,
 579                             priv->netdev->dev_addr);
 580
 581        netdev_for_each_uc_addr(ha, netdev)
 582                mlx5e_add_l2_to_hash(priv->fs.l2.netdev_uc, ha->addr);
 583
 584        netdev_for_each_mc_addr(ha, netdev)
 585                mlx5e_add_l2_to_hash(priv->fs.l2.netdev_mc, ha->addr);
 586
 587        netif_addr_unlock_bh(netdev);
 588}
 589
 590static void mlx5e_fill_addr_array(struct mlx5e_priv *priv, int list_type,
 591                                  u8 addr_array[][ETH_ALEN], int size)
 592{
 593        bool is_uc = (list_type == MLX5_NVPRT_LIST_TYPE_UC);
 594        struct net_device *ndev = priv->netdev;
 595        struct mlx5e_l2_hash_node *hn;
 596        struct hlist_head *addr_list;
 597        struct hlist_node *tmp;
 598        int i = 0;
 599        int hi;
 600
 601        addr_list = is_uc ? priv->fs.l2.netdev_uc : priv->fs.l2.netdev_mc;
 602
 603        if (is_uc) /* Make sure our own address is pushed first */
 604                ether_addr_copy(addr_array[i++], ndev->dev_addr);
 605        else if (priv->fs.l2.broadcast_enabled)
 606                ether_addr_copy(addr_array[i++], ndev->broadcast);
 607
 608        mlx5e_for_each_hash_node(hn, tmp, addr_list, hi) {
 609                if (ether_addr_equal(ndev->dev_addr, hn->ai.addr))
 610                        continue;
 611                if (i >= size)
 612                        break;
 613                ether_addr_copy(addr_array[i++], hn->ai.addr);
 614        }
 615}
 616
 617static void mlx5e_vport_context_update_addr_list(struct mlx5e_priv *priv,
 618                                                 int list_type)
 619{
 620        bool is_uc = (list_type == MLX5_NVPRT_LIST_TYPE_UC);
 621        struct mlx5e_l2_hash_node *hn;
 622        u8 (*addr_array)[ETH_ALEN] = NULL;
 623        struct hlist_head *addr_list;
 624        struct hlist_node *tmp;
 625        int max_size;
 626        int size;
 627        int err;
 628        int hi;
 629
 630        size = is_uc ? 0 : (priv->fs.l2.broadcast_enabled ? 1 : 0);
 631        max_size = is_uc ?
 632                1 << MLX5_CAP_GEN(priv->mdev, log_max_current_uc_list) :
 633                1 << MLX5_CAP_GEN(priv->mdev, log_max_current_mc_list);
 634
 635        addr_list = is_uc ? priv->fs.l2.netdev_uc : priv->fs.l2.netdev_mc;
 636        mlx5e_for_each_hash_node(hn, tmp, addr_list, hi)
 637                size++;
 638
 639        if (size > max_size) {
 640                netdev_warn(priv->netdev,
 641                            "netdev %s list size (%d) > (%d) max vport list size, some addresses will be dropped\n",
 642                            is_uc ? "UC" : "MC", size, max_size);
 643                size = max_size;
 644        }
 645
 646        if (size) {
 647                addr_array = kcalloc(size, ETH_ALEN, GFP_KERNEL);
 648                if (!addr_array) {
 649                        err = -ENOMEM;
 650                        goto out;
 651                }
 652                mlx5e_fill_addr_array(priv, list_type, addr_array, size);
 653        }
 654
 655        err = mlx5_modify_nic_vport_mac_list(priv->mdev, list_type, addr_array, size);
 656out:
 657        if (err)
 658                netdev_err(priv->netdev,
 659                           "Failed to modify vport %s list err(%d)\n",
 660                           is_uc ? "UC" : "MC", err);
 661        kfree(addr_array);
 662}
 663
 664static void mlx5e_vport_context_update(struct mlx5e_priv *priv)
 665{
 666        struct mlx5e_l2_table *ea = &priv->fs.l2;
 667
 668        mlx5e_vport_context_update_addr_list(priv, MLX5_NVPRT_LIST_TYPE_UC);
 669        mlx5e_vport_context_update_addr_list(priv, MLX5_NVPRT_LIST_TYPE_MC);
 670        mlx5_modify_nic_vport_promisc(priv->mdev, 0,
 671                                      ea->allmulti_enabled,
 672                                      ea->promisc_enabled);
 673}
 674
 675static void mlx5e_apply_netdev_addr(struct mlx5e_priv *priv)
 676{
 677        struct mlx5e_l2_hash_node *hn;
 678        struct hlist_node *tmp;
 679        int i;
 680
 681        mlx5e_for_each_hash_node(hn, tmp, priv->fs.l2.netdev_uc, i)
 682                mlx5e_execute_l2_action(priv, hn);
 683
 684        mlx5e_for_each_hash_node(hn, tmp, priv->fs.l2.netdev_mc, i)
 685                mlx5e_execute_l2_action(priv, hn);
 686}
 687
 688static void mlx5e_handle_netdev_addr(struct mlx5e_priv *priv)
 689{
 690        struct mlx5e_l2_hash_node *hn;
 691        struct hlist_node *tmp;
 692        int i;
 693
 694        mlx5e_for_each_hash_node(hn, tmp, priv->fs.l2.netdev_uc, i)
 695                hn->action = MLX5E_ACTION_DEL;
 696        mlx5e_for_each_hash_node(hn, tmp, priv->fs.l2.netdev_mc, i)
 697                hn->action = MLX5E_ACTION_DEL;
 698
 699        if (!test_bit(MLX5E_STATE_DESTROYING, &priv->state))
 700                mlx5e_sync_netdev_addr(priv);
 701
 702        mlx5e_apply_netdev_addr(priv);
 703}
 704
 705#define MLX5E_PROMISC_GROUP0_SIZE BIT(0)
 706#define MLX5E_PROMISC_TABLE_SIZE MLX5E_PROMISC_GROUP0_SIZE
 707
 708static int mlx5e_add_promisc_rule(struct mlx5e_priv *priv)
 709{
 710        struct mlx5_flow_table *ft = priv->fs.promisc.ft.t;
 711        struct mlx5_flow_destination dest = {};
 712        struct mlx5_flow_handle **rule_p;
 713        MLX5_DECLARE_FLOW_ACT(flow_act);
 714        struct mlx5_flow_spec *spec;
 715        int err = 0;
 716
 717        spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
 718        if (!spec)
 719                return -ENOMEM;
 720        dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
 721        dest.ft = priv->fs.ttc.ft.t;
 722
 723        rule_p = &priv->fs.promisc.rule;
 724        *rule_p = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1);
 725        if (IS_ERR(*rule_p)) {
 726                err = PTR_ERR(*rule_p);
 727                *rule_p = NULL;
 728                netdev_err(priv->netdev, "%s: add promiscuous rule failed\n", __func__);
 729        }
 730        kvfree(spec);
 731        return err;
 732}
 733
 734static int mlx5e_create_promisc_table(struct mlx5e_priv *priv)
 735{
 736        struct mlx5e_flow_table *ft = &priv->fs.promisc.ft;
 737        struct mlx5_flow_table_attr ft_attr = {};
 738        int err;
 739
 740        ft_attr.max_fte = MLX5E_PROMISC_TABLE_SIZE;
 741        ft_attr.autogroup.max_num_groups = 1;
 742        ft_attr.level = MLX5E_PROMISC_FT_LEVEL;
 743        ft_attr.prio = MLX5E_NIC_PRIO;
 744
 745        ft->t = mlx5_create_auto_grouped_flow_table(priv->fs.ns, &ft_attr);
 746        if (IS_ERR(ft->t)) {
 747                err = PTR_ERR(ft->t);
 748                netdev_err(priv->netdev, "fail to create promisc table err=%d\n", err);
 749                return err;
 750        }
 751
 752        err = mlx5e_add_promisc_rule(priv);
 753        if (err)
 754                goto err_destroy_promisc_table;
 755
 756        return 0;
 757
 758err_destroy_promisc_table:
 759        mlx5_destroy_flow_table(ft->t);
 760        ft->t = NULL;
 761
 762        return err;
 763}
 764
 765static void mlx5e_del_promisc_rule(struct mlx5e_priv *priv)
 766{
 767        if (WARN(!priv->fs.promisc.rule, "Trying to remove non-existing promiscuous rule"))
 768                return;
 769        mlx5_del_flow_rules(priv->fs.promisc.rule);
 770        priv->fs.promisc.rule = NULL;
 771}
 772
 773static void mlx5e_destroy_promisc_table(struct mlx5e_priv *priv)
 774{
 775        if (WARN(!priv->fs.promisc.ft.t, "Trying to remove non-existing promiscuous table"))
 776                return;
 777        mlx5e_del_promisc_rule(priv);
 778        mlx5_destroy_flow_table(priv->fs.promisc.ft.t);
 779        priv->fs.promisc.ft.t = NULL;
 780}
 781
 782void mlx5e_set_rx_mode_work(struct work_struct *work)
 783{
 784        struct mlx5e_priv *priv = container_of(work, struct mlx5e_priv,
 785                                               set_rx_mode_work);
 786
 787        struct mlx5e_l2_table *ea = &priv->fs.l2;
 788        struct net_device *ndev = priv->netdev;
 789
 790        bool rx_mode_enable   = !test_bit(MLX5E_STATE_DESTROYING, &priv->state);
 791        bool promisc_enabled   = rx_mode_enable && (ndev->flags & IFF_PROMISC);
 792        bool allmulti_enabled  = rx_mode_enable && (ndev->flags & IFF_ALLMULTI);
 793        bool broadcast_enabled = rx_mode_enable;
 794
 795        bool enable_promisc    = !ea->promisc_enabled   &&  promisc_enabled;
 796        bool disable_promisc   =  ea->promisc_enabled   && !promisc_enabled;
 797        bool enable_allmulti   = !ea->allmulti_enabled  &&  allmulti_enabled;
 798        bool disable_allmulti  =  ea->allmulti_enabled  && !allmulti_enabled;
 799        bool enable_broadcast  = !ea->broadcast_enabled &&  broadcast_enabled;
 800        bool disable_broadcast =  ea->broadcast_enabled && !broadcast_enabled;
 801        int err;
 802
 803        if (enable_promisc) {
 804                err = mlx5e_create_promisc_table(priv);
 805                if (err)
 806                        enable_promisc = false;
 807                if (!priv->channels.params.vlan_strip_disable && !err)
 808                        netdev_warn_once(ndev,
 809                                         "S-tagged traffic will be dropped while C-tag vlan stripping is enabled\n");
 810        }
 811        if (enable_allmulti)
 812                mlx5e_add_l2_flow_rule(priv, &ea->allmulti, MLX5E_ALLMULTI);
 813        if (enable_broadcast)
 814                mlx5e_add_l2_flow_rule(priv, &ea->broadcast, MLX5E_FULLMATCH);
 815
 816        mlx5e_handle_netdev_addr(priv);
 817
 818        if (disable_broadcast)
 819                mlx5e_del_l2_flow_rule(priv, &ea->broadcast);
 820        if (disable_allmulti)
 821                mlx5e_del_l2_flow_rule(priv, &ea->allmulti);
 822        if (disable_promisc)
 823                mlx5e_destroy_promisc_table(priv);
 824
 825        ea->promisc_enabled   = promisc_enabled;
 826        ea->allmulti_enabled  = allmulti_enabled;
 827        ea->broadcast_enabled = broadcast_enabled;
 828
 829        mlx5e_vport_context_update(priv);
 830}
 831
 832static void mlx5e_destroy_groups(struct mlx5e_flow_table *ft)
 833{
 834        int i;
 835
 836        for (i = ft->num_groups - 1; i >= 0; i--) {
 837                if (!IS_ERR_OR_NULL(ft->g[i]))
 838                        mlx5_destroy_flow_group(ft->g[i]);
 839                ft->g[i] = NULL;
 840        }
 841        ft->num_groups = 0;
 842}
 843
 844void mlx5e_init_l2_addr(struct mlx5e_priv *priv)
 845{
 846        ether_addr_copy(priv->fs.l2.broadcast.addr, priv->netdev->broadcast);
 847}
 848
 849void mlx5e_destroy_flow_table(struct mlx5e_flow_table *ft)
 850{
 851        mlx5e_destroy_groups(ft);
 852        kfree(ft->g);
 853        mlx5_destroy_flow_table(ft->t);
 854        ft->t = NULL;
 855}
 856
 857static void mlx5e_cleanup_ttc_rules(struct mlx5e_ttc_table *ttc)
 858{
 859        int i;
 860
 861        for (i = 0; i < MLX5E_NUM_TT; i++) {
 862                if (!IS_ERR_OR_NULL(ttc->rules[i].rule)) {
 863                        mlx5_del_flow_rules(ttc->rules[i].rule);
 864                        ttc->rules[i].rule = NULL;
 865                }
 866        }
 867
 868        for (i = 0; i < MLX5E_NUM_TUNNEL_TT; i++) {
 869                if (!IS_ERR_OR_NULL(ttc->tunnel_rules[i])) {
 870                        mlx5_del_flow_rules(ttc->tunnel_rules[i]);
 871                        ttc->tunnel_rules[i] = NULL;
 872                }
 873        }
 874}
 875
 876struct mlx5e_etype_proto {
 877        u16 etype;
 878        u8 proto;
 879};
 880
 881static struct mlx5e_etype_proto ttc_rules[] = {
 882        [MLX5E_TT_IPV4_TCP] = {
 883                .etype = ETH_P_IP,
 884                .proto = IPPROTO_TCP,
 885        },
 886        [MLX5E_TT_IPV6_TCP] = {
 887                .etype = ETH_P_IPV6,
 888                .proto = IPPROTO_TCP,
 889        },
 890        [MLX5E_TT_IPV4_UDP] = {
 891                .etype = ETH_P_IP,
 892                .proto = IPPROTO_UDP,
 893        },
 894        [MLX5E_TT_IPV6_UDP] = {
 895                .etype = ETH_P_IPV6,
 896                .proto = IPPROTO_UDP,
 897        },
 898        [MLX5E_TT_IPV4_IPSEC_AH] = {
 899                .etype = ETH_P_IP,
 900                .proto = IPPROTO_AH,
 901        },
 902        [MLX5E_TT_IPV6_IPSEC_AH] = {
 903                .etype = ETH_P_IPV6,
 904                .proto = IPPROTO_AH,
 905        },
 906        [MLX5E_TT_IPV4_IPSEC_ESP] = {
 907                .etype = ETH_P_IP,
 908                .proto = IPPROTO_ESP,
 909        },
 910        [MLX5E_TT_IPV6_IPSEC_ESP] = {
 911                .etype = ETH_P_IPV6,
 912                .proto = IPPROTO_ESP,
 913        },
 914        [MLX5E_TT_IPV4] = {
 915                .etype = ETH_P_IP,
 916                .proto = 0,
 917        },
 918        [MLX5E_TT_IPV6] = {
 919                .etype = ETH_P_IPV6,
 920                .proto = 0,
 921        },
 922        [MLX5E_TT_ANY] = {
 923                .etype = 0,
 924                .proto = 0,
 925        },
 926};
 927
 928static struct mlx5e_etype_proto ttc_tunnel_rules[] = {
 929        [MLX5E_TT_IPV4_GRE] = {
 930                .etype = ETH_P_IP,
 931                .proto = IPPROTO_GRE,
 932        },
 933        [MLX5E_TT_IPV6_GRE] = {
 934                .etype = ETH_P_IPV6,
 935                .proto = IPPROTO_GRE,
 936        },
 937        [MLX5E_TT_IPV4_IPIP] = {
 938                .etype = ETH_P_IP,
 939                .proto = IPPROTO_IPIP,
 940        },
 941        [MLX5E_TT_IPV6_IPIP] = {
 942                .etype = ETH_P_IPV6,
 943                .proto = IPPROTO_IPIP,
 944        },
 945        [MLX5E_TT_IPV4_IPV6] = {
 946                .etype = ETH_P_IP,
 947                .proto = IPPROTO_IPV6,
 948        },
 949        [MLX5E_TT_IPV6_IPV6] = {
 950                .etype = ETH_P_IPV6,
 951                .proto = IPPROTO_IPV6,
 952        },
 953
 954};
 955
 956u8 mlx5e_get_proto_by_tunnel_type(enum mlx5e_tunnel_types tt)
 957{
 958        return ttc_tunnel_rules[tt].proto;
 959}
 960
 961static bool mlx5e_tunnel_proto_supported_rx(struct mlx5_core_dev *mdev, u8 proto_type)
 962{
 963        switch (proto_type) {
 964        case IPPROTO_GRE:
 965                return MLX5_CAP_ETH(mdev, tunnel_stateless_gre);
 966        case IPPROTO_IPIP:
 967        case IPPROTO_IPV6:
 968                return (MLX5_CAP_ETH(mdev, tunnel_stateless_ip_over_ip) ||
 969                        MLX5_CAP_ETH(mdev, tunnel_stateless_ip_over_ip_rx));
 970        default:
 971                return false;
 972        }
 973}
 974
 975static bool mlx5e_tunnel_any_rx_proto_supported(struct mlx5_core_dev *mdev)
 976{
 977        int tt;
 978
 979        for (tt = 0; tt < MLX5E_NUM_TUNNEL_TT; tt++) {
 980                if (mlx5e_tunnel_proto_supported_rx(mdev, ttc_tunnel_rules[tt].proto))
 981                        return true;
 982        }
 983        return false;
 984}
 985
 986bool mlx5e_tunnel_inner_ft_supported(struct mlx5_core_dev *mdev)
 987{
 988        return (mlx5e_tunnel_any_rx_proto_supported(mdev) &&
 989                MLX5_CAP_FLOWTABLE_NIC_RX(mdev, ft_field_support.inner_ip_version));
 990}
 991
 992static u8 mlx5e_etype_to_ipv(u16 ethertype)
 993{
 994        if (ethertype == ETH_P_IP)
 995                return 4;
 996
 997        if (ethertype == ETH_P_IPV6)
 998                return 6;
 999
1000        return 0;
1001}
1002
1003static struct mlx5_flow_handle *
1004mlx5e_generate_ttc_rule(struct mlx5e_priv *priv,
1005                        struct mlx5_flow_table *ft,
1006                        struct mlx5_flow_destination *dest,
1007                        u16 etype,
1008                        u8 proto)
1009{
1010        int match_ipv_outer = MLX5_CAP_FLOWTABLE_NIC_RX(priv->mdev, ft_field_support.outer_ip_version);
1011        MLX5_DECLARE_FLOW_ACT(flow_act);
1012        struct mlx5_flow_handle *rule;
1013        struct mlx5_flow_spec *spec;
1014        int err = 0;
1015        u8 ipv;
1016
1017        spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
1018        if (!spec)
1019                return ERR_PTR(-ENOMEM);
1020
1021        if (proto) {
1022                spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
1023                MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ip_protocol);
1024                MLX5_SET(fte_match_param, spec->match_value, outer_headers.ip_protocol, proto);
1025        }
1026
1027        ipv = mlx5e_etype_to_ipv(etype);
1028        if (match_ipv_outer && ipv) {
1029                spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
1030                MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ip_version);
1031                MLX5_SET(fte_match_param, spec->match_value, outer_headers.ip_version, ipv);
1032        } else if (etype) {
1033                spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
1034                MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ethertype);
1035                MLX5_SET(fte_match_param, spec->match_value, outer_headers.ethertype, etype);
1036        }
1037
1038        rule = mlx5_add_flow_rules(ft, spec, &flow_act, dest, 1);
1039        if (IS_ERR(rule)) {
1040                err = PTR_ERR(rule);
1041                netdev_err(priv->netdev, "%s: add rule failed\n", __func__);
1042        }
1043
1044        kvfree(spec);
1045        return err ? ERR_PTR(err) : rule;
1046}
1047
1048static int mlx5e_generate_ttc_table_rules(struct mlx5e_priv *priv,
1049                                          struct ttc_params *params,
1050                                          struct mlx5e_ttc_table *ttc)
1051{
1052        struct mlx5_flow_destination dest = {};
1053        struct mlx5_flow_handle **trules;
1054        struct mlx5e_ttc_rule *rules;
1055        struct mlx5_flow_table *ft;
1056        int tt;
1057        int err;
1058
1059        ft = ttc->ft.t;
1060        rules = ttc->rules;
1061
1062        dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
1063        for (tt = 0; tt < MLX5E_NUM_TT; tt++) {
1064                struct mlx5e_ttc_rule *rule = &rules[tt];
1065
1066                if (tt == MLX5E_TT_ANY)
1067                        dest.tir_num = params->any_tt_tirn;
1068                else
1069                        dest.tir_num = params->indir_tirn[tt];
1070
1071                rule->rule = mlx5e_generate_ttc_rule(priv, ft, &dest,
1072                                                     ttc_rules[tt].etype,
1073                                                     ttc_rules[tt].proto);
1074                if (IS_ERR(rule->rule)) {
1075                        err = PTR_ERR(rule->rule);
1076                        rule->rule = NULL;
1077                        goto del_rules;
1078                }
1079                rule->default_dest = dest;
1080        }
1081
1082        if (!params->inner_ttc || !mlx5e_tunnel_inner_ft_supported(priv->mdev))
1083                return 0;
1084
1085        trules    = ttc->tunnel_rules;
1086        dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
1087        dest.ft   = params->inner_ttc->ft.t;
1088        for (tt = 0; tt < MLX5E_NUM_TUNNEL_TT; tt++) {
1089                if (!mlx5e_tunnel_proto_supported_rx(priv->mdev,
1090                                                     ttc_tunnel_rules[tt].proto))
1091                        continue;
1092                trules[tt] = mlx5e_generate_ttc_rule(priv, ft, &dest,
1093                                                     ttc_tunnel_rules[tt].etype,
1094                                                     ttc_tunnel_rules[tt].proto);
1095                if (IS_ERR(trules[tt])) {
1096                        err = PTR_ERR(trules[tt]);
1097                        trules[tt] = NULL;
1098                        goto del_rules;
1099                }
1100        }
1101
1102        return 0;
1103
1104del_rules:
1105        mlx5e_cleanup_ttc_rules(ttc);
1106        return err;
1107}
1108
1109static int mlx5e_create_ttc_table_groups(struct mlx5e_ttc_table *ttc,
1110                                         bool use_ipv)
1111{
1112        int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
1113        struct mlx5e_flow_table *ft = &ttc->ft;
1114        int ix = 0;
1115        u32 *in;
1116        int err;
1117        u8 *mc;
1118
1119        ft->g = kcalloc(MLX5E_TTC_NUM_GROUPS,
1120                        sizeof(*ft->g), GFP_KERNEL);
1121        if (!ft->g)
1122                return -ENOMEM;
1123        in = kvzalloc(inlen, GFP_KERNEL);
1124        if (!in) {
1125                kfree(ft->g);
1126                ft->g = NULL;
1127                return -ENOMEM;
1128        }
1129
1130        /* L4 Group */
1131        mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria);
1132        MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.ip_protocol);
1133        if (use_ipv)
1134                MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.ip_version);
1135        else
1136                MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.ethertype);
1137        MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS);
1138        MLX5_SET_CFG(in, start_flow_index, ix);
1139        ix += MLX5E_TTC_GROUP1_SIZE;
1140        MLX5_SET_CFG(in, end_flow_index, ix - 1);
1141        ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
1142        if (IS_ERR(ft->g[ft->num_groups]))
1143                goto err;
1144        ft->num_groups++;
1145
1146        /* L3 Group */
1147        MLX5_SET(fte_match_param, mc, outer_headers.ip_protocol, 0);
1148        MLX5_SET_CFG(in, start_flow_index, ix);
1149        ix += MLX5E_TTC_GROUP2_SIZE;
1150        MLX5_SET_CFG(in, end_flow_index, ix - 1);
1151        ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
1152        if (IS_ERR(ft->g[ft->num_groups]))
1153                goto err;
1154        ft->num_groups++;
1155
1156        /* Any Group */
1157        memset(in, 0, inlen);
1158        MLX5_SET_CFG(in, start_flow_index, ix);
1159        ix += MLX5E_TTC_GROUP3_SIZE;
1160        MLX5_SET_CFG(in, end_flow_index, ix - 1);
1161        ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
1162        if (IS_ERR(ft->g[ft->num_groups]))
1163                goto err;
1164        ft->num_groups++;
1165
1166        kvfree(in);
1167        return 0;
1168
1169err:
1170        err = PTR_ERR(ft->g[ft->num_groups]);
1171        ft->g[ft->num_groups] = NULL;
1172        kvfree(in);
1173
1174        return err;
1175}
1176
1177static struct mlx5_flow_handle *
1178mlx5e_generate_inner_ttc_rule(struct mlx5e_priv *priv,
1179                              struct mlx5_flow_table *ft,
1180                              struct mlx5_flow_destination *dest,
1181                              u16 etype, u8 proto)
1182{
1183        MLX5_DECLARE_FLOW_ACT(flow_act);
1184        struct mlx5_flow_handle *rule;
1185        struct mlx5_flow_spec *spec;
1186        int err = 0;
1187        u8 ipv;
1188
1189        spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
1190        if (!spec)
1191                return ERR_PTR(-ENOMEM);
1192
1193        ipv = mlx5e_etype_to_ipv(etype);
1194        if (etype && ipv) {
1195                spec->match_criteria_enable = MLX5_MATCH_INNER_HEADERS;
1196                MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, inner_headers.ip_version);
1197                MLX5_SET(fte_match_param, spec->match_value, inner_headers.ip_version, ipv);
1198        }
1199
1200        if (proto) {
1201                spec->match_criteria_enable = MLX5_MATCH_INNER_HEADERS;
1202                MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, inner_headers.ip_protocol);
1203                MLX5_SET(fte_match_param, spec->match_value, inner_headers.ip_protocol, proto);
1204        }
1205
1206        rule = mlx5_add_flow_rules(ft, spec, &flow_act, dest, 1);
1207        if (IS_ERR(rule)) {
1208                err = PTR_ERR(rule);
1209                netdev_err(priv->netdev, "%s: add rule failed\n", __func__);
1210        }
1211
1212        kvfree(spec);
1213        return err ? ERR_PTR(err) : rule;
1214}
1215
1216static int mlx5e_generate_inner_ttc_table_rules(struct mlx5e_priv *priv,
1217                                                struct ttc_params *params,
1218                                                struct mlx5e_ttc_table *ttc)
1219{
1220        struct mlx5_flow_destination dest = {};
1221        struct mlx5e_ttc_rule *rules;
1222        struct mlx5_flow_table *ft;
1223        int err;
1224        int tt;
1225
1226        ft = ttc->ft.t;
1227        rules = ttc->rules;
1228        dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
1229
1230        for (tt = 0; tt < MLX5E_NUM_TT; tt++) {
1231                struct mlx5e_ttc_rule *rule = &rules[tt];
1232
1233                if (tt == MLX5E_TT_ANY)
1234                        dest.tir_num = params->any_tt_tirn;
1235                else
1236                        dest.tir_num = params->indir_tirn[tt];
1237
1238                rule->rule = mlx5e_generate_inner_ttc_rule(priv, ft, &dest,
1239                                                           ttc_rules[tt].etype,
1240                                                           ttc_rules[tt].proto);
1241                if (IS_ERR(rule->rule)) {
1242                        err = PTR_ERR(rule->rule);
1243                        rule->rule = NULL;
1244                        goto del_rules;
1245                }
1246                rule->default_dest = dest;
1247        }
1248
1249        return 0;
1250
1251del_rules:
1252
1253        mlx5e_cleanup_ttc_rules(ttc);
1254        return err;
1255}
1256
1257static int mlx5e_create_inner_ttc_table_groups(struct mlx5e_ttc_table *ttc)
1258{
1259        int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
1260        struct mlx5e_flow_table *ft = &ttc->ft;
1261        int ix = 0;
1262        u32 *in;
1263        int err;
1264        u8 *mc;
1265
1266        ft->g = kcalloc(MLX5E_INNER_TTC_NUM_GROUPS, sizeof(*ft->g), GFP_KERNEL);
1267        if (!ft->g)
1268                return -ENOMEM;
1269        in = kvzalloc(inlen, GFP_KERNEL);
1270        if (!in) {
1271                kfree(ft->g);
1272                ft->g = NULL;
1273                return -ENOMEM;
1274        }
1275
1276        /* L4 Group */
1277        mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria);
1278        MLX5_SET_TO_ONES(fte_match_param, mc, inner_headers.ip_protocol);
1279        MLX5_SET_TO_ONES(fte_match_param, mc, inner_headers.ip_version);
1280        MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_INNER_HEADERS);
1281        MLX5_SET_CFG(in, start_flow_index, ix);
1282        ix += MLX5E_INNER_TTC_GROUP1_SIZE;
1283        MLX5_SET_CFG(in, end_flow_index, ix - 1);
1284        ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
1285        if (IS_ERR(ft->g[ft->num_groups]))
1286                goto err;
1287        ft->num_groups++;
1288
1289        /* L3 Group */
1290        MLX5_SET(fte_match_param, mc, inner_headers.ip_protocol, 0);
1291        MLX5_SET_CFG(in, start_flow_index, ix);
1292        ix += MLX5E_INNER_TTC_GROUP2_SIZE;
1293        MLX5_SET_CFG(in, end_flow_index, ix - 1);
1294        ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
1295        if (IS_ERR(ft->g[ft->num_groups]))
1296                goto err;
1297        ft->num_groups++;
1298
1299        /* Any Group */
1300        memset(in, 0, inlen);
1301        MLX5_SET_CFG(in, start_flow_index, ix);
1302        ix += MLX5E_INNER_TTC_GROUP3_SIZE;
1303        MLX5_SET_CFG(in, end_flow_index, ix - 1);
1304        ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
1305        if (IS_ERR(ft->g[ft->num_groups]))
1306                goto err;
1307        ft->num_groups++;
1308
1309        kvfree(in);
1310        return 0;
1311
1312err:
1313        err = PTR_ERR(ft->g[ft->num_groups]);
1314        ft->g[ft->num_groups] = NULL;
1315        kvfree(in);
1316
1317        return err;
1318}
1319
1320void mlx5e_set_ttc_basic_params(struct mlx5e_priv *priv,
1321                                struct ttc_params *ttc_params)
1322{
1323        ttc_params->any_tt_tirn = priv->direct_tir[0].tirn;
1324        ttc_params->inner_ttc = &priv->fs.inner_ttc;
1325}
1326
1327void mlx5e_set_inner_ttc_ft_params(struct ttc_params *ttc_params)
1328{
1329        struct mlx5_flow_table_attr *ft_attr = &ttc_params->ft_attr;
1330
1331        ft_attr->max_fte = MLX5E_INNER_TTC_TABLE_SIZE;
1332        ft_attr->level = MLX5E_INNER_TTC_FT_LEVEL;
1333        ft_attr->prio = MLX5E_NIC_PRIO;
1334}
1335
1336void mlx5e_set_ttc_ft_params(struct ttc_params *ttc_params)
1337
1338{
1339        struct mlx5_flow_table_attr *ft_attr = &ttc_params->ft_attr;
1340
1341        ft_attr->max_fte = MLX5E_TTC_TABLE_SIZE;
1342        ft_attr->level = MLX5E_TTC_FT_LEVEL;
1343        ft_attr->prio = MLX5E_NIC_PRIO;
1344}
1345
1346int mlx5e_create_inner_ttc_table(struct mlx5e_priv *priv, struct ttc_params *params,
1347                                 struct mlx5e_ttc_table *ttc)
1348{
1349        struct mlx5e_flow_table *ft = &ttc->ft;
1350        int err;
1351
1352        if (!mlx5e_tunnel_inner_ft_supported(priv->mdev))
1353                return 0;
1354
1355        ft->t = mlx5_create_flow_table(priv->fs.ns, &params->ft_attr);
1356        if (IS_ERR(ft->t)) {
1357                err = PTR_ERR(ft->t);
1358                ft->t = NULL;
1359                return err;
1360        }
1361
1362        err = mlx5e_create_inner_ttc_table_groups(ttc);
1363        if (err)
1364                goto err;
1365
1366        err = mlx5e_generate_inner_ttc_table_rules(priv, params, ttc);
1367        if (err)
1368                goto err;
1369
1370        return 0;
1371
1372err:
1373        mlx5e_destroy_flow_table(ft);
1374        return err;
1375}
1376
1377void mlx5e_destroy_inner_ttc_table(struct mlx5e_priv *priv,
1378                                   struct mlx5e_ttc_table *ttc)
1379{
1380        if (!mlx5e_tunnel_inner_ft_supported(priv->mdev))
1381                return;
1382
1383        mlx5e_cleanup_ttc_rules(ttc);
1384        mlx5e_destroy_flow_table(&ttc->ft);
1385}
1386
1387void mlx5e_destroy_ttc_table(struct mlx5e_priv *priv,
1388                             struct mlx5e_ttc_table *ttc)
1389{
1390        mlx5e_cleanup_ttc_rules(ttc);
1391        mlx5e_destroy_flow_table(&ttc->ft);
1392}
1393
1394int mlx5e_create_ttc_table(struct mlx5e_priv *priv, struct ttc_params *params,
1395                           struct mlx5e_ttc_table *ttc)
1396{
1397        bool match_ipv_outer = MLX5_CAP_FLOWTABLE_NIC_RX(priv->mdev, ft_field_support.outer_ip_version);
1398        struct mlx5e_flow_table *ft = &ttc->ft;
1399        int err;
1400
1401        ft->t = mlx5_create_flow_table(priv->fs.ns, &params->ft_attr);
1402        if (IS_ERR(ft->t)) {
1403                err = PTR_ERR(ft->t);
1404                ft->t = NULL;
1405                return err;
1406        }
1407
1408        err = mlx5e_create_ttc_table_groups(ttc, match_ipv_outer);
1409        if (err)
1410                goto err;
1411
1412        err = mlx5e_generate_ttc_table_rules(priv, params, ttc);
1413        if (err)
1414                goto err;
1415
1416        return 0;
1417err:
1418        mlx5e_destroy_flow_table(ft);
1419        return err;
1420}
1421
1422int mlx5e_ttc_fwd_dest(struct mlx5e_priv *priv, enum mlx5e_traffic_types type,
1423                       struct mlx5_flow_destination *new_dest)
1424{
1425        return mlx5_modify_rule_destination(priv->fs.ttc.rules[type].rule, new_dest, NULL);
1426}
1427
1428struct mlx5_flow_destination
1429mlx5e_ttc_get_default_dest(struct mlx5e_priv *priv, enum mlx5e_traffic_types type)
1430{
1431        struct mlx5_flow_destination *dest = &priv->fs.ttc.rules[type].default_dest;
1432
1433        WARN_ONCE(dest->type != MLX5_FLOW_DESTINATION_TYPE_TIR,
1434                  "TTC[%d] default dest is not setup yet", type);
1435
1436        return *dest;
1437}
1438
1439int mlx5e_ttc_fwd_default_dest(struct mlx5e_priv *priv, enum mlx5e_traffic_types type)
1440{
1441        struct mlx5_flow_destination dest = mlx5e_ttc_get_default_dest(priv, type);
1442
1443        return mlx5e_ttc_fwd_dest(priv, type, &dest);
1444}
1445
1446static void mlx5e_del_l2_flow_rule(struct mlx5e_priv *priv,
1447                                   struct mlx5e_l2_rule *ai)
1448{
1449        if (!IS_ERR_OR_NULL(ai->rule)) {
1450                mlx5_del_flow_rules(ai->rule);
1451                ai->rule = NULL;
1452        }
1453}
1454
1455static int mlx5e_add_l2_flow_rule(struct mlx5e_priv *priv,
1456                                  struct mlx5e_l2_rule *ai, int type)
1457{
1458        struct mlx5_flow_table *ft = priv->fs.l2.ft.t;
1459        struct mlx5_flow_destination dest = {};
1460        MLX5_DECLARE_FLOW_ACT(flow_act);
1461        struct mlx5_flow_spec *spec;
1462        int err = 0;
1463        u8 *mc_dmac;
1464        u8 *mv_dmac;
1465
1466        spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
1467        if (!spec)
1468                return -ENOMEM;
1469
1470        mc_dmac = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
1471                               outer_headers.dmac_47_16);
1472        mv_dmac = MLX5_ADDR_OF(fte_match_param, spec->match_value,
1473                               outer_headers.dmac_47_16);
1474
1475        dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
1476        dest.ft = priv->fs.ttc.ft.t;
1477
1478        switch (type) {
1479        case MLX5E_FULLMATCH:
1480                spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
1481                eth_broadcast_addr(mc_dmac);
1482                ether_addr_copy(mv_dmac, ai->addr);
1483                break;
1484
1485        case MLX5E_ALLMULTI:
1486                spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
1487                mc_dmac[0] = 0x01;
1488                mv_dmac[0] = 0x01;
1489                break;
1490        }
1491
1492        ai->rule = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1);
1493        if (IS_ERR(ai->rule)) {
1494                netdev_err(priv->netdev, "%s: add l2 rule(mac:%pM) failed\n",
1495                           __func__, mv_dmac);
1496                err = PTR_ERR(ai->rule);
1497                ai->rule = NULL;
1498        }
1499
1500        kvfree(spec);
1501
1502        return err;
1503}
1504
1505#define MLX5E_NUM_L2_GROUPS        3
1506#define MLX5E_L2_GROUP1_SIZE       BIT(15)
1507#define MLX5E_L2_GROUP2_SIZE       BIT(0)
1508#define MLX5E_L2_GROUP_TRAP_SIZE   BIT(0) /* must be last */
1509#define MLX5E_L2_TABLE_SIZE        (MLX5E_L2_GROUP1_SIZE +\
1510                                    MLX5E_L2_GROUP2_SIZE +\
1511                                    MLX5E_L2_GROUP_TRAP_SIZE)
1512static int mlx5e_create_l2_table_groups(struct mlx5e_l2_table *l2_table)
1513{
1514        int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
1515        struct mlx5e_flow_table *ft = &l2_table->ft;
1516        int ix = 0;
1517        u8 *mc_dmac;
1518        u32 *in;
1519        int err;
1520        u8 *mc;
1521
1522        ft->g = kcalloc(MLX5E_NUM_L2_GROUPS, sizeof(*ft->g), GFP_KERNEL);
1523        if (!ft->g)
1524                return -ENOMEM;
1525        in = kvzalloc(inlen, GFP_KERNEL);
1526        if (!in) {
1527                kfree(ft->g);
1528                return -ENOMEM;
1529        }
1530
1531        mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria);
1532        mc_dmac = MLX5_ADDR_OF(fte_match_param, mc,
1533                               outer_headers.dmac_47_16);
1534        /* Flow Group for full match */
1535        eth_broadcast_addr(mc_dmac);
1536        MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS);
1537        MLX5_SET_CFG(in, start_flow_index, ix);
1538        ix += MLX5E_L2_GROUP1_SIZE;
1539        MLX5_SET_CFG(in, end_flow_index, ix - 1);
1540        ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
1541        if (IS_ERR(ft->g[ft->num_groups]))
1542                goto err_destroy_groups;
1543        ft->num_groups++;
1544
1545        /* Flow Group for allmulti */
1546        eth_zero_addr(mc_dmac);
1547        mc_dmac[0] = 0x01;
1548        MLX5_SET_CFG(in, start_flow_index, ix);
1549        ix += MLX5E_L2_GROUP2_SIZE;
1550        MLX5_SET_CFG(in, end_flow_index, ix - 1);
1551        ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
1552        if (IS_ERR(ft->g[ft->num_groups]))
1553                goto err_destroy_groups;
1554        ft->num_groups++;
1555
1556        /* Flow Group for l2 traps */
1557        memset(in, 0, inlen);
1558        MLX5_SET_CFG(in, start_flow_index, ix);
1559        ix += MLX5E_L2_GROUP_TRAP_SIZE;
1560        MLX5_SET_CFG(in, end_flow_index, ix - 1);
1561        ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
1562        if (IS_ERR(ft->g[ft->num_groups]))
1563                goto err_destroy_groups;
1564        ft->num_groups++;
1565
1566        kvfree(in);
1567        return 0;
1568
1569err_destroy_groups:
1570        err = PTR_ERR(ft->g[ft->num_groups]);
1571        ft->g[ft->num_groups] = NULL;
1572        mlx5e_destroy_groups(ft);
1573        kvfree(in);
1574        kfree(ft->g);
1575
1576        return err;
1577}
1578
1579static void mlx5e_destroy_l2_table(struct mlx5e_priv *priv)
1580{
1581        mlx5e_destroy_flow_table(&priv->fs.l2.ft);
1582}
1583
1584static int mlx5e_create_l2_table(struct mlx5e_priv *priv)
1585{
1586        struct mlx5e_l2_table *l2_table = &priv->fs.l2;
1587        struct mlx5e_flow_table *ft = &l2_table->ft;
1588        struct mlx5_flow_table_attr ft_attr = {};
1589        int err;
1590
1591        ft->num_groups = 0;
1592
1593        ft_attr.max_fte = MLX5E_L2_TABLE_SIZE;
1594        ft_attr.level = MLX5E_L2_FT_LEVEL;
1595        ft_attr.prio = MLX5E_NIC_PRIO;
1596
1597        ft->t = mlx5_create_flow_table(priv->fs.ns, &ft_attr);
1598        if (IS_ERR(ft->t)) {
1599                err = PTR_ERR(ft->t);
1600                ft->t = NULL;
1601                return err;
1602        }
1603
1604        err = mlx5e_create_l2_table_groups(l2_table);
1605        if (err)
1606                goto err_destroy_flow_table;
1607
1608        return 0;
1609
1610err_destroy_flow_table:
1611        mlx5_destroy_flow_table(ft->t);
1612        ft->t = NULL;
1613
1614        return err;
1615}
1616
1617#define MLX5E_NUM_VLAN_GROUPS   5
1618#define MLX5E_VLAN_GROUP0_SIZE  BIT(12)
1619#define MLX5E_VLAN_GROUP1_SIZE  BIT(12)
1620#define MLX5E_VLAN_GROUP2_SIZE  BIT(1)
1621#define MLX5E_VLAN_GROUP3_SIZE  BIT(0)
1622#define MLX5E_VLAN_GROUP_TRAP_SIZE BIT(0) /* must be last */
1623#define MLX5E_VLAN_TABLE_SIZE   (MLX5E_VLAN_GROUP0_SIZE +\
1624                                 MLX5E_VLAN_GROUP1_SIZE +\
1625                                 MLX5E_VLAN_GROUP2_SIZE +\
1626                                 MLX5E_VLAN_GROUP3_SIZE +\
1627                                 MLX5E_VLAN_GROUP_TRAP_SIZE)
1628
1629static int __mlx5e_create_vlan_table_groups(struct mlx5e_flow_table *ft, u32 *in,
1630                                            int inlen)
1631{
1632        int err;
1633        int ix = 0;
1634        u8 *mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria);
1635
1636        memset(in, 0, inlen);
1637        MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS);
1638        MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.cvlan_tag);
1639        MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.first_vid);
1640        MLX5_SET_CFG(in, start_flow_index, ix);
1641        ix += MLX5E_VLAN_GROUP0_SIZE;
1642        MLX5_SET_CFG(in, end_flow_index, ix - 1);
1643        ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
1644        if (IS_ERR(ft->g[ft->num_groups]))
1645                goto err_destroy_groups;
1646        ft->num_groups++;
1647
1648        memset(in, 0, inlen);
1649        MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS);
1650        MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.svlan_tag);
1651        MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.first_vid);
1652        MLX5_SET_CFG(in, start_flow_index, ix);
1653        ix += MLX5E_VLAN_GROUP1_SIZE;
1654        MLX5_SET_CFG(in, end_flow_index, ix - 1);
1655        ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
1656        if (IS_ERR(ft->g[ft->num_groups]))
1657                goto err_destroy_groups;
1658        ft->num_groups++;
1659
1660        memset(in, 0, inlen);
1661        MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS);
1662        MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.cvlan_tag);
1663        MLX5_SET_CFG(in, start_flow_index, ix);
1664        ix += MLX5E_VLAN_GROUP2_SIZE;
1665        MLX5_SET_CFG(in, end_flow_index, ix - 1);
1666        ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
1667        if (IS_ERR(ft->g[ft->num_groups]))
1668                goto err_destroy_groups;
1669        ft->num_groups++;
1670
1671        memset(in, 0, inlen);
1672        MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS);
1673        MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.svlan_tag);
1674        MLX5_SET_CFG(in, start_flow_index, ix);
1675        ix += MLX5E_VLAN_GROUP3_SIZE;
1676        MLX5_SET_CFG(in, end_flow_index, ix - 1);
1677        ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
1678        if (IS_ERR(ft->g[ft->num_groups]))
1679                goto err_destroy_groups;
1680        ft->num_groups++;
1681
1682        memset(in, 0, inlen);
1683        MLX5_SET_CFG(in, start_flow_index, ix);
1684        ix += MLX5E_VLAN_GROUP_TRAP_SIZE;
1685        MLX5_SET_CFG(in, end_flow_index, ix - 1);
1686        ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in);
1687        if (IS_ERR(ft->g[ft->num_groups]))
1688                goto err_destroy_groups;
1689        ft->num_groups++;
1690
1691        return 0;
1692
1693err_destroy_groups:
1694        err = PTR_ERR(ft->g[ft->num_groups]);
1695        ft->g[ft->num_groups] = NULL;
1696        mlx5e_destroy_groups(ft);
1697
1698        return err;
1699}
1700
1701static int mlx5e_create_vlan_table_groups(struct mlx5e_flow_table *ft)
1702{
1703        u32 *in;
1704        int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
1705        int err;
1706
1707        in = kvzalloc(inlen, GFP_KERNEL);
1708        if (!in)
1709                return -ENOMEM;
1710
1711        err = __mlx5e_create_vlan_table_groups(ft, in, inlen);
1712
1713        kvfree(in);
1714        return err;
1715}
1716
1717static int mlx5e_create_vlan_table(struct mlx5e_priv *priv)
1718{
1719        struct mlx5_flow_table_attr ft_attr = {};
1720        struct mlx5e_flow_table *ft;
1721        int err;
1722
1723        priv->fs.vlan = kvzalloc(sizeof(*priv->fs.vlan), GFP_KERNEL);
1724        if (!priv->fs.vlan)
1725                return -ENOMEM;
1726
1727        ft = &priv->fs.vlan->ft;
1728        ft->num_groups = 0;
1729
1730        ft_attr.max_fte = MLX5E_VLAN_TABLE_SIZE;
1731        ft_attr.level = MLX5E_VLAN_FT_LEVEL;
1732        ft_attr.prio = MLX5E_NIC_PRIO;
1733
1734        ft->t = mlx5_create_flow_table(priv->fs.ns, &ft_attr);
1735        if (IS_ERR(ft->t)) {
1736                err = PTR_ERR(ft->t);
1737                goto err_free_t;
1738        }
1739
1740        ft->g = kcalloc(MLX5E_NUM_VLAN_GROUPS, sizeof(*ft->g), GFP_KERNEL);
1741        if (!ft->g) {
1742                err = -ENOMEM;
1743                goto err_destroy_vlan_table;
1744        }
1745
1746        err = mlx5e_create_vlan_table_groups(ft);
1747        if (err)
1748                goto err_free_g;
1749
1750        mlx5e_add_vlan_rules(priv);
1751
1752        return 0;
1753
1754err_free_g:
1755        kfree(ft->g);
1756err_destroy_vlan_table:
1757        mlx5_destroy_flow_table(ft->t);
1758err_free_t:
1759        kvfree(priv->fs.vlan);
1760        priv->fs.vlan = NULL;
1761
1762        return err;
1763}
1764
1765static void mlx5e_destroy_vlan_table(struct mlx5e_priv *priv)
1766{
1767        mlx5e_del_vlan_rules(priv);
1768        mlx5e_destroy_flow_table(&priv->fs.vlan->ft);
1769        kvfree(priv->fs.vlan);
1770}
1771
1772int mlx5e_create_flow_steering(struct mlx5e_priv *priv)
1773{
1774        struct ttc_params ttc_params = {};
1775        int tt, err;
1776
1777        priv->fs.ns = mlx5_get_flow_namespace(priv->mdev,
1778                                               MLX5_FLOW_NAMESPACE_KERNEL);
1779
1780        if (!priv->fs.ns)
1781                return -EOPNOTSUPP;
1782
1783        err = mlx5e_arfs_create_tables(priv);
1784        if (err) {
1785                netdev_err(priv->netdev, "Failed to create arfs tables, err=%d\n",
1786                           err);
1787                priv->netdev->hw_features &= ~NETIF_F_NTUPLE;
1788        }
1789
1790        mlx5e_set_ttc_basic_params(priv, &ttc_params);
1791        mlx5e_set_inner_ttc_ft_params(&ttc_params);
1792        for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++)
1793                ttc_params.indir_tirn[tt] = priv->inner_indir_tir[tt].tirn;
1794
1795        err = mlx5e_create_inner_ttc_table(priv, &ttc_params, &priv->fs.inner_ttc);
1796        if (err) {
1797                netdev_err(priv->netdev, "Failed to create inner ttc table, err=%d\n",
1798                           err);
1799                goto err_destroy_arfs_tables;
1800        }
1801
1802        mlx5e_set_ttc_ft_params(&ttc_params);
1803        for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++)
1804                ttc_params.indir_tirn[tt] = priv->indir_tir[tt].tirn;
1805
1806        err = mlx5e_create_ttc_table(priv, &ttc_params, &priv->fs.ttc);
1807        if (err) {
1808                netdev_err(priv->netdev, "Failed to create ttc table, err=%d\n",
1809                           err);
1810                goto err_destroy_inner_ttc_table;
1811        }
1812
1813        err = mlx5e_create_l2_table(priv);
1814        if (err) {
1815                netdev_err(priv->netdev, "Failed to create l2 table, err=%d\n",
1816                           err);
1817                goto err_destroy_ttc_table;
1818        }
1819
1820        err = mlx5e_create_vlan_table(priv);
1821        if (err) {
1822                netdev_err(priv->netdev, "Failed to create vlan table, err=%d\n",
1823                           err);
1824                goto err_destroy_l2_table;
1825        }
1826
1827        err = mlx5e_ptp_alloc_rx_fs(priv);
1828        if (err)
1829                goto err_destory_vlan_table;
1830
1831        mlx5e_ethtool_init_steering(priv);
1832
1833        return 0;
1834
1835err_destory_vlan_table:
1836        mlx5e_destroy_vlan_table(priv);
1837err_destroy_l2_table:
1838        mlx5e_destroy_l2_table(priv);
1839err_destroy_ttc_table:
1840        mlx5e_destroy_ttc_table(priv, &priv->fs.ttc);
1841err_destroy_inner_ttc_table:
1842        mlx5e_destroy_inner_ttc_table(priv, &priv->fs.inner_ttc);
1843err_destroy_arfs_tables:
1844        mlx5e_arfs_destroy_tables(priv);
1845
1846        return err;
1847}
1848
1849void mlx5e_destroy_flow_steering(struct mlx5e_priv *priv)
1850{
1851        mlx5e_ptp_free_rx_fs(priv);
1852        mlx5e_destroy_vlan_table(priv);
1853        mlx5e_destroy_l2_table(priv);
1854        mlx5e_destroy_ttc_table(priv, &priv->fs.ttc);
1855        mlx5e_destroy_inner_ttc_table(priv, &priv->fs.inner_ttc);
1856        mlx5e_arfs_destroy_tables(priv);
1857        mlx5e_ethtool_cleanup_steering(priv);
1858}
1859