]> Git Repo - linux.git/commitdiff
Merge tag 'for-linus-ioctl' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford...
authorLinus Torvalds <[email protected]>
Mon, 4 Sep 2017 00:49:17 +0000 (17:49 -0700)
committerLinus Torvalds <[email protected]>
Mon, 4 Sep 2017 00:49:17 +0000 (17:49 -0700)
Pull rdma updates from Doug Ledford:
 "This is a big pull request.

  Of note is that I'm sending you the new ioctl API for the rdma
  subsystem. We put it up on linux-api@, but didn't get much response.
  The API is complex, but it solves two different problems in one go:

   1) The bi-directional nature of the RDMA file write calls, which
      created the security hole we had to handle (and for which the fix
      is now causing problems for systems in production, we were a bit
      over zealous in the fix and the ability to open a device, then
      fork, then create new queue pairs on the device and use them is
      broken).

   2) The bloat caused by different vendors implementing extensions to
      the base verbs API. Each vendor's hardware is slightly different,
      and the hardware might be suitable for one extension but not
      another.

      By the time we add generic extensions for all the different ways
      that the different hardware can offload things, the API becomes
      bloated. Things like our completion structs have started to exceed
      a cache line in size because of all the elements needed to support
      this. That in turn shows up heavily in the performance graphs with
      a noticable drop in performance on 100Gigabit links as our
      completion structs go from occupying one cache line to 1+.

      This API makes things like the completion structs modular in a
      very similar way to netlink so that your structs can only include
      the items needed for the offloads/features you are actually using
      on a given queue pair. In that way we support everything, but only
      use what we need, and our structs stay smaller.

  The ioctl API is better explained by the posting on linux-api@ than I
  can explain it here, so I'll just leave it at that.

  The rest of the pull request is typical stuff.

  Updates for 4.14 kernel merge window

   - Lots of hfi1 driver updates (mixed with a few qib and core updates
     as well)

   - rxe updates

   - various mlx updates

   - Set default roce type to RoCEv2

   - Several larger fixes for bnxt_re that were too big for -rc

   - Several larger fixes for qedr that, likewise, were too big for -rc

   - Misc core changes

   - Make the hns_roce driver compilable on arches other than aarch64 so
     we can more easily debug build issues related to it

   - Add rdma-netlink infrastructure updates

   - Add automatic IRQ affinity infrastructure

   - Add 32bit lid support

   - Lots of misc fixes across the subsystem from random people

   - Autoloading of RDMA netlink modules

   - PCI pool cleanups from Romain Perier

   - mlx5 driver feature additions and fixes

   - Hardware tag matchine feature

   - Fix sleeping in atomic when resolving roce ah

   - Add experimental ioctl interface as posted to linux-api@"

* tag 'for-linus-ioctl' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma: (328 commits)
  IB/core: Expose ioctl interface through experimental Kconfig
  IB/core: Assign root to all drivers
  IB/core: Add completion queue (cq) object actions
  IB/core: Add legacy driver's user-data
  IB/core: Export ioctl enum types to user-space
  IB/core: Explicitly destroy an object while keeping uobject
  IB/core: Add macros for declaring methods and attributes
  IB/core: Add uverbs merge trees functionality
  IB/core: Add DEVICE object and root tree structure
  IB/core: Declare an object instead of declaring only type attributes
  IB/core: Add new ioctl interface
  RDMA/vmw_pvrdma: Fix a signedness
  RDMA/vmw_pvrdma: Report network header type in WC
  IB/core: Add might_sleep() annotation to ib_init_ah_from_wc()
  IB/cm: Fix sleeping in atomic when RoCE is used
  IB/core: Add support to finalize objects in one transaction
  IB/core: Add a generic way to execute an operation on a uobject
  Documentation: Hardware tag matching
  IB/mlx5: Support IB_SRQT_TM
  net/mlx5: Add XRQ support
  ...

17 files changed:
1  2 
drivers/infiniband/hw/hfi1/mmu_rb.c
drivers/net/ethernet/mellanox/mlx4/en_rx.c
drivers/net/ethernet/mellanox/mlx4/main.c
drivers/net/ethernet/mellanox/mlx5/core/cmd.c
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/mellanox/mlx5/core/eq.c
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
drivers/net/ethernet/mellanox/mlx5/core/main.c
drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
drivers/net/ethernet/mellanox/mlx5/core/sriov.c
drivers/net/ethernet/mellanox/mlx5/core/srq.c
drivers/nvme/host/rdma.c
include/linux/mlx4/device.h
include/linux/mlx5/driver.h
include/linux/mlx5/mlx5_ifc.h
include/linux/pci.h

index e4b56a0dd6d08ec7eb36dac1e303353f3b0095f7,13dcef08cac1de3dfb974d04238884c4dfaf2518..2f0d285dc27854ef5318000799908df046ba1dbd
@@@ -1,5 -1,5 +1,5 @@@
  /*
-  * Copyright(c) 2016 Intel Corporation.
+  * Copyright(c) 2016 - 2017 Intel Corporation.
   *
   * This file is provided under a dual BSD/GPLv2 license.  When using or
   * redistributing this file, you may do so under either license.
@@@ -67,6 -67,8 +67,6 @@@ struct mmu_rb_handler 
  
  static unsigned long mmu_node_start(struct mmu_rb_node *);
  static unsigned long mmu_node_last(struct mmu_rb_node *);
 -static inline void mmu_notifier_page(struct mmu_notifier *, struct mm_struct *,
 -                                   unsigned long);
  static inline void mmu_notifier_range_start(struct mmu_notifier *,
                                            struct mm_struct *,
                                            unsigned long, unsigned long);
@@@ -80,6 -82,7 +80,6 @@@ static void do_remove(struct mmu_rb_han
  static void handle_remove(struct work_struct *work);
  
  static const struct mmu_notifier_ops mn_opts = {
 -      .invalidate_page = mmu_notifier_page,
        .invalidate_range_start = mmu_notifier_range_start,
  };
  
@@@ -169,9 -172,8 +169,8 @@@ int hfi1_mmu_rb_insert(struct mmu_rb_ha
        unsigned long flags;
        int ret = 0;
  
+       trace_hfi1_mmu_rb_insert(mnode->addr, mnode->len);
        spin_lock_irqsave(&handler->lock, flags);
-       hfi1_cdbg(MMU, "Inserting node addr 0x%llx, len %u", mnode->addr,
-                 mnode->len);
        node = __mmu_rb_search(handler, mnode->addr, mnode->len);
        if (node) {
                ret = -EINVAL;
@@@ -197,7 -199,7 +196,7 @@@ static struct mmu_rb_node *__mmu_rb_sea
  {
        struct mmu_rb_node *node = NULL;
  
-       hfi1_cdbg(MMU, "Searching for addr 0x%llx, len %u", addr, len);
+       trace_hfi1_mmu_rb_search(addr, len);
        if (!handler->ops->filter) {
                node = __mmu_int_rb_iter_first(&handler->root, addr,
                                               (addr + len) - 1);
        return node;
  }
  
- struct mmu_rb_node *hfi1_mmu_rb_extract(struct mmu_rb_handler *handler,
-                                       unsigned long addr, unsigned long len)
+ bool hfi1_mmu_rb_remove_unless_exact(struct mmu_rb_handler *handler,
+                                    unsigned long addr, unsigned long len,
+                                    struct mmu_rb_node **rb_node)
  {
        struct mmu_rb_node *node;
        unsigned long flags;
+       bool ret = false;
  
        spin_lock_irqsave(&handler->lock, flags);
        node = __mmu_rb_search(handler, addr, len);
        if (node) {
+               if (node->addr == addr && node->len == len)
+                       goto unlock;
                __mmu_int_rb_remove(node, &handler->root);
                list_del(&node->list); /* remove from LRU list */
+               ret = true;
        }
+ unlock:
        spin_unlock_irqrestore(&handler->lock, flags);
-       return node;
+       *rb_node = node;
+       return ret;
  }
  
  void hfi1_mmu_rb_evict(struct mmu_rb_handler *handler, void *evict_arg)
@@@ -272,8 -280,7 +277,7 @@@ void hfi1_mmu_rb_remove(struct mmu_rb_h
        unsigned long flags;
  
        /* Validity of handler and node pointers has been checked by caller. */
-       hfi1_cdbg(MMU, "Removing node addr 0x%llx, len %u", node->addr,
-                 node->len);
+       trace_hfi1_mmu_rb_remove(node->addr, node->len);
        spin_lock_irqsave(&handler->lock, flags);
        __mmu_int_rb_remove(node, &handler->root);
        list_del(&node->list); /* remove from LRU list */
        handler->ops->remove(handler->ops_arg, node);
  }
  
 -static inline void mmu_notifier_page(struct mmu_notifier *mn,
 -                                   struct mm_struct *mm, unsigned long addr)
 -{
 -      mmu_notifier_mem_invalidate(mn, mm, addr, addr + PAGE_SIZE);
 -}
 -
  static inline void mmu_notifier_range_start(struct mmu_notifier *mn,
                                            struct mm_struct *mm,
                                            unsigned long start,
@@@ -306,8 -319,7 +310,7 @@@ static void mmu_notifier_mem_invalidate
             node; node = ptr) {
                /* Guard against node removal. */
                ptr = __mmu_int_rb_iter_next(node, start, end - 1);
-               hfi1_cdbg(MMU, "Invalidating node addr 0x%llx, len %u",
-                         node->addr, node->len);
+               trace_hfi1_mmu_mem_invalidate(node->addr, node->len);
                if (handler->ops->invalidate(handler->ops_arg, node)) {
                        __mmu_int_rb_remove(node, root);
                        /* move from LRU list to delete list */
index bf1638044a7a89b6e911b3f5786c75597f89f2ba,ad1ffd5857cbb53091646bfcde21a056ed0b7887..ec24c4057be696069dc1982c2a2ac5fe4f66659c
@@@ -574,21 -574,16 +574,21 @@@ static inline __wsum get_fixed_vlan_csu
   * header, the HW adds it. To address that, we are subtracting the pseudo
   * header checksum from the checksum value provided by the HW.
   */
 -static void get_fixed_ipv4_csum(__wsum hw_checksum, struct sk_buff *skb,
 -                              struct iphdr *iph)
 +static int get_fixed_ipv4_csum(__wsum hw_checksum, struct sk_buff *skb,
 +                             struct iphdr *iph)
  {
        __u16 length_for_csum = 0;
        __wsum csum_pseudo_header = 0;
 +      __u8 ipproto = iph->protocol;
 +
 +      if (unlikely(ipproto == IPPROTO_SCTP))
 +              return -1;
  
        length_for_csum = (be16_to_cpu(iph->tot_len) - (iph->ihl << 2));
        csum_pseudo_header = csum_tcpudp_nofold(iph->saddr, iph->daddr,
 -                                              length_for_csum, iph->protocol, 0);
 +                                              length_for_csum, ipproto, 0);
        skb->csum = csum_sub(hw_checksum, csum_pseudo_header);
 +      return 0;
  }
  
  #if IS_ENABLED(CONFIG_IPV6)
  static int get_fixed_ipv6_csum(__wsum hw_checksum, struct sk_buff *skb,
                               struct ipv6hdr *ipv6h)
  {
 +      __u8 nexthdr = ipv6h->nexthdr;
        __wsum csum_pseudo_hdr = 0;
  
 -      if (unlikely(ipv6h->nexthdr == IPPROTO_FRAGMENT ||
 -                   ipv6h->nexthdr == IPPROTO_HOPOPTS))
 +      if (unlikely(nexthdr == IPPROTO_FRAGMENT ||
 +                   nexthdr == IPPROTO_HOPOPTS ||
 +                   nexthdr == IPPROTO_SCTP))
                return -1;
 -      hw_checksum = csum_add(hw_checksum, (__force __wsum)htons(ipv6h->nexthdr));
 +      hw_checksum = csum_add(hw_checksum, (__force __wsum)htons(nexthdr));
  
        csum_pseudo_hdr = csum_partial(&ipv6h->saddr,
                                       sizeof(ipv6h->saddr) + sizeof(ipv6h->daddr), 0);
        csum_pseudo_hdr = csum_add(csum_pseudo_hdr, (__force __wsum)ipv6h->payload_len);
 -      csum_pseudo_hdr = csum_add(csum_pseudo_hdr, (__force __wsum)ntohs(ipv6h->nexthdr));
 +      csum_pseudo_hdr = csum_add(csum_pseudo_hdr,
 +                                 (__force __wsum)htons(nexthdr));
  
        skb->csum = csum_sub(hw_checksum, csum_pseudo_hdr);
        skb->csum = csum_add(skb->csum, csum_partial(ipv6h, sizeof(struct ipv6hdr), 0));
@@@ -635,10 -627,11 +635,10 @@@ static int check_csum(struct mlx4_cqe *
        }
  
        if (cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IPV4))
 -              get_fixed_ipv4_csum(hw_checksum, skb, hdr);
 +              return get_fixed_ipv4_csum(hw_checksum, skb, hdr);
  #if IS_ENABLED(CONFIG_IPV6)
 -      else if (cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IPV6))
 -              if (unlikely(get_fixed_ipv6_csum(hw_checksum, skb, hdr)))
 -                      return -1;
 +      if (cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IPV6))
 +              return get_fixed_ipv6_csum(hw_checksum, skb, hdr);
  #endif
        return 0;
  }
