]> Git Repo - linux.git/commitdiff
Merge tag 'rdma-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
authorLinus Torvalds <[email protected]>
Tue, 26 Feb 2013 19:41:08 +0000 (11:41 -0800)
committerLinus Torvalds <[email protected]>
Tue, 26 Feb 2013 19:41:08 +0000 (11:41 -0800)
Pull infiniband update from Roland Dreier:
 "Main batch of InfiniBand/RDMA changes for 3.9:

   - SRP error handling fixes from Bart Van Assche

   - Implementation of memory windows for mlx4 from Shani Michaeli

   - Lots of cxgb4 HW driver fixes from Vipul Pandya

   - Make iSER work for virtual functions, other fixes from Or Gerlitz

   - Fix for bug in qib HW driver from Mike Marciniszyn

   - IPoIB fixes from me, Itai Garbi, Shlomo Pongratz, Yan Burman

   - Various cleanups and warning fixes from Julia Lawall, Paul Bolle,
     Wei Yongjun"

* tag 'rdma-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband: (41 commits)
  IB/mlx4: Advertise MW support
  IB/mlx4: Support memory window binding
  mlx4: Implement memory windows allocation and deallocation
  mlx4_core: Enable memory windows in {INIT, QUERY}_HCA
  mlx4_core: Disable memory windows for virtual functions
  IPoIB: Free ipoib neigh on path record failure so path rec queries are retried
  IB/srp: Fail I/O requests if the transport is offline
  IB/srp: Avoid endless SCSI error handling loop
  IB/srp: Avoid sending a task management function needlessly
  IB/srp: Track connection state properly
  IB/mlx4: Remove redundant NULL check before kfree
  IB/mlx4: Fix compiler warning about uninitialized 'vlan' variable
  IB/mlx4: Convert is_xxx variables in build_mlx_header() to bool
  IB/iser: Enable iser when FMRs are not supported
  IB/iser: Avoid error prints on EAGAIN registration failures
  IB/iser: Use proper define for the commands per LUN value advertised to SCSI ML
  IB/uverbs: Implement memory windows support in uverbs
  IB/core: Add "type 2" memory windows support
  mlx4_core: Propagate MR deregistration failures to caller
  mlx4_core: Rename MPT-related functions to have mpt_ prefix
  ...

1  2 
drivers/infiniband/hw/cxgb3/iwch_provider.c
drivers/net/ethernet/mellanox/mlx4/en_main.c
drivers/net/ethernet/mellanox/mlx4/fw.c
drivers/net/ethernet/mellanox/mlx4/fw.h
drivers/net/ethernet/mellanox/mlx4/main.c
drivers/net/ethernet/mellanox/mlx4/mlx4.h
drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
include/linux/mlx4/device.h

index 145d82a64d0af8bf18d4caf89fa968ea28832f52,074d5c25f50b2cabedd810d6d40898325b12fce7..9c12da0cbd32539b5a8060a7a6deed8101cdd25d
@@@ -738,7 -738,7 +738,7 @@@ static struct ib_mr *iwch_get_dma_mr(st
        return ibmr;
  }
  
