Merge branch 'mlx5-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mellanox...
authorSaeed Mahameed <saeedm@mellanox.com>
Wed, 17 Oct 2018 21:13:36 +0000 (14:13 -0700)
committerSaeed Mahameed <saeedm@mellanox.com>
Wed, 17 Oct 2018 21:13:36 +0000 (14:13 -0700)
mlx5 updates for both net-next and rdma-next

* 'mlx5-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux: (21 commits)
  net/mlx5: Expose DC scatter to CQE capability bit
  net/mlx5: Update mlx5_ifc with DEVX UID bits
  net/mlx5: Set uid as part of DCT commands
  net/mlx5: Set uid as part of SRQ commands
  net/mlx5: Set uid as part of SQ commands
  net/mlx5: Set uid as part of RQ commands
  net/mlx5: Set uid as part of QP commands
  net/mlx5: Set uid as part of CQ commands
  net/mlx5: Rename incorrect naming in IFC file
  net/mlx5: Export packet reformat alloc/dealloc functions
  net/mlx5: Pass a namespace for packet reformat ID allocation
  net/mlx5: Expose new packet reformat capabilities
  {net, RDMA}/mlx5: Rename encap to reformat packet
  net/mlx5: Move header encap type to IFC header file
  net/mlx5: Break encap/decap into two separated flow table creation flags
  net/mlx5: Add support for more namespaces when allocating modify header
  net/mlx5: Export modify header alloc/dealloc functions
  net/mlx5: Add proper NIC TX steering flow tables support
  net/mlx5: Cleanup flow namespace getter switch logic
  net/mlx5: Add memic command opcode to command checker
  ...

Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
1  2 
drivers/infiniband/hw/mlx5/devx.c
drivers/net/ethernet/mellanox/mlx5/core/cmd.c
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
drivers/net/ethernet/mellanox/mlx5/core/srq.c
include/linux/mlx5/device.h
include/linux/mlx5/driver.h
include/linux/mlx5/mlx5_ifc.h

index f2f11e652dcd2a751d10397c8c65d6be8a53b53e,25dafa4ff6ca0b28a72977dbb77d744ed2ab98fb..66dc337e49a740fbfac9ee1f6b23aeb6f47cba13
@@@ -284,7 -284,7 +284,7 @@@ static bool devx_is_obj_create_cmd(cons
        case MLX5_CMD_OP_CREATE_FLOW_TABLE:
        case MLX5_CMD_OP_CREATE_FLOW_GROUP:
        case MLX5_CMD_OP_ALLOC_FLOW_COUNTER:
-       case MLX5_CMD_OP_ALLOC_ENCAP_HEADER:
+       case MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT:
        case MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT:
        case MLX5_CMD_OP_CREATE_SCHEDULING_ELEMENT:
        case MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT:
@@@ -627,9 -627,9 +627,9 @@@ static void devx_obj_build_destroy_cmd(
                MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
                         MLX5_CMD_OP_DEALLOC_FLOW_COUNTER);
                break;
-       case MLX5_CMD_OP_ALLOC_ENCAP_HEADER:
+       case MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT:
                MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
-                        MLX5_CMD_OP_DEALLOC_ENCAP_HEADER);
+                        MLX5_CMD_OP_DEALLOC_PACKET_REFORMAT_CONTEXT);
                break;
        case MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT:
                MLX5_SET(general_obj_in_cmd_hdr, din, opcode,
@@@ -723,7 -723,6 +723,7 @@@ static int UVERBS_HANDLER(MLX5_IB_METHO
                attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_HANDLE);
        struct mlx5_ib_ucontext *c = to_mucontext(uobj->context);
        struct mlx5_ib_dev *dev = to_mdev(c->ibucontext.device);
 +      u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
        struct devx_obj *obj;
        int err;
  
  
        err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT, cmd_out, cmd_out_len);
        if (err)
 -              goto obj_free;
 +              goto obj_destroy;
  
        return 0;
  
 +obj_destroy:
 +      mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out, sizeof(out));
  obj_free:
        kfree(obj);
        return err;