@@@ -1088,7 -1081,8 +1088,8 @@@ int mlx4_en_create_drop_qp(struct mlx4_
        u32 qpn;
  
        err = mlx4_qp_reserve_range(priv->mdev->dev, 1, 1, &qpn,
-                                   MLX4_RESERVE_A0_QP);
+                                   MLX4_RESERVE_A0_QP,
+                                   MLX4_RES_USAGE_DRIVER);
        if (err) {
                en_err(priv, "Failed reserving drop qpn\n");
                return err;
@@@ -1134,7 -1128,8 +1135,8 @@@ int mlx4_en_config_rss_steer(struct mlx
        flags = priv->rx_ring_num == 1 ? MLX4_RESERVE_A0_QP : 0;
        err = mlx4_qp_reserve_range(mdev->dev, priv->rx_ring_num,
                                    priv->rx_ring_num,
-                                   &rss_map->base_qpn, flags);
+                                   &rss_map->base_qpn, flags,
+                                   MLX4_RES_USAGE_DRIVER);
        if (err) {
                en_err(priv, "Failed reserving %d qps\n", priv->rx_ring_num);
                return err;
index 5fe5cdc5135776abb8fd4df748b0948520504b48,fb2591d0e7352a4599aa5be2f3fa44abc6e6a4e0..a594bfd9e09525ddb42f78e1adfa04cedf5183fe
@@@ -424,15 -424,13 +424,15 @@@ static int mlx4_dev_cap(struct mlx4_de
        dev->caps.stat_rate_support  = dev_cap->stat_rate_support;
        dev->caps.max_gso_sz         = dev_cap->max_gso_sz;
        dev->caps.max_rss_tbl_sz     = dev_cap->max_rss_tbl_sz;
 +      dev->caps.wol_port[1]          = dev_cap->wol_port[1];
 +      dev->caps.wol_port[2]          = dev_cap->wol_port[2];
  
        /* Save uar page shift */
        if (!mlx4_is_slave(dev)) {
                /* Virtual PCI function needs to determine UAR page size from
                 * firmware. Only master PCI function can set the uar page size
                 */
 -              if (enable_4k_uar)
 +              if (enable_4k_uar || !dev->persist->num_vfs)
                        dev->uar_page_shift = DEFAULT_UAR_PAGE_SHIFT;
                else
                        dev->uar_page_shift = PAGE_SHIFT;
@@@ -2277,7 -2275,7 +2277,7 @@@ static int mlx4_init_hca(struct mlx4_de
  
                dev->caps.max_fmr_maps = (1 << (32 - ilog2(dev->caps.num_mpts))) - 1;
  
 -              if (enable_4k_uar) {
 +              if (enable_4k_uar || !dev->persist->num_vfs) {
                        init_hca.log_uar_sz = ilog2(dev->caps.num_uars) +
                                                    PAGE_SHIFT - DEFAULT_UAR_PAGE_SHIFT;
                        init_hca.uar_page_sz = DEFAULT_UAR_PAGE_SHIFT - 12;
@@@ -2477,7 -2475,7 +2477,7 @@@ static int mlx4_allocate_default_counte
                priv->def_counter[port] = -1;
  
        for (port = 0; port < dev->caps.num_ports; port++) {
-               err = mlx4_counter_alloc(dev, &idx);
+               err = mlx4_counter_alloc(dev, &idx, MLX4_RES_USAGE_DRIVER);
  
                if (!err || err == -ENOSPC) {
                        priv->def_counter[port] = idx;
@@@ -2519,13 -2517,14 +2519,14 @@@ int __mlx4_counter_alloc(struct mlx4_de
        return 0;
  }
  
- int mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx)
+ int mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx, u8 usage)
  {
+       u32 in_modifier = RES_COUNTER | (((u32)usage & 3) << 30);
        u64 out_param;
        int err;
  
        if (mlx4_is_mfunc(dev)) {
-               err = mlx4_cmd_imm(dev, 0, &out_param, RES_COUNTER,
+               err = mlx4_cmd_imm(dev, 0, &out_param, in_modifier,
                                   RES_OP_RESERVE, MLX4_CMD_ALLOC_RES,
                                   MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
                if (!err)
index 31cbe5e86a01300bacd92db829d9ddc186e5db7a,7a40e8790f7558a6dca08f7432095c9c0ed743b4..1acbb721f38db3f54fa1b365b3cf146943d2691a
@@@ -786,10 -786,6 +786,10 @@@ static void cb_timeout_handler(struct w
        mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true);
  }
  
 +static void free_msg(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *msg);
 +static void mlx5_free_cmd_msg(struct mlx5_core_dev *dev,
 +                            struct mlx5_cmd_msg *msg);
 +
  static void cmd_work_handler(struct work_struct *work)
  {
        struct mlx5_cmd_work_ent *ent = container_of(work, struct mlx5_cmd_work_ent, work);
        struct semaphore *sem;
        unsigned long flags;
        bool poll_cmd = ent->polling;
 +      int alloc_ret;
  
  
        sem = ent->page_queue ? &cmd->pages_sem : &cmd->sem;
        down(sem);
        if (!ent->page_queue) {
 -              ent->idx = alloc_ent(cmd);
 -              if (ent->idx < 0) {
 +              alloc_ret = alloc_ent(cmd);
 +              if (alloc_ret < 0) {
                        mlx5_core_err(dev, "failed to allocate command entry\n");
 +                      if (ent->callback) {
 +                              ent->callback(-EAGAIN, ent->context);
 +                              mlx5_free_cmd_msg(dev, ent->out);
 +                              free_msg(dev, ent->in);
 +                              free_cmd(ent);
 +                      } else {
 +                              ent->ret = -EAGAIN;
 +                              complete(&ent->done);
 +                      }
                        up(sem);
                        return;
                }
 +              ent->idx = alloc_ret;
        } else {
                ent->idx = cmd->max_reg_cmds;
                spin_lock_irqsave(&cmd->alloc_lock, flags);
@@@ -982,7 -967,7 +982,7 @@@ static int mlx5_cmd_invoke(struct mlx5_
  
        err = wait_func(dev, ent);
        if (err == -ETIMEDOUT)
 -              goto out_free;
 +              goto out;
  
        ds = ent->ts2 - ent->ts1;
        op = MLX5_GET(mbox_in, in->first.data, opcode);
@@@ -1110,7 -1095,7 +1110,7 @@@ static struct mlx5_cmd_mailbox *alloc_c
        if (!mailbox)
                return ERR_PTR(-ENOMEM);
  
-       mailbox->buf = pci_pool_zalloc(dev->cmd.pool, flags,
+       mailbox->buf = dma_pool_zalloc(dev->cmd.pool, flags,
                                       &mailbox->dma);
        if (!mailbox->buf) {
                mlx5_core_dbg(dev, "failed allocation\n");
  static void free_cmd_box(struct mlx5_core_dev *dev,
                         struct mlx5_cmd_mailbox *mailbox)
  {
-       pci_pool_free(dev->cmd.pool, mailbox->buf, mailbox->dma);
+       dma_pool_free(dev->cmd.pool, mailbox->buf, mailbox->dma);
        kfree(mailbox);
  }
  
@@@ -1445,7 -1430,6 +1445,7 @@@ void mlx5_cmd_comp_handler(struct mlx5_
                                        mlx5_core_err(dev, "Command completion arrived after timeout (entry idx = %d).\n",
                                                      ent->idx);
                                        free_ent(cmd, ent->idx);
 +                                      free_cmd(ent);
                                }
                                continue;
                        }
                                free_msg(dev, ent->in);
  
                                err = err ? err : ent->status;
 -                              free_cmd(ent);
 +                              if (!forced)
 +                                      free_cmd(ent);
                                callback(err, context);
                        } else {
                                complete(&ent->done);
@@@ -1776,7 -1759,8 +1776,8 @@@ int mlx5_cmd_init(struct mlx5_core_dev 
                return -EINVAL;
        }
  
-       cmd->pool = pci_pool_create("mlx5_cmd", dev->pdev, size, align, 0);
+       cmd->pool = dma_pool_create("mlx5_cmd", &dev->pdev->dev, size, align,
+                                   0);
        if (!cmd->pool)
                return -ENOMEM;
  
@@@ -1866,7 -1850,7 +1867,7 @@@ err_free_page
        free_cmd_page(dev, cmd);
  
  err_free_pool:
-       pci_pool_destroy(cmd->pool);
+       dma_pool_destroy(cmd->pool);
  
        return err;
  }
@@@ -1880,6 -1864,6 +1881,6 @@@ void mlx5_cmd_cleanup(struct mlx5_core_
        destroy_workqueue(cmd->wq);
        destroy_msg_cache(dev);
        free_cmd_page(dev, cmd);
-       pci_pool_destroy(cmd->pool);
+       dma_pool_destroy(cmd->pool);
  }
  EXPORT_SYMBOL(mlx5_cmd_cleanup);
index 2f26fb34d7416b88ee8bf7a3464e40837ab90c3c,909123243a85fc1fc7456e680798d6a9aea77bd7..040d1af310b4af8dd1d8629378a01d9d46cfae69
@@@ -263,18 -263,9 +263,18 @@@ struct mlx5e_dcbx 
  
        /* The only setting that cannot be read from FW */
        u8                         tc_tsa[IEEE_8021QAZ_MAX_TCS];
 +      u8                         cap;
  };
  #endif
  
 +#define MAX_PIN_NUM   8
 +struct mlx5e_pps {
 +      u8                         pin_caps[MAX_PIN_NUM];
 +      struct work_struct         out_work;
 +      u64                        start[MAX_PIN_NUM];
 +      u8                         enabled;
 +};
 +
  struct mlx5e_tstamp {
        rwlock_t                   lock;
        struct cyclecounter        cycles;
        struct mlx5_core_dev      *mdev;
        struct ptp_clock          *ptp;
        struct ptp_clock_info      ptp_info;
 -      u8                        *pps_pin_caps;
 +      struct mlx5e_pps           pps_info;
  };
  
  enum {
@@@ -596,7 -587,6 +596,6 @@@ struct mlx5e_channel 
        struct mlx5_core_dev      *mdev;
        struct mlx5e_tstamp       *tstamp;
        int                        ix;
-       int                        cpu;
  };
  
  struct mlx5e_channels {
index 6ad7f07e7861d9c8d6922b0c115fc950e0126dfc,fb647561c5924b771a5befba43881023a8105614..d75f3099d1643d815db2a11f00f8278d275faeff
@@@ -71,6 -71,11 +71,11 @@@ struct mlx5e_channel_param 
        struct mlx5e_cq_param      icosq_cq;
  };
  
+ static int mlx5e_get_node(struct mlx5e_priv *priv, int ix)
+ {
+       return pci_irq_get_node(priv->mdev->pdev, MLX5_EQ_VEC_COMP_BASE + ix);
+ }
  static bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev)
  {
        return MLX5_CAP_GEN(mdev, striding_rq) &&
@@@ -377,6 -382,7 +382,6 @@@ static void mlx5e_async_event(struct ml
                break;
        case MLX5_DEV_EVENT_PPS:
                eqe = (struct mlx5_eqe *)param;
 -              ptp_event.type = PTP_CLOCK_EXTTS;
                ptp_event.index = eqe->data.pps.pin;
                ptp_event.timestamp =
                        timecounter_cyc2time(&priv->tstamp.clock,
@@@ -396,7 -402,7 +401,7 @@@ static void mlx5e_enable_async_events(s
  static void mlx5e_disable_async_events(struct mlx5e_priv *priv)
  {
        clear_bit(MLX5E_STATE_ASYNC_EVENTS_ENABLED, &priv->state);
-       synchronize_irq(mlx5_get_msix_vec(priv->mdev, MLX5_EQ_VEC_ASYNC));
+       synchronize_irq(pci_irq_vector(priv->mdev->pdev, MLX5_EQ_VEC_ASYNC));
  }
  
  static inline int mlx5e_get_wqe_mtt_sz(void)
@@@ -443,16 -449,17 +448,17 @@@ static int mlx5e_rq_alloc_mpwqe_info(st
        int wq_sz = mlx5_wq_ll_get_size(&rq->wq);
        int mtt_sz = mlx5e_get_wqe_mtt_sz();
        int mtt_alloc = mtt_sz + MLX5_UMR_ALIGN - 1;
+       int node = mlx5e_get_node(c->priv, c->ix);
        int i;
  
        rq->mpwqe.info = kzalloc_node(wq_sz * sizeof(*rq->mpwqe.info),
-                                     GFP_KERNEL, cpu_to_node(c->cpu));
+                                       GFP_KERNEL, node);
        if (!rq->mpwqe.info)
                goto err_out;
  
        /* We allocate more than mtt_sz as we will align the pointer */
-       rq->mpwqe.mtt_no_align = kzalloc_node(mtt_alloc * wq_sz, GFP_KERNEL,
-                                       cpu_to_node(c->cpu));
+       rq->mpwqe.mtt_no_align = kzalloc_node(mtt_alloc * wq_sz,
+                                       GFP_KERNEL, node);
        if (unlikely(!rq->mpwqe.mtt_no_align))
                goto err_free_wqe_info;
  
@@@ -560,7 -567,7 +566,7 @@@ static int mlx5e_alloc_rq(struct mlx5e_
        int err;
        int i;
  
-       rqp->wq.db_numa_node = cpu_to_node(c->cpu);
+       rqp->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix);
  
        err = mlx5_wq_ll_create(mdev, &rqp->wq, rqc_wq, &rq->wq,
                                &rq->wq_ctrl);
        default: /* MLX5_WQ_TYPE_LINKED_LIST */
                rq->wqe.frag_info =
                        kzalloc_node(wq_sz * sizeof(*rq->wqe.frag_info),
-                                    GFP_KERNEL, cpu_to_node(c->cpu));
+                                    GFP_KERNEL,
+                                    mlx5e_get_node(c->priv, c->ix));
                if (!rq->wqe.frag_info) {
                        err = -ENOMEM;
                        goto err_rq_wq_destroy;
@@@ -992,13 -1000,13 +999,13 @@@ static int mlx5e_alloc_xdpsq(struct mlx
        sq->uar_map   = mdev->mlx5e_res.bfreg.map;
        sq->min_inline_mode = params->tx_min_inline_mode;
  
-       param->wq.db_numa_node = cpu_to_node(c->cpu);
+       param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix);
        err = mlx5_wq_cyc_create(mdev, &param->wq, sqc_wq, &sq->wq, &sq->wq_ctrl);
        if (err)
                return err;
        sq->wq.db = &sq->wq.db[MLX5_SND_DBR];
  
-       err = mlx5e_alloc_xdpsq_db(sq, cpu_to_node(c->cpu));
+       err = mlx5e_alloc_xdpsq_db(sq, mlx5e_get_node(c->priv, c->ix));
        if (err)
                goto err_sq_wq_destroy;
  
@@@ -1046,13 -1054,13 +1053,13 @@@ static int mlx5e_alloc_icosq(struct mlx
        sq->channel   = c;
        sq->uar_map   = mdev->mlx5e_res.bfreg.map;
  
-       param->wq.db_numa_node = cpu_to_node(c->cpu);
+       param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix);
        err = mlx5_wq_cyc_create(mdev, &param->wq, sqc_wq, &sq->wq, &sq->wq_ctrl);
        if (err)
                return err;
        sq->wq.db = &sq->wq.db[MLX5_SND_DBR];
  
-       err = mlx5e_alloc_icosq_db(sq, cpu_to_node(c->cpu));
+       err = mlx5e_alloc_icosq_db(sq, mlx5e_get_node(c->priv, c->ix));
        if (err)
                goto err_sq_wq_destroy;
  
@@@ -1118,13 -1126,13 +1125,13 @@@ static int mlx5e_alloc_txqsq(struct mlx
        if (MLX5_IPSEC_DEV(c->priv->mdev))
                set_bit(MLX5E_SQ_STATE_IPSEC, &sq->state);
  
-       param->wq.db_numa_node = cpu_to_node(c->cpu);
+       param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix);
        err = mlx5_wq_cyc_create(mdev, &param->wq, sqc_wq, &sq->wq, &sq->wq_ctrl);
        if (err)
                return err;
        sq->wq.db    = &sq->wq.db[MLX5_SND_DBR];
  
-       err = mlx5e_alloc_txqsq_db(sq, cpu_to_node(c->cpu));
+       err = mlx5e_alloc_txqsq_db(sq, mlx5e_get_node(c->priv, c->ix));
        if (err)
                goto err_sq_wq_destroy;
  
@@@ -1496,8 -1504,8 +1503,8 @@@ static int mlx5e_alloc_cq(struct mlx5e_
        struct mlx5_core_dev *mdev = c->priv->mdev;
        int err;
  
-       param->wq.buf_numa_node = cpu_to_node(c->cpu);
-       param->wq.db_numa_node  = cpu_to_node(c->cpu);
+       param->wq.buf_numa_node = mlx5e_get_node(c->priv, c->ix);
+       param->wq.db_numa_node  = mlx5e_get_node(c->priv, c->ix);
        param->eq_ix   = c->ix;
  
        err = mlx5e_alloc_cq_common(mdev, param, cq);
@@@ -1596,11 -1604,6 +1603,6 @@@ static void mlx5e_close_cq(struct mlx5e
        mlx5e_free_cq(cq);
  }
  
- static int mlx5e_get_cpu(struct mlx5e_priv *priv, int ix)
- {
-       return cpumask_first(priv->mdev->priv.irq_info[ix].mask);
- }
  static int mlx5e_open_tx_cqs(struct mlx5e_channel *c,
                             struct mlx5e_params *params,
                             struct mlx5e_channel_param *cparam)
@@@ -1749,11 -1752,10 +1751,10 @@@ static int mlx5e_open_channel(struct ml
  {
        struct mlx5e_cq_moder icocq_moder = {0, 0};
        struct net_device *netdev = priv->netdev;
-       int cpu = mlx5e_get_cpu(priv, ix);
        struct mlx5e_channel *c;
        int err;
  
-       c = kzalloc_node(sizeof(*c), GFP_KERNEL, cpu_to_node(cpu));
+       c = kzalloc_node(sizeof(*c), GFP_KERNEL, mlx5e_get_node(priv, ix));
        if (!c)
                return -ENOMEM;
  
        c->mdev     = priv->mdev;
        c->tstamp   = &priv->tstamp;
        c->ix       = ix;
-       c->cpu      = cpu;
        c->pdev     = &priv->mdev->pdev->dev;
        c->netdev   = priv->netdev;
        c->mkey_be  = cpu_to_be32(priv->mdev->mlx5e_res.mkey.key);
@@@ -1847,7 -1848,8 +1847,8 @@@ static void mlx5e_activate_channel(stru
        for (tc = 0; tc < c->num_tc; tc++)
                mlx5e_activate_txqsq(&c->sq[tc]);
        mlx5e_activate_rq(&c->rq);
-       netif_set_xps_queue(c->netdev, get_cpu_mask(c->cpu), c->ix);
+       netif_set_xps_queue(c->netdev,
+               mlx5_get_vector_affinity(c->priv->mdev, c->ix), c->ix);
  }
  
  static void mlx5e_deactivate_channel(struct mlx5e_channel *c)
@@@ -1969,7 -1971,6 +1970,7 @@@ static void mlx5e_build_rx_cq_param(str
        }
  
        mlx5e_build_common_cq_param(priv, param);
 +      param->cq_period_mode = params->rx_cq_period_mode;
  }
  
  static void mlx5e_build_tx_cq_param(struct mlx5e_priv *priv,
@@@ -3793,18 -3794,8 +3794,8 @@@ void mlx5e_build_default_indir_rqt(stru
                                   u32 *indirection_rqt, int len,
                                   int num_channels)
  {
-       int node = mdev->priv.numa_node;
-       int node_num_of_cores;
        int i;
  
-       if (node == -1)
-               node = first_online_node;
-       node_num_of_cores = cpumask_weight(cpumask_of_node(node));
-       if (node_num_of_cores)
-               num_channels = min_t(int, num_channels, node_num_of_cores);
        for (i = 0; i < len; i++)
                indirection_rqt[i] = i % num_channels;
  }
index 52b9a64cd3a20be3eb8a8e5beb1990d583d2db93,261b3c628767e4ec77a07b0c8b1f6103d82e068a..edd11ebd392edcc83ef79efd8fb0811e0cfba0e8
@@@ -161,6 -161,8 +161,8 @@@ static const char *eqe_type_str(u8 type
                return "MLX5_EVENT_TYPE_NIC_VPORT_CHANGE";
        case MLX5_EVENT_TYPE_FPGA_ERROR:
                return "MLX5_EVENT_TYPE_FPGA_ERROR";
+       case MLX5_EVENT_TYPE_GENERAL_EVENT:
+               return "MLX5_EVENT_TYPE_GENERAL_EVENT";
        default:
                return "Unrecognized event";
        }
@@@ -378,6 -380,20 +380,20 @@@ int mlx5_core_page_fault_resume(struct 
  EXPORT_SYMBOL_GPL(mlx5_core_page_fault_resume);
  #endif
  
+ static void general_event_handler(struct mlx5_core_dev *dev,
+                                 struct mlx5_eqe *eqe)
+ {
+       switch (eqe->sub_type) {
+       case MLX5_GENERAL_SUBTYPE_DELAY_DROP_TIMEOUT:
+               if (dev->event)
+                       dev->event(dev, MLX5_DEV_EVENT_DELAY_DROP_TIMEOUT, 0);
+               break;
+       default:
+               mlx5_core_dbg(dev, "General event with unrecognized subtype: sub_type %d\n",
+                             eqe->sub_type);
+       }
+ }
  static irqreturn_t mlx5_eq_int(int irq, void *eq_ptr)
  {
        struct mlx5_eq *eq = eq_ptr;
                        mlx5_fpga_event(dev, eqe->type, &eqe->data.raw);
                        break;
  
+               case MLX5_EVENT_TYPE_GENERAL_EVENT:
+                       general_event_handler(dev, eqe);
+                       break;
                default:
                        mlx5_core_warn(dev, "Unhandled event 0x%x on EQ 0x%x\n",
                                       eqe->type, eq->eqn);
@@@ -585,7 -604,7 +604,7 @@@ int mlx5_create_map_eq(struct mlx5_core
                 name, pci_name(dev->pdev));
  
        eq->eqn = MLX5_GET(create_eq_out, out, eq_number);
-       eq->irqn = priv->msix_arr[vecidx].vector;
+       eq->irqn = pci_irq_vector(dev->pdev, vecidx);
        eq->dev = dev;
        eq->doorbell = priv->uar->map + MLX5_EQ_DOORBEL_OFFSET;
        err = request_irq(eq->irqn, handler, 0,
        return 0;
  
  err_irq:
-       free_irq(priv->msix_arr[vecidx].vector, eq);
+       free_irq(eq->irqn, eq);
  
  err_eq:
        mlx5_cmd_destroy_eq(dev, eq->eqn);
@@@ -661,11 -680,6 +680,6 @@@ int mlx5_destroy_unmap_eq(struct mlx5_c
  }
  EXPORT_SYMBOL_GPL(mlx5_destroy_unmap_eq);
  
- u32 mlx5_get_msix_vec(struct mlx5_core_dev *dev, int vecidx)
- {
-       return dev->priv.msix_arr[MLX5_EQ_VEC_ASYNC].vector;
- }
  int mlx5_eq_init(struct mlx5_core_dev *dev)
  {
        int err;
@@@ -693,12 -707,16 +707,16 @@@ int mlx5_start_eqs(struct mlx5_core_de
            mlx5_core_is_pf(dev))
                async_event_mask |= (1ull << MLX5_EVENT_TYPE_NIC_VPORT_CHANGE);
  
+       if (MLX5_CAP_GEN(dev, port_type) == MLX5_CAP_PORT_TYPE_ETH &&
+           MLX5_CAP_GEN(dev, general_notification_event))
+               async_event_mask |= (1ull << MLX5_EVENT_TYPE_GENERAL_EVENT);
        if (MLX5_CAP_GEN(dev, port_module_event))
                async_event_mask |= (1ull << MLX5_EVENT_TYPE_PORT_MODULE_EVENT);
        else
                mlx5_core_dbg(dev, "port_module_event is not set\n");
  
 -      if (MLX5_CAP_GEN(dev, pps))
 +      if (MLX5_PPS_CAP(dev))
                async_event_mask |= (1ull << MLX5_EVENT_TYPE_PPS_EVENT);
  
        if (MLX5_CAP_GEN(dev, fpga))
index 8b18cc9ec026f99d68d23626bde3d695fa1aa895,1ce2543e3889ba27dd9ef0d101329e3d2d726ca8..5b41f692acad0cbebd86af0d124620d7a7af565b
@@@ -1585,7 -1585,7 +1585,7 @@@ static void esw_disable_vport(struct ml
        /* Mark this vport as disabled to discard new events */
        vport->enabled = false;
  
-       synchronize_irq(mlx5_get_msix_vec(esw->dev, MLX5_EQ_VEC_ASYNC));
+       synchronize_irq(pci_irq_vector(esw->dev->pdev, MLX5_EQ_VEC_ASYNC));
        /* Wait for current already scheduled events to complete */
        flush_workqueue(esw->work_queue);
        /* Disable events from this vport */
@@@ -1668,8 -1668,7 +1668,8 @@@ void mlx5_eswitch_disable_sriov(struct 
        int i;
  
        if (!esw || !MLX5_CAP_GEN(esw->dev, vport_group_manager) ||
 -          MLX5_CAP_GEN(esw->dev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
 +          MLX5_CAP_GEN(esw->dev, port_type) != MLX5_CAP_PORT_TYPE_ETH ||
 +          esw->mode == SRIOV_NONE)
                return;
  
        esw_info(esw->dev, "disable SRIOV: active vports(%d) mode(%d)\n",
index 16885827367bfd9153f96faaf7c2afedc6c6a5b0,d8e761cd5448e63f167fa3bec04dcceabf4f65ac..8c4b45ef539c0fc7da69587a0756ec08241feb89
@@@ -47,6 -47,7 +47,7 @@@
  #include <linux/debugfs.h>
  #include <linux/kmod.h>
  #include <linux/mlx5/mlx5_ifc.h>
+ #include <linux/mlx5/vport.h>
  #ifdef CONFIG_RFS_ACCEL
  #include <linux/cpu_rmap.h>
  #endif
@@@ -312,13 -313,15 +313,15 @@@ static void release_bar(struct pci_dev 
        pci_release_regions(pdev);
  }
  
- static int mlx5_enable_msix(struct mlx5_core_dev *dev)
+ static int mlx5_alloc_irq_vectors(struct mlx5_core_dev *dev)
  {
        struct mlx5_priv *priv = &dev->priv;
        struct mlx5_eq_table *table = &priv->eq_table;
+       struct irq_affinity irqdesc = {
+               .pre_vectors = MLX5_EQ_VEC_COMP_BASE,
+       };
        int num_eqs = 1 << MLX5_CAP_GEN(dev, log_max_eq);
        int nvec;
-       int i;
  
        nvec = MLX5_CAP_GEN(dev, num_ports) * num_online_cpus() +
               MLX5_EQ_VEC_COMP_BASE;
        if (nvec <= MLX5_EQ_VEC_COMP_BASE)
                return -ENOMEM;
  
-       priv->msix_arr = kcalloc(nvec, sizeof(*priv->msix_arr), GFP_KERNEL);
        priv->irq_info = kcalloc(nvec, sizeof(*priv->irq_info), GFP_KERNEL);
-       if (!priv->msix_arr || !priv->irq_info)
+       if (!priv->irq_info)
                goto err_free_msix;
  
-       for (i = 0; i < nvec; i++)
-               priv->msix_arr[i].entry = i;
-       nvec = pci_enable_msix_range(dev->pdev, priv->msix_arr,
-                                    MLX5_EQ_VEC_COMP_BASE + 1, nvec);
+       nvec = pci_alloc_irq_vectors_affinity(dev->pdev,
+                       MLX5_EQ_VEC_COMP_BASE + 1, nvec,
+                       PCI_IRQ_MSIX | PCI_IRQ_AFFINITY,
+                       &irqdesc);
        if (nvec < 0)
                return nvec;
  
  
  err_free_msix:
        kfree(priv->irq_info);
-       kfree(priv->msix_arr);
        return -ENOMEM;
  }
  
- static void mlx5_disable_msix(struct mlx5_core_dev *dev)
+ static void mlx5_free_irq_vectors(struct mlx5_core_dev *dev)
  {
        struct mlx5_priv *priv = &dev->priv;
  
-       pci_disable_msix(dev->pdev);
+       pci_free_irq_vectors(dev->pdev);
        kfree(priv->irq_info);
-       kfree(priv->msix_arr);
  }
  
  struct mlx5_reg_host_endianness {
@@@ -579,6 -577,18 +577,18 @@@ static int set_hca_ctrl(struct mlx5_cor
        return err;
  }
  
+ static int mlx5_core_set_hca_defaults(struct mlx5_core_dev *dev)
+ {
+       int ret = 0;
+       /* Disable local_lb by default */
+       if ((MLX5_CAP_GEN(dev, port_type) == MLX5_CAP_PORT_TYPE_ETH) &&
+           MLX5_CAP_GEN(dev, disable_local_lb))
+               ret = mlx5_nic_vport_update_local_lb(dev, false);
+       return ret;
+ }
  int mlx5_core_enable_hca(struct mlx5_core_dev *dev, u16 func_id)
  {
        u32 out[MLX5_ST_SZ_DW(enable_hca_out)] = {0};
@@@ -612,65 -622,6 +622,6 @@@ u64 mlx5_read_internal_timer(struct mlx
        return (u64)timer_l | (u64)timer_h1 << 32;
  }
  
- static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i)
- {
-       struct mlx5_priv *priv  = &mdev->priv;
-       struct msix_entry *msix = priv->msix_arr;
-       int irq                 = msix[i + MLX5_EQ_VEC_COMP_BASE].vector;
-       if (!zalloc_cpumask_var(&priv->irq_info[i].mask, GFP_KERNEL)) {
-               mlx5_core_warn(mdev, "zalloc_cpumask_var failed");
-               return -ENOMEM;
-       }
-       cpumask_set_cpu(cpumask_local_spread(i, priv->numa_node),
-                       priv->irq_info[i].mask);
-       if (IS_ENABLED(CONFIG_SMP) &&
-           irq_set_affinity_hint(irq, priv->irq_info[i].mask))
-               mlx5_core_warn(mdev, "irq_set_affinity_hint failed, irq 0x%.4x", irq);
-       return 0;
- }
- static void mlx5_irq_clear_affinity_hint(struct mlx5_core_dev *mdev, int i)
- {
-       struct mlx5_priv *priv  = &mdev->priv;
-       struct msix_entry *msix = priv->msix_arr;
-       int irq                 = msix[i + MLX5_EQ_VEC_COMP_BASE].vector;
-       irq_set_affinity_hint(irq, NULL);
-       free_cpumask_var(priv->irq_info[i].mask);
- }
- static int mlx5_irq_set_affinity_hints(struct mlx5_core_dev *mdev)
- {
-       int err;
-       int i;
-       for (i = 0; i < mdev->priv.eq_table.num_comp_vectors; i++) {
-               err = mlx5_irq_set_affinity_hint(mdev, i);
-               if (err)
-                       goto err_out;
-       }
-       return 0;
- err_out:
-       for (i--; i >= 0; i--)
-               mlx5_irq_clear_affinity_hint(mdev, i);
-       return err;
- }
- static void mlx5_irq_clear_affinity_hints(struct mlx5_core_dev *mdev)
- {
-       int i;
-       for (i = 0; i < mdev->priv.eq_table.num_comp_vectors; i++)
-               mlx5_irq_clear_affinity_hint(mdev, i);
- }
  int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn,
                    unsigned int *irqn)
  {
@@@ -760,8 -711,8 +711,8 @@@ static int alloc_comp_eqs(struct mlx5_c
                }
  
  #ifdef CONFIG_RFS_ACCEL
-               irq_cpu_rmap_add(dev->rmap,
-                                dev->priv.msix_arr[i + MLX5_EQ_VEC_COMP_BASE].vector);
+               irq_cpu_rmap_add(dev->rmap, pci_irq_vector(dev->pdev,
+                                MLX5_EQ_VEC_COMP_BASE + i));
  #endif
                snprintf(name, MLX5_MAX_IRQ_NAME, "mlx5_comp%d", i);
                err = mlx5_create_map_eq(dev, eq,
@@@ -1119,9 -1070,9 +1070,9 @@@ static int mlx5_load_one(struct mlx5_co
                goto err_stop_poll;
        }
  
-       err = mlx5_enable_msix(dev);
+       err = mlx5_alloc_irq_vectors(dev);
        if (err) {
-               dev_err(&pdev->dev, "enable msix failed\n");
+               dev_err(&pdev->dev, "alloc irq vectors failed\n");
                goto err_cleanup_once;
        }
  
                goto err_stop_eqs;
        }
  
-       err = mlx5_irq_set_affinity_hints(dev);
+       err = mlx5_init_fs(dev);
        if (err) {
-               dev_err(&pdev->dev, "Failed to alloc affinity hint cpumask\n");
-               goto err_affinity_hints;
+               dev_err(&pdev->dev, "Failed to init flow steering\n");
+               goto err_fs;
        }
  
-       err = mlx5_init_fs(dev);
+       err = mlx5_core_set_hca_defaults(dev);
        if (err) {
-               dev_err(&pdev->dev, "Failed to init flow steering\n");
+               dev_err(&pdev->dev, "Failed to set hca defaults\n");
                goto err_fs;
        }
  
                }
        }
  
 -      clear_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state);
        set_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state);
  out:
        mutex_unlock(&dev->intf_state_mutex);
@@@ -1207,9 -1159,6 +1158,6 @@@ err_sriov
        mlx5_cleanup_fs(dev);
  
  err_fs:
-       mlx5_irq_clear_affinity_hints(dev);
- err_affinity_hints:
        free_comp_eqs(dev);
  
  err_stop_eqs:
@@@ -1219,7 -1168,7 +1167,7 @@@ err_put_uars
        mlx5_put_uars_page(dev, priv->uar);
  
  err_disable_msix:
-       mlx5_disable_msix(dev);
+       mlx5_free_irq_vectors(dev);
  
  err_cleanup_once:
        if (boot)
@@@ -1260,7 -1209,7 +1208,7 @@@ static int mlx5_unload_one(struct mlx5_
                mlx5_drain_health_recovery(dev);
  
        mutex_lock(&dev->intf_state_mutex);
 -      if (test_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state)) {
 +      if (!test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) {
                dev_warn(&dev->pdev->dev, "%s: interface is down, NOP\n",
                         __func__);
                if (cleanup)
        }
  
        clear_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state);
 -      set_bit(MLX5_INTERFACE_STATE_DOWN, &dev->intf_state);
  
        if (mlx5_device_registered(dev))
                mlx5_detach_device(dev);
        mlx5_eswitch_detach(dev->priv.eswitch);
  #endif
        mlx5_cleanup_fs(dev);
-       mlx5_irq_clear_affinity_hints(dev);
        free_comp_eqs(dev);
        mlx5_stop_eqs(dev);
        mlx5_put_uars_page(dev, priv->uar);
-       mlx5_disable_msix(dev);
+       mlx5_free_irq_vectors(dev);
        if (cleanup)
                mlx5_cleanup_once(dev);
        mlx5_stop_health_poll(dev);
@@@ -1563,6 -1512,8 +1510,6 @@@ static void shutdown(struct pci_dev *pd
        int err;
  
        dev_info(&pdev->dev, "Shutdown was called\n");
 -      /* Notify mlx5 clients that the kernel is being shut down */
 -      set_bit(MLX5_INTERFACE_STATE_SHUTDOWN, &dev->intf_state);
        err = mlx5_try_fast_unload(dev);
        if (err)
                mlx5_unload_one(dev, priv, false);
index 6a263e8d883a6bae2791a011026e03bc0cd1dead,ba1d494b016d7cf08c33059cb9028c6a1a9eda7f..01d637dac533fb2719cbf676f8fcc069c6ee5d1d
@@@ -110,7 -110,6 +110,6 @@@ int mlx5_destroy_scheduling_element_cmd
                                        u32 element_id);
  int mlx5_wait_for_vf_pages(struct mlx5_core_dev *dev);
  u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev);
- u32 mlx5_get_msix_vec(struct mlx5_core_dev *dev, int vecidx);
  struct mlx5_eq *mlx5_eqn2eq(struct mlx5_core_dev *dev, int eqn);
  void mlx5_cq_tasklet_cb(unsigned long data);
  
@@@ -154,11 -153,6 +153,11 @@@ int mlx5_set_mtpps(struct mlx5_core_de
  int mlx5_query_mtppse(struct mlx5_core_dev *mdev, u8 pin, u8 *arm, u8 *mode);
  int mlx5_set_mtppse(struct mlx5_core_dev *mdev, u8 pin, u8 arm, u8 mode);
  
 +#define MLX5_PPS_CAP(mdev) (MLX5_CAP_GEN((mdev), pps) &&              \
 +                          MLX5_CAP_GEN((mdev), pps_modify) &&         \
 +                          MLX5_CAP_MCAM_FEATURE((mdev), mtpps_fs) &&  \
 +                          MLX5_CAP_MCAM_FEATURE((mdev), mtpps_enh_out_per_adj))
 +
  int mlx5_firmware_flash(struct mlx5_core_dev *dev, const struct firmware *fw);
  
  void mlx5e_init(void);
index bf99d40e30b4e07a234ea68366d226267d365d7b,090b29e05a6a9e24aedef1cf7a8a75d9cf7489ec..28d8472b36f130cc670fdc2843eac6b13bbee1d4
@@@ -32,6 -32,7 +32,7 @@@
  
  #include <linux/pci.h>
  #include <linux/mlx5/driver.h>
+ #include <linux/mlx5/vport.h>
  #include "mlx5_core.h"
  #ifdef CONFIG_MLX5_CORE_EN
  #include "eswitch.h"
@@@ -44,6 -45,38 +45,38 @@@ bool mlx5_sriov_is_enabled(struct mlx5_
        return !!sriov->num_vfs;
  }
  
+ static int sriov_restore_guids(struct mlx5_core_dev *dev, int vf)
+ {
+       struct mlx5_core_sriov *sriov = &dev->priv.sriov;
+       struct mlx5_hca_vport_context *in;
+       int err = 0;
+       /* Restore sriov guid and policy settings */
+       if (sriov->vfs_ctx[vf].node_guid ||
+           sriov->vfs_ctx[vf].port_guid ||
+           sriov->vfs_ctx[vf].policy != MLX5_POLICY_INVALID) {
+               in = kzalloc(sizeof(*in), GFP_KERNEL);
+               if (!in)
+                       return -ENOMEM;
+               in->node_guid = sriov->vfs_ctx[vf].node_guid;
+               in->port_guid = sriov->vfs_ctx[vf].port_guid;
+               in->policy = sriov->vfs_ctx[vf].policy;
+               in->field_select =
+                       !!(in->port_guid) * MLX5_HCA_VPORT_SEL_PORT_GUID |
+                       !!(in->node_guid) * MLX5_HCA_VPORT_SEL_NODE_GUID |
+                       !!(in->policy) * MLX5_HCA_VPORT_SEL_STATE_POLICY;
+               err = mlx5_core_modify_hca_vport_context(dev, 1, 1, vf + 1, in);
+               if (err)
+                       mlx5_core_warn(dev, "modify vport context failed, unable to restore VF %d settings\n", vf);
+               kfree(in);
+       }
+       return err;
+ }
  static int mlx5_device_enable_sriov(struct mlx5_core_dev *dev, int num_vfs)
  {
        struct mlx5_core_sriov *sriov = &dev->priv.sriov;
                }
                sriov->vfs_ctx[vf].enabled = 1;
                sriov->enabled_vfs++;
+               if (MLX5_CAP_GEN(dev, port_type) == MLX5_CAP_PORT_TYPE_IB) {
+                       err = sriov_restore_guids(dev, vf);
+                       if (err) {
+                               mlx5_core_warn(dev,
+                                              "failed to restore VF %d settings, err %d\n",
+                                              vf, err);
+                       continue;
+                       }
+               }
                mlx5_core_dbg(dev, "successfully enabled VF* %d\n", vf);
  
        }
@@@ -88,11 -130,7 +130,11 @@@ static void mlx5_device_disable_sriov(s
        int vf;
  
        if (!sriov->enabled_vfs)
 +#ifdef CONFIG_MLX5_CORE_EN
 +              goto disable_sriov_resources;
 +#else
                return;
 +#endif
  
        for (vf = 0; vf < sriov->num_vfs; vf++) {
                if (!sriov->vfs_ctx[vf].enabled)
        }
  
  #ifdef CONFIG_MLX5_CORE_EN
 +disable_sriov_resources:
        mlx5_eswitch_disable_sriov(dev->priv.eswitch);
  #endif
  
index 520f6382dfdeceac61ffa383afd12a6de99daf54,7673da04efa4851452982f1ad50920151800b934..23cc337a96c96e3aa4a2b978493e8f6755b64d15
@@@ -201,13 -201,13 +201,13 @@@ static int destroy_srq_cmd(struct mlx5_
  static int arm_srq_cmd(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq,
                       u16 lwm, int is_srq)
  {
 -      /* arm_srq structs missing using identical xrc ones */
 -      u32 srq_in[MLX5_ST_SZ_DW(arm_xrc_srq_in)] = {0};
 -      u32 srq_out[MLX5_ST_SZ_DW(arm_xrc_srq_out)] = {0};
 +      u32 srq_in[MLX5_ST_SZ_DW(arm_rq_in)] = {0};
 +      u32 srq_out[MLX5_ST_SZ_DW(arm_rq_out)] = {0};
  
 -      MLX5_SET(arm_xrc_srq_in, srq_in, opcode,   MLX5_CMD_OP_ARM_XRC_SRQ);
 -      MLX5_SET(arm_xrc_srq_in, srq_in, xrc_srqn, srq->srqn);
 -      MLX5_SET(arm_xrc_srq_in, srq_in, lwm,      lwm);
 +      MLX5_SET(arm_rq_in, srq_in, opcode, MLX5_CMD_OP_ARM_RQ);
 +      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);
  
        return  mlx5_cmd_exec(dev, srq_in, sizeof(srq_in),
                              srq_out, sizeof(srq_out));
        return err;
  }
  
+ static int create_xrq_cmd(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq,
+                         struct mlx5_srq_attr *in)
+ {
+       u32 create_out[MLX5_ST_SZ_DW(create_xrq_out)] = {0};
+       void *create_in;
+       void *xrqc;
+       void *wq;
+       int pas_size;
+       int inlen;
+       int err;
+       pas_size = get_pas_size(in);
+       inlen = MLX5_ST_SZ_BYTES(create_xrq_in) + pas_size;
+       create_in = kvzalloc(inlen, GFP_KERNEL);
+       if (!create_in)
+               return -ENOMEM;
+       xrqc = MLX5_ADDR_OF(create_xrq_in, create_in, xrq_context);
+       wq = MLX5_ADDR_OF(xrqc, xrqc, wq);
+       set_wq(wq, in);
+       memcpy(MLX5_ADDR_OF(xrqc, xrqc, wq.pas), in->pas, pas_size);
+       if (in->type == IB_SRQT_TM) {
+               MLX5_SET(xrqc, xrqc, topology, MLX5_XRQC_TOPOLOGY_TAG_MATCHING);
+               if (in->flags & MLX5_SRQ_FLAG_RNDV)
+                       MLX5_SET(xrqc, xrqc, offload, MLX5_XRQC_OFFLOAD_RNDV);
+               MLX5_SET(xrqc, xrqc,
+                        tag_matching_topology_context.log_matching_list_sz,
+                        in->tm_log_list_size);
+       }
+       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);
+       err = mlx5_cmd_exec(dev, create_in, inlen, create_out,
+                           sizeof(create_out));
+       kvfree(create_in);
+       if (!err)
+               srq->srqn = MLX5_GET(create_xrq_out, create_out, xrqn);
+       return err;
+ }
+ static int destroy_xrq_cmd(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq)
+ {
+       u32 in[MLX5_ST_SZ_DW(destroy_xrq_in)] = {0};
+       u32 out[MLX5_ST_SZ_DW(destroy_xrq_out)] = {0};
+       MLX5_SET(destroy_xrq_in, in, opcode, MLX5_CMD_OP_DESTROY_XRQ);
+       MLX5_SET(destroy_xrq_in, in, xrqn,   srq->srqn);
+       return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
+ }
+ static int arm_xrq_cmd(struct mlx5_core_dev *dev,
+                      struct mlx5_core_srq *srq,
+                      u16 lwm)
+ {
+       u32 out[MLX5_ST_SZ_DW(arm_rq_out)] = {0};
+       u32 in[MLX5_ST_SZ_DW(arm_rq_in)] = {0};
+       MLX5_SET(arm_rq_in, in, opcode,     MLX5_CMD_OP_ARM_RQ);
+       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);
+       return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
+ }
+ static int query_xrq_cmd(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq,
+                        struct mlx5_srq_attr *out)
+ {
+       u32 in[MLX5_ST_SZ_DW(query_xrq_in)] = {0};
+       u32 *xrq_out;
+       int outlen = MLX5_ST_SZ_BYTES(query_xrq_out);
+       void *xrqc;
+       int err;
+       xrq_out = kvzalloc(outlen, GFP_KERNEL);
+       if (!xrq_out)
+               return -ENOMEM;
+       MLX5_SET(query_xrq_in, in, opcode, MLX5_CMD_OP_QUERY_XRQ);
+       MLX5_SET(query_xrq_in, in, xrqn, srq->srqn);
+       err = mlx5_cmd_exec(dev, in, sizeof(in), xrq_out, outlen);
+       if (err)
+               goto out;
+       xrqc = MLX5_ADDR_OF(query_xrq_out, xrq_out, xrq_context);
+       get_wq(MLX5_ADDR_OF(xrqc, xrqc, wq), out);
+       if (MLX5_GET(xrqc, xrqc, state) != MLX5_XRQC_STATE_GOOD)
+               out->flags |= MLX5_SRQ_FLAG_ERR;
+       out->tm_next_tag =
+               MLX5_GET(xrqc, xrqc,
+                        tag_matching_topology_context.append_next_index);
+       out->tm_hw_phase_cnt =
+               MLX5_GET(xrqc, xrqc,
+                        tag_matching_topology_context.hw_phase_cnt);
+       out->tm_sw_phase_cnt =
+               MLX5_GET(xrqc, xrqc,
+                        tag_matching_topology_context.sw_phase_cnt);
+ out:
+       kvfree(xrq_out);
+       return err;
+ }
  static int create_srq_split(struct mlx5_core_dev *dev,
                            struct mlx5_core_srq *srq,
                            struct mlx5_srq_attr *in)
  {
        if (!dev->issi)
                return create_srq_cmd(dev, srq, in);
-       else if (srq->common.res == MLX5_RES_XSRQ)
+       switch (srq->common.res) {
+       case MLX5_RES_XSRQ:
                return create_xrc_srq_cmd(dev, srq, in);
-       else
+       case MLX5_RES_XRQ:
+               return create_xrq_cmd(dev, srq, in);
+       default:
                return create_rmp_cmd(dev, srq, in);
+       }
  }
  
  static int destroy_srq_split(struct mlx5_core_dev *dev,
  {
        if (!dev->issi)
                return destroy_srq_cmd(dev, srq);
-       else if (srq->common.res == MLX5_RES_XSRQ)
+       switch (srq->common.res) {
+       case MLX5_RES_XSRQ:
                return destroy_xrc_srq_cmd(dev, srq);
-       else
+       case MLX5_RES_XRQ:
+               return destroy_xrq_cmd(dev, srq);
+       default:
                return destroy_rmp_cmd(dev, srq);
+       }
  }
  
  int mlx5_core_create_srq(struct mlx5_core_dev *dev, struct mlx5_core_srq *srq,
        int err;
        struct mlx5_srq_table *table = &dev->priv.srq_table;
  
-       if (in->type == IB_SRQT_XRC)
+       switch (in->type) {
+       case IB_SRQT_XRC:
                srq->common.res = MLX5_RES_XSRQ;
-       else
+               break;
+       case IB_SRQT_TM:
+               srq->common.res = MLX5_RES_XRQ;
+               break;
+       default:
                srq->common.res = MLX5_RES_SRQ;
+       }
  
        err = create_srq_split(dev, srq, in);
        if (err)
@@@ -528,10 -650,14 +650,14 @@@ int mlx5_core_query_srq(struct mlx5_cor
  {
        if (!dev->issi)
                return query_srq_cmd(dev, srq, out);
-       else if (srq->common.res == MLX5_RES_XSRQ)
+       switch (srq->common.res) {
+       case MLX5_RES_XSRQ:
                return query_xrc_srq_cmd(dev, srq, out);
-       else
+       case MLX5_RES_XRQ:
+               return query_xrq_cmd(dev, srq, out);
+       default:
                return query_rmp_cmd(dev, srq, out);
+       }
  }
  EXPORT_SYMBOL(mlx5_core_query_srq);
  
@@@ -540,10 -666,14 +666,14 @@@ int mlx5_core_arm_srq(struct mlx5_core_
  {
        if (!dev->issi)
                return arm_srq_cmd(dev, srq, lwm, is_srq);
-       else if (srq->common.res == MLX5_RES_XSRQ)
+       switch (srq->common.res) {
+       case MLX5_RES_XSRQ:
                return arm_xrc_srq_cmd(dev, srq, lwm);
-       else
+       case MLX5_RES_XRQ:
+               return arm_xrq_cmd(dev, srq, lwm);
+       default:
                return arm_rmp_cmd(dev, srq, lwm);
+       }
  }
  EXPORT_SYMBOL(mlx5_core_arm_srq);
  
diff --combined drivers/nvme/host/rdma.c
index a03299d779229de271eb28704a73515f1020ffe1,9fb6e4caddbd38b4e737f050cef58bab5800c73e..a7f7d0ae3331fafbdaa630c365379aed5334db12
@@@ -19,6 -19,7 +19,7 @@@
  #include <linux/string.h>
  #include <linux/atomic.h>
  #include <linux/blk-mq.h>
+ #include <linux/blk-mq-rdma.h>
  #include <linux/types.h>
  #include <linux/list.h>
  #include <linux/mutex.h>
@@@ -463,14 -464,10 +464,10 @@@ static int nvme_rdma_create_queue_ib(st
        ibdev = queue->device->dev;
  
        /*
-        * The admin queue is barely used once the controller is live, so don't
-        * bother to spread it out.
+        * Spread I/O queues completion vectors according their queue index.
+        * Admin queues can always go on completion vector 0.
         */
-       if (idx == 0)
-               comp_vector = 0;
-       else
-               comp_vector = idx % ibdev->num_comp_vectors;
+       comp_vector = idx == 0 ? idx : idx - 1;
  
        /* +1 for ib_stop_cq */
        queue->ib_cq = ib_alloc_cq(ibdev, queue,
@@@ -611,10 -608,20 +608,20 @@@ out_free_queues
  static int nvme_rdma_init_io_queues(struct nvme_rdma_ctrl *ctrl)
  {
        struct nvmf_ctrl_options *opts = ctrl->ctrl.opts;
+       struct ib_device *ibdev = ctrl->device->dev;
        unsigned int nr_io_queues;
        int i, ret;
  
        nr_io_queues = min(opts->nr_io_queues, num_online_cpus());
+       /*
+        * we map queues according to the device irq vectors for
+        * optimal locality so we don't need more queues than
+        * completion vectors.
+        */
+       nr_io_queues = min_t(unsigned int, nr_io_queues,
+                               ibdev->num_comp_vectors);
        ret = nvme_set_queue_count(&ctrl->ctrl, &nr_io_queues);
        if (ret)
                return ret;
@@@ -920,11 -927,7 +927,11 @@@ static int nvme_rdma_map_sg_fr(struct n
        struct nvme_keyed_sgl_desc *sg = &c->common.dptr.ksgl;
        int nr;
  
 -      nr = ib_map_mr_sg(req->mr, req->sg_table.sgl, count, NULL, PAGE_SIZE);
 +      /*
 +       * Align the MR to a 4K page size to match the ctrl page size and
 +       * the block virtual boundary.
 +       */
 +      nr = ib_map_mr_sg(req->mr, req->sg_table.sgl, count, NULL, SZ_4K);
        if (nr < count) {
                if (nr < 0)
                        return nr;
@@@ -1502,6 -1505,13 +1509,13 @@@ static void nvme_rdma_complete_rq(struc
        nvme_complete_rq(rq);
  }
  
+ static int nvme_rdma_map_queues(struct blk_mq_tag_set *set)
+ {
+       struct nvme_rdma_ctrl *ctrl = set->driver_data;
+       return blk_mq_rdma_map_queues(set, ctrl->device->dev, 0);
+ }
  static const struct blk_mq_ops nvme_rdma_mq_ops = {
        .queue_rq       = nvme_rdma_queue_rq,
        .complete       = nvme_rdma_complete_rq,
        .init_hctx      = nvme_rdma_init_hctx,
        .poll           = nvme_rdma_poll,
        .timeout        = nvme_rdma_timeout,
+       .map_queues     = nvme_rdma_map_queues,
  };
  
  static const struct blk_mq_ops nvme_rdma_admin_mq_ops = {
@@@ -1587,7 -1598,7 +1602,7 @@@ static int nvme_rdma_configure_admin_qu
                goto out_cleanup_queue;
  
        ctrl->ctrl.max_hw_sectors =
 -              (ctrl->max_fr_pages - 1) << (PAGE_SHIFT - 9);
 +              (ctrl->max_fr_pages - 1) << (ilog2(SZ_4K) - 9);
  
        error = nvme_init_identify(&ctrl->ctrl);
        if (error)
@@@ -1950,10 -1961,6 +1965,6 @@@ static struct nvmf_transport_ops nvme_r
        .create_ctrl    = nvme_rdma_create_ctrl,
  };
  
- static void nvme_rdma_add_one(struct ib_device *ib_device)
- {
- }
  static void nvme_rdma_remove_one(struct ib_device *ib_device, void *client_data)
  {
        struct nvme_rdma_ctrl *ctrl;
  
  static struct ib_client nvme_rdma_ib_client = {
        .name   = "nvme_rdma",
-       .add = nvme_rdma_add_one,
        .remove = nvme_rdma_remove_one
  };
  
index b54517c05e9ab20fff33e3526fe0ea8de1e702bb,3607da001ad3a0f3de10a92cb1c37062ff5c256a..c8a63e148a987df6582efdc28f5d8a777e75c80a
@@@ -428,6 -428,12 +428,12 @@@ enum mlx4_steer_type 
        MLX4_NUM_STEERS
  };
  
+ enum mlx4_resource_usage {
+       MLX4_RES_USAGE_NONE,
+       MLX4_RES_USAGE_DRIVER,
+       MLX4_RES_USAGE_USER_VERBS,
+ };
  enum {
        MLX4_NUM_FEXCH          = 64 * 1024,
  };
@@@ -620,7 -626,6 +626,7 @@@ struct mlx4_caps 
        u32                     dmfs_high_rate_qpn_base;
        u32                     dmfs_high_rate_qpn_range;
        u32                     vf_caps;
 +      bool                    wol_port[MLX4_MAX_PORTS + 1];
        struct mlx4_rate_limit_caps rl_caps;
  };
  
@@@ -749,6 -754,7 +755,7 @@@ struct mlx4_cq 
        } tasklet_ctx;
        int             reset_notify_added;
        struct list_head        reset_notify;
+       u8                      usage;
  };
  
  struct mlx4_qp {
  
        atomic_t                refcount;
        struct completion       free;
+       u8                      usage;
  };
  
  struct mlx4_srq {
@@@ -1121,7 -1128,7 +1129,7 @@@ int mlx4_cq_alloc(struct mlx4_dev *dev
                  unsigned vector, int collapsed, int timestamp_en);
  void mlx4_cq_free(struct mlx4_dev *dev, struct mlx4_cq *cq);
  int mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align,
-                         int *base, u8 flags);
+                         int *base, u8 flags, u8 usage);
  void mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt);
  
  int mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp);
@@@ -1418,7 -1425,7 +1426,7 @@@ int mlx4_get_phys_port_id(struct mlx4_d
  int mlx4_wol_read(struct mlx4_dev *dev, u64 *config, int port);
  int mlx4_wol_write(struct mlx4_dev *dev, u64 config, int port);
  
- int mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx);
+ int mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx, u8 usage);
  void mlx4_counter_free(struct mlx4_dev *dev, u32 idx);
  int mlx4_get_default_counter_index(struct mlx4_dev *dev, int port);
  
index 205d82d4c468717ac26050358acb65a968481097,c33e6f7a1afbef10c0f987ad0c255d9e8d83f39d..b3fc9d586a9f949c2fdba9ffdb0e60e111218014
@@@ -162,6 -162,13 +162,13 @@@ enum dbg_rsc_type 
        MLX5_DBG_RSC_CQ,
  };
  
+ enum port_state_policy {
+       MLX5_POLICY_DOWN        = 0,
+       MLX5_POLICY_UP          = 1,
+       MLX5_POLICY_FOLLOW      = 2,
+       MLX5_POLICY_INVALID     = 0xffffffff
+ };
  struct mlx5_field_desc {
        struct dentry          *dent;
        int                     i;
@@@ -185,6 -192,7 +192,7 @@@ enum mlx5_dev_event 
        MLX5_DEV_EVENT_GUID_CHANGE,
        MLX5_DEV_EVENT_CLIENT_REREG,
        MLX5_DEV_EVENT_PPS,
+       MLX5_DEV_EVENT_DELAY_DROP_TIMEOUT,
  };
  
  enum mlx5_port_status {
@@@ -291,7 -299,7 +299,7 @@@ struct mlx5_cmd 
        struct semaphore pages_sem;
        int     mode;
        struct mlx5_cmd_work_ent *ent_arr[MLX5_MAX_COMMANDS];
-       struct pci_pool *pool;
+       struct dma_pool *pool;
        struct mlx5_cmd_debug dbg;
        struct cmd_msg_cache cache[MLX5_NUM_COMMAND_CACHES];
        int checksum_disabled;
@@@ -410,6 -418,7 +418,7 @@@ enum mlx5_res_type 
        MLX5_RES_SQ     = MLX5_EVENT_QUEUE_TYPE_SQ,
        MLX5_RES_SRQ    = 3,
        MLX5_RES_XSRQ   = 4,
+       MLX5_RES_XRQ    = 5,
  };
  
  struct mlx5_core_rsc_common {
@@@ -525,6 -534,9 +534,9 @@@ struct mlx5_mkey_table 
  
  struct mlx5_vf_context {
        int     enabled;
+       u64     port_guid;
+       u64     node_guid;
+       enum port_state_policy  policy;
  };
  
  struct mlx5_core_sriov {
  };
  
  struct mlx5_irq_info {
-       cpumask_var_t mask;
        char name[MLX5_MAX_IRQ_NAME];
  };
  
@@@ -597,7 -608,6 +608,6 @@@ struct mlx5_port_module_event_stats 
  struct mlx5_priv {
        char                    name[MLX5_MAX_NAME_LEN];
        struct mlx5_eq_table    eq_table;
-       struct msix_entry       *msix_arr;
        struct mlx5_irq_info    *irq_info;
  
        /* pages stuff */
@@@ -673,7 -683,9 +683,7 @@@ enum mlx5_device_state 
  };
  
  enum mlx5_interface_state {
 -      MLX5_INTERFACE_STATE_DOWN = BIT(0),
 -      MLX5_INTERFACE_STATE_UP = BIT(1),
 -      MLX5_INTERFACE_STATE_SHUTDOWN = BIT(2),
 +      MLX5_INTERFACE_STATE_UP = BIT(0),
  };
  
  enum mlx5_pci_status {
@@@ -840,13 -852,6 +850,6 @@@ struct mlx5_pas 
        u8      log_sz;
  };
  
- enum port_state_policy {
-       MLX5_POLICY_DOWN        = 0,
-       MLX5_POLICY_UP          = 1,
-       MLX5_POLICY_FOLLOW      = 2,
-       MLX5_POLICY_INVALID     = 0xffffffff
- };
  enum phy_port_state {
        MLX5_AAA_111
  };
@@@ -1089,7 -1094,7 +1092,7 @@@ enum 
  };
  
  enum {
-       MAX_UMR_CACHE_ENTRY = 20,
+       MR_CACHE_LAST_STD_ENTRY = 20,
        MLX5_IMR_MTT_CACHE_ENTRY,
        MLX5_IMR_KSM_CACHE_ENTRY,
        MAX_MR_CACHE_ENTRIES
@@@ -1183,4 -1188,10 +1186,10 @@@ enum 
        MLX5_TRIGGERED_CMD_COMP = (u64)1 << 32,
  };
  
+ static inline const struct cpumask *
+ mlx5_get_vector_affinity(struct mlx5_core_dev *dev, int vector)
+ {
+       return pci_irq_get_affinity(dev->pdev, MLX5_EQ_VEC_COMP_BASE + vector);
+ }
  #endif /* MLX5_DRIVER_H */
index 3030121b474601b3dc7003bb5b0a48a1a5d5f5ba,e27283ab366781cc4d9eec452ed29865598525da..b7338a21c780883ffb92e1a44d011f1a4e7ff07f
@@@ -200,6 -200,7 +200,7 @@@ enum 
        MLX5_CMD_OP_QUERY_SQ                      = 0x907,
        MLX5_CMD_OP_CREATE_RQ                     = 0x908,
        MLX5_CMD_OP_MODIFY_RQ                     = 0x909,
+       MLX5_CMD_OP_SET_DELAY_DROP_PARAMS         = 0x910,
        MLX5_CMD_OP_DESTROY_RQ                    = 0x90a,
        MLX5_CMD_OP_QUERY_RQ                      = 0x90b,
        MLX5_CMD_OP_CREATE_RMP                    = 0x90c,
@@@ -294,8 -295,10 +295,10 @@@ struct mlx5_ifc_flow_table_fields_suppo
        u8         inner_tcp_dport[0x1];
        u8         inner_tcp_flags[0x1];
        u8         reserved_at_37[0x9];
+       u8         reserved_at_40[0x1a];
+       u8         bth_dst_qp[0x1];
  
-       u8         reserved_at_40[0x40];
+       u8         reserved_at_5b[0x25];
  };
  
  struct mlx5_ifc_flow_table_prop_layout_bits {
@@@ -431,7 -434,9 +434,9 @@@ struct mlx5_ifc_fte_match_set_misc_bit
        u8         reserved_at_100[0xc];
        u8         inner_ipv6_flow_label[0x14];
  
-       u8         reserved_at_120[0xe0];
+       u8         reserved_at_120[0x28];
+       u8         bth_dst_qp[0x18];
+       u8         reserved_at_160[0xa0];
  };
  
  struct mlx5_ifc_cmd_pas_bits {
@@@ -599,7 -604,7 +604,7 @@@ struct mlx5_ifc_per_protocol_networking
        u8         rss_ind_tbl_cap[0x4];
        u8         reg_umr_sq[0x1];
        u8         scatter_fcs[0x1];
-       u8         reserved_at_1a[0x1];
+       u8         enhanced_multi_pkt_send_wqe[0x1];
        u8         tunnel_lso_const_out_ip_id[0x1];
        u8         reserved_at_1c[0x2];
        u8         tunnel_statless_gre[0x1];
@@@ -840,7 -845,7 +845,7 @@@ struct mlx5_ifc_cmd_hca_cap_bits 
        u8         retransmission_q_counters[0x1];
        u8         reserved_at_183[0x1];
        u8         modify_rq_counter_set_id[0x1];
-       u8         reserved_at_185[0x1];
+       u8         rq_delay_drop[0x1];
        u8         max_qp_cnt[0xa];
        u8         pkey_table_size[0x10];
  
        u8         pcam_reg[0x1];
        u8         local_ca_ack_delay[0x5];
        u8         port_module_event[0x1];
-       u8         reserved_at_1b1[0x1];
+       u8         enhanced_error_q_counters[0x1];
        u8         ports_check[0x1];
        u8         reserved_at_1b3[0x1];
        u8         disable_link_up[0x1];
        u8         max_tc[0x4];
        u8         reserved_at_1d0[0x1];
        u8         dcbx[0x1];
-       u8         reserved_at_1d2[0x3];
+       u8         general_notification_event[0x1];
+       u8         reserved_at_1d3[0x2];
        u8         fpga[0x1];
        u8         rol_s[0x1];
        u8         rol_g[0x1];
        u8         log_max_wq_sz[0x5];
  
        u8         nic_vport_change_event[0x1];
-       u8         reserved_at_3e1[0xa];
+       u8         disable_local_lb[0x1];
+       u8         reserved_at_3e2[0x9];
        u8         log_max_vlan_list[0x5];
        u8         reserved_at_3f0[0x3];
        u8         log_max_current_mc_list[0x5];
@@@ -1187,7 -1194,8 +1194,8 @@@ struct mlx5_ifc_cong_control_r_roce_ecn
  
        u8         reserved_at_c0[0x12];
        u8         cnp_dscp[0x6];
-       u8         reserved_at_d8[0x5];
+       u8         reserved_at_d8[0x4];
+       u8         cnp_prio_mode[0x1];
        u8         cnp_802p_prio[0x3];
  
        u8         reserved_at_e0[0x720];
@@@ -2014,6 -2022,10 +2022,10 @@@ enum 
        MLX5_QPC_PM_STATE_MIGRATED  = 0x3,
  };
  
+ enum {
+       MLX5_QPC_OFFLOAD_TYPE_RNDV  = 0x1,
+ };
  enum {
        MLX5_QPC_END_PADDING_MODE_SCATTER_AS_IS                = 0x0,
        MLX5_QPC_END_PADDING_MODE_PAD_TO_CACHE_LINE_ALIGNMENT  = 0x1,
@@@ -2057,7 -2069,8 +2069,8 @@@ struct mlx5_ifc_qpc_bits 
        u8         st[0x8];
        u8         reserved_at_10[0x3];
        u8         pm_state[0x2];
-       u8         reserved_at_15[0x7];
+       u8         reserved_at_15[0x3];
+       u8         offload_type[0x4];
        u8         end_padding_mode[0x2];
        u8         reserved_at_1e[0x2];
  
@@@ -2437,7 -2450,7 +2450,7 @@@ struct mlx5_ifc_sqc_bits 
        u8         cd_master[0x1];
        u8         fre[0x1];
        u8         flush_in_error_en[0x1];
-       u8         reserved_at_4[0x1];
+       u8         allow_multi_pkt_send_wqe[0x1];
        u8         min_wqe_inline_mode[0x3];
        u8         state[0x4];
        u8         reg_umr[0x1];
@@@ -2515,7 -2528,7 +2528,7 @@@ enum 
  
  struct mlx5_ifc_rqc_bits {
        u8         rlky[0x1];
-       u8         reserved_at_1[0x1];
+       u8         delay_drop_en[0x1];
        u8         scatter_fcs[0x1];
        u8         vsd[0x1];
        u8         mem_rq_type[0x4];
@@@ -2562,7 -2575,9 +2575,9 @@@ struct mlx5_ifc_rmpc_bits 
  struct mlx5_ifc_nic_vport_context_bits {
        u8         reserved_at_0[0x5];
        u8         min_wqe_inline_mode[0x3];
-       u8         reserved_at_8[0x17];
+       u8         reserved_at_8[0x15];
+       u8         disable_mc_local_lb[0x1];
+       u8         disable_uc_local_lb[0x1];
        u8         roce_en[0x1];
  
        u8         arm_change_event[0x1];
@@@ -3000,7 -3015,7 +3015,7 @@@ struct mlx5_ifc_xrqc_bits 
  
        struct mlx5_ifc_tag_matching_topology_context_bits tag_matching_topology_context;
  
-       u8         reserved_at_180[0x880];
+       u8         reserved_at_180[0x280];
  
        struct mlx5_ifc_wq_bits wq;
  };
@@@ -3947,7 -3962,47 +3962,47 @@@ struct mlx5_ifc_query_q_counter_out_bit
  
        u8         local_ack_timeout_err[0x20];
  
-       u8         reserved_at_320[0x4e0];
+       u8         reserved_at_320[0xa0];
+       u8         resp_local_length_error[0x20];
+       u8         req_local_length_error[0x20];
+       u8         resp_local_qp_error[0x20];
+       u8         local_operation_error[0x20];
+       u8         resp_local_protection[0x20];
+       u8         req_local_protection[0x20];
+       u8         resp_cqe_error[0x20];
+       u8         req_cqe_error[0x20];
+       u8         req_mw_binding[0x20];
+       u8         req_bad_response[0x20];
+       u8         req_remote_invalid_request[0x20];
+       u8         resp_remote_invalid_request[0x20];
+       u8         req_remote_access_errors[0x20];
+       u8         resp_remote_access_errors[0x20];
+       u8         req_remote_operation_errors[0x20];
+       u8         req_transport_retries_exceeded[0x20];
+       u8         cq_overflow[0x20];
+       u8         resp_cqe_flush_error[0x20];
+       u8         req_cqe_flush_error[0x20];
+       u8         reserved_at_620[0x1e0];
  };
  
  struct mlx5_ifc_query_q_counter_in_bits {
@@@ -5229,7 -5284,9 +5284,9 @@@ struct mlx5_ifc_modify_nic_vport_contex
  };
  
  struct mlx5_ifc_modify_nic_vport_field_select_bits {
-       u8         reserved_at_0[0x16];
+       u8         reserved_at_0[0x14];
+       u8         disable_uc_local_lb[0x1];
+       u8         disable_mc_local_lb[0x1];
        u8         node_guid[0x1];
        u8         port_guid[0x1];
        u8         min_inline[0x1];
@@@ -5847,6 -5904,28 +5904,28 @@@ struct mlx5_ifc_destroy_rq_in_bits 
        u8         reserved_at_60[0x20];
  };
  
+ struct mlx5_ifc_set_delay_drop_params_in_bits {
+       u8         opcode[0x10];
+       u8         reserved_at_10[0x10];
+       u8         reserved_at_20[0x10];
+       u8         op_mod[0x10];
+       u8         reserved_at_40[0x20];
+       u8         reserved_at_60[0x10];
+       u8         delay_drop_timeout[0x10];
+ };
+ struct mlx5_ifc_set_delay_drop_params_out_bits {
+       u8         status[0x8];
+       u8         reserved_at_8[0x18];
+       u8         syndrome[0x20];
+       u8         reserved_at_40[0x40];
+ };
  struct mlx5_ifc_destroy_rmp_out_bits {
        u8         status[0x8];
        u8         reserved_at_8[0x18];
@@@ -7749,10 -7828,8 +7828,10 @@@ struct mlx5_ifc_pcam_reg_bits 
  };
  
  struct mlx5_ifc_mcam_enhanced_features_bits {
 -      u8         reserved_at_0[0x7f];
 +      u8         reserved_at_0[0x7d];
  
 +      u8         mtpps_enh_out_per_adj[0x1];
 +      u8         mtpps_fs[0x1];
        u8         pcie_performance_group[0x1];
  };
  
@@@ -8161,8 -8238,7 +8240,8 @@@ struct mlx5_ifc_mtpps_reg_bits 
        u8         reserved_at_78[0x4];
        u8         cap_pin_4_mode[0x4];
  
 -      u8         reserved_at_80[0x80];
 +      u8         field_select[0x20];
 +      u8         reserved_at_a0[0x60];
  
        u8         enable[0x1];
        u8         reserved_at_101[0xb];
  
        u8         out_pulse_duration[0x10];
        u8         out_periodic_adjustment[0x10];
 +      u8         enhanced_out_periodic_adjustment[0x20];
  
 -      u8         reserved_at_1a0[0x60];
 +      u8         reserved_at_1c0[0x20];
  };
  
  struct mlx5_ifc_mtppse_reg_bits {
diff --combined include/linux/pci.h
index f958d0732af685761c8b996cc6c79ca87f99f43f,c421af60f2df3a56f3d8dcc94b40e0a60feb829b..da05e5db06acbab4e8a6234c6a8b9a2c7f15cce3
@@@ -188,8 -188,6 +188,8 @@@ enum pci_dev_flags 
         * the direct_complete optimization.
         */
        PCI_DEV_FLAGS_NEEDS_RESUME = (__force pci_dev_flags_t) (1 << 11),
 +      /* Don't use Relaxed Ordering for TLPs directed at this device */
 +      PCI_DEV_FLAGS_NO_RELAXED_ORDERING = (__force pci_dev_flags_t) (1 << 12),
  };
  
  enum pci_irq_reroute_variant {
@@@ -731,6 -729,7 +731,7 @@@ struct pci_driver 
        void (*shutdown) (struct pci_dev *dev);
        int (*sriov_configure) (struct pci_dev *dev, int num_vfs); /* PF pdev */
        const struct pci_error_handlers *err_handler;
+       const struct attribute_group **groups;
        struct device_driver    driver;
        struct pci_dynids dynids;
  };
@@@ -1069,7 -1068,6 +1070,7 @@@ void pcie_flr(struct pci_dev *dev)
  int __pci_reset_function(struct pci_dev *dev);
  int __pci_reset_function_locked(struct pci_dev *dev);
  int pci_reset_function(struct pci_dev *dev);
 +int pci_reset_function_locked(struct pci_dev *dev);
  int pci_try_reset_function(struct pci_dev *dev);
  int pci_probe_reset_slot(struct pci_slot *slot);
  int pci_reset_slot(struct pci_slot *slot);
@@@ -1128,7 -1126,6 +1129,7 @@@ bool pci_check_pme_status(struct pci_de
  void pci_pme_wakeup_bus(struct pci_bus *bus);
  void pci_d3cold_enable(struct pci_dev *dev);
  void pci_d3cold_disable(struct pci_dev *dev);
 +bool pcie_relaxed_ordering_enabled(struct pci_dev *dev);
  
  /* PCI Virtual Channel */
  int pci_save_vc_state(struct pci_dev *dev);
This page took 0.185004 seconds and 4 git commands to generate.