- static struct ib_mw *iwch_alloc_mw(struct ib_pd *pd)
+ static struct ib_mw *iwch_alloc_mw(struct ib_pd *pd, enum ib_mw_type type)
  {
        struct iwch_dev *rhp;
        struct iwch_pd *php;
        u32 stag = 0;
        int ret;
  
+       if (type != IB_MW_TYPE_1)
+               return ERR_PTR(-EINVAL);
        php = to_iwch_pd(pd);
        rhp = php->rhp;
        mhp = kzalloc(sizeof(*mhp), GFP_KERNEL);
@@@ -783,8 -786,8 +786,8 @@@ static int iwch_dealloc_mw(struct ib_m
        mmid = (mw->rkey) >> 8;
        cxio_deallocate_window(&rhp->rdev, mhp->attr.stag);
        remove_handle(rhp, &rhp->mmidr, mmid);
 -      kfree(mhp);
        PDBG("%s ib_mw %p mmid 0x%x ptr %p\n", __func__, mw, mmid, mhp);
 +      kfree(mhp);
        return 0;
  }
  
index b2cca58de910c8c4ec1bac50175a8b4457ac4e88,a2987142734d658dfcfb5ec9b0fa9d74d6671b16..fc27800e9c383824390195445a2f45e365db61b7
@@@ -64,7 -64,7 +64,7 @@@ static const char mlx4_en_version[] 
  
  /* Enable RSS UDP traffic */
  MLX4_EN_PARM_INT(udp_rss, 1,
 -               "Enable RSS for incomming UDP traffic or disabled (0)");
 +               "Enable RSS for incoming UDP traffic or disabled (0)");
  
  /* Priority pausing */
  MLX4_EN_PARM_INT(pfctx, 0, "Priority based Flow Control policy on TX[7:0]."
@@@ -95,28 -95,6 +95,28 @@@ int en_print(const char *level, const s
        return i;
  }
  
 +void mlx4_en_update_loopback_state(struct net_device *dev,
 +                                 netdev_features_t features)
 +{
 +      struct mlx4_en_priv *priv = netdev_priv(dev);
 +
 +      priv->flags &= ~(MLX4_EN_FLAG_RX_FILTER_NEEDED|
 +                      MLX4_EN_FLAG_ENABLE_HW_LOOPBACK);
 +
 +      /* Drop the packet if SRIOV is not enabled
 +       * and not performing the selftest or flb disabled
 +       */
 +      if (mlx4_is_mfunc(priv->mdev->dev) &&
 +          !(features & NETIF_F_LOOPBACK) && !priv->validate_loopback)
 +              priv->flags |= MLX4_EN_FLAG_RX_FILTER_NEEDED;
 +
 +      /* Set dmac in Tx WQE if we are in SRIOV mode or if loopback selftest
 +       * is requested
 +       */
 +      if (mlx4_is_mfunc(priv->mdev->dev) || priv->validate_loopback)
 +              priv->flags |= MLX4_EN_FLAG_ENABLE_HW_LOOPBACK;
 +}
 +
  static int mlx4_en_get_profile(struct mlx4_en_dev *mdev)
  {
        struct mlx4_en_profile *params = &mdev->profile;
@@@ -198,7 -176,7 +198,7 @@@ static void mlx4_en_remove(struct mlx4_
  
        flush_workqueue(mdev->workqueue);
        destroy_workqueue(mdev->workqueue);
-       mlx4_mr_free(dev, &mdev->mr);
+       (void) mlx4_mr_free(dev, &mdev->mr);
        iounmap(mdev->uar_map);
        mlx4_uar_free(dev, &mdev->priv_uar);
        mlx4_pd_free(dev, mdev->priv_pdn);
@@@ -213,8 -191,10 +213,8 @@@ static void *mlx4_en_add(struct mlx4_de
  
        printk_once(KERN_INFO "%s", mlx4_en_version);
  
 -      mdev = kzalloc(sizeof *mdev, GFP_KERNEL);
 +      mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
        if (!mdev) {
 -              dev_err(&dev->pdev->dev, "Device struct alloc failed, "
 -                      "aborting.\n");
                err = -ENOMEM;
                goto err_free_res;
        }
        return mdev;
  
  err_mr:
-       mlx4_mr_free(dev, &mdev->mr);
+       (void) mlx4_mr_free(dev, &mdev->mr);
  err_map:
        if (!mdev->uar_map)
                iounmap(mdev->uar_map);
index 38b62c78d5daf79c991bf094c22e63515efa664b,d136b36952587b256c0b63074c059dbc298ef9e1..50917eb3013e1bad3aef4a572a006002d5ba61f0
@@@ -127,8 -127,7 +127,8 @@@ static void dump_dev_cap_flags2(struct 
                [0] = "RSS support",
                [1] = "RSS Toeplitz Hash Function support",
                [2] = "RSS XOR Hash Function support",
 -              [3] = "Device manage flow steering support"
 +              [3] = "Device manage flow steering support",
 +              [4] = "Automatic mac reassignment support"
        };
        int i;
  
@@@ -479,7 -478,6 +479,7 @@@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev 
  #define QUERY_DEV_CAP_BMME_FLAGS_OFFSET               0x94
  #define QUERY_DEV_CAP_RSVD_LKEY_OFFSET                0x98
  #define QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET               0xa0
 +#define QUERY_DEV_CAP_FW_REASSIGN_MAC         0x9d
  
        dev_cap->flags2 = 0;
        mailbox = mlx4_alloc_cmd_mailbox(dev);
                 QUERY_DEV_CAP_BMME_FLAGS_OFFSET);
        MLX4_GET(dev_cap->reserved_lkey, outbox,
                 QUERY_DEV_CAP_RSVD_LKEY_OFFSET);
 +      MLX4_GET(field, outbox, QUERY_DEV_CAP_FW_REASSIGN_MAC);
 +      if (field & 1<<6)
 +              dev_cap->flags2 |= MLX4_DEV_CAP_FLAGS2_REASSIGN_MAC_EN;
        MLX4_GET(dev_cap->max_icm_sz, outbox,
                 QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET);
        if (dev_cap->flags & MLX4_DEV_CAP_FLAG_COUNTERS)
@@@ -762,15 -757,19 +762,19 @@@ int mlx4_QUERY_DEV_CAP_wrapper(struct m
        u64     flags;
        int     err = 0;
        u8      field;
+       u32     bmme_flags;
  
        err = mlx4_cmd_box(dev, 0, outbox->dma, 0, 0, MLX4_CMD_QUERY_DEV_CAP,
                           MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE);
        if (err)
                return err;
  
-       /* add port mng change event capability unconditionally to slaves */
+       /* add port mng change event capability and disable mw type 1
+        * unconditionally to slaves
+        */
        MLX4_GET(flags, outbox->buf, QUERY_DEV_CAP_EXT_FLAGS_OFFSET);
        flags |= MLX4_DEV_CAP_FLAG_PORT_MNG_CHG_EV;
+       flags &= ~MLX4_DEV_CAP_FLAG_MEM_WINDOW;
        MLX4_PUT(outbox->buf, flags, QUERY_DEV_CAP_EXT_FLAGS_OFFSET);
  
        /* For guests, report Blueflame disabled */
        field &= 0x7f;
        MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_BF_OFFSET);
  
+       /* For guests, disable mw type 2 */
+       MLX4_GET(bmme_flags, outbox, QUERY_DEV_CAP_BMME_FLAGS_OFFSET);
+       bmme_flags &= ~MLX4_BMME_FLAG_TYPE_2_WIN;
+       MLX4_PUT(outbox->buf, bmme_flags, QUERY_DEV_CAP_BMME_FLAGS_OFFSET);
        return 0;
  }
  
@@@ -1203,6 -1207,7 +1212,7 @@@ int mlx4_INIT_HCA(struct mlx4_dev *dev
  #define  INIT_HCA_FS_IB_NUM_ADDRS_OFFSET  (INIT_HCA_FS_PARAM_OFFSET + 0x26)
  #define INIT_HCA_TPT_OFFSET            0x0f0
  #define        INIT_HCA_DMPT_BASE_OFFSET       (INIT_HCA_TPT_OFFSET + 0x00)
+ #define  INIT_HCA_TPT_MW_OFFSET                (INIT_HCA_TPT_OFFSET + 0x08)
  #define        INIT_HCA_LOG_MPT_SZ_OFFSET      (INIT_HCA_TPT_OFFSET + 0x0b)
  #define        INIT_HCA_MTT_BASE_OFFSET        (INIT_HCA_TPT_OFFSET + 0x10)
  #define        INIT_HCA_CMPT_BASE_OFFSET       (INIT_HCA_TPT_OFFSET + 0x18)
                /* Enable Ethernet flow steering
                 * with udp unicast and tcp unicast
                 */
 -              MLX4_PUT(inbox, param->fs_hash_enable_bits,
 +              MLX4_PUT(inbox, (u8) (MLX4_FS_UDP_UC_EN | MLX4_FS_TCP_UC_EN),
                         INIT_HCA_FS_ETH_BITS_OFFSET);
                MLX4_PUT(inbox, (u16) MLX4_FS_NUM_OF_L2_ADDR,
                         INIT_HCA_FS_ETH_NUM_ADDRS_OFFSET);
                /* Enable IPoIB flow steering
                 * with udp unicast and tcp unicast
                 */
 -              MLX4_PUT(inbox, param->fs_hash_enable_bits,
 +              MLX4_PUT(inbox, (u8) (MLX4_FS_UDP_UC_EN | MLX4_FS_TCP_UC_EN),
                         INIT_HCA_FS_IB_BITS_OFFSET);
                MLX4_PUT(inbox, (u16) MLX4_FS_NUM_OF_L2_ADDR,
                         INIT_HCA_FS_IB_NUM_ADDRS_OFFSET);
        /* TPT attributes */
  
        MLX4_PUT(inbox, param->dmpt_base,  INIT_HCA_DMPT_BASE_OFFSET);
+       MLX4_PUT(inbox, param->mw_enabled, INIT_HCA_TPT_MW_OFFSET);
        MLX4_PUT(inbox, param->log_mpt_sz, INIT_HCA_LOG_MPT_SZ_OFFSET);
        MLX4_PUT(inbox, param->mtt_base,   INIT_HCA_MTT_BASE_OFFSET);
        MLX4_PUT(inbox, param->cmpt_base,  INIT_HCA_CMPT_BASE_OFFSET);
@@@ -1415,6 -1421,7 +1426,7 @@@ int mlx4_QUERY_HCA(struct mlx4_dev *dev
        /* TPT attributes */
  
        MLX4_GET(param->dmpt_base,  outbox, INIT_HCA_DMPT_BASE_OFFSET);
+       MLX4_GET(param->mw_enabled, outbox, INIT_HCA_TPT_MW_OFFSET);
        MLX4_GET(param->log_mpt_sz, outbox, INIT_HCA_LOG_MPT_SZ_OFFSET);
        MLX4_GET(param->mtt_base,   outbox, INIT_HCA_MTT_BASE_OFFSET);
        MLX4_GET(param->cmpt_base,  outbox, INIT_HCA_CMPT_BASE_OFFSET);
index 3af33ff669cca2fc3b500607f34ef4bc10ff9595,9f1a25ca002c02b2736cdab3e799c6fae3b2d2b1..151c2bb380a60466443bcf7bb2ee6adc4be48ecc
@@@ -170,7 -170,9 +170,8 @@@ struct mlx4_init_hca_param 
        u8  log_mc_table_sz;
        u8  log_mpt_sz;
        u8  log_uar_sz;
+       u8  mw_enabled;  /* Enable memory windows */
        u8  uar_page_sz; /* log pg sz in 4k chunks */
 -      u8  fs_hash_enable_bits;
        u8  steering_mode; /* for QUERY_HCA */
        u64 dev_cap_enabled;
  };
index b9dde139dac5b0df1a2d3e99a9d4523b19aaf38e,7fdd04af379d6a9e2dc3616dc7e01071ab5fc9f3..d180bc46826afd0189eb7aa0360baf598615c02b
@@@ -1415,6 -1415,22 +1415,6 @@@ static int mlx4_init_hca(struct mlx4_de
                if (mlx4_is_master(dev))
                        mlx4_parav_master_pf_caps(dev);
  
 -              priv->fs_hash_mode = MLX4_FS_L2_HASH;
 -
 -              switch (priv->fs_hash_mode) {
 -              case MLX4_FS_L2_HASH:
 -                      init_hca.fs_hash_enable_bits = 0;
 -                      break;
 -
 -              case MLX4_FS_L2_L3_L4_HASH:
 -                      /* Enable flow steering with
 -                       * udp unicast and tcp unicast
 -                       */
 -                      init_hca.fs_hash_enable_bits =
 -                              MLX4_FS_UDP_UC_EN | MLX4_FS_TCP_UC_EN;
 -                      break;
 -              }
 -
                profile = default_profile;
                if (dev->caps.steering_mode ==
                    MLX4_STEERING_MODE_DEVICE_MANAGED)
  
                init_hca.log_uar_sz = ilog2(dev->caps.num_uars);
                init_hca.uar_page_sz = PAGE_SHIFT - 12;
+               init_hca.mw_enabled = 0;
+               if (dev->caps.flags & MLX4_DEV_CAP_FLAG_MEM_WINDOW ||
+                   dev->caps.bmme_flags & MLX4_BMME_FLAG_TYPE_2_WIN)
+                       init_hca.mw_enabled = INIT_HCA_TPT_MW_ENABLE;
  
                err = mlx4_init_icm(dev, &dev_cap, &init_hca, icm_size);
                if (err)
@@@ -1833,9 -1853,12 +1837,9 @@@ static int mlx4_init_port_info(struct m
        info->dev = dev;
        info->port = port;
        if (!mlx4_is_slave(dev)) {
 -              INIT_RADIX_TREE(&info->mac_tree, GFP_KERNEL);
                mlx4_init_mac_table(dev, &info->mac_table);
                mlx4_init_vlan_table(dev, &info->vlan_table);
 -              info->base_qpn =
 -                      dev->caps.reserved_qps_base[MLX4_QP_REGION_ETH_ADDR] +
 -                      (port - 1) * (1 << log_num_mac);
 +              info->base_qpn = mlx4_get_base_qpn(dev, port);
        }
  
        sprintf(info->dev_name, "mlx4_port%d", port);
@@@ -2051,8 -2074,10 +2055,8 @@@ static int __mlx4_init_one(struct pci_d
        /* Allow large DMA segments, up to the firmware limit of 1 GB */
        dma_set_max_seg_size(&pdev->dev, 1024 * 1024 * 1024);
  
 -      priv = kzalloc(sizeof *priv, GFP_KERNEL);
 +      priv = kzalloc(sizeof(*priv), GFP_KERNEL);
        if (!priv) {
 -              dev_err(&pdev->dev, "Device struct alloc failed, "
 -                      "aborting.\n");
                err = -ENOMEM;
                goto err_release_regions;
        }
@@@ -2141,8 -2166,7 +2145,8 @@@ slave_start
                        dev->num_slaves = MLX4_MAX_NUM_SLAVES;
                else {
                        dev->num_slaves = 0;
 -                      if (mlx4_multi_func_init(dev)) {
 +                      err = mlx4_multi_func_init(dev);
 +                      if (err) {
                                mlx4_err(dev, "Failed to init slave mfunc"
                                         " interface, aborting.\n");
                                goto err_cmd;
        /* In master functions, the communication channel must be initialized
         * after obtaining its address from fw */
        if (mlx4_is_master(dev)) {
 -              if (mlx4_multi_func_init(dev)) {
 +              err = mlx4_multi_func_init(dev);
 +              if (err) {
                        mlx4_err(dev, "Failed to init master mfunc"
                                 "interface, aborting.\n");
                        goto err_close;
        mlx4_enable_msi_x(dev);
        if ((mlx4_is_mfunc(dev)) &&
            !(dev->flags & MLX4_FLAG_MSI_X)) {
 +              err = -ENOSYS;
                mlx4_err(dev, "INTx is not supported in multi-function mode."
                         " aborting.\n");
                goto err_free_eq;
index ed4a6959e828e9b2ee1163de9d644df72876887a,8b75d5ef0940b9758cea7d1ec1235867d990276f..cf883345af8887eeac97eb5b7278b98a98ffe4bb
  #define MLX4_FS_MGM_LOG_ENTRY_SIZE    7
  #define MLX4_FS_NUM_MCG                       (1 << 17)
  
 -enum {
 -      MLX4_FS_L2_HASH = 0,
 -      MLX4_FS_L2_L3_L4_HASH,
 -};
 -
+ #define INIT_HCA_TPT_MW_ENABLE          (1 << 7)
  #define MLX4_NUM_UP           8
  #define MLX4_NUM_TC           8
  #define MLX4_RATELIMIT_UNITS 3 /* 100 Mbps */
@@@ -113,10 -120,10 +115,10 @@@ enum 
        MLX4_NUM_CMPTS          = MLX4_CMPT_NUM_TYPE << MLX4_CMPT_SHIFT
  };
  
- enum mlx4_mr_state {
-       MLX4_MR_DISABLED = 0,
-       MLX4_MR_EN_HW,
-       MLX4_MR_EN_SW
+ enum mlx4_mpt_state {
+       MLX4_MPT_DISABLED = 0,
+       MLX4_MPT_EN_HW,
+       MLX4_MPT_EN_SW
  };
  
  #define MLX4_COMM_TIME                10000
@@@ -263,6 -270,22 +265,22 @@@ struct mlx4_icm_table 
        struct mlx4_icm       **icm;
  };
  
+ #define MLX4_MPT_FLAG_SW_OWNS     (0xfUL << 28)
+ #define MLX4_MPT_FLAG_FREE        (0x3UL << 28)
+ #define MLX4_MPT_FLAG_MIO         (1 << 17)
+ #define MLX4_MPT_FLAG_BIND_ENABLE   (1 << 15)
+ #define MLX4_MPT_FLAG_PHYSICAL            (1 <<  9)
+ #define MLX4_MPT_FLAG_REGION      (1 <<  8)
+ #define MLX4_MPT_PD_FLAG_FAST_REG   (1 << 27)
+ #define MLX4_MPT_PD_FLAG_RAE      (1 << 28)
+ #define MLX4_MPT_PD_FLAG_EN_INV           (3 << 24)
+ #define MLX4_MPT_QP_FLAG_BOUND_QP   (1 << 7)
+ #define MLX4_MPT_STATUS_SW            0xF0
+ #define MLX4_MPT_STATUS_HW            0x00
  /*
   * Must be packed because mtt_seg is 64 bits but only aligned to 32 bits.
   */
@@@ -653,6 -676,11 +671,6 @@@ struct mlx4_set_port_rqp_calc_context 
        __be32 mcast;
  };
  
 -struct mlx4_mac_entry {
 -      u64 mac;
 -      u64 reg_id;
 -};
 -
  struct mlx4_port_info {
        struct mlx4_dev        *dev;
        int                     port;
        char                    dev_mtu_name[16];
        struct device_attribute port_mtu_attr;
        struct mlx4_mac_table   mac_table;
 -      struct radix_tree_root  mac_tree;
        struct mlx4_vlan_table  vlan_table;
        int                     base_qpn;
  };
@@@ -685,12 -714,9 +703,12 @@@ struct mlx4_steer 
  
  struct mlx4_net_trans_rule_hw_ctrl {
        __be32 ctrl;
 -      __be32 vf_vep_port;
 +      u8 rsvd1;
 +      u8 funcid;
 +      u8 vep;
 +      u8 port;
        __be32 qpn;
 -      __be32 reserved;
 +      __be32 rsvd2;
  };
  
  struct mlx4_net_trans_rule_hw_ib {
@@@ -863,10 -889,10 +881,10 @@@ int __mlx4_cq_alloc_icm(struct mlx4_de
  void __mlx4_cq_free_icm(struct mlx4_dev *dev, int cqn);
  int __mlx4_srq_alloc_icm(struct mlx4_dev *dev, int *srqn);
  void __mlx4_srq_free_icm(struct mlx4_dev *dev, int srqn);
- int __mlx4_mr_reserve(struct mlx4_dev *dev);
- void __mlx4_mr_release(struct mlx4_dev *dev, u32 index);
- int __mlx4_mr_alloc_icm(struct mlx4_dev *dev, u32 index);
- void __mlx4_mr_free_icm(struct mlx4_dev *dev, u32 index);
+ int __mlx4_mpt_reserve(struct mlx4_dev *dev);
+ void __mlx4_mpt_release(struct mlx4_dev *dev, u32 index);
+ int __mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index);
+ void __mlx4_mpt_free_icm(struct mlx4_dev *dev, u32 index);
  u32 __mlx4_alloc_mtt_range(struct mlx4_dev *dev, int order);
  void __mlx4_free_mtt_range(struct mlx4_dev *dev, u32 first_seg, int order);
  
@@@ -910,6 -936,7 +928,6 @@@ int __mlx4_qp_reserve_range(struct mlx4
  void __mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt);
  int __mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac);
  void __mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac);
 -int __mlx4_replace_mac(struct mlx4_dev *dev, u8 port, int qpn, u64 new_mac);
  int __mlx4_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
                     int start_index, int npages, u64 *page_list);
  int __mlx4_counter_alloc(struct mlx4_dev *dev, u32 *idx);
index 5997adc943d095ff968aab47e9929b8f7630fc27,9185e2eef8fa96bbee8992586450d34b24054efb..083fb48dc3d7bd7bfa014f8ddc9a7eed81dffca5
@@@ -1231,14 -1231,14 +1231,14 @@@ static int mpt_alloc_res(struct mlx4_de
  
        switch (op) {
        case RES_OP_RESERVE:
-               index = __mlx4_mr_reserve(dev);
+               index = __mlx4_mpt_reserve(dev);
                if (index == -1)
                        break;
                id = index & mpt_mask(dev);
  
                err = add_res_range(dev, slave, id, 1, RES_MPT, index);
                if (err) {
-                       __mlx4_mr_release(dev, index);
+                       __mlx4_mpt_release(dev, index);
                        break;
                }
                set_param_l(out_param, index);
                if (err)
                        return err;
  
-               err = __mlx4_mr_alloc_icm(dev, mpt->key);
+               err = __mlx4_mpt_alloc_icm(dev, mpt->key);
                if (err) {
                        res_abort_move(dev, slave, RES_MPT, id);
                        return err;
@@@ -1586,7 -1586,7 +1586,7 @@@ static int mpt_free_res(struct mlx4_de
                err = rem_res_range(dev, slave, id, 1, RES_MPT, 0);
                if (err)
                        break;
-               __mlx4_mr_release(dev, index);
+               __mlx4_mpt_release(dev, index);
                break;
        case RES_OP_MAP_ICM:
                        index = get_param_l(&in_param);
                        if (err)
                                return err;
  
-                       __mlx4_mr_free_icm(dev, mpt->key);
+                       __mlx4_mpt_free_icm(dev, mpt->key);
                        res_end_move(dev, slave, RES_MPT, id);
                        return err;
                break;
@@@ -1796,6 -1796,26 +1796,26 @@@ static int mr_get_mtt_size(struct mlx4_
        return be32_to_cpu(mpt->mtt_sz);
  }
  
+ static u32 mr_get_pd(struct mlx4_mpt_entry *mpt)
+ {
+       return be32_to_cpu(mpt->pd_flags) & 0x00ffffff;
+ }
+ static int mr_is_fmr(struct mlx4_mpt_entry *mpt)
+ {
+       return be32_to_cpu(mpt->pd_flags) & MLX4_MPT_PD_FLAG_FAST_REG;
+ }
+ static int mr_is_bind_enabled(struct mlx4_mpt_entry *mpt)
+ {
+       return be32_to_cpu(mpt->flags) & MLX4_MPT_FLAG_BIND_ENABLE;
+ }
+ static int mr_is_region(struct mlx4_mpt_entry *mpt)
+ {
+       return be32_to_cpu(mpt->flags) & MLX4_MPT_FLAG_REGION;
+ }
  static int qp_get_mtt_addr(struct mlx4_qp_context *qpc)
  {
        return be32_to_cpu(qpc->mtt_base_addr_l) & 0xfffffff8;
@@@ -1856,12 -1876,41 +1876,41 @@@ int mlx4_SW2HW_MPT_wrapper(struct mlx4_
        int mtt_base = mr_get_mtt_addr(inbox->buf) / dev->caps.mtt_entry_sz;
        int phys;
        int id;
+       u32 pd;
+       int pd_slave;
  
        id = index & mpt_mask(dev);
        err = mr_res_start_move_to(dev, slave, id, RES_MPT_HW, &mpt);
        if (err)
                return err;
  
+       /* Disable memory windows for VFs. */
+       if (!mr_is_region(inbox->buf)) {
+               err = -EPERM;
+               goto ex_abort;
+       }
+       /* Make sure that the PD bits related to the slave id are zeros. */
+       pd = mr_get_pd(inbox->buf);
+       pd_slave = (pd >> 17) & 0x7f;
+       if (pd_slave != 0 && pd_slave != slave) {
+               err = -EPERM;
+               goto ex_abort;
+       }
+       if (mr_is_fmr(inbox->buf)) {
+               /* FMR and Bind Enable are forbidden in slave devices. */
+               if (mr_is_bind_enabled(inbox->buf)) {
+                       err = -EPERM;
+                       goto ex_abort;
+               }
+               /* FMR and Memory Windows are also forbidden. */
+               if (!mr_is_region(inbox->buf)) {
+                       err = -EPERM;
+                       goto ex_abort;
+               }
+       }
        phys = mr_phys_mpt(inbox->buf);
        if (!phys) {
                err = get_res(dev, slave, mtt_base, RES_MTT, &mtt);
@@@ -3018,7 -3067,7 +3067,7 @@@ static int add_eth_header(struct mlx4_d
        __be64 mac_msk = cpu_to_be64(MLX4_MAC_MASK << 16);
  
        ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf;
 -      port = be32_to_cpu(ctrl->vf_vep_port) & 0xff;
 +      port = ctrl->port;
        eth_header = (struct mlx4_net_trans_rule_hw_eth *)(ctrl + 1);
  
        /* Clear a space in the inbox for eth header */
@@@ -3480,7 -3529,7 +3529,7 @@@ static void rem_slave_mrs(struct mlx4_d
                        while (state != 0) {
                                switch (state) {
                                case RES_MPT_RESERVED:
-                                       __mlx4_mr_release(dev, mpt->key);
+                                       __mlx4_mpt_release(dev, mpt->key);
                                        spin_lock_irq(mlx4_tlock(dev));
                                        rb_erase(&mpt->com.node,
                                                 &tracker->res_tree[RES_MPT]);
                                        break;
  
                                case RES_MPT_MAPPED:
-                                       __mlx4_mr_free_icm(dev, mpt->key);
+                                       __mlx4_mpt_free_icm(dev, mpt->key);
                                        state = RES_MPT_RESERVED;
                                        break;
  
index 6d48fce06b4ae360c52fa17101892c8ba4024d9a,67b4695e5940d0592c499974cee1646f92f2772e..811f91cf5e8cbf19dd15449060b3336d7e94b8fe
@@@ -150,8 -150,7 +150,8 @@@ enum 
        MLX4_DEV_CAP_FLAG2_RSS                  = 1LL <<  0,
        MLX4_DEV_CAP_FLAG2_RSS_TOP              = 1LL <<  1,
        MLX4_DEV_CAP_FLAG2_RSS_XOR              = 1LL <<  2,
 -      MLX4_DEV_CAP_FLAG2_FS_EN                = 1LL <<  3
 +      MLX4_DEV_CAP_FLAG2_FS_EN                = 1LL <<  3,
 +      MLX4_DEV_CAP_FLAGS2_REASSIGN_MAC_EN     = 1LL <<  4
  };
  
  enum {
@@@ -171,6 -170,7 +171,7 @@@ enum 
  #define MLX4_ATTR_EXTENDED_PORT_INFO  cpu_to_be16(0xff90)
  
  enum {
+       MLX4_BMME_FLAG_WIN_TYPE_2B      = 1 <<  1,
        MLX4_BMME_FLAG_LOCAL_INV        = 1 <<  6,
        MLX4_BMME_FLAG_REMOTE_INV       = 1 <<  7,
        MLX4_BMME_FLAG_TYPE_2_WIN       = 1 <<  9,
@@@ -238,7 -238,8 +239,8 @@@ enum 
        MLX4_PERM_LOCAL_WRITE   = 1 << 11,
        MLX4_PERM_REMOTE_READ   = 1 << 12,
        MLX4_PERM_REMOTE_WRITE  = 1 << 13,
-       MLX4_PERM_ATOMIC        = 1 << 14
+       MLX4_PERM_ATOMIC        = 1 << 14,
+       MLX4_PERM_BIND_MW       = 1 << 15,
  };
  
  enum {
@@@ -504,6 -505,18 +506,18 @@@ struct mlx4_mr 
        int                     enabled;
  };
  
+ enum mlx4_mw_type {
+       MLX4_MW_TYPE_1 = 1,
+       MLX4_MW_TYPE_2 = 2,
+ };
+ struct mlx4_mw {
+       u32                     key;
+       u32                     pd;
+       enum mlx4_mw_type       type;
+       int                     enabled;
+ };
  struct mlx4_fmr {
        struct mlx4_mr          mr;
        struct mlx4_mpt_entry  *mpt;
@@@ -802,8 -815,12 +816,12 @@@ u64 mlx4_mtt_addr(struct mlx4_dev *dev
  
  int mlx4_mr_alloc(struct mlx4_dev *dev, u32 pd, u64 iova, u64 size, u32 access,
                  int npages, int page_shift, struct mlx4_mr *mr);
void mlx4_mr_free(struct mlx4_dev *dev, struct mlx4_mr *mr);
int mlx4_mr_free(struct mlx4_dev *dev, struct mlx4_mr *mr);
  int mlx4_mr_enable(struct mlx4_dev *dev, struct mlx4_mr *mr);
+ int mlx4_mw_alloc(struct mlx4_dev *dev, u32 pd, enum mlx4_mw_type type,
+                 struct mlx4_mw *mw);
+ void mlx4_mw_free(struct mlx4_dev *dev, struct mlx4_mw *mw);
+ int mlx4_mw_enable(struct mlx4_dev *dev, struct mlx4_mw *mw);
  int mlx4_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
                   int start_index, int npages, u64 *page_list);
  int mlx4_buf_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
@@@ -956,8 -973,9 +974,8 @@@ int mlx4_SET_MCAST_FLTR(struct mlx4_de
  
  int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac);
  void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac);
 -int mlx4_replace_mac(struct mlx4_dev *dev, u8 port, int qpn, u64 new_mac);
 -int mlx4_get_eth_qp(struct mlx4_dev *dev, u8 port, u64 mac, int *qpn);
 -void mlx4_put_eth_qp(struct mlx4_dev *dev, u8 port, u64 mac, int qpn);
 +int mlx4_get_base_qpn(struct mlx4_dev *dev, u8 port);
 +int __mlx4_replace_mac(struct mlx4_dev *dev, u8 port, int qpn, u64 new_mac);
  void mlx4_set_stats_bitmap(struct mlx4_dev *dev, u64 *stats_bitmap);
  int mlx4_SET_PORT_general(struct mlx4_dev *dev, u8 port, int mtu,
                          u8 pptx, u8 pfctx, u8 pprx, u8 pfcrx);
This page took 0.108958 seconds and 4 git commands to generate.