index a53736c26c0cec416b119878356e2beffe17b37e,39750fca371d6bd46e0b7ca84b81c88c4c768ce1..a5a0823e5ada8fa2484c5c88ab766d349731c3c3
@@@ -206,7 -206,7 +206,7 @@@ static void poll_timeout(struct mlx5_cm
        u8 own;
  
        do {
 -              own = ent->lay->status_own;
 +              own = READ_ONCE(ent->lay->status_own);
                if (!(own & CMD_OWNER_HW)) {
                        ent->ret = 0;
                        return;
@@@ -308,10 -308,11 +308,11 @@@ static int mlx5_internal_err_ret_value(
        case MLX5_CMD_OP_MODIFY_FLOW_TABLE:
        case MLX5_CMD_OP_SET_FLOW_TABLE_ENTRY:
        case MLX5_CMD_OP_SET_FLOW_TABLE_ROOT:
-       case MLX5_CMD_OP_DEALLOC_ENCAP_HEADER:
+       case MLX5_CMD_OP_DEALLOC_PACKET_REFORMAT_CONTEXT:
        case MLX5_CMD_OP_DEALLOC_MODIFY_HEADER_CONTEXT:
        case MLX5_CMD_OP_FPGA_DESTROY_QP:
        case MLX5_CMD_OP_DESTROY_GENERAL_OBJECT:
+       case MLX5_CMD_OP_DEALLOC_MEMIC:
                return MLX5_CMD_STAT_OK;
  
        case MLX5_CMD_OP_QUERY_HCA_CAP:
        case MLX5_CMD_OP_QUERY_FLOW_TABLE_ENTRY:
        case MLX5_CMD_OP_ALLOC_FLOW_COUNTER:
        case MLX5_CMD_OP_QUERY_FLOW_COUNTER:
-       case MLX5_CMD_OP_ALLOC_ENCAP_HEADER:
+       case MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT:
        case MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT:
        case MLX5_CMD_OP_FPGA_CREATE_QP:
        case MLX5_CMD_OP_FPGA_MODIFY_QP:
        case MLX5_CMD_OP_CREATE_GENERAL_OBJECT:
        case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT:
        case MLX5_CMD_OP_QUERY_GENERAL_OBJECT:
+       case MLX5_CMD_OP_ALLOC_MEMIC:
                *status = MLX5_DRIVER_STATUS_ABORTED;
                *synd = MLX5_DRIVER_SYND;
                return -EIO;
@@@ -599,8 -601,8 +601,8 @@@ const char *mlx5_command_str(int comman
        MLX5_COMMAND_STR_CASE(DEALLOC_FLOW_COUNTER);
        MLX5_COMMAND_STR_CASE(QUERY_FLOW_COUNTER);
        MLX5_COMMAND_STR_CASE(MODIFY_FLOW_TABLE);
-       MLX5_COMMAND_STR_CASE(ALLOC_ENCAP_HEADER);
-       MLX5_COMMAND_STR_CASE(DEALLOC_ENCAP_HEADER);
+       MLX5_COMMAND_STR_CASE(ALLOC_PACKET_REFORMAT_CONTEXT);
+       MLX5_COMMAND_STR_CASE(DEALLOC_PACKET_REFORMAT_CONTEXT);
        MLX5_COMMAND_STR_CASE(ALLOC_MODIFY_HEADER_CONTEXT);
        MLX5_COMMAND_STR_CASE(DEALLOC_MODIFY_HEADER_CONTEXT);
        MLX5_COMMAND_STR_CASE(FPGA_CREATE_QP);
        MLX5_COMMAND_STR_CASE(MODIFY_GENERAL_OBJECT);
        MLX5_COMMAND_STR_CASE(QUERY_GENERAL_OBJECT);
        MLX5_COMMAND_STR_CASE(QUERY_MODIFY_HEADER_CONTEXT);
+       MLX5_COMMAND_STR_CASE(ALLOC_MEMIC);
+       MLX5_COMMAND_STR_CASE(DEALLOC_MEMIC);
        default: return "unknown command opcode";
        }
  }
index 6de21d9f4fad7dbb5c90ddc15aefb92ad31f1933,8cac8e9c8c6346403fbf0cfc726f7f8153a9292a..acf7a847f56167a9d872f8d3c6f4ed024571c5e9
@@@ -100,11 -100,6 +100,6 @@@ struct mlx5e_tc_flow_parse_attr 
        int mirred_ifindex;
  };
  
- enum {
-       MLX5_HEADER_TYPE_VXLAN = 0x0,
-       MLX5_HEADER_TYPE_NVGRE = 0x1,
- };
  #define MLX5E_TC_TABLE_NUM_GROUPS 4
  #define MLX5E_TC_TABLE_MAX_GROUP_SIZE BIT(16)
  
@@@ -532,8 -527,7 +527,8 @@@ static struct mlx5e_hairpin_entry *mlx5
  #define UNKNOWN_MATCH_PRIO 8
  
  static int mlx5e_hairpin_get_prio(struct mlx5e_priv *priv,
 -                                struct mlx5_flow_spec *spec, u8 *match_prio)
 +                                struct mlx5_flow_spec *spec, u8 *match_prio,
 +                                struct netlink_ext_ack *extack)
  {
        void *headers_c, *headers_v;
        u8 prio_val, prio_mask = 0;
  
  #ifdef CONFIG_MLX5_CORE_EN_DCB
        if (priv->dcbx_dp.trust_state != MLX5_QPTS_TRUST_PCP) {
 -              netdev_warn(priv->netdev,
 -                          "only PCP trust state supported for hairpin\n");
 +              NL_SET_ERR_MSG_MOD(extack,
 +                                 "only PCP trust state supported for hairpin");
                return -EOPNOTSUPP;
        }
  #endif
        if (!vlan_present || !prio_mask) {
                prio_val = UNKNOWN_MATCH_PRIO;
        } else if (prio_mask != 0x7) {
 -              netdev_warn(priv->netdev,
 -                          "masked priority match not supported for hairpin\n");
 +              NL_SET_ERR_MSG_MOD(extack,
 +                                 "masked priority match not supported for hairpin");
                return -EOPNOTSUPP;
        }
  
  
  static int mlx5e_hairpin_flow_add(struct mlx5e_priv *priv,
                                  struct mlx5e_tc_flow *flow,
 -                                struct mlx5e_tc_flow_parse_attr *parse_attr)
 +                                struct mlx5e_tc_flow_parse_attr *parse_attr,
 +                                struct netlink_ext_ack *extack)
  {
        int peer_ifindex = parse_attr->mirred_ifindex;
        struct mlx5_hairpin_params params;
  
        peer_mdev = mlx5e_hairpin_get_mdev(dev_net(priv->netdev), peer_ifindex);
        if (!MLX5_CAP_GEN(priv->mdev, hairpin) || !MLX5_CAP_GEN(peer_mdev, hairpin)) {
 -              netdev_warn(priv->netdev, "hairpin is not supported\n");
 +              NL_SET_ERR_MSG_MOD(extack, "hairpin is not supported");
                return -EOPNOTSUPP;
        }
  
        peer_id = MLX5_CAP_GEN(peer_mdev, vhca_id);
 -      err = mlx5e_hairpin_get_prio(priv, &parse_attr->spec, &match_prio);
 +      err = mlx5e_hairpin_get_prio(priv, &parse_attr->spec, &match_prio,
 +                                   extack);
        if (err)
                return err;
        hpe = mlx5e_hairpin_get(priv, peer_id, match_prio);
@@@ -680,8 -672,7 +675,8 @@@ static void mlx5e_hairpin_flow_del(stru
  static struct mlx5_flow_handle *
  mlx5e_tc_add_nic_flow(struct mlx5e_priv *priv,
                      struct mlx5e_tc_flow_parse_attr *parse_attr,
 -                    struct mlx5e_tc_flow *flow)
 +                    struct mlx5e_tc_flow *flow,
 +                    struct netlink_ext_ack *extack)
  {
        struct mlx5_nic_flow_attr *attr = flow->nic_attr;
        struct mlx5_core_dev *dev = priv->mdev;
                .action = attr->action,
                .has_flow_tag = true,
                .flow_tag = attr->flow_tag,
-               .encap_id = 0,
+               .reformat_id = 0,
        };
        struct mlx5_fc *counter = NULL;
        struct mlx5_flow_handle *rule;
        int err, dest_ix = 0;
  
        if (flow->flags & MLX5E_TC_FLOW_HAIRPIN) {
 -              err = mlx5e_hairpin_flow_add(priv, flow, parse_attr);
 +              err = mlx5e_hairpin_flow_add(priv, flow, parse_attr, extack);
                if (err) {
                        rule = ERR_PTR(err);
                        goto err_add_hairpin_flow;
                                                            MLX5E_TC_TABLE_NUM_GROUPS,
                                                            MLX5E_TC_FT_LEVEL, 0);
                if (IS_ERR(priv->fs.tc.t)) {
 +                      NL_SET_ERR_MSG_MOD(extack,
 +                                         "Failed to create tc offload table\n");
                        netdev_err(priv->netdev,
                                   "Failed to create tc offload table\n");
                        rule = ERR_CAST(priv->fs.tc.t);
@@@ -825,14 -814,12 +820,14 @@@ static int mlx5e_attach_encap(struct ml
                              struct ip_tunnel_info *tun_info,
                              struct net_device *mirred_dev,
                              struct net_device **encap_dev,
 -                            struct mlx5e_tc_flow *flow);
 +                            struct mlx5e_tc_flow *flow,
 +                            struct netlink_ext_ack *extack);
  
  static struct mlx5_flow_handle *
  mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
                      struct mlx5e_tc_flow_parse_attr *parse_attr,
 -                    struct mlx5e_tc_flow *flow)
 +                    struct mlx5e_tc_flow *flow,
 +                    struct netlink_ext_ack *extack)
  {
        struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
        struct mlx5_esw_flow_attr *attr = flow->esw_attr;
        struct mlx5e_priv *out_priv;
        int err;
  
-       if (attr->action & MLX5_FLOW_CONTEXT_ACTION_ENCAP) {
+       if (attr->action & MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT) {
                out_dev = __dev_get_by_index(dev_net(priv->netdev),
                                             attr->parse_attr->mirred_ifindex);
                err = mlx5e_attach_encap(priv, &parse_attr->tun_info,
 -                                       out_dev, &encap_dev, flow);
 +                                       out_dev, &encap_dev, flow, extack);
                if (err) {
                        rule = ERR_PTR(err);
                        if (err != -EAGAIN)
@@@ -898,7 -885,7 +893,7 @@@ err_add_rule
  err_mod_hdr:
        mlx5_eswitch_del_vlan_action(esw, attr);
  err_add_vlan:
-       if (attr->action & MLX5_FLOW_CONTEXT_ACTION_ENCAP)
+       if (attr->action & MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT)
                mlx5e_detach_encap(priv, flow);
  err_attach_encap:
        return rule;
@@@ -919,7 -906,7 +914,7 @@@ static void mlx5e_tc_del_fdb_flow(struc
  
        mlx5_eswitch_del_vlan_action(esw, attr);
  
-       if (attr->action & MLX5_FLOW_CONTEXT_ACTION_ENCAP) {
+       if (attr->action & MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT) {
                mlx5e_detach_encap(priv, flow);
                kvfree(attr->parse_attr);
        }
@@@ -936,9 -923,10 +931,10 @@@ void mlx5e_tc_encap_flows_add(struct ml
        struct mlx5e_tc_flow *flow;
        int err;
  
-       err = mlx5_encap_alloc(priv->mdev, e->tunnel_type,
-                              e->encap_size, e->encap_header,
-                              &e->encap_id);
+       err = mlx5_packet_reformat_alloc(priv->mdev, e->tunnel_type,
+                                        e->encap_size, e->encap_header,
+                                        MLX5_FLOW_NAMESPACE_FDB,
+                                        &e->encap_id);
        if (err) {
                mlx5_core_warn(priv->mdev, "Failed to offload cached encapsulation header, %d\n",
                               err);
@@@ -992,7 -980,7 +988,7 @@@ void mlx5e_tc_encap_flows_del(struct ml
  
        if (e->flags & MLX5_ENCAP_ENTRY_VALID) {
                e->flags &= ~MLX5_ENCAP_ENTRY_VALID;
-               mlx5_encap_dealloc(priv->mdev, e->encap_id);
+               mlx5_packet_reformat_dealloc(priv->mdev, e->encap_id);
        }
  }
  
@@@ -1061,7 -1049,7 +1057,7 @@@ static void mlx5e_detach_encap(struct m
                mlx5e_rep_encap_entry_detach(netdev_priv(e->out_dev), e);
  
                if (e->flags & MLX5_ENCAP_ENTRY_VALID)
-                       mlx5_encap_dealloc(priv->mdev, e->encap_id);
+                       mlx5_packet_reformat_dealloc(priv->mdev, e->encap_id);
  
                hash_del_rcu(&e->encap_hlist);
                kfree(e->encap_header);
@@@ -1113,7 -1101,6 +1109,7 @@@ static int parse_tunnel_attr(struct mlx
                             struct mlx5_flow_spec *spec,
                             struct tc_cls_flower_offload *f)
  {
 +      struct netlink_ext_ack *extack = f->common.extack;
        void *headers_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
                                       outer_headers);
        void *headers_v = MLX5_ADDR_OF(fte_match_param, spec->match_value,
                    MLX5_CAP_ESW(priv->mdev, vxlan_encap_decap))
                        parse_vxlan_attr(spec, f);
                else {
 +                      NL_SET_ERR_MSG_MOD(extack,
 +                                         "port isn't an offloaded vxlan udp dport");
                        netdev_warn(priv->netdev,
                                    "%d isn't an offloaded vxlan udp dport\n", be16_to_cpu(key->dst));
                        return -EOPNOTSUPP;
                         udp_sport, ntohs(key->src));
        } else { /* udp dst port must be given */
  vxlan_match_offload_err:
 +              NL_SET_ERR_MSG_MOD(extack,
 +                                 "IP tunnel decap offload supported only for vxlan, must set UDP dport");
                netdev_warn(priv->netdev,
                            "IP tunnel decap offload supported only for vxlan, must set UDP dport\n");
                return -EOPNOTSUPP;
  
                MLX5_SET(fte_match_set_lyr_2_4, headers_c, ttl_hoplimit, mask->ttl);
                MLX5_SET(fte_match_set_lyr_2_4, headers_v, ttl_hoplimit, key->ttl);
 +
 +              if (mask->ttl &&
 +                  !MLX5_CAP_ESW_FLOWTABLE_FDB
 +                      (priv->mdev,
 +                       ft_field_support.outer_ipv4_ttl)) {
 +                      NL_SET_ERR_MSG_MOD(extack,
 +                                         "Matching on TTL is not supported");
 +                      return -EOPNOTSUPP;
 +              }
 +
        }
  
        /* Enforce DMAC when offloading incoming tunneled flows.
@@@ -1270,7 -1243,6 +1266,7 @@@ static int __parse_cls_flower(struct ml
                              struct tc_cls_flower_offload *f,
                              u8 *match_level)
  {
 +      struct netlink_ext_ack *extack = f->common.extack;
        void *headers_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
                                       outer_headers);
        void *headers_v = MLX5_ADDR_OF(fte_match_param, spec->match_value,
              BIT(FLOW_DISSECTOR_KEY_TCP) |
              BIT(FLOW_DISSECTOR_KEY_IP)  |
              BIT(FLOW_DISSECTOR_KEY_ENC_IP))) {
 +              NL_SET_ERR_MSG_MOD(extack, "Unsupported key");
                netdev_warn(priv->netdev, "Unsupported key used: 0x%x\n",
                            f->dissector->used_keys);
                return -EOPNOTSUPP;
  
                        *match_level = MLX5_MATCH_L2;
                }
 +      } else {
 +              MLX5_SET(fte_match_set_lyr_2_4, headers_c, svlan_tag, 1);
 +              MLX5_SET(fte_match_set_lyr_2_4, headers_c, cvlan_tag, 1);
        }
  
        if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_CVLAN)) {
  
                if (mask->ttl &&
                    !MLX5_CAP_ESW_FLOWTABLE_FDB(priv->mdev,
 -                                              ft_field_support.outer_ipv4_ttl))
 +                                              ft_field_support.outer_ipv4_ttl)) {
 +                      NL_SET_ERR_MSG_MOD(extack,
 +                                         "Matching on TTL is not supported");
                        return -EOPNOTSUPP;
 +              }
  
                if (mask->tos || mask->ttl)
                        *match_level = MLX5_MATCH_L3;
                                 udp_dport, ntohs(key->dst));
                        break;
                default:
 +                      NL_SET_ERR_MSG_MOD(extack,
 +                                         "Only UDP and TCP transports are supported for L4 matching");
                        netdev_err(priv->netdev,
                                   "Only UDP and TCP transport are supported\n");
                        return -EINVAL;
@@@ -1662,7 -1625,6 +1658,7 @@@ static int parse_cls_flower(struct mlx5
                            struct mlx5_flow_spec *spec,
                            struct tc_cls_flower_offload *f)
  {
 +      struct netlink_ext_ack *extack = f->common.extack;
        struct mlx5_core_dev *dev = priv->mdev;
        struct mlx5_eswitch *esw = dev->priv.eswitch;
        struct mlx5e_rep_priv *rpriv = priv->ppriv;
                if (rep->vport != FDB_UPLINK_VPORT &&
                    (esw->offloads.inline_mode != MLX5_INLINE_MODE_NONE &&
                    esw->offloads.inline_mode < match_level)) {
 +                      NL_SET_ERR_MSG_MOD(extack,
 +                                         "Flow is not offloaded due to min inline setting");
                        netdev_warn(priv->netdev,
                                    "Flow is not offloaded due to min inline setting, required %d actual %d\n",
                                    match_level, esw->offloads.inline_mode);
@@@ -1780,8 -1740,7 +1776,8 @@@ static struct mlx5_fields fields[] = 
   */
  static int offload_pedit_fields(struct pedit_headers *masks,
                                struct pedit_headers *vals,
 -                              struct mlx5e_tc_flow_parse_attr *parse_attr)
 +                              struct mlx5e_tc_flow_parse_attr *parse_attr,
 +                              struct netlink_ext_ack *extack)
  {
        struct pedit_headers *set_masks, *add_masks, *set_vals, *add_vals;
        int i, action_size, nactions, max_actions, first, last, next_z;
                        continue;
  
                if (s_mask && a_mask) {
 +                      NL_SET_ERR_MSG_MOD(extack,
 +                                         "can't set and add to the same HW field");
                        printk(KERN_WARNING "mlx5: can't set and add to the same HW field (%x)\n", f->field);
                        return -EOPNOTSUPP;
                }
  
                if (nactions == max_actions) {
 +                      NL_SET_ERR_MSG_MOD(extack,
 +                                         "too many pedit actions, can't offload");
                        printk(KERN_WARNING "mlx5: parsed %d pedit actions, can't do more\n", nactions);
                        return -EOPNOTSUPP;
                }
                next_z = find_next_zero_bit(&mask, field_bsize, first);
                last  = find_last_bit(&mask, field_bsize);
                if (first < next_z && next_z < last) {
 +                      NL_SET_ERR_MSG_MOD(extack,
 +                                         "rewrite of few sub-fields isn't supported");
                        printk(KERN_WARNING "mlx5: rewrite of few sub-fields (mask %lx) isn't offloaded\n",
                               mask);
                        return -EOPNOTSUPP;
@@@ -1921,8 -1874,7 +1917,8 @@@ static const struct pedit_headers zero_
  
  static int parse_tc_pedit_action(struct mlx5e_priv *priv,
                                 const struct tc_action *a, int namespace,
 -                               struct mlx5e_tc_flow_parse_attr *parse_attr)
 +                               struct mlx5e_tc_flow_parse_attr *parse_attr,
 +                               struct netlink_ext_ack *extack)
  {
        struct pedit_headers masks[__PEDIT_CMD_MAX], vals[__PEDIT_CMD_MAX], *cmd_masks;
        int nkeys, i, err = -EOPNOTSUPP;
                err = -EOPNOTSUPP; /* can't be all optimistic */
  
                if (htype == TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK) {
 -                      netdev_warn(priv->netdev, "legacy pedit isn't offloaded\n");
 +                      NL_SET_ERR_MSG_MOD(extack,
 +                                         "legacy pedit isn't offloaded");
                        goto out_err;
                }
  
                if (cmd != TCA_PEDIT_KEY_EX_CMD_SET && cmd != TCA_PEDIT_KEY_EX_CMD_ADD) {
 -                      netdev_warn(priv->netdev, "pedit cmd %d isn't offloaded\n", cmd);
 +                      NL_SET_ERR_MSG_MOD(extack, "pedit cmd isn't offloaded");
                        goto out_err;
                }
  
        if (err)
                goto out_err;
  
 -      err = offload_pedit_fields(masks, vals, parse_attr);
 +      err = offload_pedit_fields(masks, vals, parse_attr, extack);
        if (err < 0)
                goto out_dealloc_parsed_actions;
  
        for (cmd = 0; cmd < __PEDIT_CMD_MAX; cmd++) {
                cmd_masks = &masks[cmd];
                if (memcmp(cmd_masks, &zero_masks, sizeof(zero_masks))) {
 +                      NL_SET_ERR_MSG_MOD(extack,
 +                                         "attempt to offload an unsupported field");
                        netdev_warn(priv->netdev, "attempt to offload an unsupported field (cmd %d)\n", cmd);
                        print_hex_dump(KERN_WARNING, "mask: ", DUMP_PREFIX_ADDRESS,
                                       16, 1, cmd_masks, sizeof(zero_masks), true);
@@@ -1988,26 -1937,19 +1984,26 @@@ out_err
        return err;
  }
  
 -static bool csum_offload_supported(struct mlx5e_priv *priv, u32 action, u32 update_flags)
 +static bool csum_offload_supported(struct mlx5e_priv *priv,
 +                                 u32 action,
 +                                 u32 update_flags,
 +                                 struct netlink_ext_ack *extack)
  {
        u32 prot_flags = TCA_CSUM_UPDATE_FLAG_IPV4HDR | TCA_CSUM_UPDATE_FLAG_TCP |
                         TCA_CSUM_UPDATE_FLAG_UDP;
  
        /*  The HW recalcs checksums only if re-writing headers */
        if (!(action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR)) {
 +              NL_SET_ERR_MSG_MOD(extack,
 +                                 "TC csum action is only offloaded with pedit");
                netdev_warn(priv->netdev,
                            "TC csum action is only offloaded with pedit\n");
                return false;
        }
  
        if (update_flags & ~prot_flags) {
 +              NL_SET_ERR_MSG_MOD(extack,
 +                                 "can't offload TC csum action for some header/s");
                netdev_warn(priv->netdev,
                            "can't offload TC csum action for some header/s - flags %#x\n",
                            update_flags);
  }
  
  static bool modify_header_match_supported(struct mlx5_flow_spec *spec,
 -                                        struct tcf_exts *exts)
 +                                        struct tcf_exts *exts,
 +                                        struct netlink_ext_ack *extack)
  {
        const struct tc_action *a;
        bool modify_ip_header;
                goto out_ok;
  
        modify_ip_header = false;
 -      tcf_exts_to_list(exts, &actions);
 -      list_for_each_entry(a, &actions, list) {
 +      tcf_exts_for_each_action(i, a, exts) {
 +              int k;
 +
                if (!is_tcf_pedit(a))
                        continue;
  
                nkeys = tcf_pedit_nkeys(a);
 -              for (i = 0; i < nkeys; i++) {
 -                      htype = tcf_pedit_htype(a, i);
 +              for (k = 0; k < nkeys; k++) {
 +                      htype = tcf_pedit_htype(a, k);
                        if (htype == TCA_PEDIT_KEY_EX_HDR_TYPE_IP4 ||
                            htype == TCA_PEDIT_KEY_EX_HDR_TYPE_IP6) {
                                modify_ip_header = true;
        ip_proto = MLX5_GET(fte_match_set_lyr_2_4, headers_v, ip_protocol);
        if (modify_ip_header && ip_proto != IPPROTO_TCP &&
            ip_proto != IPPROTO_UDP && ip_proto != IPPROTO_ICMP) {
 +              NL_SET_ERR_MSG_MOD(extack,
 +                                 "can't offload re-write of non TCP/UDP");
                pr_info("can't offload re-write of ip proto %d\n", ip_proto);
                return false;
        }
@@@ -2070,8 -2008,7 +2066,8 @@@ out_ok
  static bool actions_match_supported(struct mlx5e_priv *priv,
                                    struct tcf_exts *exts,
                                    struct mlx5e_tc_flow_parse_attr *parse_attr,
 -                                  struct mlx5e_tc_flow *flow)
 +                                  struct mlx5e_tc_flow *flow,
 +                                  struct netlink_ext_ack *extack)
  {
        u32 actions;
  
                return false;
  
        if (actions & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR)
 -              return modify_header_match_supported(&parse_attr->spec, exts);
 +              return modify_header_match_supported(&parse_attr->spec, exts,
 +                                                   extack);
  
        return true;
  }
@@@ -2099,29 -2035,29 +2095,29 @@@ static bool same_hw_devs(struct mlx5e_p
        fmdev = priv->mdev;
        pmdev = peer_priv->mdev;
  
 -      mlx5_query_nic_vport_system_image_guid(fmdev, &fsystem_guid);
 -      mlx5_query_nic_vport_system_image_guid(pmdev, &psystem_guid);
 +      fsystem_guid = mlx5_query_nic_system_image_guid(fmdev);
 +      psystem_guid = mlx5_query_nic_system_image_guid(pmdev);
  
        return (fsystem_guid == psystem_guid);
  }
  
  static int parse_tc_nic_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
                                struct mlx5e_tc_flow_parse_attr *parse_attr,
 -                              struct mlx5e_tc_flow *flow)
 +                              struct mlx5e_tc_flow *flow,
 +                              struct netlink_ext_ack *extack)
  {
        struct mlx5_nic_flow_attr *attr = flow->nic_attr;
        const struct tc_action *a;
        LIST_HEAD(actions);
        u32 action = 0;
 -      int err;
 +      int err, i;
  
        if (!tcf_exts_has_actions(exts))
                return -EINVAL;
  
        attr->flow_tag = MLX5_FS_DEFAULT_FLOW_TAG;
  
 -      tcf_exts_to_list(exts, &actions);
 -      list_for_each_entry(a, &actions, list) {
 +      tcf_exts_for_each_action(i, a, exts) {
                if (is_tcf_gact_shot(a)) {
                        action |= MLX5_FLOW_CONTEXT_ACTION_DROP;
                        if (MLX5_CAP_FLOWTABLE(priv->mdev,
  
                if (is_tcf_pedit(a)) {
                        err = parse_tc_pedit_action(priv, a, MLX5_FLOW_NAMESPACE_KERNEL,
 -                                                  parse_attr);
 +                                                  parse_attr, extack);
                        if (err)
                                return err;
  
  
                if (is_tcf_csum(a)) {
                        if (csum_offload_supported(priv, action,
 -                                                 tcf_csum_update_flags(a)))
 +                                                 tcf_csum_update_flags(a),
 +                                                 extack))
                                continue;
  
                        return -EOPNOTSUPP;
                                action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
                                          MLX5_FLOW_CONTEXT_ACTION_COUNT;
                        } else {
 +                              NL_SET_ERR_MSG_MOD(extack,
 +                                                 "device is not on same HW, can't offload");
                                netdev_warn(priv->netdev, "device %s not on same HW, can't offload\n",
                                            peer_dev->name);
                                return -EINVAL;
                        u32 mark = tcf_skbedit_mark(a);
  
                        if (mark & ~MLX5E_TC_FLOW_ID_MASK) {
 -                              netdev_warn(priv->netdev, "Bad flow mark - only 16 bit is supported: 0x%x\n",
 -                                          mark);
 +                              NL_SET_ERR_MSG_MOD(extack,
 +                                                 "Bad flow mark - only 16 bit is supported");
                                return -EINVAL;
                        }
  
        }
  
        attr->action = action;
 -      if (!actions_match_supported(priv, exts, parse_attr, flow))
 +      if (!actions_match_supported(priv, exts, parse_attr, flow, extack))
                return -EOPNOTSUPP;
  
        return 0;
@@@ -2391,7 -2324,7 +2387,7 @@@ static int mlx5e_create_encap_header_ip
                return -ENOMEM;
  
        switch (e->tunnel_type) {
-       case MLX5_HEADER_TYPE_VXLAN:
+       case MLX5_REFORMAT_TYPE_L2_TO_VXLAN:
                fl4.flowi4_proto = IPPROTO_UDP;
                fl4.fl4_dport = tun_key->tp_dst;
                break;
        read_unlock_bh(&n->lock);
  
        switch (e->tunnel_type) {
-       case MLX5_HEADER_TYPE_VXLAN:
+       case MLX5_REFORMAT_TYPE_L2_TO_VXLAN:
                gen_vxlan_header_ipv4(out_dev, encap_header,
                                      ipv4_encap_size, e->h_dest, tos, ttl,
                                      fl4.daddr,
                goto out;
        }
  
-       err = mlx5_encap_alloc(priv->mdev, e->tunnel_type,
-                              ipv4_encap_size, encap_header, &e->encap_id);
+       err = mlx5_packet_reformat_alloc(priv->mdev, e->tunnel_type,
+                                        ipv4_encap_size, encap_header,
+                                        MLX5_FLOW_NAMESPACE_FDB,
+                                        &e->encap_id);
        if (err)
                goto destroy_neigh_entry;
  
@@@ -2500,7 -2435,7 +2498,7 @@@ static int mlx5e_create_encap_header_ip
                return -ENOMEM;
  
        switch (e->tunnel_type) {
-       case MLX5_HEADER_TYPE_VXLAN:
+       case MLX5_REFORMAT_TYPE_L2_TO_VXLAN:
                fl6.flowi6_proto = IPPROTO_UDP;
                fl6.fl6_dport = tun_key->tp_dst;
                break;
        read_unlock_bh(&n->lock);
  
        switch (e->tunnel_type) {
-       case MLX5_HEADER_TYPE_VXLAN:
+       case MLX5_REFORMAT_TYPE_L2_TO_VXLAN:
                gen_vxlan_header_ipv6(out_dev, encap_header,
                                      ipv6_encap_size, e->h_dest, tos, ttl,
                                      &fl6.daddr,
                goto out;
        }
  
-       err = mlx5_encap_alloc(priv->mdev, e->tunnel_type,
-                              ipv6_encap_size, encap_header, &e->encap_id);
+       err = mlx5_packet_reformat_alloc(priv->mdev, e->tunnel_type,
+                                        ipv6_encap_size, encap_header,
+                                        MLX5_FLOW_NAMESPACE_FDB,
+                                        &e->encap_id);
        if (err)
                goto destroy_neigh_entry;
  
@@@ -2589,8 -2526,7 +2589,8 @@@ static int mlx5e_attach_encap(struct ml
                              struct ip_tunnel_info *tun_info,
                              struct net_device *mirred_dev,
                              struct net_device **encap_dev,
 -                            struct mlx5e_tc_flow *flow)
 +                            struct mlx5e_tc_flow *flow,
 +                            struct netlink_ext_ack *extack)
  {
        struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
        unsigned short family = ip_tunnel_info_af(tun_info);
        /* setting udp src port isn't supported */
        if (memchr_inv(&key->tp_src, 0, sizeof(key->tp_src))) {
  vxlan_encap_offload_err:
 +              NL_SET_ERR_MSG_MOD(extack,
 +                                 "must set udp dst port and not set udp src port");
                netdev_warn(priv->netdev,
                            "must set udp dst port and not set udp src port\n");
                return -EOPNOTSUPP;
  
        if (mlx5_vxlan_lookup_port(priv->mdev->vxlan, be16_to_cpu(key->tp_dst)) &&
            MLX5_CAP_ESW(priv->mdev, vxlan_encap_decap)) {
-               tunnel_type = MLX5_HEADER_TYPE_VXLAN;
+               tunnel_type = MLX5_REFORMAT_TYPE_L2_TO_VXLAN;
        } else {
 +              NL_SET_ERR_MSG_MOD(extack,
 +                                 "port isn't an offloaded vxlan udp dport");
                netdev_warn(priv->netdev,
                            "%d isn't an offloaded vxlan udp dport\n", be16_to_cpu(key->tp_dst));
                return -EOPNOTSUPP;
@@@ -2725,8 -2657,7 +2725,8 @@@ static int parse_tc_vlan_action(struct 
  
  static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
                                struct mlx5e_tc_flow_parse_attr *parse_attr,
 -                              struct mlx5e_tc_flow *flow)
 +                              struct mlx5e_tc_flow *flow,
 +                              struct netlink_ext_ack *extack)
  {
        struct mlx5_esw_flow_attr *attr = flow->esw_attr;
        struct mlx5e_rep_priv *rpriv = priv->ppriv;
        LIST_HEAD(actions);
        bool encap = false;
        u32 action = 0;
 -      int err;
 +      int err, i;
  
        if (!tcf_exts_has_actions(exts))
                return -EINVAL;
        attr->in_rep = rpriv->rep;
        attr->in_mdev = priv->mdev;
  
 -      tcf_exts_to_list(exts, &actions);
 -      list_for_each_entry(a, &actions, list) {
 +      tcf_exts_for_each_action(i, a, exts) {
                if (is_tcf_gact_shot(a)) {
                        action |= MLX5_FLOW_CONTEXT_ACTION_DROP |
                                  MLX5_FLOW_CONTEXT_ACTION_COUNT;
  
                if (is_tcf_pedit(a)) {
                        err = parse_tc_pedit_action(priv, a, MLX5_FLOW_NAMESPACE_FDB,
 -                                                  parse_attr);
 +                                                  parse_attr, extack);
                        if (err)
                                return err;
  
  
                if (is_tcf_csum(a)) {
                        if (csum_offload_supported(priv, action,
 -                                                 tcf_csum_update_flags(a)))
 +                                                 tcf_csum_update_flags(a),
 +                                                 extack))
                                continue;
  
                        return -EOPNOTSUPP;
                        out_dev = tcf_mirred_dev(a);
  
                        if (attr->out_count >= MLX5_MAX_FLOW_FWD_VPORTS) {
 +                              NL_SET_ERR_MSG_MOD(extack,
 +                                                 "can't support more output ports, can't offload forwarding");
                                pr_err("can't support more than %d output ports, can't offload forwarding\n",
                                       attr->out_count);
                                return -EOPNOTSUPP;
                                parse_attr->mirred_ifindex = out_dev->ifindex;
                                parse_attr->tun_info = *info;
                                attr->parse_attr = parse_attr;
-                               action |= MLX5_FLOW_CONTEXT_ACTION_ENCAP |
+                               action |= MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT |
                                          MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
                                          MLX5_FLOW_CONTEXT_ACTION_COUNT;
                                /* attr->out_rep is resolved when we handle encap */
                        } else {
 +                              NL_SET_ERR_MSG_MOD(extack,
 +                                                 "devices are not on same switch HW, can't offload forwarding");
                                pr_err("devices %s %s not on same switch HW, can't offload forwarding\n",
                                       priv->netdev->name, out_dev->name);
                                return -EINVAL;
        }
  
        attr->action = action;
 -      if (!actions_match_supported(priv, exts, parse_attr, flow))
 +      if (!actions_match_supported(priv, exts, parse_attr, flow, extack))
                return -EOPNOTSUPP;
  
        if (attr->out_count > 1 && !mlx5_esw_has_fwd_fdb(priv->mdev)) {
 +              NL_SET_ERR_MSG_MOD(extack,
 +                                 "current firmware doesn't support split rule for port mirroring");
                netdev_warn_once(priv->netdev, "current firmware doesn't support split rule for port mirroring\n");
                return -EOPNOTSUPP;
        }
@@@ -2887,7 -2812,6 +2887,7 @@@ static struct rhashtable *get_tc_ht(str
  int mlx5e_configure_flower(struct mlx5e_priv *priv,
                           struct tc_cls_flower_offload *f, int flags)
  {
 +      struct netlink_ext_ack *extack = f->common.extack;
        struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
        struct mlx5e_tc_flow_parse_attr *parse_attr;
        struct rhashtable *tc_ht = get_tc_ht(priv);
  
        flow = rhashtable_lookup_fast(tc_ht, &f->cookie, tc_ht_params);
        if (flow) {
 +              NL_SET_ERR_MSG_MOD(extack,
 +                                 "flow cookie already exists, ignoring");
                netdev_warn_once(priv->netdev, "flow cookie %lx already exists, ignoring\n", f->cookie);
                return 0;
        }
                goto err_free;
  
        if (flow->flags & MLX5E_TC_FLOW_ESWITCH) {
 -              err = parse_tc_fdb_actions(priv, f->exts, parse_attr, flow);
 +              err = parse_tc_fdb_actions(priv, f->exts, parse_attr, flow,
 +                                         extack);
                if (err < 0)
                        goto err_free;
 -              flow->rule[0] = mlx5e_tc_add_fdb_flow(priv, parse_attr, flow);
 +              flow->rule[0] = mlx5e_tc_add_fdb_flow(priv, parse_attr, flow,
 +                                                    extack);
        } else {
 -              err = parse_tc_nic_actions(priv, f->exts, parse_attr, flow);
 +              err = parse_tc_nic_actions(priv, f->exts, parse_attr, flow,
 +                                         extack);
                if (err < 0)
                        goto err_free;
 -              flow->rule[0] = mlx5e_tc_add_nic_flow(priv, parse_attr, flow);
 +              flow->rule[0] = mlx5e_tc_add_nic_flow(priv, parse_attr, flow,
 +                                                    extack);
        }
  
        if (IS_ERR(flow->rule[0])) {
                flow->flags |= MLX5E_TC_FLOW_OFFLOADED;
  
        if (!(flow->flags & MLX5E_TC_FLOW_ESWITCH) ||
-           !(flow->esw_attr->action & MLX5_FLOW_CONTEXT_ACTION_ENCAP))
+           !(flow->esw_attr->action &
+             MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT))
                kvfree(parse_attr);
  
        err = rhashtable_insert_fast(tc_ht, &flow->node, tc_ht_params);
@@@ -3029,71 -2948,14 +3030,71 @@@ int mlx5e_stats_flower(struct mlx5e_pri
        return 0;
  }
  
 +static void mlx5e_tc_hairpin_update_dead_peer(struct mlx5e_priv *priv,
 +                                            struct mlx5e_priv *peer_priv)
 +{
 +      struct mlx5_core_dev *peer_mdev = peer_priv->mdev;
 +      struct mlx5e_hairpin_entry *hpe;
 +      u16 peer_vhca_id;
 +      int bkt;
 +
 +      if (!same_hw_devs(priv, peer_priv))
 +              return;
 +
 +      peer_vhca_id = MLX5_CAP_GEN(peer_mdev, vhca_id);
 +
 +      hash_for_each(priv->fs.tc.hairpin_tbl, bkt, hpe, hairpin_hlist) {
 +              if (hpe->peer_vhca_id == peer_vhca_id)
 +                      hpe->hp->pair->peer_gone = true;
 +      }
 +}
 +
 +static int mlx5e_tc_netdev_event(struct notifier_block *this,
 +                               unsigned long event, void *ptr)
 +{
 +      struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
 +      struct mlx5e_flow_steering *fs;
 +      struct mlx5e_priv *peer_priv;
 +      struct mlx5e_tc_table *tc;
 +      struct mlx5e_priv *priv;
 +
 +      if (ndev->netdev_ops != &mlx5e_netdev_ops ||
 +          event != NETDEV_UNREGISTER ||
 +          ndev->reg_state == NETREG_REGISTERED)
 +              return NOTIFY_DONE;
 +
 +      tc = container_of(this, struct mlx5e_tc_table, netdevice_nb);
 +      fs = container_of(tc, struct mlx5e_flow_steering, tc);
 +      priv = container_of(fs, struct mlx5e_priv, fs);
 +      peer_priv = netdev_priv(ndev);
 +      if (priv == peer_priv ||
 +          !(priv->netdev->features & NETIF_F_HW_TC))
 +              return NOTIFY_DONE;
 +
 +      mlx5e_tc_hairpin_update_dead_peer(priv, peer_priv);
 +
 +      return NOTIFY_DONE;
 +}
 +
  int mlx5e_tc_nic_init(struct mlx5e_priv *priv)
  {
        struct mlx5e_tc_table *tc = &priv->fs.tc;
 +      int err;
  
        hash_init(tc->mod_hdr_tbl);
        hash_init(tc->hairpin_tbl);
  
 -      return rhashtable_init(&tc->ht, &tc_ht_params);
 +      err = rhashtable_init(&tc->ht, &tc_ht_params);
 +      if (err)
 +              return err;
 +
 +      tc->netdevice_nb.notifier_call = mlx5e_tc_netdev_event;
 +      if (register_netdevice_notifier(&tc->netdevice_nb)) {
 +              tc->netdevice_nb.notifier_call = NULL;
 +              mlx5_core_warn(priv->mdev, "Failed to register netdev notifier\n");
 +      }
 +
 +      return err;
  }
  
  static void _mlx5e_tc_del_flow(void *ptr, void *arg)
@@@ -3109,9 -2971,6 +3110,9 @@@ void mlx5e_tc_nic_cleanup(struct mlx5e_
  {
        struct mlx5e_tc_table *tc = &priv->fs.tc;
  
 +      if (tc->netdevice_nb.notifier_call)
 +              unregister_netdevice_notifier(&tc->netdevice_nb);
 +
        rhashtable_free_and_destroy(&tc->ht, _mlx5e_tc_del_flow, NULL);
  
        if (!IS_ERR_OR_NULL(tc->t)) {
index ea7dedc2d5adfc48081387619222c8e07da43bd4,525b7e43b298fe76525314e90d0cc7dd00389347..e1d47fa5ab837770a5961c4fb483a1ef66e5e01a
@@@ -1746,7 -1746,7 +1746,7 @@@ int mlx5_eswitch_init(struct mlx5_core_
        esw->enabled_vports = 0;
        esw->mode = SRIOV_NONE;
        esw->offloads.inline_mode = MLX5_INLINE_MODE_NONE;
-       if (MLX5_CAP_ESW_FLOWTABLE_FDB(dev, encap) &&
+       if (MLX5_CAP_ESW_FLOWTABLE_FDB(dev, reformat) &&
            MLX5_CAP_ESW_FLOWTABLE_FDB(dev, decap))
                esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_BASIC;
        else
@@@ -2000,7 -2000,7 +2000,7 @@@ static u32 calculate_vports_min_rate_di
        u32 max_guarantee = 0;
        int i;
  
 -      for (i = 0; i <= esw->total_vports; i++) {
 +      for (i = 0; i < esw->total_vports; i++) {
                evport = &esw->vports[i];
                if (!evport->enabled || evport->info.min_rate < max_guarantee)
                        continue;
@@@ -2020,7 -2020,7 +2020,7 @@@ static int normalize_vports_min_rate(st
        int err;
        int i;
  
 -      for (i = 0; i <= esw->total_vports; i++) {
 +      for (i = 0; i < esw->total_vports; i++) {
                evport = &esw->vports[i];
                if (!evport->enabled)
                        continue;
index a35a2310f8718f0a7ae67f9859aaae20d41063b0,00ec6dd72080d7d39eff54baa95eb5f3da84e361..0741683f7d7011b95e8c27747776c213beec0c4e
@@@ -127,8 -127,8 +127,8 @@@ mlx5_eswitch_add_offloaded_rule(struct 
        if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR)
                flow_act.modify_id = attr->mod_hdr_id;
  
-       if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_ENCAP)
-               flow_act.encap_id = attr->encap_id;
+       if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT)
+               flow_act.reformat_id = attr->encap_id;
  
        rule = mlx5_add_flow_rules(ft, spec, &flow_act, dest, i);
        if (IS_ERR(rule))
@@@ -529,7 -529,8 +529,8 @@@ static int esw_create_offloads_fast_fdb
                esw_size >>= 1;
  
        if (esw->offloads.encap != DEVLINK_ESWITCH_ENCAP_MODE_NONE)
-               flags |= MLX5_FLOW_TABLE_TUNNEL_EN;
+               flags |= (MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT |
+                         MLX5_FLOW_TABLE_TUNNEL_EN_DECAP);
  
        fdb = mlx5_create_auto_grouped_flow_table(root_ns, FDB_FAST_PATH,
                                                  esw_size,
@@@ -663,7 -664,6 +664,7 @@@ static int esw_create_offloads_fdb_tabl
        if (err)
                goto miss_rule_err;
  
 +      kvfree(flow_group_in);
        return 0;
  
  miss_rule_err:
@@@ -775,10 -775,10 +776,10 @@@ static void esw_destroy_vport_rx_group(
  }
  
  struct mlx5_flow_handle *
 -mlx5_eswitch_create_vport_rx_rule(struct mlx5_eswitch *esw, int vport, u32 tirn)
 +mlx5_eswitch_create_vport_rx_rule(struct mlx5_eswitch *esw, int vport,
 +                                struct mlx5_flow_destination *dest)
  {
        struct mlx5_flow_act flow_act = {0};
 -      struct mlx5_flow_destination dest = {};
        struct mlx5_flow_handle *flow_rule;
        struct mlx5_flow_spec *spec;
        void *misc;
        MLX5_SET_TO_ONES(fte_match_set_misc, misc, source_port);
  
        spec->match_criteria_enable = MLX5_MATCH_MISC_PARAMETERS;
 -      dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
 -      dest.tir_num = tirn;
  
        flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
        flow_rule = mlx5_add_flow_rules(esw->offloads.ft_offloads, spec,
 -                                      &flow_act, &dest, 1);
 +                                      &flow_act, dest, 1);
        if (IS_ERR(flow_rule)) {
                esw_warn(esw->dev, "fs offloads: Failed to add vport rx rule err %ld\n", PTR_ERR(flow_rule));
                goto out;
@@@ -810,35 -812,29 +811,35 @@@ out
        return flow_rule;
  }
  
 -static int esw_offloads_start(struct mlx5_eswitch *esw)
 +static int esw_offloads_start(struct mlx5_eswitch *esw,
 +                            struct netlink_ext_ack *extack)
  {
        int err, err1, num_vfs = esw->dev->priv.sriov.num_vfs;
  
        if (esw->mode != SRIOV_LEGACY) {
 -              esw_warn(esw->dev, "Can't set offloads mode, SRIOV legacy not enabled\n");
 +              NL_SET_ERR_MSG_MOD(extack,
 +                                 "Can't set offloads mode, SRIOV legacy not enabled");
                return -EINVAL;
        }
  
        mlx5_eswitch_disable_sriov(esw);
        err = mlx5_eswitch_enable_sriov(esw, num_vfs, SRIOV_OFFLOADS);
        if (err) {
 -              esw_warn(esw->dev, "Failed setting eswitch to offloads, err %d\n", err);
 +              NL_SET_ERR_MSG_MOD(extack,
 +                                 "Failed setting eswitch to offloads");
                err1 = mlx5_eswitch_enable_sriov(esw, num_vfs, SRIOV_LEGACY);
 -              if (err1)
 -                      esw_warn(esw->dev, "Failed setting eswitch back to legacy, err %d\n", err1);
 +              if (err1) {
 +                      NL_SET_ERR_MSG_MOD(extack,
 +                                         "Failed setting eswitch back to legacy");
 +              }
        }
        if (esw->offloads.inline_mode == MLX5_INLINE_MODE_NONE) {
                if (mlx5_eswitch_inline_mode_get(esw,
                                                 num_vfs,
                                                 &esw->offloads.inline_mode)) {
                        esw->offloads.inline_mode = MLX5_INLINE_MODE_L2;
 -                      esw_warn(esw->dev, "Inline mode is different between vports\n");
 +                      NL_SET_ERR_MSG_MOD(extack,
 +                                         "Inline mode is different between vports");
                }
        }
        return err;
@@@ -979,20 -975,17 +980,20 @@@ create_ft_err
        return err;
  }
  
 -static int esw_offloads_stop(struct mlx5_eswitch *esw)
 +static int esw_offloads_stop(struct mlx5_eswitch *esw,
 +                           struct netlink_ext_ack *extack)
  {
        int err, err1, num_vfs = esw->dev->priv.sriov.num_vfs;
  
        mlx5_eswitch_disable_sriov(esw);
        err = mlx5_eswitch_enable_sriov(esw, num_vfs, SRIOV_LEGACY);
        if (err) {
 -              esw_warn(esw->dev, "Failed setting eswitch to legacy, err %d\n", err);
 +              NL_SET_ERR_MSG_MOD(extack, "Failed setting eswitch to legacy");
                err1 = mlx5_eswitch_enable_sriov(esw, num_vfs, SRIOV_OFFLOADS);
 -              if (err1)
 -                      esw_warn(esw->dev, "Failed setting eswitch back to offloads, err %d\n", err);
 +              if (err1) {
 +                      NL_SET_ERR_MSG_MOD(extack,
 +                                         "Failed setting eswitch back to offloads");
 +              }
        }
  
        /* enable back PF RoCE */
@@@ -1101,8 -1094,7 +1102,8 @@@ static int mlx5_devlink_eswitch_check(s
        return 0;
  }
  
 -int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode)
 +int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
 +                                struct netlink_ext_ack *extack)
  {
        struct mlx5_core_dev *dev = devlink_priv(devlink);
        u16 cur_mlx5_mode, mlx5_mode = 0;
                return 0;
  
        if (mode == DEVLINK_ESWITCH_MODE_SWITCHDEV)
 -              return esw_offloads_start(dev->priv.eswitch);
 +              return esw_offloads_start(dev->priv.eswitch, extack);
        else if (mode == DEVLINK_ESWITCH_MODE_LEGACY)
 -              return esw_offloads_stop(dev->priv.eswitch);
 +              return esw_offloads_stop(dev->priv.eswitch, extack);
        else
                return -EINVAL;
  }
@@@ -1140,8 -1132,7 +1141,8 @@@ int mlx5_devlink_eswitch_mode_get(struc
        return esw_mode_to_devlink(dev->priv.eswitch->mode, mode);
  }
  
 -int mlx5_devlink_eswitch_inline_mode_set(struct devlink *devlink, u8 mode)
 +int mlx5_devlink_eswitch_inline_mode_set(struct devlink *devlink, u8 mode,
 +                                       struct netlink_ext_ack *extack)
  {
        struct mlx5_core_dev *dev = devlink_priv(devlink);
        struct mlx5_eswitch *esw = dev->priv.eswitch;
                        return 0;
                /* fall through */
        case MLX5_CAP_INLINE_MODE_L2:
 -              esw_warn(dev, "Inline mode can't be set\n");
 +              NL_SET_ERR_MSG_MOD(extack, "Inline mode can't be set");
                return -EOPNOTSUPP;
        case MLX5_CAP_INLINE_MODE_VPORT_CONTEXT:
                break;
        }
  
        if (esw->offloads.num_flows > 0) {
 -              esw_warn(dev, "Can't set inline mode when flows are configured\n");
 +              NL_SET_ERR_MSG_MOD(extack,
 +                                 "Can't set inline mode when flows are configured");
                return -EOPNOTSUPP;
        }
  
        for (vport = 1; vport < esw->enabled_vports; vport++) {
                err = mlx5_modify_nic_vport_min_inline(dev, vport, mlx5_mode);
                if (err) {
 -                      esw_warn(dev, "Failed to set min inline on vport %d\n",
 -                               vport);
 +                      NL_SET_ERR_MSG_MOD(extack,
 +                                         "Failed to set min inline on vport");
                        goto revert_inline_mode;
                }
        }
@@@ -1244,8 -1234,7 +1245,8 @@@ out
        return 0;
  }
  
 -int mlx5_devlink_eswitch_encap_mode_set(struct devlink *devlink, u8 encap)
 +int mlx5_devlink_eswitch_encap_mode_set(struct devlink *devlink, u8 encap,
 +                                      struct netlink_ext_ack *extack)
  {
        struct mlx5_core_dev *dev = devlink_priv(devlink);
        struct mlx5_eswitch *esw = dev->priv.eswitch;
                return err;
  
        if (encap != DEVLINK_ESWITCH_ENCAP_MODE_NONE &&
-           (!MLX5_CAP_ESW_FLOWTABLE_FDB(dev, encap) ||
+           (!MLX5_CAP_ESW_FLOWTABLE_FDB(dev, reformat) ||
             !MLX5_CAP_ESW_FLOWTABLE_FDB(dev, decap)))
                return -EOPNOTSUPP;
  
                return 0;
  
        if (esw->offloads.num_flows > 0) {
 -              esw_warn(dev, "Can't set encapsulation when flows are configured\n");
 +              NL_SET_ERR_MSG_MOD(extack,
 +                                 "Can't set encapsulation when flows are configured");
                return -EOPNOTSUPP;
        }
  
        esw->offloads.encap = encap;
        err = esw_create_offloads_fast_fdb_table(esw);
        if (err) {
 -              esw_warn(esw->dev, "Failed re-creating fast FDB table, err %d\n", err);
 +              NL_SET_ERR_MSG_MOD(extack,
 +                                 "Failed re-creating fast FDB table");
                esw->offloads.encap = !encap;
                (void)esw_create_offloads_fast_fdb_table(esw);
        }
index 37d114c668b7ba70ca968f76c88c42af84967f25,d2b162cfe86bf343c954acf755c64b21fafac95b..8d340e5181f8dadea456133ff9eb2279861e8521
                                           FS_CAP(flow_table_properties_nic_receive.identified_miss_table_mode), \
                                           FS_CAP(flow_table_properties_nic_receive.flow_table_modify))
  
+ #define FS_CHAINING_CAPS_EGRESS                                                \
+       FS_REQUIRED_CAPS(                                                      \
+               FS_CAP(flow_table_properties_nic_transmit.flow_modify_en),     \
+               FS_CAP(flow_table_properties_nic_transmit.modify_root),        \
+               FS_CAP(flow_table_properties_nic_transmit                      \
+                              .identified_miss_table_mode),                   \
+               FS_CAP(flow_table_properties_nic_transmit.flow_table_modify))
  #define LEFTOVERS_NUM_LEVELS 1
  #define LEFTOVERS_NUM_PRIOS 1
  
@@@ -151,6 -159,17 +159,17 @@@ static struct init_tree_node 
        }
  };
  
+ static struct init_tree_node egress_root_fs = {
+       .type = FS_TYPE_NAMESPACE,
+       .ar_size = 1,
+       .children = (struct init_tree_node[]) {
+               ADD_PRIO(0, MLX5_BY_PASS_NUM_PRIOS, 0,
+                        FS_CHAINING_CAPS_EGRESS,
+                        ADD_NS(ADD_MULTIPLE_PRIO(MLX5_BY_PASS_NUM_PRIOS,
+                                                 BY_PASS_PRIO_NUM_LEVELS))),
+       }
+ };
  enum fs_i_lock_class {
        FS_LOCK_GRANDPARENT,
        FS_LOCK_PARENT,
@@@ -1388,7 -1407,7 +1407,7 @@@ static bool check_conflicting_actions(u
                return false;
  
        if (xored_actions & (MLX5_FLOW_CONTEXT_ACTION_DROP  |
-                            MLX5_FLOW_CONTEXT_ACTION_ENCAP |
+                            MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT |
                             MLX5_FLOW_CONTEXT_ACTION_DECAP |
                             MLX5_FLOW_CONTEXT_ACTION_MOD_HDR  |
                             MLX5_FLOW_CONTEXT_ACTION_VLAN_POP |
@@@ -1578,33 -1597,6 +1597,33 @@@ static u64 matched_fgs_get_version(stru
        return version;
  }
  
 +static struct fs_fte *
 +lookup_fte_locked(struct mlx5_flow_group *g,
 +                u32 *match_value,
 +                bool take_write)
 +{
 +      struct fs_fte *fte_tmp;
 +
 +      if (take_write)
 +              nested_down_write_ref_node(&g->node, FS_LOCK_PARENT);
 +      else
 +              nested_down_read_ref_node(&g->node, FS_LOCK_PARENT);
 +      fte_tmp = rhashtable_lookup_fast(&g->ftes_hash, match_value,
 +                                       rhash_fte);
 +      if (!fte_tmp || !tree_get_node(&fte_tmp->node)) {
 +              fte_tmp = NULL;
 +              goto out;
 +      }
 +
 +      nested_down_write_ref_node(&fte_tmp->node, FS_LOCK_CHILD);
 +out:
 +      if (take_write)
 +              up_write_ref_node(&g->node);
 +      else
 +              up_read_ref_node(&g->node);
 +      return fte_tmp;
 +}
 +
  static struct mlx5_flow_handle *
  try_add_to_existing_fg(struct mlx5_flow_table *ft,
                       struct list_head *match_head,
        if (IS_ERR(fte))
                return  ERR_PTR(-ENOMEM);
  
 -      list_for_each_entry(iter, match_head, list) {
 -              nested_down_read_ref_node(&iter->g->node, FS_LOCK_PARENT);
 -      }
 -
  search_again_locked:
        version = matched_fgs_get_version(match_head);
        /* Try to find a fg that already contains a matching fte */
                struct fs_fte *fte_tmp;
  
                g = iter->g;
 -              fte_tmp = rhashtable_lookup_fast(&g->ftes_hash, spec->match_value,
 -                                               rhash_fte);
 -              if (!fte_tmp || !tree_get_node(&fte_tmp->node))
 +              fte_tmp = lookup_fte_locked(g, spec->match_value, take_write);
 +              if (!fte_tmp)
                        continue;
 -
 -              nested_down_write_ref_node(&fte_tmp->node, FS_LOCK_CHILD);
 -              if (!take_write) {
 -                      list_for_each_entry(iter, match_head, list)
 -                              up_read_ref_node(&iter->g->node);
 -              } else {
 -                      list_for_each_entry(iter, match_head, list)
 -                              up_write_ref_node(&iter->g->node);
 -              }
 -
                rule = add_rule_fg(g, spec->match_value,
                                   flow_act, dest, dest_num, fte_tmp);
                up_write_ref_node(&fte_tmp->node);
                return rule;
        }
  
 -      /* No group with matching fte found. Try to add a new fte to any
 -       * matching fg.
 -       */
 -
 -      if (!take_write) {
 -              list_for_each_entry(iter, match_head, list)
 -                      up_read_ref_node(&iter->g->node);
 -              list_for_each_entry(iter, match_head, list)
 -                      nested_down_write_ref_node(&iter->g->node,
 -                                                 FS_LOCK_PARENT);
 -              take_write = true;
 -      }
 -
        /* Check the ft version, for case that new flow group
         * was added while the fgs weren't locked
         */
        /* Check the fgs version, for case the new FTE with the
         * same values was added while the fgs weren't locked
         */
 -      if (version != matched_fgs_get_version(match_head))
 +      if (version != matched_fgs_get_version(match_head)) {
 +              take_write = true;
                goto search_again_locked;
 +      }
  
        list_for_each_entry(iter, match_head, list) {
                g = iter->g;
  
                if (!g->node.active)
                        continue;
 +
 +              nested_down_write_ref_node(&g->node, FS_LOCK_PARENT);
 +
                err = insert_fte(g, fte);
                if (err) {
 +                      up_write_ref_node(&g->node);
                        if (err == -ENOSPC)
                                continue;
 -                      list_for_each_entry(iter, match_head, list)
 -                              up_write_ref_node(&iter->g->node);
                        kmem_cache_free(steering->ftes_cache, fte);
                        return ERR_PTR(err);
                }
  
                nested_down_write_ref_node(&fte->node, FS_LOCK_CHILD);
 -              list_for_each_entry(iter, match_head, list)
 -                      up_write_ref_node(&iter->g->node);
 +              up_write_ref_node(&g->node);
                rule = add_rule_fg(g, spec->match_value,
                                   flow_act, dest, dest_num, fte);
                up_write_ref_node(&fte->node);
        }
        rule = ERR_PTR(-ENOENT);
  out:
 -      list_for_each_entry(iter, match_head, list)
 -              up_write_ref_node(&iter->g->node);
        kmem_cache_free(steering->ftes_cache, fte);
        return rule;
  }
@@@ -1726,8 -1745,6 +1745,8 @@@ search_again_locked
        if (err) {
                if (take_write)
                        up_write_ref_node(&ft->node);
 +              else
 +                      up_read_ref_node(&ft->node);
                return ERR_PTR(err);
        }
  
@@@ -1980,7 -1997,7 +1999,7 @@@ struct mlx5_flow_namespace *mlx5_get_fl
  {
        struct mlx5_flow_steering *steering = dev->priv.steering;
        struct mlx5_flow_root_namespace *root_ns;
-       int prio;
+       int prio = 0;
        struct fs_prio *fs_prio;
        struct mlx5_flow_namespace *ns;
  
                return NULL;
  
        switch (type) {
-       case MLX5_FLOW_NAMESPACE_BYPASS:
-       case MLX5_FLOW_NAMESPACE_LAG:
-       case MLX5_FLOW_NAMESPACE_OFFLOADS:
-       case MLX5_FLOW_NAMESPACE_ETHTOOL:
-       case MLX5_FLOW_NAMESPACE_KERNEL:
-       case MLX5_FLOW_NAMESPACE_LEFTOVERS:
-       case MLX5_FLOW_NAMESPACE_ANCHOR:
-               prio = type;
-               break;
        case MLX5_FLOW_NAMESPACE_FDB:
                if (steering->fdb_root_ns)
                        return &steering->fdb_root_ns->ns;
-               else
-                       return NULL;
+               return NULL;
        case MLX5_FLOW_NAMESPACE_SNIFFER_RX:
                if (steering->sniffer_rx_root_ns)
                        return &steering->sniffer_rx_root_ns->ns;
-               else
-                       return NULL;
+               return NULL;
        case MLX5_FLOW_NAMESPACE_SNIFFER_TX:
                if (steering->sniffer_tx_root_ns)
                        return &steering->sniffer_tx_root_ns->ns;
-               else
-                       return NULL;
-       case MLX5_FLOW_NAMESPACE_EGRESS:
-               if (steering->egress_root_ns)
-                       return &steering->egress_root_ns->ns;
-               else
-                       return NULL;
-       default:
                return NULL;
+       default:
+               break;
+       }
+       if (type == MLX5_FLOW_NAMESPACE_EGRESS) {
+               root_ns = steering->egress_root_ns;
+       } else { /* Must be NIC RX */
+               root_ns = steering->root_ns;
+               prio = type;
        }
  
-       root_ns = steering->root_ns;
        if (!root_ns)
                return NULL;
  
@@@ -2537,16 -2543,23 +2545,23 @@@ cleanup_root_ns
  
  static int init_egress_root_ns(struct mlx5_flow_steering *steering)
  {
-       struct fs_prio *prio;
+       int err;
  
        steering->egress_root_ns = create_root_ns(steering,
                                                  FS_FT_NIC_TX);
        if (!steering->egress_root_ns)
                return -ENOMEM;
  
-       /* create 1 prio*/
-       prio = fs_create_prio(&steering->egress_root_ns->ns, 0, 1);
-       return PTR_ERR_OR_ZERO(prio);
+       err = init_root_tree(steering, &egress_root_fs,
+                            &steering->egress_root_ns->ns.node);
+       if (err)
+               goto cleanup;
+       set_prio_attrs(steering->egress_root_ns);
+       return 0;
+ cleanup:
+       cleanup_root_ns(steering->egress_root_ns);
+       steering->egress_root_ns = NULL;
+       return err;
  }
  
  int mlx5_init_fs(struct mlx5_core_dev *dev)
                        goto err;
        }
  
-       if (MLX5_IPSEC_DEV(dev)) {
+       if (MLX5_IPSEC_DEV(dev) || MLX5_CAP_FLOWTABLE_NIC_TX(dev, ft_support)) {
                err = init_egress_root_ns(steering);
                if (err)
                        goto err;
index cc298527baf1687d3bafb8f5b345b9c6a8ad1aa9,61a014e3f6880cbe7590aed844ee22d404a40fda..0594d0961cb3fa6ba03b00e68ecc0fc3300a1ec7
@@@ -39,6 -39,7 +39,7 @@@
  #include <linux/if_link.h>
  #include <linux/firmware.h>
  #include <linux/mlx5/cq.h>
+ #include <linux/mlx5/fs.h>
  
  #define DRIVER_NAME "mlx5_core"
  #define DRIVER_VERSION "5.0-0"
@@@ -95,8 -96,6 +96,8 @@@ int mlx5_query_board_id(struct mlx5_cor
  int mlx5_cmd_init_hca(struct mlx5_core_dev *dev, uint32_t *sw_owner_id);
  int mlx5_cmd_teardown_hca(struct mlx5_core_dev *dev);
  int mlx5_cmd_force_teardown_hca(struct mlx5_core_dev *dev);
 +int mlx5_cmd_fast_teardown_hca(struct mlx5_core_dev *dev);
 +
  void mlx5_core_event(struct mlx5_core_dev *dev, enum mlx5_dev_event event,
                     unsigned long param);
  void mlx5_core_page_fault(struct mlx5_core_dev *dev,
@@@ -171,17 -170,6 +172,6 @@@ struct mlx5_core_dev *mlx5_get_next_phy
  void mlx5_dev_list_lock(void);
  void mlx5_dev_list_unlock(void);
  int mlx5_dev_list_trylock(void);
- int mlx5_encap_alloc(struct mlx5_core_dev *dev,
-                    int header_type,
-                    size_t size,
-                    void *encap_header,
-                    u32 *encap_id);
- void mlx5_encap_dealloc(struct mlx5_core_dev *dev, u32 encap_id);
- int mlx5_modify_header_alloc(struct mlx5_core_dev *dev,
-                            u8 namespace, u8 num_actions,
-                            void *modify_actions, u32 *modify_header_id);
- void mlx5_modify_header_dealloc(struct mlx5_core_dev *dev, u32 modify_header_id);
  
  bool mlx5_lag_intf_add(struct mlx5_interface *intf, struct mlx5_priv *priv);
  
@@@ -216,14 -204,4 +206,14 @@@ int mlx5_lag_allow(struct mlx5_core_de
  int mlx5_lag_forbid(struct mlx5_core_dev *dev);
  
  void mlx5_reload_interface(struct mlx5_core_dev *mdev, int protocol);
 +
 +enum {
 +      MLX5_NIC_IFC_FULL               = 0,
 +      MLX5_NIC_IFC_DISABLED           = 1,
 +      MLX5_NIC_IFC_NO_DRAM_NIC        = 2,
 +      MLX5_NIC_IFC_INVALID            = 3
 +};
 +
 +u8 mlx5_get_nic_state(struct mlx5_core_dev *dev);
 +void mlx5_set_nic_state(struct mlx5_core_dev *dev, u8 state);
  #endif /* __MLX5_CORE_H__ */
index 7e20666ce5aed9e6aead47554cc76a269816b1b9,5c519615fb1cd0f6ff9dbf6ba4facdfd4602263b..6a6fc9be01e69f77c49e7d22f2f065ba57eddb53
@@@ -73,7 -73,7 +73,7 @@@ static int get_pas_size(struct mlx5_srq
        u32 rq_sz         = 1 << (log_srq_size + 4 + log_rq_stride);
        u32 page_size     = 1 << log_page_size;
        u32 rq_sz_po      = rq_sz + (page_offset * po_quanta);
 -      u32 rq_num_pas    = (rq_sz_po + page_size - 1) / page_size;
 +      u32 rq_num_pas    = DIV_ROUND_UP(rq_sz_po, page_size);
  
        return rq_num_pas * sizeof(u64);
  }
@@@ -166,6 -166,7 +166,7 @@@ static int create_srq_cmd(struct mlx5_c
        if (!create_in)
                return -ENOMEM;
  
+       MLX5_SET(create_srq_in, create_in, uid, in->uid);
        srqc = MLX5_ADDR_OF(create_srq_in, create_in, srq_context_entry);
        pas = MLX5_ADDR_OF(create_srq_in, create_in, pas);
  
        err = mlx5_cmd_exec(dev, create_in, inlen, create_out,
                            sizeof(create_out));
        kvfree(create_in);
-       if (!err)
+       if (!err) {
                srq->srqn = MLX5_GET(create_srq_out, create_out, srqn);
+               srq->uid = in->uid;
+       }
  
        return err;
  }
@@@ -193,6 -196,7 +196,7 @@@ static int destroy_srq_cmd(struct mlx5_
        MLX5_SET(destroy_srq_in, srq_in, opcode,
                 MLX5_CMD_OP_DESTROY_SRQ);
        MLX5_SET(destroy_srq_in, srq_in, srqn, srq->srqn);
+       MLX5_SET(destroy_srq_in, srq_in, uid, srq->uid);
  
        return mlx5_cmd_exec(dev, srq_in, sizeof(srq_in),
                             srq_out, sizeof(srq_out));
@@@ -208,6 -212,7 +212,7 @@@ static int arm_srq_cmd(struct mlx5_core
        MLX5_SET(arm_rq_in, srq_in, op_mod, MLX5_ARM_RQ_IN_OP_MOD_SRQ);
        MLX5_SET(arm_rq_in, srq_in, srq_number, srq->srqn);
        MLX5_SET(arm_rq_in, srq_in, lwm,      lwm);
+       MLX5_SET(arm_rq_in, srq_in, uid, srq->uid);
  
        return  mlx5_cmd_exec(dev, srq_in, sizeof(srq_in),
                              srq_out, sizeof(srq_out));
@@@ -260,6 -265,7 +265,7 @@@ static int create_xrc_srq_cmd(struct ml
        if (!create_in)
                return -ENOMEM;
  
+       MLX5_SET(create_xrc_srq_in, create_in, uid, in->uid);
        xrc_srqc = MLX5_ADDR_OF(create_xrc_srq_in, create_in,
                                xrc_srq_context_entry);
        pas      = MLX5_ADDR_OF(create_xrc_srq_in, create_in, pas);
                goto out;
  
        srq->srqn = MLX5_GET(create_xrc_srq_out, create_out, xrc_srqn);
+       srq->uid = in->uid;
  out:
        kvfree(create_in);
        return err;
@@@ -291,6 -298,7 +298,7 @@@ static int destroy_xrc_srq_cmd(struct m
        MLX5_SET(destroy_xrc_srq_in, xrcsrq_in, opcode,
                 MLX5_CMD_OP_DESTROY_XRC_SRQ);
        MLX5_SET(destroy_xrc_srq_in, xrcsrq_in, xrc_srqn, srq->srqn);
+       MLX5_SET(destroy_xrc_srq_in, xrcsrq_in, uid, srq->uid);
  
        return mlx5_cmd_exec(dev, xrcsrq_in, sizeof(xrcsrq_in),
                             xrcsrq_out, sizeof(xrcsrq_out));
@@@ -306,6 -314,7 +314,7 @@@ static int arm_xrc_srq_cmd(struct mlx5_
        MLX5_SET(arm_xrc_srq_in, xrcsrq_in, op_mod,   MLX5_ARM_XRC_SRQ_IN_OP_MOD_XRC_SRQ);
        MLX5_SET(arm_xrc_srq_in, xrcsrq_in, xrc_srqn, srq->srqn);
        MLX5_SET(arm_xrc_srq_in, xrcsrq_in, lwm,      lwm);
+       MLX5_SET(arm_xrc_srq_in, xrcsrq_in, uid, srq->uid);
  
        return  mlx5_cmd_exec(dev, xrcsrq_in, sizeof(xrcsrq_in),
                              xrcsrq_out, sizeof(xrcsrq_out));
@@@ -365,10 -374,13 +374,13 @@@ static int create_rmp_cmd(struct mlx5_c
        wq = MLX5_ADDR_OF(rmpc, rmpc, wq);
  
        MLX5_SET(rmpc, rmpc, state, MLX5_RMPC_STATE_RDY);
+       MLX5_SET(create_rmp_in, create_in, uid, in->uid);
        set_wq(wq, in);
        memcpy(MLX5_ADDR_OF(rmpc, rmpc, wq.pas), in->pas, pas_size);
  
        err = mlx5_core_create_rmp(dev, create_in, inlen, &srq->srqn);
+       if (!err)
+               srq->uid = in->uid;
  
        kvfree(create_in);
        return err;
  static int destroy_rmp_cmd(struct mlx5_core_dev *dev,
                           struct mlx5_core_srq *srq)
  {
-       return mlx5_core_destroy_rmp(dev, srq->srqn);
+       u32 in[MLX5_ST_SZ_DW(destroy_rmp_in)]   = {};
+       u32 out[MLX5_ST_SZ_DW(destroy_rmp_out)] = {};
+       MLX5_SET(destroy_rmp_in, in, opcode, MLX5_CMD_OP_DESTROY_RMP);
+       MLX5_SET(destroy_rmp_in, in, rmpn, srq->srqn);
+       MLX5_SET(destroy_rmp_in, in, uid, srq->uid);
+       return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
  }
  
  static int arm_rmp_cmd(struct mlx5_core_dev *dev,
  
        MLX5_SET(modify_rmp_in, in,      rmp_state, MLX5_RMPC_STATE_RDY);
        MLX5_SET(modify_rmp_in, in,      rmpn,      srq->srqn);
+       MLX5_SET(modify_rmp_in, in, uid, srq->uid);
        MLX5_SET(wq,            wq,      lwm,       lwm);
        MLX5_SET(rmp_bitmask,   bitmask, lwm,       1);
        MLX5_SET(rmpc, rmpc, state, MLX5_RMPC_STATE_RDY);
@@@ -469,11 -488,14 +488,14 @@@ static int create_xrq_cmd(struct mlx5_c
        MLX5_SET(xrqc, xrqc, user_index, in->user_index);
        MLX5_SET(xrqc, xrqc, cqn, in->cqn);
        MLX5_SET(create_xrq_in, create_in, opcode, MLX5_CMD_OP_CREATE_XRQ);
+       MLX5_SET(create_xrq_in, create_in, uid, in->uid);
        err = mlx5_cmd_exec(dev, create_in, inlen, create_out,
                            sizeof(create_out));
        kvfree(create_in);
-       if (!err)
+       if (!err) {
                srq->srqn = MLX5_GET(create_xrq_out, create_out, xrqn);
+               srq->uid = in->uid;
+       }
  
        return err;
  }
@@@ -485,6 -507,7 +507,7 @@@ static int destroy_xrq_cmd(struct mlx5_
  
        MLX5_SET(destroy_xrq_in, in, opcode, MLX5_CMD_OP_DESTROY_XRQ);
        MLX5_SET(destroy_xrq_in, in, xrqn,   srq->srqn);
+       MLX5_SET(destroy_xrq_in, in, uid, srq->uid);
  
        return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
  }
@@@ -500,6 -523,7 +523,7 @@@ static int arm_xrq_cmd(struct mlx5_core
        MLX5_SET(arm_rq_in, in, op_mod,     MLX5_ARM_RQ_IN_OP_MOD_XRQ);
        MLX5_SET(arm_rq_in, in, srq_number, srq->srqn);
        MLX5_SET(arm_rq_in, in, lwm,        lwm);
+       MLX5_SET(arm_rq_in, in, uid, srq->uid);
  
        return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
  }
index e9b502d5bcc10f19abbb1f0c75d53884e79ad595,f2281e69ab398e549292f82329b0e642cb0608ff..b4c0457fbebd9b92ec74181dbd371a7e20833749
@@@ -504,10 -504,6 +504,10 @@@ struct health_buffer 
        __be16          ext_synd;
  };
  
 +enum mlx5_cmd_addr_l_sz_offset {
 +      MLX5_NIC_IFC_OFFSET = 8,
 +};
 +
  struct mlx5_init_seg {
        __be32                  fw_rev;
        __be32                  cmdif_rev_fw_sub;
@@@ -1124,6 -1120,12 +1124,12 @@@ enum mlx5_qcam_feature_groups 
  #define MLX5_CAP_FLOWTABLE_NIC_RX_MAX(mdev, cap) \
        MLX5_CAP_FLOWTABLE_MAX(mdev, flow_table_properties_nic_receive.cap)
  
+ #define MLX5_CAP_FLOWTABLE_NIC_TX(mdev, cap) \
+               MLX5_CAP_FLOWTABLE(mdev, flow_table_properties_nic_transmit.cap)
+ #define MLX5_CAP_FLOWTABLE_NIC_TX_MAX(mdev, cap) \
+       MLX5_CAP_FLOWTABLE_MAX(mdev, flow_table_properties_nic_transmit.cap)
  #define MLX5_CAP_FLOWTABLE_SNIFFER_RX(mdev, cap) \
        MLX5_CAP_FLOWTABLE(mdev, flow_table_properties_nic_receive_sniffer.cap)
  
index 4b75796cac23661cf8d766f8c18e14b8999fa3a9,8fb072aa8671d49581a1dce00bcbc306e32c6de8..94ffd02af7cdb0ee0773cac8734b82bbb7ca6206
@@@ -163,10 -163,7 +163,7 @@@ enum mlx5_dcbx_oper_mode 
  };
  
  enum mlx5_dct_atomic_mode {
-       MLX5_ATOMIC_MODE_DCT_OFF        = 20,
-       MLX5_ATOMIC_MODE_DCT_NONE       = 0 << MLX5_ATOMIC_MODE_DCT_OFF,
-       MLX5_ATOMIC_MODE_DCT_IB_COMP    = 1 << MLX5_ATOMIC_MODE_DCT_OFF,
-       MLX5_ATOMIC_MODE_DCT_CX         = 2 << MLX5_ATOMIC_MODE_DCT_OFF,
+       MLX5_ATOMIC_MODE_DCT_CX         = 2,
  };
  
  enum {
@@@ -362,8 -359,8 +359,8 @@@ struct mlx5_frag_buf 
  struct mlx5_frag_buf_ctrl {
        struct mlx5_frag_buf    frag_buf;
        u32                     sz_m1;
 -      u32                     frag_sz_m1;
 -      u32                     strides_offset;
 +      u16                     frag_sz_m1;
 +      u16                     strides_offset;
        u8                      log_sz;
        u8                      log_stride;
        u8                      log_frag_strides;
@@@ -477,6 -474,7 +474,7 @@@ struct mlx5_core_srq 
  
        atomic_t                refcount;
        struct completion       free;
+       u16             uid;
  };
  
  struct mlx5_eq_table {
@@@ -583,11 -581,10 +581,11 @@@ struct mlx5_irq_info 
  };
  
  struct mlx5_fc_stats {
 -      struct rb_root counters;
 -      struct list_head addlist;
 -      /* protect addlist add/splice operations */
 -      spinlock_t addlist_lock;
 +      spinlock_t counters_idr_lock; /* protects counters_idr */
 +      struct idr counters_idr;
 +      struct list_head counters;
 +      struct llist_head addlist;
 +      struct llist_head dellist;
  
        struct workqueue_struct *wq;
        struct delayed_work work;
@@@ -805,7 -802,7 +803,7 @@@ struct mlx5_pps 
  };
  
  struct mlx5_clock {
 -      rwlock_t                   lock;
 +      seqlock_t                  lock;
        struct cyclecounter        cycles;
        struct timecounter         tc;
        struct hwtstamp_config     hwtstamp_config;
@@@ -838,7 -835,6 +836,7 @@@ struct mlx5_core_dev 
                u32 fpga[MLX5_ST_SZ_DW(fpga_cap)];
                u32 qcam[MLX5_ST_SZ_DW(qcam_reg)];
        } caps;
 +      u64                     sys_image_guid;
        phys_addr_t             iseg_base;
        struct mlx5_init_seg __iomem *iseg;
        enum mlx5_device_state  state;
@@@ -997,7 -993,7 +995,7 @@@ static inline u32 mlx5_base_mkey(const 
  }
  
  static inline void mlx5_fill_fbc_offset(u8 log_stride, u8 log_sz,
 -                                      u32 strides_offset,
 +                                      u16 strides_offset,
                                        struct mlx5_frag_buf_ctrl *fbc)
  {
        fbc->log_stride = log_stride;
@@@ -1054,7 -1050,7 +1052,7 @@@ int mlx5_cmd_free_uar(struct mlx5_core_
  void mlx5_health_cleanup(struct mlx5_core_dev *dev);
  int mlx5_health_init(struct mlx5_core_dev *dev);
  void mlx5_start_health_poll(struct mlx5_core_dev *dev);
 -void mlx5_stop_health_poll(struct mlx5_core_dev *dev);
 +void mlx5_stop_health_poll(struct mlx5_core_dev *dev, bool disable_health);
  void mlx5_drain_health_wq(struct mlx5_core_dev *dev);
  void mlx5_trigger_health_work(struct mlx5_core_dev *dev);
  void mlx5_drain_health_recovery(struct mlx5_core_dev *dev);
@@@ -1228,15 -1224,21 +1226,15 @@@ int mlx5_lag_query_cong_counters(struc
  struct mlx5_uars_page *mlx5_get_uars_page(struct mlx5_core_dev *mdev);
  void mlx5_put_uars_page(struct mlx5_core_dev *mdev, struct mlx5_uars_page *up);
  
 -#ifndef CONFIG_MLX5_CORE_IPOIB
 -static inline
 -struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev,
 -                                        struct ib_device *ibdev,
 -                                        const char *name,
 -                                        void (*setup)(struct net_device *))
 -{
 -      return ERR_PTR(-EOPNOTSUPP);
 -}
 -#else
 +#ifdef CONFIG_MLX5_CORE_IPOIB
  struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev,
                                          struct ib_device *ibdev,
                                          const char *name,
                                          void (*setup)(struct net_device *));
  #endif /* CONFIG_MLX5_CORE_IPOIB */
 +int mlx5_rdma_rn_get_params(struct mlx5_core_dev *mdev,
 +                          struct ib_device *device,
 +                          struct rdma_netdev_alloc_params *params);
  
  struct mlx5_profile {
        u64     mask;
index 6e8a882052b1973ed845098179941e4e94a35732,0f460fb22c31bc67c8fc4453105e028f242e5797..15e36198f85fb74f442ab1ed0b57600763f08f68
@@@ -243,8 -243,8 +243,8 @@@ enum 
        MLX5_CMD_OP_DEALLOC_FLOW_COUNTER          = 0x93a,
        MLX5_CMD_OP_QUERY_FLOW_COUNTER            = 0x93b,
        MLX5_CMD_OP_MODIFY_FLOW_TABLE             = 0x93c,
-       MLX5_CMD_OP_ALLOC_ENCAP_HEADER            = 0x93d,
-       MLX5_CMD_OP_DEALLOC_ENCAP_HEADER          = 0x93e,
+       MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT = 0x93d,
+       MLX5_CMD_OP_DEALLOC_PACKET_REFORMAT_CONTEXT = 0x93e,
        MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT   = 0x940,
        MLX5_CMD_OP_DEALLOC_MODIFY_HEADER_CONTEXT = 0x941,
        MLX5_CMD_OP_QUERY_MODIFY_HEADER_CONTEXT   = 0x942,
@@@ -336,7 -336,7 +336,7 @@@ struct mlx5_ifc_flow_table_prop_layout_
        u8         modify_root[0x1];
        u8         identified_miss_table_mode[0x1];
        u8         flow_table_modify[0x1];
-       u8         encap[0x1];
+       u8         reformat[0x1];
        u8         decap[0x1];
        u8         reserved_at_9[0x1];
        u8         pop_vlan[0x1];
        u8         reserved_at_c[0x1];
        u8         pop_vlan_2[0x1];
        u8         push_vlan_2[0x1];
-       u8         reserved_at_f[0x11];
+       u8         reformat_and_vlan_action[0x1];
+       u8         reserved_at_10[0x2];
+       u8         reformat_l3_tunnel_to_l2[0x1];
+       u8         reformat_l2_to_l3_tunnel[0x1];
+       u8         reformat_and_modify_action[0x1];
+       u8         reserved_at_14[0xb];
        u8         reserved_at_20[0x2];
        u8         log_max_ft_size[0x6];
        u8         log_max_modify_header_context[0x8];
@@@ -554,7 -558,13 +558,13 @@@ struct mlx5_ifc_flow_table_nic_cap_bit
        u8         nic_rx_multi_path_tirs[0x1];
        u8         nic_rx_multi_path_tirs_fts[0x1];
        u8         allow_sniffer_and_nic_rx_shared_tir[0x1];
-       u8         reserved_at_3[0x1fd];
+       u8         reserved_at_3[0x1d];
+       u8         encap_general_header[0x1];
+       u8         reserved_at_21[0xa];
+       u8         log_max_packet_reformat_context[0x5];
+       u8         reserved_at_30[0x6];
+       u8         max_encap_header_size[0xa];
+       u8         reserved_at_40[0x1c0];
  
        struct mlx5_ifc_flow_table_prop_layout_bits flow_table_properties_nic_receive;
  
@@@ -599,7 -609,7 +609,7 @@@ struct mlx5_ifc_e_switch_cap_bits 
        u8         vxlan_encap_decap[0x1];
        u8         nvgre_encap_decap[0x1];
        u8         reserved_at_22[0x9];
-       u8         log_max_encap_headers[0x5];
+       u8         log_max_packet_reformat_context[0x5];
        u8         reserved_2b[0x6];
        u8         max_encap_header_size[0xa];
  
@@@ -896,8 -906,7 +906,8 @@@ struct mlx5_ifc_cmd_hca_cap_bits 
        u8         log_max_mkey[0x6];
        u8         reserved_at_f0[0x8];
        u8         dump_fill_mkey[0x1];
 -      u8         reserved_at_f9[0x3];
 +      u8         reserved_at_f9[0x2];
 +      u8         fast_teardown[0x1];
        u8         log_max_eq[0x4];
  
        u8         max_indirection[0x8];
        u8         umr_modify_atomic_disabled[0x1];
        u8         umr_indirect_mkey_disabled[0x1];
        u8         umr_fence[0x2];
-       u8         reserved_at_20c[0x3];
+       u8         dc_req_scat_data_cqe[0x1];
+       u8         reserved_at_20d[0x2];
        u8         drain_sigerr[0x1];
        u8         cmdif_checksum[0x2];
        u8         sigerr_cqe[0x1];
@@@ -1281,7 -1291,9 +1292,9 @@@ struct mlx5_ifc_wq_bits 
        u8         reserved_at_118[0x3];
        u8         log_wq_sz[0x5];
  
-       u8         reserved_at_120[0x3];
+       u8         dbr_umem_valid[0x1];
+       u8         wq_umem_valid[0x1];
+       u8         reserved_at_122[0x1];
        u8         log_hairpin_num_packets[0x5];
        u8         reserved_at_128[0x3];
        u8         log_hairpin_data_sz[0x5];
@@@ -2355,7 -2367,10 +2368,10 @@@ struct mlx5_ifc_qpc_bits 
  
        u8         dc_access_key[0x40];
  
-       u8         reserved_at_680[0xc0];
+       u8         reserved_at_680[0x3];
+       u8         dbr_umem_valid[0x1];
+       u8         reserved_at_684[0xbc];
  };
  
  struct mlx5_ifc_roce_addr_layout_bits {
@@@ -2395,7 -2410,7 +2411,7 @@@ enum 
        MLX5_FLOW_CONTEXT_ACTION_DROP      = 0x2,
        MLX5_FLOW_CONTEXT_ACTION_FWD_DEST  = 0x4,
        MLX5_FLOW_CONTEXT_ACTION_COUNT     = 0x8,
-       MLX5_FLOW_CONTEXT_ACTION_ENCAP     = 0x10,
+       MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT = 0x10,
        MLX5_FLOW_CONTEXT_ACTION_DECAP     = 0x20,
        MLX5_FLOW_CONTEXT_ACTION_MOD_HDR   = 0x40,
        MLX5_FLOW_CONTEXT_ACTION_VLAN_POP  = 0x80,
@@@ -2428,7 -2443,7 +2444,7 @@@ struct mlx5_ifc_flow_context_bits 
        u8         reserved_at_a0[0x8];
        u8         flow_counter_list_size[0x18];
  
-       u8         encap_id[0x20];
+       u8         packet_reformat_id[0x20];
  
        u8         modify_header_id[0x20];
  
@@@ -2455,7 -2470,7 +2471,7 @@@ struct mlx5_ifc_xrc_srqc_bits 
  
        u8         wq_signature[0x1];
        u8         cont_srq[0x1];
-       u8         reserved_at_22[0x1];
+       u8         dbr_umem_valid[0x1];
        u8         rlky[0x1];
        u8         basic_cyclic_rcv_wqe[0x1];
        u8         log_rq_stride[0x3];
@@@ -2550,8 -2565,8 +2566,8 @@@ enum 
  };
  
  enum {
-       MLX5_TIRC_SELF_LB_BLOCK_BLOCK_UNICAST_    = 0x1,
-       MLX5_TIRC_SELF_LB_BLOCK_BLOCK_MULTICAST_  = 0x2,
+       MLX5_TIRC_SELF_LB_BLOCK_BLOCK_UNICAST    = 0x1,
+       MLX5_TIRC_SELF_LB_BLOCK_BLOCK_MULTICAST  = 0x2,
  };
  
  struct mlx5_ifc_tirc_bits {
@@@ -3119,7 -3134,9 +3135,9 @@@ enum 
  
  struct mlx5_ifc_cqc_bits {
        u8         status[0x4];
-       u8         reserved_at_4[0x4];
+       u8         reserved_at_4[0x2];
+       u8         dbr_umem_valid[0x1];
+       u8         reserved_at_7[0x1];
        u8         cqe_sz[0x3];
        u8         cc[0x1];
        u8         reserved_at_c[0x1];
@@@ -3353,13 -3370,12 +3371,13 @@@ struct mlx5_ifc_teardown_hca_out_bits 
  
        u8         reserved_at_40[0x3f];
  
 -      u8         force_state[0x1];
 +      u8         state[0x1];
  };
  
  enum {
        MLX5_TEARDOWN_HCA_IN_PROFILE_GRACEFUL_CLOSE  = 0x0,
        MLX5_TEARDOWN_HCA_IN_PROFILE_FORCE_CLOSE     = 0x1,
 +      MLX5_TEARDOWN_HCA_IN_PROFILE_PREPARE_FAST_TEARDOWN = 0x2,
  };
  
  struct mlx5_ifc_teardown_hca_in_bits {
@@@ -3386,7 -3402,7 +3404,7 @@@ struct mlx5_ifc_sqerr2rts_qp_out_bits 
  
  struct mlx5_ifc_sqerr2rts_qp_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -3416,7 -3432,7 +3434,7 @@@ struct mlx5_ifc_sqd2rts_qp_out_bits 
  
  struct mlx5_ifc_sqd2rts_qp_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -3621,7 -3637,7 +3639,7 @@@ struct mlx5_ifc_rts2rts_qp_out_bits 
  
  struct mlx5_ifc_rts2rts_qp_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -3651,7 -3667,7 +3669,7 @@@ struct mlx5_ifc_rtr2rts_qp_out_bits 
  
  struct mlx5_ifc_rtr2rts_qp_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -3681,7 -3697,7 +3699,7 @@@ struct mlx5_ifc_rst2init_qp_out_bits 
  
  struct mlx5_ifc_rst2init_qp_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -4804,19 -4820,19 +4822,19 @@@ struct mlx5_ifc_query_eq_in_bits 
        u8         reserved_at_60[0x20];
  };
  
- struct mlx5_ifc_encap_header_in_bits {
+ struct mlx5_ifc_packet_reformat_context_in_bits {
        u8         reserved_at_0[0x5];
-       u8         header_type[0x3];
+       u8         reformat_type[0x3];
        u8         reserved_at_8[0xe];
-       u8         encap_header_size[0xa];
+       u8         reformat_data_size[0xa];
  
        u8         reserved_at_20[0x10];
-       u8         encap_header[2][0x8];
+       u8         reformat_data[2][0x8];
  
-       u8         more_encap_header[0][0x8];
+       u8         more_reformat_data[0][0x8];
  };
  
- struct mlx5_ifc_query_encap_header_out_bits {
+ struct mlx5_ifc_query_packet_reformat_context_out_bits {
        u8         status[0x8];
        u8         reserved_at_8[0x18];
  
  
        u8         reserved_at_40[0xa0];
  
-       struct mlx5_ifc_encap_header_in_bits encap_header[0];
+       struct mlx5_ifc_packet_reformat_context_in_bits packet_reformat_context[0];
  };
  
- struct mlx5_ifc_query_encap_header_in_bits {
+ struct mlx5_ifc_query_packet_reformat_context_in_bits {
        u8         opcode[0x10];
        u8         reserved_at_10[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
  
-       u8         encap_id[0x20];
+       u8         packet_reformat_id[0x20];
  
        u8         reserved_at_60[0xa0];
  };
  
- struct mlx5_ifc_alloc_encap_header_out_bits {
+ struct mlx5_ifc_alloc_packet_reformat_context_out_bits {
        u8         status[0x8];
        u8         reserved_at_8[0x18];
  
        u8         syndrome[0x20];
  
-       u8         encap_id[0x20];
+       u8         packet_reformat_id[0x20];
  
        u8         reserved_at_60[0x20];
  };
  
- struct mlx5_ifc_alloc_encap_header_in_bits {
+ enum {
+       MLX5_REFORMAT_TYPE_L2_TO_VXLAN = 0x0,
+       MLX5_REFORMAT_TYPE_L2_TO_NVGRE = 0x1,
+       MLX5_REFORMAT_TYPE_L2_TO_L2_TUNNEL = 0x2,
+       MLX5_REFORMAT_TYPE_L3_TUNNEL_TO_L2 = 0x3,
+       MLX5_REFORMAT_TYPE_L2_TO_L3_TUNNEL = 0x4,
+ };
+ struct mlx5_ifc_alloc_packet_reformat_context_in_bits {
        u8         opcode[0x10];
        u8         reserved_at_10[0x10];
  
  
        u8         reserved_at_40[0xa0];
  
-       struct mlx5_ifc_encap_header_in_bits encap_header;
+       struct mlx5_ifc_packet_reformat_context_in_bits packet_reformat_context;
  };
  
- struct mlx5_ifc_dealloc_encap_header_out_bits {
+ struct mlx5_ifc_dealloc_packet_reformat_context_out_bits {
        u8         status[0x8];
        u8         reserved_at_8[0x18];
  
        u8         reserved_at_40[0x40];
  };
  
- struct mlx5_ifc_dealloc_encap_header_in_bits {
+ struct mlx5_ifc_dealloc_packet_reformat_context_in_bits {
        u8         opcode[0x10];
        u8         reserved_at_10[0x10];
  
        u8         reserved_20[0x10];
        u8         op_mod[0x10];
  
-       u8         encap_id[0x20];
+       u8         packet_reformat_id[0x20];
  
        u8         reserved_60[0x20];
  };
@@@ -5176,7 -5200,7 +5202,7 @@@ struct mlx5_ifc_qp_2rst_out_bits 
  
  struct mlx5_ifc_qp_2rst_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -5198,7 -5222,7 +5224,7 @@@ struct mlx5_ifc_qp_2err_out_bits 
  
  struct mlx5_ifc_qp_2err_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -5298,7 -5322,7 +5324,7 @@@ struct mlx5_ifc_modify_tis_bitmask_bit
  
  struct mlx5_ifc_modify_tis_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -5337,7 -5361,7 +5363,7 @@@ struct mlx5_ifc_modify_tir_out_bits 
  
  struct mlx5_ifc_modify_tir_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -5365,7 -5389,7 +5391,7 @@@ struct mlx5_ifc_modify_sq_out_bits 
  
  struct mlx5_ifc_modify_sq_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -5438,7 -5462,7 +5464,7 @@@ struct mlx5_ifc_rqt_bitmask_bits 
  
  struct mlx5_ifc_modify_rqt_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -5472,7 -5496,7 +5498,7 @@@ enum 
  
  struct mlx5_ifc_modify_rq_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -5508,7 -5532,7 +5534,7 @@@ struct mlx5_ifc_rmp_bitmask_bits 
  
  struct mlx5_ifc_modify_rmp_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -5613,7 -5637,7 +5639,7 @@@ enum 
  
  struct mlx5_ifc_modify_cq_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
  
        struct mlx5_ifc_cqc_bits cq_context;
  
-       u8         reserved_at_280[0x600];
+       u8         reserved_at_280[0x40];
+       u8         cq_umem_valid[0x1];
+       u8         reserved_at_2c1[0x5bf];
  
        u8         pas[0][0x40];
  };
@@@ -5773,7 -5800,7 +5802,7 @@@ struct mlx5_ifc_init2rtr_qp_out_bits 
  
  struct mlx5_ifc_init2rtr_qp_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -5803,7 -5830,7 +5832,7 @@@ struct mlx5_ifc_init2init_qp_out_bits 
  
  struct mlx5_ifc_init2init_qp_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -5902,7 -5929,7 +5931,7 @@@ struct mlx5_ifc_drain_dct_out_bits 
  
  struct mlx5_ifc_drain_dct_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -5946,7 -5973,7 +5975,7 @@@ struct mlx5_ifc_detach_from_mcg_out_bit
  
  struct mlx5_ifc_detach_from_mcg_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -5970,7 -5997,7 +5999,7 @@@ struct mlx5_ifc_destroy_xrq_out_bits 
  
  struct mlx5_ifc_destroy_xrq_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -5992,7 -6019,7 +6021,7 @@@ struct mlx5_ifc_destroy_xrc_srq_out_bit
  
  struct mlx5_ifc_destroy_xrc_srq_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -6014,7 -6041,7 +6043,7 @@@ struct mlx5_ifc_destroy_tis_out_bits 
  
  struct mlx5_ifc_destroy_tis_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -6036,7 -6063,7 +6065,7 @@@ struct mlx5_ifc_destroy_tir_out_bits 
  
  struct mlx5_ifc_destroy_tir_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -6058,7 -6085,7 +6087,7 @@@ struct mlx5_ifc_destroy_srq_out_bits 
  
  struct mlx5_ifc_destroy_srq_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -6080,7 -6107,7 +6109,7 @@@ struct mlx5_ifc_destroy_sq_out_bits 
  
  struct mlx5_ifc_destroy_sq_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -6126,7 -6153,7 +6155,7 @@@ struct mlx5_ifc_destroy_rqt_out_bits 
  
  struct mlx5_ifc_destroy_rqt_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -6148,7 -6175,7 +6177,7 @@@ struct mlx5_ifc_destroy_rq_out_bits 
  
  struct mlx5_ifc_destroy_rq_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -6192,7 -6219,7 +6221,7 @@@ struct mlx5_ifc_destroy_rmp_out_bits 
  
  struct mlx5_ifc_destroy_rmp_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -6214,7 -6241,7 +6243,7 @@@ struct mlx5_ifc_destroy_qp_out_bits 
  
  struct mlx5_ifc_destroy_qp_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -6366,7 -6393,7 +6395,7 @@@ struct mlx5_ifc_destroy_dct_out_bits 
  
  struct mlx5_ifc_destroy_dct_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -6388,7 -6415,7 +6417,7 @@@ struct mlx5_ifc_destroy_cq_out_bits 
  
  struct mlx5_ifc_destroy_cq_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -6491,7 -6518,7 +6520,7 @@@ struct mlx5_ifc_dealloc_xrcd_out_bits 
  
  struct mlx5_ifc_dealloc_xrcd_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -6579,7 -6606,7 +6608,7 @@@ struct mlx5_ifc_dealloc_pd_out_bits 
  
  struct mlx5_ifc_dealloc_pd_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -6625,7 -6652,7 +6654,7 @@@ struct mlx5_ifc_create_xrq_out_bits 
  
  struct mlx5_ifc_create_xrq_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -6649,7 -6676,7 +6678,7 @@@ struct mlx5_ifc_create_xrc_srq_out_bit
  
  struct mlx5_ifc_create_xrc_srq_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
  
        struct mlx5_ifc_xrc_srqc_bits xrc_srq_context_entry;
  
-       u8         reserved_at_280[0x600];
+       u8         reserved_at_280[0x40];
+       u8         xrc_srq_umem_valid[0x1];
+       u8         reserved_at_2c1[0x5bf];
  
        u8         pas[0][0x40];
  };
@@@ -6677,7 -6706,7 +6708,7 @@@ struct mlx5_ifc_create_tis_out_bits 
  
  struct mlx5_ifc_create_tis_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -6701,7 -6730,7 +6732,7 @@@ struct mlx5_ifc_create_tir_out_bits 
  
  struct mlx5_ifc_create_tir_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -6725,7 -6754,7 +6756,7 @@@ struct mlx5_ifc_create_srq_out_bits 
  
  struct mlx5_ifc_create_srq_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -6753,7 -6782,7 +6784,7 @@@ struct mlx5_ifc_create_sq_out_bits 
  
  struct mlx5_ifc_create_sq_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -6807,7 -6836,7 +6838,7 @@@ struct mlx5_ifc_create_rqt_out_bits 
  
  struct mlx5_ifc_create_rqt_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -6831,7 -6860,7 +6862,7 @@@ struct mlx5_ifc_create_rq_out_bits 
  
  struct mlx5_ifc_create_rq_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -6855,7 -6884,7 +6886,7 @@@ struct mlx5_ifc_create_rmp_out_bits 
  
  struct mlx5_ifc_create_rmp_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -6879,7 -6908,7 +6910,7 @@@ struct mlx5_ifc_create_qp_out_bits 
  
  struct mlx5_ifc_create_qp_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
  
        struct mlx5_ifc_qpc_bits qpc;
  
-       u8         reserved_at_800[0x80];
+       u8         reserved_at_800[0x60];
+       u8         wq_umem_valid[0x1];
+       u8         reserved_at_861[0x1f];
  
        u8         pas[0][0x40];
  };
@@@ -6954,7 -6986,8 +6988,8 @@@ struct mlx5_ifc_create_mkey_in_bits 
        u8         reserved_at_40[0x20];
  
        u8         pg_access[0x1];
-       u8         reserved_at_61[0x1f];
+       u8         mkey_umem_valid[0x1];
+       u8         reserved_at_62[0x1e];
  
        struct mlx5_ifc_mkc_bits memory_key_mkey_entry;
  
@@@ -6980,7 -7013,7 +7015,7 @@@ struct mlx5_ifc_create_flow_table_out_b
  };
  
  struct mlx5_ifc_flow_table_context_bits {
-       u8         encap_en[0x1];
+       u8         reformat_en[0x1];
        u8         decap_en[0x1];
        u8         reserved_at_2[0x2];
        u8         table_miss_action[0x4];
@@@ -7122,7 -7155,7 +7157,7 @@@ struct mlx5_ifc_create_dct_out_bits 
  
  struct mlx5_ifc_create_dct_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -7148,7 -7181,7 +7183,7 @@@ struct mlx5_ifc_create_cq_out_bits 
  
  struct mlx5_ifc_create_cq_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
  
        struct mlx5_ifc_cqc_bits cq_context;
  
-       u8         reserved_at_280[0x600];
+       u8         reserved_at_280[0x60];
+       u8         cq_umem_valid[0x1];
+       u8         reserved_at_2e1[0x59f];
  
        u8         pas[0][0x40];
  };
@@@ -7205,7 -7241,7 +7243,7 @@@ struct mlx5_ifc_attach_to_mcg_out_bits 
  
  struct mlx5_ifc_attach_to_mcg_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -7256,7 -7292,7 +7294,7 @@@ enum 
  
  struct mlx5_ifc_arm_xrc_srq_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -7284,7 -7320,7 +7322,7 @@@ enum 
  
  struct mlx5_ifc_arm_rq_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -7332,7 -7368,7 +7370,7 @@@ struct mlx5_ifc_alloc_xrcd_out_bits 
  
  struct mlx5_ifc_alloc_xrcd_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];
@@@ -7420,7 -7456,7 +7458,7 @@@ struct mlx5_ifc_alloc_pd_out_bits 
  
  struct mlx5_ifc_alloc_pd_in_bits {
        u8         opcode[0x10];
-       u8         reserved_at_10[0x10];
+       u8         uid[0x10];
  
        u8         reserved_at_20[0x10];
        u8         op_mod[0x10];