History

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma

Pull rdma updates from Jason Gunthorpe: "A quiet cycle after the larger 5.8 effort. Substantially cleanup and driver work with a few smaller features this time. - Driver updates for hfi1, rxe, mlx5, hns, qedr, usnic, bnxt_re - Removal of dead or redundant code across the drivers - RAW resource tracker dumps to include a device specific data blob for device objects to aide device debugging - Further advance the IOCTL interface, remove the ability to turn it off. Add QUERY_CONTEXT, QUERY_MR, and QUERY_PD commands - Remove stubs related to devices with no pkey table - A shared CQ scheme to allow multiple ULPs to share the CQ rings of a device to give higher performance - Several more static checker, syzkaller and rare crashers fixed" * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: (121 commits) RDMA/mlx5: Fix flow destination setting for RDMA TX flow table RDMA/rxe: Remove pkey table RDMA/umem: Add a schedule point in ib_umem_get() RDMA/hns: Fix the unneeded process when getting a general type of CQE error RDMA/hns: Fix error during modify qp RTS2RTS RDMA/hns: Delete unnecessary memset when allocating VF resource RDMA/hns: Remove redundant parameters in set_rc_wqe() RDMA/hns: Remove support for HIP08_A RDMA/hns: Refactor hns_roce_v2_set_hem() RDMA/hns: Remove redundant hardware opcode definitions RDMA/netlink: Remove CAP_NET_RAW check when dump a raw QP RDMA/include: Replace license text with SPDX tags RDMA/rtrs: remove WQ_MEM_RECLAIM for rtrs_wq RDMA/rtrs-clt: add an additional random 8 seconds before reconnecting RDMA/cma: Execute rdma_cm destruction from a handler properly RDMA/cma: Remove unneeded locking for req paths RDMA/cma: Using the standard locking pattern when delivering the removal event RDMA/cma: Simplify DEVICE_REMOVAL for internal_id RDMA/efa: Add EFA 0xefa1 PCI ID RDMA/efa: User/kernel compatibility handshake mechanism ...

Linus Torvalds committed 6 years ago

Commit d7806bb2 parents d6efb3a 23fcc7d166 files · +6945 −7569Browse files

Unified · Split

166 files
  1. MAINTAINERS +1 −0
  2. drivers/infiniband/Kconfig +0 −8
  3. drivers/infiniband/core/cache.c +29 −16
  4. drivers/infiniband/core/cma.c +123 −134
  5. drivers/infiniband/core/counters.c +7 −17
  6. drivers/infiniband/core/device.c +22 −6
  7. drivers/infiniband/core/mad.c +15 −15
  8. drivers/infiniband/core/mad_priv.h +1 −1
  9. drivers/infiniband/core/mad_rmpp.c +9 −18
  10. drivers/infiniband/core/nldev.c +126 −97
  11. drivers/infiniband/core/sysfs.c +41 −20
  12. drivers/infiniband/core/trace.c +0 −2
  13. drivers/infiniband/core/umem.c +1 −0
  14. drivers/infiniband/core/umem_odp.c +2 −0
  15. drivers/infiniband/core/uverbs_cmd.c +99 −222
  16. drivers/infiniband/core/uverbs_ioctl.c +1 −0
  17. drivers/infiniband/core/uverbs_main.c +4 −0
  18. drivers/infiniband/core/uverbs_std_types_counters.c +9 −8
  19. drivers/infiniband/core/uverbs_std_types_cq.c +0 −3
  20. drivers/infiniband/core/uverbs_std_types_device.c +46 −2
  21. drivers/infiniband/core/uverbs_std_types_mr.c +52 −2
  22. drivers/infiniband/core/verbs.c +78 −107
  23. drivers/infiniband/hw/bnxt_re/ib_verbs.c +128 −42
  24. drivers/infiniband/hw/bnxt_re/ib_verbs.h +5 −5
  25. drivers/infiniband/hw/bnxt_re/main.c +17 −6
  26. drivers/infiniband/hw/bnxt_re/qplib_fp.c +425 −326
  27. drivers/infiniband/hw/bnxt_re/qplib_fp.h +122 −5
  28. drivers/infiniband/hw/bnxt_re/qplib_res.h +46 −12
  29. drivers/infiniband/hw/bnxt_re/roce_hsi.h +1 −0
  30. drivers/infiniband/hw/cxgb4/iw_cxgb4.h +5 −4
  31. drivers/infiniband/hw/cxgb4/mem.c +1 −2
  32. drivers/infiniband/hw/cxgb4/provider.c +3 −19
  33. drivers/infiniband/hw/cxgb4/restrack.c +5 −19
  34. drivers/infiniband/hw/efa/efa_admin_cmds_defs.h +13 −2
  35. drivers/infiniband/hw/efa/efa_com_cmd.c +2 −0
  36. drivers/infiniband/hw/efa/efa_com_cmd.h +2 −0
  37. drivers/infiniband/hw/efa/efa_main.c +4 −2
  38. drivers/infiniband/hw/efa/efa_verbs.c +42 −0
  39. drivers/infiniband/hw/hfi1/chip.c +14 −13
  40. drivers/infiniband/hw/hfi1/firmware.c +0 −16
  41. drivers/infiniband/hw/hfi1/mad.c +4 −5
  42. drivers/infiniband/hw/hfi1/pcie.c +15 −7
  43. drivers/infiniband/hw/hfi1/pio.c +1 −1
  44. drivers/infiniband/hw/hfi1/pio_copy.c +6 −6
  45. drivers/infiniband/hw/hfi1/platform.c +5 −5
  46. drivers/infiniband/hw/hfi1/qp.c +1 −1
  47. drivers/infiniband/hw/hfi1/qp.h +0 −14
  48. drivers/infiniband/hw/hfi1/qsfp.c +2 −2
  49. drivers/infiniband/hw/hfi1/rc.c +12 −13
  50. drivers/infiniband/hw/hfi1/sdma.c +4 −5
  51. drivers/infiniband/hw/hfi1/tid_rdma.c +2 −2
  52. drivers/infiniband/hw/hfi1/uc.c +4 −4
  53. drivers/infiniband/hw/hns/hns_roce_device.h +16 −15
  54. drivers/infiniband/hw/hns/hns_roce_hw_v1.c +3 −4
  55. drivers/infiniband/hw/hns/hns_roce_hw_v2.c +118 −135
  56. drivers/infiniband/hw/hns/hns_roce_hw_v2.h +2 −17
  57. drivers/infiniband/hw/hns/hns_roce_main.c +1 −1
  58. drivers/infiniband/hw/hns/hns_roce_mr.c +127 −83
  59. drivers/infiniband/hw/hns/hns_roce_qp.c +0 −10
  60. drivers/infiniband/hw/hns/hns_roce_restrack.c +2 −12
  61. drivers/infiniband/hw/i40iw/i40iw_verbs.c +1 −21
  62. drivers/infiniband/hw/mlx4/main.c +15 −22
  63. drivers/infiniband/hw/mlx4/mlx4_ib.h +1 −1
  64. drivers/infiniband/hw/mlx4/mr.c +1 −2
  65. drivers/infiniband/hw/mlx5/Makefile +4 −2
  66. drivers/infiniband/hw/mlx5/cmd.c +0 −12
  67. drivers/infiniband/hw/mlx5/cmd.h +0 −1
  68. drivers/infiniband/hw/mlx5/counters.c +709 −0
  69. drivers/infiniband/hw/mlx5/counters.h +17 −0
  70. drivers/infiniband/hw/mlx5/devx.c +28 −74
  71. drivers/infiniband/hw/mlx5/devx.h +45 −0
  72. drivers/infiniband/hw/mlx5/flow.c +0 −765
  73. drivers/infiniband/hw/mlx5/fs.c +2516 −0
  74. drivers/infiniband/hw/mlx5/fs.h +29 −0
  75. drivers/infiniband/hw/mlx5/main.c +937 −3443
  76. drivers/infiniband/hw/mlx5/mlx5_ib.h +17 −92
  77. drivers/infiniband/hw/mlx5/mr.c +1 −1
  78. drivers/infiniband/hw/mlx5/odp.c +19 −9
  79. drivers/infiniband/hw/mlx5/qp.c +25 −46
  80. drivers/infiniband/hw/mlx5/qp.h +1 −0
  81. drivers/infiniband/hw/mlx5/restrack.c +105 −16
  82. drivers/infiniband/hw/mlx5/restrack.h +13 −0
  83. drivers/infiniband/hw/mlx5/srq.c +2 −2
  84. drivers/infiniband/hw/mlx5/std_types.c +45 −0
  85. drivers/infiniband/hw/mlx5/wr.c +50 −18
  86. drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +1 −1
  87. drivers/infiniband/hw/ocrdma/ocrdma_verbs.h +1 −1
  88. drivers/infiniband/hw/qedr/main.c +1 −2
  89. drivers/infiniband/hw/qedr/qedr.h +3 −2
  90. drivers/infiniband/hw/qedr/verbs.c +25 −20
  91. drivers/infiniband/hw/qedr/verbs.h +1 −1
  92. drivers/infiniband/hw/usnic/usnic_fwd.c +2 −2
  93. drivers/infiniband/hw/vmw_pvrdma/pvrdma_mr.c +1 −1
  94. drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h +1 −1
  95. drivers/infiniband/sw/rdmavt/ah.c +1 −2
  96. drivers/infiniband/sw/rdmavt/mr.c +1 −1
  97. drivers/infiniband/sw/rdmavt/mr.h +1 −1
  98. drivers/infiniband/sw/rxe/rxe.c +4 −37
  99. drivers/infiniband/sw/rxe/rxe_loc.h +2 −6
  100. drivers/infiniband/sw/rxe/rxe_mr.c +2 −48
  101. drivers/infiniband/sw/rxe/rxe_net.c +0 −5
  102. drivers/infiniband/sw/rxe/rxe_param.h +2 −2
  103. drivers/infiniband/sw/rxe/rxe_recv.c +9 −26
  104. drivers/infiniband/sw/rxe/rxe_req.c +1 −4
  105. drivers/infiniband/sw/rxe/rxe_verbs.c +12 −36
  106. drivers/infiniband/sw/rxe/rxe_verbs.h +0 −1
  107. drivers/infiniband/sw/siw/siw_main.c +0 −1
  108. drivers/infiniband/sw/siw/siw_verbs.c +1 −10
  109. drivers/infiniband/sw/siw/siw_verbs.h +1 −2
  110. drivers/infiniband/ulp/ipoib/ipoib.h +2 −2
  111. drivers/infiniband/ulp/ipoib/ipoib_ib.c +29 −38
  112. drivers/infiniband/ulp/ipoib/ipoib_main.c +11 −2
  113. drivers/infiniband/ulp/ipoib/ipoib_multicast.c +1 −3
  114. drivers/infiniband/ulp/iser/iscsi_iser.h +6 −19
  115. drivers/infiniband/ulp/iser/iser_verbs.c +25 −87
  116. drivers/infiniband/ulp/isert/ib_isert.c +36 −139
  117. drivers/infiniband/ulp/isert/ib_isert.h +4 −17
  118. drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h +23 −0
  119. drivers/infiniband/ulp/rtrs/rtrs-clt.c +13 −3
  120. drivers/infiniband/ulp/rtrs/rtrs-srv.c +1 −1
  121. drivers/infiniband/ulp/srpt/ib_srpt.c +9 −11
  122. drivers/infiniband/ulp/srpt/ib_srpt.h +1 −0
  123. drivers/net/ethernet/mellanox/mlx5/core/alloc.c +9 −2
  124. drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +1 −0
  125. drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c +7 −0
  126. drivers/net/ethernet/mellanox/mlx5/core/main.c +3 −0
  127. include/linux/mlx5/device.h +5 −4
  128. include/linux/mlx5/driver.h +2 −0
  129. include/linux/mlx5/mlx5_ifc.h +113 −16
  130. include/rdma/ib.h +2 −29
  131. include/rdma/ib_addr.h +2 −29
  132. include/rdma/ib_cache.h +1 −28
  133. include/rdma/ib_cm.h +1 −0
  134. include/rdma/ib_hdrs.h +1 −43
  135. include/rdma/ib_mad.h +2 −29
  136. include/rdma/ib_marshall.h +2 −29
  137. include/rdma/ib_pack.h +1 −28
  138. include/rdma/ib_pma.h +2 −29
  139. include/rdma/ib_sa.h +1 −28
  140. include/rdma/ib_smi.h +2 −29
  141. include/rdma/ib_umem.h +1 −28
  142. include/rdma/ib_umem_odp.h +1 −28
  143. include/rdma/ib_verbs.h +31 −69
  144. include/rdma/iw_cm.h +2 −28
  145. include/rdma/iw_portmap.h +2 −28
  146. include/rdma/opa_addr.h +1 −43
  147. include/rdma/opa_port_info.h +2 −29
  148. include/rdma/opa_smi.h +2 −29
  149. include/rdma/opa_vnic.h +4 −45
  150. include/rdma/rdma_cm.h +2 −29
  151. include/rdma/rdma_cm_ib.h +2 −29
  152. include/rdma/rdma_netlink.h +1 −1
  153. include/rdma/rdma_vt.h +4 −46
  154. include/rdma/rdmavt_cq.h +4 −49
  155. include/rdma/rdmavt_mr.h +4 −46
  156. include/rdma/rdmavt_qp.h +4 −46
  157. include/rdma/uverbs_ioctl.h +2 −28
  158. include/rdma/uverbs_named_ioctl.h +1 −28
  159. include/rdma/uverbs_std_types.h +15 −28
  160. include/rdma/uverbs_types.h +1 −28
  161. include/uapi/rdma/efa-abi.h +14 −1
  162. include/uapi/rdma/ib_user_ioctl_cmds.h +15 −0
  163. include/uapi/rdma/mlx5_user_ioctl_cmds.h +15 −1
  164. include/uapi/rdma/qedr-abi.h +7 −3
  165. include/uapi/rdma/rdma_netlink.h +9 −0
  166. include/uapi/rdma/rdma_user_ioctl.h +1 −1
MAINTAINERS+1−0
@@ -3621,6 +3621,7 @@ M: Selvin Xavier <selvin.xavier@broadcom.com> · 3620 unmodified lines
3621M: Devesh Sharma <devesh.sharma@broadcom.com>3621M: Devesh Sharma <devesh.sharma@broadcom.com>
3622M: Somnath Kotur <somnath.kotur@broadcom.com>3622M: Somnath Kotur <somnath.kotur@broadcom.com>
3623M: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>3623M: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
3624M: Naresh Kumar PBS <nareshkumar.pbs@broadcom.com>
3624L: linux-rdma@vger.kernel.org3625L: linux-rdma@vger.kernel.org
3625S: Supported3626S: Supported
3626W: http://www.broadcom.com3627W: http://www.broadcom.com
drivers/infiniband/Kconfig+0−8
@@ -37,14 +37,6 @@ config INFINIBAND_USER_ACCESS · 36 unmodified lines
37 libibverbs, libibcm and a hardware driver library from37 libibverbs, libibcm and a hardware driver library from
38 rdma-core <https://github.com/linux-rdma/rdma-core>.38 rdma-core <https://github.com/linux-rdma/rdma-core>.
39 39
40config INFINIBAND_EXP_LEGACY_VERBS_NEW_UAPI
41 bool "Allow experimental legacy verbs in new ioctl uAPI (EXPERIMENTAL)"
42 depends on INFINIBAND_USER_ACCESS
43 help
44 IOCTL based uAPI support for Infiniband is enabled by default for
45 new verbs only. This allows userspace to invoke the IOCTL based uAPI
46 for current legacy verbs too.
47
48config INFINIBAND_USER_MEM40config INFINIBAND_USER_MEM
49 bool41 bool
50 depends on INFINIBAND_USER_ACCESS != n42 depends on INFINIBAND_USER_ACCESS != n
drivers/infiniband/core/cache.c+29−16
@@ -1054,7 +1054,7 @@ int ib_get_cached_pkey(struct ib_device *device, · 1053 unmodified lines
1054 1054
1055 cache = device->port_data[port_num].cache.pkey;1055 cache = device->port_data[port_num].cache.pkey;
1056 1056
1057 if (index < 0 || index >= cache->table_len)1057 if (!cache || index < 0 || index >= cache->table_len)
1058 ret = -EINVAL;1058 ret = -EINVAL;
1059 else1059 else
1060 *pkey = cache->table[index];1060 *pkey = cache->table[index];
@@ -1099,6 +1099,10 @@ int ib_find_cached_pkey(struct ib_device *device, · 38 unmodified lines
1099 read_lock_irqsave(&device->cache_lock, flags);1099 read_lock_irqsave(&device->cache_lock, flags);
1100 1100
1101 cache = device->port_data[port_num].cache.pkey;1101 cache = device->port_data[port_num].cache.pkey;
1102 if (!cache) {
1103 ret = -EINVAL;
1104 goto err;
1105 }
1102 1106
1103 *index = -1;1107 *index = -1;
1104 1108
@@ -1117,6 +1121,7 @@ int ib_find_cached_pkey(struct ib_device *device, · 12 unmodified lines
1117 ret = 0;1121 ret = 0;
1118 }1122 }
1119 1123
1124err:
1120 read_unlock_irqrestore(&device->cache_lock, flags);1125 read_unlock_irqrestore(&device->cache_lock, flags);
1121 1126
1122 return ret;1127 return ret;
@@ -1139,6 +1144,10 @@ int ib_find_exact_cached_pkey(struct ib_device *device, · 16 unmodified lines
1139 read_lock_irqsave(&device->cache_lock, flags);1144 read_lock_irqsave(&device->cache_lock, flags);
1140 1145
1141 cache = device->port_data[port_num].cache.pkey;1146 cache = device->port_data[port_num].cache.pkey;
1147 if (!cache) {
1148 ret = -EINVAL;
1149 goto err;
1150 }
1142 1151
1143 *index = -1;1152 *index = -1;
1144 1153
@@ -1149,6 +1158,7 @@ int ib_find_exact_cached_pkey(struct ib_device *device, · 4 unmodified lines
1149 break;1158 break;
1150 }1159 }
1151 1160
1161err:
1152 read_unlock_irqrestore(&device->cache_lock, flags);1162 read_unlock_irqrestore(&device->cache_lock, flags);
1153 1163
1154 return ret;1164 return ret;
@@ -1425,23 +1435,26 @@ ib_cache_update(struct ib_device *device, u8 port, bool enforce_security) · 270 unmodified lines
1425 goto err;1435 goto err;
1426 }1436 }
1427 1437
1428 pkey_cache = kmalloc(struct_size(pkey_cache, table,1438 if (tprops->pkey_tbl_len) {
1429 tprops->pkey_tbl_len),1439 pkey_cache = kmalloc(struct_size(pkey_cache, table,
1430 GFP_KERNEL);1440 tprops->pkey_tbl_len),
1431 if (!pkey_cache) {1441 GFP_KERNEL);
1432 ret = -ENOMEM;1442 if (!pkey_cache) {
1433 goto err;1443 ret = -ENOMEM;
1434 }1444 goto err;
1445 }
1435 1446
1436 pkey_cache->table_len = tprops->pkey_tbl_len;1447 pkey_cache->table_len = tprops->pkey_tbl_len;
1437 1448
1438 for (i = 0; i < pkey_cache->table_len; ++i) {1449 for (i = 0; i < pkey_cache->table_len; ++i) {
1439 ret = ib_query_pkey(device, port, i, pkey_cache->table + i);1450 ret = ib_query_pkey(device, port, i,
1440 if (ret) {1451 pkey_cache->table + i);
1441 dev_warn(&device->dev,1452 if (ret) {
1442 "ib_query_pkey failed (%d) for index %d\n",1453 dev_warn(&device->dev,
1443 ret, i);1454 "ib_query_pkey failed (%d) for index %d\n",
1444 goto err;1455 ret, i);
1456 goto err;
1457 }
1445 }1458 }
1446 }1459 }
1447 1460
drivers/infiniband/core/cma.c+123−134
@@ -428,19 +428,6 @@ static int cma_comp_exch(struct rdma_id_private *id_priv, · 427 unmodified lines
428 return ret;428 return ret;
429}429}
430 430
431static enum rdma_cm_state cma_exch(struct rdma_id_private *id_priv,
432 enum rdma_cm_state exch)
433{
434 unsigned long flags;
435 enum rdma_cm_state old;
436
437 spin_lock_irqsave(&id_priv->lock, flags);
438 old = id_priv->state;
439 id_priv->state = exch;
440 spin_unlock_irqrestore(&id_priv->lock, flags);
441 return old;
442}
443
444static inline u8 cma_get_ip_ver(const struct cma_hdr *hdr)431static inline u8 cma_get_ip_ver(const struct cma_hdr *hdr)
445{432{
446 return hdr->ip_version >> 4;433 return hdr->ip_version >> 4;
@@ -1829,23 +1816,11 @@ static void cma_leave_mc_groups(struct rdma_id_private *id_priv) · 1382 unmodified lines
1829 }1816 }
1830}1817}
1831 1818
1832void rdma_destroy_id(struct rdma_cm_id *id)1819static void _destroy_id(struct rdma_id_private *id_priv,
1820 enum rdma_cm_state state)
1833{1821{
1834 struct rdma_id_private *id_priv;
1835 enum rdma_cm_state state;
1836
1837 id_priv = container_of(id, struct rdma_id_private, id);
1838 trace_cm_id_destroy(id_priv);
1839 state = cma_exch(id_priv, RDMA_CM_DESTROYING);
1840 cma_cancel_operation(id_priv, state);1822 cma_cancel_operation(id_priv, state);
1841 1823
1842 /*
1843 * Wait for any active callback to finish. New callbacks will find
1844 * the id_priv state set to destroying and abort.
1845 */
1846 mutex_lock(&id_priv->handler_mutex);
1847 mutex_unlock(&id_priv->handler_mutex);
1848
1849 rdma_restrack_del(&id_priv->res);1824 rdma_restrack_del(&id_priv->res);
1850 if (id_priv->cma_dev) {1825 if (id_priv->cma_dev) {
1851 if (rdma_cap_ib_cm(id_priv->id.device, 1)) {1826 if (rdma_cap_ib_cm(id_priv->id.device, 1)) {
@@ -1874,6 +1849,42 @@ void rdma_destroy_id(struct rdma_cm_id *id) · 22 unmodified lines
1874 put_net(id_priv->id.route.addr.dev_addr.net);1849 put_net(id_priv->id.route.addr.dev_addr.net);
1875 kfree(id_priv);1850 kfree(id_priv);
1876}1851}
1852
1853/*
1854 * destroy an ID from within the handler_mutex. This ensures that no other
1855 * handlers can start running concurrently.
1856 */
1857static void destroy_id_handler_unlock(struct rdma_id_private *id_priv)
1858 __releases(&idprv->handler_mutex)
1859{
1860 enum rdma_cm_state state;
1861 unsigned long flags;
1862
1863 trace_cm_id_destroy(id_priv);
1864
1865 /*
1866 * Setting the state to destroyed under the handler mutex provides a
1867 * fence against calling handler callbacks. If this is invoked due to
1868 * the failure of a handler callback then it guarentees that no future
1869 * handlers will be called.
1870 */
1871 lockdep_assert_held(&id_priv->handler_mutex);
1872 spin_lock_irqsave(&id_priv->lock, flags);
1873 state = id_priv->state;
1874 id_priv->state = RDMA_CM_DESTROYING;
1875 spin_unlock_irqrestore(&id_priv->lock, flags);
1876 mutex_unlock(&id_priv->handler_mutex);
1877 _destroy_id(id_priv, state);
1878}
1879
1880void rdma_destroy_id(struct rdma_cm_id *id)
1881{
1882 struct rdma_id_private *id_priv =
1883 container_of(id, struct rdma_id_private, id);
1884
1885 mutex_lock(&id_priv->handler_mutex);
1886 destroy_id_handler_unlock(id_priv);
1887}
1877EXPORT_SYMBOL(rdma_destroy_id);1888EXPORT_SYMBOL(rdma_destroy_id);
1878 1889
1879static int cma_rep_recv(struct rdma_id_private *id_priv)1890static int cma_rep_recv(struct rdma_id_private *id_priv)
@@ -1925,6 +1936,8 @@ static int cma_cm_event_handler(struct rdma_id_private *id_priv, · 45 unmodified lines
1925{1936{
1926 int ret;1937 int ret;
1927 1938
1939 lockdep_assert_held(&id_priv->handler_mutex);
1940
1928 trace_cm_event_handler(id_priv, event);1941 trace_cm_event_handler(id_priv, event);
1929 ret = id_priv->id.event_handler(&id_priv->id, event);1942 ret = id_priv->id.event_handler(&id_priv->id, event);
1930 trace_cm_event_done(id_priv, event, ret);1943 trace_cm_event_done(id_priv, event, ret);
@@ -1936,7 +1949,7 @@ static int cma_ib_handler(struct ib_cm_id *cm_id, · 5 unmodified lines
1936{1949{
1937 struct rdma_id_private *id_priv = cm_id->context;1950 struct rdma_id_private *id_priv = cm_id->context;
1938 struct rdma_cm_event event = {};1951 struct rdma_cm_event event = {};
1939 int ret = 0;1952 int ret;
1940 1953
1941 mutex_lock(&id_priv->handler_mutex);1954 mutex_lock(&id_priv->handler_mutex);
1942 if ((ib_event->event != IB_CM_TIMEWAIT_EXIT &&1955 if ((ib_event->event != IB_CM_TIMEWAIT_EXIT &&
@@ -2005,14 +2018,12 @@ static int cma_ib_handler(struct ib_cm_id *cm_id, · 62 unmodified lines
2005 if (ret) {2018 if (ret) {
2006 /* Destroy the CM ID by returning a non-zero value. */2019 /* Destroy the CM ID by returning a non-zero value. */
2007 id_priv->cm_id.ib = NULL;2020 id_priv->cm_id.ib = NULL;
2008 cma_exch(id_priv, RDMA_CM_DESTROYING);2021 destroy_id_handler_unlock(id_priv);
2009 mutex_unlock(&id_priv->handler_mutex);
2010 rdma_destroy_id(&id_priv->id);
2011 return ret;2022 return ret;
2012 }2023 }
2013out:2024out:
2014 mutex_unlock(&id_priv->handler_mutex);2025 mutex_unlock(&id_priv->handler_mutex);
2015 return ret;2026 return 0;
2016}2027}
2017 2028
2018static struct rdma_id_private *2029static struct rdma_id_private *
@@ -2174,7 +2185,7 @@ static int cma_ib_req_handler(struct ib_cm_id *cm_id, · 155 unmodified lines
2174 mutex_lock(&listen_id->handler_mutex);2185 mutex_lock(&listen_id->handler_mutex);
2175 if (listen_id->state != RDMA_CM_LISTEN) {2186 if (listen_id->state != RDMA_CM_LISTEN) {
2176 ret = -ECONNABORTED;2187 ret = -ECONNABORTED;
2177 goto err1;2188 goto err_unlock;
2178 }2189 }
2179 2190
2180 offset = cma_user_data_offset(listen_id);2191 offset = cma_user_data_offset(listen_id);
@@ -2191,55 +2202,38 @@ static int cma_ib_req_handler(struct ib_cm_id *cm_id, · 10 unmodified lines
2191 }2202 }
2192 if (!conn_id) {2203 if (!conn_id) {
2193 ret = -ENOMEM;2204 ret = -ENOMEM;
2194 goto err1;2205 goto err_unlock;
2195 }2206 }
2196 2207
2197 mutex_lock_nested(&conn_id->handler_mutex, SINGLE_DEPTH_NESTING);2208 mutex_lock_nested(&conn_id->handler_mutex, SINGLE_DEPTH_NESTING);
2198 ret = cma_ib_acquire_dev(conn_id, listen_id, &req);2209 ret = cma_ib_acquire_dev(conn_id, listen_id, &req);
2199 if (ret)2210 if (ret) {
2200 goto err2;2211 destroy_id_handler_unlock(conn_id);
2212 goto err_unlock;
2213 }
2201 2214
2202 conn_id->cm_id.ib = cm_id;2215 conn_id->cm_id.ib = cm_id;
2203 cm_id->context = conn_id;2216 cm_id->context = conn_id;
2204 cm_id->cm_handler = cma_ib_handler;2217 cm_id->cm_handler = cma_ib_handler;
2205 2218
2206 /*
2207 * Protect against the user destroying conn_id from another thread
2208 * until we're done accessing it.
2209 */
2210 cma_id_get(conn_id);
2211 ret = cma_cm_event_handler(conn_id, &event);2219 ret = cma_cm_event_handler(conn_id, &event);
2212 if (ret)2220 if (ret) {
2213 goto err3;2221 /* Destroy the CM ID by returning a non-zero value. */
2214 /*2222 conn_id->cm_id.ib = NULL;
2215 * Acquire mutex to prevent user executing rdma_destroy_id()2223 mutex_unlock(&listen_id->handler_mutex);
2216 * while we're accessing the cm_id.2224 destroy_id_handler_unlock(conn_id);
2217 */2225 goto net_dev_put;
2218 mutex_lock(&lock);2226 }
2227
2219 if (cma_comp(conn_id, RDMA_CM_CONNECT) &&2228 if (cma_comp(conn_id, RDMA_CM_CONNECT) &&
2220 (conn_id->id.qp_type != IB_QPT_UD)) {2229 (conn_id->id.qp_type != IB_QPT_UD)) {
2221 trace_cm_send_mra(cm_id->context);2230 trace_cm_send_mra(cm_id->context);
2222 ib_send_cm_mra(cm_id, CMA_CM_MRA_SETTING, NULL, 0);2231 ib_send_cm_mra(cm_id, CMA_CM_MRA_SETTING, NULL, 0);
2223 }2232 }
2224 mutex_unlock(&lock);
2225 mutex_unlock(&conn_id->handler_mutex);2233 mutex_unlock(&conn_id->handler_mutex);
2226 mutex_unlock(&listen_id->handler_mutex);
2227 cma_id_put(conn_id);
2228 if (net_dev)
2229 dev_put(net_dev);
2230 return 0;
2231 2234
2232err3:2235err_unlock:
2233 cma_id_put(conn_id);
2234 /* Destroy the CM ID by returning a non-zero value. */
2235 conn_id->cm_id.ib = NULL;
2236err2:
2237 cma_exch(conn_id, RDMA_CM_DESTROYING);
2238 mutex_unlock(&conn_id->handler_mutex);
2239err1:
2240 mutex_unlock(&listen_id->handler_mutex);2236 mutex_unlock(&listen_id->handler_mutex);
2241 if (conn_id)
2242 rdma_destroy_id(&conn_id->id);
2243 2237
2244net_dev_put:2238net_dev_put:
2245 if (net_dev)2239 if (net_dev)
@@ -2339,9 +2333,7 @@ static int cma_iw_handler(struct iw_cm_id *iw_id, struct iw_cm_event *iw_event) · 93 unmodified lines
2339 if (ret) {2333 if (ret) {
2340 /* Destroy the CM ID by returning a non-zero value. */2334 /* Destroy the CM ID by returning a non-zero value. */
2341 id_priv->cm_id.iw = NULL;2335 id_priv->cm_id.iw = NULL;
2342 cma_exch(id_priv, RDMA_CM_DESTROYING);2336 destroy_id_handler_unlock(id_priv);
2343 mutex_unlock(&id_priv->handler_mutex);
2344 rdma_destroy_id(&id_priv->id);
2345 return ret;2337 return ret;
2346 }2338 }
2347 2339
@@ -2388,16 +2380,16 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, · 40 unmodified lines
2388 2380
2389 ret = rdma_translate_ip(laddr, &conn_id->id.route.addr.dev_addr);2381 ret = rdma_translate_ip(laddr, &conn_id->id.route.addr.dev_addr);
2390 if (ret) {2382 if (ret) {
2391 mutex_unlock(&conn_id->handler_mutex);2383 mutex_unlock(&listen_id->handler_mutex);
2392 rdma_destroy_id(new_cm_id);2384 destroy_id_handler_unlock(conn_id);
2393 goto out;2385 return ret;
2394 }2386 }
2395 2387
2396 ret = cma_iw_acquire_dev(conn_id, listen_id);2388 ret = cma_iw_acquire_dev(conn_id, listen_id);
2397 if (ret) {2389 if (ret) {
2398 mutex_unlock(&conn_id->handler_mutex);2390 mutex_unlock(&listen_id->handler_mutex);
2399 rdma_destroy_id(new_cm_id);2391 destroy_id_handler_unlock(conn_id);
2400 goto out;2392 return ret;
2401 }2393 }
2402 2394
2403 conn_id->cm_id.iw = cm_id;2395 conn_id->cm_id.iw = cm_id;
@@ -2407,25 +2399,16 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, · 3 unmodified lines
2407 memcpy(cma_src_addr(conn_id), laddr, rdma_addr_size(laddr));2399 memcpy(cma_src_addr(conn_id), laddr, rdma_addr_size(laddr));
2408 memcpy(cma_dst_addr(conn_id), raddr, rdma_addr_size(raddr));2400 memcpy(cma_dst_addr(conn_id), raddr, rdma_addr_size(raddr));
2409 2401
2410 /*
2411 * Protect against the user destroying conn_id from another thread
2412 * until we're done accessing it.
2413 */
2414 cma_id_get(conn_id);
2415 ret = cma_cm_event_handler(conn_id, &event);2402 ret = cma_cm_event_handler(conn_id, &event);
2416 if (ret) {2403 if (ret) {
2417 /* User wants to destroy the CM ID */2404 /* User wants to destroy the CM ID */
2418 conn_id->cm_id.iw = NULL;2405 conn_id->cm_id.iw = NULL;
2419 cma_exch(conn_id, RDMA_CM_DESTROYING);
2420 mutex_unlock(&conn_id->handler_mutex);
2421 mutex_unlock(&listen_id->handler_mutex);2406 mutex_unlock(&listen_id->handler_mutex);
2422 cma_id_put(conn_id);2407 destroy_id_handler_unlock(conn_id);
2423 rdma_destroy_id(&conn_id->id);
2424 return ret;2408 return ret;
2425 }2409 }
2426 2410
2427 mutex_unlock(&conn_id->handler_mutex);2411 mutex_unlock(&conn_id->handler_mutex);
2428 cma_id_put(conn_id);
2429 2412
2430out:2413out:
2431 mutex_unlock(&listen_id->handler_mutex);2414 mutex_unlock(&listen_id->handler_mutex);
@@ -2482,6 +2465,10 @@ static int cma_listen_handler(struct rdma_cm_id *id, · 50 unmodified lines
2482{2465{
2483 struct rdma_id_private *id_priv = id->context;2466 struct rdma_id_private *id_priv = id->context;
2484 2467
2468 /* Listening IDs are always destroyed on removal */
2469 if (event->event == RDMA_CM_EVENT_DEVICE_REMOVAL)
2470 return -1;
2471
2485 id->context = id_priv->id.context;2472 id->context = id_priv->id.context;
2486 id->event_handler = id_priv->id.event_handler;2473 id->event_handler = id_priv->id.event_handler;
2487 trace_cm_event_handler(id_priv, event);2474 trace_cm_event_handler(id_priv, event);
@@ -2657,21 +2644,21 @@ static void cma_work_handler(struct work_struct *_work) · 169 unmodified lines
2657{2644{
2658 struct cma_work *work = container_of(_work, struct cma_work, work);2645 struct cma_work *work = container_of(_work, struct cma_work, work);
2659 struct rdma_id_private *id_priv = work->id;2646 struct rdma_id_private *id_priv = work->id;
2660 int destroy = 0;
2661 2647
2662 mutex_lock(&id_priv->handler_mutex);2648 mutex_lock(&id_priv->handler_mutex);
2663 if (!cma_comp_exch(id_priv, work->old_state, work->new_state))2649 if (!cma_comp_exch(id_priv, work->old_state, work->new_state))
2664 goto out;2650 goto out_unlock;
2665 2651
2666 if (cma_cm_event_handler(id_priv, &work->event)) {2652 if (cma_cm_event_handler(id_priv, &work->event)) {
2667 cma_exch(id_priv, RDMA_CM_DESTROYING);2653 cma_id_put(id_priv);
2668 destroy = 1;2654 destroy_id_handler_unlock(id_priv);
2655 goto out_free;
2669 }2656 }
2670out:2657
2658out_unlock:
2671 mutex_unlock(&id_priv->handler_mutex);2659 mutex_unlock(&id_priv->handler_mutex);
2672 cma_id_put(id_priv);2660 cma_id_put(id_priv);
2673 if (destroy)2661out_free:
2674 rdma_destroy_id(&id_priv->id);
2675 kfree(work);2662 kfree(work);
2676}2663}
2677 2664
@@ -2679,23 +2666,22 @@ static void cma_ndev_work_handler(struct work_struct *_work) · 1 unmodified line
2679{2666{
2680 struct cma_ndev_work *work = container_of(_work, struct cma_ndev_work, work);2667 struct cma_ndev_work *work = container_of(_work, struct cma_ndev_work, work);
2681 struct rdma_id_private *id_priv = work->id;2668 struct rdma_id_private *id_priv = work->id;
2682 int destroy = 0;
2683 2669
2684 mutex_lock(&id_priv->handler_mutex);2670 mutex_lock(&id_priv->handler_mutex);
2685 if (id_priv->state == RDMA_CM_DESTROYING ||2671 if (id_priv->state == RDMA_CM_DESTROYING ||
2686 id_priv->state == RDMA_CM_DEVICE_REMOVAL)2672 id_priv->state == RDMA_CM_DEVICE_REMOVAL)
2687 goto out;2673 goto out_unlock;
2688 2674
2689 if (cma_cm_event_handler(id_priv, &work->event)) {2675 if (cma_cm_event_handler(id_priv, &work->event)) {
2690 cma_exch(id_priv, RDMA_CM_DESTROYING);2676 cma_id_put(id_priv);
2691 destroy = 1;2677 destroy_id_handler_unlock(id_priv);
2678 goto out_free;
2692 }2679 }
2693 2680
2694out:2681out_unlock:
2695 mutex_unlock(&id_priv->handler_mutex);2682 mutex_unlock(&id_priv->handler_mutex);
2696 cma_id_put(id_priv);2683 cma_id_put(id_priv);
2697 if (destroy)2684out_free:
2698 rdma_destroy_id(&id_priv->id);
2699 kfree(work);2685 kfree(work);
2700}2686}
2701 2687
@@ -3171,9 +3157,7 @@ static void addr_handler(int status, struct sockaddr *src_addr, · 469 unmodified lines
3171 event.event = RDMA_CM_EVENT_ADDR_RESOLVED;3157 event.event = RDMA_CM_EVENT_ADDR_RESOLVED;
3172 3158
3173 if (cma_cm_event_handler(id_priv, &event)) {3159 if (cma_cm_event_handler(id_priv, &event)) {
3174 cma_exch(id_priv, RDMA_CM_DESTROYING);3160 destroy_id_handler_unlock(id_priv);
3175 mutex_unlock(&id_priv->handler_mutex);
3176 rdma_destroy_id(&id_priv->id);
3177 return;3161 return;
3178 }3162 }
3179out:3163out:
@@ -3790,7 +3774,7 @@ static int cma_sidr_rep_handler(struct ib_cm_id *cm_id, · 610 unmodified lines
3790 struct rdma_cm_event event = {};3774 struct rdma_cm_event event = {};
3791 const struct ib_cm_sidr_rep_event_param *rep =3775 const struct ib_cm_sidr_rep_event_param *rep =
3792 &ib_event->param.sidr_rep_rcvd;3776 &ib_event->param.sidr_rep_rcvd;
3793 int ret = 0;3777 int ret;
3794 3778
3795 mutex_lock(&id_priv->handler_mutex);3779 mutex_lock(&id_priv->handler_mutex);
3796 if (id_priv->state != RDMA_CM_CONNECT)3780 if (id_priv->state != RDMA_CM_CONNECT)
@@ -3840,14 +3824,12 @@ static int cma_sidr_rep_handler(struct ib_cm_id *cm_id, · 43 unmodified lines
3840 if (ret) {3824 if (ret) {
3841 /* Destroy the CM ID by returning a non-zero value. */3825 /* Destroy the CM ID by returning a non-zero value. */
3842 id_priv->cm_id.ib = NULL;3826 id_priv->cm_id.ib = NULL;
3843 cma_exch(id_priv, RDMA_CM_DESTROYING);3827 destroy_id_handler_unlock(id_priv);
3844 mutex_unlock(&id_priv->handler_mutex);
3845 rdma_destroy_id(&id_priv->id);
3846 return ret;3828 return ret;
3847 }3829 }
3848out:3830out:
3849 mutex_unlock(&id_priv->handler_mutex);3831 mutex_unlock(&id_priv->handler_mutex);
3850 return ret;3832 return 0;
3851}3833}
3852 3834
3853static int cma_resolve_ib_udp(struct rdma_id_private *id_priv,3835static int cma_resolve_ib_udp(struct rdma_id_private *id_priv,
@@ -4372,9 +4354,7 @@ static int cma_ib_mc_handler(int status, struct ib_sa_multicast *multicast) · 518 unmodified lines
4372 4354
4373 rdma_destroy_ah_attr(&event.param.ud.ah_attr);4355 rdma_destroy_ah_attr(&event.param.ud.ah_attr);
4374 if (ret) {4356 if (ret) {
4375 cma_exch(id_priv, RDMA_CM_DESTROYING);4357 destroy_id_handler_unlock(id_priv);
4376 mutex_unlock(&id_priv->handler_mutex);
4377 rdma_destroy_id(&id_priv->id);
4378 return 0;4358 return 0;
4379 }4359 }
4380 4360
@@ -4789,50 +4769,59 @@ free_cma_dev: · 408 unmodified lines
4789 return ret;4769 return ret;
4790}4770}
4791 4771
4792static int cma_remove_id_dev(struct rdma_id_private *id_priv)4772static void cma_send_device_removal_put(struct rdma_id_private *id_priv)
4793{4773{
4794 struct rdma_cm_event event = {};4774 struct rdma_cm_event event = { .event = RDMA_CM_EVENT_DEVICE_REMOVAL };
4795 enum rdma_cm_state state;4775 enum rdma_cm_state state;
4796 int ret = 0;4776 unsigned long flags;
4797
4798 /* Record that we want to remove the device */
4799 state = cma_exch(id_priv, RDMA_CM_DEVICE_REMOVAL);
4800 if (state == RDMA_CM_DESTROYING)
4801 return 0;
4802 4777
4803 cma_cancel_operation(id_priv, state);
4804 mutex_lock(&id_priv->handler_mutex);4778 mutex_lock(&id_priv->handler_mutex);
4779 /* Record that we want to remove the device */
4780 spin_lock_irqsave(&id_priv->lock, flags);
4781 state = id_priv->state;
4782 if (state == RDMA_CM_DESTROYING || state == RDMA_CM_DEVICE_REMOVAL) {
4783 spin_unlock_irqrestore(&id_priv->lock, flags);
4784 mutex_unlock(&id_priv->handler_mutex);
4785 cma_id_put(id_priv);
4786 return;
4787 }
4788 id_priv->state = RDMA_CM_DEVICE_REMOVAL;
4789 spin_unlock_irqrestore(&id_priv->lock, flags);
4805 4790
4806 /* Check for destruction from another callback. */4791 if (cma_cm_event_handler(id_priv, &event)) {
4807 if (!cma_comp(id_priv, RDMA_CM_DEVICE_REMOVAL))4792 /*
4808 goto out;4793 * At this point the ULP promises it won't call
4809 4794 * rdma_destroy_id() concurrently
4810 event.event = RDMA_CM_EVENT_DEVICE_REMOVAL;4795 */
4811 ret = cma_cm_event_handler(id_priv, &event);4796 cma_id_put(id_priv);
4812out:4797 mutex_unlock(&id_priv->handler_mutex);
4798 trace_cm_id_destroy(id_priv);
4799 _destroy_id(id_priv, state);
4800 return;
4801 }
4813 mutex_unlock(&id_priv->handler_mutex);4802 mutex_unlock(&id_priv->handler_mutex);
4814 return ret;4803
4804 /*
4805 * If this races with destroy then the thread that first assigns state
4806 * to a destroying does the cancel.
4807 */
4808 cma_cancel_operation(id_priv, state);
4809 cma_id_put(id_priv);
4815}4810}
4816 4811
4817static void cma_process_remove(struct cma_device *cma_dev)4812static void cma_process_remove(struct cma_device *cma_dev)
4818{4813{
4819 struct rdma_id_private *id_priv;
4820 int ret;
4821
4822 mutex_lock(&lock);4814 mutex_lock(&lock);
4823 while (!list_empty(&cma_dev->id_list)) {4815 while (!list_empty(&cma_dev->id_list)) {
4824 id_priv = list_entry(cma_dev->id_list.next,4816 struct rdma_id_private *id_priv = list_first_entry(
4825 struct rdma_id_private, list);4817 &cma_dev->id_list, struct rdma_id_private, list);
4826 4818
4827 list_del(&id_priv->listen_list);4819 list_del(&id_priv->listen_list);
4828 list_del_init(&id_priv->list);4820 list_del_init(&id_priv->list);
4829 cma_id_get(id_priv);4821 cma_id_get(id_priv);
4830 mutex_unlock(&lock);4822 mutex_unlock(&lock);
4831 4823
4832 ret = id_priv->internal_id ? 1 : cma_remove_id_dev(id_priv);4824 cma_send_device_removal_put(id_priv);
4833 cma_id_put(id_priv);
4834 if (ret)
4835 rdma_destroy_id(&id_priv->id);
4836 4825
4837 mutex_lock(&lock);4826 mutex_lock(&lock);
4838 }4827 }
drivers/infiniband/core/counters.c+7−17
@@ -8,7 +8,7 @@ · 7 unmodified lines
8#include "core_priv.h"8#include "core_priv.h"
9#include "restrack.h"9#include "restrack.h"
10 10
11#define ALL_AUTO_MODE_MASKS (RDMA_COUNTER_MASK_QP_TYPE)11#define ALL_AUTO_MODE_MASKS (RDMA_COUNTER_MASK_QP_TYPE | RDMA_COUNTER_MASK_PID)
12 12
13static int __counter_set_mode(struct rdma_counter_mode *curr,13static int __counter_set_mode(struct rdma_counter_mode *curr,
14 enum rdma_nl_counter_mode new_mode,14 enum rdma_nl_counter_mode new_mode,
@@ -149,23 +149,13 @@ static bool auto_mode_match(struct ib_qp *qp, struct rdma_counter *counter, · 134 unmodified lines
149 struct auto_mode_param *param = &counter->mode.param;149 struct auto_mode_param *param = &counter->mode.param;
150 bool match = true;150 bool match = true;
151 151
152 /*
153 * Ensure that counter belongs to the right PID. This operation can
154 * race with user space which kills the process and leaves QP and
155 * counters orphans.
156 *
157 * It is not a big deal because exitted task will leave both QP and
158 * counter in the same bucket of zombie process. Just ensure that
159 * process is still alive before procedding.
160 *
161 */
162 if (task_pid_nr(counter->res.task) != task_pid_nr(qp->res.task) ||
163 !task_pid_nr(qp->res.task))
164 return false;
165
166 if (auto_mask & RDMA_COUNTER_MASK_QP_TYPE)152 if (auto_mask & RDMA_COUNTER_MASK_QP_TYPE)
167 match &= (param->qp_type == qp->qp_type);153 match &= (param->qp_type == qp->qp_type);
168 154
155 if (auto_mask & RDMA_COUNTER_MASK_PID)
156 match &= (task_pid_nr(counter->res.task) ==
157 task_pid_nr(qp->res.task));
158
169 return match;159 return match;
170}160}
171 161
@@ -288,7 +278,7 @@ int rdma_counter_bind_qp_auto(struct ib_qp *qp, u8 port) · 116 unmodified lines
288 struct rdma_counter *counter;278 struct rdma_counter *counter;
289 int ret;279 int ret;
290 280
291 if (!qp->res.valid)281 if (!qp->res.valid || rdma_is_kernel_res(&qp->res))
292 return 0;282 return 0;
293 283
294 if (!rdma_is_port_valid(dev, port))284 if (!rdma_is_port_valid(dev, port))
@@ -483,7 +473,7 @@ int rdma_counter_bind_qpn(struct ib_device *dev, u8 port, · 188 unmodified lines
483 goto err;473 goto err;
484 }474 }
485 475
486 if (counter->res.task != qp->res.task) {476 if (rdma_is_kernel_res(&counter->res) != rdma_is_kernel_res(&qp->res)) {
487 ret = -EINVAL;477 ret = -EINVAL;
488 goto err_task;478 goto err_task;
489 }479 }
drivers/infiniband/core/device.c+22−6
@@ -272,7 +272,6 @@ static void ib_device_check_mandatory(struct ib_device *device) · 271 unmodified lines
272 } mandatory_table[] = {272 } mandatory_table[] = {
273 IB_MANDATORY_FUNC(query_device),273 IB_MANDATORY_FUNC(query_device),
274 IB_MANDATORY_FUNC(query_port),274 IB_MANDATORY_FUNC(query_port),
275 IB_MANDATORY_FUNC(query_pkey),
276 IB_MANDATORY_FUNC(alloc_pd),275 IB_MANDATORY_FUNC(alloc_pd),
277 IB_MANDATORY_FUNC(dealloc_pd),276 IB_MANDATORY_FUNC(dealloc_pd),
278 IB_MANDATORY_FUNC(create_qp),277 IB_MANDATORY_FUNC(create_qp),
@@ -1343,6 +1342,10 @@ out: · 1064 unmodified lines
1343 return ret;1342 return ret;
1344}1343}
1345 1344
1345static void prevent_dealloc_device(struct ib_device *ib_dev)
1346{
1347}
1348
1346/**1349/**
1347 * ib_register_device - Register an IB device with IB core1350 * ib_register_device - Register an IB device with IB core
1348 * @device: Device to register1351 * @device: Device to register
@@ -1413,11 +1416,11 @@ int ib_register_device(struct ib_device *device, const char *name) · 64 unmodified lines
1413 * possibility for a parallel unregistration along with this1416 * possibility for a parallel unregistration along with this
1414 * error flow. Since we have a refcount here we know any1417 * error flow. Since we have a refcount here we know any
1415 * parallel flow is stopped in disable_device and will see the1418 * parallel flow is stopped in disable_device and will see the
1416 * NULL pointers, causing the responsibility to1419 * special dealloc_driver pointer, causing the responsibility to
1417 * ib_dealloc_device() to revert back to this thread.1420 * ib_dealloc_device() to revert back to this thread.
1418 */1421 */
1419 dealloc_fn = device->ops.dealloc_driver;1422 dealloc_fn = device->ops.dealloc_driver;
1420 device->ops.dealloc_driver = NULL;1423 device->ops.dealloc_driver = prevent_dealloc_device;
1421 ib_device_put(device);1424 ib_device_put(device);
1422 __ib_unregister_device(device);1425 __ib_unregister_device(device);
1423 device->ops.dealloc_driver = dealloc_fn;1426 device->ops.dealloc_driver = dealloc_fn;
@@ -1466,7 +1469,8 @@ static void __ib_unregister_device(struct ib_device *ib_dev) · 42 unmodified lines
1466 * Drivers using the new flow may not call ib_dealloc_device except1469 * Drivers using the new flow may not call ib_dealloc_device except
1467 * in error unwind prior to registration success.1470 * in error unwind prior to registration success.
1468 */1471 */
1469 if (ib_dev->ops.dealloc_driver) {1472 if (ib_dev->ops.dealloc_driver &&
1473 ib_dev->ops.dealloc_driver != prevent_dealloc_device) {
1470 WARN_ON(kref_read(&ib_dev->dev.kobj.kref) <= 1);1474 WARN_ON(kref_read(&ib_dev->dev.kobj.kref) <= 1);
1471 ib_dealloc_device(ib_dev);1475 ib_dealloc_device(ib_dev);
1472 }1476 }
@@ -2361,6 +2365,9 @@ int ib_query_pkey(struct ib_device *device, · 888 unmodified lines
2361 if (!rdma_is_port_valid(device, port_num))2365 if (!rdma_is_port_valid(device, port_num))
2362 return -EINVAL;2366 return -EINVAL;
2363 2367
2368 if (!device->ops.query_pkey)
2369 return -EOPNOTSUPP;
2370
2364 return device->ops.query_pkey(device, port_num, index, pkey);2371 return device->ops.query_pkey(device, port_num, index, pkey);
2365}2372}
2366EXPORT_SYMBOL(ib_query_pkey);2373EXPORT_SYMBOL(ib_query_pkey);
@@ -2621,8 +2628,14 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops) · 254 unmodified lines
2621 SET_DEVICE_OP(dev_ops, drain_rq);2628 SET_DEVICE_OP(dev_ops, drain_rq);
2622 SET_DEVICE_OP(dev_ops, drain_sq);2629 SET_DEVICE_OP(dev_ops, drain_sq);
2623 SET_DEVICE_OP(dev_ops, enable_driver);2630 SET_DEVICE_OP(dev_ops, enable_driver);
2624 SET_DEVICE_OP(dev_ops, fill_res_entry);2631 SET_DEVICE_OP(dev_ops, fill_res_cm_id_entry);
2625 SET_DEVICE_OP(dev_ops, fill_stat_entry);2632 SET_DEVICE_OP(dev_ops, fill_res_cq_entry);
2633 SET_DEVICE_OP(dev_ops, fill_res_cq_entry_raw);
2634 SET_DEVICE_OP(dev_ops, fill_res_mr_entry);
2635 SET_DEVICE_OP(dev_ops, fill_res_mr_entry_raw);
2636 SET_DEVICE_OP(dev_ops, fill_res_qp_entry);
2637 SET_DEVICE_OP(dev_ops, fill_res_qp_entry_raw);
2638 SET_DEVICE_OP(dev_ops, fill_stat_mr_entry);
2626 SET_DEVICE_OP(dev_ops, get_dev_fw_str);2639 SET_DEVICE_OP(dev_ops, get_dev_fw_str);
2627 SET_DEVICE_OP(dev_ops, get_dma_mr);2640 SET_DEVICE_OP(dev_ops, get_dma_mr);
2628 SET_DEVICE_OP(dev_ops, get_hw_stats);2641 SET_DEVICE_OP(dev_ops, get_hw_stats);
@@ -2667,6 +2680,7 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops) · 38 unmodified lines
2667 SET_DEVICE_OP(dev_ops, query_port);2680 SET_DEVICE_OP(dev_ops, query_port);
2668 SET_DEVICE_OP(dev_ops, query_qp);2681 SET_DEVICE_OP(dev_ops, query_qp);
2669 SET_DEVICE_OP(dev_ops, query_srq);2682 SET_DEVICE_OP(dev_ops, query_srq);
2683 SET_DEVICE_OP(dev_ops, query_ucontext);
2670 SET_DEVICE_OP(dev_ops, rdma_netdev_get_params);2684 SET_DEVICE_OP(dev_ops, rdma_netdev_get_params);
2671 SET_DEVICE_OP(dev_ops, read_counters);2685 SET_DEVICE_OP(dev_ops, read_counters);
2672 SET_DEVICE_OP(dev_ops, reg_dm_mr);2686 SET_DEVICE_OP(dev_ops, reg_dm_mr);
@@ -2679,10 +2693,12 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops) · 6 unmodified lines
2679 SET_DEVICE_OP(dev_ops, set_vf_link_state);2693 SET_DEVICE_OP(dev_ops, set_vf_link_state);
2680 2694
2681 SET_OBJ_SIZE(dev_ops, ib_ah);2695 SET_OBJ_SIZE(dev_ops, ib_ah);
2696 SET_OBJ_SIZE(dev_ops, ib_counters);
2682 SET_OBJ_SIZE(dev_ops, ib_cq);2697 SET_OBJ_SIZE(dev_ops, ib_cq);
2683 SET_OBJ_SIZE(dev_ops, ib_pd);2698 SET_OBJ_SIZE(dev_ops, ib_pd);
2684 SET_OBJ_SIZE(dev_ops, ib_srq);2699 SET_OBJ_SIZE(dev_ops, ib_srq);
2685 SET_OBJ_SIZE(dev_ops, ib_ucontext);2700 SET_OBJ_SIZE(dev_ops, ib_ucontext);
2701 SET_OBJ_SIZE(dev_ops, ib_xrcd);
2686}2702}
2687EXPORT_SYMBOL(ib_set_device_ops);2703EXPORT_SYMBOL(ib_set_device_ops);
2688 2704
drivers/infiniband/core/mad.c+15−15
@@ -402,7 +402,7 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device, · 401 unmodified lines
402 INIT_DELAYED_WORK(&mad_agent_priv->timed_work, timeout_sends);402 INIT_DELAYED_WORK(&mad_agent_priv->timed_work, timeout_sends);
403 INIT_LIST_HEAD(&mad_agent_priv->local_list);403 INIT_LIST_HEAD(&mad_agent_priv->local_list);
404 INIT_WORK(&mad_agent_priv->local_work, local_completions);404 INIT_WORK(&mad_agent_priv->local_work, local_completions);
405 atomic_set(&mad_agent_priv->refcount, 1);405 refcount_set(&mad_agent_priv->refcount, 1);
406 init_completion(&mad_agent_priv->comp);406 init_completion(&mad_agent_priv->comp);
407 407
408 ret2 = ib_mad_agent_security_setup(&mad_agent_priv->agent, qp_type);408 ret2 = ib_mad_agent_security_setup(&mad_agent_priv->agent, qp_type);
@@ -484,7 +484,7 @@ EXPORT_SYMBOL(ib_register_mad_agent); · 75 unmodified lines
484 484
485static inline void deref_mad_agent(struct ib_mad_agent_private *mad_agent_priv)485static inline void deref_mad_agent(struct ib_mad_agent_private *mad_agent_priv)
486{486{
487 if (atomic_dec_and_test(&mad_agent_priv->refcount))487 if (refcount_dec_and_test(&mad_agent_priv->refcount))
488 complete(&mad_agent_priv->comp);488 complete(&mad_agent_priv->comp);
489}489}
490 490
@@ -718,7 +718,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, · 227 unmodified lines
718 * Reference MAD agent until receive718 * Reference MAD agent until receive
719 * side of local completion handled719 * side of local completion handled
720 */720 */
721 atomic_inc(&mad_agent_priv->refcount);721 refcount_inc(&mad_agent_priv->refcount);
722 } else722 } else
723 kfree(mad_priv);723 kfree(mad_priv);
724 break;724 break;
@@ -758,7 +758,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, · 33 unmodified lines
758 local->return_wc_byte_len = mad_size;758 local->return_wc_byte_len = mad_size;
759 }759 }
760 /* Reference MAD agent until send side of local completion handled */760 /* Reference MAD agent until send side of local completion handled */
761 atomic_inc(&mad_agent_priv->refcount);761 refcount_inc(&mad_agent_priv->refcount);
762 /* Queue local completion to local list */762 /* Queue local completion to local list */
763 spin_lock_irqsave(&mad_agent_priv->lock, flags);763 spin_lock_irqsave(&mad_agent_priv->lock, flags);
764 list_add_tail(&local->completion_list, &mad_agent_priv->local_list);764 list_add_tail(&local->completion_list, &mad_agent_priv->local_list);
@@ -916,7 +916,7 @@ struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent, · 151 unmodified lines
916 }916 }
917 917
918 mad_send_wr->send_buf.mad_agent = mad_agent;918 mad_send_wr->send_buf.mad_agent = mad_agent;
919 atomic_inc(&mad_agent_priv->refcount);919 refcount_inc(&mad_agent_priv->refcount);
920 return &mad_send_wr->send_buf;920 return &mad_send_wr->send_buf;
921}921}
922EXPORT_SYMBOL(ib_create_send_mad);922EXPORT_SYMBOL(ib_create_send_mad);
@@ -1131,7 +1131,7 @@ int ib_post_send_mad(struct ib_mad_send_buf *send_buf, · 208 unmodified lines
1131 mad_send_wr->status = IB_WC_SUCCESS;1131 mad_send_wr->status = IB_WC_SUCCESS;
1132 1132
1133 /* Reference MAD agent until send completes */1133 /* Reference MAD agent until send completes */
1134 atomic_inc(&mad_agent_priv->refcount);1134 refcount_inc(&mad_agent_priv->refcount);
1135 spin_lock_irqsave(&mad_agent_priv->lock, flags);1135 spin_lock_irqsave(&mad_agent_priv->lock, flags);
1136 list_add_tail(&mad_send_wr->agent_list,1136 list_add_tail(&mad_send_wr->agent_list,
1137 &mad_agent_priv->send_list);1137 &mad_agent_priv->send_list);
@@ -1148,7 +1148,7 @@ int ib_post_send_mad(struct ib_mad_send_buf *send_buf, · 10 unmodified lines
1148 spin_lock_irqsave(&mad_agent_priv->lock, flags);1148 spin_lock_irqsave(&mad_agent_priv->lock, flags);
1149 list_del(&mad_send_wr->agent_list);1149 list_del(&mad_send_wr->agent_list);
1150 spin_unlock_irqrestore(&mad_agent_priv->lock, flags);1150 spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
1151 atomic_dec(&mad_agent_priv->refcount);1151 deref_mad_agent(mad_agent_priv);
1152 goto error;1152 goto error;
1153 }1153 }
1154 }1154 }
@@ -1554,7 +1554,7 @@ find_mad_agent(struct ib_mad_port_private *port_priv, · 399 unmodified lines
1554 hi_tid = be64_to_cpu(mad_hdr->tid) >> 32;1554 hi_tid = be64_to_cpu(mad_hdr->tid) >> 32;
1555 rcu_read_lock();1555 rcu_read_lock();
1556 mad_agent = xa_load(&ib_mad_clients, hi_tid);1556 mad_agent = xa_load(&ib_mad_clients, hi_tid);
1557 if (mad_agent && !atomic_inc_not_zero(&mad_agent->refcount))1557 if (mad_agent && !refcount_inc_not_zero(&mad_agent->refcount))
1558 mad_agent = NULL;1558 mad_agent = NULL;
1559 rcu_read_unlock();1559 rcu_read_unlock();
1560 } else {1560 } else {
@@ -1606,7 +1606,7 @@ find_mad_agent(struct ib_mad_port_private *port_priv, · 45 unmodified lines
1606 }1606 }
1607 }1607 }
1608 if (mad_agent)1608 if (mad_agent)
1609 atomic_inc(&mad_agent->refcount);1609 refcount_inc(&mad_agent->refcount);
1610out:1610out:
1611 spin_unlock_irqrestore(&port_priv->reg_lock, flags);1611 spin_unlock_irqrestore(&port_priv->reg_lock, flags);
1612 }1612 }
@@ -1831,7 +1831,7 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv, · 218 unmodified lines
1831 mad_agent_priv->agent.recv_handler(1831 mad_agent_priv->agent.recv_handler(
1832 &mad_agent_priv->agent, NULL,1832 &mad_agent_priv->agent, NULL,
1833 mad_recv_wc);1833 mad_recv_wc);
1834 atomic_dec(&mad_agent_priv->refcount);1834 deref_mad_agent(mad_agent_priv);
1835 } else {1835 } else {
1836 /* not user rmpp, revert to normal behavior and1836 /* not user rmpp, revert to normal behavior and
1837 * drop the mad */1837 * drop the mad */
@@ -1848,7 +1848,7 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv, · 10 unmodified lines
1848 &mad_agent_priv->agent,1848 &mad_agent_priv->agent,
1849 &mad_send_wr->send_buf,1849 &mad_send_wr->send_buf,
1850 mad_recv_wc);1850 mad_recv_wc);
1851 atomic_dec(&mad_agent_priv->refcount);1851 deref_mad_agent(mad_agent_priv);
1852 1852
1853 mad_send_wc.status = IB_WC_SUCCESS;1853 mad_send_wc.status = IB_WC_SUCCESS;
1854 mad_send_wc.vendor_err = 0;1854 mad_send_wc.vendor_err = 0;
@@ -2438,7 +2438,7 @@ static void cancel_mads(struct ib_mad_agent_private *mad_agent_priv) · 583 unmodified lines
2438 list_del(&mad_send_wr->agent_list);2438 list_del(&mad_send_wr->agent_list);
2439 mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,2439 mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
2440 &mad_send_wc);2440 &mad_send_wc);
2441 atomic_dec(&mad_agent_priv->refcount);2441 deref_mad_agent(mad_agent_priv);
2442 }2442 }
2443}2443}
2444 2444
@@ -2572,7 +2572,7 @@ static void local_completions(struct work_struct *work) · 127 unmodified lines
2572 &local->mad_send_wr->send_buf,2572 &local->mad_send_wr->send_buf,
2573 &local->mad_priv->header.recv_wc);2573 &local->mad_priv->header.recv_wc);
2574 spin_lock_irqsave(&recv_mad_agent->lock, flags);2574 spin_lock_irqsave(&recv_mad_agent->lock, flags);
2575 atomic_dec(&recv_mad_agent->refcount);2575 deref_mad_agent(recv_mad_agent);
2576 spin_unlock_irqrestore(&recv_mad_agent->lock, flags);2576 spin_unlock_irqrestore(&recv_mad_agent->lock, flags);
2577 }2577 }
2578 2578
@@ -2585,7 +2585,7 @@ local_send_completion: · 6 unmodified lines
2585 &mad_send_wc);2585 &mad_send_wc);
2586 2586
2587 spin_lock_irqsave(&mad_agent_priv->lock, flags);2587 spin_lock_irqsave(&mad_agent_priv->lock, flags);
2588 atomic_dec(&mad_agent_priv->refcount);2588 deref_mad_agent(mad_agent_priv);
2589 if (free_mad)2589 if (free_mad)
2590 kfree(local->mad_priv);2590 kfree(local->mad_priv);
2591 kfree(local);2591 kfree(local);
@@ -2671,7 +2671,7 @@ static void timeout_sends(struct work_struct *work) · 79 unmodified lines
2671 mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,2671 mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
2672 &mad_send_wc);2672 &mad_send_wc);
2673 2673
2674 atomic_dec(&mad_agent_priv->refcount);2674 deref_mad_agent(mad_agent_priv);
2675 spin_lock_irqsave(&mad_agent_priv->lock, flags);2675 spin_lock_irqsave(&mad_agent_priv->lock, flags);
2676 }2676 }
2677 spin_unlock_irqrestore(&mad_agent_priv->lock, flags);2677 spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
drivers/infiniband/core/mad_priv.h+1−1
@@ -103,7 +103,7 @@ struct ib_mad_agent_private { · 102 unmodified lines
103 struct work_struct local_work;103 struct work_struct local_work;
104 struct list_head rmpp_list;104 struct list_head rmpp_list;
105 105
106 atomic_t refcount;106 refcount_t refcount;
107 union {107 union {
108 struct completion comp;108 struct completion comp;
109 struct rcu_head rcu;109 struct rcu_head rcu;
drivers/infiniband/core/mad_rmpp.c+9−18
@@ -40,8 +40,7 @@ · 39 unmodified lines
40enum rmpp_state {40enum rmpp_state {
41 RMPP_STATE_ACTIVE,41 RMPP_STATE_ACTIVE,
42 RMPP_STATE_TIMEOUT,42 RMPP_STATE_TIMEOUT,
43 RMPP_STATE_COMPLETE,43 RMPP_STATE_COMPLETE
44 RMPP_STATE_CANCELING
45};44};
46 45
47struct mad_rmpp_recv {46struct mad_rmpp_recv {
@@ -52,7 +51,7 @@ struct mad_rmpp_recv { · 4 unmodified lines
52 struct completion comp;51 struct completion comp;
53 enum rmpp_state state;52 enum rmpp_state state;
54 spinlock_t lock;53 spinlock_t lock;
55 atomic_t refcount;54 refcount_t refcount;
56 55
57 struct ib_ah *ah;56 struct ib_ah *ah;
58 struct ib_mad_recv_wc *rmpp_wc;57 struct ib_mad_recv_wc *rmpp_wc;
@@ -73,7 +72,7 @@ struct mad_rmpp_recv { · 14 unmodified lines
73 72
74static inline void deref_rmpp_recv(struct mad_rmpp_recv *rmpp_recv)73static inline void deref_rmpp_recv(struct mad_rmpp_recv *rmpp_recv)
75{74{
76 if (atomic_dec_and_test(&rmpp_recv->refcount))75 if (refcount_dec_and_test(&rmpp_recv->refcount))
77 complete(&rmpp_recv->comp);76 complete(&rmpp_recv->comp);
78}77}
79 78
@@ -91,23 +90,19 @@ void ib_cancel_rmpp_recvs(struct ib_mad_agent_private *agent) · 11 unmodified lines
91 unsigned long flags;90 unsigned long flags;
92 91
93 spin_lock_irqsave(&agent->lock, flags);92 spin_lock_irqsave(&agent->lock, flags);
94 list_for_each_entry(rmpp_recv, &agent->rmpp_list, list) {
95 if (rmpp_recv->state != RMPP_STATE_COMPLETE)
96 ib_free_recv_mad(rmpp_recv->rmpp_wc);
97 rmpp_recv->state = RMPP_STATE_CANCELING;
98 }
99 spin_unlock_irqrestore(&agent->lock, flags);
100
101 list_for_each_entry(rmpp_recv, &agent->rmpp_list, list) {93 list_for_each_entry(rmpp_recv, &agent->rmpp_list, list) {
102 cancel_delayed_work(&rmpp_recv->timeout_work);94 cancel_delayed_work(&rmpp_recv->timeout_work);
103 cancel_delayed_work(&rmpp_recv->cleanup_work);95 cancel_delayed_work(&rmpp_recv->cleanup_work);
104 }96 }
97 spin_unlock_irqrestore(&agent->lock, flags);
105 98
106 flush_workqueue(agent->qp_info->port_priv->wq);99 flush_workqueue(agent->qp_info->port_priv->wq);
107 100
108 list_for_each_entry_safe(rmpp_recv, temp_rmpp_recv,101 list_for_each_entry_safe(rmpp_recv, temp_rmpp_recv,
109 &agent->rmpp_list, list) {102 &agent->rmpp_list, list) {
110 list_del(&rmpp_recv->list);103 list_del(&rmpp_recv->list);
104 if (rmpp_recv->state != RMPP_STATE_COMPLETE)
105 ib_free_recv_mad(rmpp_recv->rmpp_wc);
111 destroy_rmpp_recv(rmpp_recv);106 destroy_rmpp_recv(rmpp_recv);
112 }107 }
113}108}
@@ -272,10 +267,6 @@ static void recv_cleanup_handler(struct work_struct *work) · 158 unmodified lines
272 unsigned long flags;267 unsigned long flags;
273 268
274 spin_lock_irqsave(&rmpp_recv->agent->lock, flags);269 spin_lock_irqsave(&rmpp_recv->agent->lock, flags);
275 if (rmpp_recv->state == RMPP_STATE_CANCELING) {
276 spin_unlock_irqrestore(&rmpp_recv->agent->lock, flags);
277 return;
278 }
279 list_del(&rmpp_recv->list);270 list_del(&rmpp_recv->list);
280 spin_unlock_irqrestore(&rmpp_recv->agent->lock, flags);271 spin_unlock_irqrestore(&rmpp_recv->agent->lock, flags);
281 destroy_rmpp_recv(rmpp_recv);272 destroy_rmpp_recv(rmpp_recv);
@@ -305,7 +296,7 @@ create_rmpp_recv(struct ib_mad_agent_private *agent, · 23 unmodified lines
305 INIT_DELAYED_WORK(&rmpp_recv->cleanup_work, recv_cleanup_handler);296 INIT_DELAYED_WORK(&rmpp_recv->cleanup_work, recv_cleanup_handler);
306 spin_lock_init(&rmpp_recv->lock);297 spin_lock_init(&rmpp_recv->lock);
307 rmpp_recv->state = RMPP_STATE_ACTIVE;298 rmpp_recv->state = RMPP_STATE_ACTIVE;
308 atomic_set(&rmpp_recv->refcount, 1);299 refcount_set(&rmpp_recv->refcount, 1);
309 300
310 rmpp_recv->rmpp_wc = mad_recv_wc;301 rmpp_recv->rmpp_wc = mad_recv_wc;
311 rmpp_recv->cur_seg_buf = &mad_recv_wc->recv_buf;302 rmpp_recv->cur_seg_buf = &mad_recv_wc->recv_buf;
@@ -357,7 +348,7 @@ acquire_rmpp_recv(struct ib_mad_agent_private *agent, · 45 unmodified lines
357 spin_lock_irqsave(&agent->lock, flags);348 spin_lock_irqsave(&agent->lock, flags);
358 rmpp_recv = find_rmpp_recv(agent, mad_recv_wc);349 rmpp_recv = find_rmpp_recv(agent, mad_recv_wc);
359 if (rmpp_recv)350 if (rmpp_recv)
360 atomic_inc(&rmpp_recv->refcount);351 refcount_inc(&rmpp_recv->refcount);
361 spin_unlock_irqrestore(&agent->lock, flags);352 spin_unlock_irqrestore(&agent->lock, flags);
362 return rmpp_recv;353 return rmpp_recv;
363}354}
@@ -553,7 +544,7 @@ start_rmpp(struct ib_mad_agent_private *agent, · 189 unmodified lines
553 destroy_rmpp_recv(rmpp_recv);544 destroy_rmpp_recv(rmpp_recv);
554 return continue_rmpp(agent, mad_recv_wc);545 return continue_rmpp(agent, mad_recv_wc);
555 }546 }
556 atomic_inc(&rmpp_recv->refcount);547 refcount_inc(&rmpp_recv->refcount);
557 548
558 if (get_last_flag(&mad_recv_wc->recv_buf)) {549 if (get_last_flag(&mad_recv_wc->recv_buf)) {
559 rmpp_recv->state = RMPP_STATE_COMPLETE;550 rmpp_recv->state = RMPP_STATE_COMPLETE;
drivers/infiniband/core/nldev.c+126−97
@@ -114,6 +114,7 @@ static const struct nla_policy nldev_policy[RDMA_NLDEV_ATTR_MAX] = { · 113 unmodified lines
114 [RDMA_NLDEV_ATTR_RES_PS] = { .type = NLA_U32 },114 [RDMA_NLDEV_ATTR_RES_PS] = { .type = NLA_U32 },
115 [RDMA_NLDEV_ATTR_RES_QP] = { .type = NLA_NESTED },115 [RDMA_NLDEV_ATTR_RES_QP] = { .type = NLA_NESTED },
116 [RDMA_NLDEV_ATTR_RES_QP_ENTRY] = { .type = NLA_NESTED },116 [RDMA_NLDEV_ATTR_RES_QP_ENTRY] = { .type = NLA_NESTED },
117 [RDMA_NLDEV_ATTR_RES_RAW] = { .type = NLA_BINARY },
117 [RDMA_NLDEV_ATTR_RES_RKEY] = { .type = NLA_U32 },118 [RDMA_NLDEV_ATTR_RES_RKEY] = { .type = NLA_U32 },
118 [RDMA_NLDEV_ATTR_RES_RQPN] = { .type = NLA_U32 },119 [RDMA_NLDEV_ATTR_RES_RQPN] = { .type = NLA_U32 },
119 [RDMA_NLDEV_ATTR_RES_RQ_PSN] = { .type = NLA_U32 },120 [RDMA_NLDEV_ATTR_RES_RQ_PSN] = { .type = NLA_U32 },
@@ -446,27 +447,11 @@ static int fill_res_name_pid(struct sk_buff *msg, · 326 unmodified lines
446 return err ? -EMSGSIZE : 0;447 return err ? -EMSGSIZE : 0;
447}448}
448 449
449static bool fill_res_entry(struct ib_device *dev, struct sk_buff *msg,450static int fill_res_qp_entry_query(struct sk_buff *msg,
450 struct rdma_restrack_entry *res)451 struct rdma_restrack_entry *res,
452 struct ib_device *dev,
453 struct ib_qp *qp)
451{454{
452 if (!dev->ops.fill_res_entry)
453 return false;
454 return dev->ops.fill_res_entry(msg, res);
455}
456
457static bool fill_stat_entry(struct ib_device *dev, struct sk_buff *msg,
458 struct rdma_restrack_entry *res)
459{
460 if (!dev->ops.fill_stat_entry)
461 return false;
462 return dev->ops.fill_stat_entry(msg, res);
463}
464
465static int fill_res_qp_entry(struct sk_buff *msg, bool has_cap_net_admin,
466 struct rdma_restrack_entry *res, uint32_t port)
467{
468 struct ib_qp *qp = container_of(res, struct ib_qp, res);
469 struct ib_device *dev = qp->device;
470 struct ib_qp_init_attr qp_init_attr;455 struct ib_qp_init_attr qp_init_attr;
471 struct ib_qp_attr qp_attr;456 struct ib_qp_attr qp_attr;
472 int ret;457 int ret;
@@ -475,16 +460,6 @@ static int fill_res_qp_entry(struct sk_buff *msg, bool has_cap_net_admin, · 2 unmodified lines
475 if (ret)460 if (ret)
476 return ret;461 return ret;
477 462
478 if (port && port != qp_attr.port_num)
479 return -EAGAIN;
480
481 /* In create_qp() port is not set yet */
482 if (qp_attr.port_num &&
483 nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, qp_attr.port_num))
484 goto err;
485
486 if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_LQPN, qp->qp_num))
487 goto err;
488 if (qp->qp_type == IB_QPT_RC || qp->qp_type == IB_QPT_UC) {463 if (qp->qp_type == IB_QPT_RC || qp->qp_type == IB_QPT_UC) {
489 if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_RQPN,464 if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_RQPN,
490 qp_attr.dest_qp_num))465 qp_attr.dest_qp_num))
@@ -508,19 +483,53 @@ static int fill_res_qp_entry(struct sk_buff *msg, bool has_cap_net_admin, · 17 unmodified lines
508 if (nla_put_u8(msg, RDMA_NLDEV_ATTR_RES_STATE, qp_attr.qp_state))483 if (nla_put_u8(msg, RDMA_NLDEV_ATTR_RES_STATE, qp_attr.qp_state))
509 goto err;484 goto err;
510 485
486 if (dev->ops.fill_res_qp_entry)
487 return dev->ops.fill_res_qp_entry(msg, qp);
488 return 0;
489
490err: return -EMSGSIZE;
491}
492
493static int fill_res_qp_entry(struct sk_buff *msg, bool has_cap_net_admin,
494 struct rdma_restrack_entry *res, uint32_t port)
495{
496 struct ib_qp *qp = container_of(res, struct ib_qp, res);
497 struct ib_device *dev = qp->device;
498 int ret;
499
500 if (port && port != qp->port)
501 return -EAGAIN;
502
503 /* In create_qp() port is not set yet */
504 if (qp->port && nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, qp->port))
505 return -EINVAL;
506
507 ret = nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_LQPN, qp->qp_num);
508 if (ret)
509 return -EMSGSIZE;
510
511 if (!rdma_is_kernel_res(res) &&511 if (!rdma_is_kernel_res(res) &&
512 nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_PDN, qp->pd->res.id))512 nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_PDN, qp->pd->res.id))
513 goto err;513 return -EMSGSIZE;
514 514
515 if (fill_res_name_pid(msg, res))515 ret = fill_res_name_pid(msg, res);
516 goto err;516 if (ret)
517 return -EMSGSIZE;
517 518
518 if (fill_res_entry(dev, msg, res))519 return fill_res_qp_entry_query(msg, res, dev, qp);
519 goto err;520}
520 521
521 return 0;522static int fill_res_qp_raw_entry(struct sk_buff *msg, bool has_cap_net_admin,
523 struct rdma_restrack_entry *res, uint32_t port)
524{
525 struct ib_qp *qp = container_of(res, struct ib_qp, res);
526 struct ib_device *dev = qp->device;
522 527
523err: return -EMSGSIZE;528 if (port && port != qp->port)
529 return -EAGAIN;
530 if (!dev->ops.fill_res_qp_entry_raw)
531 return -EINVAL;
532 return dev->ops.fill_res_qp_entry_raw(msg, qp);
524}533}
525 534
526static int fill_res_cm_id_entry(struct sk_buff *msg, bool has_cap_net_admin,535static int fill_res_cm_id_entry(struct sk_buff *msg, bool has_cap_net_admin,
@@ -568,9 +577,8 @@ static int fill_res_cm_id_entry(struct sk_buff *msg, bool has_cap_net_admin, · 41 unmodified lines
568 if (fill_res_name_pid(msg, res))577 if (fill_res_name_pid(msg, res))
569 goto err;578 goto err;
570 579
571 if (fill_res_entry(dev, msg, res))580 if (dev->ops.fill_res_cm_id_entry)
572 goto err;581 return dev->ops.fill_res_cm_id_entry(msg, cm_id);
573
574 return 0;582 return 0;
575 583
576err: return -EMSGSIZE;584err: return -EMSGSIZE;
@@ -583,35 +591,42 @@ static int fill_res_cq_entry(struct sk_buff *msg, bool has_cap_net_admin, · 6 unmodified lines
583 struct ib_device *dev = cq->device;591 struct ib_device *dev = cq->device;
584 592
585 if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_CQE, cq->cqe))593 if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_CQE, cq->cqe))
586 goto err;594 return -EMSGSIZE;
587 if (nla_put_u64_64bit(msg, RDMA_NLDEV_ATTR_RES_USECNT,595 if (nla_put_u64_64bit(msg, RDMA_NLDEV_ATTR_RES_USECNT,
588 atomic_read(&cq->usecnt), RDMA_NLDEV_ATTR_PAD))596 atomic_read(&cq->usecnt), RDMA_NLDEV_ATTR_PAD))
589 goto err;597 return -EMSGSIZE;
590 598
591 /* Poll context is only valid for kernel CQs */599 /* Poll context is only valid for kernel CQs */
592 if (rdma_is_kernel_res(res) &&600 if (rdma_is_kernel_res(res) &&
593 nla_put_u8(msg, RDMA_NLDEV_ATTR_RES_POLL_CTX, cq->poll_ctx))601 nla_put_u8(msg, RDMA_NLDEV_ATTR_RES_POLL_CTX, cq->poll_ctx))
594 goto err;602 return -EMSGSIZE;
595 603
596 if (nla_put_u8(msg, RDMA_NLDEV_ATTR_DEV_DIM, (cq->dim != NULL)))604 if (nla_put_u8(msg, RDMA_NLDEV_ATTR_DEV_DIM, (cq->dim != NULL)))
597 goto err;605 return -EMSGSIZE;
598 606
599 if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_CQN, res->id))607 if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_CQN, res->id))
600 goto err;608 return -EMSGSIZE;
601 if (!rdma_is_kernel_res(res) &&609 if (!rdma_is_kernel_res(res) &&
602 nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_CTXN,610 nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_CTXN,
603 cq->uobject->uevent.uobject.context->res.id))611 cq->uobject->uevent.uobject.context->res.id))
604 goto err;612 return -EMSGSIZE;
605 613
606 if (fill_res_name_pid(msg, res))614 if (fill_res_name_pid(msg, res))
607 goto err;615 return -EMSGSIZE;
608 616
609 if (fill_res_entry(dev, msg, res))617 return (dev->ops.fill_res_cq_entry) ?
610 goto err;618 dev->ops.fill_res_cq_entry(msg, cq) : 0;
619}
611 620
612 return 0;621static int fill_res_cq_raw_entry(struct sk_buff *msg, bool has_cap_net_admin,
622 struct rdma_restrack_entry *res, uint32_t port)
623{
624 struct ib_cq *cq = container_of(res, struct ib_cq, res);
625 struct ib_device *dev = cq->device;
613 626
614err: return -EMSGSIZE;627 if (!dev->ops.fill_res_cq_entry_raw)
628 return -EINVAL;
629 return dev->ops.fill_res_cq_entry_raw(msg, cq);
615}630}
616 631
617static int fill_res_mr_entry(struct sk_buff *msg, bool has_cap_net_admin,632static int fill_res_mr_entry(struct sk_buff *msg, bool has_cap_net_admin,
@@ -622,38 +637,45 @@ static int fill_res_mr_entry(struct sk_buff *msg, bool has_cap_net_admin, · 4 unmodified lines
622 637
623 if (has_cap_net_admin) {638 if (has_cap_net_admin) {
624 if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_RKEY, mr->rkey))639 if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_RKEY, mr->rkey))
625 goto err;640 return -EMSGSIZE;
626 if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_LKEY, mr->lkey))641 if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_LKEY, mr->lkey))
627 goto err;642 return -EMSGSIZE;
628 }643 }
629 644
630 if (nla_put_u64_64bit(msg, RDMA_NLDEV_ATTR_RES_MRLEN, mr->length,645 if (nla_put_u64_64bit(msg, RDMA_NLDEV_ATTR_RES_MRLEN, mr->length,
631 RDMA_NLDEV_ATTR_PAD))646 RDMA_NLDEV_ATTR_PAD))
632 goto err;647 return -EMSGSIZE;
633 648
634 if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_MRN, res->id))649 if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_MRN, res->id))
635 goto err;650 return -EMSGSIZE;
636 651
637 if (!rdma_is_kernel_res(res) &&652 if (!rdma_is_kernel_res(res) &&
638 nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_PDN, mr->pd->res.id))653 nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_PDN, mr->pd->res.id))
639 goto err;654 return -EMSGSIZE;
640 655
641 if (fill_res_name_pid(msg, res))656 if (fill_res_name_pid(msg, res))
642 goto err;657 return -EMSGSIZE;
643 658
644 if (fill_res_entry(dev, msg, res))659 return (dev->ops.fill_res_mr_entry) ?
645 goto err;660 dev->ops.fill_res_mr_entry(msg, mr) :
661 0;
662}
646 663
647 return 0;664static int fill_res_mr_raw_entry(struct sk_buff *msg, bool has_cap_net_admin,
665 struct rdma_restrack_entry *res, uint32_t port)
666{
667 struct ib_mr *mr = container_of(res, struct ib_mr, res);
668 struct ib_device *dev = mr->pd->device;
648 669
649err: return -EMSGSIZE;670 if (!dev->ops.fill_res_mr_entry_raw)
671 return -EINVAL;
672 return dev->ops.fill_res_mr_entry_raw(msg, mr);
650}673}
651 674
652static int fill_res_pd_entry(struct sk_buff *msg, bool has_cap_net_admin,675static int fill_res_pd_entry(struct sk_buff *msg, bool has_cap_net_admin,
653 struct rdma_restrack_entry *res, uint32_t port)676 struct rdma_restrack_entry *res, uint32_t port)
654{677{
655 struct ib_pd *pd = container_of(res, struct ib_pd, res);678 struct ib_pd *pd = container_of(res, struct ib_pd, res);
656 struct ib_device *dev = pd->device;
657 679
658 if (has_cap_net_admin) {680 if (has_cap_net_admin) {
659 if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_LOCAL_DMA_LKEY,681 if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_LOCAL_DMA_LKEY,
@@ -676,13 +698,7 @@ static int fill_res_pd_entry(struct sk_buff *msg, bool has_cap_net_admin, · 16 unmodified lines
676 pd->uobject->context->res.id))698 pd->uobject->context->res.id))
677 goto err;699 goto err;
678 700
679 if (fill_res_name_pid(msg, res))701 return fill_res_name_pid(msg, res);
680 goto err;
681
682 if (fill_res_entry(dev, msg, res))
683 goto err;
684
685 return 0;
686 702
687err: return -EMSGSIZE;703err: return -EMSGSIZE;
688}704}
@@ -695,11 +711,16 @@ static int fill_stat_counter_mode(struct sk_buff *msg, · 6 unmodified lines
695 if (nla_put_u32(msg, RDMA_NLDEV_ATTR_STAT_MODE, m->mode))711 if (nla_put_u32(msg, RDMA_NLDEV_ATTR_STAT_MODE, m->mode))
696 return -EMSGSIZE;712 return -EMSGSIZE;
697 713
698 if (m->mode == RDMA_COUNTER_MODE_AUTO)714 if (m->mode == RDMA_COUNTER_MODE_AUTO) {
699 if ((m->mask & RDMA_COUNTER_MASK_QP_TYPE) &&715 if ((m->mask & RDMA_COUNTER_MASK_QP_TYPE) &&
700 nla_put_u8(msg, RDMA_NLDEV_ATTR_RES_TYPE, m->param.qp_type))716 nla_put_u8(msg, RDMA_NLDEV_ATTR_RES_TYPE, m->param.qp_type))
701 return -EMSGSIZE;717 return -EMSGSIZE;
702 718
719 if ((m->mask & RDMA_COUNTER_MASK_PID) &&
720 fill_res_name_pid(msg, &counter->res))
721 return -EMSGSIZE;
722 }
723
703 return 0;724 return 0;
704}725}
705 726
@@ -738,9 +759,6 @@ static int fill_stat_counter_qps(struct sk_buff *msg, · 32 unmodified lines
738 xa_lock(&rt->xa);759 xa_lock(&rt->xa);
739 xa_for_each(&rt->xa, id, res) {760 xa_for_each(&rt->xa, id, res) {
740 qp = container_of(res, struct ib_qp, res);761 qp = container_of(res, struct ib_qp, res);
741 if (qp->qp_type == IB_QPT_RAW_PACKET && !capable(CAP_NET_RAW))
742 continue;
743
744 if (!qp->counter || (qp->counter->id != counter->id))762 if (!qp->counter || (qp->counter->id != counter->id))
745 continue;763 continue;
746 764
@@ -793,9 +811,8 @@ static int fill_stat_mr_entry(struct sk_buff *msg, bool has_cap_net_admin, · 46 unmodified lines
793 if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_MRN, res->id))811 if (nla_put_u32(msg, RDMA_NLDEV_ATTR_RES_MRN, res->id))
794 goto err;812 goto err;
795 813
796 if (fill_stat_entry(dev, msg, res))814 if (dev->ops.fill_stat_mr_entry)
797 goto err;815 return dev->ops.fill_stat_mr_entry(msg, mr);
798
799 return 0;816 return 0;
800 817
801err:818err:
@@ -840,7 +857,6 @@ static int fill_res_counter_entry(struct sk_buff *msg, bool has_cap_net_admin, · 38 unmodified lines
840 857
841 if (nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, counter->port) ||858 if (nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, counter->port) ||
842 nla_put_u32(msg, RDMA_NLDEV_ATTR_STAT_COUNTER_ID, counter->id) ||859 nla_put_u32(msg, RDMA_NLDEV_ATTR_STAT_COUNTER_ID, counter->id) ||
843 fill_res_name_pid(msg, &counter->res) ||
844 fill_stat_counter_mode(msg, counter) ||860 fill_stat_counter_mode(msg, counter) ||
845 fill_stat_counter_qps(msg, counter) ||861 fill_stat_counter_qps(msg, counter) ||
846 fill_stat_counter_hwcounters(msg, counter))862 fill_stat_counter_hwcounters(msg, counter))
@@ -1177,7 +1193,6 @@ static int nldev_res_get_dumpit(struct sk_buff *skb, · 330 unmodified lines
1177 1193
1178struct nldev_fill_res_entry {1194struct nldev_fill_res_entry {
1179 enum rdma_nldev_attr nldev_attr;1195 enum rdma_nldev_attr nldev_attr;
1180 enum rdma_nldev_command nldev_cmd;
1181 u8 flags;1196 u8 flags;
1182 u32 entry;1197 u32 entry;
1183 u32 id;1198 u32 id;
@@ -1189,40 +1204,34 @@ enum nldev_res_flags { · 5 unmodified lines
1189 1204
1190static const struct nldev_fill_res_entry fill_entries[RDMA_RESTRACK_MAX] = {1205static const struct nldev_fill_res_entry fill_entries[RDMA_RESTRACK_MAX] = {
1191 [RDMA_RESTRACK_QP] = {1206 [RDMA_RESTRACK_QP] = {
1192 .nldev_cmd = RDMA_NLDEV_CMD_RES_QP_GET,
1193 .nldev_attr = RDMA_NLDEV_ATTR_RES_QP,1207 .nldev_attr = RDMA_NLDEV_ATTR_RES_QP,
1194 .entry = RDMA_NLDEV_ATTR_RES_QP_ENTRY,1208 .entry = RDMA_NLDEV_ATTR_RES_QP_ENTRY,
1195 .id = RDMA_NLDEV_ATTR_RES_LQPN,1209 .id = RDMA_NLDEV_ATTR_RES_LQPN,
1196 },1210 },
1197 [RDMA_RESTRACK_CM_ID] = {1211 [RDMA_RESTRACK_CM_ID] = {
1198 .nldev_cmd = RDMA_NLDEV_CMD_RES_CM_ID_GET,
1199 .nldev_attr = RDMA_NLDEV_ATTR_RES_CM_ID,1212 .nldev_attr = RDMA_NLDEV_ATTR_RES_CM_ID,
1200 .entry = RDMA_NLDEV_ATTR_RES_CM_ID_ENTRY,1213 .entry = RDMA_NLDEV_ATTR_RES_CM_ID_ENTRY,
1201 .id = RDMA_NLDEV_ATTR_RES_CM_IDN,1214 .id = RDMA_NLDEV_ATTR_RES_CM_IDN,
1202 },1215 },
1203 [RDMA_RESTRACK_CQ] = {1216 [RDMA_RESTRACK_CQ] = {
1204 .nldev_cmd = RDMA_NLDEV_CMD_RES_CQ_GET,
1205 .nldev_attr = RDMA_NLDEV_ATTR_RES_CQ,1217 .nldev_attr = RDMA_NLDEV_ATTR_RES_CQ,
1206 .flags = NLDEV_PER_DEV,1218 .flags = NLDEV_PER_DEV,
1207 .entry = RDMA_NLDEV_ATTR_RES_CQ_ENTRY,1219 .entry = RDMA_NLDEV_ATTR_RES_CQ_ENTRY,
1208 .id = RDMA_NLDEV_ATTR_RES_CQN,1220 .id = RDMA_NLDEV_ATTR_RES_CQN,
1209 },1221 },
1210 [RDMA_RESTRACK_MR] = {1222 [RDMA_RESTRACK_MR] = {
1211 .nldev_cmd = RDMA_NLDEV_CMD_RES_MR_GET,
1212 .nldev_attr = RDMA_NLDEV_ATTR_RES_MR,1223 .nldev_attr = RDMA_NLDEV_ATTR_RES_MR,
1213 .flags = NLDEV_PER_DEV,1224 .flags = NLDEV_PER_DEV,
1214 .entry = RDMA_NLDEV_ATTR_RES_MR_ENTRY,1225 .entry = RDMA_NLDEV_ATTR_RES_MR_ENTRY,
1215 .id = RDMA_NLDEV_ATTR_RES_MRN,1226 .id = RDMA_NLDEV_ATTR_RES_MRN,
1216 },1227 },
1217 [RDMA_RESTRACK_PD] = {1228 [RDMA_RESTRACK_PD] = {
1218 .nldev_cmd = RDMA_NLDEV_CMD_RES_PD_GET,
1219 .nldev_attr = RDMA_NLDEV_ATTR_RES_PD,1229 .nldev_attr = RDMA_NLDEV_ATTR_RES_PD,
1220 .flags = NLDEV_PER_DEV,1230 .flags = NLDEV_PER_DEV,
1221 .entry = RDMA_NLDEV_ATTR_RES_PD_ENTRY,1231 .entry = RDMA_NLDEV_ATTR_RES_PD_ENTRY,
1222 .id = RDMA_NLDEV_ATTR_RES_PDN,1232 .id = RDMA_NLDEV_ATTR_RES_PDN,
1223 },1233 },
1224 [RDMA_RESTRACK_COUNTER] = {1234 [RDMA_RESTRACK_COUNTER] = {
1225 .nldev_cmd = RDMA_NLDEV_CMD_STAT_GET,
1226 .nldev_attr = RDMA_NLDEV_ATTR_STAT_COUNTER,1235 .nldev_attr = RDMA_NLDEV_ATTR_STAT_COUNTER,
1227 .entry = RDMA_NLDEV_ATTR_STAT_COUNTER_ENTRY,1236 .entry = RDMA_NLDEV_ATTR_STAT_COUNTER_ENTRY,
1228 .id = RDMA_NLDEV_ATTR_STAT_COUNTER_ID,1237 .id = RDMA_NLDEV_ATTR_STAT_COUNTER_ID,
@@ -1281,7 +1290,8 @@ static int res_get_common_doit(struct sk_buff *skb, struct nlmsghdr *nlh, · 52 unmodified lines
1281 }1290 }
1282 1291
1283 nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq,1292 nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq,
1284 RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, fe->nldev_cmd),1293 RDMA_NL_GET_TYPE(RDMA_NL_NLDEV,
1294 RDMA_NL_GET_OP(nlh->nlmsg_type)),
1285 0, 0);1295 0, 0);
1286 1296
1287 if (fill_nldev_handle(msg, device)) {1297 if (fill_nldev_handle(msg, device)) {
@@ -1359,7 +1369,8 @@ static int res_get_common_dumpit(struct sk_buff *skb, · 71 unmodified lines
1359 }1369 }
1360 1370
1361 nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,1371 nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
1362 RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, fe->nldev_cmd),1372 RDMA_NL_GET_TYPE(RDMA_NL_NLDEV,
1373 RDMA_NL_GET_OP(cb->nlh->nlmsg_type)),
1363 0, NLM_F_MULTI);1374 0, NLM_F_MULTI);
1364 1375
1365 if (fill_nldev_handle(skb, device)) {1376 if (fill_nldev_handle(skb, device)) {
@@ -1441,26 +1452,29 @@ err_index: · 75 unmodified lines
1441 return ret;1452 return ret;
1442}1453}
1443 1454
1444#define RES_GET_FUNCS(name, type) \1455#define RES_GET_FUNCS(name, type) \
1445 static int nldev_res_get_##name##_dumpit(struct sk_buff *skb, \1456 static int nldev_res_get_##name##_dumpit(struct sk_buff *skb, \
1446 struct netlink_callback *cb) \1457 struct netlink_callback *cb) \
1447 { \1458 { \
1448 return res_get_common_dumpit(skb, cb, type, \1459 return res_get_common_dumpit(skb, cb, type, \
1449 fill_res_##name##_entry); \1460 fill_res_##name##_entry); \
1450 } \1461 } \
1451 static int nldev_res_get_##name##_doit(struct sk_buff *skb, \1462 static int nldev_res_get_##name##_doit(struct sk_buff *skb, \
1452 struct nlmsghdr *nlh, \1463 struct nlmsghdr *nlh, \
1453 struct netlink_ext_ack *extack) \1464 struct netlink_ext_ack *extack) \
1454 { \1465 { \
1455 return res_get_common_doit(skb, nlh, extack, type, \1466 return res_get_common_doit(skb, nlh, extack, type, \
1456 fill_res_##name##_entry); \1467 fill_res_##name##_entry); \
1457 }1468 }
1458 1469
1459RES_GET_FUNCS(qp, RDMA_RESTRACK_QP);1470RES_GET_FUNCS(qp, RDMA_RESTRACK_QP);
1471RES_GET_FUNCS(qp_raw, RDMA_RESTRACK_QP);
1460RES_GET_FUNCS(cm_id, RDMA_RESTRACK_CM_ID);1472RES_GET_FUNCS(cm_id, RDMA_RESTRACK_CM_ID);
1461RES_GET_FUNCS(cq, RDMA_RESTRACK_CQ);1473RES_GET_FUNCS(cq, RDMA_RESTRACK_CQ);
1474RES_GET_FUNCS(cq_raw, RDMA_RESTRACK_CQ);
1462RES_GET_FUNCS(pd, RDMA_RESTRACK_PD);1475RES_GET_FUNCS(pd, RDMA_RESTRACK_PD);
1463RES_GET_FUNCS(mr, RDMA_RESTRACK_MR);1476RES_GET_FUNCS(mr, RDMA_RESTRACK_MR);
1477RES_GET_FUNCS(mr_raw, RDMA_RESTRACK_MR);
1464RES_GET_FUNCS(counter, RDMA_RESTRACK_COUNTER);1478RES_GET_FUNCS(counter, RDMA_RESTRACK_COUNTER);
1465 1479
1466static LIST_HEAD(link_ops);1480static LIST_HEAD(link_ops);
@@ -2145,6 +2159,21 @@ static const struct rdma_nl_cbs nldev_cb_table[RDMA_NLDEV_NUM_OPS] = { · 678 unmodified lines
2145 .doit = nldev_stat_del_doit,2159 .doit = nldev_stat_del_doit,
2146 .flags = RDMA_NL_ADMIN_PERM,2160 .flags = RDMA_NL_ADMIN_PERM,
2147 },2161 },
2162 [RDMA_NLDEV_CMD_RES_QP_GET_RAW] = {
2163 .doit = nldev_res_get_qp_raw_doit,
2164 .dump = nldev_res_get_qp_raw_dumpit,
2165 .flags = RDMA_NL_ADMIN_PERM,
2166 },
2167 [RDMA_NLDEV_CMD_RES_CQ_GET_RAW] = {
2168 .doit = nldev_res_get_cq_raw_doit,
2169 .dump = nldev_res_get_cq_raw_dumpit,
2170 .flags = RDMA_NL_ADMIN_PERM,
2171 },
2172 [RDMA_NLDEV_CMD_RES_MR_GET_RAW] = {
2173 .doit = nldev_res_get_mr_raw_doit,
2174 .dump = nldev_res_get_mr_raw_dumpit,
2175 .flags = RDMA_NL_ADMIN_PERM,
2176 },
2148};2177};
2149 2178
2150void __init nldev_init(void)2179void __init nldev_init(void)
drivers/infiniband/core/sysfs.c+41−20
@@ -58,7 +58,7 @@ struct ib_port { · 57 unmodified lines
58 struct ib_device *ibdev;58 struct ib_device *ibdev;
59 struct gid_attr_group *gid_attr_group;59 struct gid_attr_group *gid_attr_group;
60 struct attribute_group gid_group;60 struct attribute_group gid_group;
61 struct attribute_group pkey_group;61 struct attribute_group *pkey_group;
62 struct attribute_group *pma_table;62 struct attribute_group *pma_table;
63 struct attribute_group *hw_stats_ag;63 struct attribute_group *hw_stats_ag;
64 struct rdma_hw_stats *hw_stats;64 struct rdma_hw_stats *hw_stats;
@@ -681,11 +681,16 @@ static void ib_port_release(struct kobject *kobj) · 616 unmodified lines
681 kfree(p->gid_group.attrs);681 kfree(p->gid_group.attrs);
682 }682 }
683 683
684 if (p->pkey_group.attrs) {684 if (p->pkey_group) {
685 for (i = 0; (a = p->pkey_group.attrs[i]); ++i)685 if (p->pkey_group->attrs) {
686 kfree(a);686 for (i = 0; (a = p->pkey_group->attrs[i]); ++i)
687 kfree(a);
688
689 kfree(p->pkey_group->attrs);
690 }
687 691
688 kfree(p->pkey_group.attrs);692 kfree(p->pkey_group);
693 p->pkey_group = NULL;
689 }694 }
690 695
691 kfree(p);696 kfree(p);
@@ -1118,17 +1123,26 @@ static int add_port(struct ib_core_device *coredev, int port_num) · 426 unmodified lines
1118 if (ret)1123 if (ret)
1119 goto err_free_gid_type;1124 goto err_free_gid_type;
1120 1125
1121 p->pkey_group.name = "pkeys";1126 if (attr.pkey_tbl_len) {
1122 p->pkey_group.attrs = alloc_group_attrs(show_port_pkey,1127 p->pkey_group = kzalloc(sizeof(*p->pkey_group), GFP_KERNEL);
1123 attr.pkey_tbl_len);1128 if (!p->pkey_group) {
1124 if (!p->pkey_group.attrs) {1129 ret = -ENOMEM;
1125 ret = -ENOMEM;1130 goto err_remove_gid_type;
1126 goto err_remove_gid_type;1131 }
1132
1133 p->pkey_group->name = "pkeys";
1134 p->pkey_group->attrs = alloc_group_attrs(show_port_pkey,
1135 attr.pkey_tbl_len);
1136 if (!p->pkey_group->attrs) {
1137 ret = -ENOMEM;
1138 goto err_free_pkey_group;
1139 }
1140
1141 ret = sysfs_create_group(&p->kobj, p->pkey_group);
1142 if (ret)
1143 goto err_free_pkey;
1127 }1144 }
1128 1145
1129 ret = sysfs_create_group(&p->kobj, &p->pkey_group);
1130 if (ret)
1131 goto err_free_pkey;
1132 1146
1133 if (device->ops.init_port && is_full_dev) {1147 if (device->ops.init_port && is_full_dev) {
1134 ret = device->ops.init_port(device, port_num, &p->kobj);1148 ret = device->ops.init_port(device, port_num, &p->kobj);
@@ -1150,14 +1164,20 @@ static int add_port(struct ib_core_device *coredev, int port_num) · 15 unmodified lines
1150 return 0;1164 return 0;
1151 1165
1152err_remove_pkey:1166err_remove_pkey:
1153 sysfs_remove_group(&p->kobj, &p->pkey_group);1167 if (p->pkey_group)
1168 sysfs_remove_group(&p->kobj, p->pkey_group);
1154 1169
1155err_free_pkey:1170err_free_pkey:
1156 for (i = 0; i < attr.pkey_tbl_len; ++i)1171 if (p->pkey_group) {
1157 kfree(p->pkey_group.attrs[i]);1172 for (i = 0; i < attr.pkey_tbl_len; ++i)
1173 kfree(p->pkey_group->attrs[i]);
1174
1175 kfree(p->pkey_group->attrs);
1176 p->pkey_group->attrs = NULL;
1177 }
1158 1178
1159 kfree(p->pkey_group.attrs);1179err_free_pkey_group:
1160 p->pkey_group.attrs = NULL;1180 kfree(p->pkey_group);
1161 1181
1162err_remove_gid_type:1182err_remove_gid_type:
1163 sysfs_remove_group(&p->gid_attr_group->kobj,1183 sysfs_remove_group(&p->gid_attr_group->kobj,
@@ -1317,7 +1337,8 @@ void ib_free_port_attrs(struct ib_core_device *coredev) · 153 unmodified lines
1317 1337
1318 if (port->pma_table)1338 if (port->pma_table)
1319 sysfs_remove_group(p, port->pma_table);1339 sysfs_remove_group(p, port->pma_table);
1320 sysfs_remove_group(p, &port->pkey_group);1340 if (port->pkey_group)
1341 sysfs_remove_group(p, port->pkey_group);
1321 sysfs_remove_group(p, &port->gid_group);1342 sysfs_remove_group(p, &port->gid_group);
1322 sysfs_remove_group(&port->gid_attr_group->kobj,1343 sysfs_remove_group(&port->gid_attr_group->kobj,
1323 &port->gid_attr_group->ndev);1344 &port->gid_attr_group->ndev);
drivers/infiniband/core/trace.c+0−2
@@ -9,6 +9,4 @@ · 8 unmodified lines
9 9
10#define CREATE_TRACE_POINTS10#define CREATE_TRACE_POINTS
11 11
12#include <rdma/ib_verbs.h>
13
14#include <trace/events/rdma_core.h>12#include <trace/events/rdma_core.h>
drivers/infiniband/core/umem.c+1−0
@@ -261,6 +261,7 @@ struct ib_umem *ib_umem_get(struct ib_device *device, unsigned long addr, · 260 unmodified lines
261 sg = umem->sg_head.sgl;261 sg = umem->sg_head.sgl;
262 262
263 while (npages) {263 while (npages) {
264 cond_resched();
264 ret = pin_user_pages_fast(cur_base,265 ret = pin_user_pages_fast(cur_base,
265 min_t(unsigned long, npages,266 min_t(unsigned long, npages,
266 PAGE_SIZE /267 PAGE_SIZE /
drivers/infiniband/core/umem_odp.c+2−0
@@ -152,6 +152,7 @@ EXPORT_SYMBOL(ib_umem_odp_alloc_implicit); · 151 unmodified lines
152 * ib_alloc_implicit_odp_umem()152 * ib_alloc_implicit_odp_umem()
153 * @addr: The starting userspace VA153 * @addr: The starting userspace VA
154 * @size: The length of the userspace VA154 * @size: The length of the userspace VA
155 * @ops: MMU interval ops, currently only @invalidate
155 */156 */
156struct ib_umem_odp *157struct ib_umem_odp *
157ib_umem_odp_alloc_child(struct ib_umem_odp *root, unsigned long addr,158ib_umem_odp_alloc_child(struct ib_umem_odp *root, unsigned long addr,
@@ -213,6 +214,7 @@ EXPORT_SYMBOL(ib_umem_odp_alloc_child); · 55 unmodified lines
213 * @addr: userspace virtual address to start at214 * @addr: userspace virtual address to start at
214 * @size: length of region to pin215 * @size: length of region to pin
215 * @access: IB_ACCESS_xxx flags for memory being pinned216 * @access: IB_ACCESS_xxx flags for memory being pinned
217 * @ops: MMU interval ops, currently only @invalidate
216 *218 *
217 * The driver should use when the access flags indicate ODP memory. It avoids219 * The driver should use when the access flags indicate ODP memory. It avoids
218 * pinning, instead, stores the mm for future page fault handling in220 * pinning, instead, stores the mm for future page fault handling in
drivers/infiniband/core/uverbs_cmd.c+99−222
@@ -415,8 +415,8 @@ static int ib_uverbs_query_port(struct uverbs_attr_bundle *attrs) · 414 unmodified lines
415 415
416static int ib_uverbs_alloc_pd(struct uverbs_attr_bundle *attrs)416static int ib_uverbs_alloc_pd(struct uverbs_attr_bundle *attrs)
417{417{
418 struct ib_uverbs_alloc_pd_resp resp = {};
418 struct ib_uverbs_alloc_pd cmd;419 struct ib_uverbs_alloc_pd cmd;
419 struct ib_uverbs_alloc_pd_resp resp;
420 struct ib_uobject *uobj;420 struct ib_uobject *uobj;
421 struct ib_pd *pd;421 struct ib_pd *pd;
422 int ret;422 int ret;
@@ -438,29 +438,20 @@ static int ib_uverbs_alloc_pd(struct uverbs_attr_bundle *attrs) · 15 unmodified lines
438 438
439 pd->device = ib_dev;439 pd->device = ib_dev;
440 pd->uobject = uobj;440 pd->uobject = uobj;
441 pd->__internal_mr = NULL;
442 atomic_set(&pd->usecnt, 0);441 atomic_set(&pd->usecnt, 0);
443 pd->res.type = RDMA_RESTRACK_PD;442 pd->res.type = RDMA_RESTRACK_PD;
444 443
445 ret = ib_dev->ops.alloc_pd(pd, &attrs->driver_udata);444 ret = ib_dev->ops.alloc_pd(pd, &attrs->driver_udata);
446 if (ret)445 if (ret)
447 goto err_alloc;446 goto err_alloc;
448
449 uobj->object = pd;
450 memset(&resp, 0, sizeof resp);
451 resp.pd_handle = uobj->id;
452 rdma_restrack_uadd(&pd->res);447 rdma_restrack_uadd(&pd->res);
453 448
454 ret = uverbs_response(attrs, &resp, sizeof(resp));449 uobj->object = pd;
455 if (ret)450 uobj_finalize_uobj_create(uobj, attrs);
456 goto err_copy;
457 451
458 rdma_alloc_commit_uobject(uobj, attrs);452 resp.pd_handle = uobj->id;
459 return 0;453 return uverbs_response(attrs, &resp, sizeof(resp));
460 454
461err_copy:
462 ib_dealloc_pd_user(pd, uverbs_get_cleared_udata(attrs));
463 pd = NULL;
464err_alloc:455err_alloc:
465 kfree(pd);456 kfree(pd);
466err:457err:
@@ -568,15 +559,15 @@ static void xrcd_table_delete(struct ib_uverbs_device *dev, · 101 unmodified lines
568static int ib_uverbs_open_xrcd(struct uverbs_attr_bundle *attrs)559static int ib_uverbs_open_xrcd(struct uverbs_attr_bundle *attrs)
569{560{
570 struct ib_uverbs_device *ibudev = attrs->ufile->device;561 struct ib_uverbs_device *ibudev = attrs->ufile->device;
562 struct ib_uverbs_open_xrcd_resp resp = {};
571 struct ib_uverbs_open_xrcd cmd;563 struct ib_uverbs_open_xrcd cmd;
572 struct ib_uverbs_open_xrcd_resp resp;
573 struct ib_uxrcd_object *obj;564 struct ib_uxrcd_object *obj;
574 struct ib_xrcd *xrcd = NULL;565 struct ib_xrcd *xrcd = NULL;
575 struct fd f = {NULL, 0};
576 struct inode *inode = NULL;566 struct inode *inode = NULL;
577 int ret = 0;
578 int new_xrcd = 0;567 int new_xrcd = 0;
579 struct ib_device *ib_dev;568 struct ib_device *ib_dev;
569 struct fd f = {};
570 int ret;
580 571
581 ret = uverbs_request(attrs, &cmd, sizeof(cmd));572 ret = uverbs_request(attrs, &cmd, sizeof(cmd));
582 if (ret)573 if (ret)
@@ -614,24 +605,16 @@ static int ib_uverbs_open_xrcd(struct uverbs_attr_bundle *attrs) · 31 unmodified lines
614 }605 }
615 606
616 if (!xrcd) {607 if (!xrcd) {
617 xrcd = ib_dev->ops.alloc_xrcd(ib_dev, &attrs->driver_udata);608 xrcd = ib_alloc_xrcd_user(ib_dev, inode, &attrs->driver_udata);
618 if (IS_ERR(xrcd)) {609 if (IS_ERR(xrcd)) {
619 ret = PTR_ERR(xrcd);610 ret = PTR_ERR(xrcd);
620 goto err;611 goto err;
621 }612 }
622
623 xrcd->inode = inode;
624 xrcd->device = ib_dev;
625 atomic_set(&xrcd->usecnt, 0);
626 mutex_init(&xrcd->tgt_qp_mutex);
627 INIT_LIST_HEAD(&xrcd->tgt_qp_list);
628 new_xrcd = 1;613 new_xrcd = 1;
629 }614 }
630 615
631 atomic_set(&obj->refcnt, 0);616 atomic_set(&obj->refcnt, 0);
632 obj->uobject.object = xrcd;617 obj->uobject.object = xrcd;
633 memset(&resp, 0, sizeof resp);
634 resp.xrcd_handle = obj->uobject.id;
635 618
636 if (inode) {619 if (inode) {
637 if (new_xrcd) {620 if (new_xrcd) {
@@ -643,27 +626,17 @@ static int ib_uverbs_open_xrcd(struct uverbs_attr_bundle *attrs) · 5 unmodified lines
643 atomic_inc(&xrcd->usecnt);626 atomic_inc(&xrcd->usecnt);
644 }627 }
645 628
646 ret = uverbs_response(attrs, &resp, sizeof(resp));
647 if (ret)
648 goto err_copy;
649
650 if (f.file)629 if (f.file)
651 fdput(f);630 fdput(f);
652 631
653 mutex_unlock(&ibudev->xrcd_tree_mutex);632 mutex_unlock(&ibudev->xrcd_tree_mutex);
633 uobj_finalize_uobj_create(&obj->uobject, attrs);
654 634
655 rdma_alloc_commit_uobject(&obj->uobject, attrs);635 resp.xrcd_handle = obj->uobject.id;
656 return 0;636 return uverbs_response(attrs, &resp, sizeof(resp));
657
658err_copy:
659 if (inode) {
660 if (new_xrcd)
661 xrcd_table_delete(ibudev, inode);
662 atomic_dec(&xrcd->usecnt);
663 }
664 637
665err_dealloc_xrcd:638err_dealloc_xrcd:
666 ib_dealloc_xrcd(xrcd, uverbs_get_cleared_udata(attrs));639 ib_dealloc_xrcd_user(xrcd, uverbs_get_cleared_udata(attrs));
667 640
668err:641err:
669 uobj_alloc_abort(&obj->uobject, attrs);642 uobj_alloc_abort(&obj->uobject, attrs);
@@ -701,7 +674,7 @@ int ib_uverbs_dealloc_xrcd(struct ib_uobject *uobject, struct ib_xrcd *xrcd, · 31 unmodified lines
701 if (inode && !atomic_dec_and_test(&xrcd->usecnt))674 if (inode && !atomic_dec_and_test(&xrcd->usecnt))
702 return 0;675 return 0;
703 676
704 ret = ib_dealloc_xrcd(xrcd, &attrs->driver_udata);677 ret = ib_dealloc_xrcd_user(xrcd, &attrs->driver_udata);
705 678
706 if (ib_is_destroy_retryable(ret, why, uobject)) {679 if (ib_is_destroy_retryable(ret, why, uobject)) {
707 atomic_inc(&xrcd->usecnt);680 atomic_inc(&xrcd->usecnt);
@@ -716,8 +689,8 @@ int ib_uverbs_dealloc_xrcd(struct ib_uobject *uobject, struct ib_xrcd *xrcd, · 8 unmodified lines
716 689
717static int ib_uverbs_reg_mr(struct uverbs_attr_bundle *attrs)690static int ib_uverbs_reg_mr(struct uverbs_attr_bundle *attrs)
718{691{
692 struct ib_uverbs_reg_mr_resp resp = {};
719 struct ib_uverbs_reg_mr cmd;693 struct ib_uverbs_reg_mr cmd;
720 struct ib_uverbs_reg_mr_resp resp;
721 struct ib_uobject *uobj;694 struct ib_uobject *uobj;
722 struct ib_pd *pd;695 struct ib_pd *pd;
723 struct ib_mr *mr;696 struct ib_mr *mr;
@@ -770,30 +743,20 @@ static int ib_uverbs_reg_mr(struct uverbs_attr_bundle *attrs) · 46 unmodified lines
770 mr->uobject = uobj;743 mr->uobject = uobj;
771 atomic_inc(&pd->usecnt);744 atomic_inc(&pd->usecnt);
772 mr->res.type = RDMA_RESTRACK_MR;745 mr->res.type = RDMA_RESTRACK_MR;
746 mr->iova = cmd.hca_va;
773 rdma_restrack_uadd(&mr->res);747 rdma_restrack_uadd(&mr->res);
774 748
775 uobj->object = mr;749 uobj->object = mr;
776
777 memset(&resp, 0, sizeof resp);
778 resp.lkey = mr->lkey;
779 resp.rkey = mr->rkey;
780 resp.mr_handle = uobj->id;
781
782 ret = uverbs_response(attrs, &resp, sizeof(resp));
783 if (ret)
784 goto err_copy;
785
786 uobj_put_obj_read(pd);750 uobj_put_obj_read(pd);
751 uobj_finalize_uobj_create(uobj, attrs);
787 752
788 rdma_alloc_commit_uobject(uobj, attrs);753 resp.lkey = mr->lkey;
789 return 0;754 resp.rkey = mr->rkey;
790 755 resp.mr_handle = uobj->id;
791err_copy:756 return uverbs_response(attrs, &resp, sizeof(resp));
792 ib_dereg_mr_user(mr, uverbs_get_cleared_udata(attrs));
793 757
794err_put:758err_put:
795 uobj_put_obj_read(pd);759 uobj_put_obj_read(pd);
796
797err_free:760err_free:
798 uobj_alloc_abort(uobj, attrs);761 uobj_alloc_abort(uobj, attrs);
799 return ret;762 return ret;
@@ -861,6 +824,9 @@ static int ib_uverbs_rereg_mr(struct uverbs_attr_bundle *attrs) · 61 unmodified lines
861 atomic_dec(&old_pd->usecnt);824 atomic_dec(&old_pd->usecnt);
862 }825 }
863 826
827 if (cmd.flags & IB_MR_REREG_TRANS)
828 mr->iova = cmd.hca_va;
829
864 memset(&resp, 0, sizeof(resp));830 memset(&resp, 0, sizeof(resp));
865 resp.lkey = mr->lkey;831 resp.lkey = mr->lkey;
866 resp.rkey = mr->rkey;832 resp.rkey = mr->rkey;
@@ -930,21 +896,13 @@ static int ib_uverbs_alloc_mw(struct uverbs_attr_bundle *attrs) · 63 unmodified lines
930 atomic_inc(&pd->usecnt);896 atomic_inc(&pd->usecnt);
931 897
932 uobj->object = mw;898 uobj->object = mw;
899 uobj_put_obj_read(pd);
900 uobj_finalize_uobj_create(uobj, attrs);
933 901
934 memset(&resp, 0, sizeof(resp));902 resp.rkey = mw->rkey;
935 resp.rkey = mw->rkey;
936 resp.mw_handle = uobj->id;903 resp.mw_handle = uobj->id;
904 return uverbs_response(attrs, &resp, sizeof(resp));
937 905
938 ret = uverbs_response(attrs, &resp, sizeof(resp));
939 if (ret)
940 goto err_copy;
941
942 uobj_put_obj_read(pd);
943 rdma_alloc_commit_uobject(uobj, attrs);
944 return 0;
945
946err_copy:
947 uverbs_dealloc_mw(mw);
948err_put:906err_put:
949 uobj_put_obj_read(pd);907 uobj_put_obj_read(pd);
950err_free:908err_free:
@@ -981,40 +939,33 @@ static int ib_uverbs_create_comp_channel(struct uverbs_attr_bundle *attrs) · 30 unmodified lines
981 if (IS_ERR(uobj))939 if (IS_ERR(uobj))
982 return PTR_ERR(uobj);940 return PTR_ERR(uobj);
983 941
984 resp.fd = uobj->id;
985
986 ev_file = container_of(uobj, struct ib_uverbs_completion_event_file,942 ev_file = container_of(uobj, struct ib_uverbs_completion_event_file,
987 uobj);943 uobj);
988 ib_uverbs_init_event_queue(&ev_file->ev_queue);944 ib_uverbs_init_event_queue(&ev_file->ev_queue);
945 uobj_finalize_uobj_create(uobj, attrs);
989 946
990 ret = uverbs_response(attrs, &resp, sizeof(resp));947 resp.fd = uobj->id;
991 if (ret) {948 return uverbs_response(attrs, &resp, sizeof(resp));
992 uobj_alloc_abort(uobj, attrs);
993 return ret;
994 }
995
996 rdma_alloc_commit_uobject(uobj, attrs);
997 return 0;
998}949}
999 950
1000static struct ib_ucq_object *create_cq(struct uverbs_attr_bundle *attrs,951static int create_cq(struct uverbs_attr_bundle *attrs,
1001 struct ib_uverbs_ex_create_cq *cmd)952 struct ib_uverbs_ex_create_cq *cmd)
1002{953{
1003 struct ib_ucq_object *obj;954 struct ib_ucq_object *obj;
1004 struct ib_uverbs_completion_event_file *ev_file = NULL;955 struct ib_uverbs_completion_event_file *ev_file = NULL;
1005 struct ib_cq *cq;956 struct ib_cq *cq;
1006 int ret;957 int ret;
1007 struct ib_uverbs_ex_create_cq_resp resp;958 struct ib_uverbs_ex_create_cq_resp resp = {};
1008 struct ib_cq_init_attr attr = {};959 struct ib_cq_init_attr attr = {};
1009 struct ib_device *ib_dev;960 struct ib_device *ib_dev;
1010 961
1011 if (cmd->comp_vector >= attrs->ufile->device->num_comp_vectors)962 if (cmd->comp_vector >= attrs->ufile->device->num_comp_vectors)
1012 return ERR_PTR(-EINVAL);963 return -EINVAL;
1013 964
1014 obj = (struct ib_ucq_object *)uobj_alloc(UVERBS_OBJECT_CQ, attrs,965 obj = (struct ib_ucq_object *)uobj_alloc(UVERBS_OBJECT_CQ, attrs,
1015 &ib_dev);966 &ib_dev);
1016 if (IS_ERR(obj))967 if (IS_ERR(obj))
1017 return obj;968 return PTR_ERR(obj);
1018 969
1019 if (cmd->comp_channel >= 0) {970 if (cmd->comp_channel >= 0) {
1020 ev_file = ib_uverbs_lookup_comp_file(cmd->comp_channel, attrs);971 ev_file = ib_uverbs_lookup_comp_file(cmd->comp_channel, attrs);
@@ -1043,53 +994,38 @@ static struct ib_ucq_object *create_cq(struct uverbs_attr_bundle *attrs, · 22 unmodified lines
1043 cq->event_handler = ib_uverbs_cq_event_handler;994 cq->event_handler = ib_uverbs_cq_event_handler;
1044 cq->cq_context = ev_file ? &ev_file->ev_queue : NULL;995 cq->cq_context = ev_file ? &ev_file->ev_queue : NULL;
1045 atomic_set(&cq->usecnt, 0);996 atomic_set(&cq->usecnt, 0);
997 cq->res.type = RDMA_RESTRACK_CQ;
1046 998
1047 ret = ib_dev->ops.create_cq(cq, &attr, &attrs->driver_udata);999 ret = ib_dev->ops.create_cq(cq, &attr, &attrs->driver_udata);
1048 if (ret)1000 if (ret)
1049 goto err_free;1001 goto err_free;
1002 rdma_restrack_uadd(&cq->res);
1050 1003
1051 obj->uevent.uobject.object = cq;1004 obj->uevent.uobject.object = cq;
1052 obj->uevent.event_file = READ_ONCE(attrs->ufile->default_async_file);1005 obj->uevent.event_file = READ_ONCE(attrs->ufile->default_async_file);
1053 if (obj->uevent.event_file)1006 if (obj->uevent.event_file)
1054 uverbs_uobject_get(&obj->uevent.event_file->uobj);1007 uverbs_uobject_get(&obj->uevent.event_file->uobj);
1008 uobj_finalize_uobj_create(&obj->uevent.uobject, attrs);
1055 1009
1056 memset(&resp, 0, sizeof resp);
1057 resp.base.cq_handle = obj->uevent.uobject.id;1010 resp.base.cq_handle = obj->uevent.uobject.id;
1058 resp.base.cqe = cq->cqe;1011 resp.base.cqe = cq->cqe;
1059 resp.response_length = uverbs_response_length(attrs, sizeof(resp));1012 resp.response_length = uverbs_response_length(attrs, sizeof(resp));
1013 return uverbs_response(attrs, &resp, sizeof(resp));
1060 1014
1061 cq->res.type = RDMA_RESTRACK_CQ;
1062 rdma_restrack_uadd(&cq->res);
1063
1064 ret = uverbs_response(attrs, &resp, sizeof(resp));
1065 if (ret)
1066 goto err_cb;
1067
1068 rdma_alloc_commit_uobject(&obj->uevent.uobject, attrs);
1069 return obj;
1070
1071err_cb:
1072 if (obj->uevent.event_file)
1073 uverbs_uobject_put(&obj->uevent.event_file->uobj);
1074 ib_destroy_cq_user(cq, uverbs_get_cleared_udata(attrs));
1075 cq = NULL;
1076err_free:1015err_free:
1077 kfree(cq);1016 kfree(cq);
1078err_file:1017err_file:
1079 if (ev_file)1018 if (ev_file)
1080 ib_uverbs_release_ucq(ev_file, obj);1019 ib_uverbs_release_ucq(ev_file, obj);
1081
1082err:1020err:
1083 uobj_alloc_abort(&obj->uevent.uobject, attrs);1021 uobj_alloc_abort(&obj->uevent.uobject, attrs);
1084 1022 return ret;
1085 return ERR_PTR(ret);
1086}1023}
1087 1024
1088static int ib_uverbs_create_cq(struct uverbs_attr_bundle *attrs)1025static int ib_uverbs_create_cq(struct uverbs_attr_bundle *attrs)
1089{1026{
1090 struct ib_uverbs_create_cq cmd;1027 struct ib_uverbs_create_cq cmd;
1091 struct ib_uverbs_ex_create_cq cmd_ex;1028 struct ib_uverbs_ex_create_cq cmd_ex;
1092 struct ib_ucq_object *obj;
1093 int ret;1029 int ret;
1094 1030
1095 ret = uverbs_request(attrs, &cmd, sizeof(cmd));1031 ret = uverbs_request(attrs, &cmd, sizeof(cmd));
@@ -1102,14 +1038,12 @@ static int ib_uverbs_create_cq(struct uverbs_attr_bundle *attrs) · 6 unmodified lines
1102 cmd_ex.comp_vector = cmd.comp_vector;1038 cmd_ex.comp_vector = cmd.comp_vector;
1103 cmd_ex.comp_channel = cmd.comp_channel;1039 cmd_ex.comp_channel = cmd.comp_channel;
1104 1040
1105 obj = create_cq(attrs, &cmd_ex);1041 return create_cq(attrs, &cmd_ex);
1106 return PTR_ERR_OR_ZERO(obj);
1107}1042}
1108 1043
1109static int ib_uverbs_ex_create_cq(struct uverbs_attr_bundle *attrs)1044static int ib_uverbs_ex_create_cq(struct uverbs_attr_bundle *attrs)
1110{1045{
1111 struct ib_uverbs_ex_create_cq cmd;1046 struct ib_uverbs_ex_create_cq cmd;
1112 struct ib_ucq_object *obj;
1113 int ret;1047 int ret;
1114 1048
1115 ret = uverbs_request(attrs, &cmd, sizeof(cmd));1049 ret = uverbs_request(attrs, &cmd, sizeof(cmd));
@@ -1122,8 +1056,7 @@ static int ib_uverbs_ex_create_cq(struct uverbs_attr_bundle *attrs) · 6 unmodified lines
1122 if (cmd.reserved)1056 if (cmd.reserved)
1123 return -EINVAL;1057 return -EINVAL;
1124 1058
1125 obj = create_cq(attrs, &cmd);1059 return create_cq(attrs, &cmd);
1126 return PTR_ERR_OR_ZERO(obj);
1127}1060}
1128 1061
1129static int ib_uverbs_resize_cq(struct uverbs_attr_bundle *attrs)1062static int ib_uverbs_resize_cq(struct uverbs_attr_bundle *attrs)
@@ -1131,7 +1064,7 @@ static int ib_uverbs_resize_cq(struct uverbs_attr_bundle *attrs) · 1 unmodified line
1131 struct ib_uverbs_resize_cq cmd;1064 struct ib_uverbs_resize_cq cmd;
1132 struct ib_uverbs_resize_cq_resp resp = {};1065 struct ib_uverbs_resize_cq_resp resp = {};
1133 struct ib_cq *cq;1066 struct ib_cq *cq;
1134 int ret = -EINVAL;1067 int ret;
1135 1068
1136 ret = uverbs_request(attrs, &cmd, sizeof(cmd));1069 ret = uverbs_request(attrs, &cmd, sizeof(cmd));
1137 if (ret)1070 if (ret)
@@ -1298,7 +1231,7 @@ static int create_qp(struct uverbs_attr_bundle *attrs, · 160 unmodified lines
1298 struct ib_srq *srq = NULL;1231 struct ib_srq *srq = NULL;
1299 struct ib_qp *qp;1232 struct ib_qp *qp;
1300 struct ib_qp_init_attr attr = {};1233 struct ib_qp_init_attr attr = {};
1301 struct ib_uverbs_ex_create_qp_resp resp;1234 struct ib_uverbs_ex_create_qp_resp resp = {};
1302 int ret;1235 int ret;
1303 struct ib_rwq_ind_table *ind_tbl = NULL;1236 struct ib_rwq_ind_table *ind_tbl = NULL;
1304 bool has_sq = true;1237 bool has_sq = true;
@@ -1468,20 +1401,6 @@ static int create_qp(struct uverbs_attr_bundle *attrs, · 163 unmodified lines
1468 if (obj->uevent.event_file)1401 if (obj->uevent.event_file)
1469 uverbs_uobject_get(&obj->uevent.event_file->uobj);1402 uverbs_uobject_get(&obj->uevent.event_file->uobj);
1470 1403
1471 memset(&resp, 0, sizeof resp);
1472 resp.base.qpn = qp->qp_num;
1473 resp.base.qp_handle = obj->uevent.uobject.id;
1474 resp.base.max_recv_sge = attr.cap.max_recv_sge;
1475 resp.base.max_send_sge = attr.cap.max_send_sge;
1476 resp.base.max_recv_wr = attr.cap.max_recv_wr;
1477 resp.base.max_send_wr = attr.cap.max_send_wr;
1478 resp.base.max_inline_data = attr.cap.max_inline_data;
1479 resp.response_length = uverbs_response_length(attrs, sizeof(resp));
1480
1481 ret = uverbs_response(attrs, &resp, sizeof(resp));
1482 if (ret)
1483 goto err_uevent;
1484
1485 if (xrcd) {1404 if (xrcd) {
1486 obj->uxrcd = container_of(xrcd_uobj, struct ib_uxrcd_object,1405 obj->uxrcd = container_of(xrcd_uobj, struct ib_uxrcd_object,
1487 uobject);1406 uobject);
@@ -1502,12 +1421,18 @@ static int create_qp(struct uverbs_attr_bundle *attrs, · 14 unmodified lines
1502 UVERBS_LOOKUP_READ);1421 UVERBS_LOOKUP_READ);
1503 if (ind_tbl)1422 if (ind_tbl)
1504 uobj_put_obj_read(ind_tbl);1423 uobj_put_obj_read(ind_tbl);
1424 uobj_finalize_uobj_create(&obj->uevent.uobject, attrs);
1425
1426 resp.base.qpn = qp->qp_num;
1427 resp.base.qp_handle = obj->uevent.uobject.id;
1428 resp.base.max_recv_sge = attr.cap.max_recv_sge;
1429 resp.base.max_send_sge = attr.cap.max_send_sge;
1430 resp.base.max_recv_wr = attr.cap.max_recv_wr;
1431 resp.base.max_send_wr = attr.cap.max_send_wr;
1432 resp.base.max_inline_data = attr.cap.max_inline_data;
1433 resp.response_length = uverbs_response_length(attrs, sizeof(resp));
1434 return uverbs_response(attrs, &resp, sizeof(resp));
1505 1435
1506 rdma_alloc_commit_uobject(&obj->uevent.uobject, attrs);
1507 return 0;
1508err_uevent:
1509 if (obj->uevent.event_file)
1510 uverbs_uobject_put(&obj->uevent.event_file->uobj);
1511err_cb:1436err_cb:
1512 ib_destroy_qp_user(qp, uverbs_get_cleared_udata(attrs));1437 ib_destroy_qp_user(qp, uverbs_get_cleared_udata(attrs));
1513 1438
@@ -1580,14 +1505,14 @@ static int ib_uverbs_ex_create_qp(struct uverbs_attr_bundle *attrs) · 66 unmodified lines
1580 1505
1581static int ib_uverbs_open_qp(struct uverbs_attr_bundle *attrs)1506static int ib_uverbs_open_qp(struct uverbs_attr_bundle *attrs)
1582{1507{
1508 struct ib_uverbs_create_qp_resp resp = {};
1583 struct ib_uverbs_open_qp cmd;1509 struct ib_uverbs_open_qp cmd;
1584 struct ib_uverbs_create_qp_resp resp;
1585 struct ib_uqp_object *obj;1510 struct ib_uqp_object *obj;
1586 struct ib_xrcd *xrcd;1511 struct ib_xrcd *xrcd;
1587 struct ib_uobject *xrcd_uobj;
1588 struct ib_qp *qp;1512 struct ib_qp *qp;
1589 struct ib_qp_open_attr attr = {};1513 struct ib_qp_open_attr attr = {};
1590 int ret;1514 int ret;
1515 struct ib_uobject *xrcd_uobj;
1591 struct ib_device *ib_dev;1516 struct ib_device *ib_dev;
1592 1517
1593 ret = uverbs_request(attrs, &cmd, sizeof(cmd));1518 ret = uverbs_request(attrs, &cmd, sizeof(cmd));
@@ -1627,24 +1552,16 @@ static int ib_uverbs_open_qp(struct uverbs_attr_bundle *attrs) · 33 unmodified lines
1627 obj->uevent.uobject.object = qp;1552 obj->uevent.uobject.object = qp;
1628 obj->uevent.uobject.user_handle = cmd.user_handle;1553 obj->uevent.uobject.user_handle = cmd.user_handle;
1629 1554
1630 memset(&resp, 0, sizeof resp);
1631 resp.qpn = qp->qp_num;
1632 resp.qp_handle = obj->uevent.uobject.id;
1633
1634 ret = uverbs_response(attrs, &resp, sizeof(resp));
1635 if (ret)
1636 goto err_destroy;
1637
1638 obj->uxrcd = container_of(xrcd_uobj, struct ib_uxrcd_object, uobject);1555 obj->uxrcd = container_of(xrcd_uobj, struct ib_uxrcd_object, uobject);
1639 atomic_inc(&obj->uxrcd->refcnt);1556 atomic_inc(&obj->uxrcd->refcnt);
1640 qp->uobject = obj;1557 qp->uobject = obj;
1641 uobj_put_read(xrcd_uobj);1558 uobj_put_read(xrcd_uobj);
1559 uobj_finalize_uobj_create(&obj->uevent.uobject, attrs);
1642 1560
1643 rdma_alloc_commit_uobject(&obj->uevent.uobject, attrs);1561 resp.qpn = qp->qp_num;
1644 return 0;1562 resp.qp_handle = obj->uevent.uobject.id;
1563 return uverbs_response(attrs, &resp, sizeof(resp));
1645 1564
1646err_destroy:
1647 ib_destroy_qp_user(qp, uverbs_get_cleared_udata(attrs));
1648err_xrcd:1565err_xrcd:
1649 uobj_put_read(xrcd_uobj);1566 uobj_put_read(xrcd_uobj);
1650err_put:1567err_put:
@@ -1980,7 +1897,7 @@ static int ib_uverbs_ex_modify_qp(struct uverbs_attr_bundle *attrs) · 329 unmodified lines
1980 * Last bit is reserved for extending the attr_mask by1897 * Last bit is reserved for extending the attr_mask by
1981 * using another field.1898 * using another field.
1982 */1899 */
1983 BUILD_BUG_ON(IB_USER_LAST_QP_ATTR_MASK == (1 << 31));1900 BUILD_BUG_ON(IB_USER_LAST_QP_ATTR_MASK == (1ULL << 31));
1984 1901
1985 if (cmd.base.attr_mask &1902 if (cmd.base.attr_mask &
1986 ~((IB_USER_LAST_QP_ATTR_MASK << 1) - 1))1903 ~((IB_USER_LAST_QP_ATTR_MASK << 1) - 1))
@@ -2480,24 +2397,14 @@ static int ib_uverbs_create_ah(struct uverbs_attr_bundle *attrs) · 493 unmodified lines
2480 ah->uobject = uobj;2397 ah->uobject = uobj;
2481 uobj->user_handle = cmd.user_handle;2398 uobj->user_handle = cmd.user_handle;
2482 uobj->object = ah;2399 uobj->object = ah;
2483
2484 resp.ah_handle = uobj->id;
2485
2486 ret = uverbs_response(attrs, &resp, sizeof(resp));
2487 if (ret)
2488 goto err_copy;
2489
2490 uobj_put_obj_read(pd);2400 uobj_put_obj_read(pd);
2491 rdma_alloc_commit_uobject(uobj, attrs);2401 uobj_finalize_uobj_create(uobj, attrs);
2492 return 0;
2493 2402
2494err_copy:2403 resp.ah_handle = uobj->id;
2495 rdma_destroy_ah_user(ah, RDMA_DESTROY_AH_SLEEPABLE,2404 return uverbs_response(attrs, &resp, sizeof(resp));
2496 uverbs_get_cleared_udata(attrs));
2497 2405
2498err_put:2406err_put:
2499 uobj_put_obj_read(pd);2407 uobj_put_obj_read(pd);
2500
2501err:2408err:
2502 uobj_alloc_abort(uobj, attrs);2409 uobj_alloc_abort(uobj, attrs);
2503 return ret;2410 return ret;
@@ -2989,26 +2896,18 @@ static int ib_uverbs_ex_create_wq(struct uverbs_attr_bundle *attrs) · 485 unmodified lines
2989 if (obj->uevent.event_file)2896 if (obj->uevent.event_file)
2990 uverbs_uobject_get(&obj->uevent.event_file->uobj);2897 uverbs_uobject_get(&obj->uevent.event_file->uobj);
2991 2898
2992 memset(&resp, 0, sizeof(resp));2899 uobj_put_obj_read(pd);
2900 rdma_lookup_put_uobject(&cq->uobject->uevent.uobject,
2901 UVERBS_LOOKUP_READ);
2902 uobj_finalize_uobj_create(&obj->uevent.uobject, attrs);
2903
2993 resp.wq_handle = obj->uevent.uobject.id;2904 resp.wq_handle = obj->uevent.uobject.id;
2994 resp.max_sge = wq_init_attr.max_sge;2905 resp.max_sge = wq_init_attr.max_sge;
2995 resp.max_wr = wq_init_attr.max_wr;2906 resp.max_wr = wq_init_attr.max_wr;
2996 resp.wqn = wq->wq_num;2907 resp.wqn = wq->wq_num;
2997 resp.response_length = uverbs_response_length(attrs, sizeof(resp));2908 resp.response_length = uverbs_response_length(attrs, sizeof(resp));
2998 err = uverbs_response(attrs, &resp, sizeof(resp));2909 return uverbs_response(attrs, &resp, sizeof(resp));
2999 if (err)
3000 goto err_copy;
3001
3002 uobj_put_obj_read(pd);
3003 rdma_lookup_put_uobject(&cq->uobject->uevent.uobject,
3004 UVERBS_LOOKUP_READ);
3005 rdma_alloc_commit_uobject(&obj->uevent.uobject, attrs);
3006 return 0;
3007 2910
3008err_copy:
3009 if (obj->uevent.event_file)
3010 uverbs_uobject_put(&obj->uevent.event_file->uobj);
3011 ib_destroy_wq(wq, uverbs_get_cleared_udata(attrs));
3012err_put_cq:2911err_put_cq:
3013 rdma_lookup_put_uobject(&cq->uobject->uevent.uobject,2912 rdma_lookup_put_uobject(&cq->uobject->uevent.uobject,
3014 UVERBS_LOOKUP_READ);2913 UVERBS_LOOKUP_READ);
@@ -3093,7 +2992,7 @@ static int ib_uverbs_ex_create_rwq_ind_table(struct uverbs_attr_bundle *attrs) · 78 unmodified lines
3093 struct ib_wq **wqs = NULL;2992 struct ib_wq **wqs = NULL;
3094 u32 *wqs_handles = NULL;2993 u32 *wqs_handles = NULL;
3095 struct ib_wq *wq = NULL;2994 struct ib_wq *wq = NULL;
3096 int i, j, num_read_wqs;2995 int i, num_read_wqs;
3097 u32 num_wq_handles;2996 u32 num_wq_handles;
3098 struct uverbs_req_iter iter;2997 struct uverbs_req_iter iter;
3099 struct ib_device *ib_dev;2998 struct ib_device *ib_dev;
@@ -3139,6 +3038,7 @@ static int ib_uverbs_ex_create_rwq_ind_table(struct uverbs_attr_bundle *attrs) · 39 unmodified lines
3139 }3038 }
3140 3039
3141 wqs[num_read_wqs] = wq;3040 wqs[num_read_wqs] = wq;
3041 atomic_inc(&wqs[num_read_wqs]->usecnt);
3142 }3042 }
3143 3043
3144 uobj = uobj_alloc(UVERBS_OBJECT_RWQ_IND_TBL, attrs, &ib_dev);3044 uobj = uobj_alloc(UVERBS_OBJECT_RWQ_IND_TBL, attrs, &ib_dev);
@@ -3166,33 +3066,24 @@ static int ib_uverbs_ex_create_rwq_ind_table(struct uverbs_attr_bundle *attrs) · 21 unmodified lines
3166 atomic_set(&rwq_ind_tbl->usecnt, 0);3066 atomic_set(&rwq_ind_tbl->usecnt, 0);
3167 3067
3168 for (i = 0; i < num_wq_handles; i++)3068 for (i = 0; i < num_wq_handles; i++)
3169 atomic_inc(&wqs[i]->usecnt);3069 rdma_lookup_put_uobject(&wqs[i]->uobject->uevent.uobject,
3070 UVERBS_LOOKUP_READ);
3071 kfree(wqs_handles);
3072 uobj_finalize_uobj_create(uobj, attrs);
3170 3073
3171 resp.ind_tbl_handle = uobj->id;3074 resp.ind_tbl_handle = uobj->id;
3172 resp.ind_tbl_num = rwq_ind_tbl->ind_tbl_num;3075 resp.ind_tbl_num = rwq_ind_tbl->ind_tbl_num;
3173 resp.response_length = uverbs_response_length(attrs, sizeof(resp));3076 resp.response_length = uverbs_response_length(attrs, sizeof(resp));
3077 return uverbs_response(attrs, &resp, sizeof(resp));
3174 3078
3175 err = uverbs_response(attrs, &resp, sizeof(resp));
3176 if (err)
3177 goto err_copy;
3178
3179 kfree(wqs_handles);
3180
3181 for (j = 0; j < num_read_wqs; j++)
3182 rdma_lookup_put_uobject(&wqs[j]->uobject->uevent.uobject,
3183 UVERBS_LOOKUP_READ);
3184
3185 rdma_alloc_commit_uobject(uobj, attrs);
3186 return 0;
3187
3188err_copy:
3189 ib_destroy_rwq_ind_table(rwq_ind_tbl);
3190err_uobj:3079err_uobj:
3191 uobj_alloc_abort(uobj, attrs);3080 uobj_alloc_abort(uobj, attrs);
3192put_wqs:3081put_wqs:
3193 for (j = 0; j < num_read_wqs; j++)3082 for (i = 0; i < num_read_wqs; i++) {
3194 rdma_lookup_put_uobject(&wqs[j]->uobject->uevent.uobject,3083 rdma_lookup_put_uobject(&wqs[i]->uobject->uevent.uobject,
3195 UVERBS_LOOKUP_READ);3084 UVERBS_LOOKUP_READ);
3085 atomic_dec(&wqs[i]->usecnt);
3086 }
3196err_free:3087err_free:
3197 kfree(wqs_handles);3088 kfree(wqs_handles);
3198 kfree(wqs);3089 kfree(wqs);
@@ -3218,7 +3109,7 @@ static int ib_uverbs_ex_destroy_rwq_ind_table(struct uverbs_attr_bundle *attrs) · 19 unmodified lines
3218static int ib_uverbs_ex_create_flow(struct uverbs_attr_bundle *attrs)3109static int ib_uverbs_ex_create_flow(struct uverbs_attr_bundle *attrs)
3219{3110{
3220 struct ib_uverbs_create_flow cmd;3111 struct ib_uverbs_create_flow cmd;
3221 struct ib_uverbs_create_flow_resp resp;3112 struct ib_uverbs_create_flow_resp resp = {};
3222 struct ib_uobject *uobj;3113 struct ib_uobject *uobj;
3223 struct ib_flow *flow_id;3114 struct ib_flow *flow_id;
3224 struct ib_uverbs_flow_attr *kern_flow_attr;3115 struct ib_uverbs_flow_attr *kern_flow_attr;
@@ -3351,23 +3242,17 @@ static int ib_uverbs_ex_create_flow(struct uverbs_attr_bundle *attrs) · 126 unmodified lines
3351 3242
3352 ib_set_flow(uobj, flow_id, qp, qp->device, uflow_res);3243 ib_set_flow(uobj, flow_id, qp, qp->device, uflow_res);
3353 3244
3354 memset(&resp, 0, sizeof(resp));
3355 resp.flow_handle = uobj->id;
3356
3357 err = uverbs_response(attrs, &resp, sizeof(resp));
3358 if (err)
3359 goto err_copy;
3360
3361 rdma_lookup_put_uobject(&qp->uobject->uevent.uobject,3245 rdma_lookup_put_uobject(&qp->uobject->uevent.uobject,
3362 UVERBS_LOOKUP_READ);3246 UVERBS_LOOKUP_READ);
3363 kfree(flow_attr);3247 kfree(flow_attr);
3248
3364 if (cmd.flow_attr.num_of_specs)3249 if (cmd.flow_attr.num_of_specs)
3365 kfree(kern_flow_attr);3250 kfree(kern_flow_attr);
3366 rdma_alloc_commit_uobject(uobj, attrs);3251 uobj_finalize_uobj_create(uobj, attrs);
3367 return 0;3252
3368err_copy:3253 resp.flow_handle = uobj->id;
3369 if (!qp->device->ops.destroy_flow(flow_id))3254 return uverbs_response(attrs, &resp, sizeof(resp));
3370 atomic_dec(&qp->usecnt);3255
3371err_free:3256err_free:
3372 ib_uverbs_flow_resources_free(uflow_res);3257 ib_uverbs_flow_resources_free(uflow_res);
3373err_free_flow_attr:3258err_free_flow_attr:
@@ -3402,13 +3287,13 @@ static int __uverbs_create_xsrq(struct uverbs_attr_bundle *attrs, · 28 unmodified lines
3402 struct ib_uverbs_create_xsrq *cmd,3287 struct ib_uverbs_create_xsrq *cmd,
3403 struct ib_udata *udata)3288 struct ib_udata *udata)
3404{3289{
3405 struct ib_uverbs_create_srq_resp resp;3290 struct ib_uverbs_create_srq_resp resp = {};
3406 struct ib_usrq_object *obj;3291 struct ib_usrq_object *obj;
3407 struct ib_pd *pd;3292 struct ib_pd *pd;
3408 struct ib_srq *srq;3293 struct ib_srq *srq;
3409 struct ib_uobject *xrcd_uobj;
3410 struct ib_srq_init_attr attr;3294 struct ib_srq_init_attr attr;
3411 int ret;3295 int ret;
3296 struct ib_uobject *xrcd_uobj;
3412 struct ib_device *ib_dev;3297 struct ib_device *ib_dev;
3413 3298
3414 obj = (struct ib_usrq_object *)uobj_alloc(UVERBS_OBJECT_SRQ, attrs,3299 obj = (struct ib_usrq_object *)uobj_alloc(UVERBS_OBJECT_SRQ, attrs,
@@ -3473,17 +3358,9 @@ static int __uverbs_create_xsrq(struct uverbs_attr_bundle *attrs, · 58 unmodified lines
3473 if (obj->uevent.event_file)3358 if (obj->uevent.event_file)
3474 uverbs_uobject_get(&obj->uevent.event_file->uobj);3359 uverbs_uobject_get(&obj->uevent.event_file->uobj);
3475 3360
3476 memset(&resp, 0, sizeof resp);
3477 resp.srq_handle = obj->uevent.uobject.id;
3478 resp.max_wr = attr.attr.max_wr;
3479 resp.max_sge = attr.attr.max_sge;
3480 if (cmd->srq_type == IB_SRQT_XRC)3361 if (cmd->srq_type == IB_SRQT_XRC)
3481 resp.srqn = srq->ext.xrc.srq_num;3362 resp.srqn = srq->ext.xrc.srq_num;
3482 3363
3483 ret = uverbs_response(attrs, &resp, sizeof(resp));
3484 if (ret)
3485 goto err_copy;
3486
3487 if (cmd->srq_type == IB_SRQT_XRC)3364 if (cmd->srq_type == IB_SRQT_XRC)
3488 uobj_put_read(xrcd_uobj);3365 uobj_put_read(xrcd_uobj);
3489 3366
@@ -3492,13 +3369,13 @@ static int __uverbs_create_xsrq(struct uverbs_attr_bundle *attrs, · 2 unmodified lines
3492 UVERBS_LOOKUP_READ);3369 UVERBS_LOOKUP_READ);
3493 3370
3494 uobj_put_obj_read(pd);3371 uobj_put_obj_read(pd);
3495 rdma_alloc_commit_uobject(&obj->uevent.uobject, attrs);3372 uobj_finalize_uobj_create(&obj->uevent.uobject, attrs);
3496 return 0;3373
3374 resp.srq_handle = obj->uevent.uobject.id;
3375 resp.max_wr = attr.attr.max_wr;
3376 resp.max_sge = attr.attr.max_sge;
3377 return uverbs_response(attrs, &resp, sizeof(resp));
3497 3378
3498err_copy:
3499 if (obj->uevent.event_file)
3500 uverbs_uobject_put(&obj->uevent.event_file->uobj);
3501 ib_destroy_srq_user(srq, uverbs_get_cleared_udata(attrs));
3502err_put_pd:3379err_put_pd:
3503 uobj_put_obj_read(pd);3380 uobj_put_obj_read(pd);
3504err_put_cq:3381err_put_cq:
drivers/infiniband/core/uverbs_ioctl.c+1−0
@@ -790,6 +790,7 @@ int uverbs_copy_to_struct_or_zero(const struct uverbs_attr_bundle *bundle, · 789 unmodified lines
790 }790 }
791 return uverbs_copy_to(bundle, idx, from, size);791 return uverbs_copy_to(bundle, idx, from, size);
792}792}
793EXPORT_SYMBOL(uverbs_copy_to_struct_or_zero);
793 794
794/* Once called an abort will call through to the type's destroy_hw() */795/* Once called an abort will call through to the type's destroy_hw() */
795void uverbs_finalize_uobj_create(const struct uverbs_attr_bundle *bundle,796void uverbs_finalize_uobj_create(const struct uverbs_attr_bundle *bundle,
drivers/infiniband/core/uverbs_main.c+4−0
@@ -601,6 +601,7 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, · 600 unmodified lines
601 memset(bundle.attr_present, 0, sizeof(bundle.attr_present));601 memset(bundle.attr_present, 0, sizeof(bundle.attr_present));
602 bundle.ufile = file;602 bundle.ufile = file;
603 bundle.context = NULL; /* only valid if bundle has uobject */603 bundle.context = NULL; /* only valid if bundle has uobject */
604 bundle.uobject = NULL;
604 if (!method_elm->is_ex) {605 if (!method_elm->is_ex) {
605 size_t in_len = hdr.in_words * 4 - sizeof(hdr);606 size_t in_len = hdr.in_words * 4 - sizeof(hdr);
606 size_t out_len = hdr.out_words * 4;607 size_t out_len = hdr.out_words * 4;
@@ -664,6 +665,9 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, · 57 unmodified lines
664 }665 }
665 666
666 ret = method_elm->handler(&bundle);667 ret = method_elm->handler(&bundle);
668 if (bundle.uobject)
669 uverbs_finalize_object(bundle.uobject, UVERBS_ACCESS_NEW, true,
670 !ret, &bundle);
667out_unlock:671out_unlock:
668 srcu_read_unlock(&file->device->disassociate_srcu, srcu_key);672 srcu_read_unlock(&file->device->disassociate_srcu, srcu_key);
669 return (ret) ? : count;673 return (ret) ? : count;
drivers/infiniband/core/uverbs_std_types_counters.c+9−8
@@ -46,7 +46,9 @@ static int uverbs_free_counters(struct ib_uobject *uobject, · 45 unmodified lines
46 if (ret)46 if (ret)
47 return ret;47 return ret;
48 48
49 return counters->device->ops.destroy_counters(counters);49 counters->device->ops.destroy_counters(counters);
50 kfree(counters);
51 return 0;
50}52}
51 53
52static int UVERBS_HANDLER(UVERBS_METHOD_COUNTERS_CREATE)(54static int UVERBS_HANDLER(UVERBS_METHOD_COUNTERS_CREATE)(
@@ -66,20 +68,19 @@ static int UVERBS_HANDLER(UVERBS_METHOD_COUNTERS_CREATE)( · 13 unmodified lines
66 if (!ib_dev->ops.create_counters)68 if (!ib_dev->ops.create_counters)
67 return -EOPNOTSUPP;69 return -EOPNOTSUPP;
68 70
69 counters = ib_dev->ops.create_counters(ib_dev, attrs);71 counters = rdma_zalloc_drv_obj(ib_dev, ib_counters);
70 if (IS_ERR(counters)) {72 if (!counters)
71 ret = PTR_ERR(counters);73 return -ENOMEM;
72 goto err_create_counters;
73 }
74 74
75 counters->device = ib_dev;75 counters->device = ib_dev;
76 counters->uobject = uobj;76 counters->uobject = uobj;
77 uobj->object = counters;77 uobj->object = counters;
78 atomic_set(&counters->usecnt, 0);78 atomic_set(&counters->usecnt, 0);
79 79
80 return 0;80 ret = ib_dev->ops.create_counters(counters, attrs);
81 if (ret)
82 kfree(counters);
81 83
82err_create_counters:
83 return ret;84 return ret;
84}85}
85 86
drivers/infiniband/core/uverbs_std_types_cq.c+0−3
@@ -207,11 +207,8 @@ DECLARE_UVERBS_NAMED_METHOD( · 206 unmodified lines
207DECLARE_UVERBS_NAMED_OBJECT(207DECLARE_UVERBS_NAMED_OBJECT(
208 UVERBS_OBJECT_CQ,208 UVERBS_OBJECT_CQ,
209 UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_ucq_object), uverbs_free_cq),209 UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_ucq_object), uverbs_free_cq),
210
211#if IS_ENABLED(CONFIG_INFINIBAND_EXP_LEGACY_VERBS_NEW_UAPI)
212 &UVERBS_METHOD(UVERBS_METHOD_CQ_CREATE),210 &UVERBS_METHOD(UVERBS_METHOD_CQ_CREATE),
213 &UVERBS_METHOD(UVERBS_METHOD_CQ_DESTROY)211 &UVERBS_METHOD(UVERBS_METHOD_CQ_DESTROY)
214#endif
215);212);
216 213
217const struct uapi_definition uverbs_def_obj_cq[] = {214const struct uapi_definition uverbs_def_obj_cq[] = {
drivers/infiniband/core/uverbs_std_types_device.c+46−2
@@ -38,7 +38,12 @@ static int UVERBS_HANDLER(UVERBS_METHOD_INVOKE_WRITE)( · 37 unmodified lines
38 attrs->ucore.outlen < method_elm->resp_size)38 attrs->ucore.outlen < method_elm->resp_size)
39 return -ENOSPC;39 return -ENOSPC;
40 40
41 return method_elm->handler(attrs);41 attrs->uobject = NULL;
42 rc = method_elm->handler(attrs);
43 if (attrs->uobject)
44 uverbs_finalize_object(attrs->uobject, UVERBS_ACCESS_NEW, true,
45 !rc, attrs);
46 return rc;
42}47}
43 48
44DECLARE_UVERBS_NAMED_METHOD(UVERBS_METHOD_INVOKE_WRITE,49DECLARE_UVERBS_NAMED_METHOD(UVERBS_METHOD_INVOKE_WRITE,
@@ -229,6 +234,37 @@ static int UVERBS_HANDLER(UVERBS_METHOD_GET_CONTEXT)( · 184 unmodified lines
229 return 0;234 return 0;
230}235}
231 236
237static int UVERBS_HANDLER(UVERBS_METHOD_QUERY_CONTEXT)(
238 struct uverbs_attr_bundle *attrs)
239{
240 u64 core_support = IB_UVERBS_CORE_SUPPORT_OPTIONAL_MR_ACCESS;
241 struct ib_ucontext *ucontext;
242 struct ib_device *ib_dev;
243 u32 num_comp;
244 int ret;
245
246 ucontext = ib_uverbs_get_ucontext(attrs);
247 if (IS_ERR(ucontext))
248 return PTR_ERR(ucontext);
249 ib_dev = ucontext->device;
250
251 if (!ib_dev->ops.query_ucontext)
252 return -EOPNOTSUPP;
253
254 num_comp = attrs->ufile->device->num_comp_vectors;
255 ret = uverbs_copy_to(attrs, UVERBS_ATTR_QUERY_CONTEXT_NUM_COMP_VECTORS,
256 &num_comp, sizeof(num_comp));
257 if (IS_UVERBS_COPY_ERR(ret))
258 return ret;
259
260 ret = uverbs_copy_to(attrs, UVERBS_ATTR_QUERY_CONTEXT_CORE_SUPPORT,
261 &core_support, sizeof(core_support));
262 if (IS_UVERBS_COPY_ERR(ret))
263 return ret;
264
265 return ucontext->device->ops.query_ucontext(ucontext, attrs);
266}
267
232DECLARE_UVERBS_NAMED_METHOD(268DECLARE_UVERBS_NAMED_METHOD(
233 UVERBS_METHOD_GET_CONTEXT,269 UVERBS_METHOD_GET_CONTEXT,
234 UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_GET_CONTEXT_NUM_COMP_VECTORS,270 UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_GET_CONTEXT_NUM_COMP_VECTORS,
@@ -237,6 +273,13 @@ DECLARE_UVERBS_NAMED_METHOD( · 2 unmodified lines
237 UVERBS_ATTR_TYPE(u64), UA_OPTIONAL),273 UVERBS_ATTR_TYPE(u64), UA_OPTIONAL),
238 UVERBS_ATTR_UHW());274 UVERBS_ATTR_UHW());
239 275
276DECLARE_UVERBS_NAMED_METHOD(
277 UVERBS_METHOD_QUERY_CONTEXT,
278 UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_QUERY_CONTEXT_NUM_COMP_VECTORS,
279 UVERBS_ATTR_TYPE(u32), UA_OPTIONAL),
280 UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_QUERY_CONTEXT_CORE_SUPPORT,
281 UVERBS_ATTR_TYPE(u64), UA_OPTIONAL));
282
240DECLARE_UVERBS_NAMED_METHOD(283DECLARE_UVERBS_NAMED_METHOD(
241 UVERBS_METHOD_INFO_HANDLES,284 UVERBS_METHOD_INFO_HANDLES,
242 /* Also includes any device specific object ids */285 /* Also includes any device specific object ids */
@@ -260,7 +303,8 @@ DECLARE_UVERBS_GLOBAL_METHODS(UVERBS_OBJECT_DEVICE, · 17 unmodified lines
260 &UVERBS_METHOD(UVERBS_METHOD_GET_CONTEXT),303 &UVERBS_METHOD(UVERBS_METHOD_GET_CONTEXT),
261 &UVERBS_METHOD(UVERBS_METHOD_INVOKE_WRITE),304 &UVERBS_METHOD(UVERBS_METHOD_INVOKE_WRITE),
262 &UVERBS_METHOD(UVERBS_METHOD_INFO_HANDLES),305 &UVERBS_METHOD(UVERBS_METHOD_INFO_HANDLES),
263 &UVERBS_METHOD(UVERBS_METHOD_QUERY_PORT));306 &UVERBS_METHOD(UVERBS_METHOD_QUERY_PORT),
307 &UVERBS_METHOD(UVERBS_METHOD_QUERY_CONTEXT));
264 308
265const struct uapi_definition uverbs_def_obj_device[] = {309const struct uapi_definition uverbs_def_obj_device[] = {
266 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_DEVICE),310 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_DEVICE),
drivers/infiniband/core/uverbs_std_types_mr.c+52−2
@@ -69,7 +69,7 @@ static int UVERBS_HANDLER(UVERBS_METHOD_ADVISE_MR)( · 68 unmodified lines
69 69
70 num_sge = uverbs_attr_ptr_get_array_size(70 num_sge = uverbs_attr_ptr_get_array_size(
71 attrs, UVERBS_ATTR_ADVISE_MR_SGE_LIST, sizeof(struct ib_sge));71 attrs, UVERBS_ATTR_ADVISE_MR_SGE_LIST, sizeof(struct ib_sge));
72 if (num_sge < 0)72 if (num_sge <= 0)
73 return num_sge;73 return num_sge;
74 74
75 sg_list = uverbs_attr_get_alloced_ptr(attrs,75 sg_list = uverbs_attr_get_alloced_ptr(attrs,
@@ -148,6 +148,36 @@ static int UVERBS_HANDLER(UVERBS_METHOD_DM_MR_REG)( · 72 unmodified lines
148 return ret;148 return ret;
149}149}
150 150
151static int UVERBS_HANDLER(UVERBS_METHOD_QUERY_MR)(
152 struct uverbs_attr_bundle *attrs)
153{
154 struct ib_mr *mr =
155 uverbs_attr_get_obj(attrs, UVERBS_ATTR_QUERY_MR_HANDLE);
156 int ret;
157
158 ret = uverbs_copy_to(attrs, UVERBS_ATTR_QUERY_MR_RESP_LKEY, &mr->lkey,
159 sizeof(mr->lkey));
160 if (ret)
161 return ret;
162
163 ret = uverbs_copy_to(attrs, UVERBS_ATTR_QUERY_MR_RESP_RKEY,
164 &mr->rkey, sizeof(mr->rkey));
165
166 if (ret)
167 return ret;
168
169 ret = uverbs_copy_to(attrs, UVERBS_ATTR_QUERY_MR_RESP_LENGTH,
170 &mr->length, sizeof(mr->length));
171
172 if (ret)
173 return ret;
174
175 ret = uverbs_copy_to(attrs, UVERBS_ATTR_QUERY_MR_RESP_IOVA,
176 &mr->iova, sizeof(mr->iova));
177
178 return IS_UVERBS_COPY_ERR(ret) ? ret : 0;
179}
180
151DECLARE_UVERBS_NAMED_METHOD(181DECLARE_UVERBS_NAMED_METHOD(
152 UVERBS_METHOD_ADVISE_MR,182 UVERBS_METHOD_ADVISE_MR,
153 UVERBS_ATTR_IDR(UVERBS_ATTR_ADVISE_MR_PD_HANDLE,183 UVERBS_ATTR_IDR(UVERBS_ATTR_ADVISE_MR_PD_HANDLE,
@@ -165,6 +195,25 @@ DECLARE_UVERBS_NAMED_METHOD( · 11 unmodified lines
165 UA_MANDATORY,195 UA_MANDATORY,
166 UA_ALLOC_AND_COPY));196 UA_ALLOC_AND_COPY));
167 197
198DECLARE_UVERBS_NAMED_METHOD(
199 UVERBS_METHOD_QUERY_MR,
200 UVERBS_ATTR_IDR(UVERBS_ATTR_QUERY_MR_HANDLE,
201 UVERBS_OBJECT_MR,
202 UVERBS_ACCESS_READ,
203 UA_MANDATORY),
204 UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_QUERY_MR_RESP_RKEY,
205 UVERBS_ATTR_TYPE(u32),
206 UA_MANDATORY),
207 UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_QUERY_MR_RESP_LKEY,
208 UVERBS_ATTR_TYPE(u32),
209 UA_MANDATORY),
210 UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_QUERY_MR_RESP_LENGTH,
211 UVERBS_ATTR_TYPE(u64),
212 UA_MANDATORY),
213 UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_QUERY_MR_RESP_IOVA,
214 UVERBS_ATTR_TYPE(u64),
215 UA_OPTIONAL));
216
168DECLARE_UVERBS_NAMED_METHOD(217DECLARE_UVERBS_NAMED_METHOD(
169 UVERBS_METHOD_DM_MR_REG,218 UVERBS_METHOD_DM_MR_REG,
170 UVERBS_ATTR_IDR(UVERBS_ATTR_REG_DM_MR_HANDLE,219 UVERBS_ATTR_IDR(UVERBS_ATTR_REG_DM_MR_HANDLE,
@@ -206,7 +255,8 @@ DECLARE_UVERBS_NAMED_OBJECT( · 35 unmodified lines
206 UVERBS_TYPE_ALLOC_IDR(uverbs_free_mr),255 UVERBS_TYPE_ALLOC_IDR(uverbs_free_mr),
207 &UVERBS_METHOD(UVERBS_METHOD_DM_MR_REG),256 &UVERBS_METHOD(UVERBS_METHOD_DM_MR_REG),
208 &UVERBS_METHOD(UVERBS_METHOD_MR_DESTROY),257 &UVERBS_METHOD(UVERBS_METHOD_MR_DESTROY),
209 &UVERBS_METHOD(UVERBS_METHOD_ADVISE_MR));258 &UVERBS_METHOD(UVERBS_METHOD_ADVISE_MR),
259 &UVERBS_METHOD(UVERBS_METHOD_QUERY_MR));
210 260
211const struct uapi_definition uverbs_def_obj_mr[] = {261const struct uapi_definition uverbs_def_obj_mr[] = {
212 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_MR,262 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_MR,
drivers/infiniband/core/verbs.c+78−107
@@ -988,8 +988,8 @@ EXPORT_SYMBOL(rdma_destroy_ah_user); · 987 unmodified lines
988 * @srq_init_attr: A list of initial attributes required to create the988 * @srq_init_attr: A list of initial attributes required to create the
989 * SRQ. If SRQ creation succeeds, then the attributes are updated to989 * SRQ. If SRQ creation succeeds, then the attributes are updated to
990 * the actual capabilities of the created SRQ.990 * the actual capabilities of the created SRQ.
991 * @uobject - uobject pointer if this is not a kernel SRQ991 * @uobject: uobject pointer if this is not a kernel SRQ
992 * @udata - udata pointer if this is not a kernel SRQ992 * @udata: udata pointer if this is not a kernel SRQ
993 *993 *
994 * srq_attr->max_wr and srq_attr->max_sge are read the determine the994 * srq_attr->max_wr and srq_attr->max_sge are read the determine the
995 * requested size of the SRQ, and set to the actual values allocated995 * requested size of the SRQ, and set to the actual values allocated
@@ -1090,13 +1090,6 @@ static void __ib_shared_qp_event_handler(struct ib_event *event, void *context) · 94 unmodified lines
1090 spin_unlock_irqrestore(&qp->device->qp_open_list_lock, flags);1090 spin_unlock_irqrestore(&qp->device->qp_open_list_lock, flags);
1091}1091}
1092 1092
1093static void __ib_insert_xrcd_qp(struct ib_xrcd *xrcd, struct ib_qp *qp)
1094{
1095 mutex_lock(&xrcd->tgt_qp_mutex);
1096 list_add(&qp->xrcd_list, &xrcd->tgt_qp_list);
1097 mutex_unlock(&xrcd->tgt_qp_mutex);
1098}
1099
1100static struct ib_qp *__ib_open_qp(struct ib_qp *real_qp,1093static struct ib_qp *__ib_open_qp(struct ib_qp *real_qp,
1101 void (*event_handler)(struct ib_event *, void *),1094 void (*event_handler)(struct ib_event *, void *),
1102 void *qp_context)1095 void *qp_context)
@@ -1139,16 +1132,15 @@ struct ib_qp *ib_open_qp(struct ib_xrcd *xrcd, · 36 unmodified lines
1139 if (qp_open_attr->qp_type != IB_QPT_XRC_TGT)1132 if (qp_open_attr->qp_type != IB_QPT_XRC_TGT)
1140 return ERR_PTR(-EINVAL);1133 return ERR_PTR(-EINVAL);
1141 1134
1142 qp = ERR_PTR(-EINVAL);1135 down_read(&xrcd->tgt_qps_rwsem);
1143 mutex_lock(&xrcd->tgt_qp_mutex);1136 real_qp = xa_load(&xrcd->tgt_qps, qp_open_attr->qp_num);
1144 list_for_each_entry(real_qp, &xrcd->tgt_qp_list, xrcd_list) {1137 if (!real_qp) {
1145 if (real_qp->qp_num == qp_open_attr->qp_num) {1138 up_read(&xrcd->tgt_qps_rwsem);
1146 qp = __ib_open_qp(real_qp, qp_open_attr->event_handler,1139 return ERR_PTR(-EINVAL);
1147 qp_open_attr->qp_context);
1148 break;
1149 }
1150 }1140 }
1151 mutex_unlock(&xrcd->tgt_qp_mutex);1141 qp = __ib_open_qp(real_qp, qp_open_attr->event_handler,
1142 qp_open_attr->qp_context);
1143 up_read(&xrcd->tgt_qps_rwsem);
1152 return qp;1144 return qp;
1153}1145}
1154EXPORT_SYMBOL(ib_open_qp);1146EXPORT_SYMBOL(ib_open_qp);
@@ -1157,6 +1149,7 @@ static struct ib_qp *create_xrc_qp_user(struct ib_qp *qp, · 2 unmodified lines
1157 struct ib_qp_init_attr *qp_init_attr)1149 struct ib_qp_init_attr *qp_init_attr)
1158{1150{
1159 struct ib_qp *real_qp = qp;1151 struct ib_qp *real_qp = qp;
1152 int err;
1160 1153
1161 qp->event_handler = __ib_shared_qp_event_handler;1154 qp->event_handler = __ib_shared_qp_event_handler;
1162 qp->qp_context = qp;1155 qp->qp_context = qp;
@@ -1172,7 +1165,12 @@ static struct ib_qp *create_xrc_qp_user(struct ib_qp *qp, · 9 unmodified lines
1172 if (IS_ERR(qp))1165 if (IS_ERR(qp))
1173 return qp;1166 return qp;
1174 1167
1175 __ib_insert_xrcd_qp(qp_init_attr->xrcd, real_qp);1168 err = xa_err(xa_store(&qp_init_attr->xrcd->tgt_qps, real_qp->qp_num,
1169 real_qp, GFP_KERNEL));
1170 if (err) {
1171 ib_close_qp(qp);
1172 return ERR_PTR(err);
1173 }
1176 return qp;1174 return qp;
1177}1175}
1178 1176
@@ -1712,7 +1710,7 @@ static int _ib_modify_qp(struct ib_qp *qp, struct ib_qp_attr *attr, · 533 unmodified lines
1712 if (!(rdma_protocol_ib(qp->device,1710 if (!(rdma_protocol_ib(qp->device,
1713 attr->alt_ah_attr.port_num) &&1711 attr->alt_ah_attr.port_num) &&
1714 rdma_protocol_ib(qp->device, port))) {1712 rdma_protocol_ib(qp->device, port))) {
1715 ret = EINVAL;1713 ret = -EINVAL;
1716 goto out;1714 goto out;
1717 }1715 }
1718 }1716 }
@@ -1887,21 +1885,18 @@ static int __ib_destroy_shared_qp(struct ib_qp *qp) · 168 unmodified lines
1887 1885
1888 real_qp = qp->real_qp;1886 real_qp = qp->real_qp;
1889 xrcd = real_qp->xrcd;1887 xrcd = real_qp->xrcd;
1890 1888 down_write(&xrcd->tgt_qps_rwsem);
1891 mutex_lock(&xrcd->tgt_qp_mutex);
1892 ib_close_qp(qp);1889 ib_close_qp(qp);
1893 if (atomic_read(&real_qp->usecnt) == 0)1890 if (atomic_read(&real_qp->usecnt) == 0)
1894 list_del(&real_qp->xrcd_list);1891 xa_erase(&xrcd->tgt_qps, real_qp->qp_num);
1895 else1892 else
1896 real_qp = NULL;1893 real_qp = NULL;
1897 mutex_unlock(&xrcd->tgt_qp_mutex);1894 up_write(&xrcd->tgt_qps_rwsem);
1898 1895
1899 if (real_qp) {1896 if (real_qp) {
1900 ret = ib_destroy_qp(real_qp);1897 ret = ib_destroy_qp(real_qp);
1901 if (!ret)1898 if (!ret)
1902 atomic_dec(&xrcd->usecnt);1899 atomic_dec(&xrcd->usecnt);
1903 else
1904 __ib_insert_xrcd_qp(xrcd, real_qp);
1905 }1900 }
1906 1901
1907 return 0;1902 return 0;
@@ -2077,6 +2072,9 @@ int ib_advise_mr(struct ib_pd *pd, enum ib_uverbs_advise_mr_advice advice, · 169 unmodified lines
2077 if (!pd->device->ops.advise_mr)2072 if (!pd->device->ops.advise_mr)
2078 return -EOPNOTSUPP;2073 return -EOPNOTSUPP;
2079 2074
2075 if (!num_sge)
2076 return 0;
2077
2080 return pd->device->ops.advise_mr(pd, advice, flags, sg_list, num_sge,2078 return pd->device->ops.advise_mr(pd, advice, flags, sg_list, num_sge,
2081 NULL);2079 NULL);
2082}2080}
@@ -2104,11 +2102,10 @@ int ib_dereg_mr_user(struct ib_mr *mr, struct ib_udata *udata) · 21 unmodified lines
2104EXPORT_SYMBOL(ib_dereg_mr_user);2102EXPORT_SYMBOL(ib_dereg_mr_user);
2105 2103
2106/**2104/**
2107 * ib_alloc_mr_user() - Allocates a memory region2105 * ib_alloc_mr() - Allocates a memory region
2108 * @pd: protection domain associated with the region2106 * @pd: protection domain associated with the region
2109 * @mr_type: memory region type2107 * @mr_type: memory region type
2110 * @max_num_sg: maximum sg entries available for registration.2108 * @max_num_sg: maximum sg entries available for registration.
2111 * @udata: user data or null for kernel objects
2112 *2109 *
2113 * Notes:2110 * Notes:
2114 * Memory registeration page/sg lists must not exceed max_num_sg.2111 * Memory registeration page/sg lists must not exceed max_num_sg.
@@ -2116,8 +2113,8 @@ EXPORT_SYMBOL(ib_dereg_mr_user); · 1 unmodified line
2116 * max_num_sg * used_page_size.2113 * max_num_sg * used_page_size.
2117 *2114 *
2118 */2115 */
2119struct ib_mr *ib_alloc_mr_user(struct ib_pd *pd, enum ib_mr_type mr_type,2116struct ib_mr *ib_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
2120 u32 max_num_sg, struct ib_udata *udata)2117 u32 max_num_sg)
2121{2118{
2122 struct ib_mr *mr;2119 struct ib_mr *mr;
2123 2120
@@ -2132,25 +2129,26 @@ struct ib_mr *ib_alloc_mr_user(struct ib_pd *pd, enum ib_mr_type mr_type, · 8 unmodified lines
2132 goto out;2129 goto out;
2133 }2130 }
2134 2131
2135 mr = pd->device->ops.alloc_mr(pd, mr_type, max_num_sg, udata);2132 mr = pd->device->ops.alloc_mr(pd, mr_type, max_num_sg);
2136 if (!IS_ERR(mr)) {2133 if (IS_ERR(mr))
2137 mr->device = pd->device;2134 goto out;
2138 mr->pd = pd;2135
2139 mr->dm = NULL;2136 mr->device = pd->device;
2140 mr->uobject = NULL;2137 mr->pd = pd;
2141 atomic_inc(&pd->usecnt);2138 mr->dm = NULL;
2142 mr->need_inval = false;2139 mr->uobject = NULL;
2143 mr->res.type = RDMA_RESTRACK_MR;2140 atomic_inc(&pd->usecnt);
2144 rdma_restrack_kadd(&mr->res);2141 mr->need_inval = false;
2145 mr->type = mr_type;2142 mr->res.type = RDMA_RESTRACK_MR;
2146 mr->sig_attrs = NULL;2143 rdma_restrack_kadd(&mr->res);
2147 }2144 mr->type = mr_type;
2145 mr->sig_attrs = NULL;
2148 2146
2149out:2147out:
2150 trace_mr_alloc(pd, mr_type, max_num_sg, mr);2148 trace_mr_alloc(pd, mr_type, max_num_sg, mr);
2151 return mr;2149 return mr;
2152}2150}
2153EXPORT_SYMBOL(ib_alloc_mr_user);2151EXPORT_SYMBOL(ib_alloc_mr);
2154 2152
2155/**2153/**
2156 * ib_alloc_mr_integrity() - Allocates an integrity memory region2154 * ib_alloc_mr_integrity() - Allocates an integrity memory region
@@ -2288,45 +2286,57 @@ int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid) · 131 unmodified lines
2288}2286}
2289EXPORT_SYMBOL(ib_detach_mcast);2287EXPORT_SYMBOL(ib_detach_mcast);
2290 2288
2291struct ib_xrcd *__ib_alloc_xrcd(struct ib_device *device, const char *caller)2289/**
2290 * ib_alloc_xrcd_user - Allocates an XRC domain.
2291 * @device: The device on which to allocate the XRC domain.
2292 * @inode: inode to connect XRCD
2293 * @udata: Valid user data or NULL for kernel object
2294 */
2295struct ib_xrcd *ib_alloc_xrcd_user(struct ib_device *device,
2296 struct inode *inode, struct ib_udata *udata)
2292{2297{
2293 struct ib_xrcd *xrcd;2298 struct ib_xrcd *xrcd;
2299 int ret;
2294 2300
2295 if (!device->ops.alloc_xrcd)2301 if (!device->ops.alloc_xrcd)
2296 return ERR_PTR(-EOPNOTSUPP);2302 return ERR_PTR(-EOPNOTSUPP);
2297 2303
2298 xrcd = device->ops.alloc_xrcd(device, NULL);2304 xrcd = rdma_zalloc_drv_obj(device, ib_xrcd);
2299 if (!IS_ERR(xrcd)) {2305 if (!xrcd)
2300 xrcd->device = device;2306 return ERR_PTR(-ENOMEM);
2301 xrcd->inode = NULL;
2302 atomic_set(&xrcd->usecnt, 0);
2303 mutex_init(&xrcd->tgt_qp_mutex);
2304 INIT_LIST_HEAD(&xrcd->tgt_qp_list);
2305 }
2306 2307
2308 xrcd->device = device;
2309 xrcd->inode = inode;
2310 atomic_set(&xrcd->usecnt, 0);
2311 init_rwsem(&xrcd->tgt_qps_rwsem);
2312 xa_init(&xrcd->tgt_qps);
2313
2314 ret = device->ops.alloc_xrcd(xrcd, udata);
2315 if (ret)
2316 goto err;
2307 return xrcd;2317 return xrcd;
2318err:
2319 kfree(xrcd);
2320 return ERR_PTR(ret);
2308}2321}
2309EXPORT_SYMBOL(__ib_alloc_xrcd);2322EXPORT_SYMBOL(ib_alloc_xrcd_user);
2310 2323
2311int ib_dealloc_xrcd(struct ib_xrcd *xrcd, struct ib_udata *udata)2324/**
2325 * ib_dealloc_xrcd_user - Deallocates an XRC domain.
2326 * @xrcd: The XRC domain to deallocate.
2327 * @udata: Valid user data or NULL for kernel object
2328 */
2329int ib_dealloc_xrcd_user(struct ib_xrcd *xrcd, struct ib_udata *udata)
2312{2330{
2313 struct ib_qp *qp;
2314 int ret;
2315
2316 if (atomic_read(&xrcd->usecnt))2331 if (atomic_read(&xrcd->usecnt))
2317 return -EBUSY;2332 return -EBUSY;
2318 2333
2319 while (!list_empty(&xrcd->tgt_qp_list)) {2334 WARN_ON(!xa_empty(&xrcd->tgt_qps));
2320 qp = list_entry(xrcd->tgt_qp_list.next, struct ib_qp, xrcd_list);2335 xrcd->device->ops.dealloc_xrcd(xrcd, udata);
2321 ret = ib_destroy_qp(qp);2336 kfree(xrcd);
2322 if (ret)2337 return 0;
2323 return ret;
2324 }
2325 mutex_destroy(&xrcd->tgt_qp_mutex);
2326
2327 return xrcd->device->ops.dealloc_xrcd(xrcd, udata);
2328}2338}
2329EXPORT_SYMBOL(ib_dealloc_xrcd);2339EXPORT_SYMBOL(ib_dealloc_xrcd_user);
2330 2340
2331/**2341/**
2332 * ib_create_wq - Creates a WQ associated with the specified protection2342 * ib_create_wq - Creates a WQ associated with the specified protection
@@ -2409,45 +2419,6 @@ int ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr, · 76 unmodified lines
2409}2419}
2410EXPORT_SYMBOL(ib_modify_wq);2420EXPORT_SYMBOL(ib_modify_wq);
2411 2421
2412/*
2413 * ib_create_rwq_ind_table - Creates a RQ Indirection Table.
2414 * @device: The device on which to create the rwq indirection table.
2415 * @ib_rwq_ind_table_init_attr: A list of initial attributes required to
2416 * create the Indirection Table.
2417 *
2418 * Note: The life time of ib_rwq_ind_table_init_attr->ind_tbl is not less
2419 * than the created ib_rwq_ind_table object and the caller is responsible
2420 * for its memory allocation/free.
2421 */
2422struct ib_rwq_ind_table *ib_create_rwq_ind_table(struct ib_device *device,
2423 struct ib_rwq_ind_table_init_attr *init_attr)
2424{
2425 struct ib_rwq_ind_table *rwq_ind_table;
2426 int i;
2427 u32 table_size;
2428
2429 if (!device->ops.create_rwq_ind_table)
2430 return ERR_PTR(-EOPNOTSUPP);
2431
2432 table_size = (1 << init_attr->log_ind_tbl_size);
2433 rwq_ind_table = device->ops.create_rwq_ind_table(device,
2434 init_attr, NULL);
2435 if (IS_ERR(rwq_ind_table))
2436 return rwq_ind_table;
2437
2438 rwq_ind_table->ind_tbl = init_attr->ind_tbl;
2439 rwq_ind_table->log_ind_tbl_size = init_attr->log_ind_tbl_size;
2440 rwq_ind_table->device = device;
2441 rwq_ind_table->uobject = NULL;
2442 atomic_set(&rwq_ind_table->usecnt, 0);
2443
2444 for (i = 0; i < table_size; i++)
2445 atomic_inc(&rwq_ind_table->ind_tbl[i]->usecnt);
2446
2447 return rwq_ind_table;
2448}
2449EXPORT_SYMBOL(ib_create_rwq_ind_table);
2450
2451/*2422/*
2452 * ib_destroy_rwq_ind_table - Destroys the specified Indirection Table.2423 * ib_destroy_rwq_ind_table - Destroys the specified Indirection Table.
2453 * @wq_ind_table: The Indirection Table to destroy.2424 * @wq_ind_table: The Indirection Table to destroy.
drivers/infiniband/hw/bnxt_re/ib_verbs.c+128−42
@@ -842,16 +842,79 @@ static u8 __from_ib_qp_type(enum ib_qp_type type) · 841 unmodified lines
842 }842 }
843}843}
844 844
845static u16 bnxt_re_setup_rwqe_size(struct bnxt_qplib_qp *qplqp,
846 int rsge, int max)
847{
848 if (qplqp->wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC)
849 rsge = max;
850 return bnxt_re_get_rwqe_size(rsge);
851}
852
853static u16 bnxt_re_get_wqe_size(int ilsize, int nsge)
854{
855 u16 wqe_size, calc_ils;
856
857 wqe_size = bnxt_re_get_swqe_size(nsge);
858 if (ilsize) {
859 calc_ils = sizeof(struct sq_send_hdr) + ilsize;
860 wqe_size = max_t(u16, calc_ils, wqe_size);
861 wqe_size = ALIGN(wqe_size, sizeof(struct sq_send_hdr));
862 }
863 return wqe_size;
864}
865
866static int bnxt_re_setup_swqe_size(struct bnxt_re_qp *qp,
867 struct ib_qp_init_attr *init_attr)
868{
869 struct bnxt_qplib_dev_attr *dev_attr;
870 struct bnxt_qplib_qp *qplqp;
871 struct bnxt_re_dev *rdev;
872 struct bnxt_qplib_q *sq;
873 int align, ilsize;
874
875 rdev = qp->rdev;
876 qplqp = &qp->qplib_qp;
877 sq = &qplqp->sq;
878 dev_attr = &rdev->dev_attr;
879
880 align = sizeof(struct sq_send_hdr);
881 ilsize = ALIGN(init_attr->cap.max_inline_data, align);
882
883 sq->wqe_size = bnxt_re_get_wqe_size(ilsize, sq->max_sge);
884 if (sq->wqe_size > bnxt_re_get_swqe_size(dev_attr->max_qp_sges))
885 return -EINVAL;
886 /* For gen p4 and gen p5 backward compatibility mode
887 * wqe size is fixed to 128 bytes
888 */
889 if (sq->wqe_size < bnxt_re_get_swqe_size(dev_attr->max_qp_sges) &&
890 qplqp->wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC)
891 sq->wqe_size = bnxt_re_get_swqe_size(dev_attr->max_qp_sges);
892
893 if (init_attr->cap.max_inline_data) {
894 qplqp->max_inline_data = sq->wqe_size -
895 sizeof(struct sq_send_hdr);
896 init_attr->cap.max_inline_data = qplqp->max_inline_data;
897 if (qplqp->wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC)
898 sq->max_sge = qplqp->max_inline_data /
899 sizeof(struct sq_sge);
900 }
901
902 return 0;
903}
904
845static int bnxt_re_init_user_qp(struct bnxt_re_dev *rdev, struct bnxt_re_pd *pd,905static int bnxt_re_init_user_qp(struct bnxt_re_dev *rdev, struct bnxt_re_pd *pd,
846 struct bnxt_re_qp *qp, struct ib_udata *udata)906 struct bnxt_re_qp *qp, struct ib_udata *udata)
847{907{
908 struct bnxt_qplib_qp *qplib_qp;
909 struct bnxt_re_ucontext *cntx;
848 struct bnxt_re_qp_req ureq;910 struct bnxt_re_qp_req ureq;
849 struct bnxt_qplib_qp *qplib_qp = &qp->qplib_qp;
850 struct ib_umem *umem;
851 int bytes = 0, psn_sz;911 int bytes = 0, psn_sz;
852 struct bnxt_re_ucontext *cntx = rdma_udata_to_drv_context(912 struct ib_umem *umem;
853 udata, struct bnxt_re_ucontext, ib_uctx);913 int psn_nume;
854 914
915 qplib_qp = &qp->qplib_qp;
916 cntx = rdma_udata_to_drv_context(udata, struct bnxt_re_ucontext,
917 ib_uctx);
855 if (ib_copy_from_udata(&ureq, udata, sizeof(ureq)))918 if (ib_copy_from_udata(&ureq, udata, sizeof(ureq)))
856 return -EFAULT;919 return -EFAULT;
857 920
@@ -859,10 +922,15 @@ static int bnxt_re_init_user_qp(struct bnxt_re_dev *rdev, struct bnxt_re_pd *pd, · 1 unmodified line
859 /* Consider mapping PSN search memory only for RC QPs. */922 /* Consider mapping PSN search memory only for RC QPs. */
860 if (qplib_qp->type == CMDQ_CREATE_QP_TYPE_RC) {923 if (qplib_qp->type == CMDQ_CREATE_QP_TYPE_RC) {
861 psn_sz = bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx) ?924 psn_sz = bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx) ?
862 sizeof(struct sq_psn_search_ext) :925 sizeof(struct sq_psn_search_ext) :
863 sizeof(struct sq_psn_search);926 sizeof(struct sq_psn_search);
864 bytes += (qplib_qp->sq.max_wqe * psn_sz);927 psn_nume = (qplib_qp->wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC) ?
928 qplib_qp->sq.max_wqe :
929 ((qplib_qp->sq.max_wqe * qplib_qp->sq.wqe_size) /
930 sizeof(struct bnxt_qplib_sge));
931 bytes += (psn_nume * psn_sz);
865 }932 }
933
866 bytes = PAGE_ALIGN(bytes);934 bytes = PAGE_ALIGN(bytes);
867 umem = ib_umem_get(&rdev->ibdev, ureq.qpsva, bytes,935 umem = ib_umem_get(&rdev->ibdev, ureq.qpsva, bytes,
868 IB_ACCESS_LOCAL_WRITE);936 IB_ACCESS_LOCAL_WRITE);
@@ -975,7 +1043,7 @@ static struct bnxt_re_qp *bnxt_re_create_shadow_qp · 106 unmodified lines
975 qp->qplib_qp.sig_type = true;1043 qp->qplib_qp.sig_type = true;
976 1044
977 /* Shadow QP SQ depth should be same as QP1 RQ depth */1045 /* Shadow QP SQ depth should be same as QP1 RQ depth */
978 qp->qplib_qp.sq.wqe_size = bnxt_re_get_swqe_size();1046 qp->qplib_qp.sq.wqe_size = bnxt_re_get_wqe_size(0, 6);
979 qp->qplib_qp.sq.max_wqe = qp1_qp->rq.max_wqe;1047 qp->qplib_qp.sq.max_wqe = qp1_qp->rq.max_wqe;
980 qp->qplib_qp.sq.max_sge = 2;1048 qp->qplib_qp.sq.max_sge = 2;
981 /* Q full delta can be 1 since it is internal QP */1049 /* Q full delta can be 1 since it is internal QP */
@@ -986,7 +1054,7 @@ static struct bnxt_re_qp *bnxt_re_create_shadow_qp · 4 unmodified lines
986 qp->qplib_qp.scq = qp1_qp->scq;1054 qp->qplib_qp.scq = qp1_qp->scq;
987 qp->qplib_qp.rcq = qp1_qp->rcq;1055 qp->qplib_qp.rcq = qp1_qp->rcq;
988 1056
989 qp->qplib_qp.rq.wqe_size = bnxt_re_get_rwqe_size();1057 qp->qplib_qp.rq.wqe_size = bnxt_re_get_rwqe_size(6);
990 qp->qplib_qp.rq.max_wqe = qp1_qp->rq.max_wqe;1058 qp->qplib_qp.rq.max_wqe = qp1_qp->rq.max_wqe;
991 qp->qplib_qp.rq.max_sge = qp1_qp->rq.max_sge;1059 qp->qplib_qp.rq.max_sge = qp1_qp->rq.max_sge;
992 /* Q full delta can be 1 since it is internal QP */1060 /* Q full delta can be 1 since it is internal QP */
@@ -1041,19 +1109,21 @@ static int bnxt_re_init_rq_attr(struct bnxt_re_qp *qp, · 48 unmodified lines
1041 qplqp->srq = &srq->qplib_srq;1109 qplqp->srq = &srq->qplib_srq;
1042 rq->max_wqe = 0;1110 rq->max_wqe = 0;
1043 } else {1111 } else {
1044 rq->wqe_size = bnxt_re_get_rwqe_size();1112 rq->max_sge = init_attr->cap.max_recv_sge;
1113 if (rq->max_sge > dev_attr->max_qp_sges)
1114 rq->max_sge = dev_attr->max_qp_sges;
1115 init_attr->cap.max_recv_sge = rq->max_sge;
1116 rq->wqe_size = bnxt_re_setup_rwqe_size(qplqp, rq->max_sge,
1117 dev_attr->max_qp_sges);
1045 /* Allocate 1 more than what's provided so posting max doesn't1118 /* Allocate 1 more than what's provided so posting max doesn't
1046 * mean empty.1119 * mean empty.
1047 */1120 */
1048 entries = roundup_pow_of_two(init_attr->cap.max_recv_wr + 1);1121 entries = roundup_pow_of_two(init_attr->cap.max_recv_wr + 1);
1049 rq->max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes + 1);1122 rq->max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes + 1);
1050 rq->q_full_delta = rq->max_wqe - init_attr->cap.max_recv_wr;1123 rq->q_full_delta = 0;
1051 rq->max_sge = init_attr->cap.max_recv_sge;1124 rq->sg_info.pgsize = PAGE_SIZE;
1052 if (rq->max_sge > dev_attr->max_qp_sges)1125 rq->sg_info.pgshft = PAGE_SHIFT;
1053 rq->max_sge = dev_attr->max_qp_sges;
1054 }1126 }
1055 rq->sg_info.pgsize = PAGE_SIZE;
1056 rq->sg_info.pgshft = PAGE_SHIFT;
1057 1127
1058 return 0;1128 return 0;
1059}1129}
@@ -1068,41 +1138,48 @@ static void bnxt_re_adjust_gsi_rq_attr(struct bnxt_re_qp *qp) · 8 unmodified lines
1068 qplqp = &qp->qplib_qp;1138 qplqp = &qp->qplib_qp;
1069 dev_attr = &rdev->dev_attr;1139 dev_attr = &rdev->dev_attr;
1070 1140
1071 qplqp->rq.max_sge = dev_attr->max_qp_sges;1141 if (!bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx)) {
1072 if (qplqp->rq.max_sge > dev_attr->max_qp_sges)
1073 qplqp->rq.max_sge = dev_attr->max_qp_sges;1142 qplqp->rq.max_sge = dev_attr->max_qp_sges;
1074 qplqp->rq.max_sge = 6;1143 if (qplqp->rq.max_sge > dev_attr->max_qp_sges)
1144 qplqp->rq.max_sge = dev_attr->max_qp_sges;
1145 qplqp->rq.max_sge = 6;
1146 }
1075}1147}
1076 1148
1077static void bnxt_re_init_sq_attr(struct bnxt_re_qp *qp,1149static int bnxt_re_init_sq_attr(struct bnxt_re_qp *qp,
1078 struct ib_qp_init_attr *init_attr,1150 struct ib_qp_init_attr *init_attr,
1079 struct ib_udata *udata)1151 struct ib_udata *udata)
1080{1152{
1081 struct bnxt_qplib_dev_attr *dev_attr;1153 struct bnxt_qplib_dev_attr *dev_attr;
1082 struct bnxt_qplib_qp *qplqp;1154 struct bnxt_qplib_qp *qplqp;
1083 struct bnxt_re_dev *rdev;1155 struct bnxt_re_dev *rdev;
1084 struct bnxt_qplib_q *sq;1156 struct bnxt_qplib_q *sq;
1085 int entries;1157 int entries;
1158 int diff;
1159 int rc;
1086 1160
1087 rdev = qp->rdev;1161 rdev = qp->rdev;
1088 qplqp = &qp->qplib_qp;1162 qplqp = &qp->qplib_qp;
1089 sq = &qplqp->sq;1163 sq = &qplqp->sq;
1090 dev_attr = &rdev->dev_attr;1164 dev_attr = &rdev->dev_attr;
1091 1165
1092 sq->wqe_size = bnxt_re_get_swqe_size();
1093 sq->max_sge = init_attr->cap.max_send_sge;1166 sq->max_sge = init_attr->cap.max_send_sge;
1094 if (sq->max_sge > dev_attr->max_qp_sges)1167 if (sq->max_sge > dev_attr->max_qp_sges) {
1095 sq->max_sge = dev_attr->max_qp_sges;1168 sq->max_sge = dev_attr->max_qp_sges;
1096 /*1169 init_attr->cap.max_send_sge = sq->max_sge;
1097 * Change the SQ depth if user has requested minimum using1170 }
1098 * configfs. Only supported for kernel consumers1171
1099 */1172 rc = bnxt_re_setup_swqe_size(qp, init_attr);
1173 if (rc)
1174 return rc;
1175
1100 entries = init_attr->cap.max_send_wr;1176 entries = init_attr->cap.max_send_wr;
1101 /* Allocate 128 + 1 more than what's provided */1177 /* Allocate 128 + 1 more than what's provided */
1102 entries = roundup_pow_of_two(entries + BNXT_QPLIB_RESERVED_QP_WRS + 1);1178 diff = (qplqp->wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE) ?
1103 sq->max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes +1179 0 : BNXT_QPLIB_RESERVED_QP_WRS;
1104 BNXT_QPLIB_RESERVED_QP_WRS + 1);1180 entries = roundup_pow_of_two(entries + diff + 1);
1105 sq->q_full_delta = BNXT_QPLIB_RESERVED_QP_WRS + 1;1181 sq->max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes + diff + 1);
1182 sq->q_full_delta = diff + 1;
1106 /*1183 /*
1107 * Reserving one slot for Phantom WQE. Application can1184 * Reserving one slot for Phantom WQE. Application can
1108 * post one extra entry in this case. But allowing this to avoid1185 * post one extra entry in this case. But allowing this to avoid
@@ -1111,6 +1188,8 @@ static void bnxt_re_init_sq_attr(struct bnxt_re_qp *qp, · 2 unmodified lines
1111 qplqp->sq.q_full_delta -= 1;1188 qplqp->sq.q_full_delta -= 1;
1112 qplqp->sq.sg_info.pgsize = PAGE_SIZE;1189 qplqp->sq.sg_info.pgsize = PAGE_SIZE;
1113 qplqp->sq.sg_info.pgshft = PAGE_SHIFT;1190 qplqp->sq.sg_info.pgshft = PAGE_SHIFT;
1191
1192 return 0;
1114}1193}
1115 1194
1116static void bnxt_re_adjust_gsi_sq_attr(struct bnxt_re_qp *qp,1195static void bnxt_re_adjust_gsi_sq_attr(struct bnxt_re_qp *qp,
@@ -1125,13 +1204,16 @@ static void bnxt_re_adjust_gsi_sq_attr(struct bnxt_re_qp *qp, · 8 unmodified lines
1125 qplqp = &qp->qplib_qp;1204 qplqp = &qp->qplib_qp;
1126 dev_attr = &rdev->dev_attr;1205 dev_attr = &rdev->dev_attr;
1127 1206
1128 entries = roundup_pow_of_two(init_attr->cap.max_send_wr + 1);1207 if (!bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx)) {
1129 qplqp->sq.max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes + 1);1208 entries = roundup_pow_of_two(init_attr->cap.max_send_wr + 1);
1130 qplqp->sq.q_full_delta = qplqp->sq.max_wqe -1209 qplqp->sq.max_wqe = min_t(u32, entries,
1131 init_attr->cap.max_send_wr;1210 dev_attr->max_qp_wqes + 1);
1132 qplqp->sq.max_sge++; /* Need one extra sge to put UD header */1211 qplqp->sq.q_full_delta = qplqp->sq.max_wqe -
1133 if (qplqp->sq.max_sge > dev_attr->max_qp_sges)1212 init_attr->cap.max_send_wr;
1134 qplqp->sq.max_sge = dev_attr->max_qp_sges;1213 qplqp->sq.max_sge++; /* Need one extra sge to put UD header */
1214 if (qplqp->sq.max_sge > dev_attr->max_qp_sges)
1215 qplqp->sq.max_sge = dev_attr->max_qp_sges;
1216 }
1135}1217}
1136 1218
1137static int bnxt_re_init_qp_type(struct bnxt_re_dev *rdev,1219static int bnxt_re_init_qp_type(struct bnxt_re_dev *rdev,
@@ -1183,6 +1265,7 @@ static int bnxt_re_init_qp_attr(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd, · 45 unmodified lines
1183 goto out;1265 goto out;
1184 }1266 }
1185 qplqp->type = (u8)qptype;1267 qplqp->type = (u8)qptype;
1268 qplqp->wqe_mode = rdev->chip_ctx->modes.wqe_mode;
1186 1269
1187 if (init_attr->qp_type == IB_QPT_RC) {1270 if (init_attr->qp_type == IB_QPT_RC) {
1188 qplqp->max_rd_atomic = dev_attr->max_qp_rd_atom;1271 qplqp->max_rd_atomic = dev_attr->max_qp_rd_atom;
@@ -1226,7 +1309,9 @@ static int bnxt_re_init_qp_attr(struct bnxt_re_qp *qp, struct bnxt_re_pd *pd, · 37 unmodified lines
1226 bnxt_re_adjust_gsi_rq_attr(qp);1309 bnxt_re_adjust_gsi_rq_attr(qp);
1227 1310
1228 /* Setup SQ */1311 /* Setup SQ */
1229 bnxt_re_init_sq_attr(qp, init_attr, udata);1312 rc = bnxt_re_init_sq_attr(qp, init_attr, udata);
1313 if (rc)
1314 goto out;
1230 if (init_attr->qp_type == IB_QPT_GSI)1315 if (init_attr->qp_type == IB_QPT_GSI)
1231 bnxt_re_adjust_gsi_sq_attr(qp, init_attr);1316 bnxt_re_adjust_gsi_sq_attr(qp, init_attr);
1232 1317
@@ -1574,8 +1659,9 @@ int bnxt_re_create_srq(struct ib_srq *ib_srq, · 341 unmodified lines
1574 entries = dev_attr->max_srq_wqes + 1;1659 entries = dev_attr->max_srq_wqes + 1;
1575 srq->qplib_srq.max_wqe = entries;1660 srq->qplib_srq.max_wqe = entries;
1576 1661
1577 srq->qplib_srq.wqe_size = bnxt_re_get_rwqe_size();
1578 srq->qplib_srq.max_sge = srq_init_attr->attr.max_sge;1662 srq->qplib_srq.max_sge = srq_init_attr->attr.max_sge;
1663 srq->qplib_srq.wqe_size =
1664 bnxt_re_get_rwqe_size(srq->qplib_srq.max_sge);
1579 srq->qplib_srq.threshold = srq_init_attr->attr.srq_limit;1665 srq->qplib_srq.threshold = srq_init_attr->attr.srq_limit;
1580 srq->srq_limit = srq_init_attr->attr.srq_limit;1666 srq->srq_limit = srq_init_attr->attr.srq_limit;
1581 srq->qplib_srq.eventq_hw_ring_id = rdev->nq[0].ring_id;1667 srq->qplib_srq.eventq_hw_ring_id = rdev->nq[0].ring_id;
@@ -3569,7 +3655,7 @@ int bnxt_re_map_mr_sg(struct ib_mr *ib_mr, struct scatterlist *sg, int sg_nents, · 1987 unmodified lines
3569}3655}
3570 3656
3571struct ib_mr *bnxt_re_alloc_mr(struct ib_pd *ib_pd, enum ib_mr_type type,3657struct ib_mr *bnxt_re_alloc_mr(struct ib_pd *ib_pd, enum ib_mr_type type,
3572 u32 max_num_sg, struct ib_udata *udata)3658 u32 max_num_sg)
3573{3659{
3574 struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd);3660 struct bnxt_re_pd *pd = container_of(ib_pd, struct bnxt_re_pd, ib_pd);
3575 struct bnxt_re_dev *rdev = pd->rdev;3661 struct bnxt_re_dev *rdev = pd->rdev;
drivers/infiniband/hw/bnxt_re/ib_verbs.h+5−5
@@ -136,14 +136,14 @@ struct bnxt_re_ucontext { · 135 unmodified lines
136 spinlock_t sh_lock; /* protect shpg */136 spinlock_t sh_lock; /* protect shpg */
137};137};
138 138
139static inline u16 bnxt_re_get_swqe_size(void)139static inline u16 bnxt_re_get_swqe_size(int nsge)
140{140{
141 return sizeof(struct sq_send);141 return sizeof(struct sq_send_hdr) + nsge * sizeof(struct sq_sge);
142}142}
143 143
144static inline u16 bnxt_re_get_rwqe_size(void)144static inline u16 bnxt_re_get_rwqe_size(int nsge)
145{145{
146 return sizeof(struct rq_wqe);146 return sizeof(struct rq_wqe_hdr) + (nsge * sizeof(struct sq_sge));
147}147}
148 148
149int bnxt_re_query_device(struct ib_device *ibdev,149int bnxt_re_query_device(struct ib_device *ibdev,
@@ -201,7 +201,7 @@ struct ib_mr *bnxt_re_get_dma_mr(struct ib_pd *pd, int mr_access_flags); · 51 unmodified lines
201int bnxt_re_map_mr_sg(struct ib_mr *ib_mr, struct scatterlist *sg, int sg_nents,201int bnxt_re_map_mr_sg(struct ib_mr *ib_mr, struct scatterlist *sg, int sg_nents,
202 unsigned int *sg_offset);202 unsigned int *sg_offset);
203struct ib_mr *bnxt_re_alloc_mr(struct ib_pd *ib_pd, enum ib_mr_type mr_type,203struct ib_mr *bnxt_re_alloc_mr(struct ib_pd *ib_pd, enum ib_mr_type mr_type,
204 u32 max_num_sg, struct ib_udata *udata);204 u32 max_num_sg);
205int bnxt_re_dereg_mr(struct ib_mr *mr, struct ib_udata *udata);205int bnxt_re_dereg_mr(struct ib_mr *mr, struct ib_udata *udata);
206struct ib_mw *bnxt_re_alloc_mw(struct ib_pd *ib_pd, enum ib_mw_type type,206struct ib_mw *bnxt_re_alloc_mw(struct ib_pd *ib_pd, enum ib_mw_type type,
207 struct ib_udata *udata);207 struct ib_udata *udata);
drivers/infiniband/hw/bnxt_re/main.c+17−6
@@ -82,6 +82,15 @@ static void bnxt_re_remove_device(struct bnxt_re_dev *rdev); · 81 unmodified lines
82static void bnxt_re_dealloc_driver(struct ib_device *ib_dev);82static void bnxt_re_dealloc_driver(struct ib_device *ib_dev);
83static void bnxt_re_stop_irq(void *handle);83static void bnxt_re_stop_irq(void *handle);
84 84
85static void bnxt_re_set_drv_mode(struct bnxt_re_dev *rdev, u8 mode)
86{
87 struct bnxt_qplib_chip_ctx *cctx;
88
89 cctx = rdev->chip_ctx;
90 cctx->modes.wqe_mode = bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx) ?
91 mode : BNXT_QPLIB_WQE_MODE_STATIC;
92}
93
85static void bnxt_re_destroy_chip_ctx(struct bnxt_re_dev *rdev)94static void bnxt_re_destroy_chip_ctx(struct bnxt_re_dev *rdev)
86{95{
87 struct bnxt_qplib_chip_ctx *chip_ctx;96 struct bnxt_qplib_chip_ctx *chip_ctx;
@@ -97,7 +106,7 @@ static void bnxt_re_destroy_chip_ctx(struct bnxt_re_dev *rdev) · 9 unmodified lines
97 kfree(chip_ctx);106 kfree(chip_ctx);
98}107}
99 108
100static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev)109static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev, u8 wqe_mode)
101{110{
102 struct bnxt_qplib_chip_ctx *chip_ctx;111 struct bnxt_qplib_chip_ctx *chip_ctx;
103 struct bnxt_en_dev *en_dev;112 struct bnxt_en_dev *en_dev;
@@ -117,6 +126,7 @@ static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev) · 13 unmodified lines
117 rdev->qplib_res.cctx = rdev->chip_ctx;126 rdev->qplib_res.cctx = rdev->chip_ctx;
118 rdev->rcfw.res = &rdev->qplib_res;127 rdev->rcfw.res = &rdev->qplib_res;
119 128
129 bnxt_re_set_drv_mode(rdev, wqe_mode);
120 return 0;130 return 0;
121}131}
122 132
@@ -1386,7 +1396,7 @@ static void bnxt_re_worker(struct work_struct *work) · 1263 unmodified lines
1386 schedule_delayed_work(&rdev->worker, msecs_to_jiffies(30000));1396 schedule_delayed_work(&rdev->worker, msecs_to_jiffies(30000));
1387}1397}
1388 1398
1389static int bnxt_re_dev_init(struct bnxt_re_dev *rdev)1399static int bnxt_re_dev_init(struct bnxt_re_dev *rdev, u8 wqe_mode)
1390{1400{
1391 struct bnxt_qplib_creq_ctx *creq;1401 struct bnxt_qplib_creq_ctx *creq;
1392 struct bnxt_re_ring_attr rattr;1402 struct bnxt_re_ring_attr rattr;
@@ -1406,7 +1416,7 @@ static int bnxt_re_dev_init(struct bnxt_re_dev *rdev) · 13 unmodified lines
1406 }1416 }
1407 set_bit(BNXT_RE_FLAG_NETDEV_REGISTERED, &rdev->flags);1417 set_bit(BNXT_RE_FLAG_NETDEV_REGISTERED, &rdev->flags);
1408 1418
1409 rc = bnxt_re_setup_chip_ctx(rdev);1419 rc = bnxt_re_setup_chip_ctx(rdev, wqe_mode);
1410 if (rc) {1420 if (rc) {
1411 ibdev_err(&rdev->ibdev, "Failed to get chip context\n");1421 ibdev_err(&rdev->ibdev, "Failed to get chip context\n");
1412 return -EINVAL;1422 return -EINVAL;
@@ -1585,7 +1595,7 @@ static void bnxt_re_remove_device(struct bnxt_re_dev *rdev) · 172 unmodified lines
1585}1595}
1586 1596
1587static int bnxt_re_add_device(struct bnxt_re_dev **rdev,1597static int bnxt_re_add_device(struct bnxt_re_dev **rdev,
1588 struct net_device *netdev)1598 struct net_device *netdev, u8 wqe_mode)
1589{1599{
1590 int rc;1600 int rc;
1591 1601
@@ -1599,7 +1609,7 @@ static int bnxt_re_add_device(struct bnxt_re_dev **rdev, · 7 unmodified lines
1599 }1609 }
1600 1610
1601 pci_dev_get((*rdev)->en_dev->pdev);1611 pci_dev_get((*rdev)->en_dev->pdev);
1602 rc = bnxt_re_dev_init(*rdev);1612 rc = bnxt_re_dev_init(*rdev, wqe_mode);
1603 if (rc) {1613 if (rc) {
1604 pci_dev_put((*rdev)->en_dev->pdev);1614 pci_dev_put((*rdev)->en_dev->pdev);
1605 bnxt_re_dev_unreg(*rdev);1615 bnxt_re_dev_unreg(*rdev);
@@ -1711,7 +1721,8 @@ static int bnxt_re_netdev_event(struct notifier_block *notifier, · 105 unmodified lines
1711 case NETDEV_REGISTER:1721 case NETDEV_REGISTER:
1712 if (rdev)1722 if (rdev)
1713 break;1723 break;
1714 rc = bnxt_re_add_device(&rdev, real_dev);1724 rc = bnxt_re_add_device(&rdev, real_dev,
1725 BNXT_QPLIB_WQE_MODE_STATIC);
1715 if (!rc)1726 if (!rc)
1716 sch_work = true;1727 sch_work = true;
1717 release = false;1728 release = false;
drivers/infiniband/hw/bnxt_re/qplib_fp.c+425−326
@@ -178,11 +178,11 @@ static void bnxt_qplib_free_qp_hdr_buf(struct bnxt_qplib_res *res, · 177 unmodified lines
178 178
179 if (qp->rq_hdr_buf)179 if (qp->rq_hdr_buf)
180 dma_free_coherent(&res->pdev->dev,180 dma_free_coherent(&res->pdev->dev,
181 rq->hwq.max_elements * qp->rq_hdr_buf_size,181 rq->max_wqe * qp->rq_hdr_buf_size,
182 qp->rq_hdr_buf, qp->rq_hdr_buf_map);182 qp->rq_hdr_buf, qp->rq_hdr_buf_map);
183 if (qp->sq_hdr_buf)183 if (qp->sq_hdr_buf)
184 dma_free_coherent(&res->pdev->dev,184 dma_free_coherent(&res->pdev->dev,
185 sq->hwq.max_elements * qp->sq_hdr_buf_size,185 sq->max_wqe * qp->sq_hdr_buf_size,
186 qp->sq_hdr_buf, qp->sq_hdr_buf_map);186 qp->sq_hdr_buf, qp->sq_hdr_buf_map);
187 qp->rq_hdr_buf = NULL;187 qp->rq_hdr_buf = NULL;
188 qp->sq_hdr_buf = NULL;188 qp->sq_hdr_buf = NULL;
@@ -199,10 +199,9 @@ static int bnxt_qplib_alloc_qp_hdr_buf(struct bnxt_qplib_res *res, · 10 unmodified lines
199 struct bnxt_qplib_q *sq = &qp->sq;199 struct bnxt_qplib_q *sq = &qp->sq;
200 int rc = 0;200 int rc = 0;
201 201
202 if (qp->sq_hdr_buf_size && sq->hwq.max_elements) {202 if (qp->sq_hdr_buf_size && sq->max_wqe) {
203 qp->sq_hdr_buf = dma_alloc_coherent(&res->pdev->dev,203 qp->sq_hdr_buf = dma_alloc_coherent(&res->pdev->dev,
204 sq->hwq.max_elements *204 sq->max_wqe * qp->sq_hdr_buf_size,
205 qp->sq_hdr_buf_size,
206 &qp->sq_hdr_buf_map, GFP_KERNEL);205 &qp->sq_hdr_buf_map, GFP_KERNEL);
207 if (!qp->sq_hdr_buf) {206 if (!qp->sq_hdr_buf) {
208 rc = -ENOMEM;207 rc = -ENOMEM;
@@ -212,9 +211,9 @@ static int bnxt_qplib_alloc_qp_hdr_buf(struct bnxt_qplib_res *res, · 3 unmodified lines
212 }211 }
213 }212 }
214 213
215 if (qp->rq_hdr_buf_size && rq->hwq.max_elements) {214 if (qp->rq_hdr_buf_size && rq->max_wqe) {
216 qp->rq_hdr_buf = dma_alloc_coherent(&res->pdev->dev,215 qp->rq_hdr_buf = dma_alloc_coherent(&res->pdev->dev,
217 rq->hwq.max_elements *216 rq->max_wqe *
218 qp->rq_hdr_buf_size,217 qp->rq_hdr_buf_size,
219 &qp->rq_hdr_buf_map,218 &qp->rq_hdr_buf_map,
220 GFP_KERNEL);219 GFP_KERNEL);
@@ -661,6 +660,7 @@ int bnxt_qplib_create_srq(struct bnxt_qplib_res *res, · 440 unmodified lines
661 srq->dbinfo.hwq = &srq->hwq;660 srq->dbinfo.hwq = &srq->hwq;
662 srq->dbinfo.xid = srq->id;661 srq->dbinfo.xid = srq->id;
663 srq->dbinfo.db = srq->dpi->dbr;662 srq->dbinfo.db = srq->dpi->dbr;
663 srq->dbinfo.max_slot = 1;
664 srq->dbinfo.priv_db = res->dpi_tbl.dbr_bar_reg_iomem;664 srq->dbinfo.priv_db = res->dpi_tbl.dbr_bar_reg_iomem;
665 if (srq->threshold)665 if (srq->threshold)
666 bnxt_qplib_armen_db(&srq->dbinfo, DBC_DBC_TYPE_SRQ_ARMENA);666 bnxt_qplib_armen_db(&srq->dbinfo, DBC_DBC_TYPE_SRQ_ARMENA);
@@ -784,6 +784,28 @@ done: · 117 unmodified lines
784}784}
785 785
786/* QP */786/* QP */
787
788static int bnxt_qplib_alloc_init_swq(struct bnxt_qplib_q *que)
789{
790 int rc = 0;
791 int indx;
792
793 que->swq = kcalloc(que->max_wqe, sizeof(*que->swq), GFP_KERNEL);
794 if (!que->swq) {
795 rc = -ENOMEM;
796 goto out;
797 }
798
799 que->swq_start = 0;
800 que->swq_last = que->max_wqe - 1;
801 for (indx = 0; indx < que->max_wqe; indx++)
802 que->swq[indx].next_idx = indx + 1;
803 que->swq[que->swq_last].next_idx = 0; /* Make it circular */
804 que->swq_last = 0;
805out:
806 return rc;
807}
808
787int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)809int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
788{810{
789 struct bnxt_qplib_hwq_attr hwq_attr = {};811 struct bnxt_qplib_hwq_attr hwq_attr = {};
@@ -808,71 +830,63 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) · 18 unmodified lines
808 /* SQ */830 /* SQ */
809 hwq_attr.res = res;831 hwq_attr.res = res;
810 hwq_attr.sginfo = &sq->sg_info;832 hwq_attr.sginfo = &sq->sg_info;
811 hwq_attr.depth = sq->max_wqe;833 hwq_attr.stride = sizeof(struct sq_sge);
812 hwq_attr.stride = sq->wqe_size;834 hwq_attr.depth = bnxt_qplib_get_depth(sq);
813 hwq_attr.type = HWQ_TYPE_QUEUE;835 hwq_attr.type = HWQ_TYPE_QUEUE;
814 rc = bnxt_qplib_alloc_init_hwq(&sq->hwq, &hwq_attr);836 rc = bnxt_qplib_alloc_init_hwq(&sq->hwq, &hwq_attr);
815 if (rc)837 if (rc)
816 goto exit;838 goto exit;
817 839
818 sq->swq = kcalloc(sq->hwq.max_elements, sizeof(*sq->swq), GFP_KERNEL);840 rc = bnxt_qplib_alloc_init_swq(sq);
819 if (!sq->swq) {841 if (rc)
820 rc = -ENOMEM;
821 goto fail_sq;842 goto fail_sq;
822 }843
844 req.sq_size = cpu_to_le32(bnxt_qplib_set_sq_size(sq, qp->wqe_mode));
823 pbl = &sq->hwq.pbl[PBL_LVL_0];845 pbl = &sq->hwq.pbl[PBL_LVL_0];
824 req.sq_pbl = cpu_to_le64(pbl->pg_map_arr[0]);846 req.sq_pbl = cpu_to_le64(pbl->pg_map_arr[0]);
825 pg_sz_lvl = (bnxt_qplib_base_pg_size(&sq->hwq) <<847 pg_sz_lvl = (bnxt_qplib_base_pg_size(&sq->hwq) <<
826 CMDQ_CREATE_QP1_SQ_PG_SIZE_SFT);848 CMDQ_CREATE_QP1_SQ_PG_SIZE_SFT);
827 pg_sz_lvl |= (sq->hwq.level & CMDQ_CREATE_QP1_SQ_LVL_MASK);849 pg_sz_lvl |= (sq->hwq.level & CMDQ_CREATE_QP1_SQ_LVL_MASK);
828 req.sq_pg_size_sq_lvl = pg_sz_lvl;850 req.sq_pg_size_sq_lvl = pg_sz_lvl;
851 req.sq_fwo_sq_sge =
852 cpu_to_le16((sq->max_sge & CMDQ_CREATE_QP1_SQ_SGE_MASK) <<
853 CMDQ_CREATE_QP1_SQ_SGE_SFT);
854 req.scq_cid = cpu_to_le32(qp->scq->id);
829 855
830 if (qp->scq)
831 req.scq_cid = cpu_to_le32(qp->scq->id);
832 /* RQ */856 /* RQ */
833 if (rq->max_wqe) {857 if (rq->max_wqe) {
834 hwq_attr.res = res;858 hwq_attr.res = res;
835 hwq_attr.sginfo = &rq->sg_info;859 hwq_attr.sginfo = &rq->sg_info;
836 hwq_attr.stride = rq->wqe_size;860 hwq_attr.stride = sizeof(struct sq_sge);
837 hwq_attr.depth = qp->rq.max_wqe;861 hwq_attr.depth = bnxt_qplib_get_depth(rq);
838 hwq_attr.type = HWQ_TYPE_QUEUE;862 hwq_attr.type = HWQ_TYPE_QUEUE;
839 rc = bnxt_qplib_alloc_init_hwq(&rq->hwq, &hwq_attr);863 rc = bnxt_qplib_alloc_init_hwq(&rq->hwq, &hwq_attr);
840 if (rc)864 if (rc)
841 goto fail_sq;865 goto sq_swq;
842 866 rc = bnxt_qplib_alloc_init_swq(rq);
843 rq->swq = kcalloc(rq->hwq.max_elements, sizeof(*rq->swq),867 if (rc)
844 GFP_KERNEL);
845 if (!rq->swq) {
846 rc = -ENOMEM;
847 goto fail_rq;868 goto fail_rq;
848 }869 req.rq_size = cpu_to_le32(rq->max_wqe);
849 pbl = &rq->hwq.pbl[PBL_LVL_0];870 pbl = &rq->hwq.pbl[PBL_LVL_0];
850 req.rq_pbl = cpu_to_le64(pbl->pg_map_arr[0]);871 req.rq_pbl = cpu_to_le64(pbl->pg_map_arr[0]);
851 pg_sz_lvl = (bnxt_qplib_base_pg_size(&rq->hwq) <<872 pg_sz_lvl = (bnxt_qplib_base_pg_size(&rq->hwq) <<
852 CMDQ_CREATE_QP1_RQ_PG_SIZE_SFT);873 CMDQ_CREATE_QP1_RQ_PG_SIZE_SFT);
853 pg_sz_lvl |= (rq->hwq.level & CMDQ_CREATE_QP1_RQ_LVL_MASK);874 pg_sz_lvl |= (rq->hwq.level & CMDQ_CREATE_QP1_RQ_LVL_MASK);
854 req.rq_pg_size_rq_lvl = pg_sz_lvl;875 req.rq_pg_size_rq_lvl = pg_sz_lvl;
855 if (qp->rcq)876 req.rq_fwo_rq_sge =
856 req.rcq_cid = cpu_to_le32(qp->rcq->id);877 cpu_to_le16((rq->max_sge &
878 CMDQ_CREATE_QP1_RQ_SGE_MASK) <<
879 CMDQ_CREATE_QP1_RQ_SGE_SFT);
857 }880 }
881 req.rcq_cid = cpu_to_le32(qp->rcq->id);
858 /* Header buffer - allow hdr_buf pass in */882 /* Header buffer - allow hdr_buf pass in */
859 rc = bnxt_qplib_alloc_qp_hdr_buf(res, qp);883 rc = bnxt_qplib_alloc_qp_hdr_buf(res, qp);
860 if (rc) {884 if (rc) {
861 rc = -ENOMEM;885 rc = -ENOMEM;
862 goto fail;886 goto rq_rwq;
863 }887 }
864 qp_flags |= CMDQ_CREATE_QP1_QP_FLAGS_RESERVED_LKEY_ENABLE;888 qp_flags |= CMDQ_CREATE_QP1_QP_FLAGS_RESERVED_LKEY_ENABLE;
865 req.qp_flags = cpu_to_le32(qp_flags);889 req.qp_flags = cpu_to_le32(qp_flags);
866 req.sq_size = cpu_to_le32(sq->hwq.max_elements);
867 req.rq_size = cpu_to_le32(rq->hwq.max_elements);
868
869 req.sq_fwo_sq_sge =
870 cpu_to_le16((sq->max_sge & CMDQ_CREATE_QP1_SQ_SGE_MASK) <<
871 CMDQ_CREATE_QP1_SQ_SGE_SFT);
872 req.rq_fwo_rq_sge =
873 cpu_to_le16((rq->max_sge & CMDQ_CREATE_QP1_RQ_SGE_MASK) <<
874 CMDQ_CREATE_QP1_RQ_SGE_SFT);
875
876 req.pd_id = cpu_to_le32(qp->pd->id);890 req.pd_id = cpu_to_le32(qp->pd->id);
877 891
878 rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,892 rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
@@ -886,10 +900,12 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) · 7 unmodified lines
886 sq->dbinfo.hwq = &sq->hwq;900 sq->dbinfo.hwq = &sq->hwq;
887 sq->dbinfo.xid = qp->id;901 sq->dbinfo.xid = qp->id;
888 sq->dbinfo.db = qp->dpi->dbr;902 sq->dbinfo.db = qp->dpi->dbr;
903 sq->dbinfo.max_slot = bnxt_qplib_set_sq_max_slot(qp->wqe_mode);
889 if (rq->max_wqe) {904 if (rq->max_wqe) {
890 rq->dbinfo.hwq = &rq->hwq;905 rq->dbinfo.hwq = &rq->hwq;
891 rq->dbinfo.xid = qp->id;906 rq->dbinfo.xid = qp->id;
892 rq->dbinfo.db = qp->dpi->dbr;907 rq->dbinfo.db = qp->dpi->dbr;
908 rq->dbinfo.max_slot = bnxt_qplib_set_rq_max_slot(rq->wqe_size);
893 }909 }
894 rcfw->qp_tbl[qp->id].qp_id = qp->id;910 rcfw->qp_tbl[qp->id].qp_id = qp->id;
895 rcfw->qp_tbl[qp->id].qp_handle = (void *)qp;911 rcfw->qp_tbl[qp->id].qp_handle = (void *)qp;
@@ -898,12 +914,14 @@ int bnxt_qplib_create_qp1(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) · 2 unmodified lines
898 914
899fail:915fail:
900 bnxt_qplib_free_qp_hdr_buf(res, qp);916 bnxt_qplib_free_qp_hdr_buf(res, qp);
917rq_rwq:
918 kfree(rq->swq);
901fail_rq:919fail_rq:
902 bnxt_qplib_free_hwq(res, &rq->hwq);920 bnxt_qplib_free_hwq(res, &rq->hwq);
903 kfree(rq->swq);921sq_swq:
922 kfree(sq->swq);
904fail_sq:923fail_sq:
905 bnxt_qplib_free_hwq(res, &sq->hwq);924 bnxt_qplib_free_hwq(res, &sq->hwq);
906 kfree(sq->swq);
907exit:925exit:
908 return rc;926 return rc;
909}927}
@@ -912,26 +930,18 @@ static void bnxt_qplib_init_psn_ptr(struct bnxt_qplib_qp *qp, int size) · 2 unmodified lines
912{930{
913 struct bnxt_qplib_hwq *hwq;931 struct bnxt_qplib_hwq *hwq;
914 struct bnxt_qplib_q *sq;932 struct bnxt_qplib_q *sq;
915 u64 fpsne, psne, psn_pg;933 u64 fpsne, psn_pg;
916 u16 indx_pad = 0, indx;934 u16 indx_pad = 0;
917 u16 pg_num, pg_indx;
918 u64 *page;
919 935
920 sq = &qp->sq;936 sq = &qp->sq;
921 hwq = &sq->hwq;937 hwq = &sq->hwq;
922 938 fpsne = (u64)bnxt_qplib_get_qe(hwq, hwq->depth, &psn_pg);
923 fpsne = (u64)bnxt_qplib_get_qe(hwq, hwq->max_elements, &psn_pg);
924 if (!IS_ALIGNED(fpsne, PAGE_SIZE))939 if (!IS_ALIGNED(fpsne, PAGE_SIZE))
925 indx_pad = ALIGN(fpsne, PAGE_SIZE) / size;940 indx_pad = ALIGN(fpsne, PAGE_SIZE) / size;
926 941
927 page = (u64 *)psn_pg;942 hwq->pad_pgofft = indx_pad;
928 for (indx = 0; indx < hwq->max_elements; indx++) {943 hwq->pad_pg = (u64 *)psn_pg;
929 pg_num = (indx + indx_pad) / (PAGE_SIZE / size);944 hwq->pad_stride = size;
930 pg_indx = (indx + indx_pad) % (PAGE_SIZE / size);
931 psne = page[pg_num] + pg_indx * size;
932 sq->swq[indx].psn_ext = (struct sq_psn_search_ext *)psne;
933 sq->swq[indx].psn_search = (struct sq_psn_search *)psne;
934 }
935}945}
936 946
937int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)947int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp)
@@ -944,12 +954,12 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) · 6 unmodified lines
944 struct creq_create_qp_resp resp;954 struct creq_create_qp_resp resp;
945 int rc, req_size, psn_sz = 0;955 int rc, req_size, psn_sz = 0;
946 struct bnxt_qplib_hwq *xrrq;956 struct bnxt_qplib_hwq *xrrq;
947 u16 cmd_flags = 0, max_ssge;
948 struct bnxt_qplib_pbl *pbl;957 struct bnxt_qplib_pbl *pbl;
949 struct cmdq_create_qp req;958 struct cmdq_create_qp req;
959 u16 cmd_flags = 0;
950 u32 qp_flags = 0;960 u32 qp_flags = 0;
951 u8 pg_sz_lvl;961 u8 pg_sz_lvl;
952 u16 max_rsge;962 u16 nsge;
953 963
954 RCFW_CMD_PREP(req, CREATE_QP, cmd_flags);964 RCFW_CMD_PREP(req, CREATE_QP, cmd_flags);
955 965
@@ -967,97 +977,78 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) · 11 unmodified lines
967 977
968 hwq_attr.res = res;978 hwq_attr.res = res;
969 hwq_attr.sginfo = &sq->sg_info;979 hwq_attr.sginfo = &sq->sg_info;
970 hwq_attr.stride = sq->wqe_size;980 hwq_attr.stride = sizeof(struct sq_sge);
971 hwq_attr.depth = sq->max_wqe;981 hwq_attr.depth = bnxt_qplib_get_depth(sq);
972 hwq_attr.aux_stride = psn_sz;982 hwq_attr.aux_stride = psn_sz;
973 hwq_attr.aux_depth = hwq_attr.depth;983 hwq_attr.aux_depth = bnxt_qplib_set_sq_size(sq, qp->wqe_mode);
974 hwq_attr.type = HWQ_TYPE_QUEUE;984 hwq_attr.type = HWQ_TYPE_QUEUE;
975 rc = bnxt_qplib_alloc_init_hwq(&sq->hwq, &hwq_attr);985 rc = bnxt_qplib_alloc_init_hwq(&sq->hwq, &hwq_attr);
976 if (rc)986 if (rc)
977 goto exit;987 goto exit;
978 988
979 sq->swq = kcalloc(sq->hwq.max_elements, sizeof(*sq->swq), GFP_KERNEL);989 rc = bnxt_qplib_alloc_init_swq(sq);
980 if (!sq->swq) {990 if (rc)
981 rc = -ENOMEM;
982 goto fail_sq;991 goto fail_sq;
983 }
984 992
985 if (psn_sz)993 if (psn_sz)
986 bnxt_qplib_init_psn_ptr(qp, psn_sz);994 bnxt_qplib_init_psn_ptr(qp, psn_sz);
987 995
996 req.sq_size = cpu_to_le32(bnxt_qplib_set_sq_size(sq, qp->wqe_mode));
988 pbl = &sq->hwq.pbl[PBL_LVL_0];997 pbl = &sq->hwq.pbl[PBL_LVL_0];
989 req.sq_pbl = cpu_to_le64(pbl->pg_map_arr[0]);998 req.sq_pbl = cpu_to_le64(pbl->pg_map_arr[0]);
990 pg_sz_lvl = (bnxt_qplib_base_pg_size(&sq->hwq) <<999 pg_sz_lvl = (bnxt_qplib_base_pg_size(&sq->hwq) <<
991 CMDQ_CREATE_QP_SQ_PG_SIZE_SFT);1000 CMDQ_CREATE_QP_SQ_PG_SIZE_SFT);
992 pg_sz_lvl |= (sq->hwq.level & CMDQ_CREATE_QP_SQ_LVL_MASK);1001 pg_sz_lvl |= (sq->hwq.level & CMDQ_CREATE_QP_SQ_LVL_MASK);
993 req.sq_pg_size_sq_lvl = pg_sz_lvl;1002 req.sq_pg_size_sq_lvl = pg_sz_lvl;
994 1003 req.sq_fwo_sq_sge =
995 if (qp->scq)1004 cpu_to_le16(((sq->max_sge & CMDQ_CREATE_QP_SQ_SGE_MASK) <<
996 req.scq_cid = cpu_to_le32(qp->scq->id);1005 CMDQ_CREATE_QP_SQ_SGE_SFT) | 0);
1006 req.scq_cid = cpu_to_le32(qp->scq->id);
997 1007
998 /* RQ */1008 /* RQ */
999 if (rq->max_wqe) {1009 if (!qp->srq) {
1000 hwq_attr.res = res;1010 hwq_attr.res = res;
1001 hwq_attr.sginfo = &rq->sg_info;1011 hwq_attr.sginfo = &rq->sg_info;
1002 hwq_attr.stride = rq->wqe_size;1012 hwq_attr.stride = sizeof(struct sq_sge);
1003 hwq_attr.depth = rq->max_wqe;1013 hwq_attr.depth = bnxt_qplib_get_depth(rq);
1004 hwq_attr.aux_stride = 0;1014 hwq_attr.aux_stride = 0;
1005 hwq_attr.aux_depth = 0;1015 hwq_attr.aux_depth = 0;
1006 hwq_attr.type = HWQ_TYPE_QUEUE;1016 hwq_attr.type = HWQ_TYPE_QUEUE;
1007 rc = bnxt_qplib_alloc_init_hwq(&rq->hwq, &hwq_attr);1017 rc = bnxt_qplib_alloc_init_hwq(&rq->hwq, &hwq_attr);
1008 if (rc)1018 if (rc)
1009 goto fail_sq;1019 goto sq_swq;
1010 1020 rc = bnxt_qplib_alloc_init_swq(rq);
1011 rq->swq = kcalloc(rq->hwq.max_elements, sizeof(*rq->swq),1021 if (rc)
1012 GFP_KERNEL);
1013 if (!rq->swq) {
1014 rc = -ENOMEM;
1015 goto fail_rq;1022 goto fail_rq;
1016 }1023
1024 req.rq_size = cpu_to_le32(rq->max_wqe);
1017 pbl = &rq->hwq.pbl[PBL_LVL_0];1025 pbl = &rq->hwq.pbl[PBL_LVL_0];
1018 req.rq_pbl = cpu_to_le64(pbl->pg_map_arr[0]);1026 req.rq_pbl = cpu_to_le64(pbl->pg_map_arr[0]);
1019 pg_sz_lvl = (bnxt_qplib_base_pg_size(&rq->hwq) <<1027 pg_sz_lvl = (bnxt_qplib_base_pg_size(&rq->hwq) <<
1020 CMDQ_CREATE_QP_RQ_PG_SIZE_SFT);1028 CMDQ_CREATE_QP_RQ_PG_SIZE_SFT);
1021 pg_sz_lvl |= (rq->hwq.level & CMDQ_CREATE_QP_RQ_LVL_MASK);1029 pg_sz_lvl |= (rq->hwq.level & CMDQ_CREATE_QP_RQ_LVL_MASK);
1022 req.rq_pg_size_rq_lvl = pg_sz_lvl;1030 req.rq_pg_size_rq_lvl = pg_sz_lvl;
1031 nsge = (qp->wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC) ?
1032 6 : rq->max_sge;
1033 req.rq_fwo_rq_sge =
1034 cpu_to_le16(((nsge &
1035 CMDQ_CREATE_QP_RQ_SGE_MASK) <<
1036 CMDQ_CREATE_QP_RQ_SGE_SFT) | 0);
1023 } else {1037 } else {
1024 /* SRQ */1038 /* SRQ */
1025 if (qp->srq) {1039 qp_flags |= CMDQ_CREATE_QP_QP_FLAGS_SRQ_USED;
1026 qp_flags |= CMDQ_CREATE_QP_QP_FLAGS_SRQ_USED;1040 req.srq_cid = cpu_to_le32(qp->srq->id);
1027 req.srq_cid = cpu_to_le32(qp->srq->id);
1028 }
1029 }1041 }
1030 1042 req.rcq_cid = cpu_to_le32(qp->rcq->id);
1031 if (qp->rcq)
1032 req.rcq_cid = cpu_to_le32(qp->rcq->id);
1033 1043
1034 qp_flags |= CMDQ_CREATE_QP_QP_FLAGS_RESERVED_LKEY_ENABLE;1044 qp_flags |= CMDQ_CREATE_QP_QP_FLAGS_RESERVED_LKEY_ENABLE;
1035 qp_flags |= CMDQ_CREATE_QP_QP_FLAGS_FR_PMR_ENABLED;1045 qp_flags |= CMDQ_CREATE_QP_QP_FLAGS_FR_PMR_ENABLED;
1036 if (qp->sig_type)1046 if (qp->sig_type)
1037 qp_flags |= CMDQ_CREATE_QP_QP_FLAGS_FORCE_COMPLETION;1047 qp_flags |= CMDQ_CREATE_QP_QP_FLAGS_FORCE_COMPLETION;
1048 if (qp->wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE)
1049 qp_flags |= CMDQ_CREATE_QP_QP_FLAGS_VARIABLE_SIZED_WQE_ENABLED;
1038 req.qp_flags = cpu_to_le32(qp_flags);1050 req.qp_flags = cpu_to_le32(qp_flags);
1039 1051
1040 req.sq_size = cpu_to_le32(sq->hwq.max_elements);
1041 req.rq_size = cpu_to_le32(rq->hwq.max_elements);
1042 qp->sq_hdr_buf = NULL;
1043 qp->rq_hdr_buf = NULL;
1044
1045 rc = bnxt_qplib_alloc_qp_hdr_buf(res, qp);
1046 if (rc)
1047 goto fail_rq;
1048
1049 /* CTRL-22434: Irrespective of the requested SGE count on the SQ
1050 * always create the QP with max send sges possible if the requested
1051 * inline size is greater than 0.
1052 */
1053 max_ssge = qp->max_inline_data ? 6 : sq->max_sge;
1054 req.sq_fwo_sq_sge = cpu_to_le16(
1055 ((max_ssge & CMDQ_CREATE_QP_SQ_SGE_MASK)
1056 << CMDQ_CREATE_QP_SQ_SGE_SFT) | 0);
1057 max_rsge = bnxt_qplib_is_chip_gen_p5(res->cctx) ? 6 : rq->max_sge;
1058 req.rq_fwo_rq_sge = cpu_to_le16(
1059 ((max_rsge & CMDQ_CREATE_QP_RQ_SGE_MASK)
1060 << CMDQ_CREATE_QP_RQ_SGE_SFT) | 0);
1061 /* ORRQ and IRRQ */1052 /* ORRQ and IRRQ */
1062 if (psn_sz) {1053 if (psn_sz) {
1063 xrrq = &qp->orrq;1054 xrrq = &qp->orrq;
@@ -1078,7 +1069,7 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) · 14 unmodified lines
1078 hwq_attr.type = HWQ_TYPE_CTX;1069 hwq_attr.type = HWQ_TYPE_CTX;
1079 rc = bnxt_qplib_alloc_init_hwq(xrrq, &hwq_attr);1070 rc = bnxt_qplib_alloc_init_hwq(xrrq, &hwq_attr);
1080 if (rc)1071 if (rc)
1081 goto fail_buf_free;1072 goto rq_swq;
1082 pbl = &xrrq->pbl[PBL_LVL_0];1073 pbl = &xrrq->pbl[PBL_LVL_0];
1083 req.orrq_addr = cpu_to_le64(pbl->pg_map_arr[0]);1074 req.orrq_addr = cpu_to_le64(pbl->pg_map_arr[0]);
1084 1075
@@ -1113,30 +1104,29 @@ int bnxt_qplib_create_qp(struct bnxt_qplib_res *res, struct bnxt_qplib_qp *qp) · 28 unmodified lines
1113 sq->dbinfo.hwq = &sq->hwq;1104 sq->dbinfo.hwq = &sq->hwq;
1114 sq->dbinfo.xid = qp->id;1105 sq->dbinfo.xid = qp->id;
1115 sq->dbinfo.db = qp->dpi->dbr;1106 sq->dbinfo.db = qp->dpi->dbr;
1107 sq->dbinfo.max_slot = bnxt_qplib_set_sq_max_slot(qp->wqe_mode);
1116 if (rq->max_wqe) {1108 if (rq->max_wqe) {
1117 rq->dbinfo.hwq = &rq->hwq;1109 rq->dbinfo.hwq = &rq->hwq;
1118 rq->dbinfo.xid = qp->id;1110 rq->dbinfo.xid = qp->id;
1119 rq->dbinfo.db = qp->dpi->dbr;1111 rq->dbinfo.db = qp->dpi->dbr;
1112 rq->dbinfo.max_slot = bnxt_qplib_set_rq_max_slot(rq->wqe_size);
1120 }1113 }
1121 rcfw->qp_tbl[qp->id].qp_id = qp->id;1114 rcfw->qp_tbl[qp->id].qp_id = qp->id;
1122 rcfw->qp_tbl[qp->id].qp_handle = (void *)qp;1115 rcfw->qp_tbl[qp->id].qp_handle = (void *)qp;
1123 1116
1124 return 0;1117 return 0;
1125
1126fail:1118fail:
1127 if (qp->irrq.max_elements)1119 bnxt_qplib_free_hwq(res, &qp->irrq);
1128 bnxt_qplib_free_hwq(res, &qp->irrq);
1129fail_orrq:1120fail_orrq:
1130 if (qp->orrq.max_elements)1121 bnxt_qplib_free_hwq(res, &qp->orrq);
1131 bnxt_qplib_free_hwq(res, &qp->orrq);1122rq_swq:
1132fail_buf_free:1123 kfree(rq->swq);
1133 bnxt_qplib_free_qp_hdr_buf(res, qp);
1134fail_rq:1124fail_rq:
1135 bnxt_qplib_free_hwq(res, &rq->hwq);1125 bnxt_qplib_free_hwq(res, &rq->hwq);
1136 kfree(rq->swq);1126sq_swq:
1127 kfree(sq->swq);
1137fail_sq:1128fail_sq:
1138 bnxt_qplib_free_hwq(res, &sq->hwq);1129 bnxt_qplib_free_hwq(res, &sq->hwq);
1139 kfree(sq->swq);
1140exit:1130exit:
1141 return rc;1131 return rc;
1142}1132}
@@ -1512,7 +1502,7 @@ void *bnxt_qplib_get_qp1_sq_buf(struct bnxt_qplib_qp *qp, · 369 unmodified lines
1512 memset(sge, 0, sizeof(*sge));1502 memset(sge, 0, sizeof(*sge));
1513 1503
1514 if (qp->sq_hdr_buf) {1504 if (qp->sq_hdr_buf) {
1515 sw_prod = HWQ_CMP(sq->hwq.prod, &sq->hwq);1505 sw_prod = sq->swq_start;
1516 sge->addr = (dma_addr_t)(qp->sq_hdr_buf_map +1506 sge->addr = (dma_addr_t)(qp->sq_hdr_buf_map +
1517 sw_prod * qp->sq_hdr_buf_size);1507 sw_prod * qp->sq_hdr_buf_size);
1518 sge->lkey = 0xFFFFFFFF;1508 sge->lkey = 0xFFFFFFFF;
@@ -1526,7 +1516,7 @@ u32 bnxt_qplib_get_rq_prod_index(struct bnxt_qplib_qp *qp) · 7 unmodified lines
1526{1516{
1527 struct bnxt_qplib_q *rq = &qp->rq;1517 struct bnxt_qplib_q *rq = &qp->rq;
1528 1518
1529 return HWQ_CMP(rq->hwq.prod, &rq->hwq);1519 return rq->swq_start;
1530}1520}
1531 1521
1532dma_addr_t bnxt_qplib_get_qp_buf_from_index(struct bnxt_qplib_qp *qp, u32 index)1522dma_addr_t bnxt_qplib_get_qp_buf_from_index(struct bnxt_qplib_qp *qp, u32 index)
@@ -1543,7 +1533,7 @@ void *bnxt_qplib_get_qp1_rq_buf(struct bnxt_qplib_qp *qp, · 10 unmodified lines
1543 memset(sge, 0, sizeof(*sge));1533 memset(sge, 0, sizeof(*sge));
1544 1534
1545 if (qp->rq_hdr_buf) {1535 if (qp->rq_hdr_buf) {
1546 sw_prod = HWQ_CMP(rq->hwq.prod, &rq->hwq);1536 sw_prod = rq->swq_start;
1547 sge->addr = (dma_addr_t)(qp->rq_hdr_buf_map +1537 sge->addr = (dma_addr_t)(qp->rq_hdr_buf_map +
1548 sw_prod * qp->rq_hdr_buf_size);1538 sw_prod * qp->rq_hdr_buf_size);
1549 sge->lkey = 0xFFFFFFFF;1539 sge->lkey = 0xFFFFFFFF;
@@ -1562,6 +1552,8 @@ static void bnxt_qplib_fill_psn_search(struct bnxt_qplib_qp *qp, · 12 unmodified lines
1562 u32 flg_npsn;1552 u32 flg_npsn;
1563 u32 op_spsn;1553 u32 op_spsn;
1564 1554
1555 if (!swq->psn_search)
1556 return;
1565 psns = swq->psn_search;1557 psns = swq->psn_search;
1566 psns_ext = swq->psn_ext;1558 psns_ext = swq->psn_ext;
1567 1559
@@ -1575,12 +1567,122 @@ static void bnxt_qplib_fill_psn_search(struct bnxt_qplib_qp *qp, · 7 unmodified lines
1575 if (bnxt_qplib_is_chip_gen_p5(qp->cctx)) {1567 if (bnxt_qplib_is_chip_gen_p5(qp->cctx)) {
1576 psns_ext->opcode_start_psn = cpu_to_le32(op_spsn);1568 psns_ext->opcode_start_psn = cpu_to_le32(op_spsn);
1577 psns_ext->flags_next_psn = cpu_to_le32(flg_npsn);1569 psns_ext->flags_next_psn = cpu_to_le32(flg_npsn);
1570 psns_ext->start_slot_idx = cpu_to_le16(swq->slot_idx);
1578 } else {1571 } else {
1579 psns->opcode_start_psn = cpu_to_le32(op_spsn);1572 psns->opcode_start_psn = cpu_to_le32(op_spsn);
1580 psns->flags_next_psn = cpu_to_le32(flg_npsn);1573 psns->flags_next_psn = cpu_to_le32(flg_npsn);
1581 }1574 }
1582}1575}
1583 1576
1577static int bnxt_qplib_put_inline(struct bnxt_qplib_qp *qp,
1578 struct bnxt_qplib_swqe *wqe,
1579 u16 *idx)
1580{
1581 struct bnxt_qplib_hwq *hwq;
1582 int len, t_len, offt;
1583 bool pull_dst = true;
1584 void *il_dst = NULL;
1585 void *il_src = NULL;
1586 int t_cplen, cplen;
1587 int indx;
1588
1589 hwq = &qp->sq.hwq;
1590 t_len = 0;
1591 for (indx = 0; indx < wqe->num_sge; indx++) {
1592 len = wqe->sg_list[indx].size;
1593 il_src = (void *)wqe->sg_list[indx].addr;
1594 t_len += len;
1595 if (t_len > qp->max_inline_data)
1596 goto bad;
1597 while (len) {
1598 if (pull_dst) {
1599 pull_dst = false;
1600 il_dst = bnxt_qplib_get_prod_qe(hwq, *idx);
1601 (*idx)++;
1602 t_cplen = 0;
1603 offt = 0;
1604 }
1605 cplen = min_t(int, len, sizeof(struct sq_sge));
1606 cplen = min_t(int, cplen,
1607 (sizeof(struct sq_sge) - offt));
1608 memcpy(il_dst, il_src, cplen);
1609 t_cplen += cplen;
1610 il_src += cplen;
1611 il_dst += cplen;
1612 offt += cplen;
1613 len -= cplen;
1614 if (t_cplen == sizeof(struct sq_sge))
1615 pull_dst = true;
1616 }
1617 }
1618
1619 return t_len;
1620bad:
1621 return -ENOMEM;
1622}
1623
1624static u32 bnxt_qplib_put_sges(struct bnxt_qplib_hwq *hwq,
1625 struct bnxt_qplib_sge *ssge,
1626 u16 nsge, u16 *idx)
1627{
1628 struct sq_sge *dsge;
1629 int indx, len = 0;
1630
1631 for (indx = 0; indx < nsge; indx++, (*idx)++) {
1632 dsge = bnxt_qplib_get_prod_qe(hwq, *idx);
1633 dsge->va_or_pa = cpu_to_le64(ssge[indx].addr);
1634 dsge->l_key = cpu_to_le32(ssge[indx].lkey);
1635 dsge->size = cpu_to_le32(ssge[indx].size);
1636 len += ssge[indx].size;
1637 }
1638
1639 return len;
1640}
1641
1642static u16 bnxt_qplib_required_slots(struct bnxt_qplib_qp *qp,
1643 struct bnxt_qplib_swqe *wqe,
1644 u16 *wqe_sz, u16 *qdf, u8 mode)
1645{
1646 u32 ilsize, bytes;
1647 u16 nsge;
1648 u16 slot;
1649
1650 nsge = wqe->num_sge;
1651 /* Adding sq_send_hdr is a misnomer, for rq also hdr size is same. */
1652 bytes = sizeof(struct sq_send_hdr) + nsge * sizeof(struct sq_sge);
1653 if (wqe->flags & BNXT_QPLIB_SWQE_FLAGS_INLINE) {
1654 ilsize = bnxt_qplib_calc_ilsize(wqe, qp->max_inline_data);
1655 bytes = ALIGN(ilsize, sizeof(struct sq_sge));
1656 bytes += sizeof(struct sq_send_hdr);
1657 }
1658
1659 *qdf = __xlate_qfd(qp->sq.q_full_delta, bytes);
1660 slot = bytes >> 4;
1661 *wqe_sz = slot;
1662 if (mode == BNXT_QPLIB_WQE_MODE_STATIC)
1663 slot = 8;
1664 return slot;
1665}
1666
1667static void bnxt_qplib_pull_psn_buff(struct bnxt_qplib_q *sq,
1668 struct bnxt_qplib_swq *swq)
1669{
1670 struct bnxt_qplib_hwq *hwq;
1671 u32 pg_num, pg_indx;
1672 void *buff;
1673 u32 tail;
1674
1675 hwq = &sq->hwq;
1676 if (!hwq->pad_pg)
1677 return;
1678 tail = swq->slot_idx / sq->dbinfo.max_slot;
1679 pg_num = (tail + hwq->pad_pgofft) / (PAGE_SIZE / hwq->pad_stride);
1680 pg_indx = (tail + hwq->pad_pgofft) % (PAGE_SIZE / hwq->pad_stride);
1681 buff = (void *)(hwq->pad_pg[pg_num] + pg_indx * hwq->pad_stride);
1682 swq->psn_ext = buff;
1683 swq->psn_search = buff;
1684}
1685
1584void bnxt_qplib_post_send_db(struct bnxt_qplib_qp *qp)1686void bnxt_qplib_post_send_db(struct bnxt_qplib_qp *qp)
1585{1687{
1586 struct bnxt_qplib_q *sq = &qp->sq;1688 struct bnxt_qplib_q *sq = &qp->sq;
@@ -1594,88 +1696,84 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp, · 7 unmodified lines
1594 struct bnxt_qplib_nq_work *nq_work = NULL;1696 struct bnxt_qplib_nq_work *nq_work = NULL;
1595 int i, rc = 0, data_len = 0, pkt_num = 0;1697 int i, rc = 0, data_len = 0, pkt_num = 0;
1596 struct bnxt_qplib_q *sq = &qp->sq;1698 struct bnxt_qplib_q *sq = &qp->sq;
1597 struct sq_send *hw_sq_send_hdr;1699 struct bnxt_qplib_hwq *hwq;
1598 struct bnxt_qplib_swq *swq;1700 struct bnxt_qplib_swq *swq;
1599 bool sch_handler = false;1701 bool sch_handler = false;
1600 struct sq_sge *hw_sge;1702 u16 wqe_sz, qdf = 0;
1601 u8 wqe_size16;1703 void *base_hdr;
1704 void *ext_hdr;
1602 __le32 temp32;1705 __le32 temp32;
1603 u32 sw_prod;1706 u32 wqe_idx;
1707 u32 slots;
1708 u16 idx;
1604 1709
1605 if (qp->state != CMDQ_MODIFY_QP_NEW_STATE_RTS) {1710 hwq = &sq->hwq;
1606 if (qp->state == CMDQ_MODIFY_QP_NEW_STATE_ERR) {1711 if (qp->state != CMDQ_MODIFY_QP_NEW_STATE_RTS &&
1607 sch_handler = true;1712 qp->state != CMDQ_MODIFY_QP_NEW_STATE_ERR) {
1608 dev_dbg(&sq->hwq.pdev->dev,1713 dev_err(&hwq->pdev->dev,
1609 "%s Error QP. Scheduling for poll_cq\n",1714 "QPLIB: FP: QP (0x%x) is in the 0x%x state",
1610 __func__);1715 qp->id, qp->state);
1611 goto queue_err;1716 rc = -EINVAL;
1612 }1717 goto done;
1613 }1718 }
1614 1719
1615 if (bnxt_qplib_queue_full(sq)) {1720 slots = bnxt_qplib_required_slots(qp, wqe, &wqe_sz, &qdf, qp->wqe_mode);
1616 dev_err(&sq->hwq.pdev->dev,1721 if (bnxt_qplib_queue_full(sq, slots + qdf)) {
1722 dev_err(&hwq->pdev->dev,
1617 "prod = %#x cons = %#x qdepth = %#x delta = %#x\n",1723 "prod = %#x cons = %#x qdepth = %#x delta = %#x\n",
1618 sq->hwq.prod, sq->hwq.cons, sq->hwq.max_elements,1724 hwq->prod, hwq->cons, hwq->depth, sq->q_full_delta);
1619 sq->q_full_delta);
1620 rc = -ENOMEM;1725 rc = -ENOMEM;
1621 goto done;1726 goto done;
1622 }1727 }
1623 sw_prod = HWQ_CMP(sq->hwq.prod, &sq->hwq);1728
1624 swq = &sq->swq[sw_prod];1729 swq = bnxt_qplib_get_swqe(sq, &wqe_idx);
1730 bnxt_qplib_pull_psn_buff(sq, swq);
1731
1732 idx = 0;
1733 swq->slot_idx = hwq->prod;
1734 swq->slots = slots;
1625 swq->wr_id = wqe->wr_id;1735 swq->wr_id = wqe->wr_id;
1626 swq->type = wqe->type;1736 swq->type = wqe->type;
1627 swq->flags = wqe->flags;1737 swq->flags = wqe->flags;
1738 swq->start_psn = sq->psn & BTH_PSN_MASK;
1628 if (qp->sig_type)1739 if (qp->sig_type)
1629 swq->flags |= SQ_SEND_FLAGS_SIGNAL_COMP;1740 swq->flags |= SQ_SEND_FLAGS_SIGNAL_COMP;
1630 swq->start_psn = sq->psn & BTH_PSN_MASK;
1631
1632 hw_sq_send_hdr = bnxt_qplib_get_qe(&sq->hwq, sw_prod, NULL);
1633 memset(hw_sq_send_hdr, 0, sq->wqe_size);
1634 1741
1635 if (wqe->flags & BNXT_QPLIB_SWQE_FLAGS_INLINE) {1742 if (qp->state == CMDQ_MODIFY_QP_NEW_STATE_ERR) {
1636 /* Copy the inline data */1743 sch_handler = true;
1637 if (wqe->inline_len > BNXT_QPLIB_SWQE_MAX_INLINE_LENGTH) {1744 dev_dbg(&hwq->pdev->dev,
1638 dev_warn(&sq->hwq.pdev->dev,1745 "%s Error QP. Scheduling for poll_cq\n", __func__);
1639 "Inline data length > 96 detected\n");1746 goto queue_err;
1640 data_len = BNXT_QPLIB_SWQE_MAX_INLINE_LENGTH;
1641 } else {
1642 data_len = wqe->inline_len;
1643 }
1644 memcpy(hw_sq_send_hdr->data, wqe->inline_data, data_len);
1645 wqe_size16 = (data_len + 15) >> 4;
1646 } else {
1647 for (i = 0, hw_sge = (struct sq_sge *)hw_sq_send_hdr->data;
1648 i < wqe->num_sge; i++, hw_sge++) {
1649 hw_sge->va_or_pa = cpu_to_le64(wqe->sg_list[i].addr);
1650 hw_sge->l_key = cpu_to_le32(wqe->sg_list[i].lkey);
1651 hw_sge->size = cpu_to_le32(wqe->sg_list[i].size);
1652 data_len += wqe->sg_list[i].size;
1653 }
1654 /* Each SGE entry = 1 WQE size16 */
1655 wqe_size16 = wqe->num_sge;
1656 /* HW requires wqe size has room for atleast one SGE even if
1657 * none was supplied by ULP
1658 */
1659 if (!wqe->num_sge)
1660 wqe_size16++;
1661 }1747 }
1662 1748
1749 base_hdr = bnxt_qplib_get_prod_qe(hwq, idx++);
1750 ext_hdr = bnxt_qplib_get_prod_qe(hwq, idx++);
1751 memset(base_hdr, 0, sizeof(struct sq_sge));
1752 memset(ext_hdr, 0, sizeof(struct sq_sge));
1753
1754 if (wqe->flags & BNXT_QPLIB_SWQE_FLAGS_INLINE)
1755 /* Copy the inline data */
1756 data_len = bnxt_qplib_put_inline(qp, wqe, &idx);
1757 else
1758 data_len = bnxt_qplib_put_sges(hwq, wqe->sg_list, wqe->num_sge,
1759 &idx);
1760 if (data_len < 0)
1761 goto queue_err;
1663 /* Specifics */1762 /* Specifics */
1664 switch (wqe->type) {1763 switch (wqe->type) {
1665 case BNXT_QPLIB_SWQE_TYPE_SEND:1764 case BNXT_QPLIB_SWQE_TYPE_SEND:
1666 if (qp->type == CMDQ_CREATE_QP1_TYPE_GSI) {1765 if (qp->type == CMDQ_CREATE_QP1_TYPE_GSI) {
1766 struct sq_send_raweth_qp1_hdr *sqe = base_hdr;
1767 struct sq_raw_ext_hdr *ext_sqe = ext_hdr;
1667 /* Assemble info for Raw Ethertype QPs */1768 /* Assemble info for Raw Ethertype QPs */
1668 struct sq_send_raweth_qp1 *sqe =
1669 (struct sq_send_raweth_qp1 *)hw_sq_send_hdr;
1670 1769
1671 sqe->wqe_type = wqe->type;1770 sqe->wqe_type = wqe->type;
1672 sqe->flags = wqe->flags;1771 sqe->flags = wqe->flags;
1673 sqe->wqe_size = wqe_size16 +1772 sqe->wqe_size = wqe_sz;
1674 ((offsetof(typeof(*sqe), data) + 15) >> 4);
1675 sqe->cfa_action = cpu_to_le16(wqe->rawqp1.cfa_action);1773 sqe->cfa_action = cpu_to_le16(wqe->rawqp1.cfa_action);
1676 sqe->lflags = cpu_to_le16(wqe->rawqp1.lflags);1774 sqe->lflags = cpu_to_le16(wqe->rawqp1.lflags);
1677 sqe->length = cpu_to_le32(data_len);1775 sqe->length = cpu_to_le32(data_len);
1678 sqe->cfa_meta = cpu_to_le32((wqe->rawqp1.cfa_meta &1776 ext_sqe->cfa_meta = cpu_to_le32((wqe->rawqp1.cfa_meta &
1679 SQ_SEND_RAWETH_QP1_CFA_META_VLAN_VID_MASK) <<1777 SQ_SEND_RAWETH_QP1_CFA_META_VLAN_VID_MASK) <<
1680 SQ_SEND_RAWETH_QP1_CFA_META_VLAN_VID_SFT);1778 SQ_SEND_RAWETH_QP1_CFA_META_VLAN_VID_SFT);
1681 1779
@@ -1685,27 +1783,24 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp, · 3 unmodified lines
1685 case BNXT_QPLIB_SWQE_TYPE_SEND_WITH_IMM:1783 case BNXT_QPLIB_SWQE_TYPE_SEND_WITH_IMM:
1686 case BNXT_QPLIB_SWQE_TYPE_SEND_WITH_INV:1784 case BNXT_QPLIB_SWQE_TYPE_SEND_WITH_INV:
1687 {1785 {
1688 struct sq_send *sqe = (struct sq_send *)hw_sq_send_hdr;1786 struct sq_ud_ext_hdr *ext_sqe = ext_hdr;
1787 struct sq_send_hdr *sqe = base_hdr;
1689 1788
1690 sqe->wqe_type = wqe->type;1789 sqe->wqe_type = wqe->type;
1691 sqe->flags = wqe->flags;1790 sqe->flags = wqe->flags;
1692 sqe->wqe_size = wqe_size16 +1791 sqe->wqe_size = wqe_sz;
1693 ((offsetof(typeof(*sqe), data) + 15) >> 4);1792 sqe->inv_key_or_imm_data = cpu_to_le32(wqe->send.inv_key);
1694 sqe->inv_key_or_imm_data = cpu_to_le32(
1695 wqe->send.inv_key);
1696 if (qp->type == CMDQ_CREATE_QP_TYPE_UD ||1793 if (qp->type == CMDQ_CREATE_QP_TYPE_UD ||
1697 qp->type == CMDQ_CREATE_QP_TYPE_GSI) {1794 qp->type == CMDQ_CREATE_QP_TYPE_GSI) {
1698 sqe->q_key = cpu_to_le32(wqe->send.q_key);1795 sqe->q_key = cpu_to_le32(wqe->send.q_key);
1699 sqe->dst_qp = cpu_to_le32(
1700 wqe->send.dst_qp & SQ_SEND_DST_QP_MASK);
1701 sqe->length = cpu_to_le32(data_len);1796 sqe->length = cpu_to_le32(data_len);
1702 sqe->avid = cpu_to_le32(wqe->send.avid &
1703 SQ_SEND_AVID_MASK);
1704 sq->psn = (sq->psn + 1) & BTH_PSN_MASK;1797 sq->psn = (sq->psn + 1) & BTH_PSN_MASK;
1798 ext_sqe->dst_qp = cpu_to_le32(wqe->send.dst_qp &
1799 SQ_SEND_DST_QP_MASK);
1800 ext_sqe->avid = cpu_to_le32(wqe->send.avid &
1801 SQ_SEND_AVID_MASK);
1705 } else {1802 } else {
1706 sqe->length = cpu_to_le32(data_len);1803 sqe->length = cpu_to_le32(data_len);
1707 sqe->dst_qp = 0;
1708 sqe->avid = 0;
1709 if (qp->mtu)1804 if (qp->mtu)
1710 pkt_num = (data_len + qp->mtu - 1) / qp->mtu;1805 pkt_num = (data_len + qp->mtu - 1) / qp->mtu;
1711 if (!pkt_num)1806 if (!pkt_num)
@@ -1718,16 +1813,16 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp, · 6 unmodified lines
1718 case BNXT_QPLIB_SWQE_TYPE_RDMA_WRITE_WITH_IMM:1813 case BNXT_QPLIB_SWQE_TYPE_RDMA_WRITE_WITH_IMM:
1719 case BNXT_QPLIB_SWQE_TYPE_RDMA_READ:1814 case BNXT_QPLIB_SWQE_TYPE_RDMA_READ:
1720 {1815 {
1721 struct sq_rdma *sqe = (struct sq_rdma *)hw_sq_send_hdr;1816 struct sq_rdma_ext_hdr *ext_sqe = ext_hdr;
1817 struct sq_rdma_hdr *sqe = base_hdr;
1722 1818
1723 sqe->wqe_type = wqe->type;1819 sqe->wqe_type = wqe->type;
1724 sqe->flags = wqe->flags;1820 sqe->flags = wqe->flags;
1725 sqe->wqe_size = wqe_size16 +1821 sqe->wqe_size = wqe_sz;
1726 ((offsetof(typeof(*sqe), data) + 15) >> 4);
1727 sqe->imm_data = cpu_to_le32(wqe->rdma.inv_key);1822 sqe->imm_data = cpu_to_le32(wqe->rdma.inv_key);
1728 sqe->length = cpu_to_le32((u32)data_len);1823 sqe->length = cpu_to_le32((u32)data_len);
1729 sqe->remote_va = cpu_to_le64(wqe->rdma.remote_va);1824 ext_sqe->remote_va = cpu_to_le64(wqe->rdma.remote_va);
1730 sqe->remote_key = cpu_to_le32(wqe->rdma.r_key);1825 ext_sqe->remote_key = cpu_to_le32(wqe->rdma.r_key);
1731 if (qp->mtu)1826 if (qp->mtu)
1732 pkt_num = (data_len + qp->mtu - 1) / qp->mtu;1827 pkt_num = (data_len + qp->mtu - 1) / qp->mtu;
1733 if (!pkt_num)1828 if (!pkt_num)
@@ -1738,14 +1833,15 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp, · 4 unmodified lines
1738 case BNXT_QPLIB_SWQE_TYPE_ATOMIC_CMP_AND_SWP:1833 case BNXT_QPLIB_SWQE_TYPE_ATOMIC_CMP_AND_SWP:
1739 case BNXT_QPLIB_SWQE_TYPE_ATOMIC_FETCH_AND_ADD:1834 case BNXT_QPLIB_SWQE_TYPE_ATOMIC_FETCH_AND_ADD:
1740 {1835 {
1741 struct sq_atomic *sqe = (struct sq_atomic *)hw_sq_send_hdr;1836 struct sq_atomic_ext_hdr *ext_sqe = ext_hdr;
1837 struct sq_atomic_hdr *sqe = base_hdr;
1742 1838
1743 sqe->wqe_type = wqe->type;1839 sqe->wqe_type = wqe->type;
1744 sqe->flags = wqe->flags;1840 sqe->flags = wqe->flags;
1745 sqe->remote_key = cpu_to_le32(wqe->atomic.r_key);1841 sqe->remote_key = cpu_to_le32(wqe->atomic.r_key);
1746 sqe->remote_va = cpu_to_le64(wqe->atomic.remote_va);1842 sqe->remote_va = cpu_to_le64(wqe->atomic.remote_va);
1747 sqe->swap_data = cpu_to_le64(wqe->atomic.swap_data);1843 ext_sqe->swap_data = cpu_to_le64(wqe->atomic.swap_data);
1748 sqe->cmp_data = cpu_to_le64(wqe->atomic.cmp_data);1844 ext_sqe->cmp_data = cpu_to_le64(wqe->atomic.cmp_data);
1749 if (qp->mtu)1845 if (qp->mtu)
1750 pkt_num = (data_len + qp->mtu - 1) / qp->mtu;1846 pkt_num = (data_len + qp->mtu - 1) / qp->mtu;
1751 if (!pkt_num)1847 if (!pkt_num)
@@ -1755,8 +1851,7 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp, · 3 unmodified lines
1755 }1851 }
1756 case BNXT_QPLIB_SWQE_TYPE_LOCAL_INV:1852 case BNXT_QPLIB_SWQE_TYPE_LOCAL_INV:
1757 {1853 {
1758 struct sq_localinvalidate *sqe =1854 struct sq_localinvalidate *sqe = base_hdr;
1759 (struct sq_localinvalidate *)hw_sq_send_hdr;
1760 1855
1761 sqe->wqe_type = wqe->type;1856 sqe->wqe_type = wqe->type;
1762 sqe->flags = wqe->flags;1857 sqe->flags = wqe->flags;
@@ -1766,7 +1861,8 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp, · 3 unmodified lines
1766 }1861 }
1767 case BNXT_QPLIB_SWQE_TYPE_FAST_REG_MR:1862 case BNXT_QPLIB_SWQE_TYPE_FAST_REG_MR:
1768 {1863 {
1769 struct sq_fr_pmr *sqe = (struct sq_fr_pmr *)hw_sq_send_hdr;1864 struct sq_fr_pmr_ext_hdr *ext_sqe = ext_hdr;
1865 struct sq_fr_pmr_hdr *sqe = base_hdr;
1770 1866
1771 sqe->wqe_type = wqe->type;1867 sqe->wqe_type = wqe->type;
1772 sqe->flags = wqe->flags;1868 sqe->flags = wqe->flags;
@@ -1790,14 +1886,15 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp, · 17 unmodified lines
1790 wqe->frmr.pbl_ptr[i] = cpu_to_le64(1886 wqe->frmr.pbl_ptr[i] = cpu_to_le64(
1791 wqe->frmr.page_list[i] |1887 wqe->frmr.page_list[i] |
1792 PTU_PTE_VALID);1888 PTU_PTE_VALID);
1793 sqe->pblptr = cpu_to_le64(wqe->frmr.pbl_dma_ptr);1889 ext_sqe->pblptr = cpu_to_le64(wqe->frmr.pbl_dma_ptr);
1794 sqe->va = cpu_to_le64(wqe->frmr.va);1890 ext_sqe->va = cpu_to_le64(wqe->frmr.va);
1795 1891
1796 break;1892 break;
1797 }1893 }
1798 case BNXT_QPLIB_SWQE_TYPE_BIND_MW:1894 case BNXT_QPLIB_SWQE_TYPE_BIND_MW:
1799 {1895 {
1800 struct sq_bind *sqe = (struct sq_bind *)hw_sq_send_hdr;1896 struct sq_bind_ext_hdr *ext_sqe = ext_hdr;
1897 struct sq_bind_hdr *sqe = base_hdr;
1801 1898
1802 sqe->wqe_type = wqe->type;1899 sqe->wqe_type = wqe->type;
1803 sqe->flags = wqe->flags;1900 sqe->flags = wqe->flags;
@@ -1806,9 +1903,8 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp, · 2 unmodified lines
1806 (wqe->bind.zero_based ? SQ_BIND_ZERO_BASED : 0);1903 (wqe->bind.zero_based ? SQ_BIND_ZERO_BASED : 0);
1807 sqe->parent_l_key = cpu_to_le32(wqe->bind.parent_l_key);1904 sqe->parent_l_key = cpu_to_le32(wqe->bind.parent_l_key);
1808 sqe->l_key = cpu_to_le32(wqe->bind.r_key);1905 sqe->l_key = cpu_to_le32(wqe->bind.r_key);
1809 sqe->va = cpu_to_le64(wqe->bind.va);1906 ext_sqe->va = cpu_to_le64(wqe->bind.va);
1810 temp32 = cpu_to_le32(wqe->bind.length);1907 ext_sqe->length_lo = cpu_to_le32(wqe->bind.length);
1811 memcpy(&sqe->length, &temp32, sizeof(wqe->bind.length));
1812 break;1908 break;
1813 }1909 }
1814 default:1910 default:
@@ -1817,23 +1913,11 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp, · 2 unmodified lines
1817 goto done;1913 goto done;
1818 }1914 }
1819 swq->next_psn = sq->psn & BTH_PSN_MASK;1915 swq->next_psn = sq->psn & BTH_PSN_MASK;
1820 if (qp->type == CMDQ_CREATE_QP_TYPE_RC)1916 bnxt_qplib_fill_psn_search(qp, wqe, swq);
1821 bnxt_qplib_fill_psn_search(qp, wqe, swq);
1822queue_err:1917queue_err:
1823 if (sch_handler) {1918 bnxt_qplib_swq_mod_start(sq, wqe_idx);
1824 /* Store the ULP info in the software structures */1919 bnxt_qplib_hwq_incr_prod(hwq, swq->slots);
1825 sw_prod = HWQ_CMP(sq->hwq.prod, &sq->hwq);
1826 swq = &sq->swq[sw_prod];
1827 swq->wr_id = wqe->wr_id;
1828 swq->type = wqe->type;
1829 swq->flags = wqe->flags;
1830 if (qp->sig_type)
1831 swq->flags |= SQ_SEND_FLAGS_SIGNAL_COMP;
1832 swq->start_psn = sq->psn & BTH_PSN_MASK;
1833 }
1834 sq->hwq.prod++;
1835 qp->wqe_cnt++;1920 qp->wqe_cnt++;
1836
1837done:1921done:
1838 if (sch_handler) {1922 if (sch_handler) {
1839 nq_work = kzalloc(sizeof(*nq_work), GFP_ATOMIC);1923 nq_work = kzalloc(sizeof(*nq_work), GFP_ATOMIC);
@@ -1843,7 +1927,7 @@ done: · 3 unmodified lines
1843 INIT_WORK(&nq_work->work, bnxt_qpn_cqn_sched_task);1927 INIT_WORK(&nq_work->work, bnxt_qpn_cqn_sched_task);
1844 queue_work(qp->scq->nq->cqn_wq, &nq_work->work);1928 queue_work(qp->scq->nq->cqn_wq, &nq_work->work);
1845 } else {1929 } else {
1846 dev_err(&sq->hwq.pdev->dev,1930 dev_err(&hwq->pdev->dev,
1847 "FP: Failed to allocate SQ nq_work!\n");1931 "FP: Failed to allocate SQ nq_work!\n");
1848 rc = -ENOMEM;1932 rc = -ENOMEM;
1849 }1933 }
@@ -1863,58 +1947,65 @@ int bnxt_qplib_post_recv(struct bnxt_qplib_qp *qp, · 13 unmodified lines
1863{1947{
1864 struct bnxt_qplib_nq_work *nq_work = NULL;1948 struct bnxt_qplib_nq_work *nq_work = NULL;
1865 struct bnxt_qplib_q *rq = &qp->rq;1949 struct bnxt_qplib_q *rq = &qp->rq;
1950 struct rq_wqe_hdr *base_hdr;
1951 struct rq_ext_hdr *ext_hdr;
1952 struct bnxt_qplib_hwq *hwq;
1953 struct bnxt_qplib_swq *swq;
1866 bool sch_handler = false;1954 bool sch_handler = false;
1867 struct sq_sge *hw_sge;1955 u16 wqe_sz, idx;
1868 struct rq_wqe *rqe;1956 u32 wqe_idx;
1869 int i, rc = 0;1957 int rc = 0;
1870 u32 sw_prod;
1871 1958
1872 if (qp->state == CMDQ_MODIFY_QP_NEW_STATE_ERR) {1959 hwq = &rq->hwq;
1873 sch_handler = true;1960 if (qp->state == CMDQ_MODIFY_QP_NEW_STATE_RESET) {
1874 dev_dbg(&rq->hwq.pdev->dev,1961 dev_err(&hwq->pdev->dev,
1875 "%s: Error QP. Scheduling for poll_cq\n", __func__);1962 "QPLIB: FP: QP (0x%x) is in the 0x%x state",
1876 goto queue_err;1963 qp->id, qp->state);
1964 rc = -EINVAL;
1965 goto done;
1877 }1966 }
1878 if (bnxt_qplib_queue_full(rq)) {1967
1879 dev_err(&rq->hwq.pdev->dev,1968 if (bnxt_qplib_queue_full(rq, rq->dbinfo.max_slot)) {
1969 dev_err(&hwq->pdev->dev,
1880 "FP: QP (0x%x) RQ is full!\n", qp->id);1970 "FP: QP (0x%x) RQ is full!\n", qp->id);
1881 rc = -EINVAL;1971 rc = -EINVAL;
1882 goto done;1972 goto done;
1883 }1973 }
1884 sw_prod = HWQ_CMP(rq->hwq.prod, &rq->hwq);
1885 rq->swq[sw_prod].wr_id = wqe->wr_id;
1886 1974
1887 rqe = bnxt_qplib_get_qe(&rq->hwq, sw_prod, NULL);1975 swq = bnxt_qplib_get_swqe(rq, &wqe_idx);
1888 memset(rqe, 0, rq->wqe_size);1976 swq->wr_id = wqe->wr_id;
1977 swq->slots = rq->dbinfo.max_slot;
1889 1978
1890 /* Calculate wqe_size16 and data_len */1979 if (qp->state == CMDQ_MODIFY_QP_NEW_STATE_ERR) {
1891 for (i = 0, hw_sge = (struct sq_sge *)rqe->data;1980 sch_handler = true;
1892 i < wqe->num_sge; i++, hw_sge++) {1981 dev_dbg(&hwq->pdev->dev,
1893 hw_sge->va_or_pa = cpu_to_le64(wqe->sg_list[i].addr);1982 "%s: Error QP. Scheduling for poll_cq\n", __func__);
1894 hw_sge->l_key = cpu_to_le32(wqe->sg_list[i].lkey);1983 goto queue_err;
1895 hw_sge->size = cpu_to_le32(wqe->sg_list[i].size);
1896 }1984 }
1897 rqe->wqe_type = wqe->type;
1898 rqe->flags = wqe->flags;
1899 rqe->wqe_size = wqe->num_sge +
1900 ((offsetof(typeof(*rqe), data) + 15) >> 4);
1901 /* HW requires wqe size has room for atleast one SGE even if none
1902 * was supplied by ULP
1903 */
1904 if (!wqe->num_sge)
1905 rqe->wqe_size++;
1906
1907 /* Supply the rqe->wr_id index to the wr_id_tbl for now */
1908 rqe->wr_id[0] = cpu_to_le32(sw_prod);
1909 1985
1986 idx = 0;
1987 base_hdr = bnxt_qplib_get_prod_qe(hwq, idx++);
1988 ext_hdr = bnxt_qplib_get_prod_qe(hwq, idx++);
1989 memset(base_hdr, 0, sizeof(struct sq_sge));
1990 memset(ext_hdr, 0, sizeof(struct sq_sge));
1991 wqe_sz = (sizeof(struct rq_wqe_hdr) +
1992 wqe->num_sge * sizeof(struct sq_sge)) >> 4;
1993 bnxt_qplib_put_sges(hwq, wqe->sg_list, wqe->num_sge, &idx);
1994 if (!wqe->num_sge) {
1995 struct sq_sge *sge;
1996
1997 sge = bnxt_qplib_get_prod_qe(hwq, idx++);
1998 sge->size = 0;
1999 wqe_sz++;
2000 }
2001 base_hdr->wqe_type = wqe->type;
2002 base_hdr->flags = wqe->flags;
2003 base_hdr->wqe_size = wqe_sz;
2004 base_hdr->wr_id[0] = cpu_to_le32(wqe_idx);
1910queue_err:2005queue_err:
1911 if (sch_handler) {2006 bnxt_qplib_swq_mod_start(rq, wqe_idx);
1912 /* Store the ULP info in the software structures */2007 bnxt_qplib_hwq_incr_prod(hwq, swq->slots);
1913 sw_prod = HWQ_CMP(rq->hwq.prod, &rq->hwq);2008done:
1914 rq->swq[sw_prod].wr_id = wqe->wr_id;
1915 }
1916
1917 rq->hwq.prod++;
1918 if (sch_handler) {2009 if (sch_handler) {
1919 nq_work = kzalloc(sizeof(*nq_work), GFP_ATOMIC);2010 nq_work = kzalloc(sizeof(*nq_work), GFP_ATOMIC);
1920 if (nq_work) {2011 if (nq_work) {
@@ -1923,12 +2014,12 @@ queue_err: · 2 unmodified lines
1923 INIT_WORK(&nq_work->work, bnxt_qpn_cqn_sched_task);2014 INIT_WORK(&nq_work->work, bnxt_qpn_cqn_sched_task);
1924 queue_work(qp->rcq->nq->cqn_wq, &nq_work->work);2015 queue_work(qp->rcq->nq->cqn_wq, &nq_work->work);
1925 } else {2016 } else {
1926 dev_err(&rq->hwq.pdev->dev,2017 dev_err(&hwq->pdev->dev,
1927 "FP: Failed to allocate RQ nq_work!\n");2018 "FP: Failed to allocate RQ nq_work!\n");
1928 rc = -ENOMEM;2019 rc = -ENOMEM;
1929 }2020 }
1930 }2021 }
1931done:2022
1932 return rc;2023 return rc;
1933}2024}
1934 2025
@@ -2026,20 +2117,19 @@ int bnxt_qplib_destroy_cq(struct bnxt_qplib_res *res, struct bnxt_qplib_cq *cq) · 91 unmodified lines
2026static int __flush_sq(struct bnxt_qplib_q *sq, struct bnxt_qplib_qp *qp,2117static int __flush_sq(struct bnxt_qplib_q *sq, struct bnxt_qplib_qp *qp,
2027 struct bnxt_qplib_cqe **pcqe, int *budget)2118 struct bnxt_qplib_cqe **pcqe, int *budget)
2028{2119{
2029 u32 sw_prod, sw_cons;
2030 struct bnxt_qplib_cqe *cqe;2120 struct bnxt_qplib_cqe *cqe;
2121 u32 start, last;
2031 int rc = 0;2122 int rc = 0;
2032 2123
2033 /* Now complete all outstanding SQEs with FLUSHED_ERR */2124 /* Now complete all outstanding SQEs with FLUSHED_ERR */
2034 sw_prod = HWQ_CMP(sq->hwq.prod, &sq->hwq);2125 start = sq->swq_start;
2035 cqe = *pcqe;2126 cqe = *pcqe;
2036 while (*budget) {2127 while (*budget) {
2037 sw_cons = HWQ_CMP(sq->hwq.cons, &sq->hwq);2128 last = sq->swq_last;
2038 if (sw_cons == sw_prod) {2129 if (start == last)
2039 break;2130 break;
2040 }
2041 /* Skip the FENCE WQE completions */2131 /* Skip the FENCE WQE completions */
2042 if (sq->swq[sw_cons].wr_id == BNXT_QPLIB_FENCE_WRID) {2132 if (sq->swq[last].wr_id == BNXT_QPLIB_FENCE_WRID) {
2043 bnxt_qplib_cancel_phantom_processing(qp);2133 bnxt_qplib_cancel_phantom_processing(qp);
2044 goto skip_compl;2134 goto skip_compl;
2045 }2135 }
@@ -2047,16 +2137,17 @@ static int __flush_sq(struct bnxt_qplib_q *sq, struct bnxt_qplib_qp *qp, · 1 unmodified line
2047 cqe->status = CQ_REQ_STATUS_WORK_REQUEST_FLUSHED_ERR;2137 cqe->status = CQ_REQ_STATUS_WORK_REQUEST_FLUSHED_ERR;
2048 cqe->opcode = CQ_BASE_CQE_TYPE_REQ;2138 cqe->opcode = CQ_BASE_CQE_TYPE_REQ;
2049 cqe->qp_handle = (u64)(unsigned long)qp;2139 cqe->qp_handle = (u64)(unsigned long)qp;
2050 cqe->wr_id = sq->swq[sw_cons].wr_id;2140 cqe->wr_id = sq->swq[last].wr_id;
2051 cqe->src_qp = qp->id;2141 cqe->src_qp = qp->id;
2052 cqe->type = sq->swq[sw_cons].type;2142 cqe->type = sq->swq[last].type;
2053 cqe++;2143 cqe++;
2054 (*budget)--;2144 (*budget)--;
2055skip_compl:2145skip_compl:
2056 sq->hwq.cons++;2146 bnxt_qplib_hwq_incr_cons(&sq->hwq, sq->swq[last].slots);
2147 sq->swq_last = sq->swq[last].next_idx;
2057 }2148 }
2058 *pcqe = cqe;2149 *pcqe = cqe;
2059 if (!(*budget) && HWQ_CMP(sq->hwq.cons, &sq->hwq) != sw_prod)2150 if (!(*budget) && sq->swq_last != start)
2060 /* Out of budget */2151 /* Out of budget */
2061 rc = -EAGAIN;2152 rc = -EAGAIN;
2062 2153
@@ -2067,9 +2158,9 @@ static int __flush_rq(struct bnxt_qplib_q *rq, struct bnxt_qplib_qp *qp, · 4 unmodified lines
2067 struct bnxt_qplib_cqe **pcqe, int *budget)2158 struct bnxt_qplib_cqe **pcqe, int *budget)
2068{2159{
2069 struct bnxt_qplib_cqe *cqe;2160 struct bnxt_qplib_cqe *cqe;
2070 u32 sw_prod, sw_cons;2161 u32 start, last;
2071 int rc = 0;
2072 int opcode = 0;2162 int opcode = 0;
2163 int rc = 0;
2073 2164
2074 switch (qp->type) {2165 switch (qp->type) {
2075 case CMDQ_CREATE_QP1_TYPE_GSI:2166 case CMDQ_CREATE_QP1_TYPE_GSI:
@@ -2085,24 +2176,25 @@ static int __flush_rq(struct bnxt_qplib_q *rq, struct bnxt_qplib_qp *qp, · 9 unmodified lines
2085 }2176 }
2086 2177
2087 /* Flush the rest of the RQ */2178 /* Flush the rest of the RQ */
2088 sw_prod = HWQ_CMP(rq->hwq.prod, &rq->hwq);2179 start = rq->swq_start;
2089 cqe = *pcqe;2180 cqe = *pcqe;
2090 while (*budget) {2181 while (*budget) {
2091 sw_cons = HWQ_CMP(rq->hwq.cons, &rq->hwq);2182 last = rq->swq_last;
2092 if (sw_cons == sw_prod)2183 if (last == start)
2093 break;2184 break;
2094 memset(cqe, 0, sizeof(*cqe));2185 memset(cqe, 0, sizeof(*cqe));
2095 cqe->status =2186 cqe->status =
2096 CQ_RES_RC_STATUS_WORK_REQUEST_FLUSHED_ERR;2187 CQ_RES_RC_STATUS_WORK_REQUEST_FLUSHED_ERR;
2097 cqe->opcode = opcode;2188 cqe->opcode = opcode;
2098 cqe->qp_handle = (unsigned long)qp;2189 cqe->qp_handle = (unsigned long)qp;
2099 cqe->wr_id = rq->swq[sw_cons].wr_id;2190 cqe->wr_id = rq->swq[last].wr_id;
2100 cqe++;2191 cqe++;
2101 (*budget)--;2192 (*budget)--;
2102 rq->hwq.cons++;2193 bnxt_qplib_hwq_incr_cons(&rq->hwq, rq->swq[last].slots);
2194 rq->swq_last = rq->swq[last].next_idx;
2103 }2195 }
2104 *pcqe = cqe;2196 *pcqe = cqe;
2105 if (!*budget && HWQ_CMP(rq->hwq.cons, &rq->hwq) != sw_prod)2197 if (!*budget && rq->swq_last != start)
2106 /* Out of budget */2198 /* Out of budget */
2107 rc = -EAGAIN;2199 rc = -EAGAIN;
2108 2200
@@ -2125,7 +2217,7 @@ void bnxt_qplib_mark_qp_error(void *qp_handle) · 16 unmodified lines
2125 * CQE is track from sw_cq_cons to max_element but valid only if VALID=12217 * CQE is track from sw_cq_cons to max_element but valid only if VALID=1
2126 */2218 */
2127static int do_wa9060(struct bnxt_qplib_qp *qp, struct bnxt_qplib_cq *cq,2219static int do_wa9060(struct bnxt_qplib_qp *qp, struct bnxt_qplib_cq *cq,
2128 u32 cq_cons, u32 sw_sq_cons, u32 cqe_sq_cons)2220 u32 cq_cons, u32 swq_last, u32 cqe_sq_cons)
2129{2221{
2130 u32 peek_sw_cq_cons, peek_raw_cq_cons, peek_sq_cons_idx;2222 u32 peek_sw_cq_cons, peek_raw_cq_cons, peek_sq_cons_idx;
2131 struct bnxt_qplib_q *sq = &qp->sq;2223 struct bnxt_qplib_q *sq = &qp->sq;
@@ -2138,7 +2230,7 @@ static int do_wa9060(struct bnxt_qplib_qp *qp, struct bnxt_qplib_cq *cq, · 6 unmodified lines
2138 2230
2139 /* Normal mode */2231 /* Normal mode */
2140 /* Check for the psn_search marking before completing */2232 /* Check for the psn_search marking before completing */
2141 swq = &sq->swq[sw_sq_cons];2233 swq = &sq->swq[swq_last];
2142 if (swq->psn_search &&2234 if (swq->psn_search &&
2143 le32_to_cpu(swq->psn_search->flags_next_psn) & 0x80000000) {2235 le32_to_cpu(swq->psn_search->flags_next_psn) & 0x80000000) {
2144 /* Unmark */2236 /* Unmark */
@@ -2147,7 +2239,7 @@ static int do_wa9060(struct bnxt_qplib_qp *qp, struct bnxt_qplib_cq *cq, · 2 unmodified lines
2147 & ~0x80000000);2239 & ~0x80000000);
2148 dev_dbg(&cq->hwq.pdev->dev,2240 dev_dbg(&cq->hwq.pdev->dev,
2149 "FP: Process Req cq_cons=0x%x qp=0x%x sq cons sw=0x%x cqe=0x%x marked!\n",2241 "FP: Process Req cq_cons=0x%x qp=0x%x sq cons sw=0x%x cqe=0x%x marked!\n",
2150 cq_cons, qp->id, sw_sq_cons, cqe_sq_cons);2242 cq_cons, qp->id, swq_last, cqe_sq_cons);
2151 sq->condition = true;2243 sq->condition = true;
2152 sq->send_phantom = true;2244 sq->send_phantom = true;
2153 2245
@@ -2184,9 +2276,10 @@ static int do_wa9060(struct bnxt_qplib_qp *qp, struct bnxt_qplib_cq *cq, · 30 unmodified lines
2184 le64_to_cpu2276 le64_to_cpu
2185 (peek_req_hwcqe->qp_handle));2277 (peek_req_hwcqe->qp_handle));
2186 peek_sq = &peek_qp->sq;2278 peek_sq = &peek_qp->sq;
2187 peek_sq_cons_idx = HWQ_CMP(le16_to_cpu(2279 peek_sq_cons_idx =
2188 peek_req_hwcqe->sq_cons_idx) - 12280 ((le16_to_cpu(
2189 , &sq->hwq);2281 peek_req_hwcqe->sq_cons_idx)
2282 - 1) % sq->max_wqe);
2190 /* If the hwcqe's sq's wr_id matches */2283 /* If the hwcqe's sq's wr_id matches */
2191 if (peek_sq == sq &&2284 if (peek_sq == sq &&
2192 sq->swq[peek_sq_cons_idx].wr_id ==2285 sq->swq[peek_sq_cons_idx].wr_id ==
@@ -2214,7 +2307,7 @@ static int do_wa9060(struct bnxt_qplib_qp *qp, struct bnxt_qplib_cq *cq, · 21 unmodified lines
2214 }2307 }
2215 dev_err(&cq->hwq.pdev->dev,2308 dev_err(&cq->hwq.pdev->dev,
2216 "Should not have come here! cq_cons=0x%x qp=0x%x sq cons sw=0x%x hw=0x%x\n",2309 "Should not have come here! cq_cons=0x%x qp=0x%x sq cons sw=0x%x hw=0x%x\n",
2217 cq_cons, qp->id, sw_sq_cons, cqe_sq_cons);2310 cq_cons, qp->id, swq_last, cqe_sq_cons);
2218 rc = -EINVAL;2311 rc = -EINVAL;
2219 }2312 }
2220out:2313out:
@@ -2226,11 +2319,11 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq, · 5 unmodified lines
2226 struct bnxt_qplib_cqe **pcqe, int *budget,2319 struct bnxt_qplib_cqe **pcqe, int *budget,
2227 u32 cq_cons, struct bnxt_qplib_qp **lib_qp)2320 u32 cq_cons, struct bnxt_qplib_qp **lib_qp)
2228{2321{
2229 u32 sw_sq_cons, cqe_sq_cons;
2230 struct bnxt_qplib_swq *swq;2322 struct bnxt_qplib_swq *swq;
2231 struct bnxt_qplib_cqe *cqe;2323 struct bnxt_qplib_cqe *cqe;
2232 struct bnxt_qplib_qp *qp;2324 struct bnxt_qplib_qp *qp;
2233 struct bnxt_qplib_q *sq;2325 struct bnxt_qplib_q *sq;
2326 u32 cqe_sq_cons;
2234 int rc = 0;2327 int rc = 0;
2235 2328
2236 qp = (struct bnxt_qplib_qp *)((unsigned long)2329 qp = (struct bnxt_qplib_qp *)((unsigned long)
@@ -2242,14 +2335,7 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq, · 5 unmodified lines
2242 }2335 }
2243 sq = &qp->sq;2336 sq = &qp->sq;
2244 2337
2245 cqe_sq_cons = HWQ_CMP(le16_to_cpu(hwcqe->sq_cons_idx), &sq->hwq);2338 cqe_sq_cons = le16_to_cpu(hwcqe->sq_cons_idx) % sq->max_wqe;
2246 if (cqe_sq_cons > sq->hwq.max_elements) {
2247 dev_err(&cq->hwq.pdev->dev,
2248 "FP: CQ Process req reported sq_cons_idx 0x%x which exceeded max 0x%x\n",
2249 cqe_sq_cons, sq->hwq.max_elements);
2250 return -EINVAL;
2251 }
2252
2253 if (qp->sq.flushed) {2339 if (qp->sq.flushed) {
2254 dev_dbg(&cq->hwq.pdev->dev,2340 dev_dbg(&cq->hwq.pdev->dev,
2255 "%s: QP in Flush QP = %p\n", __func__, qp);2341 "%s: QP in Flush QP = %p\n", __func__, qp);
@@ -2261,12 +2347,11 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq, · 5 unmodified lines
2261 */2347 */
2262 cqe = *pcqe;2348 cqe = *pcqe;
2263 while (*budget) {2349 while (*budget) {
2264 sw_sq_cons = HWQ_CMP(sq->hwq.cons, &sq->hwq);2350 if (sq->swq_last == cqe_sq_cons)
2265 if (sw_sq_cons == cqe_sq_cons)
2266 /* Done */2351 /* Done */
2267 break;2352 break;
2268 2353
2269 swq = &sq->swq[sw_sq_cons];2354 swq = &sq->swq[sq->swq_last];
2270 memset(cqe, 0, sizeof(*cqe));2355 memset(cqe, 0, sizeof(*cqe));
2271 cqe->opcode = CQ_BASE_CQE_TYPE_REQ;2356 cqe->opcode = CQ_BASE_CQE_TYPE_REQ;
2272 cqe->qp_handle = (u64)(unsigned long)qp;2357 cqe->qp_handle = (u64)(unsigned long)qp;
@@ -2280,12 +2365,12 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq, · 7 unmodified lines
2280 * of the request being signaled or not, it must complete with2365 * of the request being signaled or not, it must complete with
2281 * the hwcqe error status2366 * the hwcqe error status
2282 */2367 */
2283 if (HWQ_CMP((sw_sq_cons + 1), &sq->hwq) == cqe_sq_cons &&2368 if (swq->next_idx == cqe_sq_cons &&
2284 hwcqe->status != CQ_REQ_STATUS_OK) {2369 hwcqe->status != CQ_REQ_STATUS_OK) {
2285 cqe->status = hwcqe->status;2370 cqe->status = hwcqe->status;
2286 dev_err(&cq->hwq.pdev->dev,2371 dev_err(&cq->hwq.pdev->dev,
2287 "FP: CQ Processed Req wr_id[%d] = 0x%llx with status 0x%x\n",2372 "FP: CQ Processed Req wr_id[%d] = 0x%llx with status 0x%x\n",
2288 sw_sq_cons, cqe->wr_id, cqe->status);2373 sq->swq_last, cqe->wr_id, cqe->status);
2289 cqe++;2374 cqe++;
2290 (*budget)--;2375 (*budget)--;
2291 bnxt_qplib_mark_qp_error(qp);2376 bnxt_qplib_mark_qp_error(qp);
@@ -2293,7 +2378,7 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq, · 1 unmodified line
2293 bnxt_qplib_add_flush_qp(qp);2378 bnxt_qplib_add_flush_qp(qp);
2294 } else {2379 } else {
2295 /* Before we complete, do WA 9060 */2380 /* Before we complete, do WA 9060 */
2296 if (do_wa9060(qp, cq, cq_cons, sw_sq_cons,2381 if (do_wa9060(qp, cq, cq_cons, sq->swq_last,
2297 cqe_sq_cons)) {2382 cqe_sq_cons)) {
2298 *lib_qp = qp;2383 *lib_qp = qp;
2299 goto out;2384 goto out;
@@ -2305,13 +2390,14 @@ static int bnxt_qplib_cq_process_req(struct bnxt_qplib_cq *cq, · 5 unmodified lines
2305 }2390 }
2306 }2391 }
2307skip:2392skip:
2308 sq->hwq.cons++;2393 bnxt_qplib_hwq_incr_cons(&sq->hwq, swq->slots);
2394 sq->swq_last = swq->next_idx;
2309 if (sq->single)2395 if (sq->single)
2310 break;2396 break;
2311 }2397 }
2312out:2398out:
2313 *pcqe = cqe;2399 *pcqe = cqe;
2314 if (HWQ_CMP(sq->hwq.cons, &sq->hwq) != cqe_sq_cons) {2400 if (sq->swq_last != cqe_sq_cons) {
2315 /* Out of budget */2401 /* Out of budget */
2316 rc = -EAGAIN;2402 rc = -EAGAIN;
2317 goto done;2403 goto done;
@@ -2386,17 +2472,23 @@ static int bnxt_qplib_cq_process_res_rc(struct bnxt_qplib_cq *cq, · 68 unmodified lines
2386 (*budget)--;2472 (*budget)--;
2387 *pcqe = cqe;2473 *pcqe = cqe;
2388 } else {2474 } else {
2475 struct bnxt_qplib_swq *swq;
2476
2389 rq = &qp->rq;2477 rq = &qp->rq;
2390 if (wr_id_idx >= rq->hwq.max_elements) {2478 if (wr_id_idx > (rq->max_wqe - 1)) {
2391 dev_err(&cq->hwq.pdev->dev,2479 dev_err(&cq->hwq.pdev->dev,
2392 "FP: CQ Process RC wr_id idx 0x%x exceeded RQ max 0x%x\n",2480 "FP: CQ Process RC wr_id idx 0x%x exceeded RQ max 0x%x\n",
2393 wr_id_idx, rq->hwq.max_elements);2481 wr_id_idx, rq->max_wqe);
2394 return -EINVAL;2482 return -EINVAL;
2395 }2483 }
2396 cqe->wr_id = rq->swq[wr_id_idx].wr_id;2484 if (wr_id_idx != rq->swq_last)
2485 return -EINVAL;
2486 swq = &rq->swq[rq->swq_last];
2487 cqe->wr_id = swq->wr_id;
2397 cqe++;2488 cqe++;
2398 (*budget)--;2489 (*budget)--;
2399 rq->hwq.cons++;2490 bnxt_qplib_hwq_incr_cons(&rq->hwq, swq->slots);
2491 rq->swq_last = swq->next_idx;
2400 *pcqe = cqe;2492 *pcqe = cqe;
2401 2493
2402 if (hwcqe->status != CQ_RES_RC_STATUS_OK) {2494 if (hwcqe->status != CQ_RES_RC_STATUS_OK) {
@@ -2467,18 +2559,24 @@ static int bnxt_qplib_cq_process_res_ud(struct bnxt_qplib_cq *cq, · 64 unmodified lines
2467 (*budget)--;2559 (*budget)--;
2468 *pcqe = cqe;2560 *pcqe = cqe;
2469 } else {2561 } else {
2562 struct bnxt_qplib_swq *swq;
2563
2470 rq = &qp->rq;2564 rq = &qp->rq;
2471 if (wr_id_idx >= rq->hwq.max_elements) {2565 if (wr_id_idx > (rq->max_wqe - 1)) {
2472 dev_err(&cq->hwq.pdev->dev,2566 dev_err(&cq->hwq.pdev->dev,
2473 "FP: CQ Process UD wr_id idx 0x%x exceeded RQ max 0x%x\n",2567 "FP: CQ Process UD wr_id idx 0x%x exceeded RQ max 0x%x\n",
2474 wr_id_idx, rq->hwq.max_elements);2568 wr_id_idx, rq->max_wqe);
2475 return -EINVAL;2569 return -EINVAL;
2476 }2570 }
2477 2571
2478 cqe->wr_id = rq->swq[wr_id_idx].wr_id;2572 if (rq->swq_last != wr_id_idx)
2573 return -EINVAL;
2574 swq = &rq->swq[rq->swq_last];
2575 cqe->wr_id = swq->wr_id;
2479 cqe++;2576 cqe++;
2480 (*budget)--;2577 (*budget)--;
2481 rq->hwq.cons++;2578 bnxt_qplib_hwq_incr_cons(&rq->hwq, swq->slots);
2579 rq->swq_last = swq->next_idx;
2482 *pcqe = cqe;2580 *pcqe = cqe;
2483 2581
2484 if (hwcqe->status != CQ_RES_RC_STATUS_OK) {2582 if (hwcqe->status != CQ_RES_RC_STATUS_OK) {
@@ -2569,17 +2667,23 @@ static int bnxt_qplib_cq_process_res_raweth_qp1(struct bnxt_qplib_cq *cq, · 84 unmodified lines
2569 (*budget)--;2667 (*budget)--;
2570 *pcqe = cqe;2668 *pcqe = cqe;
2571 } else {2669 } else {
2670 struct bnxt_qplib_swq *swq;
2671
2572 rq = &qp->rq;2672 rq = &qp->rq;
2573 if (wr_id_idx >= rq->hwq.max_elements) {2673 if (wr_id_idx > (rq->max_wqe - 1)) {
2574 dev_err(&cq->hwq.pdev->dev,2674 dev_err(&cq->hwq.pdev->dev,
2575 "FP: CQ Process Raw/QP1 RQ wr_id idx 0x%x exceeded RQ max 0x%x\n",2675 "FP: CQ Process Raw/QP1 RQ wr_id idx 0x%x exceeded RQ max 0x%x\n",
2576 wr_id_idx, rq->hwq.max_elements);2676 wr_id_idx, rq->max_wqe);
2577 return -EINVAL;2677 return -EINVAL;
2578 }2678 }
2579 cqe->wr_id = rq->swq[wr_id_idx].wr_id;2679 if (rq->swq_last != wr_id_idx)
2680 return -EINVAL;
2681 swq = &rq->swq[rq->swq_last];
2682 cqe->wr_id = swq->wr_id;
2580 cqe++;2683 cqe++;
2581 (*budget)--;2684 (*budget)--;
2582 rq->hwq.cons++;2685 bnxt_qplib_hwq_incr_cons(&rq->hwq, swq->slots);
2686 rq->swq_last = swq->next_idx;
2583 *pcqe = cqe;2687 *pcqe = cqe;
2584 2688
2585 if (hwcqe->status != CQ_RES_RC_STATUS_OK) {2689 if (hwcqe->status != CQ_RES_RC_STATUS_OK) {
@@ -2601,7 +2705,7 @@ static int bnxt_qplib_cq_process_terminal(struct bnxt_qplib_cq *cq, · 15 unmodified lines
2601 struct bnxt_qplib_qp *qp;2705 struct bnxt_qplib_qp *qp;
2602 struct bnxt_qplib_q *sq, *rq;2706 struct bnxt_qplib_q *sq, *rq;
2603 struct bnxt_qplib_cqe *cqe;2707 struct bnxt_qplib_cqe *cqe;
2604 u32 sw_cons = 0, cqe_cons;2708 u32 swq_last = 0, cqe_cons;
2605 int rc = 0;2709 int rc = 0;
2606 2710
2607 /* Check the Status */2711 /* Check the Status */
@@ -2627,13 +2731,7 @@ static int bnxt_qplib_cq_process_terminal(struct bnxt_qplib_cq *cq, · 19 unmodified lines
2627 cqe_cons = le16_to_cpu(hwcqe->sq_cons_idx);2731 cqe_cons = le16_to_cpu(hwcqe->sq_cons_idx);
2628 if (cqe_cons == 0xFFFF)2732 if (cqe_cons == 0xFFFF)
2629 goto do_rq;2733 goto do_rq;
2630 2734 cqe_cons %= sq->max_wqe;
2631 if (cqe_cons > sq->hwq.max_elements) {
2632 dev_err(&cq->hwq.pdev->dev,
2633 "FP: CQ Process terminal reported sq_cons_idx 0x%x which exceeded max 0x%x\n",
2634 cqe_cons, sq->hwq.max_elements);
2635 goto do_rq;
2636 }
2637 2735
2638 if (qp->sq.flushed) {2736 if (qp->sq.flushed) {
2639 dev_dbg(&cq->hwq.pdev->dev,2737 dev_dbg(&cq->hwq.pdev->dev,
@@ -2647,24 +2745,25 @@ static int bnxt_qplib_cq_process_terminal(struct bnxt_qplib_cq *cq, · 7 unmodified lines
2647 */2745 */
2648 cqe = *pcqe;2746 cqe = *pcqe;
2649 while (*budget) {2747 while (*budget) {
2650 sw_cons = HWQ_CMP(sq->hwq.cons, &sq->hwq);2748 swq_last = sq->swq_last;
2651 if (sw_cons == cqe_cons)2749 if (swq_last == cqe_cons)
2652 break;2750 break;
2653 if (sq->swq[sw_cons].flags & SQ_SEND_FLAGS_SIGNAL_COMP) {2751 if (sq->swq[swq_last].flags & SQ_SEND_FLAGS_SIGNAL_COMP) {
2654 memset(cqe, 0, sizeof(*cqe));2752 memset(cqe, 0, sizeof(*cqe));
2655 cqe->status = CQ_REQ_STATUS_OK;2753 cqe->status = CQ_REQ_STATUS_OK;
2656 cqe->opcode = CQ_BASE_CQE_TYPE_REQ;2754 cqe->opcode = CQ_BASE_CQE_TYPE_REQ;
2657 cqe->qp_handle = (u64)(unsigned long)qp;2755 cqe->qp_handle = (u64)(unsigned long)qp;
2658 cqe->src_qp = qp->id;2756 cqe->src_qp = qp->id;
2659 cqe->wr_id = sq->swq[sw_cons].wr_id;2757 cqe->wr_id = sq->swq[swq_last].wr_id;
2660 cqe->type = sq->swq[sw_cons].type;2758 cqe->type = sq->swq[swq_last].type;
2661 cqe++;2759 cqe++;
2662 (*budget)--;2760 (*budget)--;
2663 }2761 }
2664 sq->hwq.cons++;2762 bnxt_qplib_hwq_incr_cons(&sq->hwq, sq->swq[swq_last].slots);
2763 sq->swq_last = sq->swq[swq_last].next_idx;
2665 }2764 }
2666 *pcqe = cqe;2765 *pcqe = cqe;
2667 if (!(*budget) && sw_cons != cqe_cons) {2766 if (!(*budget) && swq_last != cqe_cons) {
2668 /* Out of budget */2767 /* Out of budget */
2669 rc = -EAGAIN;2768 rc = -EAGAIN;
2670 goto sq_done;2769 goto sq_done;
@@ -2676,10 +2775,10 @@ do_rq: · 5 unmodified lines
2676 cqe_cons = le16_to_cpu(hwcqe->rq_cons_idx);2775 cqe_cons = le16_to_cpu(hwcqe->rq_cons_idx);
2677 if (cqe_cons == 0xFFFF) {2776 if (cqe_cons == 0xFFFF) {
2678 goto done;2777 goto done;
2679 } else if (cqe_cons > rq->hwq.max_elements) {2778 } else if (cqe_cons > rq->max_wqe - 1) {
2680 dev_err(&cq->hwq.pdev->dev,2779 dev_err(&cq->hwq.pdev->dev,
2681 "FP: CQ Processed terminal reported rq_cons_idx 0x%x exceeds max 0x%x\n",2780 "FP: CQ Processed terminal reported rq_cons_idx 0x%x exceeds max 0x%x\n",
2682 cqe_cons, rq->hwq.max_elements);2781 cqe_cons, rq->max_wqe);
2683 goto done;2782 goto done;
2684 }2783 }
2685 2784
drivers/infiniband/hw/bnxt_re/qplib_fp.h+122−5
@@ -39,6 +39,51 @@ · 38 unmodified lines
39#ifndef __BNXT_QPLIB_FP_H__39#ifndef __BNXT_QPLIB_FP_H__
40#define __BNXT_QPLIB_FP_H__40#define __BNXT_QPLIB_FP_H__
41 41
42/* Few helper structures temporarily defined here
43 * should get rid of these when roce_hsi.h is updated
44 * in original code base
45 */
46struct sq_ud_ext_hdr {
47 __le32 dst_qp;
48 __le32 avid;
49 __le64 rsvd;
50};
51
52struct sq_raw_ext_hdr {
53 __le32 cfa_meta;
54 __le32 rsvd0;
55 __le64 rsvd1;
56};
57
58struct sq_rdma_ext_hdr {
59 __le64 remote_va;
60 __le32 remote_key;
61 __le32 rsvd;
62};
63
64struct sq_atomic_ext_hdr {
65 __le64 swap_data;
66 __le64 cmp_data;
67};
68
69struct sq_fr_pmr_ext_hdr {
70 __le64 pblptr;
71 __le64 va;
72};
73
74struct sq_bind_ext_hdr {
75 __le64 va;
76 __le32 length_lo;
77 __le32 length_hi;
78};
79
80struct rq_ext_hdr {
81 __le64 rsvd1;
82 __le64 rsvd2;
83};
84
85/* Helper structures end */
86
42struct bnxt_qplib_srq {87struct bnxt_qplib_srq {
43 struct bnxt_qplib_pd *pd;88 struct bnxt_qplib_pd *pd;
44 struct bnxt_qplib_dpi *dpi;89 struct bnxt_qplib_dpi *dpi;
@@ -74,6 +119,8 @@ struct bnxt_qplib_swq { · 29 unmodified lines
74 u8 flags;119 u8 flags;
75 u32 start_psn;120 u32 start_psn;
76 u32 next_psn;121 u32 next_psn;
122 u32 slot_idx;
123 u8 slots;
77 struct sq_psn_search *psn_search;124 struct sq_psn_search *psn_search;
78 struct sq_psn_search_ext *psn_ext;125 struct sq_psn_search_ext *psn_ext;
79};126};
@@ -213,6 +260,8 @@ struct bnxt_qplib_q { · 133 unmodified lines
213 u32 phantom_cqe_cnt;260 u32 phantom_cqe_cnt;
214 u32 next_cq_cons;261 u32 next_cq_cons;
215 bool flushed;262 bool flushed;
263 u32 swq_start;
264 u32 swq_last;
216};265};
217 266
218struct bnxt_qplib_qp {267struct bnxt_qplib_qp {
@@ -224,9 +273,10 @@ struct bnxt_qplib_qp { · 5 unmodified lines
224 u32 id;273 u32 id;
225 u8 type;274 u8 type;
226 u8 sig_type;275 u8 sig_type;
227 u32 modify_flags;276 u8 wqe_mode;
228 u8 state;277 u8 state;
229 u8 cur_qp_state;278 u8 cur_qp_state;
279 u64 modify_flags;
230 u32 max_inline_data;280 u32 max_inline_data;
231 u32 mtu;281 u32 mtu;
232 u8 path_mtu;282 u8 path_mtu;
@@ -300,11 +350,18 @@ struct bnxt_qplib_qp { · 67 unmodified lines
300 (!!((hdr)->cqe_type_toggle & CQ_BASE_TOGGLE) == \350 (!!((hdr)->cqe_type_toggle & CQ_BASE_TOGGLE) == \
301 !((raw_cons) & (cp_bit)))351 !((raw_cons) & (cp_bit)))
302 352
303static inline bool bnxt_qplib_queue_full(struct bnxt_qplib_q *qplib_q)353static inline bool bnxt_qplib_queue_full(struct bnxt_qplib_q *que,
354 u8 slots)
304{355{
305 return HWQ_CMP((qplib_q->hwq.prod + qplib_q->q_full_delta),356 struct bnxt_qplib_hwq *hwq;
306 &qplib_q->hwq) == HWQ_CMP(qplib_q->hwq.cons,357 int avail;
307 &qplib_q->hwq);358
359 hwq = &que->hwq;
360 /* False full is possible, retrying post-send makes sense */
361 avail = hwq->cons - hwq->prod;
362 if (hwq->cons <= hwq->prod)
363 avail += hwq->depth;
364 return avail <= slots;
308}365}
309 366
310struct bnxt_qplib_cqe {367struct bnxt_qplib_cqe {
@@ -489,4 +546,64 @@ int bnxt_qplib_process_flush_list(struct bnxt_qplib_cq *cq, · 178 unmodified lines
489 struct bnxt_qplib_cqe *cqe,546 struct bnxt_qplib_cqe *cqe,
490 int num_cqes);547 int num_cqes);
491void bnxt_qplib_flush_cqn_wq(struct bnxt_qplib_qp *qp);548void bnxt_qplib_flush_cqn_wq(struct bnxt_qplib_qp *qp);
549
550static inline void *bnxt_qplib_get_swqe(struct bnxt_qplib_q *que, u32 *swq_idx)
551{
552 u32 idx;
553
554 idx = que->swq_start;
555 if (swq_idx)
556 *swq_idx = idx;
557 return &que->swq[idx];
558}
559
560static inline void bnxt_qplib_swq_mod_start(struct bnxt_qplib_q *que, u32 idx)
561{
562 que->swq_start = que->swq[idx].next_idx;
563}
564
565static inline u32 bnxt_qplib_get_depth(struct bnxt_qplib_q *que)
566{
567 return (que->wqe_size * que->max_wqe) / sizeof(struct sq_sge);
568}
569
570static inline u32 bnxt_qplib_set_sq_size(struct bnxt_qplib_q *que, u8 wqe_mode)
571{
572 return (wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC) ?
573 que->max_wqe : bnxt_qplib_get_depth(que);
574}
575
576static inline u32 bnxt_qplib_set_sq_max_slot(u8 wqe_mode)
577{
578 return (wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC) ?
579 sizeof(struct sq_send) / sizeof(struct sq_sge) : 1;
580}
581
582static inline u32 bnxt_qplib_set_rq_max_slot(u32 wqe_size)
583{
584 return (wqe_size / sizeof(struct sq_sge));
585}
586
587static inline u16 __xlate_qfd(u16 delta, u16 wqe_bytes)
588{
589 /* For Cu/Wh delta = 128, stride = 16, wqe_bytes = 128
590 * For Gen-p5 B/C mode delta = 0, stride = 16, wqe_bytes = 128.
591 * For Gen-p5 delta = 0, stride = 16, 32 <= wqe_bytes <= 512.
592 * when 8916 is disabled.
593 */
594 return (delta * wqe_bytes) / sizeof(struct sq_sge);
595}
596
597static inline u16 bnxt_qplib_calc_ilsize(struct bnxt_qplib_swqe *wqe, u16 max)
598{
599 u16 size = 0;
600 int indx;
601
602 for (indx = 0; indx < wqe->num_sge; indx++)
603 size += wqe->sg_list[indx].size;
604 if (size > max)
605 size = max;
606
607 return size;
608}
492#endif /* __BNXT_QPLIB_FP_H__ */609#endif /* __BNXT_QPLIB_FP_H__ */
drivers/infiniband/hw/bnxt_re/qplib_res.h+46−12
@@ -41,6 +41,28 @@ · 40 unmodified lines
41 41
42extern const struct bnxt_qplib_gid bnxt_qplib_gid_zero;42extern const struct bnxt_qplib_gid bnxt_qplib_gid_zero;
43 43
44#define CHIP_NUM_57508 0x1750
45#define CHIP_NUM_57504 0x1751
46#define CHIP_NUM_57502 0x1752
47
48enum bnxt_qplib_wqe_mode {
49 BNXT_QPLIB_WQE_MODE_STATIC = 0x00,
50 BNXT_QPLIB_WQE_MODE_VARIABLE = 0x01,
51 BNXT_QPLIB_WQE_MODE_INVALID = 0x02
52};
53
54struct bnxt_qplib_drv_modes {
55 u8 wqe_mode;
56 /* Other modes to follow here */
57};
58
59struct bnxt_qplib_chip_ctx {
60 u16 chip_num;
61 u8 chip_rev;
62 u8 chip_metal;
63 struct bnxt_qplib_drv_modes modes;
64};
65
44#define PTR_CNT_PER_PG (PAGE_SIZE / sizeof(void *))66#define PTR_CNT_PER_PG (PAGE_SIZE / sizeof(void *))
45#define PTR_MAX_IDX_PER_PG (PTR_CNT_PER_PG - 1)67#define PTR_MAX_IDX_PER_PG (PTR_CNT_PER_PG - 1)
46#define PTR_PG(x) (((x) & ~PTR_MAX_IDX_PER_PG) / PTR_CNT_PER_PG)68#define PTR_PG(x) (((x) & ~PTR_MAX_IDX_PER_PG) / PTR_CNT_PER_PG)
@@ -141,6 +163,9 @@ struct bnxt_qplib_hwq { · 94 unmodified lines
141 u32 cons; /* raw */163 u32 cons; /* raw */
142 u8 cp_bit;164 u8 cp_bit;
143 u8 is_user;165 u8 is_user;
166 u64 *pad_pg;
167 u32 pad_stride;
168 u32 pad_pgofft;
144};169};
145 170
146struct bnxt_qplib_db_info {171struct bnxt_qplib_db_info {
@@ -148,6 +173,7 @@ struct bnxt_qplib_db_info { · 1 unmodified line
148 void __iomem *priv_db;173 void __iomem *priv_db;
149 struct bnxt_qplib_hwq *hwq;174 struct bnxt_qplib_hwq *hwq;
150 u32 xid;175 u32 xid;
176 u32 max_slot;
151};177};
152 178
153/* Tables */179/* Tables */
@@ -230,16 +256,6 @@ struct bnxt_qplib_ctx { · 76 unmodified lines
230 u64 hwrm_intf_ver;256 u64 hwrm_intf_ver;
231};257};
232 258
233struct bnxt_qplib_chip_ctx {
234 u16 chip_num;
235 u8 chip_rev;
236 u8 chip_metal;
237};
238
239#define CHIP_NUM_57508 0x1750
240#define CHIP_NUM_57504 0x1751
241#define CHIP_NUM_57502 0x1752
242
243struct bnxt_qplib_res {259struct bnxt_qplib_res {
244 struct pci_dev *pdev;260 struct pci_dev *pdev;
245 struct bnxt_qplib_chip_ctx *cctx;261 struct bnxt_qplib_chip_ctx *cctx;
@@ -317,6 +333,14 @@ static inline void *bnxt_qplib_get_qe(struct bnxt_qplib_hwq *hwq, · 71 unmodified lines
317 return (void *)(hwq->pbl_ptr[pg_num] + hwq->element_size * pg_idx);333 return (void *)(hwq->pbl_ptr[pg_num] + hwq->element_size * pg_idx);
318}334}
319 335
336static inline void *bnxt_qplib_get_prod_qe(struct bnxt_qplib_hwq *hwq, u32 idx)
337{
338 idx += hwq->prod;
339 if (idx >= hwq->depth)
340 idx -= hwq->depth;
341 return bnxt_qplib_get_qe(hwq, idx, NULL);
342}
343
320#define to_bnxt_qplib(ptr, type, member) \344#define to_bnxt_qplib(ptr, type, member) \
321 container_of(ptr, type, member)345 container_of(ptr, type, member)
322 346
@@ -351,6 +375,17 @@ int bnxt_qplib_alloc_ctx(struct bnxt_qplib_res *res, · 28 unmodified lines
351 struct bnxt_qplib_ctx *ctx,375 struct bnxt_qplib_ctx *ctx,
352 bool virt_fn, bool is_p5);376 bool virt_fn, bool is_p5);
353 377
378static inline void bnxt_qplib_hwq_incr_prod(struct bnxt_qplib_hwq *hwq, u32 cnt)
379{
380 hwq->prod = (hwq->prod + cnt) % hwq->depth;
381}
382
383static inline void bnxt_qplib_hwq_incr_cons(struct bnxt_qplib_hwq *hwq,
384 u32 cnt)
385{
386 hwq->cons = (hwq->cons + cnt) % hwq->depth;
387}
388
354static inline void bnxt_qplib_ring_db32(struct bnxt_qplib_db_info *info,389static inline void bnxt_qplib_ring_db32(struct bnxt_qplib_db_info *info,
355 bool arm)390 bool arm)
356{391{
@@ -383,8 +418,7 @@ static inline void bnxt_qplib_ring_prod_db(struct bnxt_qplib_db_info *info, · 26 unmodified lines
383 418
384 key = (info->xid & DBC_DBC_XID_MASK) | DBC_DBC_PATH_ROCE | type;419 key = (info->xid & DBC_DBC_XID_MASK) | DBC_DBC_PATH_ROCE | type;
385 key <<= 32;420 key <<= 32;
386 key |= (info->hwq->prod & (info->hwq->max_elements - 1)) &421 key |= ((info->hwq->prod / info->max_slot)) & DBC_DBC_INDEX_MASK;
387 DBC_DBC_INDEX_MASK;
388 writeq(key, info->db);422 writeq(key, info->db);
389}423}
390 424
drivers/infiniband/hw/bnxt_re/roce_hsi.h+1−0
@@ -1126,6 +1126,7 @@ struct cmdq_create_qp { · 1125 unmodified lines
1126 #define CMDQ_CREATE_QP_QP_FLAGS_FORCE_COMPLETION 0x2UL1126 #define CMDQ_CREATE_QP_QP_FLAGS_FORCE_COMPLETION 0x2UL
1127 #define CMDQ_CREATE_QP_QP_FLAGS_RESERVED_LKEY_ENABLE 0x4UL1127 #define CMDQ_CREATE_QP_QP_FLAGS_RESERVED_LKEY_ENABLE 0x4UL
1128 #define CMDQ_CREATE_QP_QP_FLAGS_FR_PMR_ENABLED 0x8UL1128 #define CMDQ_CREATE_QP_QP_FLAGS_FR_PMR_ENABLED 0x8UL
1129 #define CMDQ_CREATE_QP_QP_FLAGS_VARIABLE_SIZED_WQE_ENABLED 0x10UL
1129 u8 type;1130 u8 type;
1130 #define CMDQ_CREATE_QP_TYPE_RC 0x2UL1131 #define CMDQ_CREATE_QP_TYPE_RC 0x2UL
1131 #define CMDQ_CREATE_QP_TYPE_UD 0x4UL1132 #define CMDQ_CREATE_QP_TYPE_UD 0x4UL
drivers/infiniband/hw/cxgb4/iw_cxgb4.h+5−4
@@ -980,7 +980,7 @@ int c4iw_reject_cr(struct iw_cm_id *cm_id, const void *pdata, u8 pdata_len); · 979 unmodified lines
980void c4iw_qp_add_ref(struct ib_qp *qp);980void c4iw_qp_add_ref(struct ib_qp *qp);
981void c4iw_qp_rem_ref(struct ib_qp *qp);981void c4iw_qp_rem_ref(struct ib_qp *qp);
982struct ib_mr *c4iw_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,982struct ib_mr *c4iw_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
983 u32 max_num_sg, struct ib_udata *udata);983 u32 max_num_sg);
984int c4iw_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,984int c4iw_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,
985 unsigned int *sg_offset);985 unsigned int *sg_offset);
986int c4iw_dealloc_mw(struct ib_mw *mw);986int c4iw_dealloc_mw(struct ib_mw *mw);
@@ -1053,8 +1053,9 @@ int c4iw_post_srq_recv(struct ib_srq *ibsrq, const struct ib_recv_wr *wr, · 66 unmodified lines
1053 const struct ib_recv_wr **bad_wr);1053 const struct ib_recv_wr **bad_wr);
1054struct c4iw_wr_wait *c4iw_alloc_wr_wait(gfp_t gfp);1054struct c4iw_wr_wait *c4iw_alloc_wr_wait(gfp_t gfp);
1055 1055
1056typedef int c4iw_restrack_func(struct sk_buff *msg,1056int c4iw_fill_res_mr_entry(struct sk_buff *msg, struct ib_mr *ibmr);
1057 struct rdma_restrack_entry *res);1057int c4iw_fill_res_cq_entry(struct sk_buff *msg, struct ib_cq *ibcq);
1058extern c4iw_restrack_func *c4iw_restrack_funcs[RDMA_RESTRACK_MAX];1058int c4iw_fill_res_qp_entry(struct sk_buff *msg, struct ib_qp *ibqp);
1059int c4iw_fill_res_cm_id_entry(struct sk_buff *msg, struct rdma_cm_id *cm_id);
1059 1060
1060#endif1061#endif
drivers/infiniband/hw/cxgb4/mem.c+1−2
@@ -399,7 +399,6 @@ static int finish_mem_reg(struct c4iw_mr *mhp, u32 stag) · 398 unmodified lines
399 mmid = stag >> 8;399 mmid = stag >> 8;
400 mhp->ibmr.rkey = mhp->ibmr.lkey = stag;400 mhp->ibmr.rkey = mhp->ibmr.lkey = stag;
401 mhp->ibmr.length = mhp->attr.len;401 mhp->ibmr.length = mhp->attr.len;
402 mhp->ibmr.iova = mhp->attr.va_fbo;
403 mhp->ibmr.page_size = 1U << (mhp->attr.page_size + 12);402 mhp->ibmr.page_size = 1U << (mhp->attr.page_size + 12);
404 pr_debug("mmid 0x%x mhp %p\n", mmid, mhp);403 pr_debug("mmid 0x%x mhp %p\n", mmid, mhp);
405 return xa_insert_irq(&mhp->rhp->mrs, mmid, mhp, GFP_KERNEL);404 return xa_insert_irq(&mhp->rhp->mrs, mmid, mhp, GFP_KERNEL);
@@ -691,7 +690,7 @@ int c4iw_dealloc_mw(struct ib_mw *mw) · 285 unmodified lines
691}690}
692 691
693struct ib_mr *c4iw_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,692struct ib_mr *c4iw_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
694 u32 max_num_sg, struct ib_udata *udata)693 u32 max_num_sg)
695{694{
696 struct c4iw_dev *rhp;695 struct c4iw_dev *rhp;
697 struct c4iw_pd *php;696 struct c4iw_pd *php;
drivers/infiniband/hw/cxgb4/provider.c+3−19
@@ -236,14 +236,6 @@ static int c4iw_allocate_pd(struct ib_pd *pd, struct ib_udata *udata) · 235 unmodified lines
236 return 0;236 return 0;
237}237}
238 238
239static int c4iw_query_pkey(struct ib_device *ibdev, u8 port, u16 index,
240 u16 *pkey)
241{
242 pr_debug("ibdev %p\n", ibdev);
243 *pkey = 0;
244 return 0;
245}
246
247static int c4iw_query_gid(struct ib_device *ibdev, u8 port, int index,239static int c4iw_query_gid(struct ib_device *ibdev, u8 port, int index,
248 union ib_gid *gid)240 union ib_gid *gid)
249{241{
@@ -317,7 +309,6 @@ static int c4iw_query_port(struct ib_device *ibdev, u8 port, · 67 unmodified lines
317 IB_PORT_DEVICE_MGMT_SUP |309 IB_PORT_DEVICE_MGMT_SUP |
318 IB_PORT_VENDOR_CLASS_SUP | IB_PORT_BOOT_MGMT_SUP;310 IB_PORT_VENDOR_CLASS_SUP | IB_PORT_BOOT_MGMT_SUP;
319 props->gid_tbl_len = 1;311 props->gid_tbl_len = 1;
320 props->pkey_tbl_len = 1;
321 props->max_msg_sz = -1;312 props->max_msg_sz = -1;
322 313
323 return ret;314 return ret;
@@ -439,7 +430,6 @@ static int c4iw_port_immutable(struct ib_device *ibdev, u8 port_num, · 115 unmodified lines
439 if (err)430 if (err)
440 return err;431 return err;
441 432
442 immutable->pkey_tbl_len = attr.pkey_tbl_len;
443 immutable->gid_tbl_len = attr.gid_tbl_len;433 immutable->gid_tbl_len = attr.gid_tbl_len;
444 434
445 return 0;435 return 0;
@@ -458,13 +448,6 @@ static void get_dev_fw_str(struct ib_device *dev, char *str) · 12 unmodified lines
458 FW_HDR_FW_VER_BUILD_G(c4iw_dev->rdev.lldi.fw_vers));448 FW_HDR_FW_VER_BUILD_G(c4iw_dev->rdev.lldi.fw_vers));
459}449}
460 450
461static int fill_res_entry(struct sk_buff *msg, struct rdma_restrack_entry *res)
462{
463 return (res->type < ARRAY_SIZE(c4iw_restrack_funcs) &&
464 c4iw_restrack_funcs[res->type]) ?
465 c4iw_restrack_funcs[res->type](msg, res) : 0;
466}
467
468static const struct ib_device_ops c4iw_dev_ops = {451static const struct ib_device_ops c4iw_dev_ops = {
469 .owner = THIS_MODULE,452 .owner = THIS_MODULE,
470 .driver_id = RDMA_DRIVER_CXGB4,453 .driver_id = RDMA_DRIVER_CXGB4,
@@ -485,7 +468,9 @@ static const struct ib_device_ops c4iw_dev_ops = { · 14 unmodified lines
485 .destroy_cq = c4iw_destroy_cq,468 .destroy_cq = c4iw_destroy_cq,
486 .destroy_qp = c4iw_destroy_qp,469 .destroy_qp = c4iw_destroy_qp,
487 .destroy_srq = c4iw_destroy_srq,470 .destroy_srq = c4iw_destroy_srq,
488 .fill_res_entry = fill_res_entry,471 .fill_res_cq_entry = c4iw_fill_res_cq_entry,
472 .fill_res_cm_id_entry = c4iw_fill_res_cm_id_entry,
473 .fill_res_mr_entry = c4iw_fill_res_mr_entry,
489 .get_dev_fw_str = get_dev_fw_str,474 .get_dev_fw_str = get_dev_fw_str,
490 .get_dma_mr = c4iw_get_dma_mr,475 .get_dma_mr = c4iw_get_dma_mr,
491 .get_hw_stats = c4iw_get_mib,476 .get_hw_stats = c4iw_get_mib,
@@ -508,7 +493,6 @@ static const struct ib_device_ops c4iw_dev_ops = { · 16 unmodified lines
508 .post_srq_recv = c4iw_post_srq_recv,493 .post_srq_recv = c4iw_post_srq_recv,
509 .query_device = c4iw_query_device,494 .query_device = c4iw_query_device,
510 .query_gid = c4iw_query_gid,495 .query_gid = c4iw_query_gid,
511 .query_pkey = c4iw_query_pkey,
512 .query_port = c4iw_query_port,496 .query_port = c4iw_query_port,
513 .query_qp = c4iw_ib_query_qp,497 .query_qp = c4iw_ib_query_qp,
514 .reg_user_mr = c4iw_reg_user_mr,498 .reg_user_mr = c4iw_reg_user_mr,
drivers/infiniband/hw/cxgb4/restrack.c+5−19
@@ -134,10 +134,8 @@ err: · 133 unmodified lines
134 return -EMSGSIZE;134 return -EMSGSIZE;
135}135}
136 136
137static int fill_res_qp_entry(struct sk_buff *msg,137int c4iw_fill_res_qp_entry(struct sk_buff *msg, struct ib_qp *ibqp)
138 struct rdma_restrack_entry *res)
139{138{
140 struct ib_qp *ibqp = container_of(res, struct ib_qp, res);
141 struct t4_swsqe *fsp = NULL, *lsp = NULL;139 struct t4_swsqe *fsp = NULL, *lsp = NULL;
142 struct c4iw_qp *qhp = to_c4iw_qp(ibqp);140 struct c4iw_qp *qhp = to_c4iw_qp(ibqp);
143 u16 first_sq_idx = 0, last_sq_idx = 0;141 u16 first_sq_idx = 0, last_sq_idx = 0;
@@ -195,10 +193,9 @@ union union_ep { · 51 unmodified lines
195 struct c4iw_ep ep;193 struct c4iw_ep ep;
196};194};
197 195
198static int fill_res_ep_entry(struct sk_buff *msg,196int c4iw_fill_res_cm_id_entry(struct sk_buff *msg,
199 struct rdma_restrack_entry *res)197 struct rdma_cm_id *cm_id)
200{198{
201 struct rdma_cm_id *cm_id = rdma_res_to_id(res);
202 struct nlattr *table_attr;199 struct nlattr *table_attr;
203 struct c4iw_ep_common *epcp;200 struct c4iw_ep_common *epcp;
204 struct c4iw_listen_ep *listen_ep = NULL;201 struct c4iw_listen_ep *listen_ep = NULL;
@@ -372,10 +369,8 @@ err: · 167 unmodified lines
372 return -EMSGSIZE;369 return -EMSGSIZE;
373}370}
374 371
375static int fill_res_cq_entry(struct sk_buff *msg,372int c4iw_fill_res_cq_entry(struct sk_buff *msg, struct ib_cq *ibcq)
376 struct rdma_restrack_entry *res)
377{373{
378 struct ib_cq *ibcq = container_of(res, struct ib_cq, res);
379 struct c4iw_cq *chp = to_c4iw_cq(ibcq);374 struct c4iw_cq *chp = to_c4iw_cq(ibcq);
380 struct nlattr *table_attr;375 struct nlattr *table_attr;
381 struct t4_cqe hwcqes[2];376 struct t4_cqe hwcqes[2];
@@ -433,10 +428,8 @@ err: · 51 unmodified lines
433 return -EMSGSIZE;428 return -EMSGSIZE;
434}429}
435 430
436static int fill_res_mr_entry(struct sk_buff *msg,431int c4iw_fill_res_mr_entry(struct sk_buff *msg, struct ib_mr *ibmr)
437 struct rdma_restrack_entry *res)
438{432{
439 struct ib_mr *ibmr = container_of(res, struct ib_mr, res);
440 struct c4iw_mr *mhp = to_c4iw_mr(ibmr);433 struct c4iw_mr *mhp = to_c4iw_mr(ibmr);
441 struct c4iw_dev *dev = mhp->rhp;434 struct c4iw_dev *dev = mhp->rhp;
442 u32 stag = mhp->attr.stag;435 u32 stag = mhp->attr.stag;
@@ -492,10 +485,3 @@ err_cancel_table: · 49 unmodified lines
492err:485err:
493 return -EMSGSIZE;486 return -EMSGSIZE;
494}487}
495
496c4iw_restrack_func *c4iw_restrack_funcs[RDMA_RESTRACK_MAX] = {
497 [RDMA_RESTRACK_QP] = fill_res_qp_entry,
498 [RDMA_RESTRACK_CM_ID] = fill_res_ep_entry,
499 [RDMA_RESTRACK_CQ] = fill_res_cq_entry,
500 [RDMA_RESTRACK_MR] = fill_res_mr_entry,
501};
drivers/infiniband/hw/efa/efa_admin_cmds_defs.h+13−2
@@ -606,8 +606,8 @@ struct efa_admin_feature_queue_attr_desc { · 605 unmodified lines
606 /* Number of sub-CQs to be created for each CQ */606 /* Number of sub-CQs to be created for each CQ */
607 u16 sub_cqs_per_cq;607 u16 sub_cqs_per_cq;
608 608
609 /* MBZ */609 /* Minimum number of WQEs per SQ */
610 u16 reserved;610 u16 min_sq_depth;
611 611
612 /* Maximum number of SGEs (buffers) allowed for a single send WQE */612 /* Maximum number of SGEs (buffers) allowed for a single send WQE */
613 u16 max_wr_send_sges;613 u16 max_wr_send_sges;
@@ -632,6 +632,17 @@ struct efa_admin_feature_queue_attr_desc { · 18 unmodified lines
632 632
633 /* Maximum number of SGEs for a single RDMA read WQE */633 /* Maximum number of SGEs for a single RDMA read WQE */
634 u16 max_wr_rdma_sges;634 u16 max_wr_rdma_sges;
635
636 /*
637 * Maximum number of bytes that can be written to SQ between two
638 * consecutive doorbells (in units of 64B). Driver must ensure that only
639 * complete WQEs are written to queue before issuing a doorbell.
640 * Examples: max_tx_batch=16 and WQE size = 64B, means up to 16 WQEs can
641 * be written to SQ between two consecutive doorbells. max_tx_batch=11
642 * and WQE size = 128B, means up to 5 WQEs can be written to SQ between
643 * two consecutive doorbells. Zero means unlimited.
644 */
645 u16 max_tx_batch;
635};646};
636 647
637struct efa_admin_feature_aenq_desc {648struct efa_admin_feature_aenq_desc {
drivers/infiniband/hw/efa/efa_com_cmd.c+2−0
@@ -480,6 +480,8 @@ int efa_com_get_device_attr(struct efa_com_dev *edev, · 479 unmodified lines
480 result->max_llq_size = resp.u.queue_attr.max_llq_size;480 result->max_llq_size = resp.u.queue_attr.max_llq_size;
481 result->sub_cqs_per_cq = resp.u.queue_attr.sub_cqs_per_cq;481 result->sub_cqs_per_cq = resp.u.queue_attr.sub_cqs_per_cq;
482 result->max_wr_rdma_sge = resp.u.queue_attr.max_wr_rdma_sges;482 result->max_wr_rdma_sge = resp.u.queue_attr.max_wr_rdma_sges;
483 result->max_tx_batch = resp.u.queue_attr.max_tx_batch;
484 result->min_sq_depth = resp.u.queue_attr.min_sq_depth;
483 485
484 err = efa_com_get_feature(edev, &resp, EFA_ADMIN_NETWORK_ATTR);486 err = efa_com_get_feature(edev, &resp, EFA_ADMIN_NETWORK_ATTR);
485 if (err) {487 if (err) {
drivers/infiniband/hw/efa/efa_com_cmd.h+2−0
@@ -127,6 +127,8 @@ struct efa_com_get_device_attr_result { · 126 unmodified lines
127 u16 max_sq_sge;127 u16 max_sq_sge;
128 u16 max_rq_sge;128 u16 max_rq_sge;
129 u16 max_wr_rdma_sge;129 u16 max_wr_rdma_sge;
130 u16 max_tx_batch;
131 u16 min_sq_depth;
130 u8 db_bar;132 u8 db_bar;
131};133};
132 134
drivers/infiniband/hw/efa/efa_main.c+4−2
@@ -12,10 +12,12 @@ · 11 unmodified lines
12 12
13#include "efa.h"13#include "efa.h"
14 14
15#define PCI_DEV_ID_EFA_VF 0xefa015#define PCI_DEV_ID_EFA0_VF 0xefa0
16#define PCI_DEV_ID_EFA1_VF 0xefa1
16 17
17static const struct pci_device_id efa_pci_tbl[] = {18static const struct pci_device_id efa_pci_tbl[] = {
18 { PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA_VF) },19 { PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA0_VF) },
20 { PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA1_VF) },
19 { }21 { }
20};22};
21 23
drivers/infiniband/hw/efa/efa_verbs.c+42−0
@@ -1502,11 +1502,39 @@ static int efa_dealloc_uar(struct efa_dev *dev, u16 uarn) · 1501 unmodified lines
1502 return efa_com_dealloc_uar(&dev->edev, &params);1502 return efa_com_dealloc_uar(&dev->edev, &params);
1503}1503}
1504 1504
1505#define EFA_CHECK_USER_COMP(_dev, _comp_mask, _attr, _mask, _attr_str) \
1506 (_attr_str = (!(_dev)->dev_attr._attr || ((_comp_mask) & (_mask))) ? \
1507 NULL : #_attr)
1508
1509static int efa_user_comp_handshake(const struct ib_ucontext *ibucontext,
1510 const struct efa_ibv_alloc_ucontext_cmd *cmd)
1511{
1512 struct efa_dev *dev = to_edev(ibucontext->device);
1513 char *attr_str;
1514
1515 if (EFA_CHECK_USER_COMP(dev, cmd->comp_mask, max_tx_batch,
1516 EFA_ALLOC_UCONTEXT_CMD_COMP_TX_BATCH, attr_str))
1517 goto err;
1518
1519 if (EFA_CHECK_USER_COMP(dev, cmd->comp_mask, min_sq_depth,
1520 EFA_ALLOC_UCONTEXT_CMD_COMP_MIN_SQ_WR,
1521 attr_str))
1522 goto err;
1523
1524 return 0;
1525
1526err:
1527 ibdev_dbg(&dev->ibdev, "Userspace handshake failed for %s attribute\n",
1528 attr_str);
1529 return -EOPNOTSUPP;
1530}
1531
1505int efa_alloc_ucontext(struct ib_ucontext *ibucontext, struct ib_udata *udata)1532int efa_alloc_ucontext(struct ib_ucontext *ibucontext, struct ib_udata *udata)
1506{1533{
1507 struct efa_ucontext *ucontext = to_eucontext(ibucontext);1534 struct efa_ucontext *ucontext = to_eucontext(ibucontext);
1508 struct efa_dev *dev = to_edev(ibucontext->device);1535 struct efa_dev *dev = to_edev(ibucontext->device);
1509 struct efa_ibv_alloc_ucontext_resp resp = {};1536 struct efa_ibv_alloc_ucontext_resp resp = {};
1537 struct efa_ibv_alloc_ucontext_cmd cmd = {};
1510 struct efa_com_alloc_uar_result result;1538 struct efa_com_alloc_uar_result result;
1511 int err;1539 int err;
1512 1540
@@ -1515,6 +1543,18 @@ int efa_alloc_ucontext(struct ib_ucontext *ibucontext, struct ib_udata *udata) · 2 unmodified lines
1515 * we will ack input fields in our response.1543 * we will ack input fields in our response.
1516 */1544 */
1517 1545
1546 err = ib_copy_from_udata(&cmd, udata,
1547 min(sizeof(cmd), udata->inlen));
1548 if (err) {
1549 ibdev_dbg(&dev->ibdev,
1550 "Cannot copy udata for alloc_ucontext\n");
1551 goto err_out;
1552 }
1553
1554 err = efa_user_comp_handshake(ibucontext, &cmd);
1555 if (err)
1556 goto err_out;
1557
1518 err = efa_com_alloc_uar(&dev->edev, &result);1558 err = efa_com_alloc_uar(&dev->edev, &result);
1519 if (err)1559 if (err)
1520 goto err_out;1560 goto err_out;
@@ -1526,6 +1566,8 @@ int efa_alloc_ucontext(struct ib_ucontext *ibucontext, struct ib_udata *udata) · 5 unmodified lines
1526 resp.sub_cqs_per_cq = dev->dev_attr.sub_cqs_per_cq;1566 resp.sub_cqs_per_cq = dev->dev_attr.sub_cqs_per_cq;
1527 resp.inline_buf_size = dev->dev_attr.inline_buf_size;1567 resp.inline_buf_size = dev->dev_attr.inline_buf_size;
1528 resp.max_llq_size = dev->dev_attr.max_llq_size;1568 resp.max_llq_size = dev->dev_attr.max_llq_size;
1569 resp.max_tx_batch = dev->dev_attr.max_tx_batch;
1570 resp.min_sq_wr = dev->dev_attr.min_sq_depth;
1529 1571
1530 if (udata && udata->outlen) {1572 if (udata && udata->outlen) {
1531 err = ib_copy_to_udata(udata, &resp,1573 err = ib_copy_to_udata(udata, &resp,
drivers/infiniband/hw/hfi1/chip.c+14−13
@@ -7317,11 +7317,11 @@ static u16 link_width_to_bits(struct hfi1_devdata *dd, u16 width) · 7316 unmodified lines
7317 case 1: return OPA_LINK_WIDTH_1X;7317 case 1: return OPA_LINK_WIDTH_1X;
7318 case 2: return OPA_LINK_WIDTH_2X;7318 case 2: return OPA_LINK_WIDTH_2X;
7319 case 3: return OPA_LINK_WIDTH_3X;7319 case 3: return OPA_LINK_WIDTH_3X;
7320 case 4: return OPA_LINK_WIDTH_4X;
7320 default:7321 default:
7321 dd_dev_info(dd, "%s: invalid width %d, using 4\n",7322 dd_dev_info(dd, "%s: invalid width %d, using 4\n",
7322 __func__, width);7323 __func__, width);
7323 /* fall through */7324 return OPA_LINK_WIDTH_4X;
7324 case 4: return OPA_LINK_WIDTH_4X;
7325 }7325 }
7326}7326}
7327 7327
@@ -7376,12 +7376,13 @@ static void get_link_widths(struct hfi1_devdata *dd, u16 *tx_width, · 48 unmodified lines
7376 case 0:7376 case 0:
7377 dd->pport[0].link_speed_active = OPA_LINK_SPEED_12_5G;7377 dd->pport[0].link_speed_active = OPA_LINK_SPEED_12_5G;
7378 break;7378 break;
7379 case 1:
7380 dd->pport[0].link_speed_active = OPA_LINK_SPEED_25G;
7381 break;
7379 default:7382 default:
7380 dd_dev_err(dd,7383 dd_dev_err(dd,
7381 "%s: unexpected max rate %d, using 25Gb\n",7384 "%s: unexpected max rate %d, using 25Gb\n",
7382 __func__, (int)max_rate);7385 __func__, (int)max_rate);
7383 /* fall through */
7384 case 1:
7385 dd->pport[0].link_speed_active = OPA_LINK_SPEED_25G;7386 dd->pport[0].link_speed_active = OPA_LINK_SPEED_25G;
7386 break;7387 break;
7387 }7388 }
@@ -12878,11 +12879,6 @@ bail: · 5490 unmodified lines
12878static u32 chip_to_opa_lstate(struct hfi1_devdata *dd, u32 chip_lstate)12879static u32 chip_to_opa_lstate(struct hfi1_devdata *dd, u32 chip_lstate)
12879{12880{
12880 switch (chip_lstate) {12881 switch (chip_lstate) {
12881 default:
12882 dd_dev_err(dd,
12883 "Unknown logical state 0x%x, reporting IB_PORT_DOWN\n",
12884 chip_lstate);
12885 /* fall through */
12886 case LSTATE_DOWN:12882 case LSTATE_DOWN:
12887 return IB_PORT_DOWN;12883 return IB_PORT_DOWN;
12888 case LSTATE_INIT:12884 case LSTATE_INIT:
@@ -12891,6 +12887,11 @@ static u32 chip_to_opa_lstate(struct hfi1_devdata *dd, u32 chip_lstate) · 2 unmodified lines
12891 return IB_PORT_ARMED;12887 return IB_PORT_ARMED;
12892 case LSTATE_ACTIVE:12888 case LSTATE_ACTIVE:
12893 return IB_PORT_ACTIVE;12889 return IB_PORT_ACTIVE;
12890 default:
12891 dd_dev_err(dd,
12892 "Unknown logical state 0x%x, reporting IB_PORT_DOWN\n",
12893 chip_lstate);
12894 return IB_PORT_DOWN;
12894 }12895 }
12895}12896}
12896 12897
@@ -12898,10 +12899,6 @@ u32 chip_to_opa_pstate(struct hfi1_devdata *dd, u32 chip_pstate) · 1 unmodified line
12898{12899{
12899 /* look at the HFI meta-states only */12900 /* look at the HFI meta-states only */
12900 switch (chip_pstate & 0xf0) {12901 switch (chip_pstate & 0xf0) {
12901 default:
12902 dd_dev_err(dd, "Unexpected chip physical state of 0x%x\n",
12903 chip_pstate);
12904 /* fall through */
12905 case PLS_DISABLED:12902 case PLS_DISABLED:
12906 return IB_PORTPHYSSTATE_DISABLED;12903 return IB_PORTPHYSSTATE_DISABLED;
12907 case PLS_OFFLINE:12904 case PLS_OFFLINE:
@@ -12914,6 +12911,10 @@ u32 chip_to_opa_pstate(struct hfi1_devdata *dd, u32 chip_pstate) · 6 unmodified lines
12914 return IB_PORTPHYSSTATE_LINKUP;12911 return IB_PORTPHYSSTATE_LINKUP;
12915 case PLS_PHYTEST:12912 case PLS_PHYTEST:
12916 return IB_PORTPHYSSTATE_PHY_TEST;12913 return IB_PORTPHYSSTATE_PHY_TEST;
12914 default:
12915 dd_dev_err(dd, "Unexpected chip physical state of 0x%x\n",
12916 chip_pstate);
12917 return IB_PORTPHYSSTATE_DISABLED;
12917 }12918 }
12918}12919}
12919 12920
drivers/infiniband/hw/hfi1/firmware.c+0−16
@@ -1868,11 +1868,8 @@ int parse_platform_config(struct hfi1_devdata *dd) · 1867 unmodified lines
1868 2;1868 2;
1869 break;1869 break;
1870 case PLATFORM_CONFIG_RX_PRESET_TABLE:1870 case PLATFORM_CONFIG_RX_PRESET_TABLE:
1871 /* fall through */
1872 case PLATFORM_CONFIG_TX_PRESET_TABLE:1871 case PLATFORM_CONFIG_TX_PRESET_TABLE:
1873 /* fall through */
1874 case PLATFORM_CONFIG_QSFP_ATTEN_TABLE:1872 case PLATFORM_CONFIG_QSFP_ATTEN_TABLE:
1875 /* fall through */
1876 case PLATFORM_CONFIG_VARIABLE_SETTINGS_TABLE:1873 case PLATFORM_CONFIG_VARIABLE_SETTINGS_TABLE:
1877 pcfgcache->config_tables[table_type].num_table =1874 pcfgcache->config_tables[table_type].num_table =
1878 table_length_dwords;1875 table_length_dwords;
@@ -1890,15 +1887,10 @@ int parse_platform_config(struct hfi1_devdata *dd) · 11 unmodified lines
1890 /* metadata table */1887 /* metadata table */
1891 switch (table_type) {1888 switch (table_type) {
1892 case PLATFORM_CONFIG_SYSTEM_TABLE:1889 case PLATFORM_CONFIG_SYSTEM_TABLE:
1893 /* fall through */
1894 case PLATFORM_CONFIG_PORT_TABLE:1890 case PLATFORM_CONFIG_PORT_TABLE:
1895 /* fall through */
1896 case PLATFORM_CONFIG_RX_PRESET_TABLE:1891 case PLATFORM_CONFIG_RX_PRESET_TABLE:
1897 /* fall through */
1898 case PLATFORM_CONFIG_TX_PRESET_TABLE:1892 case PLATFORM_CONFIG_TX_PRESET_TABLE:
1899 /* fall through */
1900 case PLATFORM_CONFIG_QSFP_ATTEN_TABLE:1893 case PLATFORM_CONFIG_QSFP_ATTEN_TABLE:
1901 /* fall through */
1902 case PLATFORM_CONFIG_VARIABLE_SETTINGS_TABLE:1894 case PLATFORM_CONFIG_VARIABLE_SETTINGS_TABLE:
1903 break;1895 break;
1904 default:1896 default:
@@ -2027,15 +2019,10 @@ static int get_platform_fw_field_metadata(struct hfi1_devdata *dd, int table, · 122 unmodified lines
2027 2019
2028 switch (table) {2020 switch (table) {
2029 case PLATFORM_CONFIG_SYSTEM_TABLE:2021 case PLATFORM_CONFIG_SYSTEM_TABLE:
2030 /* fall through */
2031 case PLATFORM_CONFIG_PORT_TABLE:2022 case PLATFORM_CONFIG_PORT_TABLE:
2032 /* fall through */
2033 case PLATFORM_CONFIG_RX_PRESET_TABLE:2023 case PLATFORM_CONFIG_RX_PRESET_TABLE:
2034 /* fall through */
2035 case PLATFORM_CONFIG_TX_PRESET_TABLE:2024 case PLATFORM_CONFIG_TX_PRESET_TABLE:
2036 /* fall through */
2037 case PLATFORM_CONFIG_QSFP_ATTEN_TABLE:2025 case PLATFORM_CONFIG_QSFP_ATTEN_TABLE:
2038 /* fall through */
2039 case PLATFORM_CONFIG_VARIABLE_SETTINGS_TABLE:2026 case PLATFORM_CONFIG_VARIABLE_SETTINGS_TABLE:
2040 if (field && field < platform_config_table_limits[table])2027 if (field && field < platform_config_table_limits[table])
2041 src_ptr =2028 src_ptr =
@@ -2138,11 +2125,8 @@ int get_platform_config_field(struct hfi1_devdata *dd, · 96 unmodified lines
2138 pcfgcache->config_tables[table_type].table;2125 pcfgcache->config_tables[table_type].table;
2139 break;2126 break;
2140 case PLATFORM_CONFIG_RX_PRESET_TABLE:2127 case PLATFORM_CONFIG_RX_PRESET_TABLE:
2141 /* fall through */
2142 case PLATFORM_CONFIG_TX_PRESET_TABLE:2128 case PLATFORM_CONFIG_TX_PRESET_TABLE:
2143 /* fall through */
2144 case PLATFORM_CONFIG_QSFP_ATTEN_TABLE:2129 case PLATFORM_CONFIG_QSFP_ATTEN_TABLE:
2145 /* fall through */
2146 case PLATFORM_CONFIG_VARIABLE_SETTINGS_TABLE:2130 case PLATFORM_CONFIG_VARIABLE_SETTINGS_TABLE:
2147 src_ptr = pcfgcache->config_tables[table_type].table;2131 src_ptr = pcfgcache->config_tables[table_type].table;
2148 2132
drivers/infiniband/hw/hfi1/mad.c+4−5
@@ -721,7 +721,7 @@ static int check_mkey(struct hfi1_ibport *ibp, struct ib_mad_hdr *mad, · 720 unmodified lines
721 /* Bad mkey not a violation below level 2 */721 /* Bad mkey not a violation below level 2 */
722 if (ibp->rvp.mkeyprot < 2)722 if (ibp->rvp.mkeyprot < 2)
723 break;723 break;
724 /* fall through */724 fallthrough;
725 case IB_MGMT_METHOD_SET:725 case IB_MGMT_METHOD_SET:
726 case IB_MGMT_METHOD_TRAP_REPRESS:726 case IB_MGMT_METHOD_TRAP_REPRESS:
727 if (ibp->rvp.mkey_violations != 0xFFFF)727 if (ibp->rvp.mkey_violations != 0xFFFF)
@@ -1272,7 +1272,7 @@ static int set_port_states(struct hfi1_pportdata *ppd, struct opa_smp *smp, · 544 unmodified lines
1272 case IB_PORT_NOP:1272 case IB_PORT_NOP:
1273 if (phys_state == IB_PORTPHYSSTATE_NOP)1273 if (phys_state == IB_PORTPHYSSTATE_NOP)
1274 break;1274 break;
1275 /* FALLTHROUGH */1275 fallthrough;
1276 case IB_PORT_DOWN:1276 case IB_PORT_DOWN:
1277 if (phys_state == IB_PORTPHYSSTATE_NOP) {1277 if (phys_state == IB_PORTPHYSSTATE_NOP) {
1278 link_state = HLS_DN_DOWNDEF;1278 link_state = HLS_DN_DOWNDEF;
@@ -2300,7 +2300,6 @@ static int __subn_set_opa_vl_arb(struct opa_smp *smp, u32 am, u8 *data, · 1021 unmodified lines
2300 * can be changed from the default values2300 * can be changed from the default values
2301 */2301 */
2302 case OPA_VLARB_PREEMPT_ELEMENTS:2302 case OPA_VLARB_PREEMPT_ELEMENTS:
2303 /* FALLTHROUGH */
2304 case OPA_VLARB_PREEMPT_MATRIX:2303 case OPA_VLARB_PREEMPT_MATRIX:
2305 smp->status |= IB_SMP_UNSUP_METH_ATTR;2304 smp->status |= IB_SMP_UNSUP_METH_ATTR;
2306 break;2305 break;
@@ -4170,7 +4169,7 @@ static int subn_get_opa_sma(__be16 attr_id, struct opa_smp *smp, u32 am, · 1863 unmodified lines
4170 return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED;4169 return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED;
4171 if (ibp->rvp.port_cap_flags & IB_PORT_SM)4170 if (ibp->rvp.port_cap_flags & IB_PORT_SM)
4172 return IB_MAD_RESULT_SUCCESS;4171 return IB_MAD_RESULT_SUCCESS;
4173 /* FALLTHROUGH */4172 fallthrough;
4174 default:4173 default:
4175 smp->status |= IB_SMP_UNSUP_METH_ATTR;4174 smp->status |= IB_SMP_UNSUP_METH_ATTR;
4176 ret = reply((struct ib_mad_hdr *)smp);4175 ret = reply((struct ib_mad_hdr *)smp);
@@ -4240,7 +4239,7 @@ static int subn_set_opa_sma(__be16 attr_id, struct opa_smp *smp, u32 am, · 63 unmodified lines
4240 return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED;4239 return IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_CONSUMED;
4241 if (ibp->rvp.port_cap_flags & IB_PORT_SM)4240 if (ibp->rvp.port_cap_flags & IB_PORT_SM)
4242 return IB_MAD_RESULT_SUCCESS;4241 return IB_MAD_RESULT_SUCCESS;
4243 /* FALLTHROUGH */4242 fallthrough;
4244 default:4243 default:
4245 smp->status |= IB_SMP_UNSUP_METH_ATTR;4244 smp->status |= IB_SMP_UNSUP_METH_ATTR;
4246 ret = reply((struct ib_mad_hdr *)smp);4245 ret = reply((struct ib_mad_hdr *)smp);
drivers/infiniband/hw/hfi1/pcie.c+15−7
@@ -306,7 +306,7 @@ int pcie_speeds(struct hfi1_devdata *dd) · 305 unmodified lines
306 ret = pcie_capability_read_dword(dd->pcidev, PCI_EXP_LNKCAP, &linkcap);306 ret = pcie_capability_read_dword(dd->pcidev, PCI_EXP_LNKCAP, &linkcap);
307 if (ret) {307 if (ret) {
308 dd_dev_err(dd, "Unable to read from PCI config\n");308 dd_dev_err(dd, "Unable to read from PCI config\n");
309 return ret;309 return pcibios_err_to_errno(ret);
310 }310 }
311 311
312 if ((linkcap & PCI_EXP_LNKCAP_SLS) != PCI_EXP_LNKCAP_SLS_8_0GB) {312 if ((linkcap & PCI_EXP_LNKCAP_SLS) != PCI_EXP_LNKCAP_SLS_8_0GB) {
@@ -334,10 +334,14 @@ int pcie_speeds(struct hfi1_devdata *dd) · 21 unmodified lines
334 return 0;334 return 0;
335}335}
336 336
337/* restore command and BARs after a reset has wiped them out */337/**
338 * Restore command and BARs after a reset has wiped them out
339 *
340 * Returns 0 on success, otherwise a negative error value
341 */
338int restore_pci_variables(struct hfi1_devdata *dd)342int restore_pci_variables(struct hfi1_devdata *dd)
339{343{
340 int ret = 0;344 int ret;
341 345
342 ret = pci_write_config_word(dd->pcidev, PCI_COMMAND, dd->pci_command);346 ret = pci_write_config_word(dd->pcidev, PCI_COMMAND, dd->pci_command);
343 if (ret)347 if (ret)
@@ -386,13 +390,17 @@ int restore_pci_variables(struct hfi1_devdata *dd) · 42 unmodified lines
386 390
387error:391error:
388 dd_dev_err(dd, "Unable to write to PCI config\n");392 dd_dev_err(dd, "Unable to write to PCI config\n");
389 return ret;393 return pcibios_err_to_errno(ret);
390}394}
391 395
392/* Save BARs and command to rewrite after device reset */396/**
397 * Save BARs and command to rewrite after device reset
398 *
399 * Returns 0 on success, otherwise a negative error value
400 */
393int save_pci_variables(struct hfi1_devdata *dd)401int save_pci_variables(struct hfi1_devdata *dd)
394{402{
395 int ret = 0;403 int ret;
396 404
397 ret = pci_read_config_dword(dd->pcidev, PCI_BASE_ADDRESS_0,405 ret = pci_read_config_dword(dd->pcidev, PCI_BASE_ADDRESS_0,
398 &dd->pcibar0);406 &dd->pcibar0);
@@ -441,7 +449,7 @@ int save_pci_variables(struct hfi1_devdata *dd) · 42 unmodified lines
441 449
442error:450error:
443 dd_dev_err(dd, "Unable to read from PCI config\n");451 dd_dev_err(dd, "Unable to read from PCI config\n");
444 return ret;452 return pcibios_err_to_errno(ret);
445}453}
446 454
447/*455/*
drivers/infiniband/hw/hfi1/pio.c+1−1
@@ -86,7 +86,7 @@ void pio_send_control(struct hfi1_devdata *dd, int op) · 85 unmodified lines
86 switch (op) {86 switch (op) {
87 case PSC_GLOBAL_ENABLE:87 case PSC_GLOBAL_ENABLE:
88 reg |= SEND_CTRL_SEND_ENABLE_SMASK;88 reg |= SEND_CTRL_SEND_ENABLE_SMASK;
89 /* Fall through */89 fallthrough;
90 case PSC_DATA_VL_ENABLE:90 case PSC_DATA_VL_ENABLE:
91 mask = 0;91 mask = 0;
92 for (i = 0; i < ARRAY_SIZE(dd->vld); i++)92 for (i = 0; i < ARRAY_SIZE(dd->vld); i++)
drivers/infiniband/hw/hfi1/pio_copy.c+6−6
@@ -191,22 +191,22 @@ static inline void jcopy(u8 *dest, const u8 *src, u32 n) · 190 unmodified lines
191 switch (n) {191 switch (n) {
192 case 7:192 case 7:
193 *dest++ = *src++;193 *dest++ = *src++;
194 /* fall through */194 fallthrough;
195 case 6:195 case 6:
196 *dest++ = *src++;196 *dest++ = *src++;
197 /* fall through */197 fallthrough;
198 case 5:198 case 5:
199 *dest++ = *src++;199 *dest++ = *src++;
200 /* fall through */200 fallthrough;
201 case 4:201 case 4:
202 *dest++ = *src++;202 *dest++ = *src++;
203 /* fall through */203 fallthrough;
204 case 3:204 case 3:
205 *dest++ = *src++;205 *dest++ = *src++;
206 /* fall through */206 fallthrough;
207 case 2:207 case 2:
208 *dest++ = *src++;208 *dest++ = *src++;
209 /* fall through */209 fallthrough;
210 case 1:210 case 1:
211 *dest++ = *src++;211 *dest++ = *src++;
212 /* fall through */212 /* fall through */
drivers/infiniband/hw/hfi1/platform.c+5−5
@@ -668,8 +668,8 @@ static u8 aoc_low_power_setting(struct hfi1_pportdata *ppd) · 667 unmodified lines
668 668
669 /* active optical cables only */669 /* active optical cables only */
670 switch ((cache[QSFP_MOD_TECH_OFFS] & 0xF0) >> 4) {670 switch ((cache[QSFP_MOD_TECH_OFFS] & 0xF0) >> 4) {
671 case 0x0 ... 0x9: /* fallthrough */671 case 0x0 ... 0x9: fallthrough;
672 case 0xC: /* fallthrough */672 case 0xC: fallthrough;
673 case 0xE:673 case 0xE:
674 /* active AOC */674 /* active AOC */
675 power_class = get_qsfp_power_class(cache[QSFP_MOD_PWR_OFFS]);675 power_class = get_qsfp_power_class(cache[QSFP_MOD_PWR_OFFS]);
@@ -899,8 +899,8 @@ static int tune_qsfp(struct hfi1_pportdata *ppd, · 223 unmodified lines
899 899
900 *ptr_tuning_method = OPA_PASSIVE_TUNING;900 *ptr_tuning_method = OPA_PASSIVE_TUNING;
901 break;901 break;
902 case 0x0 ... 0x9: /* fallthrough */902 case 0x0 ... 0x9: fallthrough;
903 case 0xC: /* fallthrough */903 case 0xC: fallthrough;
904 case 0xE:904 case 0xE:
905 ret = tune_active_qsfp(ppd, ptr_tx_preset, ptr_rx_preset,905 ret = tune_active_qsfp(ppd, ptr_tx_preset, ptr_rx_preset,
906 ptr_total_atten);906 ptr_total_atten);
@@ -909,7 +909,7 @@ static int tune_qsfp(struct hfi1_pportdata *ppd, · 2 unmodified lines
909 909
910 *ptr_tuning_method = OPA_ACTIVE_TUNING;910 *ptr_tuning_method = OPA_ACTIVE_TUNING;
911 break;911 break;
912 case 0xD: /* fallthrough */912 case 0xD: fallthrough;
913 case 0xF:913 case 0xF:
914 default:914 default:
915 dd_dev_warn(ppd->dd, "%s: Unknown/unsupported cable\n",915 dd_dev_warn(ppd->dd, "%s: Unknown/unsupported cable\n",
drivers/infiniband/hw/hfi1/qp.c+1−1
@@ -312,7 +312,7 @@ int hfi1_setup_wqe(struct rvt_qp *qp, struct rvt_swqe *wqe, bool *call_send) · 311 unmodified lines
312 switch (qp->ibqp.qp_type) {312 switch (qp->ibqp.qp_type) {
313 case IB_QPT_RC:313 case IB_QPT_RC:
314 hfi1_setup_tid_rdma_wqe(qp, wqe);314 hfi1_setup_tid_rdma_wqe(qp, wqe);
315 /* fall through */315 fallthrough;
316 case IB_QPT_UC:316 case IB_QPT_UC:
317 if (wqe->length > 0x80000000U)317 if (wqe->length > 0x80000000U)
318 return -EINVAL;318 return -EINVAL;
drivers/infiniband/hw/hfi1/qp.h+0−14
@@ -112,20 +112,6 @@ static inline void clear_ahg(struct rvt_qp *qp) · 111 unmodified lines
112 qp->s_ahgidx = -1;112 qp->s_ahgidx = -1;
113}113}
114 114
115/**
116 * hfi1_create_qp - create a queue pair for a device
117 * @ibpd: the protection domain who's device we create the queue pair for
118 * @init_attr: the attributes of the queue pair
119 * @udata: user data for libibverbs.so
120 *
121 * Returns the queue pair on success, otherwise returns an errno.
122 *
123 * Called by the ib_create_qp() core verbs function.
124 */
125struct ib_qp *hfi1_create_qp(struct ib_pd *ibpd,
126 struct ib_qp_init_attr *init_attr,
127 struct ib_udata *udata);
128
129/**115/**
130 * hfi1_qp_wakeup - wake up on the indicated event116 * hfi1_qp_wakeup - wake up on the indicated event
131 * @qp: the QP117 * @qp: the QP
drivers/infiniband/hw/hfi1/qsfp.c+2−2
@@ -231,7 +231,7 @@ static int i2c_bus_write(struct hfi1_devdata *dd, struct hfi1_i2c_bus *i2c, · 230 unmodified lines
231 break;231 break;
232 case 2:232 case 2:
233 offset_bytes[1] = (offset >> 8) & 0xff;233 offset_bytes[1] = (offset >> 8) & 0xff;
234 /* fall through */234 fallthrough;
235 case 1:235 case 1:
236 num_msgs = 2;236 num_msgs = 2;
237 offset_bytes[0] = offset & 0xff;237 offset_bytes[0] = offset & 0xff;
@@ -279,7 +279,7 @@ static int i2c_bus_read(struct hfi1_devdata *dd, struct hfi1_i2c_bus *bus, · 41 unmodified lines
279 break;279 break;
280 case 2:280 case 2:
281 offset_bytes[1] = (offset >> 8) & 0xff;281 offset_bytes[1] = (offset >> 8) & 0xff;
282 /* fall through */282 fallthrough;
283 case 1:283 case 1:
284 num_msgs = 2;284 num_msgs = 2;
285 offset_bytes[0] = offset & 0xff;285 offset_bytes[0] = offset & 0xff;
drivers/infiniband/hw/hfi1/rc.c+12−13
@@ -141,7 +141,7 @@ static int make_rc_ack(struct hfi1_ibdev *dev, struct rvt_qp *qp, · 140 unmodified lines
141 case OP(RDMA_READ_RESPONSE_ONLY):141 case OP(RDMA_READ_RESPONSE_ONLY):
142 e = &qp->s_ack_queue[qp->s_tail_ack_queue];142 e = &qp->s_ack_queue[qp->s_tail_ack_queue];
143 release_rdma_sge_mr(e);143 release_rdma_sge_mr(e);
144 /* FALLTHROUGH */144 fallthrough;
145 case OP(ATOMIC_ACKNOWLEDGE):145 case OP(ATOMIC_ACKNOWLEDGE):
146 /*146 /*
147 * We can increment the tail pointer now that the last147 * We can increment the tail pointer now that the last
@@ -160,7 +160,7 @@ static int make_rc_ack(struct hfi1_ibdev *dev, struct rvt_qp *qp, · 12 unmodified lines
160 qp->s_acked_ack_queue = next;160 qp->s_acked_ack_queue = next;
161 qp->s_tail_ack_queue = next;161 qp->s_tail_ack_queue = next;
162 trace_hfi1_rsp_make_rc_ack(qp, e->psn);162 trace_hfi1_rsp_make_rc_ack(qp, e->psn);
163 /* FALLTHROUGH */163 fallthrough;
164 case OP(SEND_ONLY):164 case OP(SEND_ONLY):
165 case OP(ACKNOWLEDGE):165 case OP(ACKNOWLEDGE):
166 /* Check for no next entry in the queue. */166 /* Check for no next entry in the queue. */
@@ -267,7 +267,7 @@ static int make_rc_ack(struct hfi1_ibdev *dev, struct rvt_qp *qp, · 100 unmodified lines
267 267
268 case OP(RDMA_READ_RESPONSE_FIRST):268 case OP(RDMA_READ_RESPONSE_FIRST):
269 qp->s_ack_state = OP(RDMA_READ_RESPONSE_MIDDLE);269 qp->s_ack_state = OP(RDMA_READ_RESPONSE_MIDDLE);
270 /* FALLTHROUGH */270 fallthrough;
271 case OP(RDMA_READ_RESPONSE_MIDDLE):271 case OP(RDMA_READ_RESPONSE_MIDDLE):
272 ps->s_txreq->ss = &qp->s_ack_rdma_sge;272 ps->s_txreq->ss = &qp->s_ack_rdma_sge;
273 ps->s_txreq->mr = qp->s_ack_rdma_sge.sge.mr;273 ps->s_txreq->mr = qp->s_ack_rdma_sge.sge.mr;
@@ -881,8 +881,7 @@ no_flow_control: · 607 unmodified lines
881 goto bail;881 goto bail;
882 }882 }
883 qp->s_num_rd_atomic++;883 qp->s_num_rd_atomic++;
884 884 fallthrough;
885 /* FALLTHROUGH */
886 case IB_WR_OPFN:885 case IB_WR_OPFN:
887 if (newreq && !(qp->s_flags & RVT_S_UNLIMITED_CREDIT))886 if (newreq && !(qp->s_flags & RVT_S_UNLIMITED_CREDIT))
888 qp->s_lsn++;887 qp->s_lsn++;
@@ -946,10 +945,10 @@ no_flow_control: · 57 unmodified lines
946 * See restart_rc().945 * See restart_rc().
947 */946 */
948 qp->s_len = restart_sge(&qp->s_sge, wqe, qp->s_psn, pmtu);947 qp->s_len = restart_sge(&qp->s_sge, wqe, qp->s_psn, pmtu);
949 /* FALLTHROUGH */948 fallthrough;
950 case OP(SEND_FIRST):949 case OP(SEND_FIRST):
951 qp->s_state = OP(SEND_MIDDLE);950 qp->s_state = OP(SEND_MIDDLE);
952 /* FALLTHROUGH */951 fallthrough;
953 case OP(SEND_MIDDLE):952 case OP(SEND_MIDDLE):
954 bth2 = mask_psn(qp->s_psn++);953 bth2 = mask_psn(qp->s_psn++);
955 ss = &qp->s_sge;954 ss = &qp->s_sge;
@@ -991,10 +990,10 @@ no_flow_control: · 35 unmodified lines
991 * See restart_rc().990 * See restart_rc().
992 */991 */
993 qp->s_len = restart_sge(&qp->s_sge, wqe, qp->s_psn, pmtu);992 qp->s_len = restart_sge(&qp->s_sge, wqe, qp->s_psn, pmtu);
994 /* FALLTHROUGH */993 fallthrough;
995 case OP(RDMA_WRITE_FIRST):994 case OP(RDMA_WRITE_FIRST):
996 qp->s_state = OP(RDMA_WRITE_MIDDLE);995 qp->s_state = OP(RDMA_WRITE_MIDDLE);
997 /* FALLTHROUGH */996 fallthrough;
998 case OP(RDMA_WRITE_MIDDLE):997 case OP(RDMA_WRITE_MIDDLE):
999 bth2 = mask_psn(qp->s_psn++);998 bth2 = mask_psn(qp->s_psn++);
1000 ss = &qp->s_sge;999 ss = &qp->s_sge;
@@ -2901,7 +2900,7 @@ void hfi1_rc_rcv(struct hfi1_packet *packet) · 1900 unmodified lines
2901 if (!ret)2900 if (!ret)
2902 goto rnr_nak;2901 goto rnr_nak;
2903 qp->r_rcv_len = 0;2902 qp->r_rcv_len = 0;
2904 /* FALLTHROUGH */2903 fallthrough;
2905 case OP(SEND_MIDDLE):2904 case OP(SEND_MIDDLE):
2906 case OP(RDMA_WRITE_MIDDLE):2905 case OP(RDMA_WRITE_MIDDLE):
2907send_middle:2906send_middle:
@@ -2941,7 +2940,7 @@ send_middle: · 33 unmodified lines
2941 goto no_immediate_data;2940 goto no_immediate_data;
2942 if (opcode == OP(SEND_ONLY_WITH_INVALIDATE))2941 if (opcode == OP(SEND_ONLY_WITH_INVALIDATE))
2943 goto send_last_inv;2942 goto send_last_inv;
2944 /* FALLTHROUGH -- for SEND_ONLY_WITH_IMMEDIATE */2943 fallthrough; /* for SEND_ONLY_WITH_IMMEDIATE */
2945 case OP(SEND_LAST_WITH_IMMEDIATE):2944 case OP(SEND_LAST_WITH_IMMEDIATE):
2946send_last_imm:2945send_last_imm:
2947 wc.ex.imm_data = ohdr->u.imm_data;2946 wc.ex.imm_data = ohdr->u.imm_data;
@@ -2957,7 +2956,7 @@ send_last_inv: · 9 unmodified lines
2957 goto send_last;2956 goto send_last;
2958 case OP(RDMA_WRITE_LAST):2957 case OP(RDMA_WRITE_LAST):
2959 copy_last = rvt_is_user_qp(qp);2958 copy_last = rvt_is_user_qp(qp);
2960 /* fall through */2959 fallthrough;
2961 case OP(SEND_LAST):2960 case OP(SEND_LAST):
2962no_immediate_data:2961no_immediate_data:
2963 wc.wc_flags = 0;2962 wc.wc_flags = 0;
@@ -3010,7 +3009,7 @@ send_last: · 46 unmodified lines
3010 3009
3011 case OP(RDMA_WRITE_ONLY):3010 case OP(RDMA_WRITE_ONLY):
3012 copy_last = rvt_is_user_qp(qp);3011 copy_last = rvt_is_user_qp(qp);
3013 /* fall through */3012 fallthrough;
3014 case OP(RDMA_WRITE_FIRST):3013 case OP(RDMA_WRITE_FIRST):
3015 case OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE):3014 case OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE):
3016 if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_WRITE)))3015 if (unlikely(!(qp->qp_access_flags & IB_ACCESS_REMOTE_WRITE)))
drivers/infiniband/hw/hfi1/sdma.c+4−5
@@ -2584,7 +2584,7 @@ static void __sdma_process_event(struct sdma_engine *sde, · 2583 unmodified lines
2584 * 7220, e.g.2584 * 7220, e.g.
2585 */2585 */
2586 ss->go_s99_running = 1;2586 ss->go_s99_running = 1;
2587 /* fall through -- and start dma engine */2587 fallthrough; /* and start dma engine */
2588 case sdma_event_e10_go_hw_start:2588 case sdma_event_e10_go_hw_start:
2589 /* This reference means the state machine is started */2589 /* This reference means the state machine is started */
2590 sdma_get(&sde->state);2590 sdma_get(&sde->state);
@@ -2726,7 +2726,6 @@ static void __sdma_process_event(struct sdma_engine *sde, · 135 unmodified lines
2726 case sdma_event_e70_go_idle:2726 case sdma_event_e70_go_idle:
2727 break;2727 break;
2728 case sdma_event_e85_link_down:2728 case sdma_event_e85_link_down:
2729 /* fall through */
2730 case sdma_event_e80_hw_freeze:2729 case sdma_event_e80_hw_freeze:
2731 sdma_set_state(sde, sdma_state_s80_hw_freeze);2730 sdma_set_state(sde, sdma_state_s80_hw_freeze);
2732 atomic_dec(&sde->dd->sdma_unfreeze_count);2731 atomic_dec(&sde->dd->sdma_unfreeze_count);
@@ -3007,7 +3006,7 @@ static void __sdma_process_event(struct sdma_engine *sde, · 274 unmodified lines
3007 case sdma_event_e60_hw_halted:3006 case sdma_event_e60_hw_halted:
3008 need_progress = 1;3007 need_progress = 1;
3009 sdma_err_progress_check_schedule(sde);3008 sdma_err_progress_check_schedule(sde);
3010 /* fall through */3009 fallthrough;
3011 case sdma_event_e90_sw_halted:3010 case sdma_event_e90_sw_halted:
3012 /*3011 /*
3013 * SW initiated halt does not perform engines3012 * SW initiated halt does not perform engines
@@ -3021,7 +3020,7 @@ static void __sdma_process_event(struct sdma_engine *sde, · 7 unmodified lines
3021 break;3020 break;
3022 case sdma_event_e85_link_down:3021 case sdma_event_e85_link_down:
3023 ss->go_s99_running = 0;3022 ss->go_s99_running = 0;
3024 /* fall through */3023 fallthrough;
3025 case sdma_event_e80_hw_freeze:3024 case sdma_event_e80_hw_freeze:
3026 sdma_set_state(sde, sdma_state_s80_hw_freeze);3025 sdma_set_state(sde, sdma_state_s80_hw_freeze);
3027 atomic_dec(&sde->dd->sdma_unfreeze_count);3026 atomic_dec(&sde->dd->sdma_unfreeze_count);
@@ -3252,7 +3251,7 @@ void _sdma_txreq_ahgadd( · 224 unmodified lines
3252 tx->num_desc++;3251 tx->num_desc++;
3253 tx->descs[2].qw[0] = 0;3252 tx->descs[2].qw[0] = 0;
3254 tx->descs[2].qw[1] = 0;3253 tx->descs[2].qw[1] = 0;
3255 /* FALLTHROUGH */3254 fallthrough;
3256 case SDMA_AHG_APPLY_UPDATE2:3255 case SDMA_AHG_APPLY_UPDATE2:
3257 tx->num_desc++;3256 tx->num_desc++;
3258 tx->descs[1].qw[0] = 0;3257 tx->descs[1].qw[0] = 0;
drivers/infiniband/hw/hfi1/tid_rdma.c+2−2
@@ -3227,7 +3227,7 @@ bool hfi1_tid_rdma_wqe_interlock(struct rvt_qp *qp, struct rvt_swqe *wqe) · 3226 unmodified lines
3227 case IB_WR_RDMA_READ:3227 case IB_WR_RDMA_READ:
3228 if (prev->wr.opcode != IB_WR_TID_RDMA_WRITE)3228 if (prev->wr.opcode != IB_WR_TID_RDMA_WRITE)
3229 break;3229 break;
3230 /* fall through */3230 fallthrough;
3231 case IB_WR_TID_RDMA_READ:3231 case IB_WR_TID_RDMA_READ:
3232 switch (prev->wr.opcode) {3232 switch (prev->wr.opcode) {
3233 case IB_WR_RDMA_READ:3233 case IB_WR_RDMA_READ:
@@ -5067,7 +5067,7 @@ int hfi1_make_tid_rdma_pkt(struct rvt_qp *qp, struct hfi1_pkt_state *ps) · 1833 unmodified lines
5067 if (priv->s_state == TID_OP(WRITE_REQ))5067 if (priv->s_state == TID_OP(WRITE_REQ))
5068 hfi1_tid_rdma_restart_req(qp, wqe, &bth2);5068 hfi1_tid_rdma_restart_req(qp, wqe, &bth2);
5069 priv->s_state = TID_OP(WRITE_DATA);5069 priv->s_state = TID_OP(WRITE_DATA);
5070 /* fall through */5070 fallthrough;
5071 5071
5072 case TID_OP(WRITE_DATA):5072 case TID_OP(WRITE_DATA):
5073 /*5073 /*
drivers/infiniband/hw/hfi1/uc.c+4−4
@@ -216,7 +216,7 @@ int hfi1_make_uc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps) · 215 unmodified lines
216 216
217 case OP(SEND_FIRST):217 case OP(SEND_FIRST):
218 qp->s_state = OP(SEND_MIDDLE);218 qp->s_state = OP(SEND_MIDDLE);
219 /* FALLTHROUGH */219 fallthrough;
220 case OP(SEND_MIDDLE):220 case OP(SEND_MIDDLE):
221 len = qp->s_len;221 len = qp->s_len;
222 if (len > pmtu) {222 if (len > pmtu) {
@@ -241,7 +241,7 @@ int hfi1_make_uc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps) · 18 unmodified lines
241 241
242 case OP(RDMA_WRITE_FIRST):242 case OP(RDMA_WRITE_FIRST):
243 qp->s_state = OP(RDMA_WRITE_MIDDLE);243 qp->s_state = OP(RDMA_WRITE_MIDDLE);
244 /* FALLTHROUGH */244 fallthrough;
245 case OP(RDMA_WRITE_MIDDLE):245 case OP(RDMA_WRITE_MIDDLE):
246 len = qp->s_len;246 len = qp->s_len;
247 if (len > pmtu) {247 if (len > pmtu) {
@@ -414,7 +414,7 @@ send_first: · 166 unmodified lines
414 goto no_immediate_data;414 goto no_immediate_data;
415 else if (opcode == OP(SEND_ONLY_WITH_IMMEDIATE))415 else if (opcode == OP(SEND_ONLY_WITH_IMMEDIATE))
416 goto send_last_imm;416 goto send_last_imm;
417 /* FALLTHROUGH */417 fallthrough;
418 case OP(SEND_MIDDLE):418 case OP(SEND_MIDDLE):
419 /* Check for invalid length PMTU or posted rwqe len. */419 /* Check for invalid length PMTU or posted rwqe len. */
420 /*420 /*
@@ -515,7 +515,7 @@ rdma_first: · 94 unmodified lines
515 wc.ex.imm_data = ohdr->u.rc.imm_data;515 wc.ex.imm_data = ohdr->u.rc.imm_data;
516 goto rdma_last_imm;516 goto rdma_last_imm;
517 }517 }
518 /* FALLTHROUGH */518 fallthrough;
519 case OP(RDMA_WRITE_MIDDLE):519 case OP(RDMA_WRITE_MIDDLE):
520 /* Check for invalid length PMTU or posted rwqe len. */520 /* Check for invalid length PMTU or posted rwqe len. */
521 if (unlikely(tlen != (hdrsize + pmtu + 4)))521 if (unlikely(tlen != (hdrsize + pmtu + 4)))
drivers/infiniband/hw/hns/hns_roce_device.h+16−15
@@ -37,9 +37,8 @@ · 36 unmodified lines
37 37
38#define DRV_NAME "hns_roce"38#define DRV_NAME "hns_roce"
39 39
40/* hip08 is a pci device, it includes two version according pci version id */40/* hip08 is a pci device */
41#define PCI_REVISION_ID_HIP08_A 0x2041#define PCI_REVISION_ID_HIP08 0x21
42#define PCI_REVISION_ID_HIP08_B 0x21
43 42
44#define HNS_ROCE_HW_VER1 ('h' << 24 | 'i' << 16 | '0' << 8 | '6')43#define HNS_ROCE_HW_VER1 ('h' << 24 | 'i' << 16 | '0' << 8 | '6')
45 44
@@ -348,20 +347,22 @@ struct hns_roce_buf_attr { · 302 unmodified lines
348 bool mtt_only; /* only alloc buffer-required MTT memory */347 bool mtt_only; /* only alloc buffer-required MTT memory */
349};348};
350 349
350struct hns_roce_hem_cfg {
351 dma_addr_t root_ba; /* root BA table's address */
352 bool is_direct; /* addressing without BA table */
353 unsigned int ba_pg_shift; /* BA table page shift */
354 unsigned int buf_pg_shift; /* buffer page shift */
355 unsigned int buf_pg_count; /* buffer page count */
356 struct hns_roce_buf_region region[HNS_ROCE_MAX_BT_REGION];
357 int region_count;
358};
359
351/* memory translate region */360/* memory translate region */
352struct hns_roce_mtr {361struct hns_roce_mtr {
353 struct hns_roce_hem_list hem_list; /* multi-hop addressing resource */362 struct hns_roce_hem_list hem_list; /* multi-hop addressing resource */
354 struct ib_umem *umem; /* user space buffer */363 struct ib_umem *umem; /* user space buffer */
355 struct hns_roce_buf *kmem; /* kernel space buffer */364 struct hns_roce_buf *kmem; /* kernel space buffer */
356 struct {365 struct hns_roce_hem_cfg hem_cfg; /* config for hardware addressing */
357 dma_addr_t root_ba; /* root BA table's address */
358 bool is_direct; /* addressing without BA table */
359 unsigned int ba_pg_shift; /* BA table page shift */
360 unsigned int buf_pg_shift; /* buffer page shift */
361 int buf_pg_count; /* buffer page count */
362 struct hns_roce_buf_region region[HNS_ROCE_MAX_BT_REGION];
363 unsigned int region_count;
364 } hem_cfg; /* config for hardware addressing */
365};366};
366 367
367struct hns_roce_mw {368struct hns_roce_mw {
@@ -1192,7 +1193,7 @@ int hns_roce_rereg_user_mr(struct ib_mr *mr, int flags, u64 start, u64 length, · 824 unmodified lines
1192 u64 virt_addr, int mr_access_flags, struct ib_pd *pd,1193 u64 virt_addr, int mr_access_flags, struct ib_pd *pd,
1193 struct ib_udata *udata);1194 struct ib_udata *udata);
1194struct ib_mr *hns_roce_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,1195struct ib_mr *hns_roce_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
1195 u32 max_num_sg, struct ib_udata *udata);1196 u32 max_num_sg);
1196int hns_roce_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,1197int hns_roce_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,
1197 unsigned int *sg_offset);1198 unsigned int *sg_offset);
1198int hns_roce_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata);1199int hns_roce_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata);
@@ -1267,6 +1268,6 @@ void hns_roce_handle_device_err(struct hns_roce_dev *hr_dev); · 68 unmodified lines
1267int hns_roce_init(struct hns_roce_dev *hr_dev);1268int hns_roce_init(struct hns_roce_dev *hr_dev);
1268void hns_roce_exit(struct hns_roce_dev *hr_dev);1269void hns_roce_exit(struct hns_roce_dev *hr_dev);
1269 1270
1270int hns_roce_fill_res_entry(struct sk_buff *msg,1271int hns_roce_fill_res_cq_entry(struct sk_buff *msg,
1271 struct rdma_restrack_entry *res);1272 struct ib_cq *ib_cq);
1272#endif /* _HNS_ROCE_DEVICE_H */1273#endif /* _HNS_ROCE_DEVICE_H */
drivers/infiniband/hw/hns/hns_roce_hw_v1.c+3−4
@@ -2483,7 +2483,6 @@ static int find_wqe_mtt(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp, · 2482 unmodified lines
2483 u64 *sq_ba, u64 *rq_ba, dma_addr_t *bt_ba)2483 u64 *sq_ba, u64 *rq_ba, dma_addr_t *bt_ba)
2484{2484{
2485 struct ib_device *ibdev = &hr_dev->ib_dev;2485 struct ib_device *ibdev = &hr_dev->ib_dev;
2486 int rq_pa_start;
2487 int count;2486 int count;
2488 2487
2489 count = hns_roce_mtr_find(hr_dev, &hr_qp->mtr, 0, sq_ba, 1, bt_ba);2488 count = hns_roce_mtr_find(hr_dev, &hr_qp->mtr, 0, sq_ba, 1, bt_ba);
@@ -2491,9 +2490,9 @@ static int find_wqe_mtt(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp, · 1 unmodified line
2491 ibdev_err(ibdev, "Failed to find SQ ba\n");2490 ibdev_err(ibdev, "Failed to find SQ ba\n");
2492 return -ENOBUFS;2491 return -ENOBUFS;
2493 }2492 }
2494 rq_pa_start = hr_qp->rq.offset >> hr_qp->mtr.hem_cfg.buf_pg_shift;2493
2495 count = hns_roce_mtr_find(hr_dev, &hr_qp->mtr, rq_pa_start, rq_ba, 1,2494 count = hns_roce_mtr_find(hr_dev, &hr_qp->mtr, hr_qp->rq.offset, rq_ba,
2496 NULL);2495 1, NULL);
2497 if (!count) {2496 if (!count) {
2498 ibdev_err(ibdev, "Failed to find RQ ba\n");2497 ibdev_err(ibdev, "Failed to find RQ ba\n");
2499 return -ENOBUFS;2498 return -ENOBUFS;
drivers/infiniband/hw/hns/hns_roce_hw_v2.c+118−135
@@ -91,10 +91,11 @@ static u32 to_hr_opcode(u32 ib_opcode) · 90 unmodified lines
91}91}
92 92
93static void set_frmr_seg(struct hns_roce_v2_rc_send_wqe *rc_sq_wqe,93static void set_frmr_seg(struct hns_roce_v2_rc_send_wqe *rc_sq_wqe,
94 void *wqe, const struct ib_reg_wr *wr)94 const struct ib_reg_wr *wr)
95{95{
96 struct hns_roce_wqe_frmr_seg *fseg =
97 (void *)rc_sq_wqe + sizeof(struct hns_roce_v2_rc_send_wqe);
96 struct hns_roce_mr *mr = to_hr_mr(wr->mr);98 struct hns_roce_mr *mr = to_hr_mr(wr->mr);
97 struct hns_roce_wqe_frmr_seg *fseg = wqe;
98 u64 pbl_ba;99 u64 pbl_ba;
99 100
100 /* use ib_access_flags */101 /* use ib_access_flags */
@@ -128,14 +129,16 @@ static void set_frmr_seg(struct hns_roce_v2_rc_send_wqe *rc_sq_wqe, · 27 unmodified lines
128 V2_RC_FRMR_WQE_BYTE_40_BLK_MODE_S, 0);129 V2_RC_FRMR_WQE_BYTE_40_BLK_MODE_S, 0);
129}130}
130 131
131static void set_atomic_seg(const struct ib_send_wr *wr, void *wqe,132static void set_atomic_seg(const struct ib_send_wr *wr,
132 struct hns_roce_v2_rc_send_wqe *rc_sq_wqe,133 struct hns_roce_v2_rc_send_wqe *rc_sq_wqe,
133 unsigned int valid_num_sge)134 unsigned int valid_num_sge)
134{135{
135 struct hns_roce_wqe_atomic_seg *aseg;136 struct hns_roce_v2_wqe_data_seg *dseg =
137 (void *)rc_sq_wqe + sizeof(struct hns_roce_v2_rc_send_wqe);
138 struct hns_roce_wqe_atomic_seg *aseg =
139 (void *)dseg + sizeof(struct hns_roce_v2_wqe_data_seg);
136 140
137 set_data_seg_v2(wqe, wr->sg_list);141 set_data_seg_v2(dseg, wr->sg_list);
138 aseg = wqe + sizeof(struct hns_roce_v2_wqe_data_seg);
139 142
140 if (wr->opcode == IB_WR_ATOMIC_CMP_AND_SWP) {143 if (wr->opcode == IB_WR_ATOMIC_CMP_AND_SWP) {
141 aseg->fetchadd_swap_data = cpu_to_le64(atomic_wr(wr)->swap);144 aseg->fetchadd_swap_data = cpu_to_le64(atomic_wr(wr)->swap);
@@ -143,7 +146,7 @@ static void set_atomic_seg(const struct ib_send_wr *wr, void *wqe, · 1 unmodified line
143 } else {146 } else {
144 aseg->fetchadd_swap_data =147 aseg->fetchadd_swap_data =
145 cpu_to_le64(atomic_wr(wr)->compare_add);148 cpu_to_le64(atomic_wr(wr)->compare_add);
146 aseg->cmp_data = 0;149 aseg->cmp_data = 0;
147 }150 }
148 151
149 roce_set_field(rc_sq_wqe->byte_16, V2_RC_SEND_WQE_BYTE_16_SGE_NUM_M,152 roce_set_field(rc_sq_wqe->byte_16, V2_RC_SEND_WQE_BYTE_16_SGE_NUM_M,
@@ -176,13 +179,15 @@ static void set_extend_sge(struct hns_roce_qp *qp, const struct ib_send_wr *wr, · 26 unmodified lines
176 179
177static int set_rwqe_data_seg(struct ib_qp *ibqp, const struct ib_send_wr *wr,180static int set_rwqe_data_seg(struct ib_qp *ibqp, const struct ib_send_wr *wr,
178 struct hns_roce_v2_rc_send_wqe *rc_sq_wqe,181 struct hns_roce_v2_rc_send_wqe *rc_sq_wqe,
179 void *wqe, unsigned int *sge_ind,182 unsigned int *sge_ind,
180 unsigned int valid_num_sge)183 unsigned int valid_num_sge)
181{184{
182 struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);185 struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
183 struct hns_roce_v2_wqe_data_seg *dseg = wqe;186 struct hns_roce_v2_wqe_data_seg *dseg =
187 (void *)rc_sq_wqe + sizeof(struct hns_roce_v2_rc_send_wqe);
184 struct ib_device *ibdev = &hr_dev->ib_dev;188 struct ib_device *ibdev = &hr_dev->ib_dev;
185 struct hns_roce_qp *qp = to_hr_qp(ibqp);189 struct hns_roce_qp *qp = to_hr_qp(ibqp);
190 void *wqe = dseg;
186 int j = 0;191 int j = 0;
187 int i;192 int i;
188 193
@@ -438,7 +443,6 @@ static inline int set_rc_wqe(struct hns_roce_qp *qp, · 249 unmodified lines
438 roce_set_bit(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_OWNER_S,443 roce_set_bit(rc_sq_wqe->byte_4, V2_RC_SEND_WQE_BYTE_4_OWNER_S,
439 owner_bit);444 owner_bit);
440 445
441 wqe += sizeof(struct hns_roce_v2_rc_send_wqe);
442 switch (wr->opcode) {446 switch (wr->opcode) {
443 case IB_WR_RDMA_READ:447 case IB_WR_RDMA_READ:
444 case IB_WR_RDMA_WRITE:448 case IB_WR_RDMA_WRITE:
@@ -451,7 +455,7 @@ static inline int set_rc_wqe(struct hns_roce_qp *qp, · 6 unmodified lines
451 rc_sq_wqe->inv_key = cpu_to_le32(wr->ex.invalidate_rkey);455 rc_sq_wqe->inv_key = cpu_to_le32(wr->ex.invalidate_rkey);
452 break;456 break;
453 case IB_WR_REG_MR:457 case IB_WR_REG_MR:
454 set_frmr_seg(rc_sq_wqe, wqe, reg_wr(wr));458 set_frmr_seg(rc_sq_wqe, reg_wr(wr));
455 break;459 break;
456 case IB_WR_ATOMIC_CMP_AND_SWP:460 case IB_WR_ATOMIC_CMP_AND_SWP:
457 case IB_WR_ATOMIC_FETCH_AND_ADD:461 case IB_WR_ATOMIC_FETCH_AND_ADD:
@@ -468,10 +472,10 @@ static inline int set_rc_wqe(struct hns_roce_qp *qp, · 10 unmodified lines
468 472
469 if (wr->opcode == IB_WR_ATOMIC_CMP_AND_SWP ||473 if (wr->opcode == IB_WR_ATOMIC_CMP_AND_SWP ||
470 wr->opcode == IB_WR_ATOMIC_FETCH_AND_ADD)474 wr->opcode == IB_WR_ATOMIC_FETCH_AND_ADD)
471 set_atomic_seg(wr, wqe, rc_sq_wqe, valid_num_sge);475 set_atomic_seg(wr, rc_sq_wqe, valid_num_sge);
472 else if (wr->opcode != IB_WR_REG_MR)476 else if (wr->opcode != IB_WR_REG_MR)
473 ret = set_rwqe_data_seg(&qp->ibqp, wr, rc_sq_wqe,477 ret = set_rwqe_data_seg(&qp->ibqp, wr, rc_sq_wqe,
474 wqe, &curr_idx, valid_num_sge);478 &curr_idx, valid_num_sge);
475 479
476 *sge_idx = curr_idx;480 *sge_idx = curr_idx;
477 481
@@ -1510,8 +1514,6 @@ static int hns_roce_alloc_vf_resource(struct hns_roce_dev *hr_dev) · 1032 unmodified lines
1510 1514
1511 req_a = (struct hns_roce_vf_res_a *)desc[0].data;1515 req_a = (struct hns_roce_vf_res_a *)desc[0].data;
1512 req_b = (struct hns_roce_vf_res_b *)desc[1].data;1516 req_b = (struct hns_roce_vf_res_b *)desc[1].data;
1513 memset(req_a, 0, sizeof(*req_a));
1514 memset(req_b, 0, sizeof(*req_b));
1515 for (i = 0; i < 2; i++) {1517 for (i = 0; i < 2; i++) {
1516 hns_roce_cmq_setup_basic_desc(&desc[i],1518 hns_roce_cmq_setup_basic_desc(&desc[i],
1517 HNS_ROCE_OPC_ALLOC_VF_RES, false);1519 HNS_ROCE_OPC_ALLOC_VF_RES, false);
@@ -1744,27 +1746,25 @@ static void set_default_caps(struct hns_roce_dev *hr_dev) · 226 unmodified lines
1744 caps->max_srq_wrs = HNS_ROCE_V2_MAX_SRQ_WR;1746 caps->max_srq_wrs = HNS_ROCE_V2_MAX_SRQ_WR;
1745 caps->max_srq_sges = HNS_ROCE_V2_MAX_SRQ_SGE;1747 caps->max_srq_sges = HNS_ROCE_V2_MAX_SRQ_SGE;
1746 1748
1747 if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP08_B) {1749 caps->flags |= HNS_ROCE_CAP_FLAG_ATOMIC | HNS_ROCE_CAP_FLAG_MW |
1748 caps->flags |= HNS_ROCE_CAP_FLAG_ATOMIC | HNS_ROCE_CAP_FLAG_MW |1750 HNS_ROCE_CAP_FLAG_SRQ | HNS_ROCE_CAP_FLAG_FRMR |
1749 HNS_ROCE_CAP_FLAG_SRQ | HNS_ROCE_CAP_FLAG_FRMR |1751 HNS_ROCE_CAP_FLAG_QP_FLOW_CTRL;
1750 HNS_ROCE_CAP_FLAG_QP_FLOW_CTRL;
1751 1752
1752 caps->num_qpc_timer = HNS_ROCE_V2_MAX_QPC_TIMER_NUM;1753 caps->num_qpc_timer = HNS_ROCE_V2_MAX_QPC_TIMER_NUM;
1753 caps->qpc_timer_entry_sz = HNS_ROCE_V2_QPC_TIMER_ENTRY_SZ;1754 caps->qpc_timer_entry_sz = HNS_ROCE_V2_QPC_TIMER_ENTRY_SZ;
1754 caps->qpc_timer_ba_pg_sz = 0;1755 caps->qpc_timer_ba_pg_sz = 0;
1755 caps->qpc_timer_buf_pg_sz = 0;1756 caps->qpc_timer_buf_pg_sz = 0;
1756 caps->qpc_timer_hop_num = HNS_ROCE_HOP_NUM_0;1757 caps->qpc_timer_hop_num = HNS_ROCE_HOP_NUM_0;
1757 caps->num_cqc_timer = HNS_ROCE_V2_MAX_CQC_TIMER_NUM;1758 caps->num_cqc_timer = HNS_ROCE_V2_MAX_CQC_TIMER_NUM;
1758 caps->cqc_timer_entry_sz = HNS_ROCE_V2_CQC_TIMER_ENTRY_SZ;1759 caps->cqc_timer_entry_sz = HNS_ROCE_V2_CQC_TIMER_ENTRY_SZ;
1759 caps->cqc_timer_ba_pg_sz = 0;1760 caps->cqc_timer_ba_pg_sz = 0;
1760 caps->cqc_timer_buf_pg_sz = 0;1761 caps->cqc_timer_buf_pg_sz = 0;
1761 caps->cqc_timer_hop_num = HNS_ROCE_HOP_NUM_0;1762 caps->cqc_timer_hop_num = HNS_ROCE_HOP_NUM_0;
1762 1763
1763 caps->sccc_entry_sz = HNS_ROCE_V2_SCCC_ENTRY_SZ;1764 caps->sccc_entry_sz = HNS_ROCE_V2_SCCC_ENTRY_SZ;
1764 caps->sccc_ba_pg_sz = 0;1765 caps->sccc_ba_pg_sz = 0;
1765 caps->sccc_buf_pg_sz = 0;1766 caps->sccc_buf_pg_sz = 0;
1766 caps->sccc_hop_num = HNS_ROCE_SCCC_HOP_NUM;1767 caps->sccc_hop_num = HNS_ROCE_SCCC_HOP_NUM;
1767 }
1768}1768}
1769 1769
1770static void calc_pg_sz(int obj_num, int obj_size, int hop_num, int ctx_bt_num,1770static void calc_pg_sz(int obj_num, int obj_size, int hop_num, int ctx_bt_num,
@@ -1995,20 +1995,18 @@ static int hns_roce_query_pf_caps(struct hns_roce_dev *hr_dev) · 224 unmodified lines
1995 caps->srqc_bt_num, &caps->srqc_buf_pg_sz,1995 caps->srqc_bt_num, &caps->srqc_buf_pg_sz,
1996 &caps->srqc_ba_pg_sz, HEM_TYPE_SRQC);1996 &caps->srqc_ba_pg_sz, HEM_TYPE_SRQC);
1997 1997
1998 if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP08_B) {1998 caps->sccc_hop_num = ctx_hop_num;
1999 caps->sccc_hop_num = ctx_hop_num;1999 caps->qpc_timer_hop_num = HNS_ROCE_HOP_NUM_0;
2000 caps->qpc_timer_hop_num = HNS_ROCE_HOP_NUM_0;2000 caps->cqc_timer_hop_num = HNS_ROCE_HOP_NUM_0;
2001 caps->cqc_timer_hop_num = HNS_ROCE_HOP_NUM_0;
2002 2001
2003 calc_pg_sz(caps->num_qps, caps->sccc_entry_sz,2002 calc_pg_sz(caps->num_qps, caps->sccc_entry_sz,
2004 caps->sccc_hop_num, caps->sccc_bt_num,2003 caps->sccc_hop_num, caps->sccc_bt_num,
2005 &caps->sccc_buf_pg_sz, &caps->sccc_ba_pg_sz,2004 &caps->sccc_buf_pg_sz, &caps->sccc_ba_pg_sz,
2006 HEM_TYPE_SCCC);2005 HEM_TYPE_SCCC);
2007 calc_pg_sz(caps->num_cqc_timer, caps->cqc_timer_entry_sz,2006 calc_pg_sz(caps->num_cqc_timer, caps->cqc_timer_entry_sz,
2008 caps->cqc_timer_hop_num, caps->cqc_timer_bt_num,2007 caps->cqc_timer_hop_num, caps->cqc_timer_bt_num,
2009 &caps->cqc_timer_buf_pg_sz,2008 &caps->cqc_timer_buf_pg_sz,
2010 &caps->cqc_timer_ba_pg_sz, HEM_TYPE_CQC_TIMER);2009 &caps->cqc_timer_ba_pg_sz, HEM_TYPE_CQC_TIMER);
2011 }
2012 2010
2013 calc_pg_sz(caps->num_cqe_segs, caps->mtt_entry_sz, caps->cqe_hop_num,2011 calc_pg_sz(caps->num_cqe_segs, caps->mtt_entry_sz, caps->cqe_hop_num,
2014 1, &caps->cqe_buf_pg_sz, &caps->cqe_ba_pg_sz, HEM_TYPE_CQE);2012 1, &caps->cqe_buf_pg_sz, &caps->cqe_ba_pg_sz, HEM_TYPE_CQE);
@@ -2055,22 +2053,19 @@ static int hns_roce_v2_profile(struct hns_roce_dev *hr_dev) · 40 unmodified lines
2055 return ret;2053 return ret;
2056 }2054 }
2057 2055
2058 if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP08_B) {2056 ret = hns_roce_query_pf_timer_resource(hr_dev);
2059 ret = hns_roce_query_pf_timer_resource(hr_dev);2057 if (ret) {
2060 if (ret) {2058 dev_err(hr_dev->dev,
2061 dev_err(hr_dev->dev,2059 "failed to query pf timer resource, ret = %d.\n", ret);
2062 "Query pf timer resource fail, ret = %d.\n",2060 return ret;
2063 ret);2061 }
2064 return ret;
2065 }
2066 2062
2067 ret = hns_roce_set_vf_switch_param(hr_dev, 0);2063 ret = hns_roce_set_vf_switch_param(hr_dev, 0);
2068 if (ret) {2064 if (ret) {
2069 dev_err(hr_dev->dev,2065 dev_err(hr_dev->dev,
2070 "Set function switch param fail, ret = %d.\n",2066 "failed to set function switch param, ret = %d.\n",
2071 ret);2067 ret);
2072 return ret;2068 return ret;
2073 }
2074 }2069 }
2075 2070
2076 hr_dev->vendor_part_id = hr_dev->pci_dev->device;2071 hr_dev->vendor_part_id = hr_dev->pci_dev->device;
@@ -2336,8 +2331,7 @@ static void hns_roce_v2_exit(struct hns_roce_dev *hr_dev) · 259 unmodified lines
2336{2331{
2337 struct hns_roce_v2_priv *priv = hr_dev->priv;2332 struct hns_roce_v2_priv *priv = hr_dev->priv;
2338 2333
2339 if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP08_B)2334 hns_roce_function_clear(hr_dev);
2340 hns_roce_function_clear(hr_dev);
2341 2335
2342 hns_roce_free_link_table(hr_dev, &priv->tpq);2336 hns_roce_free_link_table(hr_dev, &priv->tpq);
2343 hns_roce_free_link_table(hr_dev, &priv->tsq);2337 hns_roce_free_link_table(hr_dev, &priv->tsq);
@@ -3053,6 +3047,7 @@ static void get_cqe_status(struct hns_roce_dev *hr_dev, struct hns_roce_qp *qp, · 709 unmodified lines
3053 IB_WC_RETRY_EXC_ERR },3047 IB_WC_RETRY_EXC_ERR },
3054 { HNS_ROCE_CQE_V2_RNR_RETRY_EXC_ERR, IB_WC_RNR_RETRY_EXC_ERR },3048 { HNS_ROCE_CQE_V2_RNR_RETRY_EXC_ERR, IB_WC_RNR_RETRY_EXC_ERR },
3055 { HNS_ROCE_CQE_V2_REMOTE_ABORT_ERR, IB_WC_REM_ABORT_ERR },3049 { HNS_ROCE_CQE_V2_REMOTE_ABORT_ERR, IB_WC_REM_ABORT_ERR },
3050 { HNS_ROCE_CQE_V2_GENERAL_ERR, IB_WC_GENERAL_ERR}
3056 };3051 };
3057 3052
3058 u32 cqe_status = roce_get_field(cqe->byte_4, V2_CQE_BYTE_4_STATUS_M,3053 u32 cqe_status = roce_get_field(cqe->byte_4, V2_CQE_BYTE_4_STATUS_M,
@@ -3074,6 +3069,14 @@ static void get_cqe_status(struct hns_roce_dev *hr_dev, struct hns_roce_qp *qp, · 15 unmodified lines
3074 print_hex_dump(KERN_ERR, "", DUMP_PREFIX_NONE, 16, 4, cqe,3069 print_hex_dump(KERN_ERR, "", DUMP_PREFIX_NONE, 16, 4, cqe,
3075 sizeof(*cqe), false);3070 sizeof(*cqe), false);
3076 3071
3072 /*
3073 * For hns ROCEE, GENERAL_ERR is an error type that is not defined in
3074 * the standard protocol, the driver must ignore it and needn't to set
3075 * the QP to an error state.
3076 */
3077 if (cqe_status == HNS_ROCE_CQE_V2_GENERAL_ERR)
3078 return;
3079
3077 /*3080 /*
3078 * Hip08 hardware cannot flush the WQEs in SQ/RQ if the QP state gets3081 * Hip08 hardware cannot flush the WQEs in SQ/RQ if the QP state gets
3079 * into errored mode. Hence, as a workaround to this hardware3082 * into errored mode. Hence, as a workaround to this hardware
@@ -3170,51 +3173,51 @@ static int hns_roce_v2_poll_one(struct hns_roce_cq *hr_cq, · 90 unmodified lines
3170 /* SQ corresponding to CQE */3173 /* SQ corresponding to CQE */
3171 switch (roce_get_field(cqe->byte_4, V2_CQE_BYTE_4_OPCODE_M,3174 switch (roce_get_field(cqe->byte_4, V2_CQE_BYTE_4_OPCODE_M,
3172 V2_CQE_BYTE_4_OPCODE_S) & 0x1f) {3175 V2_CQE_BYTE_4_OPCODE_S) & 0x1f) {
3173 case HNS_ROCE_SQ_OPCODE_SEND:3176 case HNS_ROCE_V2_WQE_OP_SEND:
3174 wc->opcode = IB_WC_SEND;3177 wc->opcode = IB_WC_SEND;
3175 break;3178 break;
3176 case HNS_ROCE_SQ_OPCODE_SEND_WITH_INV:3179 case HNS_ROCE_V2_WQE_OP_SEND_WITH_INV:
3177 wc->opcode = IB_WC_SEND;3180 wc->opcode = IB_WC_SEND;
3178 break;3181 break;
3179 case HNS_ROCE_SQ_OPCODE_SEND_WITH_IMM:3182 case HNS_ROCE_V2_WQE_OP_SEND_WITH_IMM:
3180 wc->opcode = IB_WC_SEND;3183 wc->opcode = IB_WC_SEND;
3181 wc->wc_flags |= IB_WC_WITH_IMM;3184 wc->wc_flags |= IB_WC_WITH_IMM;
3182 break;3185 break;
3183 case HNS_ROCE_SQ_OPCODE_RDMA_READ:3186 case HNS_ROCE_V2_WQE_OP_RDMA_READ:
3184 wc->opcode = IB_WC_RDMA_READ;3187 wc->opcode = IB_WC_RDMA_READ;
3185 wc->byte_len = le32_to_cpu(cqe->byte_cnt);3188 wc->byte_len = le32_to_cpu(cqe->byte_cnt);
3186 break;3189 break;
3187 case HNS_ROCE_SQ_OPCODE_RDMA_WRITE:3190 case HNS_ROCE_V2_WQE_OP_RDMA_WRITE:
3188 wc->opcode = IB_WC_RDMA_WRITE;3191 wc->opcode = IB_WC_RDMA_WRITE;
3189 break;3192 break;
3190 case HNS_ROCE_SQ_OPCODE_RDMA_WRITE_WITH_IMM:3193 case HNS_ROCE_V2_WQE_OP_RDMA_WRITE_WITH_IMM:
3191 wc->opcode = IB_WC_RDMA_WRITE;3194 wc->opcode = IB_WC_RDMA_WRITE;
3192 wc->wc_flags |= IB_WC_WITH_IMM;3195 wc->wc_flags |= IB_WC_WITH_IMM;
3193 break;3196 break;
3194 case HNS_ROCE_SQ_OPCODE_LOCAL_INV:3197 case HNS_ROCE_V2_WQE_OP_LOCAL_INV:
3195 wc->opcode = IB_WC_LOCAL_INV;3198 wc->opcode = IB_WC_LOCAL_INV;
3196 wc->wc_flags |= IB_WC_WITH_INVALIDATE;3199 wc->wc_flags |= IB_WC_WITH_INVALIDATE;
3197 break;3200 break;
3198 case HNS_ROCE_SQ_OPCODE_ATOMIC_COMP_AND_SWAP:3201 case HNS_ROCE_V2_WQE_OP_ATOM_CMP_AND_SWAP:
3199 wc->opcode = IB_WC_COMP_SWAP;3202 wc->opcode = IB_WC_COMP_SWAP;
3200 wc->byte_len = 8;3203 wc->byte_len = 8;
3201 break;3204 break;
3202 case HNS_ROCE_SQ_OPCODE_ATOMIC_FETCH_AND_ADD:3205 case HNS_ROCE_V2_WQE_OP_ATOM_FETCH_AND_ADD:
3203 wc->opcode = IB_WC_FETCH_ADD;3206 wc->opcode = IB_WC_FETCH_ADD;
3204 wc->byte_len = 8;3207 wc->byte_len = 8;
3205 break;3208 break;
3206 case HNS_ROCE_SQ_OPCODE_ATOMIC_MASK_COMP_AND_SWAP:3209 case HNS_ROCE_V2_WQE_OP_ATOM_MSK_CMP_AND_SWAP:
3207 wc->opcode = IB_WC_MASKED_COMP_SWAP;3210 wc->opcode = IB_WC_MASKED_COMP_SWAP;
3208 wc->byte_len = 8;3211 wc->byte_len = 8;
3209 break;3212 break;
3210 case HNS_ROCE_SQ_OPCODE_ATOMIC_MASK_FETCH_AND_ADD:3213 case HNS_ROCE_V2_WQE_OP_ATOM_MSK_FETCH_AND_ADD:
3211 wc->opcode = IB_WC_MASKED_FETCH_ADD;3214 wc->opcode = IB_WC_MASKED_FETCH_ADD;
3212 wc->byte_len = 8;3215 wc->byte_len = 8;
3213 break;3216 break;
3214 case HNS_ROCE_SQ_OPCODE_FAST_REG_WR:3217 case HNS_ROCE_V2_WQE_OP_FAST_REG_PMR:
3215 wc->opcode = IB_WC_REG_MR;3218 wc->opcode = IB_WC_REG_MR;
3216 break;3219 break;
3217 case HNS_ROCE_SQ_OPCODE_BIND_MW:3220 case HNS_ROCE_V2_WQE_OP_BIND_MW:
3218 wc->opcode = IB_WC_REG_MR;3221 wc->opcode = IB_WC_REG_MR;
3219 break;3222 break;
3220 default:3223 default:
@@ -3374,11 +3377,33 @@ static int get_op_for_set_hem(struct hns_roce_dev *hr_dev, u32 type, · 153 unmodified lines
3374 return op + step_idx;3377 return op + step_idx;
3375}3378}
3376 3379
3380static int set_hem_to_hw(struct hns_roce_dev *hr_dev, int obj, u64 bt_ba,
3381 u32 hem_type, int step_idx)
3382{
3383 struct hns_roce_cmd_mailbox *mailbox;
3384 int ret;
3385 int op;
3386
3387 op = get_op_for_set_hem(hr_dev, hem_type, step_idx);
3388 if (op < 0)
3389 return 0;
3390
3391 mailbox = hns_roce_alloc_cmd_mailbox(hr_dev);
3392 if (IS_ERR(mailbox))
3393 return PTR_ERR(mailbox);
3394
3395 ret = hns_roce_cmd_mbox(hr_dev, bt_ba, mailbox->dma, obj,
3396 0, op, HNS_ROCE_CMD_TIMEOUT_MSECS);
3397
3398 hns_roce_free_cmd_mailbox(hr_dev, mailbox);
3399
3400 return ret;
3401}
3402
3377static int hns_roce_v2_set_hem(struct hns_roce_dev *hr_dev,3403static int hns_roce_v2_set_hem(struct hns_roce_dev *hr_dev,
3378 struct hns_roce_hem_table *table, int obj,3404 struct hns_roce_hem_table *table, int obj,
3379 int step_idx)3405 int step_idx)
3380{3406{
3381 struct hns_roce_cmd_mailbox *mailbox;
3382 struct hns_roce_hem_iter iter;3407 struct hns_roce_hem_iter iter;
3383 struct hns_roce_hem_mhop mhop;3408 struct hns_roce_hem_mhop mhop;
3384 struct hns_roce_hem *hem;3409 struct hns_roce_hem *hem;
@@ -3390,7 +3415,6 @@ static int hns_roce_v2_set_hem(struct hns_roce_dev *hr_dev, · 5 unmodified lines
3390 u64 bt_ba = 0;3415 u64 bt_ba = 0;
3391 u32 chunk_ba_num;3416 u32 chunk_ba_num;
3392 u32 hop_num;3417 u32 hop_num;
3393 int op;
3394 3418
3395 if (!hns_roce_check_whether_mhop(hr_dev, table->type))3419 if (!hns_roce_check_whether_mhop(hr_dev, table->type))
3396 return 0;3420 return 0;
@@ -3412,14 +3436,6 @@ static int hns_roce_v2_set_hem(struct hns_roce_dev *hr_dev, · 15 unmodified lines
3412 hem_idx = i;3436 hem_idx = i;
3413 }3437 }
3414 3438
3415 op = get_op_for_set_hem(hr_dev, table->type, step_idx);
3416 if (op == -EINVAL)
3417 return 0;
3418
3419 mailbox = hns_roce_alloc_cmd_mailbox(hr_dev);
3420 if (IS_ERR(mailbox))
3421 return PTR_ERR(mailbox);
3422
3423 if (table->type == HEM_TYPE_SCCC)3439 if (table->type == HEM_TYPE_SCCC)
3424 obj = mhop.l0_idx;3440 obj = mhop.l0_idx;
3425 3441
@@ -3428,11 +3444,8 @@ static int hns_roce_v2_set_hem(struct hns_roce_dev *hr_dev, · 2 unmodified lines
3428 for (hns_roce_hem_first(hem, &iter);3444 for (hns_roce_hem_first(hem, &iter);
3429 !hns_roce_hem_last(&iter); hns_roce_hem_next(&iter)) {3445 !hns_roce_hem_last(&iter); hns_roce_hem_next(&iter)) {
3430 bt_ba = hns_roce_hem_addr(&iter);3446 bt_ba = hns_roce_hem_addr(&iter);
3431 3447 ret = set_hem_to_hw(hr_dev, obj, bt_ba, table->type,
3432 /* configure the ba, tag, and op */3448 step_idx);
3433 ret = hns_roce_cmd_mbox(hr_dev, bt_ba, mailbox->dma,
3434 obj, 0, op,
3435 HNS_ROCE_CMD_TIMEOUT_MSECS);
3436 }3449 }
3437 } else {3450 } else {
3438 if (step_idx == 0)3451 if (step_idx == 0)
@@ -3440,12 +3453,9 @@ static int hns_roce_v2_set_hem(struct hns_roce_dev *hr_dev, · 1 unmodified line
3440 else if (step_idx == 1 && hop_num == 2)3453 else if (step_idx == 1 && hop_num == 2)
3441 bt_ba = table->bt_l1_dma_addr[l1_idx];3454 bt_ba = table->bt_l1_dma_addr[l1_idx];
3442 3455
3443 /* configure the ba, tag, and op */3456 ret = set_hem_to_hw(hr_dev, obj, bt_ba, table->type, step_idx);
3444 ret = hns_roce_cmd_mbox(hr_dev, bt_ba, mailbox->dma, obj,
3445 0, op, HNS_ROCE_CMD_TIMEOUT_MSECS);
3446 }3457 }
3447 3458
3448 hns_roce_free_cmd_mailbox(hr_dev, mailbox);
3449 return ret;3459 return ret;
3450}3460}
3451 3461
@@ -3745,51 +3755,23 @@ static void modify_qp_init_to_init(struct ib_qp *ibqp, · 293 unmodified lines
3745 }3755 }
3746}3756}
3747 3757
3748static bool check_wqe_rq_mtt_count(struct hns_roce_dev *hr_dev,
3749 struct hns_roce_qp *hr_qp, int mtt_cnt,
3750 u32 page_size)
3751{
3752 struct ib_device *ibdev = &hr_dev->ib_dev;
3753
3754 if (hr_qp->rq.wqe_cnt < 1)
3755 return true;
3756
3757 if (mtt_cnt < 1) {
3758 ibdev_err(ibdev, "failed to find RQWQE buf ba of QP(0x%lx)\n",
3759 hr_qp->qpn);
3760 return false;
3761 }
3762
3763 if (mtt_cnt < MTT_MIN_COUNT &&
3764 (hr_qp->rq.offset + page_size) < hr_qp->buff_size) {
3765 ibdev_err(ibdev,
3766 "failed to find next RQWQE buf ba of QP(0x%lx)\n",
3767 hr_qp->qpn);
3768 return false;
3769 }
3770
3771 return true;
3772}
3773
3774static int config_qp_rq_buf(struct hns_roce_dev *hr_dev,3758static int config_qp_rq_buf(struct hns_roce_dev *hr_dev,
3775 struct hns_roce_qp *hr_qp,3759 struct hns_roce_qp *hr_qp,
3776 struct hns_roce_v2_qp_context *context,3760 struct hns_roce_v2_qp_context *context,
3777 struct hns_roce_v2_qp_context *qpc_mask)3761 struct hns_roce_v2_qp_context *qpc_mask)
3778{3762{
3779 struct ib_qp *ibqp = &hr_qp->ibqp;
3780 u64 mtts[MTT_MIN_COUNT] = { 0 };3763 u64 mtts[MTT_MIN_COUNT] = { 0 };
3781 u64 wqe_sge_ba;3764 u64 wqe_sge_ba;
3782 u32 page_size;
3783 int count;3765 int count;
3784 3766
3785 /* Search qp buf's mtts */3767 /* Search qp buf's mtts */
3786 page_size = 1 << hr_qp->mtr.hem_cfg.buf_pg_shift;3768 count = hns_roce_mtr_find(hr_dev, &hr_qp->mtr, hr_qp->rq.offset, mtts,
3787 count = hns_roce_mtr_find(hr_dev, &hr_qp->mtr,
3788 hr_qp->rq.offset / page_size, mtts,
3789 MTT_MIN_COUNT, &wqe_sge_ba);3769 MTT_MIN_COUNT, &wqe_sge_ba);
3790 if (!ibqp->srq)3770 if (hr_qp->rq.wqe_cnt && count < 1) {
3791 if (!check_wqe_rq_mtt_count(hr_dev, hr_qp, count, page_size))3771 ibdev_err(&hr_dev->ib_dev,
3792 return -EINVAL;3772 "failed to find RQ WQE, QPN = 0x%lx.\n", hr_qp->qpn);
3773 return -EINVAL;
3774 }
3793 3775
3794 context->wqe_sge_ba = cpu_to_le32(wqe_sge_ba >> 3);3776 context->wqe_sge_ba = cpu_to_le32(wqe_sge_ba >> 3);
3795 qpc_mask->wqe_sge_ba = 0;3777 qpc_mask->wqe_sge_ba = 0;
@@ -3891,7 +3873,6 @@ static int config_qp_sq_buf(struct hns_roce_dev *hr_dev, · 95 unmodified lines
3891 struct ib_device *ibdev = &hr_dev->ib_dev;3873 struct ib_device *ibdev = &hr_dev->ib_dev;
3892 u64 sge_cur_blk = 0;3874 u64 sge_cur_blk = 0;
3893 u64 sq_cur_blk = 0;3875 u64 sq_cur_blk = 0;
3894 u32 page_size;
3895 int count;3876 int count;
3896 3877
3897 /* search qp buf's mtts */3878 /* search qp buf's mtts */
@@ -3902,9 +3883,8 @@ static int config_qp_sq_buf(struct hns_roce_dev *hr_dev, · 4 unmodified lines
3902 return -EINVAL;3883 return -EINVAL;
3903 }3884 }
3904 if (hr_qp->sge.sge_cnt > 0) {3885 if (hr_qp->sge.sge_cnt > 0) {
3905 page_size = 1 << hr_qp->mtr.hem_cfg.buf_pg_shift;
3906 count = hns_roce_mtr_find(hr_dev, &hr_qp->mtr,3886 count = hns_roce_mtr_find(hr_dev, &hr_qp->mtr,
3907 hr_qp->sge.offset / page_size,3887 hr_qp->sge.offset,
3908 &sge_cur_blk, 1, NULL);3888 &sge_cur_blk, 1, NULL);
3909 if (count < 1) {3889 if (count < 1) {
3910 ibdev_err(ibdev, "failed to find QP(0x%lx) SGE buf.\n",3890 ibdev_err(ibdev, "failed to find QP(0x%lx) SGE buf.\n",
@@ -4265,12 +4245,13 @@ static int hns_roce_v2_set_path(struct ib_qp *ibqp, · 354 unmodified lines
4265 roce_set_field(qpc_mask->byte_24_mtu_tc, V2_QPC_BYTE_24_HOP_LIMIT_M,4245 roce_set_field(qpc_mask->byte_24_mtu_tc, V2_QPC_BYTE_24_HOP_LIMIT_M,
4266 V2_QPC_BYTE_24_HOP_LIMIT_S, 0);4246 V2_QPC_BYTE_24_HOP_LIMIT_S, 0);
4267 4247
4268 if (hr_dev->pci_dev->revision >= PCI_REVISION_ID_HIP08_B && is_udp)4248 if (is_udp)
4269 roce_set_field(context->byte_24_mtu_tc, V2_QPC_BYTE_24_TC_M,4249 roce_set_field(context->byte_24_mtu_tc, V2_QPC_BYTE_24_TC_M,
4270 V2_QPC_BYTE_24_TC_S, grh->traffic_class >> 2);4250 V2_QPC_BYTE_24_TC_S, grh->traffic_class >> 2);
4271 else4251 else
4272 roce_set_field(context->byte_24_mtu_tc, V2_QPC_BYTE_24_TC_M,4252 roce_set_field(context->byte_24_mtu_tc, V2_QPC_BYTE_24_TC_M,
4273 V2_QPC_BYTE_24_TC_S, grh->traffic_class);4253 V2_QPC_BYTE_24_TC_S, grh->traffic_class);
4254
4274 roce_set_field(qpc_mask->byte_24_mtu_tc, V2_QPC_BYTE_24_TC_M,4255 roce_set_field(qpc_mask->byte_24_mtu_tc, V2_QPC_BYTE_24_TC_M,
4275 V2_QPC_BYTE_24_TC_S, 0);4256 V2_QPC_BYTE_24_TC_S, 0);
4276 roce_set_field(context->byte_28_at_fl, V2_QPC_BYTE_28_FL_M,4257 roce_set_field(context->byte_28_at_fl, V2_QPC_BYTE_28_FL_M,
@@ -4301,7 +4282,9 @@ static bool check_qp_state(enum ib_qp_state cur_state, · 24 unmodified lines
4301 [IB_QPS_RTR] = { [IB_QPS_RESET] = true,4282 [IB_QPS_RTR] = { [IB_QPS_RESET] = true,
4302 [IB_QPS_RTS] = true,4283 [IB_QPS_RTS] = true,
4303 [IB_QPS_ERR] = true },4284 [IB_QPS_ERR] = true },
4304 [IB_QPS_RTS] = { [IB_QPS_RESET] = true, [IB_QPS_ERR] = true },4285 [IB_QPS_RTS] = { [IB_QPS_RESET] = true,
4286 [IB_QPS_RTS] = true,
4287 [IB_QPS_ERR] = true },
4305 [IB_QPS_SQD] = {},4288 [IB_QPS_SQD] = {},
4306 [IB_QPS_SQE] = {},4289 [IB_QPS_SQE] = {},
4307 [IB_QPS_ERR] = { [IB_QPS_RESET] = true, [IB_QPS_ERR] = true }4290 [IB_QPS_ERR] = { [IB_QPS_RESET] = true, [IB_QPS_ERR] = true }
drivers/infiniband/hw/hns/hns_roce_hw_v2.h+2−17
@@ -179,26 +179,10 @@ enum { · 178 unmodified lines
179 HNS_ROCE_V2_WQE_OP_ATOM_MSK_FETCH_AND_ADD = 0x9,179 HNS_ROCE_V2_WQE_OP_ATOM_MSK_FETCH_AND_ADD = 0x9,
180 HNS_ROCE_V2_WQE_OP_FAST_REG_PMR = 0xa,180 HNS_ROCE_V2_WQE_OP_FAST_REG_PMR = 0xa,
181 HNS_ROCE_V2_WQE_OP_LOCAL_INV = 0xb,181 HNS_ROCE_V2_WQE_OP_LOCAL_INV = 0xb,
182 HNS_ROCE_V2_WQE_OP_BIND_MW_TYPE = 0xc,182 HNS_ROCE_V2_WQE_OP_BIND_MW = 0xc,
183 HNS_ROCE_V2_WQE_OP_MASK = 0x1f,183 HNS_ROCE_V2_WQE_OP_MASK = 0x1f,
184};184};
185 185
186enum {
187 HNS_ROCE_SQ_OPCODE_SEND = 0x0,
188 HNS_ROCE_SQ_OPCODE_SEND_WITH_INV = 0x1,
189 HNS_ROCE_SQ_OPCODE_SEND_WITH_IMM = 0x2,
190 HNS_ROCE_SQ_OPCODE_RDMA_WRITE = 0x3,
191 HNS_ROCE_SQ_OPCODE_RDMA_WRITE_WITH_IMM = 0x4,
192 HNS_ROCE_SQ_OPCODE_RDMA_READ = 0x5,
193 HNS_ROCE_SQ_OPCODE_ATOMIC_COMP_AND_SWAP = 0x6,
194 HNS_ROCE_SQ_OPCODE_ATOMIC_FETCH_AND_ADD = 0x7,
195 HNS_ROCE_SQ_OPCODE_ATOMIC_MASK_COMP_AND_SWAP = 0x8,
196 HNS_ROCE_SQ_OPCODE_ATOMIC_MASK_FETCH_AND_ADD = 0x9,
197 HNS_ROCE_SQ_OPCODE_FAST_REG_WR = 0xa,
198 HNS_ROCE_SQ_OPCODE_LOCAL_INV = 0xb,
199 HNS_ROCE_SQ_OPCODE_BIND_MW = 0xc,
200};
201
202enum {186enum {
203 /* rq operations */187 /* rq operations */
204 HNS_ROCE_V2_OPCODE_RDMA_WRITE_IMM = 0x0,188 HNS_ROCE_V2_OPCODE_RDMA_WRITE_IMM = 0x0,
@@ -230,6 +214,7 @@ enum { · 25 unmodified lines
230 HNS_ROCE_CQE_V2_TRANSPORT_RETRY_EXC_ERR = 0x15,214 HNS_ROCE_CQE_V2_TRANSPORT_RETRY_EXC_ERR = 0x15,
231 HNS_ROCE_CQE_V2_RNR_RETRY_EXC_ERR = 0x16,215 HNS_ROCE_CQE_V2_RNR_RETRY_EXC_ERR = 0x16,
232 HNS_ROCE_CQE_V2_REMOTE_ABORT_ERR = 0x22,216 HNS_ROCE_CQE_V2_REMOTE_ABORT_ERR = 0x22,
217 HNS_ROCE_CQE_V2_GENERAL_ERR = 0x23,
233 218
234 HNS_ROCE_V2_CQE_STATUS_MASK = 0xff,219 HNS_ROCE_V2_CQE_STATUS_MASK = 0xff,
235};220};
drivers/infiniband/hw/hns/hns_roce_main.c+1−1
@@ -428,7 +428,7 @@ static const struct ib_device_ops hns_roce_dev_ops = { · 427 unmodified lines
428 .destroy_ah = hns_roce_destroy_ah,428 .destroy_ah = hns_roce_destroy_ah,
429 .destroy_cq = hns_roce_destroy_cq,429 .destroy_cq = hns_roce_destroy_cq,
430 .disassociate_ucontext = hns_roce_disassociate_ucontext,430 .disassociate_ucontext = hns_roce_disassociate_ucontext,
431 .fill_res_entry = hns_roce_fill_res_entry,431 .fill_res_cq_entry = hns_roce_fill_res_cq_entry,
432 .get_dma_mr = hns_roce_get_dma_mr,432 .get_dma_mr = hns_roce_get_dma_mr,
433 .get_link_layer = hns_roce_get_link_layer,433 .get_link_layer = hns_roce_get_link_layer,
434 .get_port_immutable = hns_roce_port_immutable,434 .get_port_immutable = hns_roce_port_immutable,
drivers/infiniband/hw/hns/hns_roce_mr.c+127−83
@@ -415,7 +415,7 @@ int hns_roce_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata) · 414 unmodified lines
415}415}
416 416
417struct ib_mr *hns_roce_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,417struct ib_mr *hns_roce_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
418 u32 max_num_sg, struct ib_udata *udata)418 u32 max_num_sg)
419{419{
420 struct hns_roce_dev *hr_dev = to_hr_dev(pd->device);420 struct hns_roce_dev *hr_dev = to_hr_dev(pd->device);
421 struct device *dev = hr_dev->dev;421 struct device *dev = hr_dev->dev;
@@ -871,6 +871,15 @@ int hns_roce_mtr_map(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr, · 449 unmodified lines
871 int err;871 int err;
872 int i;872 int i;
873 873
874 /*
875 * Only use the first page address as root ba when hopnum is 0, this
876 * is because the addresses of all pages are consecutive in this case.
877 */
878 if (mtr->hem_cfg.is_direct) {
879 mtr->hem_cfg.root_ba = pages[0];
880 return 0;
881 }
882
874 for (i = 0; i < mtr->hem_cfg.region_count; i++) {883 for (i = 0; i < mtr->hem_cfg.region_count; i++) {
875 r = &mtr->hem_cfg.region[i];884 r = &mtr->hem_cfg.region[i];
876 if (r->offset + r->count > page_cnt) {885 if (r->offset + r->count > page_cnt) {
@@ -896,6 +905,8 @@ int hns_roce_mtr_map(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr, · 19 unmodified lines
896int hns_roce_mtr_find(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,905int hns_roce_mtr_find(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
897 int offset, u64 *mtt_buf, int mtt_max, u64 *base_addr)906 int offset, u64 *mtt_buf, int mtt_max, u64 *base_addr)
898{907{
908 struct hns_roce_hem_cfg *cfg = &mtr->hem_cfg;
909 int start_index;
899 int mtt_count;910 int mtt_count;
900 int total = 0;911 int total = 0;
901 __le64 *mtts;912 __le64 *mtts;
@@ -907,26 +918,32 @@ int hns_roce_mtr_find(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr, · 5 unmodified lines
907 goto done;918 goto done;
908 919
909 /* no mtt memory in direct mode, so just return the buffer address */920 /* no mtt memory in direct mode, so just return the buffer address */
910 if (mtr->hem_cfg.is_direct) {921 if (cfg->is_direct) {
911 npage = offset;922 start_index = offset >> HNS_HW_PAGE_SHIFT;
912 for (total = 0; total < mtt_max; total++, npage++) {923 for (mtt_count = 0; mtt_count < cfg->region_count &&
913 addr = mtr->hem_cfg.root_ba +924 total < mtt_max; mtt_count++) {
914 (npage << mtr->hem_cfg.buf_pg_shift);925 npage = cfg->region[mtt_count].offset;
915 926 if (npage < start_index)
927 continue;
928
929 addr = cfg->root_ba + (npage << HNS_HW_PAGE_SHIFT);
916 if (hr_dev->hw_rev == HNS_ROCE_HW_VER1)930 if (hr_dev->hw_rev == HNS_ROCE_HW_VER1)
917 mtt_buf[total] = to_hr_hw_page_addr(addr);931 mtt_buf[total] = to_hr_hw_page_addr(addr);
918 else932 else
919 mtt_buf[total] = addr;933 mtt_buf[total] = addr;
934
935 total++;
920 }936 }
921 937
922 goto done;938 goto done;
923 }939 }
924 940
941 start_index = offset >> cfg->buf_pg_shift;
925 left = mtt_max;942 left = mtt_max;
926 while (left > 0) {943 while (left > 0) {
927 mtt_count = 0;944 mtt_count = 0;
928 mtts = hns_roce_hem_list_find_mtt(hr_dev, &mtr->hem_list,945 mtts = hns_roce_hem_list_find_mtt(hr_dev, &mtr->hem_list,
929 offset + total,946 start_index + total,
930 &mtt_count, NULL);947 &mtt_count, NULL);
931 if (!mtts || !mtt_count)948 if (!mtts || !mtt_count)
932 goto done;949 goto done;
@@ -939,104 +956,136 @@ int hns_roce_mtr_find(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr, · 6 unmodified lines
939 956
940done:957done:
941 if (base_addr)958 if (base_addr)
942 *base_addr = mtr->hem_cfg.root_ba;959 *base_addr = cfg->root_ba;
943 960
944 return total;961 return total;
945}962}
946 963
947/* convert buffer size to page index and page count */964static int mtr_init_buf_cfg(struct hns_roce_dev *hr_dev,
948static unsigned int mtr_init_region(struct hns_roce_buf_attr *attr,965 struct hns_roce_buf_attr *attr,
949 int page_cnt,966 struct hns_roce_hem_cfg *cfg,
950 struct hns_roce_buf_region *regions,967 unsigned int *buf_page_shift)
951 int region_cnt, unsigned int page_shift)
952{968{
953 unsigned int page_size = 1 << page_shift;
954 int max_region = attr->region_count;
955 struct hns_roce_buf_region *r;969 struct hns_roce_buf_region *r;
956 unsigned int i = 0;970 unsigned int page_shift = 0;
957 int page_idx = 0;971 int page_cnt = 0;
958 972 size_t buf_size;
959 for (; i < region_cnt && i < max_region && page_idx < page_cnt; i++) {973 int region_cnt;
960 r = &regions[i];974
961 r->hopnum = attr->region[i].hopnum == HNS_ROCE_HOP_NUM_0 ?975 if (cfg->is_direct) {
962 0 : attr->region[i].hopnum;976 buf_size = cfg->buf_pg_count << cfg->buf_pg_shift;
963 r->offset = page_idx;977 page_cnt = DIV_ROUND_UP(buf_size, HNS_HW_PAGE_SIZE);
964 r->count = DIV_ROUND_UP(attr->region[i].size, page_size);978 /*
965 page_idx += r->count;979 * When HEM buffer use level-0 addressing, the page size equals
980 * the buffer size, and the the page size = 4K * 2^N.
981 */
982 cfg->buf_pg_shift = HNS_HW_PAGE_SHIFT + order_base_2(page_cnt);
983 if (attr->region_count > 1) {
984 cfg->buf_pg_count = page_cnt;
985 page_shift = HNS_HW_PAGE_SHIFT;
986 } else {
987 cfg->buf_pg_count = 1;
988 page_shift = cfg->buf_pg_shift;
989 if (buf_size != 1 << page_shift) {
990 ibdev_err(&hr_dev->ib_dev,
991 "failed to check direct size %zu shift %d.\n",
992 buf_size, page_shift);
993 return -EINVAL;
994 }
995 }
996 } else {
997 page_shift = cfg->buf_pg_shift;
998 }
999
1000 /* convert buffer size to page index and page count */
1001 for (page_cnt = 0, region_cnt = 0; page_cnt < cfg->buf_pg_count &&
1002 region_cnt < attr->region_count &&
1003 region_cnt < ARRAY_SIZE(cfg->region); region_cnt++) {
1004 r = &cfg->region[region_cnt];
1005 r->offset = page_cnt;
1006 buf_size = hr_hw_page_align(attr->region[region_cnt].size);
1007 r->count = DIV_ROUND_UP(buf_size, 1 << page_shift);
1008 page_cnt += r->count;
1009 r->hopnum = to_hr_hem_hopnum(attr->region[region_cnt].hopnum,
1010 r->count);
1011 }
1012
1013 if (region_cnt < 1) {
1014 ibdev_err(&hr_dev->ib_dev,
1015 "failed to check mtr region count, pages = %d.\n",
1016 cfg->buf_pg_count);
1017 return -ENOBUFS;
966 }1018 }
967 1019
968 return i;1020 cfg->region_count = region_cnt;
1021 *buf_page_shift = page_shift;
1022
1023 return page_cnt;
969}1024}
970 1025
971/**1026/**
972 * hns_roce_mtr_create - Create hns memory translate region.1027 * hns_roce_mtr_create - Create hns memory translate region.
973 *1028 *
974 * @mtr: memory translate region1029 * @mtr: memory translate region
975 * @init_attr: init attribute for creating mtr1030 * @buf_attr: buffer attribute for creating mtr
976 * @page_shift: page shift for multi-hop base address table1031 * @ba_page_shift: page shift for multi-hop base address table
977 * @udata: user space context, if it's NULL, means kernel space1032 * @udata: user space context, if it's NULL, means kernel space
978 * @user_addr: userspace virtual address to start at1033 * @user_addr: userspace virtual address to start at
979 * @buf_alloced: mtr has private buffer, true means need to alloc
980 */1034 */
981int hns_roce_mtr_create(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,1035int hns_roce_mtr_create(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
982 struct hns_roce_buf_attr *buf_attr,1036 struct hns_roce_buf_attr *buf_attr,
983 unsigned int page_shift, struct ib_udata *udata,1037 unsigned int ba_page_shift, struct ib_udata *udata,
984 unsigned long user_addr)1038 unsigned long user_addr)
985{1039{
1040 struct hns_roce_hem_cfg *cfg = &mtr->hem_cfg;
986 struct ib_device *ibdev = &hr_dev->ib_dev;1041 struct ib_device *ibdev = &hr_dev->ib_dev;
1042 unsigned int buf_page_shift = 0;
987 dma_addr_t *pages = NULL;1043 dma_addr_t *pages = NULL;
988 int region_cnt = 0;
989 int all_pg_cnt;1044 int all_pg_cnt;
990 int get_pg_cnt;1045 int get_pg_cnt;
991 bool has_mtt;1046 int ret = 0;
992 int err = 0;1047
1048 /* if disable mtt, all pages must in a continuous address range */
1049 cfg->is_direct = !mtr_has_mtt(buf_attr);
993 1050
994 has_mtt = mtr_has_mtt(buf_attr);
995 /* if buffer only need mtt, just init the hem cfg */1051 /* if buffer only need mtt, just init the hem cfg */
996 if (buf_attr->mtt_only) {1052 if (buf_attr->mtt_only) {
997 mtr->hem_cfg.buf_pg_shift = buf_attr->page_shift;1053 cfg->buf_pg_shift = buf_attr->page_shift;
998 mtr->hem_cfg.buf_pg_count = mtr_bufs_size(buf_attr) >>1054 cfg->buf_pg_count = mtr_bufs_size(buf_attr) >>
999 buf_attr->page_shift;1055 buf_attr->page_shift;
1000 mtr->umem = NULL;1056 mtr->umem = NULL;
1001 mtr->kmem = NULL;1057 mtr->kmem = NULL;
1002 } else {1058 } else {
1003 err = mtr_alloc_bufs(hr_dev, mtr, buf_attr, !has_mtt, udata,1059 ret = mtr_alloc_bufs(hr_dev, mtr, buf_attr, cfg->is_direct,
1004 user_addr);1060 udata, user_addr);
1005 if (err) {1061 if (ret) {
1006 ibdev_err(ibdev, "Failed to alloc mtr bufs, err %d\n",1062 ibdev_err(ibdev,
1007 err);1063 "failed to alloc mtr bufs, ret = %d.\n", ret);
1008 return err;1064 return ret;
1009 }1065 }
1010 }1066 }
1011 1067
1012 /* alloc mtt memory */1068 all_pg_cnt = mtr_init_buf_cfg(hr_dev, buf_attr, cfg, &buf_page_shift);
1013 all_pg_cnt = mtr->hem_cfg.buf_pg_count;1069 if (all_pg_cnt < 1) {
1014 hns_roce_hem_list_init(&mtr->hem_list);1070 ret = -ENOBUFS;
1015 mtr->hem_cfg.is_direct = !has_mtt;1071 ibdev_err(ibdev, "failed to init mtr buf cfg.\n");
1016 mtr->hem_cfg.ba_pg_shift = page_shift;
1017 mtr->hem_cfg.region_count = 0;
1018 region_cnt = mtr_init_region(buf_attr, all_pg_cnt,
1019 mtr->hem_cfg.region,
1020 ARRAY_SIZE(mtr->hem_cfg.region),
1021 mtr->hem_cfg.buf_pg_shift);
1022 if (region_cnt < 1) {
1023 err = -ENOBUFS;
1024 ibdev_err(ibdev, "failed to init mtr region %d\n", region_cnt);
1025 goto err_alloc_bufs;1072 goto err_alloc_bufs;
1026 }1073 }
1027 1074
1028 mtr->hem_cfg.region_count = region_cnt;1075 hns_roce_hem_list_init(&mtr->hem_list);
1029 1076 if (!cfg->is_direct) {
1030 if (has_mtt) {1077 ret = hns_roce_hem_list_request(hr_dev, &mtr->hem_list,
1031 err = hns_roce_hem_list_request(hr_dev, &mtr->hem_list,1078 cfg->region, cfg->region_count,
1032 mtr->hem_cfg.region, region_cnt,1079 ba_page_shift);
1033 page_shift);1080 if (ret) {
1034 if (err) {1081 ibdev_err(ibdev, "failed to request mtr hem, ret = %d.\n",
1035 ibdev_err(ibdev, "Failed to request mtr hem, err %d\n",1082 ret);
1036 err);
1037 goto err_alloc_bufs;1083 goto err_alloc_bufs;
1038 }1084 }
1039 mtr->hem_cfg.root_ba = mtr->hem_list.root_ba;1085 cfg->root_ba = mtr->hem_list.root_ba;
1086 cfg->ba_pg_shift = ba_page_shift;
1087 } else {
1088 cfg->ba_pg_shift = cfg->buf_pg_shift;
1040 }1089 }
1041 1090
1042 /* no buffer to map */1091 /* no buffer to map */
@@ -1046,31 +1095,26 @@ int hns_roce_mtr_create(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr, · 3 unmodified lines
1046 /* alloc a tmp array to store buffer's dma address */1095 /* alloc a tmp array to store buffer's dma address */
1047 pages = kvcalloc(all_pg_cnt, sizeof(dma_addr_t), GFP_KERNEL);1096 pages = kvcalloc(all_pg_cnt, sizeof(dma_addr_t), GFP_KERNEL);
1048 if (!pages) {1097 if (!pages) {
1049 err = -ENOMEM;1098 ret = -ENOMEM;
1050 ibdev_err(ibdev, "Failed to alloc mtr page list %d\n",1099 ibdev_err(ibdev, "failed to alloc mtr page list %d.\n",
1051 all_pg_cnt);1100 all_pg_cnt);
1052 goto err_alloc_hem_list;1101 goto err_alloc_hem_list;
1053 }1102 }
1054 1103
1055 get_pg_cnt = mtr_get_pages(hr_dev, mtr, pages, all_pg_cnt,1104 get_pg_cnt = mtr_get_pages(hr_dev, mtr, pages, all_pg_cnt,
1056 mtr->hem_cfg.buf_pg_shift);1105 buf_page_shift);
1057 if (get_pg_cnt != all_pg_cnt) {1106 if (get_pg_cnt != all_pg_cnt) {
1058 ibdev_err(ibdev, "Failed to get mtr page %d != %d\n",1107 ibdev_err(ibdev, "failed to get mtr page %d != %d.\n",
1059 get_pg_cnt, all_pg_cnt);1108 get_pg_cnt, all_pg_cnt);
1060 err = -ENOBUFS;1109 ret = -ENOBUFS;
1061 goto err_alloc_page_list;1110 goto err_alloc_page_list;
1062 }1111 }
1063 1112
1064 if (!has_mtt) {1113 /* write buffer's dma address to BA table */
1065 mtr->hem_cfg.root_ba = pages[0];1114 ret = hns_roce_mtr_map(hr_dev, mtr, pages, all_pg_cnt);
1066 } else {1115 if (ret) {
1067 /* write buffer's dma address to BA table */1116 ibdev_err(ibdev, "failed to map mtr pages, ret = %d.\n", ret);
1068 err = hns_roce_mtr_map(hr_dev, mtr, pages, all_pg_cnt);1117 goto err_alloc_page_list;
1069 if (err) {
1070 ibdev_err(ibdev, "Failed to map mtr pages, err %d\n",
1071 err);
1072 goto err_alloc_page_list;
1073 }
1074 }1118 }
1075 1119
1076 /* drop tmp array */1120 /* drop tmp array */
@@ -1082,7 +1126,7 @@ err_alloc_hem_list: · 5 unmodified lines
1082 hns_roce_hem_list_release(hr_dev, &mtr->hem_list);1126 hns_roce_hem_list_release(hr_dev, &mtr->hem_list);
1083err_alloc_bufs:1127err_alloc_bufs:
1084 mtr_free_bufs(hr_dev, mtr);1128 mtr_free_bufs(hr_dev, mtr);
1085 return err;1129 return ret;
1086}1130}
1087 1131
1088void hns_roce_mtr_destroy(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr)1132void hns_roce_mtr_destroy(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr)
drivers/infiniband/hw/hns/hns_roce_qp.c+0−10
@@ -411,7 +411,6 @@ static int set_extend_sge_param(struct hns_roce_dev *hr_dev, u32 sq_wqe_cnt, · 410 unmodified lines
411 struct hns_roce_qp *hr_qp,411 struct hns_roce_qp *hr_qp,
412 struct ib_qp_cap *cap)412 struct ib_qp_cap *cap)
413{413{
414 struct ib_device *ibdev = &hr_dev->ib_dev;
415 u32 cnt;414 u32 cnt;
416 415
417 cnt = max(1U, cap->max_send_sge);416 cnt = max(1U, cap->max_send_sge);
@@ -431,15 +430,6 @@ static int set_extend_sge_param(struct hns_roce_dev *hr_dev, u32 sq_wqe_cnt, · 13 unmodified lines
431 } else if (hr_qp->sq.max_gs > HNS_ROCE_SGE_IN_WQE) {430 } else if (hr_qp->sq.max_gs > HNS_ROCE_SGE_IN_WQE) {
432 cnt = roundup_pow_of_two(sq_wqe_cnt *431 cnt = roundup_pow_of_two(sq_wqe_cnt *
433 (hr_qp->sq.max_gs - HNS_ROCE_SGE_IN_WQE));432 (hr_qp->sq.max_gs - HNS_ROCE_SGE_IN_WQE));
434
435 if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08_A) {
436 if (cnt > hr_dev->caps.max_extend_sg) {
437 ibdev_err(ibdev,
438 "failed to check exSGE num, exSGE num = %d.\n",
439 cnt);
440 return -EINVAL;
441 }
442 }
443 } else {433 } else {
444 cnt = 0;434 cnt = 0;
445 }435 }
drivers/infiniband/hw/hns/hns_roce_restrack.c+2−12
@@ -76,10 +76,9 @@ err: · 75 unmodified lines
76 return -EMSGSIZE;76 return -EMSGSIZE;
77}77}
78 78
79static int hns_roce_fill_res_cq_entry(struct sk_buff *msg,79int hns_roce_fill_res_cq_entry(struct sk_buff *msg,
80 struct rdma_restrack_entry *res)80 struct ib_cq *ib_cq)
81{81{
82 struct ib_cq *ib_cq = container_of(res, struct ib_cq, res);
83 struct hns_roce_dev *hr_dev = to_hr_dev(ib_cq->device);82 struct hns_roce_dev *hr_dev = to_hr_dev(ib_cq->device);
84 struct hns_roce_cq *hr_cq = to_hr_cq(ib_cq);83 struct hns_roce_cq *hr_cq = to_hr_cq(ib_cq);
85 struct hns_roce_v2_cq_context *context;84 struct hns_roce_v2_cq_context *context;
@@ -119,12 +118,3 @@ err: · 33 unmodified lines
119 kfree(context);118 kfree(context);
120 return ret;119 return ret;
121}120}
122
123int hns_roce_fill_res_entry(struct sk_buff *msg,
124 struct rdma_restrack_entry *res)
125{
126 if (res->type == RDMA_RESTRACK_CQ)
127 return hns_roce_fill_res_cq_entry(msg, res);
128
129 return 0;
130}
drivers/infiniband/hw/i40iw/i40iw_verbs.c+1−21
@@ -101,7 +101,6 @@ static int i40iw_query_port(struct ib_device *ibdev, · 100 unmodified lines
101 props->port_cap_flags = IB_PORT_CM_SUP | IB_PORT_REINIT_SUP |101 props->port_cap_flags = IB_PORT_CM_SUP | IB_PORT_REINIT_SUP |
102 IB_PORT_VENDOR_CLASS_SUP | IB_PORT_BOOT_MGMT_SUP;102 IB_PORT_VENDOR_CLASS_SUP | IB_PORT_BOOT_MGMT_SUP;
103 props->gid_tbl_len = 1;103 props->gid_tbl_len = 1;
104 props->pkey_tbl_len = 1;
105 props->active_width = IB_WIDTH_4X;104 props->active_width = IB_WIDTH_4X;
106 props->active_speed = 1;105 props->active_speed = 1;
107 props->max_msg_sz = I40IW_MAX_OUTBOUND_MESSAGE_SIZE;106 props->max_msg_sz = I40IW_MAX_OUTBOUND_MESSAGE_SIZE;
@@ -1543,10 +1542,9 @@ static int i40iw_hw_alloc_stag(struct i40iw_device *iwdev, struct i40iw_mr *iwmr · 1435 unmodified lines
1543 * @pd: ibpd pointer1542 * @pd: ibpd pointer
1544 * @mr_type: memory for stag registrion1543 * @mr_type: memory for stag registrion
1545 * @max_num_sg: man number of pages1544 * @max_num_sg: man number of pages
1546 * @udata: user data or NULL for kernel objects
1547 */1545 */
1548static struct ib_mr *i40iw_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,1546static struct ib_mr *i40iw_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
1549 u32 max_num_sg, struct ib_udata *udata)1547 u32 max_num_sg)
1550{1548{
1551 struct i40iw_pd *iwpd = to_iwpd(pd);1549 struct i40iw_pd *iwpd = to_iwpd(pd);
1552 struct i40iw_device *iwdev = to_iwdev(pd->device);1550 struct i40iw_device *iwdev = to_iwdev(pd->device);
@@ -2460,7 +2458,6 @@ static int i40iw_port_immutable(struct ib_device *ibdev, u8 port_num, · 907 unmodified lines
2460 if (err)2458 if (err)
2461 return err;2459 return err;
2462 2460
2463 immutable->pkey_tbl_len = attr.pkey_tbl_len;
2464 immutable->gid_tbl_len = attr.gid_tbl_len;2461 immutable->gid_tbl_len = attr.gid_tbl_len;
2465 2462
2466 return 0;2463 return 0;
@@ -2616,22 +2613,6 @@ static int i40iw_query_gid(struct ib_device *ibdev, · 149 unmodified lines
2616 return 0;2613 return 0;
2617}2614}
2618 2615
2619/**
2620 * i40iw_query_pkey - Query partition key
2621 * @ibdev: device pointer from stack
2622 * @port: port number
2623 * @index: index of pkey
2624 * @pkey: pointer to store the pkey
2625 */
2626static int i40iw_query_pkey(struct ib_device *ibdev,
2627 u8 port,
2628 u16 index,
2629 u16 *pkey)
2630{
2631 *pkey = 0;
2632 return 0;
2633}
2634
2635static const struct ib_device_ops i40iw_dev_ops = {2616static const struct ib_device_ops i40iw_dev_ops = {
2636 .owner = THIS_MODULE,2617 .owner = THIS_MODULE,
2637 .driver_id = RDMA_DRIVER_I40IW,2618 .driver_id = RDMA_DRIVER_I40IW,
@@ -2671,7 +2652,6 @@ static const struct ib_device_ops i40iw_dev_ops = { · 33 unmodified lines
2671 .post_send = i40iw_post_send,2652 .post_send = i40iw_post_send,
2672 .query_device = i40iw_query_device,2653 .query_device = i40iw_query_device,
2673 .query_gid = i40iw_query_gid,2654 .query_gid = i40iw_query_gid,
2674 .query_pkey = i40iw_query_pkey,
2675 .query_port = i40iw_query_port,2655 .query_port = i40iw_query_port,
2676 .query_qp = i40iw_query_qp,2656 .query_qp = i40iw_query_qp,
2677 .reg_user_mr = i40iw_reg_user_mr,2657 .reg_user_mr = i40iw_reg_user_mr,
drivers/infiniband/hw/mlx4/main.c+15−22
@@ -1219,56 +1219,47 @@ static void mlx4_ib_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata) · 1218 unmodified lines
1219 mlx4_pd_free(to_mdev(pd->device)->dev, to_mpd(pd)->pdn);1219 mlx4_pd_free(to_mdev(pd->device)->dev, to_mpd(pd)->pdn);
1220}1220}
1221 1221
1222static struct ib_xrcd *mlx4_ib_alloc_xrcd(struct ib_device *ibdev,1222static int mlx4_ib_alloc_xrcd(struct ib_xrcd *ibxrcd, struct ib_udata *udata)
1223 struct ib_udata *udata)
1224{1223{
1225 struct mlx4_ib_xrcd *xrcd;1224 struct mlx4_ib_dev *dev = to_mdev(ibxrcd->device);
1225 struct mlx4_ib_xrcd *xrcd = to_mxrcd(ibxrcd);
1226 struct ib_cq_init_attr cq_attr = {};1226 struct ib_cq_init_attr cq_attr = {};
1227 int err;1227 int err;
1228 1228
1229 if (!(to_mdev(ibdev)->dev->caps.flags & MLX4_DEV_CAP_FLAG_XRC))1229 if (!(dev->dev->caps.flags & MLX4_DEV_CAP_FLAG_XRC))
1230 return ERR_PTR(-ENOSYS);1230 return -EOPNOTSUPP;
1231
1232 xrcd = kmalloc(sizeof *xrcd, GFP_KERNEL);
1233 if (!xrcd)
1234 return ERR_PTR(-ENOMEM);
1235 1231
1236 err = mlx4_xrcd_alloc(to_mdev(ibdev)->dev, &xrcd->xrcdn);1232 err = mlx4_xrcd_alloc(dev->dev, &xrcd->xrcdn);
1237 if (err)1233 if (err)
1238 goto err1;1234 return err;
1239 1235
1240 xrcd->pd = ib_alloc_pd(ibdev, 0);1236 xrcd->pd = ib_alloc_pd(ibxrcd->device, 0);
1241 if (IS_ERR(xrcd->pd)) {1237 if (IS_ERR(xrcd->pd)) {
1242 err = PTR_ERR(xrcd->pd);1238 err = PTR_ERR(xrcd->pd);
1243 goto err2;1239 goto err2;
1244 }1240 }
1245 1241
1246 cq_attr.cqe = 1;1242 cq_attr.cqe = 1;
1247 xrcd->cq = ib_create_cq(ibdev, NULL, NULL, xrcd, &cq_attr);1243 xrcd->cq = ib_create_cq(ibxrcd->device, NULL, NULL, xrcd, &cq_attr);
1248 if (IS_ERR(xrcd->cq)) {1244 if (IS_ERR(xrcd->cq)) {
1249 err = PTR_ERR(xrcd->cq);1245 err = PTR_ERR(xrcd->cq);
1250 goto err3;1246 goto err3;
1251 }1247 }
1252 1248
1253 return &xrcd->ibxrcd;1249 return 0;
1254 1250
1255err3:1251err3:
1256 ib_dealloc_pd(xrcd->pd);1252 ib_dealloc_pd(xrcd->pd);
1257err2:1253err2:
1258 mlx4_xrcd_free(to_mdev(ibdev)->dev, xrcd->xrcdn);1254 mlx4_xrcd_free(dev->dev, xrcd->xrcdn);
1259err1:1255 return err;
1260 kfree(xrcd);
1261 return ERR_PTR(err);
1262}1256}
1263 1257
1264static int mlx4_ib_dealloc_xrcd(struct ib_xrcd *xrcd, struct ib_udata *udata)1258static void mlx4_ib_dealloc_xrcd(struct ib_xrcd *xrcd, struct ib_udata *udata)
1265{1259{
1266 ib_destroy_cq(to_mxrcd(xrcd)->cq);1260 ib_destroy_cq(to_mxrcd(xrcd)->cq);
1267 ib_dealloc_pd(to_mxrcd(xrcd)->pd);1261 ib_dealloc_pd(to_mxrcd(xrcd)->pd);
1268 mlx4_xrcd_free(to_mdev(xrcd->device)->dev, to_mxrcd(xrcd)->xrcdn);1262 mlx4_xrcd_free(to_mdev(xrcd->device)->dev, to_mxrcd(xrcd)->xrcdn);
1269 kfree(xrcd);
1270
1271 return 0;
1272}1263}
1273 1264
1274static int add_gid_entry(struct ib_qp *ibqp, union ib_gid *gid)1265static int add_gid_entry(struct ib_qp *ibqp, union ib_gid *gid)
@@ -2607,6 +2598,8 @@ static const struct ib_device_ops mlx4_ib_dev_mw_ops = { · 1332 unmodified lines
2607static const struct ib_device_ops mlx4_ib_dev_xrc_ops = {2598static const struct ib_device_ops mlx4_ib_dev_xrc_ops = {
2608 .alloc_xrcd = mlx4_ib_alloc_xrcd,2599 .alloc_xrcd = mlx4_ib_alloc_xrcd,
2609 .dealloc_xrcd = mlx4_ib_dealloc_xrcd,2600 .dealloc_xrcd = mlx4_ib_dealloc_xrcd,
2601
2602 INIT_RDMA_OBJ_SIZE(ib_xrcd, mlx4_ib_xrcd, ibxrcd),
2610};2603};
2611 2604
2612static const struct ib_device_ops mlx4_ib_dev_fs_ops = {2605static const struct ib_device_ops mlx4_ib_dev_fs_ops = {
drivers/infiniband/hw/mlx4/mlx4_ib.h+1−1
@@ -729,7 +729,7 @@ struct ib_mw *mlx4_ib_alloc_mw(struct ib_pd *pd, enum ib_mw_type type, · 728 unmodified lines
729 struct ib_udata *udata);729 struct ib_udata *udata);
730int mlx4_ib_dealloc_mw(struct ib_mw *mw);730int mlx4_ib_dealloc_mw(struct ib_mw *mw);
731struct ib_mr *mlx4_ib_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,731struct ib_mr *mlx4_ib_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
732 u32 max_num_sg, struct ib_udata *udata);732 u32 max_num_sg);
733int mlx4_ib_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,733int mlx4_ib_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,
734 unsigned int *sg_offset);734 unsigned int *sg_offset);
735int mlx4_ib_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period);735int mlx4_ib_modify_cq(struct ib_cq *cq, u16 cq_count, u16 cq_period);
drivers/infiniband/hw/mlx4/mr.c+1−2
@@ -439,7 +439,6 @@ struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, · 438 unmodified lines
439 439
440 mr->ibmr.rkey = mr->ibmr.lkey = mr->mmr.key;440 mr->ibmr.rkey = mr->ibmr.lkey = mr->mmr.key;
441 mr->ibmr.length = length;441 mr->ibmr.length = length;
442 mr->ibmr.iova = virt_addr;
443 mr->ibmr.page_size = 1U << shift;442 mr->ibmr.page_size = 1U << shift;
444 443
445 return &mr->ibmr;444 return &mr->ibmr;
@@ -655,7 +654,7 @@ int mlx4_ib_dealloc_mw(struct ib_mw *ibmw) · 209 unmodified lines
655}654}
656 655
657struct ib_mr *mlx4_ib_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,656struct ib_mr *mlx4_ib_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
658 u32 max_num_sg, struct ib_udata *udata)657 u32 max_num_sg)
659{658{
660 struct mlx4_ib_dev *dev = to_mdev(pd->device);659 struct mlx4_ib_dev *dev = to_mdev(pd->device);
661 struct mlx4_ib_mr *mr;660 struct mlx4_ib_mr *mr;
drivers/infiniband/hw/mlx5/Makefile+4−2
@@ -4,6 +4,7 @@ obj-$(CONFIG_MLX5_INFINIBAND) += mlx5_ib.o · 3 unmodified lines
4mlx5_ib-y := ah.o \4mlx5_ib-y := ah.o \
5 cmd.o \5 cmd.o \
6 cong.o \6 cong.o \
7 counters.o \
7 cq.o \8 cq.o \
8 doorbell.o \9 doorbell.o \
9 gsi.o \10 gsi.o \
@@ -22,5 +23,6 @@ mlx5_ib-y := ah.o \ · 12 unmodified lines
22mlx5_ib-$(CONFIG_INFINIBAND_ON_DEMAND_PAGING) += odp.o23mlx5_ib-$(CONFIG_INFINIBAND_ON_DEMAND_PAGING) += odp.o
23mlx5_ib-$(CONFIG_MLX5_ESWITCH) += ib_rep.o24mlx5_ib-$(CONFIG_MLX5_ESWITCH) += ib_rep.o
24mlx5_ib-$(CONFIG_INFINIBAND_USER_ACCESS) += devx.o \25mlx5_ib-$(CONFIG_INFINIBAND_USER_ACCESS) += devx.o \
25 flow.o \26 fs.o \
26 qos.o27 qos.o \
28 std_types.o
drivers/infiniband/hw/mlx5/cmd.c+0−12
@@ -148,18 +148,6 @@ void mlx5_cmd_dealloc_memic(struct mlx5_dm *dm, phys_addr_t addr, u64 length) · 147 unmodified lines
148 spin_unlock(&dm->lock);148 spin_unlock(&dm->lock);
149}149}
150 150
151int mlx5_cmd_query_ext_ppcnt_counters(struct mlx5_core_dev *dev, void *out)
152{
153 u32 in[MLX5_ST_SZ_DW(ppcnt_reg)] = {};
154 int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
155
156 MLX5_SET(ppcnt_reg, in, local_port, 1);
157
158 MLX5_SET(ppcnt_reg, in, grp, MLX5_ETHERNET_EXTENDED_COUNTERS_GROUP);
159 return mlx5_core_access_reg(dev, in, sz, out, sz, MLX5_REG_PPCNT,
160 0, 0);
161}
162
163void mlx5_cmd_destroy_tir(struct mlx5_core_dev *dev, u32 tirn, u16 uid)151void mlx5_cmd_destroy_tir(struct mlx5_core_dev *dev, u32 tirn, u16 uid)
164{152{
165 u32 in[MLX5_ST_SZ_DW(destroy_tir_in)] = {};153 u32 in[MLX5_ST_SZ_DW(destroy_tir_in)] = {};
drivers/infiniband/hw/mlx5/cmd.h+0−1
@@ -41,7 +41,6 @@ int mlx5_cmd_dump_fill_mkey(struct mlx5_core_dev *dev, u32 *mkey); · 40 unmodified lines
41int mlx5_cmd_null_mkey(struct mlx5_core_dev *dev, u32 *null_mkey);41int mlx5_cmd_null_mkey(struct mlx5_core_dev *dev, u32 *null_mkey);
42int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point,42int mlx5_cmd_query_cong_params(struct mlx5_core_dev *dev, int cong_point,
43 void *out);43 void *out);
44int mlx5_cmd_query_ext_ppcnt_counters(struct mlx5_core_dev *dev, void *out);
45int mlx5_cmd_alloc_memic(struct mlx5_dm *dm, phys_addr_t *addr,44int mlx5_cmd_alloc_memic(struct mlx5_dm *dm, phys_addr_t *addr,
46 u64 length, u32 alignment);45 u64 length, u32 alignment);
47void mlx5_cmd_dealloc_memic(struct mlx5_dm *dm, phys_addr_t addr, u64 length);46void mlx5_cmd_dealloc_memic(struct mlx5_dm *dm, phys_addr_t addr, u64 length);
drivers/infiniband/hw/mlx5/counters.c+709−0
@@ -0,0 +1,709 @@
1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2/*
3 * Copyright (c) 2013-2020, Mellanox Technologies inc. All rights reserved.
4 */
5
6#include "mlx5_ib.h"
7#include <linux/mlx5/eswitch.h>
8#include "counters.h"
9#include "ib_rep.h"
10#include "qp.h"
11
12struct mlx5_ib_counter {
13 const char *name;
14 size_t offset;
15};
16
17#define INIT_Q_COUNTER(_name) \
18 { .name = #_name, .offset = MLX5_BYTE_OFF(query_q_counter_out, _name)}
19
20static const struct mlx5_ib_counter basic_q_cnts[] = {
21 INIT_Q_COUNTER(rx_write_requests),
22 INIT_Q_COUNTER(rx_read_requests),
23 INIT_Q_COUNTER(rx_atomic_requests),
24 INIT_Q_COUNTER(out_of_buffer),
25};
26
27static const struct mlx5_ib_counter out_of_seq_q_cnts[] = {
28 INIT_Q_COUNTER(out_of_sequence),
29};
30
31static const struct mlx5_ib_counter retrans_q_cnts[] = {
32 INIT_Q_COUNTER(duplicate_request),
33 INIT_Q_COUNTER(rnr_nak_retry_err),
34 INIT_Q_COUNTER(packet_seq_err),
35 INIT_Q_COUNTER(implied_nak_seq_err),
36 INIT_Q_COUNTER(local_ack_timeout_err),
37};
38
39#define INIT_CONG_COUNTER(_name) \
40 { .name = #_name, .offset = \
41 MLX5_BYTE_OFF(query_cong_statistics_out, _name ## _high)}
42
43static const struct mlx5_ib_counter cong_cnts[] = {
44 INIT_CONG_COUNTER(rp_cnp_ignored),
45 INIT_CONG_COUNTER(rp_cnp_handled),
46 INIT_CONG_COUNTER(np_ecn_marked_roce_packets),
47 INIT_CONG_COUNTER(np_cnp_sent),
48};
49
50static const struct mlx5_ib_counter extended_err_cnts[] = {
51 INIT_Q_COUNTER(resp_local_length_error),
52 INIT_Q_COUNTER(resp_cqe_error),
53 INIT_Q_COUNTER(req_cqe_error),
54 INIT_Q_COUNTER(req_remote_invalid_request),
55 INIT_Q_COUNTER(req_remote_access_errors),
56 INIT_Q_COUNTER(resp_remote_access_errors),
57 INIT_Q_COUNTER(resp_cqe_flush_error),
58 INIT_Q_COUNTER(req_cqe_flush_error),
59};
60
61static const struct mlx5_ib_counter roce_accl_cnts[] = {
62 INIT_Q_COUNTER(roce_adp_retrans),
63 INIT_Q_COUNTER(roce_adp_retrans_to),
64 INIT_Q_COUNTER(roce_slow_restart),
65 INIT_Q_COUNTER(roce_slow_restart_cnps),
66 INIT_Q_COUNTER(roce_slow_restart_trans),
67};
68
69#define INIT_EXT_PPCNT_COUNTER(_name) \
70 { .name = #_name, .offset = \
71 MLX5_BYTE_OFF(ppcnt_reg, \
72 counter_set.eth_extended_cntrs_grp_data_layout._name##_high)}
73
74static const struct mlx5_ib_counter ext_ppcnt_cnts[] = {
75 INIT_EXT_PPCNT_COUNTER(rx_icrc_encapsulated),
76};
77
78static int mlx5_ib_read_counters(struct ib_counters *counters,
79 struct ib_counters_read_attr *read_attr,
80 struct uverbs_attr_bundle *attrs)
81{
82 struct mlx5_ib_mcounters *mcounters = to_mcounters(counters);
83 struct mlx5_read_counters_attr mread_attr = {};
84 struct mlx5_ib_flow_counters_desc *desc;
85 int ret, i;
86
87 mutex_lock(&mcounters->mcntrs_mutex);
88 if (mcounters->cntrs_max_index > read_attr->ncounters) {
89 ret = -EINVAL;
90 goto err_bound;
91 }
92
93 mread_attr.out = kcalloc(mcounters->counters_num, sizeof(u64),
94 GFP_KERNEL);
95 if (!mread_attr.out) {
96 ret = -ENOMEM;
97 goto err_bound;
98 }
99
100 mread_attr.hw_cntrs_hndl = mcounters->hw_cntrs_hndl;
101 mread_attr.flags = read_attr->flags;
102 ret = mcounters->read_counters(counters->device, &mread_attr);
103 if (ret)
104 goto err_read;
105
106 /* do the pass over the counters data array to assign according to the
107 * descriptions and indexing pairs
108 */
109 desc = mcounters->counters_data;
110 for (i = 0; i < mcounters->ncounters; i++)
111 read_attr->counters_buff[desc[i].index] += mread_attr.out[desc[i].description];
112
113err_read:
114 kfree(mread_attr.out);
115err_bound:
116 mutex_unlock(&mcounters->mcntrs_mutex);
117 return ret;
118}
119
120static void mlx5_ib_destroy_counters(struct ib_counters *counters)
121{
122 struct mlx5_ib_mcounters *mcounters = to_mcounters(counters);
123
124 mlx5_ib_counters_clear_description(counters);
125 if (mcounters->hw_cntrs_hndl)
126 mlx5_fc_destroy(to_mdev(counters->device)->mdev,
127 mcounters->hw_cntrs_hndl);
128}
129
130static int mlx5_ib_create_counters(struct ib_counters *counters,
131 struct uverbs_attr_bundle *attrs)
132{
133 struct mlx5_ib_mcounters *mcounters = to_mcounters(counters);
134
135 mutex_init(&mcounters->mcntrs_mutex);
136 return 0;
137}
138
139
140static bool is_mdev_switchdev_mode(const struct mlx5_core_dev *mdev)
141{
142 return MLX5_ESWITCH_MANAGER(mdev) &&
143 mlx5_ib_eswitch_mode(mdev->priv.eswitch) ==
144 MLX5_ESWITCH_OFFLOADS;
145}
146
147static const struct mlx5_ib_counters *get_counters(struct mlx5_ib_dev *dev,
148 u8 port_num)
149{
150 return is_mdev_switchdev_mode(dev->mdev) ? &dev->port[0].cnts :
151 &dev->port[port_num].cnts;
152}
153
154/**
155 * mlx5_ib_get_counters_id - Returns counters id to use for device+port
156 * @dev: Pointer to mlx5 IB device
157 * @port_num: Zero based port number
158 *
159 * mlx5_ib_get_counters_id() Returns counters set id to use for given
160 * device port combination in switchdev and non switchdev mode of the
161 * parent device.
162 */
163u16 mlx5_ib_get_counters_id(struct mlx5_ib_dev *dev, u8 port_num)
164{
165 const struct mlx5_ib_counters *cnts = get_counters(dev, port_num);
166
167 return cnts->set_id;
168}
169
170static struct rdma_hw_stats *mlx5_ib_alloc_hw_stats(struct ib_device *ibdev,
171 u8 port_num)
172{
173 struct mlx5_ib_dev *dev = to_mdev(ibdev);
174 const struct mlx5_ib_counters *cnts;
175 bool is_switchdev = is_mdev_switchdev_mode(dev->mdev);
176
177 if ((is_switchdev && port_num) || (!is_switchdev && !port_num))
178 return NULL;
179
180 cnts = get_counters(dev, port_num - 1);
181
182 return rdma_alloc_hw_stats_struct(cnts->names,
183 cnts->num_q_counters +
184 cnts->num_cong_counters +
185 cnts->num_ext_ppcnt_counters,
186 RDMA_HW_STATS_DEFAULT_LIFESPAN);
187}
188
189static int mlx5_ib_query_q_counters(struct mlx5_core_dev *mdev,
190 const struct mlx5_ib_counters *cnts,
191 struct rdma_hw_stats *stats,
192 u16 set_id)
193{
194 u32 out[MLX5_ST_SZ_DW(query_q_counter_out)] = {};
195 u32 in[MLX5_ST_SZ_DW(query_q_counter_in)] = {};
196 __be32 val;
197 int ret, i;
198
199 MLX5_SET(query_q_counter_in, in, opcode, MLX5_CMD_OP_QUERY_Q_COUNTER);
200 MLX5_SET(query_q_counter_in, in, counter_set_id, set_id);
201 ret = mlx5_cmd_exec_inout(mdev, query_q_counter, in, out);
202 if (ret)
203 return ret;
204
205 for (i = 0; i < cnts->num_q_counters; i++) {
206 val = *(__be32 *)((void *)out + cnts->offsets[i]);
207 stats->value[i] = (u64)be32_to_cpu(val);
208 }
209
210 return 0;
211}
212
213static int mlx5_ib_query_ext_ppcnt_counters(struct mlx5_ib_dev *dev,
214 const struct mlx5_ib_counters *cnts,
215 struct rdma_hw_stats *stats)
216{
217 int offset = cnts->num_q_counters + cnts->num_cong_counters;
218 u32 in[MLX5_ST_SZ_DW(ppcnt_reg)] = {};
219 int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
220 int ret, i;
221 void *out;
222
223 out = kvzalloc(sz, GFP_KERNEL);
224 if (!out)
225 return -ENOMEM;
226
227 MLX5_SET(ppcnt_reg, in, local_port, 1);
228 MLX5_SET(ppcnt_reg, in, grp, MLX5_ETHERNET_EXTENDED_COUNTERS_GROUP);
229 ret = mlx5_core_access_reg(dev->mdev, in, sz, out, sz, MLX5_REG_PPCNT,
230 0, 0);
231 if (ret)
232 goto free;
233
234 for (i = 0; i < cnts->num_ext_ppcnt_counters; i++)
235 stats->value[i + offset] =
236 be64_to_cpup((__be64 *)(out +
237 cnts->offsets[i + offset]));
238free:
239 kvfree(out);
240 return ret;
241}
242
243static int mlx5_ib_get_hw_stats(struct ib_device *ibdev,
244 struct rdma_hw_stats *stats,
245 u8 port_num, int index)
246{
247 struct mlx5_ib_dev *dev = to_mdev(ibdev);
248 const struct mlx5_ib_counters *cnts = get_counters(dev, port_num - 1);
249 struct mlx5_core_dev *mdev;
250 int ret, num_counters;
251 u8 mdev_port_num;
252
253 if (!stats)
254 return -EINVAL;
255
256 num_counters = cnts->num_q_counters +
257 cnts->num_cong_counters +
258 cnts->num_ext_ppcnt_counters;
259
260 /* q_counters are per IB device, query the master mdev */
261 ret = mlx5_ib_query_q_counters(dev->mdev, cnts, stats, cnts->set_id);
262 if (ret)
263 return ret;
264
265 if (MLX5_CAP_PCAM_FEATURE(dev->mdev, rx_icrc_encapsulated_counter)) {
266 ret = mlx5_ib_query_ext_ppcnt_counters(dev, cnts, stats);
267 if (ret)
268 return ret;
269 }
270
271 if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) {
272 mdev = mlx5_ib_get_native_port_mdev(dev, port_num,
273 &mdev_port_num);
274 if (!mdev) {
275 /* If port is not affiliated yet, its in down state
276 * which doesn't have any counters yet, so it would be
277 * zero. So no need to read from the HCA.
278 */
279 goto done;
280 }
281 ret = mlx5_lag_query_cong_counters(dev->mdev,
282 stats->value +
283 cnts->num_q_counters,
284 cnts->num_cong_counters,
285 cnts->offsets +
286 cnts->num_q_counters);
287
288 mlx5_ib_put_native_port_mdev(dev, port_num);
289 if (ret)
290 return ret;
291 }
292
293done:
294 return num_counters;
295}
296
297static struct rdma_hw_stats *
298mlx5_ib_counter_alloc_stats(struct rdma_counter *counter)
299{
300 struct mlx5_ib_dev *dev = to_mdev(counter->device);
301 const struct mlx5_ib_counters *cnts =
302 get_counters(dev, counter->port - 1);
303
304 return rdma_alloc_hw_stats_struct(cnts->names,
305 cnts->num_q_counters +
306 cnts->num_cong_counters +
307 cnts->num_ext_ppcnt_counters,
308 RDMA_HW_STATS_DEFAULT_LIFESPAN);
309}
310
311static int mlx5_ib_counter_update_stats(struct rdma_counter *counter)
312{
313 struct mlx5_ib_dev *dev = to_mdev(counter->device);
314 const struct mlx5_ib_counters *cnts =
315 get_counters(dev, counter->port - 1);
316
317 return mlx5_ib_query_q_counters(dev->mdev, cnts,
318 counter->stats, counter->id);
319}
320
321static int mlx5_ib_counter_dealloc(struct rdma_counter *counter)
322{
323 struct mlx5_ib_dev *dev = to_mdev(counter->device);
324 u32 in[MLX5_ST_SZ_DW(dealloc_q_counter_in)] = {};
325
326 if (!counter->id)
327 return 0;
328
329 MLX5_SET(dealloc_q_counter_in, in, opcode,
330 MLX5_CMD_OP_DEALLOC_Q_COUNTER);
331 MLX5_SET(dealloc_q_counter_in, in, counter_set_id, counter->id);
332 return mlx5_cmd_exec_in(dev->mdev, dealloc_q_counter, in);
333}
334
335static int mlx5_ib_counter_bind_qp(struct rdma_counter *counter,
336 struct ib_qp *qp)
337{
338 struct mlx5_ib_dev *dev = to_mdev(qp->device);
339 int err;
340
341 if (!counter->id) {
342 u32 out[MLX5_ST_SZ_DW(alloc_q_counter_out)] = {};
343 u32 in[MLX5_ST_SZ_DW(alloc_q_counter_in)] = {};
344
345 MLX5_SET(alloc_q_counter_in, in, opcode,
346 MLX5_CMD_OP_ALLOC_Q_COUNTER);
347 MLX5_SET(alloc_q_counter_in, in, uid, MLX5_SHARED_RESOURCE_UID);
348 err = mlx5_cmd_exec_inout(dev->mdev, alloc_q_counter, in, out);
349 if (err)
350 return err;
351 counter->id =
352 MLX5_GET(alloc_q_counter_out, out, counter_set_id);
353 }
354
355 err = mlx5_ib_qp_set_counter(qp, counter);
356 if (err)
357 goto fail_set_counter;
358
359 return 0;
360
361fail_set_counter:
362 mlx5_ib_counter_dealloc(counter);
363 counter->id = 0;
364
365 return err;
366}
367
368static int mlx5_ib_counter_unbind_qp(struct ib_qp *qp)
369{
370 return mlx5_ib_qp_set_counter(qp, NULL);
371}
372
373
374static void mlx5_ib_fill_counters(struct mlx5_ib_dev *dev,
375 const char **names,
376 size_t *offsets)
377{
378 int i;
379 int j = 0;
380
381 for (i = 0; i < ARRAY_SIZE(basic_q_cnts); i++, j++) {
382 names[j] = basic_q_cnts[i].name;
383 offsets[j] = basic_q_cnts[i].offset;
384 }
385
386 if (MLX5_CAP_GEN(dev->mdev, out_of_seq_cnt)) {
387 for (i = 0; i < ARRAY_SIZE(out_of_seq_q_cnts); i++, j++) {
388 names[j] = out_of_seq_q_cnts[i].name;
389 offsets[j] = out_of_seq_q_cnts[i].offset;
390 }
391 }
392
393 if (MLX5_CAP_GEN(dev->mdev, retransmission_q_counters)) {
394 for (i = 0; i < ARRAY_SIZE(retrans_q_cnts); i++, j++) {
395 names[j] = retrans_q_cnts[i].name;
396 offsets[j] = retrans_q_cnts[i].offset;
397 }
398 }
399
400 if (MLX5_CAP_GEN(dev->mdev, enhanced_error_q_counters)) {
401 for (i = 0; i < ARRAY_SIZE(extended_err_cnts); i++, j++) {
402 names[j] = extended_err_cnts[i].name;
403 offsets[j] = extended_err_cnts[i].offset;
404 }
405 }
406
407 if (MLX5_CAP_GEN(dev->mdev, roce_accl)) {
408 for (i = 0; i < ARRAY_SIZE(roce_accl_cnts); i++, j++) {
409 names[j] = roce_accl_cnts[i].name;
410 offsets[j] = roce_accl_cnts[i].offset;
411 }
412 }
413
414 if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) {
415 for (i = 0; i < ARRAY_SIZE(cong_cnts); i++, j++) {
416 names[j] = cong_cnts[i].name;
417 offsets[j] = cong_cnts[i].offset;
418 }
419 }
420
421 if (MLX5_CAP_PCAM_FEATURE(dev->mdev, rx_icrc_encapsulated_counter)) {
422 for (i = 0; i < ARRAY_SIZE(ext_ppcnt_cnts); i++, j++) {
423 names[j] = ext_ppcnt_cnts[i].name;
424 offsets[j] = ext_ppcnt_cnts[i].offset;
425 }
426 }
427}
428
429
430static int __mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev,
431 struct mlx5_ib_counters *cnts)
432{
433 u32 num_counters;
434
435 num_counters = ARRAY_SIZE(basic_q_cnts);
436
437 if (MLX5_CAP_GEN(dev->mdev, out_of_seq_cnt))
438 num_counters += ARRAY_SIZE(out_of_seq_q_cnts);
439
440 if (MLX5_CAP_GEN(dev->mdev, retransmission_q_counters))
441 num_counters += ARRAY_SIZE(retrans_q_cnts);
442
443 if (MLX5_CAP_GEN(dev->mdev, enhanced_error_q_counters))
444 num_counters += ARRAY_SIZE(extended_err_cnts);
445
446 if (MLX5_CAP_GEN(dev->mdev, roce_accl))
447 num_counters += ARRAY_SIZE(roce_accl_cnts);
448
449 cnts->num_q_counters = num_counters;
450
451 if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) {
452 cnts->num_cong_counters = ARRAY_SIZE(cong_cnts);
453 num_counters += ARRAY_SIZE(cong_cnts);
454 }
455 if (MLX5_CAP_PCAM_FEATURE(dev->mdev, rx_icrc_encapsulated_counter)) {
456 cnts->num_ext_ppcnt_counters = ARRAY_SIZE(ext_ppcnt_cnts);
457 num_counters += ARRAY_SIZE(ext_ppcnt_cnts);
458 }
459 cnts->names = kcalloc(num_counters, sizeof(cnts->names), GFP_KERNEL);
460 if (!cnts->names)
461 return -ENOMEM;
462
463 cnts->offsets = kcalloc(num_counters,
464 sizeof(cnts->offsets), GFP_KERNEL);
465 if (!cnts->offsets)
466 goto err_names;
467
468 return 0;
469
470err_names:
471 kfree(cnts->names);
472 cnts->names = NULL;
473 return -ENOMEM;
474}
475
476static void mlx5_ib_dealloc_counters(struct mlx5_ib_dev *dev)
477{
478 u32 in[MLX5_ST_SZ_DW(dealloc_q_counter_in)] = {};
479 int num_cnt_ports;
480 int i;
481
482 num_cnt_ports = is_mdev_switchdev_mode(dev->mdev) ? 1 : dev->num_ports;
483
484 MLX5_SET(dealloc_q_counter_in, in, opcode,
485 MLX5_CMD_OP_DEALLOC_Q_COUNTER);
486
487 for (i = 0; i < num_cnt_ports; i++) {
488 if (dev->port[i].cnts.set_id) {
489 MLX5_SET(dealloc_q_counter_in, in, counter_set_id,
490 dev->port[i].cnts.set_id);
491 mlx5_cmd_exec_in(dev->mdev, dealloc_q_counter, in);
492 }
493 kfree(dev->port[i].cnts.names);
494 kfree(dev->port[i].cnts.offsets);
495 }
496}
497
498static int mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev)
499{
500 u32 out[MLX5_ST_SZ_DW(alloc_q_counter_out)] = {};
501 u32 in[MLX5_ST_SZ_DW(alloc_q_counter_in)] = {};
502 int num_cnt_ports;
503 int err = 0;
504 int i;
505 bool is_shared;
506
507 MLX5_SET(alloc_q_counter_in, in, opcode, MLX5_CMD_OP_ALLOC_Q_COUNTER);
508 is_shared = MLX5_CAP_GEN(dev->mdev, log_max_uctx) != 0;
509 num_cnt_ports = is_mdev_switchdev_mode(dev->mdev) ? 1 : dev->num_ports;
510
511 for (i = 0; i < num_cnt_ports; i++) {
512 err = __mlx5_ib_alloc_counters(dev, &dev->port[i].cnts);
513 if (err)
514 goto err_alloc;
515
516 mlx5_ib_fill_counters(dev, dev->port[i].cnts.names,
517 dev->port[i].cnts.offsets);
518
519 MLX5_SET(alloc_q_counter_in, in, uid,
520 is_shared ? MLX5_SHARED_RESOURCE_UID : 0);
521
522 err = mlx5_cmd_exec_inout(dev->mdev, alloc_q_counter, in, out);
523 if (err) {
524 mlx5_ib_warn(dev,
525 "couldn't allocate queue counter for port %d, err %d\n",
526 i + 1, err);
527 goto err_alloc;
528 }
529
530 dev->port[i].cnts.set_id =
531 MLX5_GET(alloc_q_counter_out, out, counter_set_id);
532 }
533 return 0;
534
535err_alloc:
536 mlx5_ib_dealloc_counters(dev);
537 return err;
538}
539
540static int read_flow_counters(struct ib_device *ibdev,
541 struct mlx5_read_counters_attr *read_attr)
542{
543 struct mlx5_fc *fc = read_attr->hw_cntrs_hndl;
544 struct mlx5_ib_dev *dev = to_mdev(ibdev);
545
546 return mlx5_fc_query(dev->mdev, fc,
547 &read_attr->out[IB_COUNTER_PACKETS],
548 &read_attr->out[IB_COUNTER_BYTES]);
549}
550
551/* flow counters currently expose two counters packets and bytes */
552#define FLOW_COUNTERS_NUM 2
553static int counters_set_description(
554 struct ib_counters *counters, enum mlx5_ib_counters_type counters_type,
555 struct mlx5_ib_flow_counters_desc *desc_data, u32 ncounters)
556{
557 struct mlx5_ib_mcounters *mcounters = to_mcounters(counters);
558 u32 cntrs_max_index = 0;
559 int i;
560
561 if (counters_type != MLX5_IB_COUNTERS_FLOW)
562 return -EINVAL;
563
564 /* init the fields for the object */
565 mcounters->type = counters_type;
566 mcounters->read_counters = read_flow_counters;
567 mcounters->counters_num = FLOW_COUNTERS_NUM;
568 mcounters->ncounters = ncounters;
569 /* each counter entry have both description and index pair */
570 for (i = 0; i < ncounters; i++) {
571 if (desc_data[i].description > IB_COUNTER_BYTES)
572 return -EINVAL;
573
574 if (cntrs_max_index <= desc_data[i].index)
575 cntrs_max_index = desc_data[i].index + 1;
576 }
577
578 mutex_lock(&mcounters->mcntrs_mutex);
579 mcounters->counters_data = desc_data;
580 mcounters->cntrs_max_index = cntrs_max_index;
581 mutex_unlock(&mcounters->mcntrs_mutex);
582
583 return 0;
584}
585
586#define MAX_COUNTERS_NUM (USHRT_MAX / (sizeof(u32) * 2))
587int mlx5_ib_flow_counters_set_data(struct ib_counters *ibcounters,
588 struct mlx5_ib_create_flow *ucmd)
589{
590 struct mlx5_ib_mcounters *mcounters = to_mcounters(ibcounters);
591 struct mlx5_ib_flow_counters_data *cntrs_data = NULL;
592 struct mlx5_ib_flow_counters_desc *desc_data = NULL;
593 bool hw_hndl = false;
594 int ret = 0;
595
596 if (ucmd && ucmd->ncounters_data != 0) {
597 cntrs_data = ucmd->data;
598 if (cntrs_data->ncounters > MAX_COUNTERS_NUM)
599 return -EINVAL;
600
601 desc_data = kcalloc(cntrs_data->ncounters,
602 sizeof(*desc_data),
603 GFP_KERNEL);
604 if (!desc_data)
605 return -ENOMEM;
606
607 if (copy_from_user(desc_data,
608 u64_to_user_ptr(cntrs_data->counters_data),
609 sizeof(*desc_data) * cntrs_data->ncounters)) {
610 ret = -EFAULT;
611 goto free;
612 }
613 }
614
615 if (!mcounters->hw_cntrs_hndl) {
616 mcounters->hw_cntrs_hndl = mlx5_fc_create(
617 to_mdev(ibcounters->device)->mdev, false);
618 if (IS_ERR(mcounters->hw_cntrs_hndl)) {
619 ret = PTR_ERR(mcounters->hw_cntrs_hndl);
620 goto free;
621 }
622 hw_hndl = true;
623 }
624
625 if (desc_data) {
626 /* counters already bound to at least one flow */
627 if (mcounters->cntrs_max_index) {
628 ret = -EINVAL;
629 goto free_hndl;
630 }
631
632 ret = counters_set_description(ibcounters,
633 MLX5_IB_COUNTERS_FLOW,
634 desc_data,
635 cntrs_data->ncounters);
636 if (ret)
637 goto free_hndl;
638
639 } else if (!mcounters->cntrs_max_index) {
640 /* counters not bound yet, must have udata passed */
641 ret = -EINVAL;
642 goto free_hndl;
643 }
644
645 return 0;
646
647free_hndl:
648 if (hw_hndl) {
649 mlx5_fc_destroy(to_mdev(ibcounters->device)->mdev,
650 mcounters->hw_cntrs_hndl);
651 mcounters->hw_cntrs_hndl = NULL;
652 }
653free:
654 kfree(desc_data);
655 return ret;
656}
657
658void mlx5_ib_counters_clear_description(struct ib_counters *counters)
659{
660 struct mlx5_ib_mcounters *mcounters;
661
662 if (!counters || atomic_read(&counters->usecnt) != 1)
663 return;
664
665 mcounters = to_mcounters(counters);
666
667 mutex_lock(&mcounters->mcntrs_mutex);
668 kfree(mcounters->counters_data);
669 mcounters->counters_data = NULL;
670 mcounters->cntrs_max_index = 0;
671 mutex_unlock(&mcounters->mcntrs_mutex);
672}
673
674static const struct ib_device_ops hw_stats_ops = {
675 .alloc_hw_stats = mlx5_ib_alloc_hw_stats,
676 .get_hw_stats = mlx5_ib_get_hw_stats,
677 .counter_bind_qp = mlx5_ib_counter_bind_qp,
678 .counter_unbind_qp = mlx5_ib_counter_unbind_qp,
679 .counter_dealloc = mlx5_ib_counter_dealloc,
680 .counter_alloc_stats = mlx5_ib_counter_alloc_stats,
681 .counter_update_stats = mlx5_ib_counter_update_stats,
682};
683
684static const struct ib_device_ops counters_ops = {
685 .create_counters = mlx5_ib_create_counters,
686 .destroy_counters = mlx5_ib_destroy_counters,
687 .read_counters = mlx5_ib_read_counters,
688
689 INIT_RDMA_OBJ_SIZE(ib_counters, mlx5_ib_mcounters, ibcntrs),
690};
691
692int mlx5_ib_counters_init(struct mlx5_ib_dev *dev)
693{
694 ib_set_device_ops(&dev->ib_dev, &counters_ops);
695
696 if (!MLX5_CAP_GEN(dev->mdev, max_qp_cnt))
697 return 0;
698
699 ib_set_device_ops(&dev->ib_dev, &hw_stats_ops);
700 return mlx5_ib_alloc_counters(dev);
701}
702
703void mlx5_ib_counters_cleanup(struct mlx5_ib_dev *dev)
704{
705 if (!MLX5_CAP_GEN(dev->mdev, max_qp_cnt))
706 return;
707
708 mlx5_ib_dealloc_counters(dev);
709}
drivers/infiniband/hw/mlx5/counters.h+17−0
@@ -0,0 +1,17 @@
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
2/*
3 * Copyright (c) 2013-2020, Mellanox Technologies inc. All rights reserved.
4 */
5
6#ifndef _MLX5_IB_COUNTERS_H
7#define _MLX5_IB_COUNTERS_H
8
9#include "mlx5_ib.h"
10
11int mlx5_ib_counters_init(struct mlx5_ib_dev *dev);
12void mlx5_ib_counters_cleanup(struct mlx5_ib_dev *dev);
13void mlx5_ib_counters_clear_description(struct ib_counters *counters);
14int mlx5_ib_flow_counters_set_data(struct ib_counters *ibcounters,
15 struct mlx5_ib_create_flow *ucmd);
16u16 mlx5_ib_get_counters_id(struct mlx5_ib_dev *dev, u8 port_num);
17#endif /* _MLX5_IB_COUNTERS_H */
drivers/infiniband/hw/mlx5/devx.c+28−74
@@ -14,6 +14,7 @@ · 13 unmodified lines
14#include <linux/mlx5/driver.h>14#include <linux/mlx5/driver.h>
15#include <linux/mlx5/fs.h>15#include <linux/mlx5/fs.h>
16#include "mlx5_ib.h"16#include "mlx5_ib.h"
17#include "devx.h"
17#include "qp.h"18#include "qp.h"
18#include <linux/xarray.h>19#include <linux/xarray.h>
19 20
@@ -89,22 +90,6 @@ struct devx_async_event_file { · 69 unmodified lines
89 u8 is_destroyed:1;90 u8 is_destroyed:1;
90};91};
91 92
92#define MLX5_MAX_DESTROY_INBOX_SIZE_DW MLX5_ST_SZ_DW(delete_fte_in)
93struct devx_obj {
94 struct mlx5_ib_dev *ib_dev;
95 u64 obj_id;
96 u32 dinlen; /* destroy inbox length */
97 u32 dinbox[MLX5_MAX_DESTROY_INBOX_SIZE_DW];
98 u32 flags;
99 union {
100 struct mlx5_ib_devx_mr devx_mr;
101 struct mlx5_core_dct core_dct;
102 struct mlx5_core_cq core_cq;
103 u32 flow_counter_bulk_size;
104 };
105 struct list_head event_sub; /* holds devx_event_subscription entries */
106};
107
108struct devx_umem {93struct devx_umem {
109 struct mlx5_core_dev *mdev;94 struct mlx5_core_dev *mdev;
110 struct ib_umem *umem;95 struct ib_umem *umem;
@@ -171,48 +156,6 @@ void mlx5_ib_devx_destroy(struct mlx5_ib_dev *dev, u16 uid) · 60 unmodified lines
171 mlx5_cmd_exec(dev->mdev, in, sizeof(in), out, sizeof(out));156 mlx5_cmd_exec(dev->mdev, in, sizeof(in), out, sizeof(out));
172}157}
173 158
174bool mlx5_ib_devx_is_flow_dest(void *obj, int *dest_id, int *dest_type)
175{
176 struct devx_obj *devx_obj = obj;
177 u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, devx_obj->dinbox, opcode);
178
179 switch (opcode) {
180 case MLX5_CMD_OP_DESTROY_TIR:
181 *dest_type = MLX5_FLOW_DESTINATION_TYPE_TIR;
182 *dest_id = MLX5_GET(general_obj_in_cmd_hdr, devx_obj->dinbox,
183 obj_id);
184 return true;
185
186 case MLX5_CMD_OP_DESTROY_FLOW_TABLE:
187 *dest_type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
188 *dest_id = MLX5_GET(destroy_flow_table_in, devx_obj->dinbox,
189 table_id);
190 return true;
191 default:
192 return false;
193 }
194}
195
196bool mlx5_ib_devx_is_flow_counter(void *obj, u32 offset, u32 *counter_id)
197{
198 struct devx_obj *devx_obj = obj;
199 u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, devx_obj->dinbox, opcode);
200
201 if (opcode == MLX5_CMD_OP_DEALLOC_FLOW_COUNTER) {
202
203 if (offset && offset >= devx_obj->flow_counter_bulk_size)
204 return false;
205
206 *counter_id = MLX5_GET(dealloc_flow_counter_in,
207 devx_obj->dinbox,
208 flow_counter_id);
209 *counter_id += offset;
210 return true;
211 }
212
213 return false;
214}
215
216static bool is_legacy_unaffiliated_event_num(u16 event_num)159static bool is_legacy_unaffiliated_event_num(u16 event_num)
217{160{
218 switch (event_num) {161 switch (event_num) {
@@ -2419,17 +2362,24 @@ static int devx_event_notifier(struct notifier_block *nb, · 2200 unmodified lines
2419 return NOTIFY_OK;2362 return NOTIFY_OK;
2420}2363}
2421 2364
2422void mlx5_ib_devx_init_event_table(struct mlx5_ib_dev *dev)2365int mlx5_ib_devx_init(struct mlx5_ib_dev *dev)
2423{2366{
2424 struct mlx5_devx_event_table *table = &dev->devx_event_table;2367 struct mlx5_devx_event_table *table = &dev->devx_event_table;
2368 int uid;
2425 2369
2426 xa_init(&table->event_xa);2370 uid = mlx5_ib_devx_create(dev, false);
2427 mutex_init(&table->event_xa_lock);2371 if (uid > 0) {
2428 MLX5_NB_INIT(&table->devx_nb, devx_event_notifier, NOTIFY_ANY);2372 dev->devx_whitelist_uid = uid;
2429 mlx5_eq_notifier_register(dev->mdev, &table->devx_nb);2373 xa_init(&table->event_xa);
2374 mutex_init(&table->event_xa_lock);
2375 MLX5_NB_INIT(&table->devx_nb, devx_event_notifier, NOTIFY_ANY);
2376 mlx5_eq_notifier_register(dev->mdev, &table->devx_nb);
2377 }
2378
2379 return 0;
2430}2380}
2431 2381
2432void mlx5_ib_devx_cleanup_event_table(struct mlx5_ib_dev *dev)2382void mlx5_ib_devx_cleanup(struct mlx5_ib_dev *dev)
2433{2383{
2434 struct mlx5_devx_event_table *table = &dev->devx_event_table;2384 struct mlx5_devx_event_table *table = &dev->devx_event_table;
2435 struct devx_event_subscription *sub, *tmp;2385 struct devx_event_subscription *sub, *tmp;
@@ -2437,17 +2387,21 @@ void mlx5_ib_devx_cleanup_event_table(struct mlx5_ib_dev *dev) · 1 unmodified line
2437 void *entry;2387 void *entry;
2438 unsigned long id;2388 unsigned long id;
2439 2389
2440 mlx5_eq_notifier_unregister(dev->mdev, &table->devx_nb);2390 if (dev->devx_whitelist_uid) {
2441 mutex_lock(&dev->devx_event_table.event_xa_lock);2391 mlx5_eq_notifier_unregister(dev->mdev, &table->devx_nb);
2442 xa_for_each(&table->event_xa, id, entry) {2392 mutex_lock(&dev->devx_event_table.event_xa_lock);
2443 event = entry;2393 xa_for_each(&table->event_xa, id, entry) {
2444 list_for_each_entry_safe(sub, tmp, &event->unaffiliated_list,2394 event = entry;
2445 xa_list)2395 list_for_each_entry_safe(
2446 devx_cleanup_subscription(dev, sub);2396 sub, tmp, &event->unaffiliated_list, xa_list)
2447 kfree(entry);2397 devx_cleanup_subscription(dev, sub);
2398 kfree(entry);
2399 }
2400 mutex_unlock(&dev->devx_event_table.event_xa_lock);
2401 xa_destroy(&table->event_xa);
2402
2403 mlx5_ib_devx_destroy(dev, dev->devx_whitelist_uid);
2448 }2404 }
2449 mutex_unlock(&dev->devx_event_table.event_xa_lock);
2450 xa_destroy(&table->event_xa);
2451}2405}
2452 2406
2453static ssize_t devx_async_cmd_event_read(struct file *filp, char __user *buf,2407static ssize_t devx_async_cmd_event_read(struct file *filp, char __user *buf,
drivers/infiniband/hw/mlx5/devx.h+45−0
@@ -0,0 +1,45 @@
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
2/*
3 * Copyright (c) 2019-2020, Mellanox Technologies inc. All rights reserved.
4 */
5
6#ifndef _MLX5_IB_DEVX_H
7#define _MLX5_IB_DEVX_H
8
9#include "mlx5_ib.h"
10
11#define MLX5_MAX_DESTROY_INBOX_SIZE_DW MLX5_ST_SZ_DW(delete_fte_in)
12struct devx_obj {
13 struct mlx5_ib_dev *ib_dev;
14 u64 obj_id;
15 u32 dinlen; /* destroy inbox length */
16 u32 dinbox[MLX5_MAX_DESTROY_INBOX_SIZE_DW];
17 u32 flags;
18 union {
19 struct mlx5_ib_devx_mr devx_mr;
20 struct mlx5_core_dct core_dct;
21 struct mlx5_core_cq core_cq;
22 u32 flow_counter_bulk_size;
23 };
24 struct list_head event_sub; /* holds devx_event_subscription entries */
25};
26#if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
27int mlx5_ib_devx_create(struct mlx5_ib_dev *dev, bool is_user);
28void mlx5_ib_devx_destroy(struct mlx5_ib_dev *dev, u16 uid);
29int mlx5_ib_devx_init(struct mlx5_ib_dev *dev);
30void mlx5_ib_devx_cleanup(struct mlx5_ib_dev *dev);
31#else
32static inline int mlx5_ib_devx_create(struct mlx5_ib_dev *dev, bool is_user)
33{
34 return -EOPNOTSUPP;
35}
36static inline void mlx5_ib_devx_destroy(struct mlx5_ib_dev *dev, u16 uid) {}
37static inline int mlx5_ib_devx_init(struct mlx5_ib_dev *dev)
38{
39 return 0;
40}
41static inline void mlx5_ib_devx_cleanup(struct mlx5_ib_dev *dev)
42{
43}
44#endif
45#endif /* _MLX5_IB_DEVX_H */
drivers/infiniband/hw/mlx5/flow.c+0−765
@@ -1,765 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2/*
3 * Copyright (c) 2018, Mellanox Technologies inc. All rights reserved.
4 */
5
6#include <rdma/ib_user_verbs.h>
7#include <rdma/ib_verbs.h>
8#include <rdma/uverbs_types.h>
9#include <rdma/uverbs_ioctl.h>
10#include <rdma/uverbs_std_types.h>
11#include <rdma/mlx5_user_ioctl_cmds.h>
12#include <rdma/mlx5_user_ioctl_verbs.h>
13#include <rdma/ib_umem.h>
14#include <linux/mlx5/driver.h>
15#include <linux/mlx5/fs.h>
16#include "mlx5_ib.h"
17
18#define UVERBS_MODULE_NAME mlx5_ib
19#include <rdma/uverbs_named_ioctl.h>
20
21static int
22mlx5_ib_ft_type_to_namespace(enum mlx5_ib_uapi_flow_table_type table_type,
23 enum mlx5_flow_namespace_type *namespace)
24{
25 switch (table_type) {
26 case MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_RX:
27 *namespace = MLX5_FLOW_NAMESPACE_BYPASS;
28 break;
29 case MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX:
30 *namespace = MLX5_FLOW_NAMESPACE_EGRESS;
31 break;
32 case MLX5_IB_UAPI_FLOW_TABLE_TYPE_FDB:
33 *namespace = MLX5_FLOW_NAMESPACE_FDB;
34 break;
35 case MLX5_IB_UAPI_FLOW_TABLE_TYPE_RDMA_RX:
36 *namespace = MLX5_FLOW_NAMESPACE_RDMA_RX;
37 break;
38 case MLX5_IB_UAPI_FLOW_TABLE_TYPE_RDMA_TX:
39 *namespace = MLX5_FLOW_NAMESPACE_RDMA_TX;
40 break;
41 default:
42 return -EINVAL;
43 }
44
45 return 0;
46}
47
48static const struct uverbs_attr_spec mlx5_ib_flow_type[] = {
49 [MLX5_IB_FLOW_TYPE_NORMAL] = {
50 .type = UVERBS_ATTR_TYPE_PTR_IN,
51 .u.ptr = {
52 .len = sizeof(u16), /* data is priority */
53 .min_len = sizeof(u16),
54 }
55 },
56 [MLX5_IB_FLOW_TYPE_SNIFFER] = {
57 .type = UVERBS_ATTR_TYPE_PTR_IN,
58 UVERBS_ATTR_NO_DATA(),
59 },
60 [MLX5_IB_FLOW_TYPE_ALL_DEFAULT] = {
61 .type = UVERBS_ATTR_TYPE_PTR_IN,
62 UVERBS_ATTR_NO_DATA(),
63 },
64 [MLX5_IB_FLOW_TYPE_MC_DEFAULT] = {
65 .type = UVERBS_ATTR_TYPE_PTR_IN,
66 UVERBS_ATTR_NO_DATA(),
67 },
68};
69
70static int get_dests(struct uverbs_attr_bundle *attrs,
71 struct mlx5_ib_flow_matcher *fs_matcher, int *dest_id,
72 int *dest_type, struct ib_qp **qp, u32 *flags)
73{
74 bool dest_devx, dest_qp;
75 void *devx_obj;
76 int err;
77
78 dest_devx = uverbs_attr_is_valid(attrs,
79 MLX5_IB_ATTR_CREATE_FLOW_DEST_DEVX);
80 dest_qp = uverbs_attr_is_valid(attrs,
81 MLX5_IB_ATTR_CREATE_FLOW_DEST_QP);
82
83 *flags = 0;
84 err = uverbs_get_flags32(flags, attrs, MLX5_IB_ATTR_CREATE_FLOW_FLAGS,
85 MLX5_IB_ATTR_CREATE_FLOW_FLAGS_DEFAULT_MISS |
86 MLX5_IB_ATTR_CREATE_FLOW_FLAGS_DROP);
87 if (err)
88 return err;
89
90 /* Both flags are not allowed */
91 if (*flags & MLX5_IB_ATTR_CREATE_FLOW_FLAGS_DEFAULT_MISS &&
92 *flags & MLX5_IB_ATTR_CREATE_FLOW_FLAGS_DROP)
93 return -EINVAL;
94
95 if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_BYPASS) {
96 if (dest_devx && (dest_qp || *flags))
97 return -EINVAL;
98 else if (dest_qp && *flags)
99 return -EINVAL;
100 }
101
102 /* Allow only DEVX object, drop as dest for FDB */
103 if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_FDB && !(dest_devx ||
104 (*flags & MLX5_IB_ATTR_CREATE_FLOW_FLAGS_DROP)))
105 return -EINVAL;
106
107 /* Allow only DEVX object or QP as dest when inserting to RDMA_RX */
108 if ((fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_RDMA_RX) &&
109 ((!dest_devx && !dest_qp) || (dest_devx && dest_qp)))
110 return -EINVAL;
111
112 *qp = NULL;
113 if (dest_devx) {
114 devx_obj =
115 uverbs_attr_get_obj(attrs,
116 MLX5_IB_ATTR_CREATE_FLOW_DEST_DEVX);
117
118 /* Verify that the given DEVX object is a flow
119 * steering destination.
120 */
121 if (!mlx5_ib_devx_is_flow_dest(devx_obj, dest_id, dest_type))
122 return -EINVAL;
123 /* Allow only flow table as dest when inserting to FDB or RDMA_RX */
124 if ((fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_FDB ||
125 fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_RDMA_RX) &&
126 *dest_type != MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE)
127 return -EINVAL;
128 } else if (dest_qp) {
129 struct mlx5_ib_qp *mqp;
130
131 *qp = uverbs_attr_get_obj(attrs,
132 MLX5_IB_ATTR_CREATE_FLOW_DEST_QP);
133 if (IS_ERR(*qp))
134 return PTR_ERR(*qp);
135
136 if ((*qp)->qp_type != IB_QPT_RAW_PACKET)
137 return -EINVAL;
138
139 mqp = to_mqp(*qp);
140 if (mqp->is_rss)
141 *dest_id = mqp->rss_qp.tirn;
142 else
143 *dest_id = mqp->raw_packet_qp.rq.tirn;
144 *dest_type = MLX5_FLOW_DESTINATION_TYPE_TIR;
145 } else if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_EGRESS) {
146 *dest_type = MLX5_FLOW_DESTINATION_TYPE_PORT;
147 }
148
149 if (*dest_type == MLX5_FLOW_DESTINATION_TYPE_TIR &&
150 fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_EGRESS)
151 return -EINVAL;
152
153 return 0;
154}
155
156#define MLX5_IB_CREATE_FLOW_MAX_FLOW_ACTIONS 2
157static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
158 struct uverbs_attr_bundle *attrs)
159{
160 struct mlx5_flow_context flow_context = {.flow_tag =
161 MLX5_FS_DEFAULT_FLOW_TAG};
162 u32 *offset_attr, offset = 0, counter_id = 0;
163 int dest_id, dest_type, inlen, len, ret, i;
164 struct mlx5_ib_flow_handler *flow_handler;
165 struct mlx5_ib_flow_matcher *fs_matcher;
166 struct ib_uobject **arr_flow_actions;
167 struct ib_uflow_resources *uflow_res;
168 struct mlx5_flow_act flow_act = {};
169 struct ib_qp *qp = NULL;
170 void *devx_obj, *cmd_in;
171 struct ib_uobject *uobj;
172 struct mlx5_ib_dev *dev;
173 u32 flags;
174
175 if (!capable(CAP_NET_RAW))
176 return -EPERM;
177
178 fs_matcher = uverbs_attr_get_obj(attrs,
179 MLX5_IB_ATTR_CREATE_FLOW_MATCHER);
180 uobj = uverbs_attr_get_uobject(attrs, MLX5_IB_ATTR_CREATE_FLOW_HANDLE);
181 dev = mlx5_udata_to_mdev(&attrs->driver_udata);
182
183 if (get_dests(attrs, fs_matcher, &dest_id, &dest_type, &qp, &flags))
184 return -EINVAL;
185
186 if (flags & MLX5_IB_ATTR_CREATE_FLOW_FLAGS_DEFAULT_MISS)
187 flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_NS;
188
189 if (flags & MLX5_IB_ATTR_CREATE_FLOW_FLAGS_DROP)
190 flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_DROP;
191
192 len = uverbs_attr_get_uobjs_arr(attrs,
193 MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX, &arr_flow_actions);
194 if (len) {
195 devx_obj = arr_flow_actions[0]->object;
196
197 if (uverbs_attr_is_valid(attrs,
198 MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET)) {
199
200 int num_offsets = uverbs_attr_ptr_get_array_size(
201 attrs,
202 MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET,
203 sizeof(u32));
204
205 if (num_offsets != 1)
206 return -EINVAL;
207
208 offset_attr = uverbs_attr_get_alloced_ptr(
209 attrs,
210 MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET);
211 offset = *offset_attr;
212 }
213
214 if (!mlx5_ib_devx_is_flow_counter(devx_obj, offset,
215 &counter_id))
216 return -EINVAL;
217
218 flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_COUNT;
219 }
220
221 cmd_in = uverbs_attr_get_alloced_ptr(
222 attrs, MLX5_IB_ATTR_CREATE_FLOW_MATCH_VALUE);
223 inlen = uverbs_attr_get_len(attrs,
224 MLX5_IB_ATTR_CREATE_FLOW_MATCH_VALUE);
225
226 uflow_res = flow_resources_alloc(MLX5_IB_CREATE_FLOW_MAX_FLOW_ACTIONS);
227 if (!uflow_res)
228 return -ENOMEM;
229
230 len = uverbs_attr_get_uobjs_arr(attrs,
231 MLX5_IB_ATTR_CREATE_FLOW_ARR_FLOW_ACTIONS, &arr_flow_actions);
232 for (i = 0; i < len; i++) {
233 struct mlx5_ib_flow_action *maction =
234 to_mflow_act(arr_flow_actions[i]->object);
235
236 ret = parse_flow_flow_action(maction, false, &flow_act);
237 if (ret)
238 goto err_out;
239 flow_resources_add(uflow_res, IB_FLOW_SPEC_ACTION_HANDLE,
240 arr_flow_actions[i]->object);
241 }
242
243 ret = uverbs_copy_from(&flow_context.flow_tag, attrs,
244 MLX5_IB_ATTR_CREATE_FLOW_TAG);
245 if (!ret) {
246 if (flow_context.flow_tag >= BIT(24)) {
247 ret = -EINVAL;
248 goto err_out;
249 }
250 flow_context.flags |= FLOW_CONTEXT_HAS_TAG;
251 }
252
253 flow_handler = mlx5_ib_raw_fs_rule_add(dev, fs_matcher,
254 &flow_context,
255 &flow_act,
256 counter_id,
257 cmd_in, inlen,
258 dest_id, dest_type);
259 if (IS_ERR(flow_handler)) {
260 ret = PTR_ERR(flow_handler);
261 goto err_out;
262 }
263
264 ib_set_flow(uobj, &flow_handler->ibflow, qp, &dev->ib_dev, uflow_res);
265
266 return 0;
267err_out:
268 ib_uverbs_flow_resources_free(uflow_res);
269 return ret;
270}
271
272static int flow_matcher_cleanup(struct ib_uobject *uobject,
273 enum rdma_remove_reason why,
274 struct uverbs_attr_bundle *attrs)
275{
276 struct mlx5_ib_flow_matcher *obj = uobject->object;
277 int ret;
278
279 ret = ib_destroy_usecnt(&obj->usecnt, why, uobject);
280 if (ret)
281 return ret;
282
283 kfree(obj);
284 return 0;
285}
286
287static int mlx5_ib_matcher_ns(struct uverbs_attr_bundle *attrs,
288 struct mlx5_ib_flow_matcher *obj)
289{
290 enum mlx5_ib_uapi_flow_table_type ft_type =
291 MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_RX;
292 u32 flags;
293 int err;
294
295 /* New users should use MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE and older
296 * users should switch to it. We leave this to not break userspace
297 */
298 if (uverbs_attr_is_valid(attrs, MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE) &&
299 uverbs_attr_is_valid(attrs, MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS))
300 return -EINVAL;
301
302 if (uverbs_attr_is_valid(attrs, MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE)) {
303 err = uverbs_get_const(&ft_type, attrs,
304 MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE);
305 if (err)
306 return err;
307
308 err = mlx5_ib_ft_type_to_namespace(ft_type, &obj->ns_type);
309 if (err)
310 return err;
311
312 return 0;
313 }
314
315 if (uverbs_attr_is_valid(attrs, MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS)) {
316 err = uverbs_get_flags32(&flags, attrs,
317 MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS,
318 IB_FLOW_ATTR_FLAGS_EGRESS);
319 if (err)
320 return err;
321
322 if (flags) {
323 mlx5_ib_ft_type_to_namespace(
324 MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX,
325 &obj->ns_type);
326 return 0;
327 }
328 }
329
330 obj->ns_type = MLX5_FLOW_NAMESPACE_BYPASS;
331
332 return 0;
333}
334
335static int UVERBS_HANDLER(MLX5_IB_METHOD_FLOW_MATCHER_CREATE)(
336 struct uverbs_attr_bundle *attrs)
337{
338 struct ib_uobject *uobj = uverbs_attr_get_uobject(
339 attrs, MLX5_IB_ATTR_FLOW_MATCHER_CREATE_HANDLE);
340 struct mlx5_ib_dev *dev = mlx5_udata_to_mdev(&attrs->driver_udata);
341 struct mlx5_ib_flow_matcher *obj;
342 int err;
343
344 obj = kzalloc(sizeof(struct mlx5_ib_flow_matcher), GFP_KERNEL);
345 if (!obj)
346 return -ENOMEM;
347
348 obj->mask_len = uverbs_attr_get_len(
349 attrs, MLX5_IB_ATTR_FLOW_MATCHER_MATCH_MASK);
350 err = uverbs_copy_from(&obj->matcher_mask,
351 attrs,
352 MLX5_IB_ATTR_FLOW_MATCHER_MATCH_MASK);
353 if (err)
354 goto end;
355
356 obj->flow_type = uverbs_attr_get_enum_id(
357 attrs, MLX5_IB_ATTR_FLOW_MATCHER_FLOW_TYPE);
358
359 if (obj->flow_type == MLX5_IB_FLOW_TYPE_NORMAL) {
360 err = uverbs_copy_from(&obj->priority,
361 attrs,
362 MLX5_IB_ATTR_FLOW_MATCHER_FLOW_TYPE);
363 if (err)
364 goto end;
365 }
366
367 err = uverbs_copy_from(&obj->match_criteria_enable,
368 attrs,
369 MLX5_IB_ATTR_FLOW_MATCHER_MATCH_CRITERIA);
370 if (err)
371 goto end;
372
373 err = mlx5_ib_matcher_ns(attrs, obj);
374 if (err)
375 goto end;
376
377 uobj->object = obj;
378 obj->mdev = dev->mdev;
379 atomic_set(&obj->usecnt, 0);
380 return 0;
381
382end:
383 kfree(obj);
384 return err;
385}
386
387void mlx5_ib_destroy_flow_action_raw(struct mlx5_ib_flow_action *maction)
388{
389 switch (maction->flow_action_raw.sub_type) {
390 case MLX5_IB_FLOW_ACTION_MODIFY_HEADER:
391 mlx5_modify_header_dealloc(maction->flow_action_raw.dev->mdev,
392 maction->flow_action_raw.modify_hdr);
393 break;
394 case MLX5_IB_FLOW_ACTION_PACKET_REFORMAT:
395 mlx5_packet_reformat_dealloc(maction->flow_action_raw.dev->mdev,
396 maction->flow_action_raw.pkt_reformat);
397 break;
398 case MLX5_IB_FLOW_ACTION_DECAP:
399 break;
400 default:
401 break;
402 }
403}
404
405static struct ib_flow_action *
406mlx5_ib_create_modify_header(struct mlx5_ib_dev *dev,
407 enum mlx5_ib_uapi_flow_table_type ft_type,
408 u8 num_actions, void *in)
409{
410 enum mlx5_flow_namespace_type namespace;
411 struct mlx5_ib_flow_action *maction;
412 int ret;
413
414 ret = mlx5_ib_ft_type_to_namespace(ft_type, &namespace);
415 if (ret)
416 return ERR_PTR(-EINVAL);
417
418 maction = kzalloc(sizeof(*maction), GFP_KERNEL);
419 if (!maction)
420 return ERR_PTR(-ENOMEM);
421
422 maction->flow_action_raw.modify_hdr =
423 mlx5_modify_header_alloc(dev->mdev, namespace, num_actions, in);
424
425 if (IS_ERR(maction->flow_action_raw.modify_hdr)) {
426 ret = PTR_ERR(maction->flow_action_raw.modify_hdr);
427 kfree(maction);
428 return ERR_PTR(ret);
429 }
430 maction->flow_action_raw.sub_type =
431 MLX5_IB_FLOW_ACTION_MODIFY_HEADER;
432 maction->flow_action_raw.dev = dev;
433
434 return &maction->ib_action;
435}
436
437static bool mlx5_ib_modify_header_supported(struct mlx5_ib_dev *dev)
438{
439 return MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev,
440 max_modify_header_actions) ||
441 MLX5_CAP_FLOWTABLE_NIC_TX(dev->mdev,
442 max_modify_header_actions) ||
443 MLX5_CAP_FLOWTABLE_RDMA_TX(dev->mdev,
444 max_modify_header_actions);
445}
446
447static int UVERBS_HANDLER(MLX5_IB_METHOD_FLOW_ACTION_CREATE_MODIFY_HEADER)(
448 struct uverbs_attr_bundle *attrs)
449{
450 struct ib_uobject *uobj = uverbs_attr_get_uobject(
451 attrs, MLX5_IB_ATTR_CREATE_MODIFY_HEADER_HANDLE);
452 struct mlx5_ib_dev *mdev = mlx5_udata_to_mdev(&attrs->driver_udata);
453 enum mlx5_ib_uapi_flow_table_type ft_type;
454 struct ib_flow_action *action;
455 int num_actions;
456 void *in;
457 int ret;
458
459 if (!mlx5_ib_modify_header_supported(mdev))
460 return -EOPNOTSUPP;
461
462 in = uverbs_attr_get_alloced_ptr(attrs,
463 MLX5_IB_ATTR_CREATE_MODIFY_HEADER_ACTIONS_PRM);
464
465 num_actions = uverbs_attr_ptr_get_array_size(
466 attrs, MLX5_IB_ATTR_CREATE_MODIFY_HEADER_ACTIONS_PRM,
467 MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto));
468 if (num_actions < 0)
469 return num_actions;
470
471 ret = uverbs_get_const(&ft_type, attrs,
472 MLX5_IB_ATTR_CREATE_MODIFY_HEADER_FT_TYPE);
473 if (ret)
474 return ret;
475 action = mlx5_ib_create_modify_header(mdev, ft_type, num_actions, in);
476 if (IS_ERR(action))
477 return PTR_ERR(action);
478
479 uverbs_flow_action_fill_action(action, uobj, &mdev->ib_dev,
480 IB_FLOW_ACTION_UNSPECIFIED);
481
482 return 0;
483}
484
485static bool mlx5_ib_flow_action_packet_reformat_valid(struct mlx5_ib_dev *ibdev,
486 u8 packet_reformat_type,
487 u8 ft_type)
488{
489 switch (packet_reformat_type) {
490 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L2_TUNNEL:
491 if (ft_type == MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX)
492 return MLX5_CAP_FLOWTABLE(ibdev->mdev,
493 encap_general_header);
494 break;
495 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L3_TUNNEL:
496 if (ft_type == MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX)
497 return MLX5_CAP_FLOWTABLE_NIC_TX(ibdev->mdev,
498 reformat_l2_to_l3_tunnel);
499 break;
500 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L3_TUNNEL_TO_L2:
501 if (ft_type == MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_RX)
502 return MLX5_CAP_FLOWTABLE_NIC_RX(ibdev->mdev,
503 reformat_l3_tunnel_to_l2);
504 break;
505 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TUNNEL_TO_L2:
506 if (ft_type == MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_RX)
507 return MLX5_CAP_FLOWTABLE_NIC_RX(ibdev->mdev, decap);
508 break;
509 default:
510 break;
511 }
512
513 return false;
514}
515
516static int mlx5_ib_dv_to_prm_packet_reforamt_type(u8 dv_prt, u8 *prm_prt)
517{
518 switch (dv_prt) {
519 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L2_TUNNEL:
520 *prm_prt = MLX5_REFORMAT_TYPE_L2_TO_L2_TUNNEL;
521 break;
522 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L3_TUNNEL_TO_L2:
523 *prm_prt = MLX5_REFORMAT_TYPE_L3_TUNNEL_TO_L2;
524 break;
525 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L3_TUNNEL:
526 *prm_prt = MLX5_REFORMAT_TYPE_L2_TO_L3_TUNNEL;
527 break;
528 default:
529 return -EINVAL;
530 }
531
532 return 0;
533}
534
535static int mlx5_ib_flow_action_create_packet_reformat_ctx(
536 struct mlx5_ib_dev *dev,
537 struct mlx5_ib_flow_action *maction,
538 u8 ft_type, u8 dv_prt,
539 void *in, size_t len)
540{
541 enum mlx5_flow_namespace_type namespace;
542 u8 prm_prt;
543 int ret;
544
545 ret = mlx5_ib_ft_type_to_namespace(ft_type, &namespace);
546 if (ret)
547 return ret;
548
549 ret = mlx5_ib_dv_to_prm_packet_reforamt_type(dv_prt, &prm_prt);
550 if (ret)
551 return ret;
552
553 maction->flow_action_raw.pkt_reformat =
554 mlx5_packet_reformat_alloc(dev->mdev, prm_prt, len,
555 in, namespace);
556 if (IS_ERR(maction->flow_action_raw.pkt_reformat)) {
557 ret = PTR_ERR(maction->flow_action_raw.pkt_reformat);
558 return ret;
559 }
560
561 maction->flow_action_raw.sub_type =
562 MLX5_IB_FLOW_ACTION_PACKET_REFORMAT;
563 maction->flow_action_raw.dev = dev;
564
565 return 0;
566}
567
568static int UVERBS_HANDLER(MLX5_IB_METHOD_FLOW_ACTION_CREATE_PACKET_REFORMAT)(
569 struct uverbs_attr_bundle *attrs)
570{
571 struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs,
572 MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_HANDLE);
573 struct mlx5_ib_dev *mdev = mlx5_udata_to_mdev(&attrs->driver_udata);
574 enum mlx5_ib_uapi_flow_action_packet_reformat_type dv_prt;
575 enum mlx5_ib_uapi_flow_table_type ft_type;
576 struct mlx5_ib_flow_action *maction;
577 int ret;
578
579 ret = uverbs_get_const(&ft_type, attrs,
580 MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_FT_TYPE);
581 if (ret)
582 return ret;
583
584 ret = uverbs_get_const(&dv_prt, attrs,
585 MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_TYPE);
586 if (ret)
587 return ret;
588
589 if (!mlx5_ib_flow_action_packet_reformat_valid(mdev, dv_prt, ft_type))
590 return -EOPNOTSUPP;
591
592 maction = kzalloc(sizeof(*maction), GFP_KERNEL);
593 if (!maction)
594 return -ENOMEM;
595
596 if (dv_prt ==
597 MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TUNNEL_TO_L2) {
598 maction->flow_action_raw.sub_type =
599 MLX5_IB_FLOW_ACTION_DECAP;
600 maction->flow_action_raw.dev = mdev;
601 } else {
602 void *in;
603 int len;
604
605 in = uverbs_attr_get_alloced_ptr(attrs,
606 MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_DATA_BUF);
607 if (IS_ERR(in)) {
608 ret = PTR_ERR(in);
609 goto free_maction;
610 }
611
612 len = uverbs_attr_get_len(attrs,
613 MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_DATA_BUF);
614
615 ret = mlx5_ib_flow_action_create_packet_reformat_ctx(mdev,
616 maction, ft_type, dv_prt, in, len);
617 if (ret)
618 goto free_maction;
619 }
620
621 uverbs_flow_action_fill_action(&maction->ib_action, uobj, &mdev->ib_dev,
622 IB_FLOW_ACTION_UNSPECIFIED);
623 return 0;
624
625free_maction:
626 kfree(maction);
627 return ret;
628}
629
630DECLARE_UVERBS_NAMED_METHOD(
631 MLX5_IB_METHOD_CREATE_FLOW,
632 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_FLOW_HANDLE,
633 UVERBS_OBJECT_FLOW,
634 UVERBS_ACCESS_NEW,
635 UA_MANDATORY),
636 UVERBS_ATTR_PTR_IN(
637 MLX5_IB_ATTR_CREATE_FLOW_MATCH_VALUE,
638 UVERBS_ATTR_SIZE(1, sizeof(struct mlx5_ib_match_params)),
639 UA_MANDATORY,
640 UA_ALLOC_AND_COPY),
641 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_FLOW_MATCHER,
642 MLX5_IB_OBJECT_FLOW_MATCHER,
643 UVERBS_ACCESS_READ,
644 UA_MANDATORY),
645 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_FLOW_DEST_QP,
646 UVERBS_OBJECT_QP,
647 UVERBS_ACCESS_READ),
648 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_FLOW_DEST_DEVX,
649 MLX5_IB_OBJECT_DEVX_OBJ,
650 UVERBS_ACCESS_READ),
651 UVERBS_ATTR_IDRS_ARR(MLX5_IB_ATTR_CREATE_FLOW_ARR_FLOW_ACTIONS,
652 UVERBS_OBJECT_FLOW_ACTION,
653 UVERBS_ACCESS_READ, 1,
654 MLX5_IB_CREATE_FLOW_MAX_FLOW_ACTIONS,
655 UA_OPTIONAL),
656 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_CREATE_FLOW_TAG,
657 UVERBS_ATTR_TYPE(u32),
658 UA_OPTIONAL),
659 UVERBS_ATTR_IDRS_ARR(MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX,
660 MLX5_IB_OBJECT_DEVX_OBJ,
661 UVERBS_ACCESS_READ, 1, 1,
662 UA_OPTIONAL),
663 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET,
664 UVERBS_ATTR_MIN_SIZE(sizeof(u32)),
665 UA_OPTIONAL,
666 UA_ALLOC_AND_COPY),
667 UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_CREATE_FLOW_FLAGS,
668 enum mlx5_ib_create_flow_flags,
669 UA_OPTIONAL));
670
671DECLARE_UVERBS_NAMED_METHOD_DESTROY(
672 MLX5_IB_METHOD_DESTROY_FLOW,
673 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_FLOW_HANDLE,
674 UVERBS_OBJECT_FLOW,
675 UVERBS_ACCESS_DESTROY,
676 UA_MANDATORY));
677
678ADD_UVERBS_METHODS(mlx5_ib_fs,
679 UVERBS_OBJECT_FLOW,
680 &UVERBS_METHOD(MLX5_IB_METHOD_CREATE_FLOW),
681 &UVERBS_METHOD(MLX5_IB_METHOD_DESTROY_FLOW));
682
683DECLARE_UVERBS_NAMED_METHOD(
684 MLX5_IB_METHOD_FLOW_ACTION_CREATE_MODIFY_HEADER,
685 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_MODIFY_HEADER_HANDLE,
686 UVERBS_OBJECT_FLOW_ACTION,
687 UVERBS_ACCESS_NEW,
688 UA_MANDATORY),
689 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_CREATE_MODIFY_HEADER_ACTIONS_PRM,
690 UVERBS_ATTR_MIN_SIZE(MLX5_UN_SZ_BYTES(
691 set_add_copy_action_in_auto)),
692 UA_MANDATORY,
693 UA_ALLOC_AND_COPY),
694 UVERBS_ATTR_CONST_IN(MLX5_IB_ATTR_CREATE_MODIFY_HEADER_FT_TYPE,
695 enum mlx5_ib_uapi_flow_table_type,
696 UA_MANDATORY));
697
698DECLARE_UVERBS_NAMED_METHOD(
699 MLX5_IB_METHOD_FLOW_ACTION_CREATE_PACKET_REFORMAT,
700 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_HANDLE,
701 UVERBS_OBJECT_FLOW_ACTION,
702 UVERBS_ACCESS_NEW,
703 UA_MANDATORY),
704 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_DATA_BUF,
705 UVERBS_ATTR_MIN_SIZE(1),
706 UA_ALLOC_AND_COPY,
707 UA_OPTIONAL),
708 UVERBS_ATTR_CONST_IN(MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_TYPE,
709 enum mlx5_ib_uapi_flow_action_packet_reformat_type,
710 UA_MANDATORY),
711 UVERBS_ATTR_CONST_IN(MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_FT_TYPE,
712 enum mlx5_ib_uapi_flow_table_type,
713 UA_MANDATORY));
714
715ADD_UVERBS_METHODS(
716 mlx5_ib_flow_actions,
717 UVERBS_OBJECT_FLOW_ACTION,
718 &UVERBS_METHOD(MLX5_IB_METHOD_FLOW_ACTION_CREATE_MODIFY_HEADER),
719 &UVERBS_METHOD(MLX5_IB_METHOD_FLOW_ACTION_CREATE_PACKET_REFORMAT));
720
721DECLARE_UVERBS_NAMED_METHOD(
722 MLX5_IB_METHOD_FLOW_MATCHER_CREATE,
723 UVERBS_ATTR_IDR(MLX5_IB_ATTR_FLOW_MATCHER_CREATE_HANDLE,
724 MLX5_IB_OBJECT_FLOW_MATCHER,
725 UVERBS_ACCESS_NEW,
726 UA_MANDATORY),
727 UVERBS_ATTR_PTR_IN(
728 MLX5_IB_ATTR_FLOW_MATCHER_MATCH_MASK,
729 UVERBS_ATTR_SIZE(1, sizeof(struct mlx5_ib_match_params)),
730 UA_MANDATORY),
731 UVERBS_ATTR_ENUM_IN(MLX5_IB_ATTR_FLOW_MATCHER_FLOW_TYPE,
732 mlx5_ib_flow_type,
733 UA_MANDATORY),
734 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_FLOW_MATCHER_MATCH_CRITERIA,
735 UVERBS_ATTR_TYPE(u8),
736 UA_MANDATORY),
737 UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS,
738 enum ib_flow_flags,
739 UA_OPTIONAL),
740 UVERBS_ATTR_CONST_IN(MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE,
741 enum mlx5_ib_uapi_flow_table_type,
742 UA_OPTIONAL));
743
744DECLARE_UVERBS_NAMED_METHOD_DESTROY(
745 MLX5_IB_METHOD_FLOW_MATCHER_DESTROY,
746 UVERBS_ATTR_IDR(MLX5_IB_ATTR_FLOW_MATCHER_DESTROY_HANDLE,
747 MLX5_IB_OBJECT_FLOW_MATCHER,
748 UVERBS_ACCESS_DESTROY,
749 UA_MANDATORY));
750
751DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_FLOW_MATCHER,
752 UVERBS_TYPE_ALLOC_IDR(flow_matcher_cleanup),
753 &UVERBS_METHOD(MLX5_IB_METHOD_FLOW_MATCHER_CREATE),
754 &UVERBS_METHOD(MLX5_IB_METHOD_FLOW_MATCHER_DESTROY));
755
756const struct uapi_definition mlx5_ib_flow_defs[] = {
757 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(
758 MLX5_IB_OBJECT_FLOW_MATCHER),
759 UAPI_DEF_CHAIN_OBJ_TREE(
760 UVERBS_OBJECT_FLOW,
761 &mlx5_ib_fs),
762 UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_FLOW_ACTION,
763 &mlx5_ib_flow_actions),
764 {},
765};
drivers/infiniband/hw/mlx5/fs.c+2516−0
@@ -0,0 +1,2516 @@
1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2/*
3 * Copyright (c) 2018, Mellanox Technologies inc. All rights reserved.
4 */
5
6#include <rdma/ib_user_verbs.h>
7#include <rdma/ib_verbs.h>
8#include <rdma/uverbs_types.h>
9#include <rdma/uverbs_ioctl.h>
10#include <rdma/uverbs_std_types.h>
11#include <rdma/mlx5_user_ioctl_cmds.h>
12#include <rdma/mlx5_user_ioctl_verbs.h>
13#include <rdma/ib_umem.h>
14#include <linux/mlx5/driver.h>
15#include <linux/mlx5/fs.h>
16#include <linux/mlx5/fs_helpers.h>
17#include <linux/mlx5/accel.h>
18#include <linux/mlx5/eswitch.h>
19#include "mlx5_ib.h"
20#include "counters.h"
21#include "devx.h"
22#include "fs.h"
23
24#define UVERBS_MODULE_NAME mlx5_ib
25#include <rdma/uverbs_named_ioctl.h>
26
27enum {
28 MATCH_CRITERIA_ENABLE_OUTER_BIT,
29 MATCH_CRITERIA_ENABLE_MISC_BIT,
30 MATCH_CRITERIA_ENABLE_INNER_BIT,
31 MATCH_CRITERIA_ENABLE_MISC2_BIT
32};
33
34#define HEADER_IS_ZERO(match_criteria, headers) \
35 !(memchr_inv(MLX5_ADDR_OF(fte_match_param, match_criteria, headers), \
36 0, MLX5_FLD_SZ_BYTES(fte_match_param, headers))) \
37
38static u8 get_match_criteria_enable(u32 *match_criteria)
39{
40 u8 match_criteria_enable;
41
42 match_criteria_enable =
43 (!HEADER_IS_ZERO(match_criteria, outer_headers)) <<
44 MATCH_CRITERIA_ENABLE_OUTER_BIT;
45 match_criteria_enable |=
46 (!HEADER_IS_ZERO(match_criteria, misc_parameters)) <<
47 MATCH_CRITERIA_ENABLE_MISC_BIT;
48 match_criteria_enable |=
49 (!HEADER_IS_ZERO(match_criteria, inner_headers)) <<
50 MATCH_CRITERIA_ENABLE_INNER_BIT;
51 match_criteria_enable |=
52 (!HEADER_IS_ZERO(match_criteria, misc_parameters_2)) <<
53 MATCH_CRITERIA_ENABLE_MISC2_BIT;
54
55 return match_criteria_enable;
56}
57
58static int set_proto(void *outer_c, void *outer_v, u8 mask, u8 val)
59{
60 u8 entry_mask;
61 u8 entry_val;
62 int err = 0;
63
64 if (!mask)
65 goto out;
66
67 entry_mask = MLX5_GET(fte_match_set_lyr_2_4, outer_c,
68 ip_protocol);
69 entry_val = MLX5_GET(fte_match_set_lyr_2_4, outer_v,
70 ip_protocol);
71 if (!entry_mask) {
72 MLX5_SET(fte_match_set_lyr_2_4, outer_c, ip_protocol, mask);
73 MLX5_SET(fte_match_set_lyr_2_4, outer_v, ip_protocol, val);
74 goto out;
75 }
76 /* Don't override existing ip protocol */
77 if (mask != entry_mask || val != entry_val)
78 err = -EINVAL;
79out:
80 return err;
81}
82
83static void set_flow_label(void *misc_c, void *misc_v, u32 mask, u32 val,
84 bool inner)
85{
86 if (inner) {
87 MLX5_SET(fte_match_set_misc,
88 misc_c, inner_ipv6_flow_label, mask);
89 MLX5_SET(fte_match_set_misc,
90 misc_v, inner_ipv6_flow_label, val);
91 } else {
92 MLX5_SET(fte_match_set_misc,
93 misc_c, outer_ipv6_flow_label, mask);
94 MLX5_SET(fte_match_set_misc,
95 misc_v, outer_ipv6_flow_label, val);
96 }
97}
98
99static void set_tos(void *outer_c, void *outer_v, u8 mask, u8 val)
100{
101 MLX5_SET(fte_match_set_lyr_2_4, outer_c, ip_ecn, mask);
102 MLX5_SET(fte_match_set_lyr_2_4, outer_v, ip_ecn, val);
103 MLX5_SET(fte_match_set_lyr_2_4, outer_c, ip_dscp, mask >> 2);
104 MLX5_SET(fte_match_set_lyr_2_4, outer_v, ip_dscp, val >> 2);
105}
106
107static int check_mpls_supp_fields(u32 field_support, const __be32 *set_mask)
108{
109 if (MLX5_GET(fte_match_mpls, set_mask, mpls_label) &&
110 !(field_support & MLX5_FIELD_SUPPORT_MPLS_LABEL))
111 return -EOPNOTSUPP;
112
113 if (MLX5_GET(fte_match_mpls, set_mask, mpls_exp) &&
114 !(field_support & MLX5_FIELD_SUPPORT_MPLS_EXP))
115 return -EOPNOTSUPP;
116
117 if (MLX5_GET(fte_match_mpls, set_mask, mpls_s_bos) &&
118 !(field_support & MLX5_FIELD_SUPPORT_MPLS_S_BOS))
119 return -EOPNOTSUPP;
120
121 if (MLX5_GET(fte_match_mpls, set_mask, mpls_ttl) &&
122 !(field_support & MLX5_FIELD_SUPPORT_MPLS_TTL))
123 return -EOPNOTSUPP;
124
125 return 0;
126}
127
128#define LAST_ETH_FIELD vlan_tag
129#define LAST_IB_FIELD sl
130#define LAST_IPV4_FIELD tos
131#define LAST_IPV6_FIELD traffic_class
132#define LAST_TCP_UDP_FIELD src_port
133#define LAST_TUNNEL_FIELD tunnel_id
134#define LAST_FLOW_TAG_FIELD tag_id
135#define LAST_DROP_FIELD size
136#define LAST_COUNTERS_FIELD counters
137
138/* Field is the last supported field */
139#define FIELDS_NOT_SUPPORTED(filter, field)\
140 memchr_inv((void *)&filter.field +\
141 sizeof(filter.field), 0,\
142 sizeof(filter) -\
143 offsetof(typeof(filter), field) -\
144 sizeof(filter.field))
145
146int parse_flow_flow_action(struct mlx5_ib_flow_action *maction,
147 bool is_egress,
148 struct mlx5_flow_act *action)
149{
150
151 switch (maction->ib_action.type) {
152 case IB_FLOW_ACTION_ESP:
153 if (action->action & (MLX5_FLOW_CONTEXT_ACTION_ENCRYPT |
154 MLX5_FLOW_CONTEXT_ACTION_DECRYPT))
155 return -EINVAL;
156 /* Currently only AES_GCM keymat is supported by the driver */
157 action->esp_id = (uintptr_t)maction->esp_aes_gcm.ctx;
158 action->action |= is_egress ?
159 MLX5_FLOW_CONTEXT_ACTION_ENCRYPT :
160 MLX5_FLOW_CONTEXT_ACTION_DECRYPT;
161 return 0;
162 case IB_FLOW_ACTION_UNSPECIFIED:
163 if (maction->flow_action_raw.sub_type ==
164 MLX5_IB_FLOW_ACTION_MODIFY_HEADER) {
165 if (action->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR)
166 return -EINVAL;
167 action->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
168 action->modify_hdr =
169 maction->flow_action_raw.modify_hdr;
170 return 0;
171 }
172 if (maction->flow_action_raw.sub_type ==
173 MLX5_IB_FLOW_ACTION_DECAP) {
174 if (action->action & MLX5_FLOW_CONTEXT_ACTION_DECAP)
175 return -EINVAL;
176 action->action |= MLX5_FLOW_CONTEXT_ACTION_DECAP;
177 return 0;
178 }
179 if (maction->flow_action_raw.sub_type ==
180 MLX5_IB_FLOW_ACTION_PACKET_REFORMAT) {
181 if (action->action &
182 MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT)
183 return -EINVAL;
184 action->action |=
185 MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT;
186 action->pkt_reformat =
187 maction->flow_action_raw.pkt_reformat;
188 return 0;
189 }
190 fallthrough;
191 default:
192 return -EOPNOTSUPP;
193 }
194}
195
196static int parse_flow_attr(struct mlx5_core_dev *mdev,
197 struct mlx5_flow_spec *spec,
198 const union ib_flow_spec *ib_spec,
199 const struct ib_flow_attr *flow_attr,
200 struct mlx5_flow_act *action, u32 prev_type)
201{
202 struct mlx5_flow_context *flow_context = &spec->flow_context;
203 u32 *match_c = spec->match_criteria;
204 u32 *match_v = spec->match_value;
205 void *misc_params_c = MLX5_ADDR_OF(fte_match_param, match_c,
206 misc_parameters);
207 void *misc_params_v = MLX5_ADDR_OF(fte_match_param, match_v,
208 misc_parameters);
209 void *misc_params2_c = MLX5_ADDR_OF(fte_match_param, match_c,
210 misc_parameters_2);
211 void *misc_params2_v = MLX5_ADDR_OF(fte_match_param, match_v,
212 misc_parameters_2);
213 void *headers_c;
214 void *headers_v;
215 int match_ipv;
216 int ret;
217
218 if (ib_spec->type & IB_FLOW_SPEC_INNER) {
219 headers_c = MLX5_ADDR_OF(fte_match_param, match_c,
220 inner_headers);
221 headers_v = MLX5_ADDR_OF(fte_match_param, match_v,
222 inner_headers);
223 match_ipv = MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
224 ft_field_support.inner_ip_version);
225 } else {
226 headers_c = MLX5_ADDR_OF(fte_match_param, match_c,
227 outer_headers);
228 headers_v = MLX5_ADDR_OF(fte_match_param, match_v,
229 outer_headers);
230 match_ipv = MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
231 ft_field_support.outer_ip_version);
232 }
233
234 switch (ib_spec->type & ~IB_FLOW_SPEC_INNER) {
235 case IB_FLOW_SPEC_ETH:
236 if (FIELDS_NOT_SUPPORTED(ib_spec->eth.mask, LAST_ETH_FIELD))
237 return -EOPNOTSUPP;
238
239 ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
240 dmac_47_16),
241 ib_spec->eth.mask.dst_mac);
242 ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
243 dmac_47_16),
244 ib_spec->eth.val.dst_mac);
245
246 ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
247 smac_47_16),
248 ib_spec->eth.mask.src_mac);
249 ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
250 smac_47_16),
251 ib_spec->eth.val.src_mac);
252
253 if (ib_spec->eth.mask.vlan_tag) {
254 MLX5_SET(fte_match_set_lyr_2_4, headers_c,
255 cvlan_tag, 1);
256 MLX5_SET(fte_match_set_lyr_2_4, headers_v,
257 cvlan_tag, 1);
258
259 MLX5_SET(fte_match_set_lyr_2_4, headers_c,
260 first_vid, ntohs(ib_spec->eth.mask.vlan_tag));
261 MLX5_SET(fte_match_set_lyr_2_4, headers_v,
262 first_vid, ntohs(ib_spec->eth.val.vlan_tag));
263
264 MLX5_SET(fte_match_set_lyr_2_4, headers_c,
265 first_cfi,
266 ntohs(ib_spec->eth.mask.vlan_tag) >> 12);
267 MLX5_SET(fte_match_set_lyr_2_4, headers_v,
268 first_cfi,
269 ntohs(ib_spec->eth.val.vlan_tag) >> 12);
270
271 MLX5_SET(fte_match_set_lyr_2_4, headers_c,
272 first_prio,
273 ntohs(ib_spec->eth.mask.vlan_tag) >> 13);
274 MLX5_SET(fte_match_set_lyr_2_4, headers_v,
275 first_prio,
276 ntohs(ib_spec->eth.val.vlan_tag) >> 13);
277 }
278 MLX5_SET(fte_match_set_lyr_2_4, headers_c,
279 ethertype, ntohs(ib_spec->eth.mask.ether_type));
280 MLX5_SET(fte_match_set_lyr_2_4, headers_v,
281 ethertype, ntohs(ib_spec->eth.val.ether_type));
282 break;
283 case IB_FLOW_SPEC_IPV4:
284 if (FIELDS_NOT_SUPPORTED(ib_spec->ipv4.mask, LAST_IPV4_FIELD))
285 return -EOPNOTSUPP;
286
287 if (match_ipv) {
288 MLX5_SET(fte_match_set_lyr_2_4, headers_c,
289 ip_version, 0xf);
290 MLX5_SET(fte_match_set_lyr_2_4, headers_v,
291 ip_version, MLX5_FS_IPV4_VERSION);
292 } else {
293 MLX5_SET(fte_match_set_lyr_2_4, headers_c,
294 ethertype, 0xffff);
295 MLX5_SET(fte_match_set_lyr_2_4, headers_v,
296 ethertype, ETH_P_IP);
297 }
298
299 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
300 src_ipv4_src_ipv6.ipv4_layout.ipv4),
301 &ib_spec->ipv4.mask.src_ip,
302 sizeof(ib_spec->ipv4.mask.src_ip));
303 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
304 src_ipv4_src_ipv6.ipv4_layout.ipv4),
305 &ib_spec->ipv4.val.src_ip,
306 sizeof(ib_spec->ipv4.val.src_ip));
307 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
308 dst_ipv4_dst_ipv6.ipv4_layout.ipv4),
309 &ib_spec->ipv4.mask.dst_ip,
310 sizeof(ib_spec->ipv4.mask.dst_ip));
311 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
312 dst_ipv4_dst_ipv6.ipv4_layout.ipv4),
313 &ib_spec->ipv4.val.dst_ip,
314 sizeof(ib_spec->ipv4.val.dst_ip));
315
316 set_tos(headers_c, headers_v,
317 ib_spec->ipv4.mask.tos, ib_spec->ipv4.val.tos);
318
319 if (set_proto(headers_c, headers_v,
320 ib_spec->ipv4.mask.proto,
321 ib_spec->ipv4.val.proto))
322 return -EINVAL;
323 break;
324 case IB_FLOW_SPEC_IPV6:
325 if (FIELDS_NOT_SUPPORTED(ib_spec->ipv6.mask, LAST_IPV6_FIELD))
326 return -EOPNOTSUPP;
327
328 if (match_ipv) {
329 MLX5_SET(fte_match_set_lyr_2_4, headers_c,
330 ip_version, 0xf);
331 MLX5_SET(fte_match_set_lyr_2_4, headers_v,
332 ip_version, MLX5_FS_IPV6_VERSION);
333 } else {
334 MLX5_SET(fte_match_set_lyr_2_4, headers_c,
335 ethertype, 0xffff);
336 MLX5_SET(fte_match_set_lyr_2_4, headers_v,
337 ethertype, ETH_P_IPV6);
338 }
339
340 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
341 src_ipv4_src_ipv6.ipv6_layout.ipv6),
342 &ib_spec->ipv6.mask.src_ip,
343 sizeof(ib_spec->ipv6.mask.src_ip));
344 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
345 src_ipv4_src_ipv6.ipv6_layout.ipv6),
346 &ib_spec->ipv6.val.src_ip,
347 sizeof(ib_spec->ipv6.val.src_ip));
348 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
349 dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
350 &ib_spec->ipv6.mask.dst_ip,
351 sizeof(ib_spec->ipv6.mask.dst_ip));
352 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
353 dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
354 &ib_spec->ipv6.val.dst_ip,
355 sizeof(ib_spec->ipv6.val.dst_ip));
356
357 set_tos(headers_c, headers_v,
358 ib_spec->ipv6.mask.traffic_class,
359 ib_spec->ipv6.val.traffic_class);
360
361 if (set_proto(headers_c, headers_v,
362 ib_spec->ipv6.mask.next_hdr,
363 ib_spec->ipv6.val.next_hdr))
364 return -EINVAL;
365
366 set_flow_label(misc_params_c, misc_params_v,
367 ntohl(ib_spec->ipv6.mask.flow_label),
368 ntohl(ib_spec->ipv6.val.flow_label),
369 ib_spec->type & IB_FLOW_SPEC_INNER);
370 break;
371 case IB_FLOW_SPEC_ESP:
372 if (ib_spec->esp.mask.seq)
373 return -EOPNOTSUPP;
374
375 MLX5_SET(fte_match_set_misc, misc_params_c, outer_esp_spi,
376 ntohl(ib_spec->esp.mask.spi));
377 MLX5_SET(fte_match_set_misc, misc_params_v, outer_esp_spi,
378 ntohl(ib_spec->esp.val.spi));
379 break;
380 case IB_FLOW_SPEC_TCP:
381 if (FIELDS_NOT_SUPPORTED(ib_spec->tcp_udp.mask,
382 LAST_TCP_UDP_FIELD))
383 return -EOPNOTSUPP;
384
385 if (set_proto(headers_c, headers_v, 0xff, IPPROTO_TCP))
386 return -EINVAL;
387
388 MLX5_SET(fte_match_set_lyr_2_4, headers_c, tcp_sport,
389 ntohs(ib_spec->tcp_udp.mask.src_port));
390 MLX5_SET(fte_match_set_lyr_2_4, headers_v, tcp_sport,
391 ntohs(ib_spec->tcp_udp.val.src_port));
392
393 MLX5_SET(fte_match_set_lyr_2_4, headers_c, tcp_dport,
394 ntohs(ib_spec->tcp_udp.mask.dst_port));
395 MLX5_SET(fte_match_set_lyr_2_4, headers_v, tcp_dport,
396 ntohs(ib_spec->tcp_udp.val.dst_port));
397 break;
398 case IB_FLOW_SPEC_UDP:
399 if (FIELDS_NOT_SUPPORTED(ib_spec->tcp_udp.mask,
400 LAST_TCP_UDP_FIELD))
401 return -EOPNOTSUPP;
402
403 if (set_proto(headers_c, headers_v, 0xff, IPPROTO_UDP))
404 return -EINVAL;
405
406 MLX5_SET(fte_match_set_lyr_2_4, headers_c, udp_sport,
407 ntohs(ib_spec->tcp_udp.mask.src_port));
408 MLX5_SET(fte_match_set_lyr_2_4, headers_v, udp_sport,
409 ntohs(ib_spec->tcp_udp.val.src_port));
410
411 MLX5_SET(fte_match_set_lyr_2_4, headers_c, udp_dport,
412 ntohs(ib_spec->tcp_udp.mask.dst_port));
413 MLX5_SET(fte_match_set_lyr_2_4, headers_v, udp_dport,
414 ntohs(ib_spec->tcp_udp.val.dst_port));
415 break;
416 case IB_FLOW_SPEC_GRE:
417 if (ib_spec->gre.mask.c_ks_res0_ver)
418 return -EOPNOTSUPP;
419
420 if (set_proto(headers_c, headers_v, 0xff, IPPROTO_GRE))
421 return -EINVAL;
422
423 MLX5_SET(fte_match_set_lyr_2_4, headers_c, ip_protocol,
424 0xff);
425 MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_protocol,
426 IPPROTO_GRE);
427
428 MLX5_SET(fte_match_set_misc, misc_params_c, gre_protocol,
429 ntohs(ib_spec->gre.mask.protocol));
430 MLX5_SET(fte_match_set_misc, misc_params_v, gre_protocol,
431 ntohs(ib_spec->gre.val.protocol));
432
433 memcpy(MLX5_ADDR_OF(fte_match_set_misc, misc_params_c,
434 gre_key.nvgre.hi),
435 &ib_spec->gre.mask.key,
436 sizeof(ib_spec->gre.mask.key));
437 memcpy(MLX5_ADDR_OF(fte_match_set_misc, misc_params_v,
438 gre_key.nvgre.hi),
439 &ib_spec->gre.val.key,
440 sizeof(ib_spec->gre.val.key));
441 break;
442 case IB_FLOW_SPEC_MPLS:
443 switch (prev_type) {
444 case IB_FLOW_SPEC_UDP:
445 if (check_mpls_supp_fields(MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
446 ft_field_support.outer_first_mpls_over_udp),
447 &ib_spec->mpls.mask.tag))
448 return -EOPNOTSUPP;
449
450 memcpy(MLX5_ADDR_OF(fte_match_set_misc2, misc_params2_v,
451 outer_first_mpls_over_udp),
452 &ib_spec->mpls.val.tag,
453 sizeof(ib_spec->mpls.val.tag));
454 memcpy(MLX5_ADDR_OF(fte_match_set_misc2, misc_params2_c,
455 outer_first_mpls_over_udp),
456 &ib_spec->mpls.mask.tag,
457 sizeof(ib_spec->mpls.mask.tag));
458 break;
459 case IB_FLOW_SPEC_GRE:
460 if (check_mpls_supp_fields(MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
461 ft_field_support.outer_first_mpls_over_gre),
462 &ib_spec->mpls.mask.tag))
463 return -EOPNOTSUPP;
464
465 memcpy(MLX5_ADDR_OF(fte_match_set_misc2, misc_params2_v,
466 outer_first_mpls_over_gre),
467 &ib_spec->mpls.val.tag,
468 sizeof(ib_spec->mpls.val.tag));
469 memcpy(MLX5_ADDR_OF(fte_match_set_misc2, misc_params2_c,
470 outer_first_mpls_over_gre),
471 &ib_spec->mpls.mask.tag,
472 sizeof(ib_spec->mpls.mask.tag));
473 break;
474 default:
475 if (ib_spec->type & IB_FLOW_SPEC_INNER) {
476 if (check_mpls_supp_fields(MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
477 ft_field_support.inner_first_mpls),
478 &ib_spec->mpls.mask.tag))
479 return -EOPNOTSUPP;
480
481 memcpy(MLX5_ADDR_OF(fte_match_set_misc2, misc_params2_v,
482 inner_first_mpls),
483 &ib_spec->mpls.val.tag,
484 sizeof(ib_spec->mpls.val.tag));
485 memcpy(MLX5_ADDR_OF(fte_match_set_misc2, misc_params2_c,
486 inner_first_mpls),
487 &ib_spec->mpls.mask.tag,
488 sizeof(ib_spec->mpls.mask.tag));
489 } else {
490 if (check_mpls_supp_fields(MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
491 ft_field_support.outer_first_mpls),
492 &ib_spec->mpls.mask.tag))
493 return -EOPNOTSUPP;
494
495 memcpy(MLX5_ADDR_OF(fte_match_set_misc2, misc_params2_v,
496 outer_first_mpls),
497 &ib_spec->mpls.val.tag,
498 sizeof(ib_spec->mpls.val.tag));
499 memcpy(MLX5_ADDR_OF(fte_match_set_misc2, misc_params2_c,
500 outer_first_mpls),
501 &ib_spec->mpls.mask.tag,
502 sizeof(ib_spec->mpls.mask.tag));
503 }
504 }
505 break;
506 case IB_FLOW_SPEC_VXLAN_TUNNEL:
507 if (FIELDS_NOT_SUPPORTED(ib_spec->tunnel.mask,
508 LAST_TUNNEL_FIELD))
509 return -EOPNOTSUPP;
510
511 MLX5_SET(fte_match_set_misc, misc_params_c, vxlan_vni,
512 ntohl(ib_spec->tunnel.mask.tunnel_id));
513 MLX5_SET(fte_match_set_misc, misc_params_v, vxlan_vni,
514 ntohl(ib_spec->tunnel.val.tunnel_id));
515 break;
516 case IB_FLOW_SPEC_ACTION_TAG:
517 if (FIELDS_NOT_SUPPORTED(ib_spec->flow_tag,
518 LAST_FLOW_TAG_FIELD))
519 return -EOPNOTSUPP;
520 if (ib_spec->flow_tag.tag_id >= BIT(24))
521 return -EINVAL;
522
523 flow_context->flow_tag = ib_spec->flow_tag.tag_id;
524 flow_context->flags |= FLOW_CONTEXT_HAS_TAG;
525 break;
526 case IB_FLOW_SPEC_ACTION_DROP:
527 if (FIELDS_NOT_SUPPORTED(ib_spec->drop,
528 LAST_DROP_FIELD))
529 return -EOPNOTSUPP;
530 action->action |= MLX5_FLOW_CONTEXT_ACTION_DROP;
531 break;
532 case IB_FLOW_SPEC_ACTION_HANDLE:
533 ret = parse_flow_flow_action(to_mflow_act(ib_spec->action.act),
534 flow_attr->flags & IB_FLOW_ATTR_FLAGS_EGRESS, action);
535 if (ret)
536 return ret;
537 break;
538 case IB_FLOW_SPEC_ACTION_COUNT:
539 if (FIELDS_NOT_SUPPORTED(ib_spec->flow_count,
540 LAST_COUNTERS_FIELD))
541 return -EOPNOTSUPP;
542
543 /* for now support only one counters spec per flow */
544 if (action->action & MLX5_FLOW_CONTEXT_ACTION_COUNT)
545 return -EINVAL;
546
547 action->counters = ib_spec->flow_count.counters;
548 action->action |= MLX5_FLOW_CONTEXT_ACTION_COUNT;
549 break;
550 default:
551 return -EINVAL;
552 }
553
554 return 0;
555}
556
557/* If a flow could catch both multicast and unicast packets,
558 * it won't fall into the multicast flow steering table and this rule
559 * could steal other multicast packets.
560 */
561static bool flow_is_multicast_only(const struct ib_flow_attr *ib_attr)
562{
563 union ib_flow_spec *flow_spec;
564
565 if (ib_attr->type != IB_FLOW_ATTR_NORMAL ||
566 ib_attr->num_of_specs < 1)
567 return false;
568
569 flow_spec = (union ib_flow_spec *)(ib_attr + 1);
570 if (flow_spec->type == IB_FLOW_SPEC_IPV4) {
571 struct ib_flow_spec_ipv4 *ipv4_spec;
572
573 ipv4_spec = (struct ib_flow_spec_ipv4 *)flow_spec;
574 if (ipv4_is_multicast(ipv4_spec->val.dst_ip))
575 return true;
576
577 return false;
578 }
579
580 if (flow_spec->type == IB_FLOW_SPEC_ETH) {
581 struct ib_flow_spec_eth *eth_spec;
582
583 eth_spec = (struct ib_flow_spec_eth *)flow_spec;
584 return is_multicast_ether_addr(eth_spec->mask.dst_mac) &&
585 is_multicast_ether_addr(eth_spec->val.dst_mac);
586 }
587
588 return false;
589}
590
591enum valid_spec {
592 VALID_SPEC_INVALID,
593 VALID_SPEC_VALID,
594 VALID_SPEC_NA,
595};
596
597static enum valid_spec
598is_valid_esp_aes_gcm(struct mlx5_core_dev *mdev,
599 const struct mlx5_flow_spec *spec,
600 const struct mlx5_flow_act *flow_act,
601 bool egress)
602{
603 const u32 *match_c = spec->match_criteria;
604 bool is_crypto =
605 (flow_act->action & (MLX5_FLOW_CONTEXT_ACTION_ENCRYPT |
606 MLX5_FLOW_CONTEXT_ACTION_DECRYPT));
607 bool is_ipsec = mlx5_fs_is_ipsec_flow(match_c);
608 bool is_drop = flow_act->action & MLX5_FLOW_CONTEXT_ACTION_DROP;
609
610 /*
611 * Currently only crypto is supported in egress, when regular egress
612 * rules would be supported, always return VALID_SPEC_NA.
613 */
614 if (!is_crypto)
615 return VALID_SPEC_NA;
616
617 return is_crypto && is_ipsec &&
618 (!egress || (!is_drop &&
619 !(spec->flow_context.flags & FLOW_CONTEXT_HAS_TAG))) ?
620 VALID_SPEC_VALID : VALID_SPEC_INVALID;
621}
622
623static bool is_valid_spec(struct mlx5_core_dev *mdev,
624 const struct mlx5_flow_spec *spec,
625 const struct mlx5_flow_act *flow_act,
626 bool egress)
627{
628 /* We curretly only support ipsec egress flow */
629 return is_valid_esp_aes_gcm(mdev, spec, flow_act, egress) != VALID_SPEC_INVALID;
630}
631
632static bool is_valid_ethertype(struct mlx5_core_dev *mdev,
633 const struct ib_flow_attr *flow_attr,
634 bool check_inner)
635{
636 union ib_flow_spec *ib_spec = (union ib_flow_spec *)(flow_attr + 1);
637 int match_ipv = check_inner ?
638 MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
639 ft_field_support.inner_ip_version) :
640 MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
641 ft_field_support.outer_ip_version);
642 int inner_bit = check_inner ? IB_FLOW_SPEC_INNER : 0;
643 bool ipv4_spec_valid, ipv6_spec_valid;
644 unsigned int ip_spec_type = 0;
645 bool has_ethertype = false;
646 unsigned int spec_index;
647 bool mask_valid = true;
648 u16 eth_type = 0;
649 bool type_valid;
650
651 /* Validate that ethertype is correct */
652 for (spec_index = 0; spec_index < flow_attr->num_of_specs; spec_index++) {
653 if ((ib_spec->type == (IB_FLOW_SPEC_ETH | inner_bit)) &&
654 ib_spec->eth.mask.ether_type) {
655 mask_valid = (ib_spec->eth.mask.ether_type ==
656 htons(0xffff));
657 has_ethertype = true;
658 eth_type = ntohs(ib_spec->eth.val.ether_type);
659 } else if ((ib_spec->type == (IB_FLOW_SPEC_IPV4 | inner_bit)) ||
660 (ib_spec->type == (IB_FLOW_SPEC_IPV6 | inner_bit))) {
661 ip_spec_type = ib_spec->type;
662 }
663 ib_spec = (void *)ib_spec + ib_spec->size;
664 }
665
666 type_valid = (!has_ethertype) || (!ip_spec_type);
667 if (!type_valid && mask_valid) {
668 ipv4_spec_valid = (eth_type == ETH_P_IP) &&
669 (ip_spec_type == (IB_FLOW_SPEC_IPV4 | inner_bit));
670 ipv6_spec_valid = (eth_type == ETH_P_IPV6) &&
671 (ip_spec_type == (IB_FLOW_SPEC_IPV6 | inner_bit));
672
673 type_valid = (ipv4_spec_valid) || (ipv6_spec_valid) ||
674 (((eth_type == ETH_P_MPLS_UC) ||
675 (eth_type == ETH_P_MPLS_MC)) && match_ipv);
676 }
677
678 return type_valid;
679}
680
681static bool is_valid_attr(struct mlx5_core_dev *mdev,
682 const struct ib_flow_attr *flow_attr)
683{
684 return is_valid_ethertype(mdev, flow_attr, false) &&
685 is_valid_ethertype(mdev, flow_attr, true);
686}
687
688static void put_flow_table(struct mlx5_ib_dev *dev,
689 struct mlx5_ib_flow_prio *prio, bool ft_added)
690{
691 prio->refcount -= !!ft_added;
692 if (!prio->refcount) {
693 mlx5_destroy_flow_table(prio->flow_table);
694 prio->flow_table = NULL;
695 }
696}
697
698static int mlx5_ib_destroy_flow(struct ib_flow *flow_id)
699{
700 struct mlx5_ib_flow_handler *handler = container_of(flow_id,
701 struct mlx5_ib_flow_handler,
702 ibflow);
703 struct mlx5_ib_flow_handler *iter, *tmp;
704 struct mlx5_ib_dev *dev = handler->dev;
705
706 mutex_lock(&dev->flow_db->lock);
707
708 list_for_each_entry_safe(iter, tmp, &handler->list, list) {
709 mlx5_del_flow_rules(iter->rule);
710 put_flow_table(dev, iter->prio, true);
711 list_del(&iter->list);
712 kfree(iter);
713 }
714
715 mlx5_del_flow_rules(handler->rule);
716 put_flow_table(dev, handler->prio, true);
717 mlx5_ib_counters_clear_description(handler->ibcounters);
718 mutex_unlock(&dev->flow_db->lock);
719 if (handler->flow_matcher)
720 atomic_dec(&handler->flow_matcher->usecnt);
721 kfree(handler);
722
723 return 0;
724}
725
726static int ib_prio_to_core_prio(unsigned int priority, bool dont_trap)
727{
728 priority *= 2;
729 if (!dont_trap)
730 priority++;
731 return priority;
732}
733
734enum flow_table_type {
735 MLX5_IB_FT_RX,
736 MLX5_IB_FT_TX
737};
738
739#define MLX5_FS_MAX_TYPES 6
740#define MLX5_FS_MAX_ENTRIES BIT(16)
741
742static struct mlx5_ib_flow_prio *_get_prio(struct mlx5_flow_namespace *ns,
743 struct mlx5_ib_flow_prio *prio,
744 int priority,
745 int num_entries, int num_groups,
746 u32 flags)
747{
748 struct mlx5_flow_table_attr ft_attr = {};
749 struct mlx5_flow_table *ft;
750
751 ft_attr.prio = priority;
752 ft_attr.max_fte = num_entries;
753 ft_attr.flags = flags;
754 ft_attr.autogroup.max_num_groups = num_groups;
755 ft = mlx5_create_auto_grouped_flow_table(ns, &ft_attr);
756 if (IS_ERR(ft))
757 return ERR_CAST(ft);
758
759 prio->flow_table = ft;
760 prio->refcount = 0;
761 return prio;
762}
763
764static struct mlx5_ib_flow_prio *get_flow_table(struct mlx5_ib_dev *dev,
765 struct ib_flow_attr *flow_attr,
766 enum flow_table_type ft_type)
767{
768 bool dont_trap = flow_attr->flags & IB_FLOW_ATTR_FLAGS_DONT_TRAP;
769 struct mlx5_flow_namespace *ns = NULL;
770 struct mlx5_ib_flow_prio *prio;
771 struct mlx5_flow_table *ft;
772 int max_table_size;
773 int num_entries;
774 int num_groups;
775 bool esw_encap;
776 u32 flags = 0;
777 int priority;
778
779 max_table_size = BIT(MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev,
780 log_max_ft_size));
781 esw_encap = mlx5_eswitch_get_encap_mode(dev->mdev) !=
782 DEVLINK_ESWITCH_ENCAP_MODE_NONE;
783 if (flow_attr->type == IB_FLOW_ATTR_NORMAL) {
784 enum mlx5_flow_namespace_type fn_type;
785
786 if (flow_is_multicast_only(flow_attr) &&
787 !dont_trap)
788 priority = MLX5_IB_FLOW_MCAST_PRIO;
789 else
790 priority = ib_prio_to_core_prio(flow_attr->priority,
791 dont_trap);
792 if (ft_type == MLX5_IB_FT_RX) {
793 fn_type = MLX5_FLOW_NAMESPACE_BYPASS;
794 prio = &dev->flow_db->prios[priority];
795 if (!dev->is_rep && !esw_encap &&
796 MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev, decap))
797 flags |= MLX5_FLOW_TABLE_TUNNEL_EN_DECAP;
798 if (!dev->is_rep && !esw_encap &&
799 MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev,
800 reformat_l3_tunnel_to_l2))
801 flags |= MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT;
802 } else {
803 max_table_size =
804 BIT(MLX5_CAP_FLOWTABLE_NIC_TX(dev->mdev,
805 log_max_ft_size));
806 fn_type = MLX5_FLOW_NAMESPACE_EGRESS;
807 prio = &dev->flow_db->egress_prios[priority];
808 if (!dev->is_rep && !esw_encap &&
809 MLX5_CAP_FLOWTABLE_NIC_TX(dev->mdev, reformat))
810 flags |= MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT;
811 }
812 ns = mlx5_get_flow_namespace(dev->mdev, fn_type);
813 num_entries = MLX5_FS_MAX_ENTRIES;
814 num_groups = MLX5_FS_MAX_TYPES;
815 } else if (flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT ||
816 flow_attr->type == IB_FLOW_ATTR_MC_DEFAULT) {
817 ns = mlx5_get_flow_namespace(dev->mdev,
818 MLX5_FLOW_NAMESPACE_LEFTOVERS);
819 build_leftovers_ft_param(&priority,
820 &num_entries,
821 &num_groups);
822 prio = &dev->flow_db->prios[MLX5_IB_FLOW_LEFTOVERS_PRIO];
823 } else if (flow_attr->type == IB_FLOW_ATTR_SNIFFER) {
824 if (!MLX5_CAP_FLOWTABLE(dev->mdev,
825 allow_sniffer_and_nic_rx_shared_tir))
826 return ERR_PTR(-EOPNOTSUPP);
827
828 ns = mlx5_get_flow_namespace(dev->mdev, ft_type == MLX5_IB_FT_RX ?
829 MLX5_FLOW_NAMESPACE_SNIFFER_RX :
830 MLX5_FLOW_NAMESPACE_SNIFFER_TX);
831
832 prio = &dev->flow_db->sniffer[ft_type];
833 priority = 0;
834 num_entries = 1;
835 num_groups = 1;
836 }
837
838 if (!ns)
839 return ERR_PTR(-EOPNOTSUPP);
840
841 max_table_size = min_t(int, num_entries, max_table_size);
842
843 ft = prio->flow_table;
844 if (!ft)
845 return _get_prio(ns, prio, priority, max_table_size, num_groups,
846 flags);
847
848 return prio;
849}
850
851static void set_underlay_qp(struct mlx5_ib_dev *dev,
852 struct mlx5_flow_spec *spec,
853 u32 underlay_qpn)
854{
855 void *misc_params_c = MLX5_ADDR_OF(fte_match_param,
856 spec->match_criteria,
857 misc_parameters);
858 void *misc_params_v = MLX5_ADDR_OF(fte_match_param, spec->match_value,
859 misc_parameters);
860
861 if (underlay_qpn &&
862 MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev,
863 ft_field_support.bth_dst_qp)) {
864 MLX5_SET(fte_match_set_misc,
865 misc_params_v, bth_dst_qp, underlay_qpn);
866 MLX5_SET(fte_match_set_misc,
867 misc_params_c, bth_dst_qp, 0xffffff);
868 }
869}
870
871static void mlx5_ib_set_rule_source_port(struct mlx5_ib_dev *dev,
872 struct mlx5_flow_spec *spec,
873 struct mlx5_eswitch_rep *rep)
874{
875 struct mlx5_eswitch *esw = dev->mdev->priv.eswitch;
876 void *misc;
877
878 if (mlx5_eswitch_vport_match_metadata_enabled(esw)) {
879 misc = MLX5_ADDR_OF(fte_match_param, spec->match_value,
880 misc_parameters_2);
881
882 MLX5_SET(fte_match_set_misc2, misc, metadata_reg_c_0,
883 mlx5_eswitch_get_vport_metadata_for_match(esw,
884 rep->vport));
885 misc = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
886 misc_parameters_2);
887
888 MLX5_SET(fte_match_set_misc2, misc, metadata_reg_c_0,
889 mlx5_eswitch_get_vport_metadata_mask());
890 } else {
891 misc = MLX5_ADDR_OF(fte_match_param, spec->match_value,
892 misc_parameters);
893
894 MLX5_SET(fte_match_set_misc, misc, source_port, rep->vport);
895
896 misc = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
897 misc_parameters);
898
899 MLX5_SET_TO_ONES(fte_match_set_misc, misc, source_port);
900 }
901}
902
903static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev,
904 struct mlx5_ib_flow_prio *ft_prio,
905 const struct ib_flow_attr *flow_attr,
906 struct mlx5_flow_destination *dst,
907 u32 underlay_qpn,
908 struct mlx5_ib_create_flow *ucmd)
909{
910 struct mlx5_flow_table *ft = ft_prio->flow_table;
911 struct mlx5_ib_flow_handler *handler;
912 struct mlx5_flow_act flow_act = {};
913 struct mlx5_flow_spec *spec;
914 struct mlx5_flow_destination dest_arr[2] = {};
915 struct mlx5_flow_destination *rule_dst = dest_arr;
916 const void *ib_flow = (const void *)flow_attr + sizeof(*flow_attr);
917 unsigned int spec_index;
918 u32 prev_type = 0;
919 int err = 0;
920 int dest_num = 0;
921 bool is_egress = flow_attr->flags & IB_FLOW_ATTR_FLAGS_EGRESS;
922
923 if (!is_valid_attr(dev->mdev, flow_attr))
924 return ERR_PTR(-EINVAL);
925
926 if (dev->is_rep && is_egress)
927 return ERR_PTR(-EINVAL);
928
929 spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
930 handler = kzalloc(sizeof(*handler), GFP_KERNEL);
931 if (!handler || !spec) {
932 err = -ENOMEM;
933 goto free;
934 }
935
936 INIT_LIST_HEAD(&handler->list);
937
938 for (spec_index = 0; spec_index < flow_attr->num_of_specs; spec_index++) {
939 err = parse_flow_attr(dev->mdev, spec,
940 ib_flow, flow_attr, &flow_act,
941 prev_type);
942 if (err < 0)
943 goto free;
944
945 prev_type = ((union ib_flow_spec *)ib_flow)->type;
946 ib_flow += ((union ib_flow_spec *)ib_flow)->size;
947 }
948
949 if (dst && !(flow_act.action & MLX5_FLOW_CONTEXT_ACTION_DROP)) {
950 memcpy(&dest_arr[0], dst, sizeof(*dst));
951 dest_num++;
952 }
953
954 if (!flow_is_multicast_only(flow_attr))
955 set_underlay_qp(dev, spec, underlay_qpn);
956
957 if (dev->is_rep) {
958 struct mlx5_eswitch_rep *rep;
959
960 rep = dev->port[flow_attr->port - 1].rep;
961 if (!rep) {
962 err = -EINVAL;
963 goto free;
964 }
965
966 mlx5_ib_set_rule_source_port(dev, spec, rep);
967 }
968
969 spec->match_criteria_enable = get_match_criteria_enable(spec->match_criteria);
970
971 if (is_egress &&
972 !is_valid_spec(dev->mdev, spec, &flow_act, is_egress)) {
973 err = -EINVAL;
974 goto free;
975 }
976
977 if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_COUNT) {
978 struct mlx5_ib_mcounters *mcounters;
979
980 err = mlx5_ib_flow_counters_set_data(flow_act.counters, ucmd);
981 if (err)
982 goto free;
983
984 mcounters = to_mcounters(flow_act.counters);
985 handler->ibcounters = flow_act.counters;
986 dest_arr[dest_num].type =
987 MLX5_FLOW_DESTINATION_TYPE_COUNTER;
988 dest_arr[dest_num].counter_id =
989 mlx5_fc_id(mcounters->hw_cntrs_hndl);
990 dest_num++;
991 }
992
993 if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_DROP) {
994 if (!dest_num)
995 rule_dst = NULL;
996 } else {
997 if (flow_attr->flags & IB_FLOW_ATTR_FLAGS_DONT_TRAP)
998 flow_act.action |=
999 MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO;
1000 if (is_egress)
1001 flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_ALLOW;
1002 else if (dest_num)
1003 flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
1004 }
1005
1006 if ((spec->flow_context.flags & FLOW_CONTEXT_HAS_TAG) &&
1007 (flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT ||
1008 flow_attr->type == IB_FLOW_ATTR_MC_DEFAULT)) {
1009 mlx5_ib_warn(dev, "Flow tag %u and attribute type %x isn't allowed in leftovers\n",
1010 spec->flow_context.flow_tag, flow_attr->type);
1011 err = -EINVAL;
1012 goto free;
1013 }
1014 handler->rule = mlx5_add_flow_rules(ft, spec,
1015 &flow_act,
1016 rule_dst, dest_num);
1017
1018 if (IS_ERR(handler->rule)) {
1019 err = PTR_ERR(handler->rule);
1020 goto free;
1021 }
1022
1023 ft_prio->refcount++;
1024 handler->prio = ft_prio;
1025 handler->dev = dev;
1026
1027 ft_prio->flow_table = ft;
1028free:
1029 if (err && handler) {
1030 mlx5_ib_counters_clear_description(handler->ibcounters);
1031 kfree(handler);
1032 }
1033 kvfree(spec);
1034 return err ? ERR_PTR(err) : handler;
1035}
1036
1037static struct mlx5_ib_flow_handler *create_flow_rule(struct mlx5_ib_dev *dev,
1038 struct mlx5_ib_flow_prio *ft_prio,
1039 const struct ib_flow_attr *flow_attr,
1040 struct mlx5_flow_destination *dst)
1041{
1042 return _create_flow_rule(dev, ft_prio, flow_attr, dst, 0, NULL);
1043}
1044
1045enum {
1046 LEFTOVERS_MC,
1047 LEFTOVERS_UC,
1048};
1049
1050static struct mlx5_ib_flow_handler *create_leftovers_rule(struct mlx5_ib_dev *dev,
1051 struct mlx5_ib_flow_prio *ft_prio,
1052 struct ib_flow_attr *flow_attr,
1053 struct mlx5_flow_destination *dst)
1054{
1055 struct mlx5_ib_flow_handler *handler_ucast = NULL;
1056 struct mlx5_ib_flow_handler *handler = NULL;
1057
1058 static struct {
1059 struct ib_flow_attr flow_attr;
1060 struct ib_flow_spec_eth eth_flow;
1061 } leftovers_specs[] = {
1062 [LEFTOVERS_MC] = {
1063 .flow_attr = {
1064 .num_of_specs = 1,
1065 .size = sizeof(leftovers_specs[0])
1066 },
1067 .eth_flow = {
1068 .type = IB_FLOW_SPEC_ETH,
1069 .size = sizeof(struct ib_flow_spec_eth),
1070 .mask = {.dst_mac = {0x1} },
1071 .val = {.dst_mac = {0x1} }
1072 }
1073 },
1074 [LEFTOVERS_UC] = {
1075 .flow_attr = {
1076 .num_of_specs = 1,
1077 .size = sizeof(leftovers_specs[0])
1078 },
1079 .eth_flow = {
1080 .type = IB_FLOW_SPEC_ETH,
1081 .size = sizeof(struct ib_flow_spec_eth),
1082 .mask = {.dst_mac = {0x1} },
1083 .val = {.dst_mac = {} }
1084 }
1085 }
1086 };
1087
1088 handler = create_flow_rule(dev, ft_prio,
1089 &leftovers_specs[LEFTOVERS_MC].flow_attr,
1090 dst);
1091 if (!IS_ERR(handler) &&
1092 flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT) {
1093 handler_ucast = create_flow_rule(dev, ft_prio,
1094 &leftovers_specs[LEFTOVERS_UC].flow_attr,
1095 dst);
1096 if (IS_ERR(handler_ucast)) {
1097 mlx5_del_flow_rules(handler->rule);
1098 ft_prio->refcount--;
1099 kfree(handler);
1100 handler = handler_ucast;
1101 } else {
1102 list_add(&handler_ucast->list, &handler->list);
1103 }
1104 }
1105
1106 return handler;
1107}
1108
1109static struct mlx5_ib_flow_handler *create_sniffer_rule(struct mlx5_ib_dev *dev,
1110 struct mlx5_ib_flow_prio *ft_rx,
1111 struct mlx5_ib_flow_prio *ft_tx,
1112 struct mlx5_flow_destination *dst)
1113{
1114 struct mlx5_ib_flow_handler *handler_rx;
1115 struct mlx5_ib_flow_handler *handler_tx;
1116 int err;
1117 static const struct ib_flow_attr flow_attr = {
1118 .num_of_specs = 0,
1119 .size = sizeof(flow_attr)
1120 };
1121
1122 handler_rx = create_flow_rule(dev, ft_rx, &flow_attr, dst);
1123 if (IS_ERR(handler_rx)) {
1124 err = PTR_ERR(handler_rx);
1125 goto err;
1126 }
1127
1128 handler_tx = create_flow_rule(dev, ft_tx, &flow_attr, dst);
1129 if (IS_ERR(handler_tx)) {
1130 err = PTR_ERR(handler_tx);
1131 goto err_tx;
1132 }
1133
1134 list_add(&handler_tx->list, &handler_rx->list);
1135
1136 return handler_rx;
1137
1138err_tx:
1139 mlx5_del_flow_rules(handler_rx->rule);
1140 ft_rx->refcount--;
1141 kfree(handler_rx);
1142err:
1143 return ERR_PTR(err);
1144}
1145
1146
1147static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp,
1148 struct ib_flow_attr *flow_attr,
1149 int domain,
1150 struct ib_udata *udata)
1151{
1152 struct mlx5_ib_dev *dev = to_mdev(qp->device);
1153 struct mlx5_ib_qp *mqp = to_mqp(qp);
1154 struct mlx5_ib_flow_handler *handler = NULL;
1155 struct mlx5_flow_destination *dst = NULL;
1156 struct mlx5_ib_flow_prio *ft_prio_tx = NULL;
1157 struct mlx5_ib_flow_prio *ft_prio;
1158 bool is_egress = flow_attr->flags & IB_FLOW_ATTR_FLAGS_EGRESS;
1159 struct mlx5_ib_create_flow *ucmd = NULL, ucmd_hdr;
1160 size_t min_ucmd_sz, required_ucmd_sz;
1161 int err;
1162 int underlay_qpn;
1163
1164 if (udata && udata->inlen) {
1165 min_ucmd_sz = offsetof(typeof(ucmd_hdr), reserved) +
1166 sizeof(ucmd_hdr.reserved);
1167 if (udata->inlen < min_ucmd_sz)
1168 return ERR_PTR(-EOPNOTSUPP);
1169
1170 err = ib_copy_from_udata(&ucmd_hdr, udata, min_ucmd_sz);
1171 if (err)
1172 return ERR_PTR(err);
1173
1174 /* currently supports only one counters data */
1175 if (ucmd_hdr.ncounters_data > 1)
1176 return ERR_PTR(-EINVAL);
1177
1178 required_ucmd_sz = min_ucmd_sz +
1179 sizeof(struct mlx5_ib_flow_counters_data) *
1180 ucmd_hdr.ncounters_data;
1181 if (udata->inlen > required_ucmd_sz &&
1182 !ib_is_udata_cleared(udata, required_ucmd_sz,
1183 udata->inlen - required_ucmd_sz))
1184 return ERR_PTR(-EOPNOTSUPP);
1185
1186 ucmd = kzalloc(required_ucmd_sz, GFP_KERNEL);
1187 if (!ucmd)
1188 return ERR_PTR(-ENOMEM);
1189
1190 err = ib_copy_from_udata(ucmd, udata, required_ucmd_sz);
1191 if (err)
1192 goto free_ucmd;
1193 }
1194
1195 if (flow_attr->priority > MLX5_IB_FLOW_LAST_PRIO) {
1196 err = -ENOMEM;
1197 goto free_ucmd;
1198 }
1199
1200 if (domain != IB_FLOW_DOMAIN_USER ||
1201 flow_attr->port > dev->num_ports ||
1202 (flow_attr->flags & ~(IB_FLOW_ATTR_FLAGS_DONT_TRAP |
1203 IB_FLOW_ATTR_FLAGS_EGRESS))) {
1204 err = -EINVAL;
1205 goto free_ucmd;
1206 }
1207
1208 if (is_egress &&
1209 (flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT ||
1210 flow_attr->type == IB_FLOW_ATTR_MC_DEFAULT)) {
1211 err = -EINVAL;
1212 goto free_ucmd;
1213 }
1214
1215 dst = kzalloc(sizeof(*dst), GFP_KERNEL);
1216 if (!dst) {
1217 err = -ENOMEM;
1218 goto free_ucmd;
1219 }
1220
1221 mutex_lock(&dev->flow_db->lock);
1222
1223 ft_prio = get_flow_table(dev, flow_attr,
1224 is_egress ? MLX5_IB_FT_TX : MLX5_IB_FT_RX);
1225 if (IS_ERR(ft_prio)) {
1226 err = PTR_ERR(ft_prio);
1227 goto unlock;
1228 }
1229 if (flow_attr->type == IB_FLOW_ATTR_SNIFFER) {
1230 ft_prio_tx = get_flow_table(dev, flow_attr, MLX5_IB_FT_TX);
1231 if (IS_ERR(ft_prio_tx)) {
1232 err = PTR_ERR(ft_prio_tx);
1233 ft_prio_tx = NULL;
1234 goto destroy_ft;
1235 }
1236 }
1237
1238 if (is_egress) {
1239 dst->type = MLX5_FLOW_DESTINATION_TYPE_PORT;
1240 } else {
1241 dst->type = MLX5_FLOW_DESTINATION_TYPE_TIR;
1242 if (mqp->is_rss)
1243 dst->tir_num = mqp->rss_qp.tirn;
1244 else
1245 dst->tir_num = mqp->raw_packet_qp.rq.tirn;
1246 }
1247
1248 if (flow_attr->type == IB_FLOW_ATTR_NORMAL) {
1249 underlay_qpn = (mqp->flags & IB_QP_CREATE_SOURCE_QPN) ?
1250 mqp->underlay_qpn :
1251 0;
1252 handler = _create_flow_rule(dev, ft_prio, flow_attr, dst,
1253 underlay_qpn, ucmd);
1254 } else if (flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT ||
1255 flow_attr->type == IB_FLOW_ATTR_MC_DEFAULT) {
1256 handler = create_leftovers_rule(dev, ft_prio, flow_attr,
1257 dst);
1258 } else if (flow_attr->type == IB_FLOW_ATTR_SNIFFER) {
1259 handler = create_sniffer_rule(dev, ft_prio, ft_prio_tx, dst);
1260 } else {
1261 err = -EINVAL;
1262 goto destroy_ft;
1263 }
1264
1265 if (IS_ERR(handler)) {
1266 err = PTR_ERR(handler);
1267 handler = NULL;
1268 goto destroy_ft;
1269 }
1270
1271 mutex_unlock(&dev->flow_db->lock);
1272 kfree(dst);
1273 kfree(ucmd);
1274
1275 return &handler->ibflow;
1276
1277destroy_ft:
1278 put_flow_table(dev, ft_prio, false);
1279 if (ft_prio_tx)
1280 put_flow_table(dev, ft_prio_tx, false);
1281unlock:
1282 mutex_unlock(&dev->flow_db->lock);
1283 kfree(dst);
1284free_ucmd:
1285 kfree(ucmd);
1286 return ERR_PTR(err);
1287}
1288
1289static struct mlx5_ib_flow_prio *
1290_get_flow_table(struct mlx5_ib_dev *dev,
1291 struct mlx5_ib_flow_matcher *fs_matcher,
1292 bool mcast)
1293{
1294 struct mlx5_flow_namespace *ns = NULL;
1295 struct mlx5_ib_flow_prio *prio = NULL;
1296 int max_table_size = 0;
1297 bool esw_encap;
1298 u32 flags = 0;
1299 int priority;
1300
1301 if (mcast)
1302 priority = MLX5_IB_FLOW_MCAST_PRIO;
1303 else
1304 priority = ib_prio_to_core_prio(fs_matcher->priority, false);
1305
1306 esw_encap = mlx5_eswitch_get_encap_mode(dev->mdev) !=
1307 DEVLINK_ESWITCH_ENCAP_MODE_NONE;
1308 if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_BYPASS) {
1309 max_table_size = BIT(MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev,
1310 log_max_ft_size));
1311 if (MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev, decap) && !esw_encap)
1312 flags |= MLX5_FLOW_TABLE_TUNNEL_EN_DECAP;
1313 if (MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev,
1314 reformat_l3_tunnel_to_l2) &&
1315 !esw_encap)
1316 flags |= MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT;
1317 } else if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_EGRESS) {
1318 max_table_size = BIT(
1319 MLX5_CAP_FLOWTABLE_NIC_TX(dev->mdev, log_max_ft_size));
1320 if (MLX5_CAP_FLOWTABLE_NIC_TX(dev->mdev, reformat) && !esw_encap)
1321 flags |= MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT;
1322 } else if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_FDB) {
1323 max_table_size = BIT(
1324 MLX5_CAP_ESW_FLOWTABLE_FDB(dev->mdev, log_max_ft_size));
1325 if (MLX5_CAP_ESW_FLOWTABLE_FDB(dev->mdev, decap) && esw_encap)
1326 flags |= MLX5_FLOW_TABLE_TUNNEL_EN_DECAP;
1327 if (MLX5_CAP_ESW_FLOWTABLE_FDB(dev->mdev, reformat_l3_tunnel_to_l2) &&
1328 esw_encap)
1329 flags |= MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT;
1330 priority = FDB_BYPASS_PATH;
1331 } else if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_RDMA_RX) {
1332 max_table_size =
1333 BIT(MLX5_CAP_FLOWTABLE_RDMA_RX(dev->mdev,
1334 log_max_ft_size));
1335 priority = fs_matcher->priority;
1336 } else if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_RDMA_TX) {
1337 max_table_size =
1338 BIT(MLX5_CAP_FLOWTABLE_RDMA_TX(dev->mdev,
1339 log_max_ft_size));
1340 priority = fs_matcher->priority;
1341 }
1342
1343 max_table_size = min_t(int, max_table_size, MLX5_FS_MAX_ENTRIES);
1344
1345 ns = mlx5_get_flow_namespace(dev->mdev, fs_matcher->ns_type);
1346 if (!ns)
1347 return ERR_PTR(-EOPNOTSUPP);
1348
1349 if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_BYPASS)
1350 prio = &dev->flow_db->prios[priority];
1351 else if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_EGRESS)
1352 prio = &dev->flow_db->egress_prios[priority];
1353 else if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_FDB)
1354 prio = &dev->flow_db->fdb;
1355 else if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_RDMA_RX)
1356 prio = &dev->flow_db->rdma_rx[priority];
1357 else if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_RDMA_TX)
1358 prio = &dev->flow_db->rdma_tx[priority];
1359
1360 if (!prio)
1361 return ERR_PTR(-EINVAL);
1362
1363 if (prio->flow_table)
1364 return prio;
1365
1366 return _get_prio(ns, prio, priority, max_table_size,
1367 MLX5_FS_MAX_TYPES, flags);
1368}
1369
1370static struct mlx5_ib_flow_handler *
1371_create_raw_flow_rule(struct mlx5_ib_dev *dev,
1372 struct mlx5_ib_flow_prio *ft_prio,
1373 struct mlx5_flow_destination *dst,
1374 struct mlx5_ib_flow_matcher *fs_matcher,
1375 struct mlx5_flow_context *flow_context,
1376 struct mlx5_flow_act *flow_act,
1377 void *cmd_in, int inlen,
1378 int dst_num)
1379{
1380 struct mlx5_ib_flow_handler *handler;
1381 struct mlx5_flow_spec *spec;
1382 struct mlx5_flow_table *ft = ft_prio->flow_table;
1383 int err = 0;
1384
1385 spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
1386 handler = kzalloc(sizeof(*handler), GFP_KERNEL);
1387 if (!handler || !spec) {
1388 err = -ENOMEM;
1389 goto free;
1390 }
1391
1392 INIT_LIST_HEAD(&handler->list);
1393
1394 memcpy(spec->match_value, cmd_in, inlen);
1395 memcpy(spec->match_criteria, fs_matcher->matcher_mask.match_params,
1396 fs_matcher->mask_len);
1397 spec->match_criteria_enable = fs_matcher->match_criteria_enable;
1398 spec->flow_context = *flow_context;
1399
1400 handler->rule = mlx5_add_flow_rules(ft, spec,
1401 flow_act, dst, dst_num);
1402
1403 if (IS_ERR(handler->rule)) {
1404 err = PTR_ERR(handler->rule);
1405 goto free;
1406 }
1407
1408 ft_prio->refcount++;
1409 handler->prio = ft_prio;
1410 handler->dev = dev;
1411 ft_prio->flow_table = ft;
1412
1413free:
1414 if (err)
1415 kfree(handler);
1416 kvfree(spec);
1417 return err ? ERR_PTR(err) : handler;
1418}
1419
1420static bool raw_fs_is_multicast(struct mlx5_ib_flow_matcher *fs_matcher,
1421 void *match_v)
1422{
1423 void *match_c;
1424 void *match_v_set_lyr_2_4, *match_c_set_lyr_2_4;
1425 void *dmac, *dmac_mask;
1426 void *ipv4, *ipv4_mask;
1427
1428 if (!(fs_matcher->match_criteria_enable &
1429 (1 << MATCH_CRITERIA_ENABLE_OUTER_BIT)))
1430 return false;
1431
1432 match_c = fs_matcher->matcher_mask.match_params;
1433 match_v_set_lyr_2_4 = MLX5_ADDR_OF(fte_match_param, match_v,
1434 outer_headers);
1435 match_c_set_lyr_2_4 = MLX5_ADDR_OF(fte_match_param, match_c,
1436 outer_headers);
1437
1438 dmac = MLX5_ADDR_OF(fte_match_set_lyr_2_4, match_v_set_lyr_2_4,
1439 dmac_47_16);
1440 dmac_mask = MLX5_ADDR_OF(fte_match_set_lyr_2_4, match_c_set_lyr_2_4,
1441 dmac_47_16);
1442
1443 if (is_multicast_ether_addr(dmac) &&
1444 is_multicast_ether_addr(dmac_mask))
1445 return true;
1446
1447 ipv4 = MLX5_ADDR_OF(fte_match_set_lyr_2_4, match_v_set_lyr_2_4,
1448 dst_ipv4_dst_ipv6.ipv4_layout.ipv4);
1449
1450 ipv4_mask = MLX5_ADDR_OF(fte_match_set_lyr_2_4, match_c_set_lyr_2_4,
1451 dst_ipv4_dst_ipv6.ipv4_layout.ipv4);
1452
1453 if (ipv4_is_multicast(*(__be32 *)(ipv4)) &&
1454 ipv4_is_multicast(*(__be32 *)(ipv4_mask)))
1455 return true;
1456
1457 return false;
1458}
1459
1460static struct mlx5_ib_flow_handler *raw_fs_rule_add(
1461 struct mlx5_ib_dev *dev, struct mlx5_ib_flow_matcher *fs_matcher,
1462 struct mlx5_flow_context *flow_context, struct mlx5_flow_act *flow_act,
1463 u32 counter_id, void *cmd_in, int inlen, int dest_id, int dest_type)
1464{
1465 struct mlx5_flow_destination *dst;
1466 struct mlx5_ib_flow_prio *ft_prio;
1467 struct mlx5_ib_flow_handler *handler;
1468 int dst_num = 0;
1469 bool mcast;
1470 int err;
1471
1472 if (fs_matcher->flow_type != MLX5_IB_FLOW_TYPE_NORMAL)
1473 return ERR_PTR(-EOPNOTSUPP);
1474
1475 if (fs_matcher->priority > MLX5_IB_FLOW_LAST_PRIO)
1476 return ERR_PTR(-ENOMEM);
1477
1478 dst = kcalloc(2, sizeof(*dst), GFP_KERNEL);
1479 if (!dst)
1480 return ERR_PTR(-ENOMEM);
1481
1482 mcast = raw_fs_is_multicast(fs_matcher, cmd_in);
1483 mutex_lock(&dev->flow_db->lock);
1484
1485 ft_prio = _get_flow_table(dev, fs_matcher, mcast);
1486 if (IS_ERR(ft_prio)) {
1487 err = PTR_ERR(ft_prio);
1488 goto unlock;
1489 }
1490
1491 if (dest_type == MLX5_FLOW_DESTINATION_TYPE_TIR) {
1492 dst[dst_num].type = dest_type;
1493 dst[dst_num++].tir_num = dest_id;
1494 flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
1495 } else if (dest_type == MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE) {
1496 dst[dst_num].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE_NUM;
1497 dst[dst_num++].ft_num = dest_id;
1498 flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
1499 } else if (dest_type == MLX5_FLOW_DESTINATION_TYPE_PORT) {
1500 dst[dst_num++].type = MLX5_FLOW_DESTINATION_TYPE_PORT;
1501 flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_ALLOW;
1502 }
1503
1504
1505 if (flow_act->action & MLX5_FLOW_CONTEXT_ACTION_COUNT) {
1506 dst[dst_num].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
1507 dst[dst_num].counter_id = counter_id;
1508 dst_num++;
1509 }
1510
1511 handler = _create_raw_flow_rule(dev, ft_prio, dst, fs_matcher,
1512 flow_context, flow_act,
1513 cmd_in, inlen, dst_num);
1514
1515 if (IS_ERR(handler)) {
1516 err = PTR_ERR(handler);
1517 goto destroy_ft;
1518 }
1519
1520 mutex_unlock(&dev->flow_db->lock);
1521 atomic_inc(&fs_matcher->usecnt);
1522 handler->flow_matcher = fs_matcher;
1523
1524 kfree(dst);
1525
1526 return handler;
1527
1528destroy_ft:
1529 put_flow_table(dev, ft_prio, false);
1530unlock:
1531 mutex_unlock(&dev->flow_db->lock);
1532 kfree(dst);
1533
1534 return ERR_PTR(err);
1535}
1536
1537static u32 mlx5_ib_flow_action_flags_to_accel_xfrm_flags(u32 mlx5_flags)
1538{
1539 u32 flags = 0;
1540
1541 if (mlx5_flags & MLX5_IB_UAPI_FLOW_ACTION_FLAGS_REQUIRE_METADATA)
1542 flags |= MLX5_ACCEL_XFRM_FLAG_REQUIRE_METADATA;
1543
1544 return flags;
1545}
1546
1547#define MLX5_FLOW_ACTION_ESP_CREATE_LAST_SUPPORTED \
1548 MLX5_IB_UAPI_FLOW_ACTION_FLAGS_REQUIRE_METADATA
1549static struct ib_flow_action *
1550mlx5_ib_create_flow_action_esp(struct ib_device *device,
1551 const struct ib_flow_action_attrs_esp *attr,
1552 struct uverbs_attr_bundle *attrs)
1553{
1554 struct mlx5_ib_dev *mdev = to_mdev(device);
1555 struct ib_uverbs_flow_action_esp_keymat_aes_gcm *aes_gcm;
1556 struct mlx5_accel_esp_xfrm_attrs accel_attrs = {};
1557 struct mlx5_ib_flow_action *action;
1558 u64 action_flags;
1559 u64 flags;
1560 int err = 0;
1561
1562 err = uverbs_get_flags64(
1563 &action_flags, attrs, MLX5_IB_ATTR_CREATE_FLOW_ACTION_FLAGS,
1564 ((MLX5_FLOW_ACTION_ESP_CREATE_LAST_SUPPORTED << 1) - 1));
1565 if (err)
1566 return ERR_PTR(err);
1567
1568 flags = mlx5_ib_flow_action_flags_to_accel_xfrm_flags(action_flags);
1569
1570 /* We current only support a subset of the standard features. Only a
1571 * keymat of type AES_GCM, with icv_len == 16, iv_algo == SEQ and esn
1572 * (with overlap). Full offload mode isn't supported.
1573 */
1574 if (!attr->keymat || attr->replay || attr->encap ||
1575 attr->spi || attr->seq || attr->tfc_pad ||
1576 attr->hard_limit_pkts ||
1577 (attr->flags & ~(IB_FLOW_ACTION_ESP_FLAGS_ESN_TRIGGERED |
1578 IB_UVERBS_FLOW_ACTION_ESP_FLAGS_ENCRYPT)))
1579 return ERR_PTR(-EOPNOTSUPP);
1580
1581 if (attr->keymat->protocol !=
1582 IB_UVERBS_FLOW_ACTION_ESP_KEYMAT_AES_GCM)
1583 return ERR_PTR(-EOPNOTSUPP);
1584
1585 aes_gcm = &attr->keymat->keymat.aes_gcm;
1586
1587 if (aes_gcm->icv_len != 16 ||
1588 aes_gcm->iv_algo != IB_UVERBS_FLOW_ACTION_IV_ALGO_SEQ)
1589 return ERR_PTR(-EOPNOTSUPP);
1590
1591 action = kmalloc(sizeof(*action), GFP_KERNEL);
1592 if (!action)
1593 return ERR_PTR(-ENOMEM);
1594
1595 action->esp_aes_gcm.ib_flags = attr->flags;
1596 memcpy(&accel_attrs.keymat.aes_gcm.aes_key, &aes_gcm->aes_key,
1597 sizeof(accel_attrs.keymat.aes_gcm.aes_key));
1598 accel_attrs.keymat.aes_gcm.key_len = aes_gcm->key_len * 8;
1599 memcpy(&accel_attrs.keymat.aes_gcm.salt, &aes_gcm->salt,
1600 sizeof(accel_attrs.keymat.aes_gcm.salt));
1601 memcpy(&accel_attrs.keymat.aes_gcm.seq_iv, &aes_gcm->iv,
1602 sizeof(accel_attrs.keymat.aes_gcm.seq_iv));
1603 accel_attrs.keymat.aes_gcm.icv_len = aes_gcm->icv_len * 8;
1604 accel_attrs.keymat.aes_gcm.iv_algo = MLX5_ACCEL_ESP_AES_GCM_IV_ALGO_SEQ;
1605 accel_attrs.keymat_type = MLX5_ACCEL_ESP_KEYMAT_AES_GCM;
1606
1607 accel_attrs.esn = attr->esn;
1608 if (attr->flags & IB_FLOW_ACTION_ESP_FLAGS_ESN_TRIGGERED)
1609 accel_attrs.flags |= MLX5_ACCEL_ESP_FLAGS_ESN_TRIGGERED;
1610 if (attr->flags & IB_UVERBS_FLOW_ACTION_ESP_FLAGS_ESN_NEW_WINDOW)
1611 accel_attrs.flags |= MLX5_ACCEL_ESP_FLAGS_ESN_STATE_OVERLAP;
1612
1613 if (attr->flags & IB_UVERBS_FLOW_ACTION_ESP_FLAGS_ENCRYPT)
1614 accel_attrs.action |= MLX5_ACCEL_ESP_ACTION_ENCRYPT;
1615
1616 action->esp_aes_gcm.ctx =
1617 mlx5_accel_esp_create_xfrm(mdev->mdev, &accel_attrs, flags);
1618 if (IS_ERR(action->esp_aes_gcm.ctx)) {
1619 err = PTR_ERR(action->esp_aes_gcm.ctx);
1620 goto err_parse;
1621 }
1622
1623 action->esp_aes_gcm.ib_flags = attr->flags;
1624
1625 return &action->ib_action;
1626
1627err_parse:
1628 kfree(action);
1629 return ERR_PTR(err);
1630}
1631
1632static int
1633mlx5_ib_modify_flow_action_esp(struct ib_flow_action *action,
1634 const struct ib_flow_action_attrs_esp *attr,
1635 struct uverbs_attr_bundle *attrs)
1636{
1637 struct mlx5_ib_flow_action *maction = to_mflow_act(action);
1638 struct mlx5_accel_esp_xfrm_attrs accel_attrs;
1639 int err = 0;
1640
1641 if (attr->keymat || attr->replay || attr->encap ||
1642 attr->spi || attr->seq || attr->tfc_pad ||
1643 attr->hard_limit_pkts ||
1644 (attr->flags & ~(IB_FLOW_ACTION_ESP_FLAGS_ESN_TRIGGERED |
1645 IB_FLOW_ACTION_ESP_FLAGS_MOD_ESP_ATTRS |
1646 IB_UVERBS_FLOW_ACTION_ESP_FLAGS_ESN_NEW_WINDOW)))
1647 return -EOPNOTSUPP;
1648
1649 /* Only the ESN value or the MLX5_ACCEL_ESP_FLAGS_ESN_STATE_OVERLAP can
1650 * be modified.
1651 */
1652 if (!(maction->esp_aes_gcm.ib_flags &
1653 IB_FLOW_ACTION_ESP_FLAGS_ESN_TRIGGERED) &&
1654 attr->flags & (IB_FLOW_ACTION_ESP_FLAGS_ESN_TRIGGERED |
1655 IB_UVERBS_FLOW_ACTION_ESP_FLAGS_ESN_NEW_WINDOW))
1656 return -EINVAL;
1657
1658 memcpy(&accel_attrs, &maction->esp_aes_gcm.ctx->attrs,
1659 sizeof(accel_attrs));
1660
1661 accel_attrs.esn = attr->esn;
1662 if (attr->flags & IB_UVERBS_FLOW_ACTION_ESP_FLAGS_ESN_NEW_WINDOW)
1663 accel_attrs.flags |= MLX5_ACCEL_ESP_FLAGS_ESN_STATE_OVERLAP;
1664 else
1665 accel_attrs.flags &= ~MLX5_ACCEL_ESP_FLAGS_ESN_STATE_OVERLAP;
1666
1667 err = mlx5_accel_esp_modify_xfrm(maction->esp_aes_gcm.ctx,
1668 &accel_attrs);
1669 if (err)
1670 return err;
1671
1672 maction->esp_aes_gcm.ib_flags &=
1673 ~IB_UVERBS_FLOW_ACTION_ESP_FLAGS_ESN_NEW_WINDOW;
1674 maction->esp_aes_gcm.ib_flags |=
1675 attr->flags & IB_UVERBS_FLOW_ACTION_ESP_FLAGS_ESN_NEW_WINDOW;
1676
1677 return 0;
1678}
1679
1680static void destroy_flow_action_raw(struct mlx5_ib_flow_action *maction)
1681{
1682 switch (maction->flow_action_raw.sub_type) {
1683 case MLX5_IB_FLOW_ACTION_MODIFY_HEADER:
1684 mlx5_modify_header_dealloc(maction->flow_action_raw.dev->mdev,
1685 maction->flow_action_raw.modify_hdr);
1686 break;
1687 case MLX5_IB_FLOW_ACTION_PACKET_REFORMAT:
1688 mlx5_packet_reformat_dealloc(maction->flow_action_raw.dev->mdev,
1689 maction->flow_action_raw.pkt_reformat);
1690 break;
1691 case MLX5_IB_FLOW_ACTION_DECAP:
1692 break;
1693 default:
1694 break;
1695 }
1696}
1697
1698static int mlx5_ib_destroy_flow_action(struct ib_flow_action *action)
1699{
1700 struct mlx5_ib_flow_action *maction = to_mflow_act(action);
1701
1702 switch (action->type) {
1703 case IB_FLOW_ACTION_ESP:
1704 /*
1705 * We only support aes_gcm by now, so we implicitly know this is
1706 * the underline crypto.
1707 */
1708 mlx5_accel_esp_destroy_xfrm(maction->esp_aes_gcm.ctx);
1709 break;
1710 case IB_FLOW_ACTION_UNSPECIFIED:
1711 destroy_flow_action_raw(maction);
1712 break;
1713 default:
1714 WARN_ON(true);
1715 break;
1716 }
1717
1718 kfree(maction);
1719 return 0;
1720}
1721
1722static int
1723mlx5_ib_ft_type_to_namespace(enum mlx5_ib_uapi_flow_table_type table_type,
1724 enum mlx5_flow_namespace_type *namespace)
1725{
1726 switch (table_type) {
1727 case MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_RX:
1728 *namespace = MLX5_FLOW_NAMESPACE_BYPASS;
1729 break;
1730 case MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX:
1731 *namespace = MLX5_FLOW_NAMESPACE_EGRESS;
1732 break;
1733 case MLX5_IB_UAPI_FLOW_TABLE_TYPE_FDB:
1734 *namespace = MLX5_FLOW_NAMESPACE_FDB;
1735 break;
1736 case MLX5_IB_UAPI_FLOW_TABLE_TYPE_RDMA_RX:
1737 *namespace = MLX5_FLOW_NAMESPACE_RDMA_RX;
1738 break;
1739 case MLX5_IB_UAPI_FLOW_TABLE_TYPE_RDMA_TX:
1740 *namespace = MLX5_FLOW_NAMESPACE_RDMA_TX;
1741 break;
1742 default:
1743 return -EINVAL;
1744 }
1745
1746 return 0;
1747}
1748
1749static const struct uverbs_attr_spec mlx5_ib_flow_type[] = {
1750 [MLX5_IB_FLOW_TYPE_NORMAL] = {
1751 .type = UVERBS_ATTR_TYPE_PTR_IN,
1752 .u.ptr = {
1753 .len = sizeof(u16), /* data is priority */
1754 .min_len = sizeof(u16),
1755 }
1756 },
1757 [MLX5_IB_FLOW_TYPE_SNIFFER] = {
1758 .type = UVERBS_ATTR_TYPE_PTR_IN,
1759 UVERBS_ATTR_NO_DATA(),
1760 },
1761 [MLX5_IB_FLOW_TYPE_ALL_DEFAULT] = {
1762 .type = UVERBS_ATTR_TYPE_PTR_IN,
1763 UVERBS_ATTR_NO_DATA(),
1764 },
1765 [MLX5_IB_FLOW_TYPE_MC_DEFAULT] = {
1766 .type = UVERBS_ATTR_TYPE_PTR_IN,
1767 UVERBS_ATTR_NO_DATA(),
1768 },
1769};
1770
1771static bool is_flow_dest(void *obj, int *dest_id, int *dest_type)
1772{
1773 struct devx_obj *devx_obj = obj;
1774 u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, devx_obj->dinbox, opcode);
1775
1776 switch (opcode) {
1777 case MLX5_CMD_OP_DESTROY_TIR:
1778 *dest_type = MLX5_FLOW_DESTINATION_TYPE_TIR;
1779 *dest_id = MLX5_GET(general_obj_in_cmd_hdr, devx_obj->dinbox,
1780 obj_id);
1781 return true;
1782
1783 case MLX5_CMD_OP_DESTROY_FLOW_TABLE:
1784 *dest_type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
1785 *dest_id = MLX5_GET(destroy_flow_table_in, devx_obj->dinbox,
1786 table_id);
1787 return true;
1788 default:
1789 return false;
1790 }
1791}
1792
1793static int get_dests(struct uverbs_attr_bundle *attrs,
1794 struct mlx5_ib_flow_matcher *fs_matcher, int *dest_id,
1795 int *dest_type, struct ib_qp **qp, u32 *flags)
1796{
1797 bool dest_devx, dest_qp;
1798 void *devx_obj;
1799 int err;
1800
1801 dest_devx = uverbs_attr_is_valid(attrs,
1802 MLX5_IB_ATTR_CREATE_FLOW_DEST_DEVX);
1803 dest_qp = uverbs_attr_is_valid(attrs,
1804 MLX5_IB_ATTR_CREATE_FLOW_DEST_QP);
1805
1806 *flags = 0;
1807 err = uverbs_get_flags32(flags, attrs, MLX5_IB_ATTR_CREATE_FLOW_FLAGS,
1808 MLX5_IB_ATTR_CREATE_FLOW_FLAGS_DEFAULT_MISS |
1809 MLX5_IB_ATTR_CREATE_FLOW_FLAGS_DROP);
1810 if (err)
1811 return err;
1812
1813 /* Both flags are not allowed */
1814 if (*flags & MLX5_IB_ATTR_CREATE_FLOW_FLAGS_DEFAULT_MISS &&
1815 *flags & MLX5_IB_ATTR_CREATE_FLOW_FLAGS_DROP)
1816 return -EINVAL;
1817
1818 if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_BYPASS) {
1819 if (dest_devx && (dest_qp || *flags))
1820 return -EINVAL;
1821 else if (dest_qp && *flags)
1822 return -EINVAL;
1823 }
1824
1825 /* Allow only DEVX object, drop as dest for FDB */
1826 if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_FDB && !(dest_devx ||
1827 (*flags & MLX5_IB_ATTR_CREATE_FLOW_FLAGS_DROP)))
1828 return -EINVAL;
1829
1830 /* Allow only DEVX object or QP as dest when inserting to RDMA_RX */
1831 if ((fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_RDMA_RX) &&
1832 ((!dest_devx && !dest_qp) || (dest_devx && dest_qp)))
1833 return -EINVAL;
1834
1835 *qp = NULL;
1836 if (dest_devx) {
1837 devx_obj =
1838 uverbs_attr_get_obj(attrs,
1839 MLX5_IB_ATTR_CREATE_FLOW_DEST_DEVX);
1840
1841 /* Verify that the given DEVX object is a flow
1842 * steering destination.
1843 */
1844 if (!is_flow_dest(devx_obj, dest_id, dest_type))
1845 return -EINVAL;
1846 /* Allow only flow table as dest when inserting to FDB or RDMA_RX */
1847 if ((fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_FDB ||
1848 fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_RDMA_RX) &&
1849 *dest_type != MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE)
1850 return -EINVAL;
1851 } else if (dest_qp) {
1852 struct mlx5_ib_qp *mqp;
1853
1854 *qp = uverbs_attr_get_obj(attrs,
1855 MLX5_IB_ATTR_CREATE_FLOW_DEST_QP);
1856 if (IS_ERR(*qp))
1857 return PTR_ERR(*qp);
1858
1859 if ((*qp)->qp_type != IB_QPT_RAW_PACKET)
1860 return -EINVAL;
1861
1862 mqp = to_mqp(*qp);
1863 if (mqp->is_rss)
1864 *dest_id = mqp->rss_qp.tirn;
1865 else
1866 *dest_id = mqp->raw_packet_qp.rq.tirn;
1867 *dest_type = MLX5_FLOW_DESTINATION_TYPE_TIR;
1868 } else if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_EGRESS ||
1869 fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_RDMA_TX) {
1870 *dest_type = MLX5_FLOW_DESTINATION_TYPE_PORT;
1871 }
1872
1873 if (*dest_type == MLX5_FLOW_DESTINATION_TYPE_TIR &&
1874 (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_EGRESS ||
1875 fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_RDMA_TX))
1876 return -EINVAL;
1877
1878 return 0;
1879}
1880
1881static bool is_flow_counter(void *obj, u32 offset, u32 *counter_id)
1882{
1883 struct devx_obj *devx_obj = obj;
1884 u16 opcode = MLX5_GET(general_obj_in_cmd_hdr, devx_obj->dinbox, opcode);
1885
1886 if (opcode == MLX5_CMD_OP_DEALLOC_FLOW_COUNTER) {
1887
1888 if (offset && offset >= devx_obj->flow_counter_bulk_size)
1889 return false;
1890
1891 *counter_id = MLX5_GET(dealloc_flow_counter_in,
1892 devx_obj->dinbox,
1893 flow_counter_id);
1894 *counter_id += offset;
1895 return true;
1896 }
1897
1898 return false;
1899}
1900
1901#define MLX5_IB_CREATE_FLOW_MAX_FLOW_ACTIONS 2
1902static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
1903 struct uverbs_attr_bundle *attrs)
1904{
1905 struct mlx5_flow_context flow_context = {.flow_tag =
1906 MLX5_FS_DEFAULT_FLOW_TAG};
1907 u32 *offset_attr, offset = 0, counter_id = 0;
1908 int dest_id, dest_type = -1, inlen, len, ret, i;
1909 struct mlx5_ib_flow_handler *flow_handler;
1910 struct mlx5_ib_flow_matcher *fs_matcher;
1911 struct ib_uobject **arr_flow_actions;
1912 struct ib_uflow_resources *uflow_res;
1913 struct mlx5_flow_act flow_act = {};
1914 struct ib_qp *qp = NULL;
1915 void *devx_obj, *cmd_in;
1916 struct ib_uobject *uobj;
1917 struct mlx5_ib_dev *dev;
1918 u32 flags;
1919
1920 if (!capable(CAP_NET_RAW))
1921 return -EPERM;
1922
1923 fs_matcher = uverbs_attr_get_obj(attrs,
1924 MLX5_IB_ATTR_CREATE_FLOW_MATCHER);
1925 uobj = uverbs_attr_get_uobject(attrs, MLX5_IB_ATTR_CREATE_FLOW_HANDLE);
1926 dev = mlx5_udata_to_mdev(&attrs->driver_udata);
1927
1928 if (get_dests(attrs, fs_matcher, &dest_id, &dest_type, &qp, &flags))
1929 return -EINVAL;
1930
1931 if (flags & MLX5_IB_ATTR_CREATE_FLOW_FLAGS_DEFAULT_MISS)
1932 flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_NS;
1933
1934 if (flags & MLX5_IB_ATTR_CREATE_FLOW_FLAGS_DROP)
1935 flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_DROP;
1936
1937 len = uverbs_attr_get_uobjs_arr(attrs,
1938 MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX, &arr_flow_actions);
1939 if (len) {
1940 devx_obj = arr_flow_actions[0]->object;
1941
1942 if (uverbs_attr_is_valid(attrs,
1943 MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET)) {
1944
1945 int num_offsets = uverbs_attr_ptr_get_array_size(
1946 attrs,
1947 MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET,
1948 sizeof(u32));
1949
1950 if (num_offsets != 1)
1951 return -EINVAL;
1952
1953 offset_attr = uverbs_attr_get_alloced_ptr(
1954 attrs,
1955 MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET);
1956 offset = *offset_attr;
1957 }
1958
1959 if (!is_flow_counter(devx_obj, offset, &counter_id))
1960 return -EINVAL;
1961
1962 flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_COUNT;
1963 }
1964
1965 cmd_in = uverbs_attr_get_alloced_ptr(
1966 attrs, MLX5_IB_ATTR_CREATE_FLOW_MATCH_VALUE);
1967 inlen = uverbs_attr_get_len(attrs,
1968 MLX5_IB_ATTR_CREATE_FLOW_MATCH_VALUE);
1969
1970 uflow_res = flow_resources_alloc(MLX5_IB_CREATE_FLOW_MAX_FLOW_ACTIONS);
1971 if (!uflow_res)
1972 return -ENOMEM;
1973
1974 len = uverbs_attr_get_uobjs_arr(attrs,
1975 MLX5_IB_ATTR_CREATE_FLOW_ARR_FLOW_ACTIONS, &arr_flow_actions);
1976 for (i = 0; i < len; i++) {
1977 struct mlx5_ib_flow_action *maction =
1978 to_mflow_act(arr_flow_actions[i]->object);
1979
1980 ret = parse_flow_flow_action(maction, false, &flow_act);
1981 if (ret)
1982 goto err_out;
1983 flow_resources_add(uflow_res, IB_FLOW_SPEC_ACTION_HANDLE,
1984 arr_flow_actions[i]->object);
1985 }
1986
1987 ret = uverbs_copy_from(&flow_context.flow_tag, attrs,
1988 MLX5_IB_ATTR_CREATE_FLOW_TAG);
1989 if (!ret) {
1990 if (flow_context.flow_tag >= BIT(24)) {
1991 ret = -EINVAL;
1992 goto err_out;
1993 }
1994 flow_context.flags |= FLOW_CONTEXT_HAS_TAG;
1995 }
1996
1997 flow_handler =
1998 raw_fs_rule_add(dev, fs_matcher, &flow_context, &flow_act,
1999 counter_id, cmd_in, inlen, dest_id, dest_type);
2000 if (IS_ERR(flow_handler)) {
2001 ret = PTR_ERR(flow_handler);
2002 goto err_out;
2003 }
2004
2005 ib_set_flow(uobj, &flow_handler->ibflow, qp, &dev->ib_dev, uflow_res);
2006
2007 return 0;
2008err_out:
2009 ib_uverbs_flow_resources_free(uflow_res);
2010 return ret;
2011}
2012
2013static int flow_matcher_cleanup(struct ib_uobject *uobject,
2014 enum rdma_remove_reason why,
2015 struct uverbs_attr_bundle *attrs)
2016{
2017 struct mlx5_ib_flow_matcher *obj = uobject->object;
2018 int ret;
2019
2020 ret = ib_destroy_usecnt(&obj->usecnt, why, uobject);
2021 if (ret)
2022 return ret;
2023
2024 kfree(obj);
2025 return 0;
2026}
2027
2028static int mlx5_ib_matcher_ns(struct uverbs_attr_bundle *attrs,
2029 struct mlx5_ib_flow_matcher *obj)
2030{
2031 enum mlx5_ib_uapi_flow_table_type ft_type =
2032 MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_RX;
2033 u32 flags;
2034 int err;
2035
2036 /* New users should use MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE and older
2037 * users should switch to it. We leave this to not break userspace
2038 */
2039 if (uverbs_attr_is_valid(attrs, MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE) &&
2040 uverbs_attr_is_valid(attrs, MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS))
2041 return -EINVAL;
2042
2043 if (uverbs_attr_is_valid(attrs, MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE)) {
2044 err = uverbs_get_const(&ft_type, attrs,
2045 MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE);
2046 if (err)
2047 return err;
2048
2049 err = mlx5_ib_ft_type_to_namespace(ft_type, &obj->ns_type);
2050 if (err)
2051 return err;
2052
2053 return 0;
2054 }
2055
2056 if (uverbs_attr_is_valid(attrs, MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS)) {
2057 err = uverbs_get_flags32(&flags, attrs,
2058 MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS,
2059 IB_FLOW_ATTR_FLAGS_EGRESS);
2060 if (err)
2061 return err;
2062
2063 if (flags) {
2064 mlx5_ib_ft_type_to_namespace(
2065 MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX,
2066 &obj->ns_type);
2067 return 0;
2068 }
2069 }
2070
2071 obj->ns_type = MLX5_FLOW_NAMESPACE_BYPASS;
2072
2073 return 0;
2074}
2075
2076static int UVERBS_HANDLER(MLX5_IB_METHOD_FLOW_MATCHER_CREATE)(
2077 struct uverbs_attr_bundle *attrs)
2078{
2079 struct ib_uobject *uobj = uverbs_attr_get_uobject(
2080 attrs, MLX5_IB_ATTR_FLOW_MATCHER_CREATE_HANDLE);
2081 struct mlx5_ib_dev *dev = mlx5_udata_to_mdev(&attrs->driver_udata);
2082 struct mlx5_ib_flow_matcher *obj;
2083 int err;
2084
2085 obj = kzalloc(sizeof(struct mlx5_ib_flow_matcher), GFP_KERNEL);
2086 if (!obj)
2087 return -ENOMEM;
2088
2089 obj->mask_len = uverbs_attr_get_len(
2090 attrs, MLX5_IB_ATTR_FLOW_MATCHER_MATCH_MASK);
2091 err = uverbs_copy_from(&obj->matcher_mask,
2092 attrs,
2093 MLX5_IB_ATTR_FLOW_MATCHER_MATCH_MASK);
2094 if (err)
2095 goto end;
2096
2097 obj->flow_type = uverbs_attr_get_enum_id(
2098 attrs, MLX5_IB_ATTR_FLOW_MATCHER_FLOW_TYPE);
2099
2100 if (obj->flow_type == MLX5_IB_FLOW_TYPE_NORMAL) {
2101 err = uverbs_copy_from(&obj->priority,
2102 attrs,
2103 MLX5_IB_ATTR_FLOW_MATCHER_FLOW_TYPE);
2104 if (err)
2105 goto end;
2106 }
2107
2108 err = uverbs_copy_from(&obj->match_criteria_enable,
2109 attrs,
2110 MLX5_IB_ATTR_FLOW_MATCHER_MATCH_CRITERIA);
2111 if (err)
2112 goto end;
2113
2114 err = mlx5_ib_matcher_ns(attrs, obj);
2115 if (err)
2116 goto end;
2117
2118 uobj->object = obj;
2119 obj->mdev = dev->mdev;
2120 atomic_set(&obj->usecnt, 0);
2121 return 0;
2122
2123end:
2124 kfree(obj);
2125 return err;
2126}
2127
2128static struct ib_flow_action *
2129mlx5_ib_create_modify_header(struct mlx5_ib_dev *dev,
2130 enum mlx5_ib_uapi_flow_table_type ft_type,
2131 u8 num_actions, void *in)
2132{
2133 enum mlx5_flow_namespace_type namespace;
2134 struct mlx5_ib_flow_action *maction;
2135 int ret;
2136
2137 ret = mlx5_ib_ft_type_to_namespace(ft_type, &namespace);
2138 if (ret)
2139 return ERR_PTR(-EINVAL);
2140
2141 maction = kzalloc(sizeof(*maction), GFP_KERNEL);
2142 if (!maction)
2143 return ERR_PTR(-ENOMEM);
2144
2145 maction->flow_action_raw.modify_hdr =
2146 mlx5_modify_header_alloc(dev->mdev, namespace, num_actions, in);
2147
2148 if (IS_ERR(maction->flow_action_raw.modify_hdr)) {
2149 ret = PTR_ERR(maction->flow_action_raw.modify_hdr);
2150 kfree(maction);
2151 return ERR_PTR(ret);
2152 }
2153 maction->flow_action_raw.sub_type =
2154 MLX5_IB_FLOW_ACTION_MODIFY_HEADER;
2155 maction->flow_action_raw.dev = dev;
2156
2157 return &maction->ib_action;
2158}
2159
2160static bool mlx5_ib_modify_header_supported(struct mlx5_ib_dev *dev)
2161{
2162 return MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev,
2163 max_modify_header_actions) ||
2164 MLX5_CAP_FLOWTABLE_NIC_TX(dev->mdev,
2165 max_modify_header_actions) ||
2166 MLX5_CAP_FLOWTABLE_RDMA_TX(dev->mdev,
2167 max_modify_header_actions);
2168}
2169
2170static int UVERBS_HANDLER(MLX5_IB_METHOD_FLOW_ACTION_CREATE_MODIFY_HEADER)(
2171 struct uverbs_attr_bundle *attrs)
2172{
2173 struct ib_uobject *uobj = uverbs_attr_get_uobject(
2174 attrs, MLX5_IB_ATTR_CREATE_MODIFY_HEADER_HANDLE);
2175 struct mlx5_ib_dev *mdev = mlx5_udata_to_mdev(&attrs->driver_udata);
2176 enum mlx5_ib_uapi_flow_table_type ft_type;
2177 struct ib_flow_action *action;
2178 int num_actions;
2179 void *in;
2180 int ret;
2181
2182 if (!mlx5_ib_modify_header_supported(mdev))
2183 return -EOPNOTSUPP;
2184
2185 in = uverbs_attr_get_alloced_ptr(attrs,
2186 MLX5_IB_ATTR_CREATE_MODIFY_HEADER_ACTIONS_PRM);
2187
2188 num_actions = uverbs_attr_ptr_get_array_size(
2189 attrs, MLX5_IB_ATTR_CREATE_MODIFY_HEADER_ACTIONS_PRM,
2190 MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto));
2191 if (num_actions < 0)
2192 return num_actions;
2193
2194 ret = uverbs_get_const(&ft_type, attrs,
2195 MLX5_IB_ATTR_CREATE_MODIFY_HEADER_FT_TYPE);
2196 if (ret)
2197 return ret;
2198 action = mlx5_ib_create_modify_header(mdev, ft_type, num_actions, in);
2199 if (IS_ERR(action))
2200 return PTR_ERR(action);
2201
2202 uverbs_flow_action_fill_action(action, uobj, &mdev->ib_dev,
2203 IB_FLOW_ACTION_UNSPECIFIED);
2204
2205 return 0;
2206}
2207
2208static bool mlx5_ib_flow_action_packet_reformat_valid(struct mlx5_ib_dev *ibdev,
2209 u8 packet_reformat_type,
2210 u8 ft_type)
2211{
2212 switch (packet_reformat_type) {
2213 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L2_TUNNEL:
2214 if (ft_type == MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX)
2215 return MLX5_CAP_FLOWTABLE(ibdev->mdev,
2216 encap_general_header);
2217 break;
2218 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L3_TUNNEL:
2219 if (ft_type == MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX)
2220 return MLX5_CAP_FLOWTABLE_NIC_TX(ibdev->mdev,
2221 reformat_l2_to_l3_tunnel);
2222 break;
2223 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L3_TUNNEL_TO_L2:
2224 if (ft_type == MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_RX)
2225 return MLX5_CAP_FLOWTABLE_NIC_RX(ibdev->mdev,
2226 reformat_l3_tunnel_to_l2);
2227 break;
2228 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TUNNEL_TO_L2:
2229 if (ft_type == MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_RX)
2230 return MLX5_CAP_FLOWTABLE_NIC_RX(ibdev->mdev, decap);
2231 break;
2232 default:
2233 break;
2234 }
2235
2236 return false;
2237}
2238
2239static int mlx5_ib_dv_to_prm_packet_reforamt_type(u8 dv_prt, u8 *prm_prt)
2240{
2241 switch (dv_prt) {
2242 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L2_TUNNEL:
2243 *prm_prt = MLX5_REFORMAT_TYPE_L2_TO_L2_TUNNEL;
2244 break;
2245 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L3_TUNNEL_TO_L2:
2246 *prm_prt = MLX5_REFORMAT_TYPE_L3_TUNNEL_TO_L2;
2247 break;
2248 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L3_TUNNEL:
2249 *prm_prt = MLX5_REFORMAT_TYPE_L2_TO_L3_TUNNEL;
2250 break;
2251 default:
2252 return -EINVAL;
2253 }
2254
2255 return 0;
2256}
2257
2258static int mlx5_ib_flow_action_create_packet_reformat_ctx(
2259 struct mlx5_ib_dev *dev,
2260 struct mlx5_ib_flow_action *maction,
2261 u8 ft_type, u8 dv_prt,
2262 void *in, size_t len)
2263{
2264 enum mlx5_flow_namespace_type namespace;
2265 u8 prm_prt;
2266 int ret;
2267
2268 ret = mlx5_ib_ft_type_to_namespace(ft_type, &namespace);
2269 if (ret)
2270 return ret;
2271
2272 ret = mlx5_ib_dv_to_prm_packet_reforamt_type(dv_prt, &prm_prt);
2273 if (ret)
2274 return ret;
2275
2276 maction->flow_action_raw.pkt_reformat =
2277 mlx5_packet_reformat_alloc(dev->mdev, prm_prt, len,
2278 in, namespace);
2279 if (IS_ERR(maction->flow_action_raw.pkt_reformat)) {
2280 ret = PTR_ERR(maction->flow_action_raw.pkt_reformat);
2281 return ret;
2282 }
2283
2284 maction->flow_action_raw.sub_type =
2285 MLX5_IB_FLOW_ACTION_PACKET_REFORMAT;
2286 maction->flow_action_raw.dev = dev;
2287
2288 return 0;
2289}
2290
2291static int UVERBS_HANDLER(MLX5_IB_METHOD_FLOW_ACTION_CREATE_PACKET_REFORMAT)(
2292 struct uverbs_attr_bundle *attrs)
2293{
2294 struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs,
2295 MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_HANDLE);
2296 struct mlx5_ib_dev *mdev = mlx5_udata_to_mdev(&attrs->driver_udata);
2297 enum mlx5_ib_uapi_flow_action_packet_reformat_type dv_prt;
2298 enum mlx5_ib_uapi_flow_table_type ft_type;
2299 struct mlx5_ib_flow_action *maction;
2300 int ret;
2301
2302 ret = uverbs_get_const(&ft_type, attrs,
2303 MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_FT_TYPE);
2304 if (ret)
2305 return ret;
2306
2307 ret = uverbs_get_const(&dv_prt, attrs,
2308 MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_TYPE);
2309 if (ret)
2310 return ret;
2311
2312 if (!mlx5_ib_flow_action_packet_reformat_valid(mdev, dv_prt, ft_type))
2313 return -EOPNOTSUPP;
2314
2315 maction = kzalloc(sizeof(*maction), GFP_KERNEL);
2316 if (!maction)
2317 return -ENOMEM;
2318
2319 if (dv_prt ==
2320 MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TUNNEL_TO_L2) {
2321 maction->flow_action_raw.sub_type =
2322 MLX5_IB_FLOW_ACTION_DECAP;
2323 maction->flow_action_raw.dev = mdev;
2324 } else {
2325 void *in;
2326 int len;
2327
2328 in = uverbs_attr_get_alloced_ptr(attrs,
2329 MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_DATA_BUF);
2330 if (IS_ERR(in)) {
2331 ret = PTR_ERR(in);
2332 goto free_maction;
2333 }
2334
2335 len = uverbs_attr_get_len(attrs,
2336 MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_DATA_BUF);
2337
2338 ret = mlx5_ib_flow_action_create_packet_reformat_ctx(mdev,
2339 maction, ft_type, dv_prt, in, len);
2340 if (ret)
2341 goto free_maction;
2342 }
2343
2344 uverbs_flow_action_fill_action(&maction->ib_action, uobj, &mdev->ib_dev,
2345 IB_FLOW_ACTION_UNSPECIFIED);
2346 return 0;
2347
2348free_maction:
2349 kfree(maction);
2350 return ret;
2351}
2352
2353DECLARE_UVERBS_NAMED_METHOD(
2354 MLX5_IB_METHOD_CREATE_FLOW,
2355 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_FLOW_HANDLE,
2356 UVERBS_OBJECT_FLOW,
2357 UVERBS_ACCESS_NEW,
2358 UA_MANDATORY),
2359 UVERBS_ATTR_PTR_IN(
2360 MLX5_IB_ATTR_CREATE_FLOW_MATCH_VALUE,
2361 UVERBS_ATTR_SIZE(1, sizeof(struct mlx5_ib_match_params)),
2362 UA_MANDATORY,
2363 UA_ALLOC_AND_COPY),
2364 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_FLOW_MATCHER,
2365 MLX5_IB_OBJECT_FLOW_MATCHER,
2366 UVERBS_ACCESS_READ,
2367 UA_MANDATORY),
2368 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_FLOW_DEST_QP,
2369 UVERBS_OBJECT_QP,
2370 UVERBS_ACCESS_READ),
2371 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_FLOW_DEST_DEVX,
2372 MLX5_IB_OBJECT_DEVX_OBJ,
2373 UVERBS_ACCESS_READ),
2374 UVERBS_ATTR_IDRS_ARR(MLX5_IB_ATTR_CREATE_FLOW_ARR_FLOW_ACTIONS,
2375 UVERBS_OBJECT_FLOW_ACTION,
2376 UVERBS_ACCESS_READ, 1,
2377 MLX5_IB_CREATE_FLOW_MAX_FLOW_ACTIONS,
2378 UA_OPTIONAL),
2379 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_CREATE_FLOW_TAG,
2380 UVERBS_ATTR_TYPE(u32),
2381 UA_OPTIONAL),
2382 UVERBS_ATTR_IDRS_ARR(MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX,
2383 MLX5_IB_OBJECT_DEVX_OBJ,
2384 UVERBS_ACCESS_READ, 1, 1,
2385 UA_OPTIONAL),
2386 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET,
2387 UVERBS_ATTR_MIN_SIZE(sizeof(u32)),
2388 UA_OPTIONAL,
2389 UA_ALLOC_AND_COPY),
2390 UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_CREATE_FLOW_FLAGS,
2391 enum mlx5_ib_create_flow_flags,
2392 UA_OPTIONAL));
2393
2394DECLARE_UVERBS_NAMED_METHOD_DESTROY(
2395 MLX5_IB_METHOD_DESTROY_FLOW,
2396 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_FLOW_HANDLE,
2397 UVERBS_OBJECT_FLOW,
2398 UVERBS_ACCESS_DESTROY,
2399 UA_MANDATORY));
2400
2401ADD_UVERBS_METHODS(mlx5_ib_fs,
2402 UVERBS_OBJECT_FLOW,
2403 &UVERBS_METHOD(MLX5_IB_METHOD_CREATE_FLOW),
2404 &UVERBS_METHOD(MLX5_IB_METHOD_DESTROY_FLOW));
2405
2406DECLARE_UVERBS_NAMED_METHOD(
2407 MLX5_IB_METHOD_FLOW_ACTION_CREATE_MODIFY_HEADER,
2408 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_MODIFY_HEADER_HANDLE,
2409 UVERBS_OBJECT_FLOW_ACTION,
2410 UVERBS_ACCESS_NEW,
2411 UA_MANDATORY),
2412 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_CREATE_MODIFY_HEADER_ACTIONS_PRM,
2413 UVERBS_ATTR_MIN_SIZE(MLX5_UN_SZ_BYTES(
2414 set_add_copy_action_in_auto)),
2415 UA_MANDATORY,
2416 UA_ALLOC_AND_COPY),
2417 UVERBS_ATTR_CONST_IN(MLX5_IB_ATTR_CREATE_MODIFY_HEADER_FT_TYPE,
2418 enum mlx5_ib_uapi_flow_table_type,
2419 UA_MANDATORY));
2420
2421DECLARE_UVERBS_NAMED_METHOD(
2422 MLX5_IB_METHOD_FLOW_ACTION_CREATE_PACKET_REFORMAT,
2423 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_HANDLE,
2424 UVERBS_OBJECT_FLOW_ACTION,
2425 UVERBS_ACCESS_NEW,
2426 UA_MANDATORY),
2427 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_DATA_BUF,
2428 UVERBS_ATTR_MIN_SIZE(1),
2429 UA_ALLOC_AND_COPY,
2430 UA_OPTIONAL),
2431 UVERBS_ATTR_CONST_IN(MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_TYPE,
2432 enum mlx5_ib_uapi_flow_action_packet_reformat_type,
2433 UA_MANDATORY),
2434 UVERBS_ATTR_CONST_IN(MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_FT_TYPE,
2435 enum mlx5_ib_uapi_flow_table_type,
2436 UA_MANDATORY));
2437
2438ADD_UVERBS_METHODS(
2439 mlx5_ib_flow_actions,
2440 UVERBS_OBJECT_FLOW_ACTION,
2441 &UVERBS_METHOD(MLX5_IB_METHOD_FLOW_ACTION_CREATE_MODIFY_HEADER),
2442 &UVERBS_METHOD(MLX5_IB_METHOD_FLOW_ACTION_CREATE_PACKET_REFORMAT));
2443
2444DECLARE_UVERBS_NAMED_METHOD(
2445 MLX5_IB_METHOD_FLOW_MATCHER_CREATE,
2446 UVERBS_ATTR_IDR(MLX5_IB_ATTR_FLOW_MATCHER_CREATE_HANDLE,
2447 MLX5_IB_OBJECT_FLOW_MATCHER,
2448 UVERBS_ACCESS_NEW,
2449 UA_MANDATORY),
2450 UVERBS_ATTR_PTR_IN(
2451 MLX5_IB_ATTR_FLOW_MATCHER_MATCH_MASK,
2452 UVERBS_ATTR_SIZE(1, sizeof(struct mlx5_ib_match_params)),
2453 UA_MANDATORY),
2454 UVERBS_ATTR_ENUM_IN(MLX5_IB_ATTR_FLOW_MATCHER_FLOW_TYPE,
2455 mlx5_ib_flow_type,
2456 UA_MANDATORY),
2457 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_FLOW_MATCHER_MATCH_CRITERIA,
2458 UVERBS_ATTR_TYPE(u8),
2459 UA_MANDATORY),
2460 UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS,
2461 enum ib_flow_flags,
2462 UA_OPTIONAL),
2463 UVERBS_ATTR_CONST_IN(MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE,
2464 enum mlx5_ib_uapi_flow_table_type,
2465 UA_OPTIONAL));
2466
2467DECLARE_UVERBS_NAMED_METHOD_DESTROY(
2468 MLX5_IB_METHOD_FLOW_MATCHER_DESTROY,
2469 UVERBS_ATTR_IDR(MLX5_IB_ATTR_FLOW_MATCHER_DESTROY_HANDLE,
2470 MLX5_IB_OBJECT_FLOW_MATCHER,
2471 UVERBS_ACCESS_DESTROY,
2472 UA_MANDATORY));
2473
2474DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_FLOW_MATCHER,
2475 UVERBS_TYPE_ALLOC_IDR(flow_matcher_cleanup),
2476 &UVERBS_METHOD(MLX5_IB_METHOD_FLOW_MATCHER_CREATE),
2477 &UVERBS_METHOD(MLX5_IB_METHOD_FLOW_MATCHER_DESTROY));
2478
2479const struct uapi_definition mlx5_ib_flow_defs[] = {
2480 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(
2481 MLX5_IB_OBJECT_FLOW_MATCHER),
2482 UAPI_DEF_CHAIN_OBJ_TREE(
2483 UVERBS_OBJECT_FLOW,
2484 &mlx5_ib_fs),
2485 UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_FLOW_ACTION,
2486 &mlx5_ib_flow_actions),
2487 {},
2488};
2489
2490static const struct ib_device_ops flow_ops = {
2491 .create_flow = mlx5_ib_create_flow,
2492 .destroy_flow = mlx5_ib_destroy_flow,
2493 .destroy_flow_action = mlx5_ib_destroy_flow_action,
2494};
2495
2496static const struct ib_device_ops flow_ipsec_ops = {
2497 .create_flow_action_esp = mlx5_ib_create_flow_action_esp,
2498 .modify_flow_action_esp = mlx5_ib_modify_flow_action_esp,
2499};
2500
2501int mlx5_ib_fs_init(struct mlx5_ib_dev *dev)
2502{
2503 dev->flow_db = kzalloc(sizeof(*dev->flow_db), GFP_KERNEL);
2504
2505 if (!dev->flow_db)
2506 return -ENOMEM;
2507
2508 mutex_init(&dev->flow_db->lock);
2509
2510 ib_set_device_ops(&dev->ib_dev, &flow_ops);
2511 if (mlx5_accel_ipsec_device_caps(dev->mdev) &
2512 MLX5_ACCEL_IPSEC_CAP_DEVICE)
2513 ib_set_device_ops(&dev->ib_dev, &flow_ipsec_ops);
2514
2515 return 0;
2516}
drivers/infiniband/hw/mlx5/fs.h+29−0
@@ -0,0 +1,29 @@
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
2/*
3 * Copyright (c) 2013-2020, Mellanox Technologies inc. All rights reserved.
4 */
5
6#ifndef _MLX5_IB_FS_H
7#define _MLX5_IB_FS_H
8
9#include "mlx5_ib.h"
10
11#if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
12int mlx5_ib_fs_init(struct mlx5_ib_dev *dev);
13#else
14static inline int mlx5_ib_fs_init(struct mlx5_ib_dev *dev)
15{
16 dev->flow_db = kzalloc(sizeof(*dev->flow_db), GFP_KERNEL);
17
18 if (!dev->flow_db)
19 return -ENOMEM;
20
21 mutex_init(&dev->flow_db->lock);
22 return 0;
23}
24#endif
25static inline void mlx5_ib_fs_cleanup(struct mlx5_ib_dev *dev)
26{
27 kfree(dev->flow_db);
28}
29#endif /* _MLX5_IB_FS_H */
drivers/infiniband/hw/mlx5/main.c+937−3443
@@ -1,33 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
1/*2/*
2 * Copyright (c) 2013-2015, Mellanox Technologies. All rights reserved.3 * Copyright (c) 2013-2020, Mellanox Technologies inc. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */4 */
32 5
33#include <linux/debugfs.h>6#include <linux/debugfs.h>
@@ -59,10 +32,13 @@ · 25 unmodified lines
59#include "mlx5_ib.h"32#include "mlx5_ib.h"
60#include "ib_rep.h"33#include "ib_rep.h"
61#include "cmd.h"34#include "cmd.h"
35#include "devx.h"
36#include "fs.h"
62#include "srq.h"37#include "srq.h"
63#include "qp.h"38#include "qp.h"
64#include "wr.h"39#include "wr.h"
65#include <linux/mlx5/fs_helpers.h>40#include "restrack.h"
41#include "counters.h"
66#include <linux/mlx5/accel.h>42#include <linux/mlx5/accel.h>
67#include <rdma/uverbs_std_types.h>43#include <rdma/uverbs_std_types.h>
68#include <rdma/mlx5_user_ioctl_verbs.h>44#include <rdma/mlx5_user_ioctl_verbs.h>
@@ -311,9 +287,6 @@ struct mlx5_core_dev *mlx5_ib_get_native_port_mdev(struct mlx5_ib_dev *ibdev, · 242 unmodified lines
311 *native_port_num = 1;287 *native_port_num = 1;
312 288
313 port = &ibdev->port[ib_port_num - 1];289 port = &ibdev->port[ib_port_num - 1];
314 if (!port)
315 return NULL;
316
317 spin_lock(&port->mp.mpi_lock);290 spin_lock(&port->mp.mpi_lock);
318 mpi = ibdev->port[ib_port_num - 1].mp.mpi;291 mpi = ibdev->port[ib_port_num - 1].mp.mpi;
319 if (mpi && !mpi->unaffiliate) {292 if (mpi && !mpi->unaffiliate) {
@@ -1765,6 +1738,92 @@ static void mlx5_ib_dealloc_transport_domain(struct mlx5_ib_dev *dev, u32 tdn, · 1445 unmodified lines
1765 mlx5_ib_disable_lb(dev, true, false);1738 mlx5_ib_disable_lb(dev, true, false);
1766}1739}
1767 1740
1741static int set_ucontext_resp(struct ib_ucontext *uctx,
1742 struct mlx5_ib_alloc_ucontext_resp *resp)
1743{
1744 struct ib_device *ibdev = uctx->device;
1745 struct mlx5_ib_dev *dev = to_mdev(ibdev);
1746 struct mlx5_ib_ucontext *context = to_mucontext(uctx);
1747 struct mlx5_bfreg_info *bfregi = &context->bfregi;
1748 int err;
1749
1750 if (MLX5_CAP_GEN(dev->mdev, dump_fill_mkey)) {
1751 err = mlx5_cmd_dump_fill_mkey(dev->mdev,
1752 &resp->dump_fill_mkey);
1753 if (err)
1754 return err;
1755 resp->comp_mask |=
1756 MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_DUMP_FILL_MKEY;
1757 }
1758
1759 resp->qp_tab_size = 1 << MLX5_CAP_GEN(dev->mdev, log_max_qp);
1760 if (dev->wc_support)
1761 resp->bf_reg_size = 1 << MLX5_CAP_GEN(dev->mdev,
1762 log_bf_reg_size);
1763 resp->cache_line_size = cache_line_size();
1764 resp->max_sq_desc_sz = MLX5_CAP_GEN(dev->mdev, max_wqe_sz_sq);
1765 resp->max_rq_desc_sz = MLX5_CAP_GEN(dev->mdev, max_wqe_sz_rq);
1766 resp->max_send_wqebb = 1 << MLX5_CAP_GEN(dev->mdev, log_max_qp_sz);
1767 resp->max_recv_wr = 1 << MLX5_CAP_GEN(dev->mdev, log_max_qp_sz);
1768 resp->max_srq_recv_wr = 1 << MLX5_CAP_GEN(dev->mdev, log_max_srq_sz);
1769 resp->cqe_version = context->cqe_version;
1770 resp->log_uar_size = MLX5_CAP_GEN(dev->mdev, uar_4k) ?
1771 MLX5_ADAPTER_PAGE_SHIFT : PAGE_SHIFT;
1772 resp->num_uars_per_page = MLX5_CAP_GEN(dev->mdev, uar_4k) ?
1773 MLX5_CAP_GEN(dev->mdev,
1774 num_of_uars_per_page) : 1;
1775
1776 if (mlx5_accel_ipsec_device_caps(dev->mdev) &
1777 MLX5_ACCEL_IPSEC_CAP_DEVICE) {
1778 if (mlx5_get_flow_namespace(dev->mdev,
1779 MLX5_FLOW_NAMESPACE_EGRESS))
1780 resp->flow_action_flags |= MLX5_USER_ALLOC_UCONTEXT_FLOW_ACTION_FLAGS_ESP_AES_GCM;
1781 if (mlx5_accel_ipsec_device_caps(dev->mdev) &
1782 MLX5_ACCEL_IPSEC_CAP_REQUIRED_METADATA)
1783 resp->flow_action_flags |= MLX5_USER_ALLOC_UCONTEXT_FLOW_ACTION_FLAGS_ESP_AES_GCM_REQ_METADATA;
1784 if (MLX5_CAP_FLOWTABLE(dev->mdev, flow_table_properties_nic_receive.ft_field_support.outer_esp_spi))
1785 resp->flow_action_flags |= MLX5_USER_ALLOC_UCONTEXT_FLOW_ACTION_FLAGS_ESP_AES_GCM_SPI_STEERING;
1786 if (mlx5_accel_ipsec_device_caps(dev->mdev) &
1787 MLX5_ACCEL_IPSEC_CAP_TX_IV_IS_ESN)
1788 resp->flow_action_flags |= MLX5_USER_ALLOC_UCONTEXT_FLOW_ACTION_FLAGS_ESP_AES_GCM_TX_IV_IS_ESN;
1789 /* MLX5_USER_ALLOC_UCONTEXT_FLOW_ACTION_FLAGS_ESP_AES_GCM_FULL_OFFLOAD is currently always 0 */
1790 }
1791
1792 resp->tot_bfregs = bfregi->lib_uar_dyn ? 0 :
1793 bfregi->total_num_bfregs - bfregi->num_dyn_bfregs;
1794 resp->num_ports = dev->num_ports;
1795 resp->cmds_supp_uhw |= MLX5_USER_CMDS_SUPP_UHW_QUERY_DEVICE |
1796 MLX5_USER_CMDS_SUPP_UHW_CREATE_AH;
1797
1798 if (mlx5_ib_port_link_layer(ibdev, 1) == IB_LINK_LAYER_ETHERNET) {
1799 mlx5_query_min_inline(dev->mdev, &resp->eth_min_inline);
1800 resp->eth_min_inline++;
1801 }
1802
1803 if (dev->mdev->clock_info)
1804 resp->clock_info_versions = BIT(MLX5_IB_CLOCK_INFO_V1);
1805
1806 /*
1807 * We don't want to expose information from the PCI bar that is located
1808 * after 4096 bytes, so if the arch only supports larger pages, let's
1809 * pretend we don't support reading the HCA's core clock. This is also
1810 * forced by mmap function.
1811 */
1812 if (PAGE_SIZE <= 4096) {
1813 resp->comp_mask |=
1814 MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_CORE_CLOCK_OFFSET;
1815 resp->hca_core_clock_offset =
1816 offsetof(struct mlx5_init_seg,
1817 internal_timer_h) % PAGE_SIZE;
1818 }
1819
1820 if (MLX5_CAP_GEN(dev->mdev, ece_support))
1821 resp->comp_mask |= MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_ECE;
1822
1823 resp->num_dyn_bfregs = bfregi->num_dyn_bfregs;
1824 return 0;
1825}
1826
1768static int mlx5_ib_alloc_ucontext(struct ib_ucontext *uctx,1827static int mlx5_ib_alloc_ucontext(struct ib_ucontext *uctx,
1769 struct ib_udata *udata)1828 struct ib_udata *udata)
1770{1829{
@@ -1772,14 +1831,12 @@ static int mlx5_ib_alloc_ucontext(struct ib_ucontext *uctx, · 1 unmodified line
1772 struct mlx5_ib_dev *dev = to_mdev(ibdev);1831 struct mlx5_ib_dev *dev = to_mdev(ibdev);
1773 struct mlx5_ib_alloc_ucontext_req_v2 req = {};1832 struct mlx5_ib_alloc_ucontext_req_v2 req = {};
1774 struct mlx5_ib_alloc_ucontext_resp resp = {};1833 struct mlx5_ib_alloc_ucontext_resp resp = {};
1775 struct mlx5_core_dev *mdev = dev->mdev;
1776 struct mlx5_ib_ucontext *context = to_mucontext(uctx);1834 struct mlx5_ib_ucontext *context = to_mucontext(uctx);
1777 struct mlx5_bfreg_info *bfregi;1835 struct mlx5_bfreg_info *bfregi;
1778 int ver;1836 int ver;
1779 int err;1837 int err;
1780 size_t min_req_v2 = offsetof(struct mlx5_ib_alloc_ucontext_req_v2,1838 size_t min_req_v2 = offsetof(struct mlx5_ib_alloc_ucontext_req_v2,
1781 max_cqe_version);1839 max_cqe_version);
1782 u32 dump_fill_mkey;
1783 bool lib_uar_4k;1840 bool lib_uar_4k;
1784 bool lib_uar_dyn;1841 bool lib_uar_dyn;
1785 1842
@@ -1808,37 +1865,6 @@ static int mlx5_ib_alloc_ucontext(struct ib_ucontext *uctx, · 22 unmodified lines
1808 if (req.num_low_latency_bfregs > req.total_num_bfregs - 1)1865 if (req.num_low_latency_bfregs > req.total_num_bfregs - 1)
1809 return -EINVAL;1866 return -EINVAL;
1810 1867
1811 resp.qp_tab_size = 1 << MLX5_CAP_GEN(dev->mdev, log_max_qp);
1812 if (dev->wc_support)
1813 resp.bf_reg_size = 1 << MLX5_CAP_GEN(dev->mdev, log_bf_reg_size);
1814 resp.cache_line_size = cache_line_size();
1815 resp.max_sq_desc_sz = MLX5_CAP_GEN(dev->mdev, max_wqe_sz_sq);
1816 resp.max_rq_desc_sz = MLX5_CAP_GEN(dev->mdev, max_wqe_sz_rq);
1817 resp.max_send_wqebb = 1 << MLX5_CAP_GEN(dev->mdev, log_max_qp_sz);
1818 resp.max_recv_wr = 1 << MLX5_CAP_GEN(dev->mdev, log_max_qp_sz);
1819 resp.max_srq_recv_wr = 1 << MLX5_CAP_GEN(dev->mdev, log_max_srq_sz);
1820 resp.cqe_version = min_t(__u8,
1821 (__u8)MLX5_CAP_GEN(dev->mdev, cqe_version),
1822 req.max_cqe_version);
1823 resp.log_uar_size = MLX5_CAP_GEN(dev->mdev, uar_4k) ?
1824 MLX5_ADAPTER_PAGE_SHIFT : PAGE_SHIFT;
1825 resp.num_uars_per_page = MLX5_CAP_GEN(dev->mdev, uar_4k) ?
1826 MLX5_CAP_GEN(dev->mdev, num_of_uars_per_page) : 1;
1827 resp.response_length = min(offsetof(typeof(resp), response_length) +
1828 sizeof(resp.response_length), udata->outlen);
1829
1830 if (mlx5_accel_ipsec_device_caps(dev->mdev) & MLX5_ACCEL_IPSEC_CAP_DEVICE) {
1831 if (mlx5_get_flow_namespace(dev->mdev, MLX5_FLOW_NAMESPACE_EGRESS))
1832 resp.flow_action_flags |= MLX5_USER_ALLOC_UCONTEXT_FLOW_ACTION_FLAGS_ESP_AES_GCM;
1833 if (mlx5_accel_ipsec_device_caps(dev->mdev) & MLX5_ACCEL_IPSEC_CAP_REQUIRED_METADATA)
1834 resp.flow_action_flags |= MLX5_USER_ALLOC_UCONTEXT_FLOW_ACTION_FLAGS_ESP_AES_GCM_REQ_METADATA;
1835 if (MLX5_CAP_FLOWTABLE(dev->mdev, flow_table_properties_nic_receive.ft_field_support.outer_esp_spi))
1836 resp.flow_action_flags |= MLX5_USER_ALLOC_UCONTEXT_FLOW_ACTION_FLAGS_ESP_AES_GCM_SPI_STEERING;
1837 if (mlx5_accel_ipsec_device_caps(dev->mdev) & MLX5_ACCEL_IPSEC_CAP_TX_IV_IS_ESN)
1838 resp.flow_action_flags |= MLX5_USER_ALLOC_UCONTEXT_FLOW_ACTION_FLAGS_ESP_AES_GCM_TX_IV_IS_ESN;
1839 /* MLX5_USER_ALLOC_UCONTEXT_FLOW_ACTION_FLAGS_ESP_AES_GCM_FULL_OFFLOAD is currently always 0 */
1840 }
1841
1842 lib_uar_4k = req.lib_caps & MLX5_LIB_CAP_4K_UAR;1868 lib_uar_4k = req.lib_caps & MLX5_LIB_CAP_4K_UAR;
1843 lib_uar_dyn = req.lib_caps & MLX5_LIB_CAP_DYN_UAR;1869 lib_uar_dyn = req.lib_caps & MLX5_LIB_CAP_DYN_UAR;
1844 bfregi = &context->bfregi;1870 bfregi = &context->bfregi;
@@ -1887,87 +1913,24 @@ uar_done: · 42 unmodified lines
1887 if (err)1913 if (err)
1888 goto out_devx;1914 goto out_devx;
1889 1915
1890 if (MLX5_CAP_GEN(dev->mdev, dump_fill_mkey)) {
1891 err = mlx5_cmd_dump_fill_mkey(dev->mdev, &dump_fill_mkey);
1892 if (err)
1893 goto out_mdev;
1894 }
1895
1896 INIT_LIST_HEAD(&context->db_page_list);1916 INIT_LIST_HEAD(&context->db_page_list);
1897 mutex_init(&context->db_page_mutex);1917 mutex_init(&context->db_page_mutex);
1898 1918
1899 resp.tot_bfregs = lib_uar_dyn ? 0 : req.total_num_bfregs;1919 context->cqe_version = min_t(__u8,
1900 resp.num_ports = dev->num_ports;1920 (__u8)MLX5_CAP_GEN(dev->mdev, cqe_version),
1901 1921 req.max_cqe_version);
1902 if (offsetofend(typeof(resp), cqe_version) <= udata->outlen)
1903 resp.response_length += sizeof(resp.cqe_version);
1904
1905 if (offsetofend(typeof(resp), cmds_supp_uhw) <= udata->outlen) {
1906 resp.cmds_supp_uhw |= MLX5_USER_CMDS_SUPP_UHW_QUERY_DEVICE |
1907 MLX5_USER_CMDS_SUPP_UHW_CREATE_AH;
1908 resp.response_length += sizeof(resp.cmds_supp_uhw);
1909 }
1910
1911 if (offsetofend(typeof(resp), eth_min_inline) <= udata->outlen) {
1912 if (mlx5_ib_port_link_layer(ibdev, 1) == IB_LINK_LAYER_ETHERNET) {
1913 mlx5_query_min_inline(dev->mdev, &resp.eth_min_inline);
1914 resp.eth_min_inline++;
1915 }
1916 resp.response_length += sizeof(resp.eth_min_inline);
1917 }
1918
1919 if (offsetofend(typeof(resp), clock_info_versions) <= udata->outlen) {
1920 if (mdev->clock_info)
1921 resp.clock_info_versions = BIT(MLX5_IB_CLOCK_INFO_V1);
1922 resp.response_length += sizeof(resp.clock_info_versions);
1923 }
1924
1925 /*
1926 * We don't want to expose information from the PCI bar that is located
1927 * after 4096 bytes, so if the arch only supports larger pages, let's
1928 * pretend we don't support reading the HCA's core clock. This is also
1929 * forced by mmap function.
1930 */
1931 if (offsetofend(typeof(resp), hca_core_clock_offset) <= udata->outlen) {
1932 if (PAGE_SIZE <= 4096) {
1933 resp.comp_mask |=
1934 MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_CORE_CLOCK_OFFSET;
1935 resp.hca_core_clock_offset =
1936 offsetof(struct mlx5_init_seg, internal_timer_h) % PAGE_SIZE;
1937 }
1938 resp.response_length += sizeof(resp.hca_core_clock_offset);
1939 }
1940
1941 if (offsetofend(typeof(resp), log_uar_size) <= udata->outlen)
1942 resp.response_length += sizeof(resp.log_uar_size);
1943
1944 if (offsetofend(typeof(resp), num_uars_per_page) <= udata->outlen)
1945 resp.response_length += sizeof(resp.num_uars_per_page);
1946
1947 if (offsetofend(typeof(resp), num_dyn_bfregs) <= udata->outlen) {
1948 resp.num_dyn_bfregs = bfregi->num_dyn_bfregs;
1949 resp.response_length += sizeof(resp.num_dyn_bfregs);
1950 }
1951
1952 if (offsetofend(typeof(resp), dump_fill_mkey) <= udata->outlen) {
1953 if (MLX5_CAP_GEN(dev->mdev, dump_fill_mkey)) {
1954 resp.dump_fill_mkey = dump_fill_mkey;
1955 resp.comp_mask |=
1956 MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_DUMP_FILL_MKEY;
1957 }
1958 resp.response_length += sizeof(resp.dump_fill_mkey);
1959 }
1960 1922
1961 if (MLX5_CAP_GEN(dev->mdev, ece_support))1923 err = set_ucontext_resp(uctx, &resp);
1962 resp.comp_mask |= MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_ECE;1924 if (err)
1925 goto out_mdev;
1963 1926
1927 resp.response_length = min(udata->outlen, sizeof(resp));
1964 err = ib_copy_to_udata(udata, &resp, resp.response_length);1928 err = ib_copy_to_udata(udata, &resp, resp.response_length);
1965 if (err)1929 if (err)
1966 goto out_mdev;1930 goto out_mdev;
1967 1931
1968 bfregi->ver = ver;1932 bfregi->ver = ver;
1969 bfregi->num_low_latency_bfregs = req.num_low_latency_bfregs;1933 bfregi->num_low_latency_bfregs = req.num_low_latency_bfregs;
1970 context->cqe_version = resp.cqe_version;
1971 context->lib_caps = req.lib_caps;1934 context->lib_caps = req.lib_caps;
1972 print_lib_caps(dev, context->lib_caps);1935 print_lib_caps(dev, context->lib_caps);
1973 1936
@@ -2000,6 +1963,29 @@ out_ctx: · 26 unmodified lines
2000 return err;1963 return err;
2001}1964}
2002 1965
1966static int mlx5_ib_query_ucontext(struct ib_ucontext *ibcontext,
1967 struct uverbs_attr_bundle *attrs)
1968{
1969 struct mlx5_ib_alloc_ucontext_resp uctx_resp = {};
1970 int ret;
1971
1972 ret = set_ucontext_resp(ibcontext, &uctx_resp);
1973 if (ret)
1974 return ret;
1975
1976 uctx_resp.response_length =
1977 min_t(size_t,
1978 uverbs_attr_get_len(attrs,
1979 MLX5_IB_ATTR_QUERY_CONTEXT_RESP_UCTX),
1980 sizeof(uctx_resp));
1981
1982 ret = uverbs_copy_to_struct_or_zero(attrs,
1983 MLX5_IB_ATTR_QUERY_CONTEXT_RESP_UCTX,
1984 &uctx_resp,
1985 sizeof(uctx_resp));
1986 return ret;
1987}
1988
2003static void mlx5_ib_dealloc_ucontext(struct ib_ucontext *ibcontext)1989static void mlx5_ib_dealloc_ucontext(struct ib_ucontext *ibcontext)
2004{1990{
2005 struct mlx5_ib_ucontext *context = to_mucontext(ibcontext);1991 struct mlx5_ib_ucontext *context = to_mucontext(ibcontext);
@@ -2591,3205 +2577,786 @@ static void mlx5_ib_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata) · 585 unmodified lines
2591 mlx5_cmd_dealloc_pd(mdev->mdev, mpd->pdn, mpd->uid);2577 mlx5_cmd_dealloc_pd(mdev->mdev, mpd->pdn, mpd->uid);
2592}2578}
2593 2579
2594enum {2580static int mlx5_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
2595 MATCH_CRITERIA_ENABLE_OUTER_BIT,
2596 MATCH_CRITERIA_ENABLE_MISC_BIT,
2597 MATCH_CRITERIA_ENABLE_INNER_BIT,
2598 MATCH_CRITERIA_ENABLE_MISC2_BIT
2599};
2600
2601#define HEADER_IS_ZERO(match_criteria, headers) \
2602 !(memchr_inv(MLX5_ADDR_OF(fte_match_param, match_criteria, headers), \
2603 0, MLX5_FLD_SZ_BYTES(fte_match_param, headers))) \
2604
2605static u8 get_match_criteria_enable(u32 *match_criteria)
2606{2581{
2607 u8 match_criteria_enable;2582 struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
2608 2583 struct mlx5_ib_qp *mqp = to_mqp(ibqp);
2609 match_criteria_enable =2584 int err;
2610 (!HEADER_IS_ZERO(match_criteria, outer_headers)) <<2585 u16 uid;
2611 MATCH_CRITERIA_ENABLE_OUTER_BIT;
2612 match_criteria_enable |=
2613 (!HEADER_IS_ZERO(match_criteria, misc_parameters)) <<
2614 MATCH_CRITERIA_ENABLE_MISC_BIT;
2615 match_criteria_enable |=
2616 (!HEADER_IS_ZERO(match_criteria, inner_headers)) <<
2617 MATCH_CRITERIA_ENABLE_INNER_BIT;
2618 match_criteria_enable |=
2619 (!HEADER_IS_ZERO(match_criteria, misc_parameters_2)) <<
2620 MATCH_CRITERIA_ENABLE_MISC2_BIT;
2621 2586
2622 return match_criteria_enable;2587 uid = ibqp->pd ?
2623}2588 to_mpd(ibqp->pd)->uid : 0;
2624 2589
2625static int set_proto(void *outer_c, void *outer_v, u8 mask, u8 val)2590 if (mqp->flags & IB_QP_CREATE_SOURCE_QPN) {
2626{2591 mlx5_ib_dbg(dev, "Attaching a multi cast group to underlay QP is not supported\n");
2627 u8 entry_mask;2592 return -EOPNOTSUPP;
2628 u8 entry_val;2593 }
2629 int err = 0;
2630 2594
2631 if (!mask)2595 err = mlx5_cmd_attach_mcg(dev->mdev, gid, ibqp->qp_num, uid);
2632 goto out;2596 if (err)
2597 mlx5_ib_warn(dev, "failed attaching QPN 0x%x, MGID %pI6\n",
2598 ibqp->qp_num, gid->raw);
2633 2599
2634 entry_mask = MLX5_GET(fte_match_set_lyr_2_4, outer_c,
2635 ip_protocol);
2636 entry_val = MLX5_GET(fte_match_set_lyr_2_4, outer_v,
2637 ip_protocol);
2638 if (!entry_mask) {
2639 MLX5_SET(fte_match_set_lyr_2_4, outer_c, ip_protocol, mask);
2640 MLX5_SET(fte_match_set_lyr_2_4, outer_v, ip_protocol, val);
2641 goto out;
2642 }
2643 /* Don't override existing ip protocol */
2644 if (mask != entry_mask || val != entry_val)
2645 err = -EINVAL;
2646out:
2647 return err;2600 return err;
2648}2601}
2649 2602
2650static void set_flow_label(void *misc_c, void *misc_v, u32 mask, u32 val,2603static int mlx5_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
2651 bool inner)
2652{2604{
2653 if (inner) {2605 struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
2654 MLX5_SET(fte_match_set_misc,2606 int err;
2655 misc_c, inner_ipv6_flow_label, mask);2607 u16 uid;
2656 MLX5_SET(fte_match_set_misc,
2657 misc_v, inner_ipv6_flow_label, val);
2658 } else {
2659 MLX5_SET(fte_match_set_misc,
2660 misc_c, outer_ipv6_flow_label, mask);
2661 MLX5_SET(fte_match_set_misc,
2662 misc_v, outer_ipv6_flow_label, val);
2663 }
2664}
2665 2608
2666static void set_tos(void *outer_c, void *outer_v, u8 mask, u8 val)2609 uid = ibqp->pd ?
2667{2610 to_mpd(ibqp->pd)->uid : 0;
2668 MLX5_SET(fte_match_set_lyr_2_4, outer_c, ip_ecn, mask);2611 err = mlx5_cmd_detach_mcg(dev->mdev, gid, ibqp->qp_num, uid);
2669 MLX5_SET(fte_match_set_lyr_2_4, outer_v, ip_ecn, val);2612 if (err)
2670 MLX5_SET(fte_match_set_lyr_2_4, outer_c, ip_dscp, mask >> 2);2613 mlx5_ib_warn(dev, "failed detaching QPN 0x%x, MGID %pI6\n",
2671 MLX5_SET(fte_match_set_lyr_2_4, outer_v, ip_dscp, val >> 2);2614 ibqp->qp_num, gid->raw);
2615
2616 return err;
2672}2617}
2673 2618
2674static int check_mpls_supp_fields(u32 field_support, const __be32 *set_mask)2619static int init_node_data(struct mlx5_ib_dev *dev)
2675{2620{
2676 if (MLX5_GET(fte_match_mpls, set_mask, mpls_label) &&2621 int err;
2677 !(field_support & MLX5_FIELD_SUPPORT_MPLS_LABEL))
2678 return -EOPNOTSUPP;
2679
2680 if (MLX5_GET(fte_match_mpls, set_mask, mpls_exp) &&
2681 !(field_support & MLX5_FIELD_SUPPORT_MPLS_EXP))
2682 return -EOPNOTSUPP;
2683
2684 if (MLX5_GET(fte_match_mpls, set_mask, mpls_s_bos) &&
2685 !(field_support & MLX5_FIELD_SUPPORT_MPLS_S_BOS))
2686 return -EOPNOTSUPP;
2687 2622
2688 if (MLX5_GET(fte_match_mpls, set_mask, mpls_ttl) &&2623 err = mlx5_query_node_desc(dev, dev->ib_dev.node_desc);
2689 !(field_support & MLX5_FIELD_SUPPORT_MPLS_TTL))2624 if (err)
2690 return -EOPNOTSUPP;2625 return err;
2691 2626
2692 return 0;2627 dev->mdev->rev_id = dev->mdev->pdev->revision;
2693}
2694 2628
2695#define LAST_ETH_FIELD vlan_tag2629 return mlx5_query_node_guid(dev, &dev->ib_dev.node_guid);
2696#define LAST_IB_FIELD sl
2697#define LAST_IPV4_FIELD tos
2698#define LAST_IPV6_FIELD traffic_class
2699#define LAST_TCP_UDP_FIELD src_port
2700#define LAST_TUNNEL_FIELD tunnel_id
2701#define LAST_FLOW_TAG_FIELD tag_id
2702#define LAST_DROP_FIELD size
2703#define LAST_COUNTERS_FIELD counters
2704
2705/* Field is the last supported field */
2706#define FIELDS_NOT_SUPPORTED(filter, field)\
2707 memchr_inv((void *)&filter.field +\
2708 sizeof(filter.field), 0,\
2709 sizeof(filter) -\
2710 offsetof(typeof(filter), field) -\
2711 sizeof(filter.field))
2712
2713int parse_flow_flow_action(struct mlx5_ib_flow_action *maction,
2714 bool is_egress,
2715 struct mlx5_flow_act *action)
2716{
2717
2718 switch (maction->ib_action.type) {
2719 case IB_FLOW_ACTION_ESP:
2720 if (action->action & (MLX5_FLOW_CONTEXT_ACTION_ENCRYPT |
2721 MLX5_FLOW_CONTEXT_ACTION_DECRYPT))
2722 return -EINVAL;
2723 /* Currently only AES_GCM keymat is supported by the driver */
2724 action->esp_id = (uintptr_t)maction->esp_aes_gcm.ctx;
2725 action->action |= is_egress ?
2726 MLX5_FLOW_CONTEXT_ACTION_ENCRYPT :
2727 MLX5_FLOW_CONTEXT_ACTION_DECRYPT;
2728 return 0;
2729 case IB_FLOW_ACTION_UNSPECIFIED:
2730 if (maction->flow_action_raw.sub_type ==
2731 MLX5_IB_FLOW_ACTION_MODIFY_HEADER) {
2732 if (action->action & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR)
2733 return -EINVAL;
2734 action->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
2735 action->modify_hdr =
2736 maction->flow_action_raw.modify_hdr;
2737 return 0;
2738 }
2739 if (maction->flow_action_raw.sub_type ==
2740 MLX5_IB_FLOW_ACTION_DECAP) {
2741 if (action->action & MLX5_FLOW_CONTEXT_ACTION_DECAP)
2742 return -EINVAL;
2743 action->action |= MLX5_FLOW_CONTEXT_ACTION_DECAP;
2744 return 0;
2745 }
2746 if (maction->flow_action_raw.sub_type ==
2747 MLX5_IB_FLOW_ACTION_PACKET_REFORMAT) {
2748 if (action->action &
2749 MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT)
2750 return -EINVAL;
2751 action->action |=
2752 MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT;
2753 action->pkt_reformat =
2754 maction->flow_action_raw.pkt_reformat;
2755 return 0;
2756 }
2757 /* fall through */
2758 default:
2759 return -EOPNOTSUPP;
2760 }
2761}2630}
2762 2631
2763static int parse_flow_attr(struct mlx5_core_dev *mdev,2632static ssize_t fw_pages_show(struct device *device,
2764 struct mlx5_flow_spec *spec,2633 struct device_attribute *attr, char *buf)
2765 const union ib_flow_spec *ib_spec,2634{
2766 const struct ib_flow_attr *flow_attr,2635 struct mlx5_ib_dev *dev =
2767 struct mlx5_flow_act *action, u32 prev_type)2636 rdma_device_to_drv_device(device, struct mlx5_ib_dev, ib_dev);
2768{
2769 struct mlx5_flow_context *flow_context = &spec->flow_context;
2770 u32 *match_c = spec->match_criteria;
2771 u32 *match_v = spec->match_value;
2772 void *misc_params_c = MLX5_ADDR_OF(fte_match_param, match_c,
2773 misc_parameters);
2774 void *misc_params_v = MLX5_ADDR_OF(fte_match_param, match_v,
2775 misc_parameters);
2776 void *misc_params2_c = MLX5_ADDR_OF(fte_match_param, match_c,
2777 misc_parameters_2);
2778 void *misc_params2_v = MLX5_ADDR_OF(fte_match_param, match_v,
2779 misc_parameters_2);
2780 void *headers_c;
2781 void *headers_v;
2782 int match_ipv;
2783 int ret;
2784 2637
2785 if (ib_spec->type & IB_FLOW_SPEC_INNER) {2638 return sprintf(buf, "%d\n", dev->mdev->priv.fw_pages);
2786 headers_c = MLX5_ADDR_OF(fte_match_param, match_c,2639}
2787 inner_headers);2640static DEVICE_ATTR_RO(fw_pages);
2788 headers_v = MLX5_ADDR_OF(fte_match_param, match_v,
2789 inner_headers);
2790 match_ipv = MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
2791 ft_field_support.inner_ip_version);
2792 } else {
2793 headers_c = MLX5_ADDR_OF(fte_match_param, match_c,
2794 outer_headers);
2795 headers_v = MLX5_ADDR_OF(fte_match_param, match_v,
2796 outer_headers);
2797 match_ipv = MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
2798 ft_field_support.outer_ip_version);
2799 }
2800 2641
2801 switch (ib_spec->type & ~IB_FLOW_SPEC_INNER) {2642static ssize_t reg_pages_show(struct device *device,
2802 case IB_FLOW_SPEC_ETH:2643 struct device_attribute *attr, char *buf)
2803 if (FIELDS_NOT_SUPPORTED(ib_spec->eth.mask, LAST_ETH_FIELD))2644{
2804 return -EOPNOTSUPP;2645 struct mlx5_ib_dev *dev =
2646 rdma_device_to_drv_device(device, struct mlx5_ib_dev, ib_dev);
2805 2647
2806 ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,2648 return sprintf(buf, "%d\n", atomic_read(&dev->mdev->priv.reg_pages));
2807 dmac_47_16),2649}
2808 ib_spec->eth.mask.dst_mac);2650static DEVICE_ATTR_RO(reg_pages);
2809 ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
2810 dmac_47_16),
2811 ib_spec->eth.val.dst_mac);
2812
2813 ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
2814 smac_47_16),
2815 ib_spec->eth.mask.src_mac);
2816 ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
2817 smac_47_16),
2818 ib_spec->eth.val.src_mac);
2819
2820 if (ib_spec->eth.mask.vlan_tag) {
2821 MLX5_SET(fte_match_set_lyr_2_4, headers_c,
2822 cvlan_tag, 1);
2823 MLX5_SET(fte_match_set_lyr_2_4, headers_v,
2824 cvlan_tag, 1);
2825
2826 MLX5_SET(fte_match_set_lyr_2_4, headers_c,
2827 first_vid, ntohs(ib_spec->eth.mask.vlan_tag));
2828 MLX5_SET(fte_match_set_lyr_2_4, headers_v,
2829 first_vid, ntohs(ib_spec->eth.val.vlan_tag));
2830
2831 MLX5_SET(fte_match_set_lyr_2_4, headers_c,
2832 first_cfi,
2833 ntohs(ib_spec->eth.mask.vlan_tag) >> 12);
2834 MLX5_SET(fte_match_set_lyr_2_4, headers_v,
2835 first_cfi,
2836 ntohs(ib_spec->eth.val.vlan_tag) >> 12);
2837
2838 MLX5_SET(fte_match_set_lyr_2_4, headers_c,
2839 first_prio,
2840 ntohs(ib_spec->eth.mask.vlan_tag) >> 13);
2841 MLX5_SET(fte_match_set_lyr_2_4, headers_v,
2842 first_prio,
2843 ntohs(ib_spec->eth.val.vlan_tag) >> 13);
2844 }
2845 MLX5_SET(fte_match_set_lyr_2_4, headers_c,
2846 ethertype, ntohs(ib_spec->eth.mask.ether_type));
2847 MLX5_SET(fte_match_set_lyr_2_4, headers_v,
2848 ethertype, ntohs(ib_spec->eth.val.ether_type));
2849 break;
2850 case IB_FLOW_SPEC_IPV4:
2851 if (FIELDS_NOT_SUPPORTED(ib_spec->ipv4.mask, LAST_IPV4_FIELD))
2852 return -EOPNOTSUPP;
2853 2651
2854 if (match_ipv) {2652static ssize_t hca_type_show(struct device *device,
2855 MLX5_SET(fte_match_set_lyr_2_4, headers_c,2653 struct device_attribute *attr, char *buf)
2856 ip_version, 0xf);2654{
2857 MLX5_SET(fte_match_set_lyr_2_4, headers_v,2655 struct mlx5_ib_dev *dev =
2858 ip_version, MLX5_FS_IPV4_VERSION);2656 rdma_device_to_drv_device(device, struct mlx5_ib_dev, ib_dev);
2859 } else {
2860 MLX5_SET(fte_match_set_lyr_2_4, headers_c,
2861 ethertype, 0xffff);
2862 MLX5_SET(fte_match_set_lyr_2_4, headers_v,
2863 ethertype, ETH_P_IP);
2864 }
2865 2657
2866 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,2658 return sprintf(buf, "MT%d\n", dev->mdev->pdev->device);
2867 src_ipv4_src_ipv6.ipv4_layout.ipv4),2659}
2868 &ib_spec->ipv4.mask.src_ip,2660static DEVICE_ATTR_RO(hca_type);
2869 sizeof(ib_spec->ipv4.mask.src_ip));
2870 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
2871 src_ipv4_src_ipv6.ipv4_layout.ipv4),
2872 &ib_spec->ipv4.val.src_ip,
2873 sizeof(ib_spec->ipv4.val.src_ip));
2874 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
2875 dst_ipv4_dst_ipv6.ipv4_layout.ipv4),
2876 &ib_spec->ipv4.mask.dst_ip,
2877 sizeof(ib_spec->ipv4.mask.dst_ip));
2878 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
2879 dst_ipv4_dst_ipv6.ipv4_layout.ipv4),
2880 &ib_spec->ipv4.val.dst_ip,
2881 sizeof(ib_spec->ipv4.val.dst_ip));
2882
2883 set_tos(headers_c, headers_v,
2884 ib_spec->ipv4.mask.tos, ib_spec->ipv4.val.tos);
2885
2886 if (set_proto(headers_c, headers_v,
2887 ib_spec->ipv4.mask.proto,
2888 ib_spec->ipv4.val.proto))
2889 return -EINVAL;
2890 break;
2891 case IB_FLOW_SPEC_IPV6:
2892 if (FIELDS_NOT_SUPPORTED(ib_spec->ipv6.mask, LAST_IPV6_FIELD))
2893 return -EOPNOTSUPP;
2894 2661
2895 if (match_ipv) {2662static ssize_t hw_rev_show(struct device *device,
2896 MLX5_SET(fte_match_set_lyr_2_4, headers_c,2663 struct device_attribute *attr, char *buf)
2897 ip_version, 0xf);2664{
2898 MLX5_SET(fte_match_set_lyr_2_4, headers_v,2665 struct mlx5_ib_dev *dev =
2899 ip_version, MLX5_FS_IPV6_VERSION);2666 rdma_device_to_drv_device(device, struct mlx5_ib_dev, ib_dev);
2900 } else {
2901 MLX5_SET(fte_match_set_lyr_2_4, headers_c,
2902 ethertype, 0xffff);
2903 MLX5_SET(fte_match_set_lyr_2_4, headers_v,
2904 ethertype, ETH_P_IPV6);
2905 }
2906 2667
2907 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,2668 return sprintf(buf, "%x\n", dev->mdev->rev_id);
2908 src_ipv4_src_ipv6.ipv6_layout.ipv6),2669}
2909 &ib_spec->ipv6.mask.src_ip,2670static DEVICE_ATTR_RO(hw_rev);
2910 sizeof(ib_spec->ipv6.mask.src_ip));
2911 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
2912 src_ipv4_src_ipv6.ipv6_layout.ipv6),
2913 &ib_spec->ipv6.val.src_ip,
2914 sizeof(ib_spec->ipv6.val.src_ip));
2915 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
2916 dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
2917 &ib_spec->ipv6.mask.dst_ip,
2918 sizeof(ib_spec->ipv6.mask.dst_ip));
2919 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
2920 dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
2921 &ib_spec->ipv6.val.dst_ip,
2922 sizeof(ib_spec->ipv6.val.dst_ip));
2923
2924 set_tos(headers_c, headers_v,
2925 ib_spec->ipv6.mask.traffic_class,
2926 ib_spec->ipv6.val.traffic_class);
2927
2928 if (set_proto(headers_c, headers_v,
2929 ib_spec->ipv6.mask.next_hdr,
2930 ib_spec->ipv6.val.next_hdr))
2931 return -EINVAL;
2932 2671
2933 set_flow_label(misc_params_c, misc_params_v,2672static ssize_t board_id_show(struct device *device,
2934 ntohl(ib_spec->ipv6.mask.flow_label),2673 struct device_attribute *attr, char *buf)
2935 ntohl(ib_spec->ipv6.val.flow_label),2674{
2936 ib_spec->type & IB_FLOW_SPEC_INNER);2675 struct mlx5_ib_dev *dev =
2937 break;2676 rdma_device_to_drv_device(device, struct mlx5_ib_dev, ib_dev);
2938 case IB_FLOW_SPEC_ESP:
2939 if (ib_spec->esp.mask.seq)
2940 return -EOPNOTSUPP;
2941 2677
2942 MLX5_SET(fte_match_set_misc, misc_params_c, outer_esp_spi,2678 return sprintf(buf, "%.*s\n", MLX5_BOARD_ID_LEN,
2943 ntohl(ib_spec->esp.mask.spi));2679 dev->mdev->board_id);
2944 MLX5_SET(fte_match_set_misc, misc_params_v, outer_esp_spi,2680}
2945 ntohl(ib_spec->esp.val.spi));2681static DEVICE_ATTR_RO(board_id);
2946 break;
2947 case IB_FLOW_SPEC_TCP:
2948 if (FIELDS_NOT_SUPPORTED(ib_spec->tcp_udp.mask,
2949 LAST_TCP_UDP_FIELD))
2950 return -EOPNOTSUPP;
2951 2682
2952 if (set_proto(headers_c, headers_v, 0xff, IPPROTO_TCP))2683static struct attribute *mlx5_class_attributes[] = {
2953 return -EINVAL;2684 &dev_attr_hw_rev.attr,
2685 &dev_attr_hca_type.attr,
2686 &dev_attr_board_id.attr,
2687 &dev_attr_fw_pages.attr,
2688 &dev_attr_reg_pages.attr,
2689 NULL,
2690};
2954 2691
2955 MLX5_SET(fte_match_set_lyr_2_4, headers_c, tcp_sport,2692static const struct attribute_group mlx5_attr_group = {
2956 ntohs(ib_spec->tcp_udp.mask.src_port));2693 .attrs = mlx5_class_attributes,
2957 MLX5_SET(fte_match_set_lyr_2_4, headers_v, tcp_sport,2694};
2958 ntohs(ib_spec->tcp_udp.val.src_port));
2959 2695
2960 MLX5_SET(fte_match_set_lyr_2_4, headers_c, tcp_dport,2696static void pkey_change_handler(struct work_struct *work)
2961 ntohs(ib_spec->tcp_udp.mask.dst_port));2697{
2962 MLX5_SET(fte_match_set_lyr_2_4, headers_v, tcp_dport,2698 struct mlx5_ib_port_resources *ports =
2963 ntohs(ib_spec->tcp_udp.val.dst_port));2699 container_of(work, struct mlx5_ib_port_resources,
2964 break;2700 pkey_change_work);
2965 case IB_FLOW_SPEC_UDP:
2966 if (FIELDS_NOT_SUPPORTED(ib_spec->tcp_udp.mask,
2967 LAST_TCP_UDP_FIELD))
2968 return -EOPNOTSUPP;
2969 2701
2970 if (set_proto(headers_c, headers_v, 0xff, IPPROTO_UDP))2702 mutex_lock(&ports->devr->mutex);
2971 return -EINVAL;2703 mlx5_ib_gsi_pkey_change(ports->gsi);
2704 mutex_unlock(&ports->devr->mutex);
2705}
2972 2706
2973 MLX5_SET(fte_match_set_lyr_2_4, headers_c, udp_sport,2707static void mlx5_ib_handle_internal_error(struct mlx5_ib_dev *ibdev)
2974 ntohs(ib_spec->tcp_udp.mask.src_port));2708{
2975 MLX5_SET(fte_match_set_lyr_2_4, headers_v, udp_sport,2709 struct mlx5_ib_qp *mqp;
2976 ntohs(ib_spec->tcp_udp.val.src_port));2710 struct mlx5_ib_cq *send_mcq, *recv_mcq;
2711 struct mlx5_core_cq *mcq;
2712 struct list_head cq_armed_list;
2713 unsigned long flags_qp;
2714 unsigned long flags_cq;
2715 unsigned long flags;
2977 2716
2978 MLX5_SET(fte_match_set_lyr_2_4, headers_c, udp_dport,2717 INIT_LIST_HEAD(&cq_armed_list);
2979 ntohs(ib_spec->tcp_udp.mask.dst_port));
2980 MLX5_SET(fte_match_set_lyr_2_4, headers_v, udp_dport,
2981 ntohs(ib_spec->tcp_udp.val.dst_port));
2982 break;
2983 case IB_FLOW_SPEC_GRE:
2984 if (ib_spec->gre.mask.c_ks_res0_ver)
2985 return -EOPNOTSUPP;
2986 2718
2987 if (set_proto(headers_c, headers_v, 0xff, IPPROTO_GRE))2719 /* Go over qp list reside on that ibdev, sync with create/destroy qp.*/
2988 return -EINVAL;2720 spin_lock_irqsave(&ibdev->reset_flow_resource_lock, flags);
2989 2721 list_for_each_entry(mqp, &ibdev->qp_list, qps_list) {
2990 MLX5_SET(fte_match_set_lyr_2_4, headers_c, ip_protocol,2722 spin_lock_irqsave(&mqp->sq.lock, flags_qp);
2991 0xff);2723 if (mqp->sq.tail != mqp->sq.head) {
2992 MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_protocol,2724 send_mcq = to_mcq(mqp->ibqp.send_cq);
2993 IPPROTO_GRE);2725 spin_lock_irqsave(&send_mcq->lock, flags_cq);
2994 2726 if (send_mcq->mcq.comp &&
2995 MLX5_SET(fte_match_set_misc, misc_params_c, gre_protocol,2727 mqp->ibqp.send_cq->comp_handler) {
2996 ntohs(ib_spec->gre.mask.protocol));2728 if (!send_mcq->mcq.reset_notify_added) {
2997 MLX5_SET(fte_match_set_misc, misc_params_v, gre_protocol,2729 send_mcq->mcq.reset_notify_added = 1;
2998 ntohs(ib_spec->gre.val.protocol));2730 list_add_tail(&send_mcq->mcq.reset_notify,
2999 2731 &cq_armed_list);
3000 memcpy(MLX5_ADDR_OF(fte_match_set_misc, misc_params_c,2732 }
3001 gre_key.nvgre.hi),
3002 &ib_spec->gre.mask.key,
3003 sizeof(ib_spec->gre.mask.key));
3004 memcpy(MLX5_ADDR_OF(fte_match_set_misc, misc_params_v,
3005 gre_key.nvgre.hi),
3006 &ib_spec->gre.val.key,
3007 sizeof(ib_spec->gre.val.key));
3008 break;
3009 case IB_FLOW_SPEC_MPLS:
3010 switch (prev_type) {
3011 case IB_FLOW_SPEC_UDP:
3012 if (check_mpls_supp_fields(MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
3013 ft_field_support.outer_first_mpls_over_udp),
3014 &ib_spec->mpls.mask.tag))
3015 return -EOPNOTSUPP;
3016
3017 memcpy(MLX5_ADDR_OF(fte_match_set_misc2, misc_params2_v,
3018 outer_first_mpls_over_udp),
3019 &ib_spec->mpls.val.tag,
3020 sizeof(ib_spec->mpls.val.tag));
3021 memcpy(MLX5_ADDR_OF(fte_match_set_misc2, misc_params2_c,
3022 outer_first_mpls_over_udp),
3023 &ib_spec->mpls.mask.tag,
3024 sizeof(ib_spec->mpls.mask.tag));
3025 break;
3026 case IB_FLOW_SPEC_GRE:
3027 if (check_mpls_supp_fields(MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
3028 ft_field_support.outer_first_mpls_over_gre),
3029 &ib_spec->mpls.mask.tag))
3030 return -EOPNOTSUPP;
3031
3032 memcpy(MLX5_ADDR_OF(fte_match_set_misc2, misc_params2_v,
3033 outer_first_mpls_over_gre),
3034 &ib_spec->mpls.val.tag,
3035 sizeof(ib_spec->mpls.val.tag));
3036 memcpy(MLX5_ADDR_OF(fte_match_set_misc2, misc_params2_c,
3037 outer_first_mpls_over_gre),
3038 &ib_spec->mpls.mask.tag,
3039 sizeof(ib_spec->mpls.mask.tag));
3040 break;
3041 default:
3042 if (ib_spec->type & IB_FLOW_SPEC_INNER) {
3043 if (check_mpls_supp_fields(MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
3044 ft_field_support.inner_first_mpls),
3045 &ib_spec->mpls.mask.tag))
3046 return -EOPNOTSUPP;
3047
3048 memcpy(MLX5_ADDR_OF(fte_match_set_misc2, misc_params2_v,
3049 inner_first_mpls),
3050 &ib_spec->mpls.val.tag,
3051 sizeof(ib_spec->mpls.val.tag));
3052 memcpy(MLX5_ADDR_OF(fte_match_set_misc2, misc_params2_c,
3053 inner_first_mpls),
3054 &ib_spec->mpls.mask.tag,
3055 sizeof(ib_spec->mpls.mask.tag));
3056 } else {
3057 if (check_mpls_supp_fields(MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
3058 ft_field_support.outer_first_mpls),
3059 &ib_spec->mpls.mask.tag))
3060 return -EOPNOTSUPP;
3061
3062 memcpy(MLX5_ADDR_OF(fte_match_set_misc2, misc_params2_v,
3063 outer_first_mpls),
3064 &ib_spec->mpls.val.tag,
3065 sizeof(ib_spec->mpls.val.tag));
3066 memcpy(MLX5_ADDR_OF(fte_match_set_misc2, misc_params2_c,
3067 outer_first_mpls),
3068 &ib_spec->mpls.mask.tag,
3069 sizeof(ib_spec->mpls.mask.tag));
3070 }2733 }
2734 spin_unlock_irqrestore(&send_mcq->lock, flags_cq);
3071 }2735 }
3072 break;2736 spin_unlock_irqrestore(&mqp->sq.lock, flags_qp);
3073 case IB_FLOW_SPEC_VXLAN_TUNNEL:2737 spin_lock_irqsave(&mqp->rq.lock, flags_qp);
3074 if (FIELDS_NOT_SUPPORTED(ib_spec->tunnel.mask,2738 /* no handling is needed for SRQ */
3075 LAST_TUNNEL_FIELD))2739 if (!mqp->ibqp.srq) {
3076 return -EOPNOTSUPP;2740 if (mqp->rq.tail != mqp->rq.head) {
3077 2741 recv_mcq = to_mcq(mqp->ibqp.recv_cq);
3078 MLX5_SET(fte_match_set_misc, misc_params_c, vxlan_vni,2742 spin_lock_irqsave(&recv_mcq->lock, flags_cq);
3079 ntohl(ib_spec->tunnel.mask.tunnel_id));2743 if (recv_mcq->mcq.comp &&
3080 MLX5_SET(fte_match_set_misc, misc_params_v, vxlan_vni,2744 mqp->ibqp.recv_cq->comp_handler) {
3081 ntohl(ib_spec->tunnel.val.tunnel_id));2745 if (!recv_mcq->mcq.reset_notify_added) {
3082 break;2746 recv_mcq->mcq.reset_notify_added = 1;
3083 case IB_FLOW_SPEC_ACTION_TAG:2747 list_add_tail(&recv_mcq->mcq.reset_notify,
3084 if (FIELDS_NOT_SUPPORTED(ib_spec->flow_tag,2748 &cq_armed_list);
3085 LAST_FLOW_TAG_FIELD))2749 }
3086 return -EOPNOTSUPP;2750 }
3087 if (ib_spec->flow_tag.tag_id >= BIT(24))2751 spin_unlock_irqrestore(&recv_mcq->lock,
3088 return -EINVAL;2752 flags_cq);
3089 2753 }
3090 flow_context->flow_tag = ib_spec->flow_tag.tag_id;2754 }
3091 flow_context->flags |= FLOW_CONTEXT_HAS_TAG;2755 spin_unlock_irqrestore(&mqp->rq.lock, flags_qp);
3092 break;
3093 case IB_FLOW_SPEC_ACTION_DROP:
3094 if (FIELDS_NOT_SUPPORTED(ib_spec->drop,
3095 LAST_DROP_FIELD))
3096 return -EOPNOTSUPP;
3097 action->action |= MLX5_FLOW_CONTEXT_ACTION_DROP;
3098 break;
3099 case IB_FLOW_SPEC_ACTION_HANDLE:
3100 ret = parse_flow_flow_action(to_mflow_act(ib_spec->action.act),
3101 flow_attr->flags & IB_FLOW_ATTR_FLAGS_EGRESS, action);
3102 if (ret)
3103 return ret;
3104 break;
3105 case IB_FLOW_SPEC_ACTION_COUNT:
3106 if (FIELDS_NOT_SUPPORTED(ib_spec->flow_count,
3107 LAST_COUNTERS_FIELD))
3108 return -EOPNOTSUPP;
3109
3110 /* for now support only one counters spec per flow */
3111 if (action->action & MLX5_FLOW_CONTEXT_ACTION_COUNT)
3112 return -EINVAL;
3113
3114 action->counters = ib_spec->flow_count.counters;
3115 action->action |= MLX5_FLOW_CONTEXT_ACTION_COUNT;
3116 break;
3117 default:
3118 return -EINVAL;
3119 }
3120
3121 return 0;
3122}
3123
3124/* If a flow could catch both multicast and unicast packets,
3125 * it won't fall into the multicast flow steering table and this rule
3126 * could steal other multicast packets.
3127 */
3128static bool flow_is_multicast_only(const struct ib_flow_attr *ib_attr)
3129{
3130 union ib_flow_spec *flow_spec;
3131
3132 if (ib_attr->type != IB_FLOW_ATTR_NORMAL ||
3133 ib_attr->num_of_specs < 1)
3134 return false;
3135
3136 flow_spec = (union ib_flow_spec *)(ib_attr + 1);
3137 if (flow_spec->type == IB_FLOW_SPEC_IPV4) {
3138 struct ib_flow_spec_ipv4 *ipv4_spec;
3139
3140 ipv4_spec = (struct ib_flow_spec_ipv4 *)flow_spec;
3141 if (ipv4_is_multicast(ipv4_spec->val.dst_ip))
3142 return true;
3143
3144 return false;
3145 }2756 }
3146 2757 /*At that point all inflight post send were put to be executed as of we
3147 if (flow_spec->type == IB_FLOW_SPEC_ETH) {2758 * lock/unlock above locks Now need to arm all involved CQs.
3148 struct ib_flow_spec_eth *eth_spec;2759 */
3149 2760 list_for_each_entry(mcq, &cq_armed_list, reset_notify) {
3150 eth_spec = (struct ib_flow_spec_eth *)flow_spec;2761 mcq->comp(mcq, NULL);
3151 return is_multicast_ether_addr(eth_spec->mask.dst_mac) &&
3152 is_multicast_ether_addr(eth_spec->val.dst_mac);
3153 }2762 }
3154 2763 spin_unlock_irqrestore(&ibdev->reset_flow_resource_lock, flags);
3155 return false;
3156}2764}
3157 2765
3158enum valid_spec {2766static void delay_drop_handler(struct work_struct *work)
3159 VALID_SPEC_INVALID,
3160 VALID_SPEC_VALID,
3161 VALID_SPEC_NA,
3162};
3163
3164static enum valid_spec
3165is_valid_esp_aes_gcm(struct mlx5_core_dev *mdev,
3166 const struct mlx5_flow_spec *spec,
3167 const struct mlx5_flow_act *flow_act,
3168 bool egress)
3169{2767{
3170 const u32 *match_c = spec->match_criteria;2768 int err;
3171 bool is_crypto =2769 struct mlx5_ib_delay_drop *delay_drop =
3172 (flow_act->action & (MLX5_FLOW_CONTEXT_ACTION_ENCRYPT |2770 container_of(work, struct mlx5_ib_delay_drop,
3173 MLX5_FLOW_CONTEXT_ACTION_DECRYPT));2771 delay_drop_work);
3174 bool is_ipsec = mlx5_fs_is_ipsec_flow(match_c);
3175 bool is_drop = flow_act->action & MLX5_FLOW_CONTEXT_ACTION_DROP;
3176
3177 /*
3178 * Currently only crypto is supported in egress, when regular egress
3179 * rules would be supported, always return VALID_SPEC_NA.
3180 */
3181 if (!is_crypto)
3182 return VALID_SPEC_NA;
3183
3184 return is_crypto && is_ipsec &&
3185 (!egress || (!is_drop &&
3186 !(spec->flow_context.flags & FLOW_CONTEXT_HAS_TAG))) ?
3187 VALID_SPEC_VALID : VALID_SPEC_INVALID;
3188}
3189
3190static bool is_valid_spec(struct mlx5_core_dev *mdev,
3191 const struct mlx5_flow_spec *spec,
3192 const struct mlx5_flow_act *flow_act,
3193 bool egress)
3194{
3195 /* We curretly only support ipsec egress flow */
3196 return is_valid_esp_aes_gcm(mdev, spec, flow_act, egress) != VALID_SPEC_INVALID;
3197}
3198
3199static bool is_valid_ethertype(struct mlx5_core_dev *mdev,
3200 const struct ib_flow_attr *flow_attr,
3201 bool check_inner)
3202{
3203 union ib_flow_spec *ib_spec = (union ib_flow_spec *)(flow_attr + 1);
3204 int match_ipv = check_inner ?
3205 MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
3206 ft_field_support.inner_ip_version) :
3207 MLX5_CAP_FLOWTABLE_NIC_RX(mdev,
3208 ft_field_support.outer_ip_version);
3209 int inner_bit = check_inner ? IB_FLOW_SPEC_INNER : 0;
3210 bool ipv4_spec_valid, ipv6_spec_valid;
3211 unsigned int ip_spec_type = 0;
3212 bool has_ethertype = false;
3213 unsigned int spec_index;
3214 bool mask_valid = true;
3215 u16 eth_type = 0;
3216 bool type_valid;
3217
3218 /* Validate that ethertype is correct */
3219 for (spec_index = 0; spec_index < flow_attr->num_of_specs; spec_index++) {
3220 if ((ib_spec->type == (IB_FLOW_SPEC_ETH | inner_bit)) &&
3221 ib_spec->eth.mask.ether_type) {
3222 mask_valid = (ib_spec->eth.mask.ether_type ==
3223 htons(0xffff));
3224 has_ethertype = true;
3225 eth_type = ntohs(ib_spec->eth.val.ether_type);
3226 } else if ((ib_spec->type == (IB_FLOW_SPEC_IPV4 | inner_bit)) ||
3227 (ib_spec->type == (IB_FLOW_SPEC_IPV6 | inner_bit))) {
3228 ip_spec_type = ib_spec->type;
3229 }
3230 ib_spec = (void *)ib_spec + ib_spec->size;
3231 }
3232 2772
3233 type_valid = (!has_ethertype) || (!ip_spec_type);2773 atomic_inc(&delay_drop->events_cnt);
3234 if (!type_valid && mask_valid) {
3235 ipv4_spec_valid = (eth_type == ETH_P_IP) &&
3236 (ip_spec_type == (IB_FLOW_SPEC_IPV4 | inner_bit));
3237 ipv6_spec_valid = (eth_type == ETH_P_IPV6) &&
3238 (ip_spec_type == (IB_FLOW_SPEC_IPV6 | inner_bit));
3239 2774
3240 type_valid = (ipv4_spec_valid) || (ipv6_spec_valid) ||2775 mutex_lock(&delay_drop->lock);
3241 (((eth_type == ETH_P_MPLS_UC) ||2776 err = mlx5_core_set_delay_drop(delay_drop->dev, delay_drop->timeout);
3242 (eth_type == ETH_P_MPLS_MC)) && match_ipv);2777 if (err) {
2778 mlx5_ib_warn(delay_drop->dev, "Failed to set delay drop, timeout=%u\n",
2779 delay_drop->timeout);
2780 delay_drop->activate = false;
3243 }2781 }
3244 2782 mutex_unlock(&delay_drop->lock);
3245 return type_valid;
3246}2783}
3247 2784
3248static bool is_valid_attr(struct mlx5_core_dev *mdev,2785static void handle_general_event(struct mlx5_ib_dev *ibdev, struct mlx5_eqe *eqe,
3249 const struct ib_flow_attr *flow_attr)2786 struct ib_event *ibev)
3250{2787{
3251 return is_valid_ethertype(mdev, flow_attr, false) &&2788 u8 port = (eqe->data.port.port >> 4) & 0xf;
3252 is_valid_ethertype(mdev, flow_attr, true);
3253}
3254 2789
3255static void put_flow_table(struct mlx5_ib_dev *dev,2790 switch (eqe->sub_type) {
3256 struct mlx5_ib_flow_prio *prio, bool ft_added)2791 case MLX5_GENERAL_SUBTYPE_DELAY_DROP_TIMEOUT:
3257{2792 if (mlx5_ib_port_link_layer(&ibdev->ib_dev, port) ==
3258 prio->refcount -= !!ft_added;2793 IB_LINK_LAYER_ETHERNET)
3259 if (!prio->refcount) {2794 schedule_work(&ibdev->delay_drop.delay_drop_work);
3260 mlx5_destroy_flow_table(prio->flow_table);2795 break;
3261 prio->flow_table = NULL;2796 default: /* do nothing */
2797 return;
3262 }2798 }
3263}2799}
3264 2800
3265static void counters_clear_description(struct ib_counters *counters)2801static int handle_port_change(struct mlx5_ib_dev *ibdev, struct mlx5_eqe *eqe,
2802 struct ib_event *ibev)
3266{2803{
3267 struct mlx5_ib_mcounters *mcounters = to_mcounters(counters);2804 u8 port = (eqe->data.port.port >> 4) & 0xf;
3268 2805
3269 mutex_lock(&mcounters->mcntrs_mutex);2806 ibev->element.port_num = port;
3270 kfree(mcounters->counters_data);
3271 mcounters->counters_data = NULL;
3272 mcounters->cntrs_max_index = 0;
3273 mutex_unlock(&mcounters->mcntrs_mutex);
3274}
3275 2807
3276static int mlx5_ib_destroy_flow(struct ib_flow *flow_id)2808 switch (eqe->sub_type) {
3277{2809 case MLX5_PORT_CHANGE_SUBTYPE_ACTIVE:
3278 struct mlx5_ib_flow_handler *handler = container_of(flow_id,2810 case MLX5_PORT_CHANGE_SUBTYPE_DOWN:
3279 struct mlx5_ib_flow_handler,2811 case MLX5_PORT_CHANGE_SUBTYPE_INITIALIZED:
3280 ibflow);2812 /* In RoCE, port up/down events are handled in
3281 struct mlx5_ib_flow_handler *iter, *tmp;2813 * mlx5_netdev_event().
3282 struct mlx5_ib_dev *dev = handler->dev;2814 */
2815 if (mlx5_ib_port_link_layer(&ibdev->ib_dev, port) ==
2816 IB_LINK_LAYER_ETHERNET)
2817 return -EINVAL;
2818
2819 ibev->event = (eqe->sub_type == MLX5_PORT_CHANGE_SUBTYPE_ACTIVE) ?
2820 IB_EVENT_PORT_ACTIVE : IB_EVENT_PORT_ERR;
2821 break;
3283 2822
3284 mutex_lock(&dev->flow_db->lock);2823 case MLX5_PORT_CHANGE_SUBTYPE_LID:
2824 ibev->event = IB_EVENT_LID_CHANGE;
2825 break;
3285 2826
3286 list_for_each_entry_safe(iter, tmp, &handler->list, list) {2827 case MLX5_PORT_CHANGE_SUBTYPE_PKEY:
3287 mlx5_del_flow_rules(iter->rule);2828 ibev->event = IB_EVENT_PKEY_CHANGE;
3288 put_flow_table(dev, iter->prio, true);2829 schedule_work(&ibdev->devr.ports[port - 1].pkey_change_work);
3289 list_del(&iter->list);2830 break;
3290 kfree(iter);
3291 }
3292 2831
3293 mlx5_del_flow_rules(handler->rule);2832 case MLX5_PORT_CHANGE_SUBTYPE_GUID:
3294 put_flow_table(dev, handler->prio, true);2833 ibev->event = IB_EVENT_GID_CHANGE;
3295 if (handler->ibcounters &&2834 break;
3296 atomic_read(&handler->ibcounters->usecnt) == 1)
3297 counters_clear_description(handler->ibcounters);
3298 2835
3299 mutex_unlock(&dev->flow_db->lock);2836 case MLX5_PORT_CHANGE_SUBTYPE_CLIENT_REREG:
3300 if (handler->flow_matcher)2837 ibev->event = IB_EVENT_CLIENT_REREGISTER;
3301 atomic_dec(&handler->flow_matcher->usecnt);2838 break;
3302 kfree(handler);2839 default:
2840 return -EINVAL;
2841 }
3303 2842
3304 return 0;2843 return 0;
3305}2844}
3306 2845
3307static int ib_prio_to_core_prio(unsigned int priority, bool dont_trap)2846static void mlx5_ib_handle_event(struct work_struct *_work)
3308{
3309 priority *= 2;
3310 if (!dont_trap)
3311 priority++;
3312 return priority;
3313}
3314
3315enum flow_table_type {
3316 MLX5_IB_FT_RX,
3317 MLX5_IB_FT_TX
3318};
3319
3320#define MLX5_FS_MAX_TYPES 6
3321#define MLX5_FS_MAX_ENTRIES BIT(16)
3322
3323static struct mlx5_ib_flow_prio *_get_prio(struct mlx5_flow_namespace *ns,
3324 struct mlx5_ib_flow_prio *prio,
3325 int priority,
3326 int num_entries, int num_groups,
3327 u32 flags)
3328{2847{
3329 struct mlx5_flow_table_attr ft_attr = {};2848 struct mlx5_ib_event_work *work =
3330 struct mlx5_flow_table *ft;2849 container_of(_work, struct mlx5_ib_event_work, work);
3331 2850 struct mlx5_ib_dev *ibdev;
3332 ft_attr.prio = priority;2851 struct ib_event ibev;
3333 ft_attr.max_fte = num_entries;2852 bool fatal = false;
3334 ft_attr.flags = flags;
3335 ft_attr.autogroup.max_num_groups = num_groups;
3336 ft = mlx5_create_auto_grouped_flow_table(ns, &ft_attr);
3337 if (IS_ERR(ft))
3338 return ERR_CAST(ft);
3339
3340 prio->flow_table = ft;
3341 prio->refcount = 0;
3342 return prio;
3343}
3344 2853
3345static struct mlx5_ib_flow_prio *get_flow_table(struct mlx5_ib_dev *dev,2854 if (work->is_slave) {
3346 struct ib_flow_attr *flow_attr,2855 ibdev = mlx5_ib_get_ibdev_from_mpi(work->mpi);
3347 enum flow_table_type ft_type)2856 if (!ibdev)
3348{2857 goto out;
3349 bool dont_trap = flow_attr->flags & IB_FLOW_ATTR_FLAGS_DONT_TRAP;2858 } else {
3350 struct mlx5_flow_namespace *ns = NULL;2859 ibdev = work->dev;
3351 struct mlx5_ib_flow_prio *prio;
3352 struct mlx5_flow_table *ft;
3353 int max_table_size;
3354 int num_entries;
3355 int num_groups;
3356 bool esw_encap;
3357 u32 flags = 0;
3358 int priority;
3359
3360 max_table_size = BIT(MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev,
3361 log_max_ft_size));
3362 esw_encap = mlx5_eswitch_get_encap_mode(dev->mdev) !=
3363 DEVLINK_ESWITCH_ENCAP_MODE_NONE;
3364 if (flow_attr->type == IB_FLOW_ATTR_NORMAL) {
3365 enum mlx5_flow_namespace_type fn_type;
3366
3367 if (flow_is_multicast_only(flow_attr) &&
3368 !dont_trap)
3369 priority = MLX5_IB_FLOW_MCAST_PRIO;
3370 else
3371 priority = ib_prio_to_core_prio(flow_attr->priority,
3372 dont_trap);
3373 if (ft_type == MLX5_IB_FT_RX) {
3374 fn_type = MLX5_FLOW_NAMESPACE_BYPASS;
3375 prio = &dev->flow_db->prios[priority];
3376 if (!dev->is_rep && !esw_encap &&
3377 MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev, decap))
3378 flags |= MLX5_FLOW_TABLE_TUNNEL_EN_DECAP;
3379 if (!dev->is_rep && !esw_encap &&
3380 MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev,
3381 reformat_l3_tunnel_to_l2))
3382 flags |= MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT;
3383 } else {
3384 max_table_size =
3385 BIT(MLX5_CAP_FLOWTABLE_NIC_TX(dev->mdev,
3386 log_max_ft_size));
3387 fn_type = MLX5_FLOW_NAMESPACE_EGRESS;
3388 prio = &dev->flow_db->egress_prios[priority];
3389 if (!dev->is_rep && !esw_encap &&
3390 MLX5_CAP_FLOWTABLE_NIC_TX(dev->mdev, reformat))
3391 flags |= MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT;
3392 }
3393 ns = mlx5_get_flow_namespace(dev->mdev, fn_type);
3394 num_entries = MLX5_FS_MAX_ENTRIES;
3395 num_groups = MLX5_FS_MAX_TYPES;
3396 } else if (flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT ||
3397 flow_attr->type == IB_FLOW_ATTR_MC_DEFAULT) {
3398 ns = mlx5_get_flow_namespace(dev->mdev,
3399 MLX5_FLOW_NAMESPACE_LEFTOVERS);
3400 build_leftovers_ft_param(&priority,
3401 &num_entries,
3402 &num_groups);
3403 prio = &dev->flow_db->prios[MLX5_IB_FLOW_LEFTOVERS_PRIO];
3404 } else if (flow_attr->type == IB_FLOW_ATTR_SNIFFER) {
3405 if (!MLX5_CAP_FLOWTABLE(dev->mdev,
3406 allow_sniffer_and_nic_rx_shared_tir))
3407 return ERR_PTR(-ENOTSUPP);
3408
3409 ns = mlx5_get_flow_namespace(dev->mdev, ft_type == MLX5_IB_FT_RX ?
3410 MLX5_FLOW_NAMESPACE_SNIFFER_RX :
3411 MLX5_FLOW_NAMESPACE_SNIFFER_TX);
3412
3413 prio = &dev->flow_db->sniffer[ft_type];
3414 priority = 0;
3415 num_entries = 1;
3416 num_groups = 1;
3417 }2860 }
3418 2861
3419 if (!ns)2862 switch (work->event) {
3420 return ERR_PTR(-ENOTSUPP);2863 case MLX5_DEV_EVENT_SYS_ERROR:
3421 2864 ibev.event = IB_EVENT_DEVICE_FATAL;
3422 max_table_size = min_t(int, num_entries, max_table_size);2865 mlx5_ib_handle_internal_error(ibdev);
3423 2866 ibev.element.port_num = (u8)(unsigned long)work->param;
3424 ft = prio->flow_table;2867 fatal = true;
3425 if (!ft)2868 break;
3426 return _get_prio(ns, prio, priority, max_table_size, num_groups,2869 case MLX5_EVENT_TYPE_PORT_CHANGE:
3427 flags);2870 if (handle_port_change(ibdev, work->param, &ibev))
3428 2871 goto out;
3429 return prio;2872 break;
3430}2873 case MLX5_EVENT_TYPE_GENERAL_EVENT:
2874 handle_general_event(ibdev, work->param, &ibev);
2875 /* fall through */
2876 default:
2877 goto out;
2878 }
3431 2879
3432static void set_underlay_qp(struct mlx5_ib_dev *dev,2880 ibev.device = &ibdev->ib_dev;
3433 struct mlx5_flow_spec *spec,
3434 u32 underlay_qpn)
3435{
3436 void *misc_params_c = MLX5_ADDR_OF(fte_match_param,
3437 spec->match_criteria,
3438 misc_parameters);
3439 void *misc_params_v = MLX5_ADDR_OF(fte_match_param, spec->match_value,
3440 misc_parameters);
3441 2881
3442 if (underlay_qpn &&2882 if (!rdma_is_port_valid(&ibdev->ib_dev, ibev.element.port_num)) {
3443 MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev,2883 mlx5_ib_warn(ibdev, "warning: event on port %d\n", ibev.element.port_num);
3444 ft_field_support.bth_dst_qp)) {2884 goto out;
3445 MLX5_SET(fte_match_set_misc,
3446 misc_params_v, bth_dst_qp, underlay_qpn);
3447 MLX5_SET(fte_match_set_misc,
3448 misc_params_c, bth_dst_qp, 0xffffff);
3449 }2885 }
3450}
3451 2886
3452static int read_flow_counters(struct ib_device *ibdev,2887 if (ibdev->ib_active)
3453 struct mlx5_read_counters_attr *read_attr)2888 ib_dispatch_event(&ibev);
3454{
3455 struct mlx5_fc *fc = read_attr->hw_cntrs_hndl;
3456 struct mlx5_ib_dev *dev = to_mdev(ibdev);
3457 2889
3458 return mlx5_fc_query(dev->mdev, fc,2890 if (fatal)
3459 &read_attr->out[IB_COUNTER_PACKETS],2891 ibdev->ib_active = false;
3460 &read_attr->out[IB_COUNTER_BYTES]);2892out:
2893 kfree(work);
3461}2894}
3462 2895
3463/* flow counters currently expose two counters packets and bytes */2896static int mlx5_ib_event(struct notifier_block *nb,
3464#define FLOW_COUNTERS_NUM 22897 unsigned long event, void *param)
3465static int counters_set_description(struct ib_counters *counters,
3466 enum mlx5_ib_counters_type counters_type,
3467 struct mlx5_ib_flow_counters_desc *desc_data,
3468 u32 ncounters)
3469{2898{
3470 struct mlx5_ib_mcounters *mcounters = to_mcounters(counters);2899 struct mlx5_ib_event_work *work;
3471 u32 cntrs_max_index = 0;
3472 int i;
3473
3474 if (counters_type != MLX5_IB_COUNTERS_FLOW)
3475 return -EINVAL;
3476 2900
3477 /* init the fields for the object */2901 work = kmalloc(sizeof(*work), GFP_ATOMIC);
3478 mcounters->type = counters_type;2902 if (!work)
3479 mcounters->read_counters = read_flow_counters;2903 return NOTIFY_DONE;
3480 mcounters->counters_num = FLOW_COUNTERS_NUM;
3481 mcounters->ncounters = ncounters;
3482 /* each counter entry have both description and index pair */
3483 for (i = 0; i < ncounters; i++) {
3484 if (desc_data[i].description > IB_COUNTER_BYTES)
3485 return -EINVAL;
3486 2904
3487 if (cntrs_max_index <= desc_data[i].index)2905 INIT_WORK(&work->work, mlx5_ib_handle_event);
3488 cntrs_max_index = desc_data[i].index + 1;2906 work->dev = container_of(nb, struct mlx5_ib_dev, mdev_events);
3489 }2907 work->is_slave = false;
2908 work->param = param;
2909 work->event = event;
3490 2910
3491 mutex_lock(&mcounters->mcntrs_mutex);2911 queue_work(mlx5_ib_event_wq, &work->work);
3492 mcounters->counters_data = desc_data;
3493 mcounters->cntrs_max_index = cntrs_max_index;
3494 mutex_unlock(&mcounters->mcntrs_mutex);
3495 2912
3496 return 0;2913 return NOTIFY_OK;
3497}2914}
3498 2915
3499#define MAX_COUNTERS_NUM (USHRT_MAX / (sizeof(u32) * 2))2916static int mlx5_ib_event_slave_port(struct notifier_block *nb,
3500static int flow_counters_set_data(struct ib_counters *ibcounters,2917 unsigned long event, void *param)
3501 struct mlx5_ib_create_flow *ucmd)
3502{2918{
3503 struct mlx5_ib_mcounters *mcounters = to_mcounters(ibcounters);2919 struct mlx5_ib_event_work *work;
3504 struct mlx5_ib_flow_counters_data *cntrs_data = NULL;
3505 struct mlx5_ib_flow_counters_desc *desc_data = NULL;
3506 bool hw_hndl = false;
3507 int ret = 0;
3508
3509 if (ucmd && ucmd->ncounters_data != 0) {
3510 cntrs_data = ucmd->data;
3511 if (cntrs_data->ncounters > MAX_COUNTERS_NUM)
3512 return -EINVAL;
3513
3514 desc_data = kcalloc(cntrs_data->ncounters,
3515 sizeof(*desc_data),
3516 GFP_KERNEL);
3517 if (!desc_data)
3518 return -ENOMEM;
3519
3520 if (copy_from_user(desc_data,
3521 u64_to_user_ptr(cntrs_data->counters_data),
3522 sizeof(*desc_data) * cntrs_data->ncounters)) {
3523 ret = -EFAULT;
3524 goto free;
3525 }
3526 }
3527
3528 if (!mcounters->hw_cntrs_hndl) {
3529 mcounters->hw_cntrs_hndl = mlx5_fc_create(
3530 to_mdev(ibcounters->device)->mdev, false);
3531 if (IS_ERR(mcounters->hw_cntrs_hndl)) {
3532 ret = PTR_ERR(mcounters->hw_cntrs_hndl);
3533 goto free;
3534 }
3535 hw_hndl = true;
3536 }
3537
3538 if (desc_data) {
3539 /* counters already bound to at least one flow */
3540 if (mcounters->cntrs_max_index) {
3541 ret = -EINVAL;
3542 goto free_hndl;
3543 }
3544
3545 ret = counters_set_description(ibcounters,
3546 MLX5_IB_COUNTERS_FLOW,
3547 desc_data,
3548 cntrs_data->ncounters);
3549 if (ret)
3550 goto free_hndl;
3551
3552 } else if (!mcounters->cntrs_max_index) {
3553 /* counters not bound yet, must have udata passed */
3554 ret = -EINVAL;
3555 goto free_hndl;
3556 }
3557
3558 return 0;
3559
3560free_hndl:
3561 if (hw_hndl) {
3562 mlx5_fc_destroy(to_mdev(ibcounters->device)->mdev,
3563 mcounters->hw_cntrs_hndl);
3564 mcounters->hw_cntrs_hndl = NULL;
3565 }
3566free:
3567 kfree(desc_data);
3568 return ret;
3569}
3570
3571static void mlx5_ib_set_rule_source_port(struct mlx5_ib_dev *dev,
3572 struct mlx5_flow_spec *spec,
3573 struct mlx5_eswitch_rep *rep)
3574{
3575 struct mlx5_eswitch *esw = dev->mdev->priv.eswitch;
3576 void *misc;
3577
3578 if (mlx5_eswitch_vport_match_metadata_enabled(esw)) {
3579 misc = MLX5_ADDR_OF(fte_match_param, spec->match_value,
3580 misc_parameters_2);
3581
3582 MLX5_SET(fte_match_set_misc2, misc, metadata_reg_c_0,
3583 mlx5_eswitch_get_vport_metadata_for_match(esw,
3584 rep->vport));
3585 misc = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
3586 misc_parameters_2);
3587
3588 MLX5_SET(fte_match_set_misc2, misc, metadata_reg_c_0,
3589 mlx5_eswitch_get_vport_metadata_mask());
3590 } else {
3591 misc = MLX5_ADDR_OF(fte_match_param, spec->match_value,
3592 misc_parameters);
3593
3594 MLX5_SET(fte_match_set_misc, misc, source_port, rep->vport);
3595
3596 misc = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
3597 misc_parameters);
3598
3599 MLX5_SET_TO_ONES(fte_match_set_misc, misc, source_port);
3600 }
3601}
3602
3603static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev,
3604 struct mlx5_ib_flow_prio *ft_prio,
3605 const struct ib_flow_attr *flow_attr,
3606 struct mlx5_flow_destination *dst,
3607 u32 underlay_qpn,
3608 struct mlx5_ib_create_flow *ucmd)
3609{
3610 struct mlx5_flow_table *ft = ft_prio->flow_table;
3611 struct mlx5_ib_flow_handler *handler;
3612 struct mlx5_flow_act flow_act = {};
3613 struct mlx5_flow_spec *spec;
3614 struct mlx5_flow_destination dest_arr[2] = {};
3615 struct mlx5_flow_destination *rule_dst = dest_arr;
3616 const void *ib_flow = (const void *)flow_attr + sizeof(*flow_attr);
3617 unsigned int spec_index;
3618 u32 prev_type = 0;
3619 int err = 0;
3620 int dest_num = 0;
3621 bool is_egress = flow_attr->flags & IB_FLOW_ATTR_FLAGS_EGRESS;
3622
3623 if (!is_valid_attr(dev->mdev, flow_attr))
3624 return ERR_PTR(-EINVAL);
3625
3626 if (dev->is_rep && is_egress)
3627 return ERR_PTR(-EINVAL);
3628
3629 spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
3630 handler = kzalloc(sizeof(*handler), GFP_KERNEL);
3631 if (!handler || !spec) {
3632 err = -ENOMEM;
3633 goto free;
3634 }
3635
3636 INIT_LIST_HEAD(&handler->list);
3637
3638 for (spec_index = 0; spec_index < flow_attr->num_of_specs; spec_index++) {
3639 err = parse_flow_attr(dev->mdev, spec,
3640 ib_flow, flow_attr, &flow_act,
3641 prev_type);
3642 if (err < 0)
3643 goto free;
3644
3645 prev_type = ((union ib_flow_spec *)ib_flow)->type;
3646 ib_flow += ((union ib_flow_spec *)ib_flow)->size;
3647 }
3648
3649 if (dst && !(flow_act.action & MLX5_FLOW_CONTEXT_ACTION_DROP)) {
3650 memcpy(&dest_arr[0], dst, sizeof(*dst));
3651 dest_num++;
3652 }
3653
3654 if (!flow_is_multicast_only(flow_attr))
3655 set_underlay_qp(dev, spec, underlay_qpn);
3656
3657 if (dev->is_rep) {
3658 struct mlx5_eswitch_rep *rep;
3659
3660 rep = dev->port[flow_attr->port - 1].rep;
3661 if (!rep) {
3662 err = -EINVAL;
3663 goto free;
3664 }
3665
3666 mlx5_ib_set_rule_source_port(dev, spec, rep);
3667 }
3668
3669 spec->match_criteria_enable = get_match_criteria_enable(spec->match_criteria);
3670
3671 if (is_egress &&
3672 !is_valid_spec(dev->mdev, spec, &flow_act, is_egress)) {
3673 err = -EINVAL;
3674 goto free;
3675 }
3676
3677 if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_COUNT) {
3678 struct mlx5_ib_mcounters *mcounters;
3679
3680 err = flow_counters_set_data(flow_act.counters, ucmd);
3681 if (err)
3682 goto free;
3683
3684 mcounters = to_mcounters(flow_act.counters);
3685 handler->ibcounters = flow_act.counters;
3686 dest_arr[dest_num].type =
3687 MLX5_FLOW_DESTINATION_TYPE_COUNTER;
3688 dest_arr[dest_num].counter_id =
3689 mlx5_fc_id(mcounters->hw_cntrs_hndl);
3690 dest_num++;
3691 }
3692
3693 if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_DROP) {
3694 if (!dest_num)
3695 rule_dst = NULL;
3696 } else {
3697 if (flow_attr->flags & IB_FLOW_ATTR_FLAGS_DONT_TRAP)
3698 flow_act.action |=
3699 MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO;
3700 if (is_egress)
3701 flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_ALLOW;
3702 else if (dest_num)
3703 flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
3704 }
3705
3706 if ((spec->flow_context.flags & FLOW_CONTEXT_HAS_TAG) &&
3707 (flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT ||
3708 flow_attr->type == IB_FLOW_ATTR_MC_DEFAULT)) {
3709 mlx5_ib_warn(dev, "Flow tag %u and attribute type %x isn't allowed in leftovers\n",
3710 spec->flow_context.flow_tag, flow_attr->type);
3711 err = -EINVAL;
3712 goto free;
3713 }
3714 handler->rule = mlx5_add_flow_rules(ft, spec,
3715 &flow_act,
3716 rule_dst, dest_num);
3717
3718 if (IS_ERR(handler->rule)) {
3719 err = PTR_ERR(handler->rule);
3720 goto free;
3721 }
3722
3723 ft_prio->refcount++;
3724 handler->prio = ft_prio;
3725 handler->dev = dev;
3726
3727 ft_prio->flow_table = ft;
3728free:
3729 if (err && handler) {
3730 if (handler->ibcounters &&
3731 atomic_read(&handler->ibcounters->usecnt) == 1)
3732 counters_clear_description(handler->ibcounters);
3733 kfree(handler);
3734 }
3735 kvfree(spec);
3736 return err ? ERR_PTR(err) : handler;
3737}
3738
3739static struct mlx5_ib_flow_handler *create_flow_rule(struct mlx5_ib_dev *dev,
3740 struct mlx5_ib_flow_prio *ft_prio,
3741 const struct ib_flow_attr *flow_attr,
3742 struct mlx5_flow_destination *dst)
3743{
3744 return _create_flow_rule(dev, ft_prio, flow_attr, dst, 0, NULL);
3745}
3746
3747enum {
3748 LEFTOVERS_MC,
3749 LEFTOVERS_UC,
3750};
3751
3752static struct mlx5_ib_flow_handler *create_leftovers_rule(struct mlx5_ib_dev *dev,
3753 struct mlx5_ib_flow_prio *ft_prio,
3754 struct ib_flow_attr *flow_attr,
3755 struct mlx5_flow_destination *dst)
3756{
3757 struct mlx5_ib_flow_handler *handler_ucast = NULL;
3758 struct mlx5_ib_flow_handler *handler = NULL;
3759
3760 static struct {
3761 struct ib_flow_attr flow_attr;
3762 struct ib_flow_spec_eth eth_flow;
3763 } leftovers_specs[] = {
3764 [LEFTOVERS_MC] = {
3765 .flow_attr = {
3766 .num_of_specs = 1,
3767 .size = sizeof(leftovers_specs[0])
3768 },
3769 .eth_flow = {
3770 .type = IB_FLOW_SPEC_ETH,
3771 .size = sizeof(struct ib_flow_spec_eth),
3772 .mask = {.dst_mac = {0x1} },
3773 .val = {.dst_mac = {0x1} }
3774 }
3775 },
3776 [LEFTOVERS_UC] = {
3777 .flow_attr = {
3778 .num_of_specs = 1,
3779 .size = sizeof(leftovers_specs[0])
3780 },
3781 .eth_flow = {
3782 .type = IB_FLOW_SPEC_ETH,
3783 .size = sizeof(struct ib_flow_spec_eth),
3784 .mask = {.dst_mac = {0x1} },
3785 .val = {.dst_mac = {} }
3786 }
3787 }
3788 };
3789
3790 handler = create_flow_rule(dev, ft_prio,
3791 &leftovers_specs[LEFTOVERS_MC].flow_attr,
3792 dst);
3793 if (!IS_ERR(handler) &&
3794 flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT) {
3795 handler_ucast = create_flow_rule(dev, ft_prio,
3796 &leftovers_specs[LEFTOVERS_UC].flow_attr,
3797 dst);
3798 if (IS_ERR(handler_ucast)) {
3799 mlx5_del_flow_rules(handler->rule);
3800 ft_prio->refcount--;
3801 kfree(handler);
3802 handler = handler_ucast;
3803 } else {
3804 list_add(&handler_ucast->list, &handler->list);
3805 }
3806 }
3807
3808 return handler;
3809}
3810
3811static struct mlx5_ib_flow_handler *create_sniffer_rule(struct mlx5_ib_dev *dev,
3812 struct mlx5_ib_flow_prio *ft_rx,
3813 struct mlx5_ib_flow_prio *ft_tx,
3814 struct mlx5_flow_destination *dst)
3815{
3816 struct mlx5_ib_flow_handler *handler_rx;
3817 struct mlx5_ib_flow_handler *handler_tx;
3818 int err;
3819 static const struct ib_flow_attr flow_attr = {
3820 .num_of_specs = 0,
3821 .size = sizeof(flow_attr)
3822 };
3823
3824 handler_rx = create_flow_rule(dev, ft_rx, &flow_attr, dst);
3825 if (IS_ERR(handler_rx)) {
3826 err = PTR_ERR(handler_rx);
3827 goto err;
3828 }
3829
3830 handler_tx = create_flow_rule(dev, ft_tx, &flow_attr, dst);
3831 if (IS_ERR(handler_tx)) {
3832 err = PTR_ERR(handler_tx);
3833 goto err_tx;
3834 }
3835
3836 list_add(&handler_tx->list, &handler_rx->list);
3837
3838 return handler_rx;
3839
3840err_tx:
3841 mlx5_del_flow_rules(handler_rx->rule);
3842 ft_rx->refcount--;
3843 kfree(handler_rx);
3844err:
3845 return ERR_PTR(err);
3846}
3847
3848static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp,
3849 struct ib_flow_attr *flow_attr,
3850 int domain,
3851 struct ib_udata *udata)
3852{
3853 struct mlx5_ib_dev *dev = to_mdev(qp->device);
3854 struct mlx5_ib_qp *mqp = to_mqp(qp);
3855 struct mlx5_ib_flow_handler *handler = NULL;
3856 struct mlx5_flow_destination *dst = NULL;
3857 struct mlx5_ib_flow_prio *ft_prio_tx = NULL;
3858 struct mlx5_ib_flow_prio *ft_prio;
3859 bool is_egress = flow_attr->flags & IB_FLOW_ATTR_FLAGS_EGRESS;
3860 struct mlx5_ib_create_flow *ucmd = NULL, ucmd_hdr;
3861 size_t min_ucmd_sz, required_ucmd_sz;
3862 int err;
3863 int underlay_qpn;
3864
3865 if (udata && udata->inlen) {
3866 min_ucmd_sz = offsetof(typeof(ucmd_hdr), reserved) +
3867 sizeof(ucmd_hdr.reserved);
3868 if (udata->inlen < min_ucmd_sz)
3869 return ERR_PTR(-EOPNOTSUPP);
3870
3871 err = ib_copy_from_udata(&ucmd_hdr, udata, min_ucmd_sz);
3872 if (err)
3873 return ERR_PTR(err);
3874
3875 /* currently supports only one counters data */
3876 if (ucmd_hdr.ncounters_data > 1)
3877 return ERR_PTR(-EINVAL);
3878
3879 required_ucmd_sz = min_ucmd_sz +
3880 sizeof(struct mlx5_ib_flow_counters_data) *
3881 ucmd_hdr.ncounters_data;
3882 if (udata->inlen > required_ucmd_sz &&
3883 !ib_is_udata_cleared(udata, required_ucmd_sz,
3884 udata->inlen - required_ucmd_sz))
3885 return ERR_PTR(-EOPNOTSUPP);
3886
3887 ucmd = kzalloc(required_ucmd_sz, GFP_KERNEL);
3888 if (!ucmd)
3889 return ERR_PTR(-ENOMEM);
3890
3891 err = ib_copy_from_udata(ucmd, udata, required_ucmd_sz);
3892 if (err)
3893 goto free_ucmd;
3894 }
3895
3896 if (flow_attr->priority > MLX5_IB_FLOW_LAST_PRIO) {
3897 err = -ENOMEM;
3898 goto free_ucmd;
3899 }
3900
3901 if (domain != IB_FLOW_DOMAIN_USER ||
3902 flow_attr->port > dev->num_ports ||
3903 (flow_attr->flags & ~(IB_FLOW_ATTR_FLAGS_DONT_TRAP |
3904 IB_FLOW_ATTR_FLAGS_EGRESS))) {
3905 err = -EINVAL;
3906 goto free_ucmd;
3907 }
3908
3909 if (is_egress &&
3910 (flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT ||
3911 flow_attr->type == IB_FLOW_ATTR_MC_DEFAULT)) {
3912 err = -EINVAL;
3913 goto free_ucmd;
3914 }
3915
3916 dst = kzalloc(sizeof(*dst), GFP_KERNEL);
3917 if (!dst) {
3918 err = -ENOMEM;
3919 goto free_ucmd;
3920 }
3921
3922 mutex_lock(&dev->flow_db->lock);
3923
3924 ft_prio = get_flow_table(dev, flow_attr,
3925 is_egress ? MLX5_IB_FT_TX : MLX5_IB_FT_RX);
3926 if (IS_ERR(ft_prio)) {
3927 err = PTR_ERR(ft_prio);
3928 goto unlock;
3929 }
3930 if (flow_attr->type == IB_FLOW_ATTR_SNIFFER) {
3931 ft_prio_tx = get_flow_table(dev, flow_attr, MLX5_IB_FT_TX);
3932 if (IS_ERR(ft_prio_tx)) {
3933 err = PTR_ERR(ft_prio_tx);
3934 ft_prio_tx = NULL;
3935 goto destroy_ft;
3936 }
3937 }
3938
3939 if (is_egress) {
3940 dst->type = MLX5_FLOW_DESTINATION_TYPE_PORT;
3941 } else {
3942 dst->type = MLX5_FLOW_DESTINATION_TYPE_TIR;
3943 if (mqp->is_rss)
3944 dst->tir_num = mqp->rss_qp.tirn;
3945 else
3946 dst->tir_num = mqp->raw_packet_qp.rq.tirn;
3947 }
3948
3949 if (flow_attr->type == IB_FLOW_ATTR_NORMAL) {
3950 underlay_qpn = (mqp->flags & IB_QP_CREATE_SOURCE_QPN) ?
3951 mqp->underlay_qpn :
3952 0;
3953 handler = _create_flow_rule(dev, ft_prio, flow_attr, dst,
3954 underlay_qpn, ucmd);
3955 } else if (flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT ||
3956 flow_attr->type == IB_FLOW_ATTR_MC_DEFAULT) {
3957 handler = create_leftovers_rule(dev, ft_prio, flow_attr,
3958 dst);
3959 } else if (flow_attr->type == IB_FLOW_ATTR_SNIFFER) {
3960 handler = create_sniffer_rule(dev, ft_prio, ft_prio_tx, dst);
3961 } else {
3962 err = -EINVAL;
3963 goto destroy_ft;
3964 }
3965
3966 if (IS_ERR(handler)) {
3967 err = PTR_ERR(handler);
3968 handler = NULL;
3969 goto destroy_ft;
3970 }
3971
3972 mutex_unlock(&dev->flow_db->lock);
3973 kfree(dst);
3974 kfree(ucmd);
3975
3976 return &handler->ibflow;
3977
3978destroy_ft:
3979 put_flow_table(dev, ft_prio, false);
3980 if (ft_prio_tx)
3981 put_flow_table(dev, ft_prio_tx, false);
3982unlock:
3983 mutex_unlock(&dev->flow_db->lock);
3984 kfree(dst);
3985free_ucmd:
3986 kfree(ucmd);
3987 return ERR_PTR(err);
3988}
3989
3990static struct mlx5_ib_flow_prio *
3991_get_flow_table(struct mlx5_ib_dev *dev,
3992 struct mlx5_ib_flow_matcher *fs_matcher,
3993 bool mcast)
3994{
3995 struct mlx5_flow_namespace *ns = NULL;
3996 struct mlx5_ib_flow_prio *prio = NULL;
3997 int max_table_size = 0;
3998 bool esw_encap;
3999 u32 flags = 0;
4000 int priority;
4001
4002 if (mcast)
4003 priority = MLX5_IB_FLOW_MCAST_PRIO;
4004 else
4005 priority = ib_prio_to_core_prio(fs_matcher->priority, false);
4006
4007 esw_encap = mlx5_eswitch_get_encap_mode(dev->mdev) !=
4008 DEVLINK_ESWITCH_ENCAP_MODE_NONE;
4009 if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_BYPASS) {
4010 max_table_size = BIT(MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev,
4011 log_max_ft_size));
4012 if (MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev, decap) && !esw_encap)
4013 flags |= MLX5_FLOW_TABLE_TUNNEL_EN_DECAP;
4014 if (MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev,
4015 reformat_l3_tunnel_to_l2) &&
4016 !esw_encap)
4017 flags |= MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT;
4018 } else if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_EGRESS) {
4019 max_table_size = BIT(
4020 MLX5_CAP_FLOWTABLE_NIC_TX(dev->mdev, log_max_ft_size));
4021 if (MLX5_CAP_FLOWTABLE_NIC_TX(dev->mdev, reformat) && !esw_encap)
4022 flags |= MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT;
4023 } else if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_FDB) {
4024 max_table_size = BIT(
4025 MLX5_CAP_ESW_FLOWTABLE_FDB(dev->mdev, log_max_ft_size));
4026 if (MLX5_CAP_ESW_FLOWTABLE_FDB(dev->mdev, decap) && esw_encap)
4027 flags |= MLX5_FLOW_TABLE_TUNNEL_EN_DECAP;
4028 if (MLX5_CAP_ESW_FLOWTABLE_FDB(dev->mdev, reformat_l3_tunnel_to_l2) &&
4029 esw_encap)
4030 flags |= MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT;
4031 priority = FDB_BYPASS_PATH;
4032 } else if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_RDMA_RX) {
4033 max_table_size =
4034 BIT(MLX5_CAP_FLOWTABLE_RDMA_RX(dev->mdev,
4035 log_max_ft_size));
4036 priority = fs_matcher->priority;
4037 } else if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_RDMA_TX) {
4038 max_table_size =
4039 BIT(MLX5_CAP_FLOWTABLE_RDMA_TX(dev->mdev,
4040 log_max_ft_size));
4041 priority = fs_matcher->priority;
4042 }
4043
4044 max_table_size = min_t(int, max_table_size, MLX5_FS_MAX_ENTRIES);
4045
4046 ns = mlx5_get_flow_namespace(dev->mdev, fs_matcher->ns_type);
4047 if (!ns)
4048 return ERR_PTR(-ENOTSUPP);
4049
4050 if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_BYPASS)
4051 prio = &dev->flow_db->prios[priority];
4052 else if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_EGRESS)
4053 prio = &dev->flow_db->egress_prios[priority];
4054 else if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_FDB)
4055 prio = &dev->flow_db->fdb;
4056 else if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_RDMA_RX)
4057 prio = &dev->flow_db->rdma_rx[priority];
4058 else if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_RDMA_TX)
4059 prio = &dev->flow_db->rdma_tx[priority];
4060
4061 if (!prio)
4062 return ERR_PTR(-EINVAL);
4063
4064 if (prio->flow_table)
4065 return prio;
4066
4067 return _get_prio(ns, prio, priority, max_table_size,
4068 MLX5_FS_MAX_TYPES, flags);
4069}
4070
4071static struct mlx5_ib_flow_handler *
4072_create_raw_flow_rule(struct mlx5_ib_dev *dev,
4073 struct mlx5_ib_flow_prio *ft_prio,
4074 struct mlx5_flow_destination *dst,
4075 struct mlx5_ib_flow_matcher *fs_matcher,
4076 struct mlx5_flow_context *flow_context,
4077 struct mlx5_flow_act *flow_act,
4078 void *cmd_in, int inlen,
4079 int dst_num)
4080{
4081 struct mlx5_ib_flow_handler *handler;
4082 struct mlx5_flow_spec *spec;
4083 struct mlx5_flow_table *ft = ft_prio->flow_table;
4084 int err = 0;
4085
4086 spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
4087 handler = kzalloc(sizeof(*handler), GFP_KERNEL);
4088 if (!handler || !spec) {
4089 err = -ENOMEM;
4090 goto free;
4091 }
4092
4093 INIT_LIST_HEAD(&handler->list);
4094
4095 memcpy(spec->match_value, cmd_in, inlen);
4096 memcpy(spec->match_criteria, fs_matcher->matcher_mask.match_params,
4097 fs_matcher->mask_len);
4098 spec->match_criteria_enable = fs_matcher->match_criteria_enable;
4099 spec->flow_context = *flow_context;
4100
4101 handler->rule = mlx5_add_flow_rules(ft, spec,
4102 flow_act, dst, dst_num);
4103
4104 if (IS_ERR(handler->rule)) {
4105 err = PTR_ERR(handler->rule);
4106 goto free;
4107 }
4108
4109 ft_prio->refcount++;
4110 handler->prio = ft_prio;
4111 handler->dev = dev;
4112 ft_prio->flow_table = ft;
4113
4114free:
4115 if (err)
4116 kfree(handler);
4117 kvfree(spec);
4118 return err ? ERR_PTR(err) : handler;
4119}
4120
4121static bool raw_fs_is_multicast(struct mlx5_ib_flow_matcher *fs_matcher,
4122 void *match_v)
4123{
4124 void *match_c;
4125 void *match_v_set_lyr_2_4, *match_c_set_lyr_2_4;
4126 void *dmac, *dmac_mask;
4127 void *ipv4, *ipv4_mask;
4128
4129 if (!(fs_matcher->match_criteria_enable &
4130 (1 << MATCH_CRITERIA_ENABLE_OUTER_BIT)))
4131 return false;
4132
4133 match_c = fs_matcher->matcher_mask.match_params;
4134 match_v_set_lyr_2_4 = MLX5_ADDR_OF(fte_match_param, match_v,
4135 outer_headers);
4136 match_c_set_lyr_2_4 = MLX5_ADDR_OF(fte_match_param, match_c,
4137 outer_headers);
4138
4139 dmac = MLX5_ADDR_OF(fte_match_set_lyr_2_4, match_v_set_lyr_2_4,
4140 dmac_47_16);
4141 dmac_mask = MLX5_ADDR_OF(fte_match_set_lyr_2_4, match_c_set_lyr_2_4,
4142 dmac_47_16);
4143
4144 if (is_multicast_ether_addr(dmac) &&
4145 is_multicast_ether_addr(dmac_mask))
4146 return true;
4147
4148 ipv4 = MLX5_ADDR_OF(fte_match_set_lyr_2_4, match_v_set_lyr_2_4,
4149 dst_ipv4_dst_ipv6.ipv4_layout.ipv4);
4150
4151 ipv4_mask = MLX5_ADDR_OF(fte_match_set_lyr_2_4, match_c_set_lyr_2_4,
4152 dst_ipv4_dst_ipv6.ipv4_layout.ipv4);
4153
4154 if (ipv4_is_multicast(*(__be32 *)(ipv4)) &&
4155 ipv4_is_multicast(*(__be32 *)(ipv4_mask)))
4156 return true;
4157
4158 return false;
4159}
4160
4161struct mlx5_ib_flow_handler *
4162mlx5_ib_raw_fs_rule_add(struct mlx5_ib_dev *dev,
4163 struct mlx5_ib_flow_matcher *fs_matcher,
4164 struct mlx5_flow_context *flow_context,
4165 struct mlx5_flow_act *flow_act,
4166 u32 counter_id,
4167 void *cmd_in, int inlen, int dest_id,
4168 int dest_type)
4169{
4170 struct mlx5_flow_destination *dst;
4171 struct mlx5_ib_flow_prio *ft_prio;
4172 struct mlx5_ib_flow_handler *handler;
4173 int dst_num = 0;
4174 bool mcast;
4175 int err;
4176
4177 if (fs_matcher->flow_type != MLX5_IB_FLOW_TYPE_NORMAL)
4178 return ERR_PTR(-EOPNOTSUPP);
4179
4180 if (fs_matcher->priority > MLX5_IB_FLOW_LAST_PRIO)
4181 return ERR_PTR(-ENOMEM);
4182
4183 dst = kcalloc(2, sizeof(*dst), GFP_KERNEL);
4184 if (!dst)
4185 return ERR_PTR(-ENOMEM);
4186
4187 mcast = raw_fs_is_multicast(fs_matcher, cmd_in);
4188 mutex_lock(&dev->flow_db->lock);
4189
4190 ft_prio = _get_flow_table(dev, fs_matcher, mcast);
4191 if (IS_ERR(ft_prio)) {
4192 err = PTR_ERR(ft_prio);
4193 goto unlock;
4194 }
4195
4196 if (dest_type == MLX5_FLOW_DESTINATION_TYPE_TIR) {
4197 dst[dst_num].type = dest_type;
4198 dst[dst_num++].tir_num = dest_id;
4199 flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
4200 } else if (dest_type == MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE) {
4201 dst[dst_num].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE_NUM;
4202 dst[dst_num++].ft_num = dest_id;
4203 flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
4204 } else if (dest_type == MLX5_FLOW_DESTINATION_TYPE_PORT) {
4205 dst[dst_num++].type = MLX5_FLOW_DESTINATION_TYPE_PORT;
4206 flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_ALLOW;
4207 }
4208
4209
4210 if (flow_act->action & MLX5_FLOW_CONTEXT_ACTION_COUNT) {
4211 dst[dst_num].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
4212 dst[dst_num].counter_id = counter_id;
4213 dst_num++;
4214 }
4215
4216 handler = _create_raw_flow_rule(dev, ft_prio, dst, fs_matcher,
4217 flow_context, flow_act,
4218 cmd_in, inlen, dst_num);
4219
4220 if (IS_ERR(handler)) {
4221 err = PTR_ERR(handler);
4222 goto destroy_ft;
4223 }
4224
4225 mutex_unlock(&dev->flow_db->lock);
4226 atomic_inc(&fs_matcher->usecnt);
4227 handler->flow_matcher = fs_matcher;
4228
4229 kfree(dst);
4230
4231 return handler;
4232
4233destroy_ft:
4234 put_flow_table(dev, ft_prio, false);
4235unlock:
4236 mutex_unlock(&dev->flow_db->lock);
4237 kfree(dst);
4238
4239 return ERR_PTR(err);
4240}
4241
4242static u32 mlx5_ib_flow_action_flags_to_accel_xfrm_flags(u32 mlx5_flags)
4243{
4244 u32 flags = 0;
4245
4246 if (mlx5_flags & MLX5_IB_UAPI_FLOW_ACTION_FLAGS_REQUIRE_METADATA)
4247 flags |= MLX5_ACCEL_XFRM_FLAG_REQUIRE_METADATA;
4248
4249 return flags;
4250}
4251
4252#define MLX5_FLOW_ACTION_ESP_CREATE_LAST_SUPPORTED MLX5_IB_UAPI_FLOW_ACTION_FLAGS_REQUIRE_METADATA
4253static struct ib_flow_action *
4254mlx5_ib_create_flow_action_esp(struct ib_device *device,
4255 const struct ib_flow_action_attrs_esp *attr,
4256 struct uverbs_attr_bundle *attrs)
4257{
4258 struct mlx5_ib_dev *mdev = to_mdev(device);
4259 struct ib_uverbs_flow_action_esp_keymat_aes_gcm *aes_gcm;
4260 struct mlx5_accel_esp_xfrm_attrs accel_attrs = {};
4261 struct mlx5_ib_flow_action *action;
4262 u64 action_flags;
4263 u64 flags;
4264 int err = 0;
4265
4266 err = uverbs_get_flags64(
4267 &action_flags, attrs, MLX5_IB_ATTR_CREATE_FLOW_ACTION_FLAGS,
4268 ((MLX5_FLOW_ACTION_ESP_CREATE_LAST_SUPPORTED << 1) - 1));
4269 if (err)
4270 return ERR_PTR(err);
4271
4272 flags = mlx5_ib_flow_action_flags_to_accel_xfrm_flags(action_flags);
4273
4274 /* We current only support a subset of the standard features. Only a
4275 * keymat of type AES_GCM, with icv_len == 16, iv_algo == SEQ and esn
4276 * (with overlap). Full offload mode isn't supported.
4277 */
4278 if (!attr->keymat || attr->replay || attr->encap ||
4279 attr->spi || attr->seq || attr->tfc_pad ||
4280 attr->hard_limit_pkts ||
4281 (attr->flags & ~(IB_FLOW_ACTION_ESP_FLAGS_ESN_TRIGGERED |
4282 IB_UVERBS_FLOW_ACTION_ESP_FLAGS_ENCRYPT)))
4283 return ERR_PTR(-EOPNOTSUPP);
4284
4285 if (attr->keymat->protocol !=
4286 IB_UVERBS_FLOW_ACTION_ESP_KEYMAT_AES_GCM)
4287 return ERR_PTR(-EOPNOTSUPP);
4288
4289 aes_gcm = &attr->keymat->keymat.aes_gcm;
4290
4291 if (aes_gcm->icv_len != 16 ||
4292 aes_gcm->iv_algo != IB_UVERBS_FLOW_ACTION_IV_ALGO_SEQ)
4293 return ERR_PTR(-EOPNOTSUPP);
4294
4295 action = kmalloc(sizeof(*action), GFP_KERNEL);
4296 if (!action)
4297 return ERR_PTR(-ENOMEM);
4298
4299 action->esp_aes_gcm.ib_flags = attr->flags;
4300 memcpy(&accel_attrs.keymat.aes_gcm.aes_key, &aes_gcm->aes_key,
4301 sizeof(accel_attrs.keymat.aes_gcm.aes_key));
4302 accel_attrs.keymat.aes_gcm.key_len = aes_gcm->key_len * 8;
4303 memcpy(&accel_attrs.keymat.aes_gcm.salt, &aes_gcm->salt,
4304 sizeof(accel_attrs.keymat.aes_gcm.salt));
4305 memcpy(&accel_attrs.keymat.aes_gcm.seq_iv, &aes_gcm->iv,
4306 sizeof(accel_attrs.keymat.aes_gcm.seq_iv));
4307 accel_attrs.keymat.aes_gcm.icv_len = aes_gcm->icv_len * 8;
4308 accel_attrs.keymat.aes_gcm.iv_algo = MLX5_ACCEL_ESP_AES_GCM_IV_ALGO_SEQ;
4309 accel_attrs.keymat_type = MLX5_ACCEL_ESP_KEYMAT_AES_GCM;
4310
4311 accel_attrs.esn = attr->esn;
4312 if (attr->flags & IB_FLOW_ACTION_ESP_FLAGS_ESN_TRIGGERED)
4313 accel_attrs.flags |= MLX5_ACCEL_ESP_FLAGS_ESN_TRIGGERED;
4314 if (attr->flags & IB_UVERBS_FLOW_ACTION_ESP_FLAGS_ESN_NEW_WINDOW)
4315 accel_attrs.flags |= MLX5_ACCEL_ESP_FLAGS_ESN_STATE_OVERLAP;
4316
4317 if (attr->flags & IB_UVERBS_FLOW_ACTION_ESP_FLAGS_ENCRYPT)
4318 accel_attrs.action |= MLX5_ACCEL_ESP_ACTION_ENCRYPT;
4319
4320 action->esp_aes_gcm.ctx =
4321 mlx5_accel_esp_create_xfrm(mdev->mdev, &accel_attrs, flags);
4322 if (IS_ERR(action->esp_aes_gcm.ctx)) {
4323 err = PTR_ERR(action->esp_aes_gcm.ctx);
4324 goto err_parse;
4325 }
4326
4327 action->esp_aes_gcm.ib_flags = attr->flags;
4328
4329 return &action->ib_action;
4330
4331err_parse:
4332 kfree(action);
4333 return ERR_PTR(err);
4334}
4335
4336static int
4337mlx5_ib_modify_flow_action_esp(struct ib_flow_action *action,
4338 const struct ib_flow_action_attrs_esp *attr,
4339 struct uverbs_attr_bundle *attrs)
4340{
4341 struct mlx5_ib_flow_action *maction = to_mflow_act(action);
4342 struct mlx5_accel_esp_xfrm_attrs accel_attrs;
4343 int err = 0;
4344
4345 if (attr->keymat || attr->replay || attr->encap ||
4346 attr->spi || attr->seq || attr->tfc_pad ||
4347 attr->hard_limit_pkts ||
4348 (attr->flags & ~(IB_FLOW_ACTION_ESP_FLAGS_ESN_TRIGGERED |
4349 IB_FLOW_ACTION_ESP_FLAGS_MOD_ESP_ATTRS |
4350 IB_UVERBS_FLOW_ACTION_ESP_FLAGS_ESN_NEW_WINDOW)))
4351 return -EOPNOTSUPP;
4352
4353 /* Only the ESN value or the MLX5_ACCEL_ESP_FLAGS_ESN_STATE_OVERLAP can
4354 * be modified.
4355 */
4356 if (!(maction->esp_aes_gcm.ib_flags &
4357 IB_FLOW_ACTION_ESP_FLAGS_ESN_TRIGGERED) &&
4358 attr->flags & (IB_FLOW_ACTION_ESP_FLAGS_ESN_TRIGGERED |
4359 IB_UVERBS_FLOW_ACTION_ESP_FLAGS_ESN_NEW_WINDOW))
4360 return -EINVAL;
4361
4362 memcpy(&accel_attrs, &maction->esp_aes_gcm.ctx->attrs,
4363 sizeof(accel_attrs));
4364
4365 accel_attrs.esn = attr->esn;
4366 if (attr->flags & IB_UVERBS_FLOW_ACTION_ESP_FLAGS_ESN_NEW_WINDOW)
4367 accel_attrs.flags |= MLX5_ACCEL_ESP_FLAGS_ESN_STATE_OVERLAP;
4368 else
4369 accel_attrs.flags &= ~MLX5_ACCEL_ESP_FLAGS_ESN_STATE_OVERLAP;
4370
4371 err = mlx5_accel_esp_modify_xfrm(maction->esp_aes_gcm.ctx,
4372 &accel_attrs);
4373 if (err)
4374 return err;
4375
4376 maction->esp_aes_gcm.ib_flags &=
4377 ~IB_UVERBS_FLOW_ACTION_ESP_FLAGS_ESN_NEW_WINDOW;
4378 maction->esp_aes_gcm.ib_flags |=
4379 attr->flags & IB_UVERBS_FLOW_ACTION_ESP_FLAGS_ESN_NEW_WINDOW;
4380
4381 return 0;
4382}
4383
4384static int mlx5_ib_destroy_flow_action(struct ib_flow_action *action)
4385{
4386 struct mlx5_ib_flow_action *maction = to_mflow_act(action);
4387
4388 switch (action->type) {
4389 case IB_FLOW_ACTION_ESP:
4390 /*
4391 * We only support aes_gcm by now, so we implicitly know this is
4392 * the underline crypto.
4393 */
4394 mlx5_accel_esp_destroy_xfrm(maction->esp_aes_gcm.ctx);
4395 break;
4396 case IB_FLOW_ACTION_UNSPECIFIED:
4397 mlx5_ib_destroy_flow_action_raw(maction);
4398 break;
4399 default:
4400 WARN_ON(true);
4401 break;
4402 }
4403
4404 kfree(maction);
4405 return 0;
4406}
4407
4408static int mlx5_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
4409{
4410 struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
4411 struct mlx5_ib_qp *mqp = to_mqp(ibqp);
4412 int err;
4413 u16 uid;
4414
4415 uid = ibqp->pd ?
4416 to_mpd(ibqp->pd)->uid : 0;
4417
4418 if (mqp->flags & IB_QP_CREATE_SOURCE_QPN) {
4419 mlx5_ib_dbg(dev, "Attaching a multi cast group to underlay QP is not supported\n");
4420 return -EOPNOTSUPP;
4421 }
4422
4423 err = mlx5_cmd_attach_mcg(dev->mdev, gid, ibqp->qp_num, uid);
4424 if (err)
4425 mlx5_ib_warn(dev, "failed attaching QPN 0x%x, MGID %pI6\n",
4426 ibqp->qp_num, gid->raw);
4427
4428 return err;
4429}
4430
4431static int mlx5_ib_mcg_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
4432{
4433 struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
4434 int err;
4435 u16 uid;
4436
4437 uid = ibqp->pd ?
4438 to_mpd(ibqp->pd)->uid : 0;
4439 err = mlx5_cmd_detach_mcg(dev->mdev, gid, ibqp->qp_num, uid);
4440 if (err)
4441 mlx5_ib_warn(dev, "failed detaching QPN 0x%x, MGID %pI6\n",
4442 ibqp->qp_num, gid->raw);
4443
4444 return err;
4445}
4446
4447static int init_node_data(struct mlx5_ib_dev *dev)
4448{
4449 int err;
4450
4451 err = mlx5_query_node_desc(dev, dev->ib_dev.node_desc);
4452 if (err)
4453 return err;
4454
4455 dev->mdev->rev_id = dev->mdev->pdev->revision;
4456
4457 return mlx5_query_node_guid(dev, &dev->ib_dev.node_guid);
4458}
4459
4460static ssize_t fw_pages_show(struct device *device,
4461 struct device_attribute *attr, char *buf)
4462{
4463 struct mlx5_ib_dev *dev =
4464 rdma_device_to_drv_device(device, struct mlx5_ib_dev, ib_dev);
4465
4466 return sprintf(buf, "%d\n", dev->mdev->priv.fw_pages);
4467}
4468static DEVICE_ATTR_RO(fw_pages);
4469
4470static ssize_t reg_pages_show(struct device *device,
4471 struct device_attribute *attr, char *buf)
4472{
4473 struct mlx5_ib_dev *dev =
4474 rdma_device_to_drv_device(device, struct mlx5_ib_dev, ib_dev);
4475
4476 return sprintf(buf, "%d\n", atomic_read(&dev->mdev->priv.reg_pages));
4477}
4478static DEVICE_ATTR_RO(reg_pages);
4479
4480static ssize_t hca_type_show(struct device *device,
4481 struct device_attribute *attr, char *buf)
4482{
4483 struct mlx5_ib_dev *dev =
4484 rdma_device_to_drv_device(device, struct mlx5_ib_dev, ib_dev);
4485
4486 return sprintf(buf, "MT%d\n", dev->mdev->pdev->device);
4487}
4488static DEVICE_ATTR_RO(hca_type);
4489
4490static ssize_t hw_rev_show(struct device *device,
4491 struct device_attribute *attr, char *buf)
4492{
4493 struct mlx5_ib_dev *dev =
4494 rdma_device_to_drv_device(device, struct mlx5_ib_dev, ib_dev);
4495
4496 return sprintf(buf, "%x\n", dev->mdev->rev_id);
4497}
4498static DEVICE_ATTR_RO(hw_rev);
4499
4500static ssize_t board_id_show(struct device *device,
4501 struct device_attribute *attr, char *buf)
4502{
4503 struct mlx5_ib_dev *dev =
4504 rdma_device_to_drv_device(device, struct mlx5_ib_dev, ib_dev);
4505
4506 return sprintf(buf, "%.*s\n", MLX5_BOARD_ID_LEN,
4507 dev->mdev->board_id);
4508}
4509static DEVICE_ATTR_RO(board_id);
4510
4511static struct attribute *mlx5_class_attributes[] = {
4512 &dev_attr_hw_rev.attr,
4513 &dev_attr_hca_type.attr,
4514 &dev_attr_board_id.attr,
4515 &dev_attr_fw_pages.attr,
4516 &dev_attr_reg_pages.attr,
4517 NULL,
4518};
4519
4520static const struct attribute_group mlx5_attr_group = {
4521 .attrs = mlx5_class_attributes,
4522};
4523
4524static void pkey_change_handler(struct work_struct *work)
4525{
4526 struct mlx5_ib_port_resources *ports =
4527 container_of(work, struct mlx5_ib_port_resources,
4528 pkey_change_work);
4529
4530 mutex_lock(&ports->devr->mutex);
4531 mlx5_ib_gsi_pkey_change(ports->gsi);
4532 mutex_unlock(&ports->devr->mutex);
4533}
4534
4535static void mlx5_ib_handle_internal_error(struct mlx5_ib_dev *ibdev)
4536{
4537 struct mlx5_ib_qp *mqp;
4538 struct mlx5_ib_cq *send_mcq, *recv_mcq;
4539 struct mlx5_core_cq *mcq;
4540 struct list_head cq_armed_list;
4541 unsigned long flags_qp;
4542 unsigned long flags_cq;
4543 unsigned long flags;
4544
4545 INIT_LIST_HEAD(&cq_armed_list);
4546
4547 /* Go over qp list reside on that ibdev, sync with create/destroy qp.*/
4548 spin_lock_irqsave(&ibdev->reset_flow_resource_lock, flags);
4549 list_for_each_entry(mqp, &ibdev->qp_list, qps_list) {
4550 spin_lock_irqsave(&mqp->sq.lock, flags_qp);
4551 if (mqp->sq.tail != mqp->sq.head) {
4552 send_mcq = to_mcq(mqp->ibqp.send_cq);
4553 spin_lock_irqsave(&send_mcq->lock, flags_cq);
4554 if (send_mcq->mcq.comp &&
4555 mqp->ibqp.send_cq->comp_handler) {
4556 if (!send_mcq->mcq.reset_notify_added) {
4557 send_mcq->mcq.reset_notify_added = 1;
4558 list_add_tail(&send_mcq->mcq.reset_notify,
4559 &cq_armed_list);
4560 }
4561 }
4562 spin_unlock_irqrestore(&send_mcq->lock, flags_cq);
4563 }
4564 spin_unlock_irqrestore(&mqp->sq.lock, flags_qp);
4565 spin_lock_irqsave(&mqp->rq.lock, flags_qp);
4566 /* no handling is needed for SRQ */
4567 if (!mqp->ibqp.srq) {
4568 if (mqp->rq.tail != mqp->rq.head) {
4569 recv_mcq = to_mcq(mqp->ibqp.recv_cq);
4570 spin_lock_irqsave(&recv_mcq->lock, flags_cq);
4571 if (recv_mcq->mcq.comp &&
4572 mqp->ibqp.recv_cq->comp_handler) {
4573 if (!recv_mcq->mcq.reset_notify_added) {
4574 recv_mcq->mcq.reset_notify_added = 1;
4575 list_add_tail(&recv_mcq->mcq.reset_notify,
4576 &cq_armed_list);
4577 }
4578 }
4579 spin_unlock_irqrestore(&recv_mcq->lock,
4580 flags_cq);
4581 }
4582 }
4583 spin_unlock_irqrestore(&mqp->rq.lock, flags_qp);
4584 }
4585 /*At that point all inflight post send were put to be executed as of we
4586 * lock/unlock above locks Now need to arm all involved CQs.
4587 */
4588 list_for_each_entry(mcq, &cq_armed_list, reset_notify) {
4589 mcq->comp(mcq, NULL);
4590 }
4591 spin_unlock_irqrestore(&ibdev->reset_flow_resource_lock, flags);
4592}
4593
4594static void delay_drop_handler(struct work_struct *work)
4595{
4596 int err;
4597 struct mlx5_ib_delay_drop *delay_drop =
4598 container_of(work, struct mlx5_ib_delay_drop,
4599 delay_drop_work);
4600
4601 atomic_inc(&delay_drop->events_cnt);
4602
4603 mutex_lock(&delay_drop->lock);
4604 err = mlx5_core_set_delay_drop(delay_drop->dev, delay_drop->timeout);
4605 if (err) {
4606 mlx5_ib_warn(delay_drop->dev, "Failed to set delay drop, timeout=%u\n",
4607 delay_drop->timeout);
4608 delay_drop->activate = false;
4609 }
4610 mutex_unlock(&delay_drop->lock);
4611}
4612
4613static void handle_general_event(struct mlx5_ib_dev *ibdev, struct mlx5_eqe *eqe,
4614 struct ib_event *ibev)
4615{
4616 u8 port = (eqe->data.port.port >> 4) & 0xf;
4617
4618 switch (eqe->sub_type) {
4619 case MLX5_GENERAL_SUBTYPE_DELAY_DROP_TIMEOUT:
4620 if (mlx5_ib_port_link_layer(&ibdev->ib_dev, port) ==
4621 IB_LINK_LAYER_ETHERNET)
4622 schedule_work(&ibdev->delay_drop.delay_drop_work);
4623 break;
4624 default: /* do nothing */
4625 return;
4626 }
4627}
4628
4629static int handle_port_change(struct mlx5_ib_dev *ibdev, struct mlx5_eqe *eqe,
4630 struct ib_event *ibev)
4631{
4632 u8 port = (eqe->data.port.port >> 4) & 0xf;
4633
4634 ibev->element.port_num = port;
4635
4636 switch (eqe->sub_type) {
4637 case MLX5_PORT_CHANGE_SUBTYPE_ACTIVE:
4638 case MLX5_PORT_CHANGE_SUBTYPE_DOWN:
4639 case MLX5_PORT_CHANGE_SUBTYPE_INITIALIZED:
4640 /* In RoCE, port up/down events are handled in
4641 * mlx5_netdev_event().
4642 */
4643 if (mlx5_ib_port_link_layer(&ibdev->ib_dev, port) ==
4644 IB_LINK_LAYER_ETHERNET)
4645 return -EINVAL;
4646
4647 ibev->event = (eqe->sub_type == MLX5_PORT_CHANGE_SUBTYPE_ACTIVE) ?
4648 IB_EVENT_PORT_ACTIVE : IB_EVENT_PORT_ERR;
4649 break;
4650
4651 case MLX5_PORT_CHANGE_SUBTYPE_LID:
4652 ibev->event = IB_EVENT_LID_CHANGE;
4653 break;
4654
4655 case MLX5_PORT_CHANGE_SUBTYPE_PKEY:
4656 ibev->event = IB_EVENT_PKEY_CHANGE;
4657 schedule_work(&ibdev->devr.ports[port - 1].pkey_change_work);
4658 break;
4659
4660 case MLX5_PORT_CHANGE_SUBTYPE_GUID:
4661 ibev->event = IB_EVENT_GID_CHANGE;
4662 break;
4663
4664 case MLX5_PORT_CHANGE_SUBTYPE_CLIENT_REREG:
4665 ibev->event = IB_EVENT_CLIENT_REREGISTER;
4666 break;
4667 default:
4668 return -EINVAL;
4669 }
4670
4671 return 0;
4672}
4673
4674static void mlx5_ib_handle_event(struct work_struct *_work)
4675{
4676 struct mlx5_ib_event_work *work =
4677 container_of(_work, struct mlx5_ib_event_work, work);
4678 struct mlx5_ib_dev *ibdev;
4679 struct ib_event ibev;
4680 bool fatal = false;
4681
4682 if (work->is_slave) {
4683 ibdev = mlx5_ib_get_ibdev_from_mpi(work->mpi);
4684 if (!ibdev)
4685 goto out;
4686 } else {
4687 ibdev = work->dev;
4688 }
4689
4690 switch (work->event) {
4691 case MLX5_DEV_EVENT_SYS_ERROR:
4692 ibev.event = IB_EVENT_DEVICE_FATAL;
4693 mlx5_ib_handle_internal_error(ibdev);
4694 ibev.element.port_num = (u8)(unsigned long)work->param;
4695 fatal = true;
4696 break;
4697 case MLX5_EVENT_TYPE_PORT_CHANGE:
4698 if (handle_port_change(ibdev, work->param, &ibev))
4699 goto out;
4700 break;
4701 case MLX5_EVENT_TYPE_GENERAL_EVENT:
4702 handle_general_event(ibdev, work->param, &ibev);
4703 /* fall through */
4704 default:
4705 goto out;
4706 }
4707
4708 ibev.device = &ibdev->ib_dev;
4709
4710 if (!rdma_is_port_valid(&ibdev->ib_dev, ibev.element.port_num)) {
4711 mlx5_ib_warn(ibdev, "warning: event on port %d\n", ibev.element.port_num);
4712 goto out;
4713 }
4714
4715 if (ibdev->ib_active)
4716 ib_dispatch_event(&ibev);
4717
4718 if (fatal)
4719 ibdev->ib_active = false;
4720out:
4721 kfree(work);
4722}
4723
4724static int mlx5_ib_event(struct notifier_block *nb,
4725 unsigned long event, void *param)
4726{
4727 struct mlx5_ib_event_work *work;
4728
4729 work = kmalloc(sizeof(*work), GFP_ATOMIC);
4730 if (!work)
4731 return NOTIFY_DONE;
4732
4733 INIT_WORK(&work->work, mlx5_ib_handle_event);
4734 work->dev = container_of(nb, struct mlx5_ib_dev, mdev_events);
4735 work->is_slave = false;
4736 work->param = param;
4737 work->event = event;
4738
4739 queue_work(mlx5_ib_event_wq, &work->work);
4740
4741 return NOTIFY_OK;
4742}
4743
4744static int mlx5_ib_event_slave_port(struct notifier_block *nb,
4745 unsigned long event, void *param)
4746{
4747 struct mlx5_ib_event_work *work;
4748
4749 work = kmalloc(sizeof(*work), GFP_ATOMIC);
4750 if (!work)
4751 return NOTIFY_DONE;
4752
4753 INIT_WORK(&work->work, mlx5_ib_handle_event);
4754 work->mpi = container_of(nb, struct mlx5_ib_multiport_info, mdev_events);
4755 work->is_slave = true;
4756 work->param = param;
4757 work->event = event;
4758 queue_work(mlx5_ib_event_wq, &work->work);
4759
4760 return NOTIFY_OK;
4761}
4762
4763static int set_has_smi_cap(struct mlx5_ib_dev *dev)
4764{
4765 struct mlx5_hca_vport_context vport_ctx;
4766 int err;
4767 int port;
4768
4769 for (port = 1; port <= ARRAY_SIZE(dev->mdev->port_caps); port++) {
4770 dev->mdev->port_caps[port - 1].has_smi = false;
4771 if (MLX5_CAP_GEN(dev->mdev, port_type) ==
4772 MLX5_CAP_PORT_TYPE_IB) {
4773 if (MLX5_CAP_GEN(dev->mdev, ib_virt)) {
4774 err = mlx5_query_hca_vport_context(dev->mdev, 0,
4775 port, 0,
4776 &vport_ctx);
4777 if (err) {
4778 mlx5_ib_err(dev, "query_hca_vport_context for port=%d failed %d\n",
4779 port, err);
4780 return err;
4781 }
4782 dev->mdev->port_caps[port - 1].has_smi =
4783 vport_ctx.has_smi;
4784 } else {
4785 dev->mdev->port_caps[port - 1].has_smi = true;
4786 }
4787 }
4788 }
4789 return 0;
4790}
4791
4792static void get_ext_port_caps(struct mlx5_ib_dev *dev)
4793{
4794 int port;
4795
4796 for (port = 1; port <= dev->num_ports; port++)
4797 mlx5_query_ext_port_caps(dev, port);
4798}
4799
4800static int __get_port_caps(struct mlx5_ib_dev *dev, u8 port)
4801{
4802 struct ib_device_attr *dprops = NULL;
4803 struct ib_port_attr *pprops = NULL;
4804 int err = -ENOMEM;
4805
4806 pprops = kzalloc(sizeof(*pprops), GFP_KERNEL);
4807 if (!pprops)
4808 goto out;
4809
4810 dprops = kmalloc(sizeof(*dprops), GFP_KERNEL);
4811 if (!dprops)
4812 goto out;
4813
4814 err = mlx5_ib_query_device(&dev->ib_dev, dprops, NULL);
4815 if (err) {
4816 mlx5_ib_warn(dev, "query_device failed %d\n", err);
4817 goto out;
4818 }
4819
4820 err = mlx5_ib_query_port(&dev->ib_dev, port, pprops);
4821 if (err) {
4822 mlx5_ib_warn(dev, "query_port %d failed %d\n",
4823 port, err);
4824 goto out;
4825 }
4826
4827 dev->mdev->port_caps[port - 1].pkey_table_len =
4828 dprops->max_pkeys;
4829 dev->mdev->port_caps[port - 1].gid_table_len =
4830 pprops->gid_tbl_len;
4831 mlx5_ib_dbg(dev, "port %d: pkey_table_len %d, gid_table_len %d\n",
4832 port, dprops->max_pkeys, pprops->gid_tbl_len);
4833
4834out:
4835 kfree(pprops);
4836 kfree(dprops);
4837
4838 return err;
4839}
4840
4841static int get_port_caps(struct mlx5_ib_dev *dev, u8 port)
4842{
4843 /* For representors use port 1, is this is the only native
4844 * port
4845 */
4846 if (dev->is_rep)
4847 return __get_port_caps(dev, 1);
4848 return __get_port_caps(dev, port);
4849}
4850
4851static void destroy_umrc_res(struct mlx5_ib_dev *dev)
4852{
4853 int err;
4854
4855 err = mlx5_mr_cache_cleanup(dev);
4856 if (err)
4857 mlx5_ib_warn(dev, "mr cache cleanup failed\n");
4858
4859 if (dev->umrc.qp)
4860 mlx5_ib_destroy_qp(dev->umrc.qp, NULL);
4861 if (dev->umrc.cq)
4862 ib_free_cq(dev->umrc.cq);
4863 if (dev->umrc.pd)
4864 ib_dealloc_pd(dev->umrc.pd);
4865}
4866
4867enum {
4868 MAX_UMR_WR = 128,
4869};
4870
4871static int create_umr_res(struct mlx5_ib_dev *dev)
4872{
4873 struct ib_qp_init_attr *init_attr = NULL;
4874 struct ib_qp_attr *attr = NULL;
4875 struct ib_pd *pd;
4876 struct ib_cq *cq;
4877 struct ib_qp *qp;
4878 int ret;
4879
4880 attr = kzalloc(sizeof(*attr), GFP_KERNEL);
4881 init_attr = kzalloc(sizeof(*init_attr), GFP_KERNEL);
4882 if (!attr || !init_attr) {
4883 ret = -ENOMEM;
4884 goto error_0;
4885 }
4886
4887 pd = ib_alloc_pd(&dev->ib_dev, 0);
4888 if (IS_ERR(pd)) {
4889 mlx5_ib_dbg(dev, "Couldn't create PD for sync UMR QP\n");
4890 ret = PTR_ERR(pd);
4891 goto error_0;
4892 }
4893
4894 cq = ib_alloc_cq(&dev->ib_dev, NULL, 128, 0, IB_POLL_SOFTIRQ);
4895 if (IS_ERR(cq)) {
4896 mlx5_ib_dbg(dev, "Couldn't create CQ for sync UMR QP\n");
4897 ret = PTR_ERR(cq);
4898 goto error_2;
4899 }
4900
4901 init_attr->send_cq = cq;
4902 init_attr->recv_cq = cq;
4903 init_attr->sq_sig_type = IB_SIGNAL_ALL_WR;
4904 init_attr->cap.max_send_wr = MAX_UMR_WR;
4905 init_attr->cap.max_send_sge = 1;
4906 init_attr->qp_type = MLX5_IB_QPT_REG_UMR;
4907 init_attr->port_num = 1;
4908 qp = mlx5_ib_create_qp(pd, init_attr, NULL);
4909 if (IS_ERR(qp)) {
4910 mlx5_ib_dbg(dev, "Couldn't create sync UMR QP\n");
4911 ret = PTR_ERR(qp);
4912 goto error_3;
4913 }
4914 qp->device = &dev->ib_dev;
4915 qp->real_qp = qp;
4916 qp->uobject = NULL;
4917 qp->qp_type = MLX5_IB_QPT_REG_UMR;
4918 qp->send_cq = init_attr->send_cq;
4919 qp->recv_cq = init_attr->recv_cq;
4920
4921 attr->qp_state = IB_QPS_INIT;
4922 attr->port_num = 1;
4923 ret = mlx5_ib_modify_qp(qp, attr, IB_QP_STATE | IB_QP_PKEY_INDEX |
4924 IB_QP_PORT, NULL);
4925 if (ret) {
4926 mlx5_ib_dbg(dev, "Couldn't modify UMR QP\n");
4927 goto error_4;
4928 }
4929
4930 memset(attr, 0, sizeof(*attr));
4931 attr->qp_state = IB_QPS_RTR;
4932 attr->path_mtu = IB_MTU_256;
4933
4934 ret = mlx5_ib_modify_qp(qp, attr, IB_QP_STATE, NULL);
4935 if (ret) {
4936 mlx5_ib_dbg(dev, "Couldn't modify umr QP to rtr\n");
4937 goto error_4;
4938 }
4939
4940 memset(attr, 0, sizeof(*attr));
4941 attr->qp_state = IB_QPS_RTS;
4942 ret = mlx5_ib_modify_qp(qp, attr, IB_QP_STATE, NULL);
4943 if (ret) {
4944 mlx5_ib_dbg(dev, "Couldn't modify umr QP to rts\n");
4945 goto error_4;
4946 }
4947
4948 dev->umrc.qp = qp;
4949 dev->umrc.cq = cq;
4950 dev->umrc.pd = pd;
4951
4952 sema_init(&dev->umrc.sem, MAX_UMR_WR);
4953 ret = mlx5_mr_cache_init(dev);
4954 if (ret) {
4955 mlx5_ib_warn(dev, "mr cache init failed %d\n", ret);
4956 goto error_4;
4957 }
4958
4959 kfree(attr);
4960 kfree(init_attr);
4961
4962 return 0;
4963
4964error_4:
4965 mlx5_ib_destroy_qp(qp, NULL);
4966 dev->umrc.qp = NULL;
4967
4968error_3:
4969 ib_free_cq(cq);
4970 dev->umrc.cq = NULL;
4971
4972error_2:
4973 ib_dealloc_pd(pd);
4974 dev->umrc.pd = NULL;
4975
4976error_0:
4977 kfree(attr);
4978 kfree(init_attr);
4979 return ret;
4980}
4981
4982static u8 mlx5_get_umr_fence(u8 umr_fence_cap)
4983{
4984 switch (umr_fence_cap) {
4985 case MLX5_CAP_UMR_FENCE_NONE:
4986 return MLX5_FENCE_MODE_NONE;
4987 case MLX5_CAP_UMR_FENCE_SMALL:
4988 return MLX5_FENCE_MODE_INITIATOR_SMALL;
4989 default:
4990 return MLX5_FENCE_MODE_STRONG_ORDERING;
4991 }
4992}
4993
4994static int create_dev_resources(struct mlx5_ib_resources *devr)
4995{
4996 struct ib_srq_init_attr attr;
4997 struct mlx5_ib_dev *dev;
4998 struct ib_device *ibdev;
4999 struct ib_cq_init_attr cq_attr = {.cqe = 1};
5000 int port;
5001 int ret = 0;
5002
5003 dev = container_of(devr, struct mlx5_ib_dev, devr);
5004 ibdev = &dev->ib_dev;
5005
5006 mutex_init(&devr->mutex);
5007
5008 devr->p0 = rdma_zalloc_drv_obj(ibdev, ib_pd);
5009 if (!devr->p0)
5010 return -ENOMEM;
5011
5012 devr->p0->device = ibdev;
5013 devr->p0->uobject = NULL;
5014 atomic_set(&devr->p0->usecnt, 0);
5015
5016 ret = mlx5_ib_alloc_pd(devr->p0, NULL);
5017 if (ret)
5018 goto error0;
5019
5020 devr->c0 = rdma_zalloc_drv_obj(ibdev, ib_cq);
5021 if (!devr->c0) {
5022 ret = -ENOMEM;
5023 goto error1;
5024 }
5025
5026 devr->c0->device = &dev->ib_dev;
5027 atomic_set(&devr->c0->usecnt, 0);
5028
5029 ret = mlx5_ib_create_cq(devr->c0, &cq_attr, NULL);
5030 if (ret)
5031 goto err_create_cq;
5032
5033 devr->x0 = mlx5_ib_alloc_xrcd(&dev->ib_dev, NULL);
5034 if (IS_ERR(devr->x0)) {
5035 ret = PTR_ERR(devr->x0);
5036 goto error2;
5037 }
5038 devr->x0->device = &dev->ib_dev;
5039 devr->x0->inode = NULL;
5040 atomic_set(&devr->x0->usecnt, 0);
5041 mutex_init(&devr->x0->tgt_qp_mutex);
5042 INIT_LIST_HEAD(&devr->x0->tgt_qp_list);
5043
5044 devr->x1 = mlx5_ib_alloc_xrcd(&dev->ib_dev, NULL);
5045 if (IS_ERR(devr->x1)) {
5046 ret = PTR_ERR(devr->x1);
5047 goto error3;
5048 }
5049 devr->x1->device = &dev->ib_dev;
5050 devr->x1->inode = NULL;
5051 atomic_set(&devr->x1->usecnt, 0);
5052 mutex_init(&devr->x1->tgt_qp_mutex);
5053 INIT_LIST_HEAD(&devr->x1->tgt_qp_list);
5054
5055 memset(&attr, 0, sizeof(attr));
5056 attr.attr.max_sge = 1;
5057 attr.attr.max_wr = 1;
5058 attr.srq_type = IB_SRQT_XRC;
5059 attr.ext.cq = devr->c0;
5060 attr.ext.xrc.xrcd = devr->x0;
5061
5062 devr->s0 = rdma_zalloc_drv_obj(ibdev, ib_srq);
5063 if (!devr->s0) {
5064 ret = -ENOMEM;
5065 goto error4;
5066 }
5067
5068 devr->s0->device = &dev->ib_dev;
5069 devr->s0->pd = devr->p0;
5070 devr->s0->srq_type = IB_SRQT_XRC;
5071 devr->s0->ext.xrc.xrcd = devr->x0;
5072 devr->s0->ext.cq = devr->c0;
5073 ret = mlx5_ib_create_srq(devr->s0, &attr, NULL);
5074 if (ret)
5075 goto err_create;
5076
5077 atomic_inc(&devr->s0->ext.xrc.xrcd->usecnt);
5078 atomic_inc(&devr->s0->ext.cq->usecnt);
5079 atomic_inc(&devr->p0->usecnt);
5080 atomic_set(&devr->s0->usecnt, 0);
5081
5082 memset(&attr, 0, sizeof(attr));
5083 attr.attr.max_sge = 1;
5084 attr.attr.max_wr = 1;
5085 attr.srq_type = IB_SRQT_BASIC;
5086 devr->s1 = rdma_zalloc_drv_obj(ibdev, ib_srq);
5087 if (!devr->s1) {
5088 ret = -ENOMEM;
5089 goto error5;
5090 }
5091
5092 devr->s1->device = &dev->ib_dev;
5093 devr->s1->pd = devr->p0;
5094 devr->s1->srq_type = IB_SRQT_BASIC;
5095 devr->s1->ext.cq = devr->c0;
5096
5097 ret = mlx5_ib_create_srq(devr->s1, &attr, NULL);
5098 if (ret)
5099 goto error6;
5100
5101 atomic_inc(&devr->p0->usecnt);
5102 atomic_set(&devr->s1->usecnt, 0);
5103
5104 for (port = 0; port < ARRAY_SIZE(devr->ports); ++port) {
5105 INIT_WORK(&devr->ports[port].pkey_change_work,
5106 pkey_change_handler);
5107 devr->ports[port].devr = devr;
5108 }
5109
5110 return 0;
5111
5112error6:
5113 kfree(devr->s1);
5114error5:
5115 mlx5_ib_destroy_srq(devr->s0, NULL);
5116err_create:
5117 kfree(devr->s0);
5118error4:
5119 mlx5_ib_dealloc_xrcd(devr->x1, NULL);
5120error3:
5121 mlx5_ib_dealloc_xrcd(devr->x0, NULL);
5122error2:
5123 mlx5_ib_destroy_cq(devr->c0, NULL);
5124err_create_cq:
5125 kfree(devr->c0);
5126error1:
5127 mlx5_ib_dealloc_pd(devr->p0, NULL);
5128error0:
5129 kfree(devr->p0);
5130 return ret;
5131}
5132
5133static void destroy_dev_resources(struct mlx5_ib_resources *devr)
5134{
5135 int port;
5136
5137 mlx5_ib_destroy_srq(devr->s1, NULL);
5138 kfree(devr->s1);
5139 mlx5_ib_destroy_srq(devr->s0, NULL);
5140 kfree(devr->s0);
5141 mlx5_ib_dealloc_xrcd(devr->x0, NULL);
5142 mlx5_ib_dealloc_xrcd(devr->x1, NULL);
5143 mlx5_ib_destroy_cq(devr->c0, NULL);
5144 kfree(devr->c0);
5145 mlx5_ib_dealloc_pd(devr->p0, NULL);
5146 kfree(devr->p0);
5147
5148 /* Make sure no change P_Key work items are still executing */
5149 for (port = 0; port < ARRAY_SIZE(devr->ports); ++port)
5150 cancel_work_sync(&devr->ports[port].pkey_change_work);
5151}
5152
5153static u32 get_core_cap_flags(struct ib_device *ibdev,
5154 struct mlx5_hca_vport_context *rep)
5155{
5156 struct mlx5_ib_dev *dev = to_mdev(ibdev);
5157 enum rdma_link_layer ll = mlx5_ib_port_link_layer(ibdev, 1);
5158 u8 l3_type_cap = MLX5_CAP_ROCE(dev->mdev, l3_type);
5159 u8 roce_version_cap = MLX5_CAP_ROCE(dev->mdev, roce_version);
5160 bool raw_support = !mlx5_core_mp_enabled(dev->mdev);
5161 u32 ret = 0;
5162
5163 if (rep->grh_required)
5164 ret |= RDMA_CORE_CAP_IB_GRH_REQUIRED;
5165
5166 if (ll == IB_LINK_LAYER_INFINIBAND)
5167 return ret | RDMA_CORE_PORT_IBA_IB;
5168
5169 if (raw_support)
5170 ret |= RDMA_CORE_PORT_RAW_PACKET;
5171
5172 if (!(l3_type_cap & MLX5_ROCE_L3_TYPE_IPV4_CAP))
5173 return ret;
5174
5175 if (!(l3_type_cap & MLX5_ROCE_L3_TYPE_IPV6_CAP))
5176 return ret;
5177
5178 if (roce_version_cap & MLX5_ROCE_VERSION_1_CAP)
5179 ret |= RDMA_CORE_PORT_IBA_ROCE;
5180
5181 if (roce_version_cap & MLX5_ROCE_VERSION_2_CAP)
5182 ret |= RDMA_CORE_PORT_IBA_ROCE_UDP_ENCAP;
5183
5184 return ret;
5185}
5186
5187static int mlx5_port_immutable(struct ib_device *ibdev, u8 port_num,
5188 struct ib_port_immutable *immutable)
5189{
5190 struct ib_port_attr attr;
5191 struct mlx5_ib_dev *dev = to_mdev(ibdev);
5192 enum rdma_link_layer ll = mlx5_ib_port_link_layer(ibdev, port_num);
5193 struct mlx5_hca_vport_context rep = {0};
5194 int err;
5195
5196 err = ib_query_port(ibdev, port_num, &attr);
5197 if (err)
5198 return err;
5199
5200 if (ll == IB_LINK_LAYER_INFINIBAND) {
5201 err = mlx5_query_hca_vport_context(dev->mdev, 0, port_num, 0,
5202 &rep);
5203 if (err)
5204 return err;
5205 }
5206
5207 immutable->pkey_tbl_len = attr.pkey_tbl_len;
5208 immutable->gid_tbl_len = attr.gid_tbl_len;
5209 immutable->core_cap_flags = get_core_cap_flags(ibdev, &rep);
5210 immutable->max_mad_size = IB_MGMT_MAD_SIZE;
5211
5212 return 0;
5213}
5214
5215static int mlx5_port_rep_immutable(struct ib_device *ibdev, u8 port_num,
5216 struct ib_port_immutable *immutable)
5217{
5218 struct ib_port_attr attr;
5219 int err;
5220
5221 immutable->core_cap_flags = RDMA_CORE_PORT_RAW_PACKET;
5222
5223 err = ib_query_port(ibdev, port_num, &attr);
5224 if (err)
5225 return err;
5226
5227 immutable->pkey_tbl_len = attr.pkey_tbl_len;
5228 immutable->gid_tbl_len = attr.gid_tbl_len;
5229 immutable->core_cap_flags = RDMA_CORE_PORT_RAW_PACKET;
5230
5231 return 0;
5232}
5233
5234static void get_dev_fw_str(struct ib_device *ibdev, char *str)
5235{
5236 struct mlx5_ib_dev *dev =
5237 container_of(ibdev, struct mlx5_ib_dev, ib_dev);
5238 snprintf(str, IB_FW_VERSION_NAME_MAX, "%d.%d.%04d",
5239 fw_rev_maj(dev->mdev), fw_rev_min(dev->mdev),
5240 fw_rev_sub(dev->mdev));
5241}
5242
5243static int mlx5_eth_lag_init(struct mlx5_ib_dev *dev)
5244{
5245 struct mlx5_core_dev *mdev = dev->mdev;
5246 struct mlx5_flow_namespace *ns = mlx5_get_flow_namespace(mdev,
5247 MLX5_FLOW_NAMESPACE_LAG);
5248 struct mlx5_flow_table *ft;
5249 int err;
5250
5251 if (!ns || !mlx5_lag_is_roce(mdev))
5252 return 0;
5253
5254 err = mlx5_cmd_create_vport_lag(mdev);
5255 if (err)
5256 return err;
5257
5258 ft = mlx5_create_lag_demux_flow_table(ns, 0, 0);
5259 if (IS_ERR(ft)) {
5260 err = PTR_ERR(ft);
5261 goto err_destroy_vport_lag;
5262 }
5263
5264 dev->flow_db->lag_demux_ft = ft;
5265 dev->lag_active = true;
5266 return 0;
5267
5268err_destroy_vport_lag:
5269 mlx5_cmd_destroy_vport_lag(mdev);
5270 return err;
5271}
5272
5273static void mlx5_eth_lag_cleanup(struct mlx5_ib_dev *dev)
5274{
5275 struct mlx5_core_dev *mdev = dev->mdev;
5276
5277 if (dev->lag_active) {
5278 dev->lag_active = false;
5279 2920
5280 mlx5_destroy_flow_table(dev->flow_db->lag_demux_ft);2921 work = kmalloc(sizeof(*work), GFP_ATOMIC);
5281 dev->flow_db->lag_demux_ft = NULL;2922 if (!work)
2923 return NOTIFY_DONE;
5282 2924
5283 mlx5_cmd_destroy_vport_lag(mdev);2925 INIT_WORK(&work->work, mlx5_ib_handle_event);
5284 }2926 work->mpi = container_of(nb, struct mlx5_ib_multiport_info, mdev_events);
2927 work->is_slave = true;
2928 work->param = param;
2929 work->event = event;
2930 queue_work(mlx5_ib_event_wq, &work->work);
2931
2932 return NOTIFY_OK;
5285}2933}
5286 2934
5287static int mlx5_add_netdev_notifier(struct mlx5_ib_dev *dev, u8 port_num)2935static int set_has_smi_cap(struct mlx5_ib_dev *dev)
5288{2936{
2937 struct mlx5_hca_vport_context vport_ctx;
5289 int err;2938 int err;
2939 int port;
5290 2940
5291 dev->port[port_num].roce.nb.notifier_call = mlx5_netdev_event;2941 for (port = 1; port <= ARRAY_SIZE(dev->mdev->port_caps); port++) {
5292 err = register_netdevice_notifier(&dev->port[port_num].roce.nb);2942 dev->mdev->port_caps[port - 1].has_smi = false;
5293 if (err) {2943 if (MLX5_CAP_GEN(dev->mdev, port_type) ==
5294 dev->port[port_num].roce.nb.notifier_call = NULL;2944 MLX5_CAP_PORT_TYPE_IB) {
5295 return err;2945 if (MLX5_CAP_GEN(dev->mdev, ib_virt)) {
2946 err = mlx5_query_hca_vport_context(dev->mdev, 0,
2947 port, 0,
2948 &vport_ctx);
2949 if (err) {
2950 mlx5_ib_err(dev, "query_hca_vport_context for port=%d failed %d\n",
2951 port, err);
2952 return err;
2953 }
2954 dev->mdev->port_caps[port - 1].has_smi =
2955 vport_ctx.has_smi;
2956 } else {
2957 dev->mdev->port_caps[port - 1].has_smi = true;
2958 }
2959 }
5296 }2960 }
5297
5298 return 0;2961 return 0;
5299}2962}
5300 2963
5301static void mlx5_remove_netdev_notifier(struct mlx5_ib_dev *dev, u8 port_num)2964static void get_ext_port_caps(struct mlx5_ib_dev *dev)
5302{2965{
5303 if (dev->port[port_num].roce.nb.notifier_call) {2966 int port;
5304 unregister_netdevice_notifier(&dev->port[port_num].roce.nb);2967
5305 dev->port[port_num].roce.nb.notifier_call = NULL;2968 for (port = 1; port <= dev->num_ports; port++)
5306 }2969 mlx5_query_ext_port_caps(dev, port);
5307}2970}
5308 2971
5309static int mlx5_enable_eth(struct mlx5_ib_dev *dev)2972static int __get_port_caps(struct mlx5_ib_dev *dev, u8 port)
5310{2973{
5311 int err;2974 struct ib_device_attr *dprops = NULL;
2975 struct ib_port_attr *pprops = NULL;
2976 int err = -ENOMEM;
5312 2977
5313 err = mlx5_nic_vport_enable_roce(dev->mdev);2978 pprops = kzalloc(sizeof(*pprops), GFP_KERNEL);
5314 if (err)2979 if (!pprops)
5315 return err;2980 goto out;
5316 2981
5317 err = mlx5_eth_lag_init(dev);2982 dprops = kmalloc(sizeof(*dprops), GFP_KERNEL);
5318 if (err)2983 if (!dprops)
5319 goto err_disable_roce;2984 goto out;
5320 2985
5321 return 0;2986 err = mlx5_ib_query_device(&dev->ib_dev, dprops, NULL);
2987 if (err) {
2988 mlx5_ib_warn(dev, "query_device failed %d\n", err);
2989 goto out;
2990 }
5322 2991
5323err_disable_roce:2992 err = mlx5_ib_query_port(&dev->ib_dev, port, pprops);
5324 mlx5_nic_vport_disable_roce(dev->mdev);2993 if (err) {
2994 mlx5_ib_warn(dev, "query_port %d failed %d\n",
2995 port, err);
2996 goto out;
2997 }
2998
2999 dev->mdev->port_caps[port - 1].pkey_table_len =
3000 dprops->max_pkeys;
3001 dev->mdev->port_caps[port - 1].gid_table_len =
3002 pprops->gid_tbl_len;
3003 mlx5_ib_dbg(dev, "port %d: pkey_table_len %d, gid_table_len %d\n",
3004 port, dprops->max_pkeys, pprops->gid_tbl_len);
3005
3006out:
3007 kfree(pprops);
3008 kfree(dprops);
5325 3009
5326 return err;3010 return err;
5327}3011}
5328 3012
5329static void mlx5_disable_eth(struct mlx5_ib_dev *dev)3013static int get_port_caps(struct mlx5_ib_dev *dev, u8 port)
5330{3014{
5331 mlx5_eth_lag_cleanup(dev);3015 /* For representors use port 1, is this is the only native
5332 mlx5_nic_vport_disable_roce(dev->mdev);3016 * port
3017 */
3018 if (dev->is_rep)
3019 return __get_port_caps(dev, 1);
3020 return __get_port_caps(dev, port);
5333}3021}
5334 3022
5335struct mlx5_ib_counter {3023static u8 mlx5_get_umr_fence(u8 umr_fence_cap)
5336 const char *name;3024{
5337 size_t offset;3025 switch (umr_fence_cap) {
5338};3026 case MLX5_CAP_UMR_FENCE_NONE:
5339 3027 return MLX5_FENCE_MODE_NONE;
5340#define INIT_Q_COUNTER(_name) \3028 case MLX5_CAP_UMR_FENCE_SMALL:
5341 { .name = #_name, .offset = MLX5_BYTE_OFF(query_q_counter_out, _name)}3029 return MLX5_FENCE_MODE_INITIATOR_SMALL;
3030 default:
3031 return MLX5_FENCE_MODE_STRONG_ORDERING;
3032 }
3033}
5342 3034
5343static const struct mlx5_ib_counter basic_q_cnts[] = {3035static int mlx5_ib_dev_res_init(struct mlx5_ib_dev *dev)
5344 INIT_Q_COUNTER(rx_write_requests),3036{
5345 INIT_Q_COUNTER(rx_read_requests),3037 struct mlx5_ib_resources *devr = &dev->devr;
5346 INIT_Q_COUNTER(rx_atomic_requests),3038 struct ib_srq_init_attr attr;
5347 INIT_Q_COUNTER(out_of_buffer),3039 struct ib_device *ibdev;
5348};3040 struct ib_cq_init_attr cq_attr = {.cqe = 1};
3041 int port;
3042 int ret = 0;
5349 3043
5350static const struct mlx5_ib_counter out_of_seq_q_cnts[] = {3044 ibdev = &dev->ib_dev;
5351 INIT_Q_COUNTER(out_of_sequence),
5352};
5353 3045
5354static const struct mlx5_ib_counter retrans_q_cnts[] = {3046 if (!MLX5_CAP_GEN(dev->mdev, xrc))
5355 INIT_Q_COUNTER(duplicate_request),3047 return -EOPNOTSUPP;
5356 INIT_Q_COUNTER(rnr_nak_retry_err),
5357 INIT_Q_COUNTER(packet_seq_err),
5358 INIT_Q_COUNTER(implied_nak_seq_err),
5359 INIT_Q_COUNTER(local_ack_timeout_err),
5360};
5361 3048
5362#define INIT_CONG_COUNTER(_name) \3049 mutex_init(&devr->mutex);
5363 { .name = #_name, .offset = \
5364 MLX5_BYTE_OFF(query_cong_statistics_out, _name ## _high)}
5365 3050
5366static const struct mlx5_ib_counter cong_cnts[] = {3051 devr->p0 = rdma_zalloc_drv_obj(ibdev, ib_pd);
5367 INIT_CONG_COUNTER(rp_cnp_ignored),3052 if (!devr->p0)
5368 INIT_CONG_COUNTER(rp_cnp_handled),3053 return -ENOMEM;
5369 INIT_CONG_COUNTER(np_ecn_marked_roce_packets),
5370 INIT_CONG_COUNTER(np_cnp_sent),
5371};
5372 3054
5373static const struct mlx5_ib_counter extended_err_cnts[] = {3055 devr->p0->device = ibdev;
5374 INIT_Q_COUNTER(resp_local_length_error),3056 devr->p0->uobject = NULL;
5375 INIT_Q_COUNTER(resp_cqe_error),3057 atomic_set(&devr->p0->usecnt, 0);
5376 INIT_Q_COUNTER(req_cqe_error),
5377 INIT_Q_COUNTER(req_remote_invalid_request),
5378 INIT_Q_COUNTER(req_remote_access_errors),
5379 INIT_Q_COUNTER(resp_remote_access_errors),
5380 INIT_Q_COUNTER(resp_cqe_flush_error),
5381 INIT_Q_COUNTER(req_cqe_flush_error),
5382};
5383 3058
5384static const struct mlx5_ib_counter roce_accl_cnts[] = {3059 ret = mlx5_ib_alloc_pd(devr->p0, NULL);
5385 INIT_Q_COUNTER(roce_adp_retrans),3060 if (ret)
5386 INIT_Q_COUNTER(roce_adp_retrans_to),3061 goto error0;
5387 INIT_Q_COUNTER(roce_slow_restart),
5388 INIT_Q_COUNTER(roce_slow_restart_cnps),
5389 INIT_Q_COUNTER(roce_slow_restart_trans),
5390};
5391 3062
5392#define INIT_EXT_PPCNT_COUNTER(_name) \3063 devr->c0 = rdma_zalloc_drv_obj(ibdev, ib_cq);
5393 { .name = #_name, .offset = \3064 if (!devr->c0) {
5394 MLX5_BYTE_OFF(ppcnt_reg, \3065 ret = -ENOMEM;
5395 counter_set.eth_extended_cntrs_grp_data_layout._name##_high)}3066 goto error1;
3067 }
5396 3068
5397static const struct mlx5_ib_counter ext_ppcnt_cnts[] = {3069 devr->c0->device = &dev->ib_dev;
5398 INIT_EXT_PPCNT_COUNTER(rx_icrc_encapsulated),3070 atomic_set(&devr->c0->usecnt, 0);
5399};
5400 3071
5401static bool is_mdev_switchdev_mode(const struct mlx5_core_dev *mdev)3072 ret = mlx5_ib_create_cq(devr->c0, &cq_attr, NULL);
5402{3073 if (ret)
5403 return MLX5_ESWITCH_MANAGER(mdev) &&3074 goto err_create_cq;
5404 mlx5_ib_eswitch_mode(mdev->priv.eswitch) ==
5405 MLX5_ESWITCH_OFFLOADS;
5406}
5407 3075
5408static void mlx5_ib_dealloc_counters(struct mlx5_ib_dev *dev)3076 ret = mlx5_cmd_xrcd_alloc(dev->mdev, &devr->xrcdn0, 0);
5409{3077 if (ret)
5410 u32 in[MLX5_ST_SZ_DW(dealloc_q_counter_in)] = {};3078 goto error2;
5411 int num_cnt_ports;
5412 int i;
5413 3079
5414 num_cnt_ports = is_mdev_switchdev_mode(dev->mdev) ? 1 : dev->num_ports;3080 ret = mlx5_cmd_xrcd_alloc(dev->mdev, &devr->xrcdn1, 0);
3081 if (ret)
3082 goto error3;
5415 3083
5416 MLX5_SET(dealloc_q_counter_in, in, opcode,3084 memset(&attr, 0, sizeof(attr));
5417 MLX5_CMD_OP_DEALLOC_Q_COUNTER);3085 attr.attr.max_sge = 1;
3086 attr.attr.max_wr = 1;
3087 attr.srq_type = IB_SRQT_XRC;
3088 attr.ext.cq = devr->c0;
5418 3089
5419 for (i = 0; i < num_cnt_ports; i++) {3090 devr->s0 = rdma_zalloc_drv_obj(ibdev, ib_srq);
5420 if (dev->port[i].cnts.set_id) {3091 if (!devr->s0) {
5421 MLX5_SET(dealloc_q_counter_in, in, counter_set_id,3092 ret = -ENOMEM;
5422 dev->port[i].cnts.set_id);3093 goto error4;
5423 mlx5_cmd_exec_in(dev->mdev, dealloc_q_counter, in);
5424 }
5425 kfree(dev->port[i].cnts.names);
5426 kfree(dev->port[i].cnts.offsets);
5427 }3094 }
5428}
5429
5430static int __mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev,
5431 struct mlx5_ib_counters *cnts)
5432{
5433 u32 num_counters;
5434 3095
5435 num_counters = ARRAY_SIZE(basic_q_cnts);3096 devr->s0->device = &dev->ib_dev;
3097 devr->s0->pd = devr->p0;
3098 devr->s0->srq_type = IB_SRQT_XRC;
3099 devr->s0->ext.cq = devr->c0;
3100 ret = mlx5_ib_create_srq(devr->s0, &attr, NULL);
3101 if (ret)
3102 goto err_create;
5436 3103
5437 if (MLX5_CAP_GEN(dev->mdev, out_of_seq_cnt))3104 atomic_inc(&devr->s0->ext.cq->usecnt);
5438 num_counters += ARRAY_SIZE(out_of_seq_q_cnts);3105 atomic_inc(&devr->p0->usecnt);
3106 atomic_set(&devr->s0->usecnt, 0);
5439 3107
5440 if (MLX5_CAP_GEN(dev->mdev, retransmission_q_counters))3108 memset(&attr, 0, sizeof(attr));
5441 num_counters += ARRAY_SIZE(retrans_q_cnts);3109 attr.attr.max_sge = 1;
3110 attr.attr.max_wr = 1;
3111 attr.srq_type = IB_SRQT_BASIC;
3112 devr->s1 = rdma_zalloc_drv_obj(ibdev, ib_srq);
3113 if (!devr->s1) {
3114 ret = -ENOMEM;
3115 goto error5;
3116 }
5442 3117
5443 if (MLX5_CAP_GEN(dev->mdev, enhanced_error_q_counters))3118 devr->s1->device = &dev->ib_dev;
5444 num_counters += ARRAY_SIZE(extended_err_cnts);3119 devr->s1->pd = devr->p0;
3120 devr->s1->srq_type = IB_SRQT_BASIC;
3121 devr->s1->ext.cq = devr->c0;
5445 3122
5446 if (MLX5_CAP_GEN(dev->mdev, roce_accl))3123 ret = mlx5_ib_create_srq(devr->s1, &attr, NULL);
5447 num_counters += ARRAY_SIZE(roce_accl_cnts);3124 if (ret)
3125 goto error6;
5448 3126
5449 cnts->num_q_counters = num_counters;3127 atomic_inc(&devr->p0->usecnt);
3128 atomic_set(&devr->s1->usecnt, 0);
5450 3129
5451 if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) {3130 for (port = 0; port < ARRAY_SIZE(devr->ports); ++port) {
5452 cnts->num_cong_counters = ARRAY_SIZE(cong_cnts);3131 INIT_WORK(&devr->ports[port].pkey_change_work,
5453 num_counters += ARRAY_SIZE(cong_cnts);3132 pkey_change_handler);
5454 }3133 devr->ports[port].devr = devr;
5455 if (MLX5_CAP_PCAM_FEATURE(dev->mdev, rx_icrc_encapsulated_counter)) {
5456 cnts->num_ext_ppcnt_counters = ARRAY_SIZE(ext_ppcnt_cnts);
5457 num_counters += ARRAY_SIZE(ext_ppcnt_cnts);
5458 }3134 }
5459 cnts->names = kcalloc(num_counters, sizeof(cnts->names), GFP_KERNEL);
5460 if (!cnts->names)
5461 return -ENOMEM;
5462
5463 cnts->offsets = kcalloc(num_counters,
5464 sizeof(cnts->offsets), GFP_KERNEL);
5465 if (!cnts->offsets)
5466 goto err_names;
5467 3135
5468 return 0;3136 return 0;
5469 3137
5470err_names:3138error6:
5471 kfree(cnts->names);3139 kfree(devr->s1);
5472 cnts->names = NULL;3140error5:
5473 return -ENOMEM;3141 mlx5_ib_destroy_srq(devr->s0, NULL);
3142err_create:
3143 kfree(devr->s0);
3144error4:
3145 mlx5_cmd_xrcd_dealloc(dev->mdev, devr->xrcdn1, 0);
3146error3:
3147 mlx5_cmd_xrcd_dealloc(dev->mdev, devr->xrcdn0, 0);
3148error2:
3149 mlx5_ib_destroy_cq(devr->c0, NULL);
3150err_create_cq:
3151 kfree(devr->c0);
3152error1:
3153 mlx5_ib_dealloc_pd(devr->p0, NULL);
3154error0:
3155 kfree(devr->p0);
3156 return ret;
5474}3157}
5475 3158
5476static void mlx5_ib_fill_counters(struct mlx5_ib_dev *dev,3159static void mlx5_ib_dev_res_cleanup(struct mlx5_ib_dev *dev)
5477 const char **names,
5478 size_t *offsets)
5479{3160{
5480 int i;3161 struct mlx5_ib_resources *devr = &dev->devr;
5481 int j = 0;3162 int port;
5482
5483 for (i = 0; i < ARRAY_SIZE(basic_q_cnts); i++, j++) {
5484 names[j] = basic_q_cnts[i].name;
5485 offsets[j] = basic_q_cnts[i].offset;
5486 }
5487
5488 if (MLX5_CAP_GEN(dev->mdev, out_of_seq_cnt)) {
5489 for (i = 0; i < ARRAY_SIZE(out_of_seq_q_cnts); i++, j++) {
5490 names[j] = out_of_seq_q_cnts[i].name;
5491 offsets[j] = out_of_seq_q_cnts[i].offset;
5492 }
5493 }
5494
5495 if (MLX5_CAP_GEN(dev->mdev, retransmission_q_counters)) {
5496 for (i = 0; i < ARRAY_SIZE(retrans_q_cnts); i++, j++) {
5497 names[j] = retrans_q_cnts[i].name;
5498 offsets[j] = retrans_q_cnts[i].offset;
5499 }
5500 }
5501
5502 if (MLX5_CAP_GEN(dev->mdev, enhanced_error_q_counters)) {
5503 for (i = 0; i < ARRAY_SIZE(extended_err_cnts); i++, j++) {
5504 names[j] = extended_err_cnts[i].name;
5505 offsets[j] = extended_err_cnts[i].offset;
5506 }
5507 }
5508
5509 if (MLX5_CAP_GEN(dev->mdev, roce_accl)) {
5510 for (i = 0; i < ARRAY_SIZE(roce_accl_cnts); i++, j++) {
5511 names[j] = roce_accl_cnts[i].name;
5512 offsets[j] = roce_accl_cnts[i].offset;
5513 }
5514 }
5515 3163
5516 if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) {3164 mlx5_ib_destroy_srq(devr->s1, NULL);
5517 for (i = 0; i < ARRAY_SIZE(cong_cnts); i++, j++) {3165 kfree(devr->s1);
5518 names[j] = cong_cnts[i].name;3166 mlx5_ib_destroy_srq(devr->s0, NULL);
5519 offsets[j] = cong_cnts[i].offset;3167 kfree(devr->s0);
5520 }3168 mlx5_cmd_xrcd_dealloc(dev->mdev, devr->xrcdn1, 0);
5521 }3169 mlx5_cmd_xrcd_dealloc(dev->mdev, devr->xrcdn0, 0);
3170 mlx5_ib_destroy_cq(devr->c0, NULL);
3171 kfree(devr->c0);
3172 mlx5_ib_dealloc_pd(devr->p0, NULL);
3173 kfree(devr->p0);
5522 3174
5523 if (MLX5_CAP_PCAM_FEATURE(dev->mdev, rx_icrc_encapsulated_counter)) {3175 /* Make sure no change P_Key work items are still executing */
5524 for (i = 0; i < ARRAY_SIZE(ext_ppcnt_cnts); i++, j++) {3176 for (port = 0; port < ARRAY_SIZE(devr->ports); ++port)
5525 names[j] = ext_ppcnt_cnts[i].name;3177 cancel_work_sync(&devr->ports[port].pkey_change_work);
5526 offsets[j] = ext_ppcnt_cnts[i].offset;
5527 }
5528 }
5529}3178}
5530 3179
5531static int mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev)3180static u32 get_core_cap_flags(struct ib_device *ibdev,
3181 struct mlx5_hca_vport_context *rep)
5532{3182{
5533 u32 out[MLX5_ST_SZ_DW(alloc_q_counter_out)] = {};3183 struct mlx5_ib_dev *dev = to_mdev(ibdev);
5534 u32 in[MLX5_ST_SZ_DW(alloc_q_counter_in)] = {};3184 enum rdma_link_layer ll = mlx5_ib_port_link_layer(ibdev, 1);
5535 int num_cnt_ports;3185 u8 l3_type_cap = MLX5_CAP_ROCE(dev->mdev, l3_type);
5536 int err = 0;3186 u8 roce_version_cap = MLX5_CAP_ROCE(dev->mdev, roce_version);
5537 int i;3187 bool raw_support = !mlx5_core_mp_enabled(dev->mdev);
5538 bool is_shared;3188 u32 ret = 0;
5539
5540 MLX5_SET(alloc_q_counter_in, in, opcode, MLX5_CMD_OP_ALLOC_Q_COUNTER);
5541 is_shared = MLX5_CAP_GEN(dev->mdev, log_max_uctx) != 0;
5542 num_cnt_ports = is_mdev_switchdev_mode(dev->mdev) ? 1 : dev->num_ports;
5543
5544 for (i = 0; i < num_cnt_ports; i++) {
5545 err = __mlx5_ib_alloc_counters(dev, &dev->port[i].cnts);
5546 if (err)
5547 goto err_alloc;
5548 3189
5549 mlx5_ib_fill_counters(dev, dev->port[i].cnts.names,3190 if (rep->grh_required)
5550 dev->port[i].cnts.offsets);3191 ret |= RDMA_CORE_CAP_IB_GRH_REQUIRED;
5551 3192
5552 MLX5_SET(alloc_q_counter_in, in, uid,3193 if (ll == IB_LINK_LAYER_INFINIBAND)
5553 is_shared ? MLX5_SHARED_RESOURCE_UID : 0);3194 return ret | RDMA_CORE_PORT_IBA_IB;
5554 3195
5555 err = mlx5_cmd_exec_inout(dev->mdev, alloc_q_counter, in, out);3196 if (raw_support)
5556 if (err) {3197 ret |= RDMA_CORE_PORT_RAW_PACKET;
5557 mlx5_ib_warn(dev,
5558 "couldn't allocate queue counter for port %d, err %d\n",
5559 i + 1, err);
5560 goto err_alloc;
5561 }
5562 3198
5563 dev->port[i].cnts.set_id =3199 if (!(l3_type_cap & MLX5_ROCE_L3_TYPE_IPV4_CAP))
5564 MLX5_GET(alloc_q_counter_out, out, counter_set_id);3200 return ret;
5565 }
5566 return 0;
5567 3201
5568err_alloc:3202 if (!(l3_type_cap & MLX5_ROCE_L3_TYPE_IPV6_CAP))
5569 mlx5_ib_dealloc_counters(dev);3203 return ret;
5570 return err;
5571}
5572 3204
5573static const struct mlx5_ib_counters *get_counters(struct mlx5_ib_dev *dev,3205 if (roce_version_cap & MLX5_ROCE_VERSION_1_CAP)
5574 u8 port_num)3206 ret |= RDMA_CORE_PORT_IBA_ROCE;
5575{
5576 return is_mdev_switchdev_mode(dev->mdev) ? &dev->port[0].cnts :
5577 &dev->port[port_num].cnts;
5578}
5579 3207
5580/**3208 if (roce_version_cap & MLX5_ROCE_VERSION_2_CAP)
5581 * mlx5_ib_get_counters_id - Returns counters id to use for device+port3209 ret |= RDMA_CORE_PORT_IBA_ROCE_UDP_ENCAP;
5582 * @dev: Pointer to mlx5 IB device
5583 * @port_num: Zero based port number
5584 *
5585 * mlx5_ib_get_counters_id() Returns counters set id to use for given
5586 * device port combination in switchdev and non switchdev mode of the
5587 * parent device.
5588 */
5589u16 mlx5_ib_get_counters_id(struct mlx5_ib_dev *dev, u8 port_num)
5590{
5591 const struct mlx5_ib_counters *cnts = get_counters(dev, port_num);
5592 3210
5593 return cnts->set_id;3211 return ret;
5594}3212}
5595 3213
5596static struct rdma_hw_stats *mlx5_ib_alloc_hw_stats(struct ib_device *ibdev,3214static int mlx5_port_immutable(struct ib_device *ibdev, u8 port_num,
5597 u8 port_num)3215 struct ib_port_immutable *immutable)
5598{3216{
3217 struct ib_port_attr attr;
5599 struct mlx5_ib_dev *dev = to_mdev(ibdev);3218 struct mlx5_ib_dev *dev = to_mdev(ibdev);
5600 const struct mlx5_ib_counters *cnts;3219 enum rdma_link_layer ll = mlx5_ib_port_link_layer(ibdev, port_num);
5601 bool is_switchdev = is_mdev_switchdev_mode(dev->mdev);3220 struct mlx5_hca_vport_context rep = {0};
3221 int err;
5602 3222
5603 if ((is_switchdev && port_num) || (!is_switchdev && !port_num))3223 err = ib_query_port(ibdev, port_num, &attr);
5604 return NULL;3224 if (err)
3225 return err;
3226
3227 if (ll == IB_LINK_LAYER_INFINIBAND) {
3228 err = mlx5_query_hca_vport_context(dev->mdev, 0, port_num, 0,
3229 &rep);
3230 if (err)
3231 return err;
3232 }
5605 3233
5606 cnts = get_counters(dev, port_num - 1);3234 immutable->pkey_tbl_len = attr.pkey_tbl_len;
3235 immutable->gid_tbl_len = attr.gid_tbl_len;
3236 immutable->core_cap_flags = get_core_cap_flags(ibdev, &rep);
3237 immutable->max_mad_size = IB_MGMT_MAD_SIZE;
5607 3238
5608 return rdma_alloc_hw_stats_struct(cnts->names,3239 return 0;
5609 cnts->num_q_counters +
5610 cnts->num_cong_counters +
5611 cnts->num_ext_ppcnt_counters,
5612 RDMA_HW_STATS_DEFAULT_LIFESPAN);
5613}3240}
5614 3241
5615static int mlx5_ib_query_q_counters(struct mlx5_core_dev *mdev,3242static int mlx5_port_rep_immutable(struct ib_device *ibdev, u8 port_num,
5616 const struct mlx5_ib_counters *cnts,3243 struct ib_port_immutable *immutable)
5617 struct rdma_hw_stats *stats,
5618 u16 set_id)
5619{3244{
5620 u32 out[MLX5_ST_SZ_DW(query_q_counter_out)] = {};3245 struct ib_port_attr attr;
5621 u32 in[MLX5_ST_SZ_DW(query_q_counter_in)] = {};3246 int err;
5622 __be32 val;
5623 int ret, i;
5624 3247
5625 MLX5_SET(query_q_counter_in, in, opcode, MLX5_CMD_OP_QUERY_Q_COUNTER);3248 immutable->core_cap_flags = RDMA_CORE_PORT_RAW_PACKET;
5626 MLX5_SET(query_q_counter_in, in, counter_set_id, set_id);
5627 ret = mlx5_cmd_exec_inout(mdev, query_q_counter, in, out);
5628 if (ret)
5629 return ret;
5630 3249
5631 for (i = 0; i < cnts->num_q_counters; i++) {3250 err = ib_query_port(ibdev, port_num, &attr);
5632 val = *(__be32 *)((void *)out + cnts->offsets[i]);3251 if (err)
5633 stats->value[i] = (u64)be32_to_cpu(val);3252 return err;
5634 }3253
3254 immutable->pkey_tbl_len = attr.pkey_tbl_len;
3255 immutable->gid_tbl_len = attr.gid_tbl_len;
3256 immutable->core_cap_flags = RDMA_CORE_PORT_RAW_PACKET;
5635 3257
5636 return 0;3258 return 0;
5637}3259}
5638 3260
5639static int mlx5_ib_query_ext_ppcnt_counters(struct mlx5_ib_dev *dev,3261static void get_dev_fw_str(struct ib_device *ibdev, char *str)
5640 const struct mlx5_ib_counters *cnts,
5641 struct rdma_hw_stats *stats)
5642{3262{
5643 int offset = cnts->num_q_counters + cnts->num_cong_counters;3263 struct mlx5_ib_dev *dev =
5644 int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);3264 container_of(ibdev, struct mlx5_ib_dev, ib_dev);
5645 int ret, i;3265 snprintf(str, IB_FW_VERSION_NAME_MAX, "%d.%d.%04d",
5646 void *out;3266 fw_rev_maj(dev->mdev), fw_rev_min(dev->mdev),
5647 3267 fw_rev_sub(dev->mdev));
5648 out = kvzalloc(sz, GFP_KERNEL);
5649 if (!out)
5650 return -ENOMEM;
5651
5652 ret = mlx5_cmd_query_ext_ppcnt_counters(dev->mdev, out);
5653 if (ret)
5654 goto free;
5655
5656 for (i = 0; i < cnts->num_ext_ppcnt_counters; i++)
5657 stats->value[i + offset] =
5658 be64_to_cpup((__be64 *)(out +
5659 cnts->offsets[i + offset]));
5660free:
5661 kvfree(out);
5662 return ret;
5663}3268}
5664 3269
5665static int mlx5_ib_get_hw_stats(struct ib_device *ibdev,3270static int mlx5_eth_lag_init(struct mlx5_ib_dev *dev)
5666 struct rdma_hw_stats *stats,
5667 u8 port_num, int index)
5668{3271{
5669 struct mlx5_ib_dev *dev = to_mdev(ibdev);3272 struct mlx5_core_dev *mdev = dev->mdev;
5670 const struct mlx5_ib_counters *cnts = get_counters(dev, port_num - 1);3273 struct mlx5_flow_namespace *ns = mlx5_get_flow_namespace(mdev,
5671 struct mlx5_core_dev *mdev;3274 MLX5_FLOW_NAMESPACE_LAG);
5672 int ret, num_counters;3275 struct mlx5_flow_table *ft;
5673 u8 mdev_port_num;3276 int err;
5674
5675 if (!stats)
5676 return -EINVAL;
5677 3277
5678 num_counters = cnts->num_q_counters +3278 if (!ns || !mlx5_lag_is_roce(mdev))
5679 cnts->num_cong_counters +3279 return 0;
5680 cnts->num_ext_ppcnt_counters;
5681 3280
5682 /* q_counters are per IB device, query the master mdev */3281 err = mlx5_cmd_create_vport_lag(mdev);
5683 ret = mlx5_ib_query_q_counters(dev->mdev, cnts, stats, cnts->set_id);3282 if (err)
5684 if (ret)3283 return err;
5685 return ret;
5686 3284
5687 if (MLX5_CAP_PCAM_FEATURE(dev->mdev, rx_icrc_encapsulated_counter)) {3285 ft = mlx5_create_lag_demux_flow_table(ns, 0, 0);
5688 ret = mlx5_ib_query_ext_ppcnt_counters(dev, cnts, stats);3286 if (IS_ERR(ft)) {
5689 if (ret)3287 err = PTR_ERR(ft);
5690 return ret;3288 goto err_destroy_vport_lag;
5691 }3289 }
5692 3290
5693 if (MLX5_CAP_GEN(dev->mdev, cc_query_allowed)) {3291 dev->flow_db->lag_demux_ft = ft;
5694 mdev = mlx5_ib_get_native_port_mdev(dev, port_num,3292 dev->lag_active = true;
5695 &mdev_port_num);3293 return 0;
5696 if (!mdev) {
5697 /* If port is not affiliated yet, its in down state
5698 * which doesn't have any counters yet, so it would be
5699 * zero. So no need to read from the HCA.
5700 */
5701 goto done;
5702 }
5703 ret = mlx5_lag_query_cong_counters(dev->mdev,
5704 stats->value +
5705 cnts->num_q_counters,
5706 cnts->num_cong_counters,
5707 cnts->offsets +
5708 cnts->num_q_counters);
5709
5710 mlx5_ib_put_native_port_mdev(dev, port_num);
5711 if (ret)
5712 return ret;
5713 }
5714 3294
5715done:3295err_destroy_vport_lag:
5716 return num_counters;3296 mlx5_cmd_destroy_vport_lag(mdev);
3297 return err;
5717}3298}
5718 3299
5719static struct rdma_hw_stats *3300static void mlx5_eth_lag_cleanup(struct mlx5_ib_dev *dev)
5720mlx5_ib_counter_alloc_stats(struct rdma_counter *counter)
5721{3301{
5722 struct mlx5_ib_dev *dev = to_mdev(counter->device);3302 struct mlx5_core_dev *mdev = dev->mdev;
5723 const struct mlx5_ib_counters *cnts =
5724 get_counters(dev, counter->port - 1);
5725 3303
5726 return rdma_alloc_hw_stats_struct(cnts->names,3304 if (dev->lag_active) {
5727 cnts->num_q_counters +3305 dev->lag_active = false;
5728 cnts->num_cong_counters +
5729 cnts->num_ext_ppcnt_counters,
5730 RDMA_HW_STATS_DEFAULT_LIFESPAN);
5731}
5732 3306
5733static int mlx5_ib_counter_update_stats(struct rdma_counter *counter)3307 mlx5_destroy_flow_table(dev->flow_db->lag_demux_ft);
5734{3308 dev->flow_db->lag_demux_ft = NULL;
5735 struct mlx5_ib_dev *dev = to_mdev(counter->device);
5736 const struct mlx5_ib_counters *cnts =
5737 get_counters(dev, counter->port - 1);
5738 3309
5739 return mlx5_ib_query_q_counters(dev->mdev, cnts,3310 mlx5_cmd_destroy_vport_lag(mdev);
5740 counter->stats, counter->id);3311 }
5741}3312}
5742 3313
5743static int mlx5_ib_counter_dealloc(struct rdma_counter *counter)3314static int mlx5_add_netdev_notifier(struct mlx5_ib_dev *dev, u8 port_num)
5744{3315{
5745 struct mlx5_ib_dev *dev = to_mdev(counter->device);3316 int err;
5746 u32 in[MLX5_ST_SZ_DW(dealloc_q_counter_in)] = {};
5747 3317
5748 if (!counter->id)3318 dev->port[port_num].roce.nb.notifier_call = mlx5_netdev_event;
5749 return 0;3319 err = register_netdevice_notifier(&dev->port[port_num].roce.nb);
3320 if (err) {
3321 dev->port[port_num].roce.nb.notifier_call = NULL;
3322 return err;
3323 }
5750 3324
5751 MLX5_SET(dealloc_q_counter_in, in, opcode,3325 return 0;
5752 MLX5_CMD_OP_DEALLOC_Q_COUNTER);
5753 MLX5_SET(dealloc_q_counter_in, in, counter_set_id, counter->id);
5754 return mlx5_cmd_exec_in(dev->mdev, dealloc_q_counter, in);
5755}3326}
5756 3327
5757static int mlx5_ib_counter_bind_qp(struct rdma_counter *counter,3328static void mlx5_remove_netdev_notifier(struct mlx5_ib_dev *dev, u8 port_num)
5758 struct ib_qp *qp)
5759{3329{
5760 struct mlx5_ib_dev *dev = to_mdev(qp->device);3330 if (dev->port[port_num].roce.nb.notifier_call) {
5761 int err;3331 unregister_netdevice_notifier(&dev->port[port_num].roce.nb);
3332 dev->port[port_num].roce.nb.notifier_call = NULL;
3333 }
3334}
5762 3335
5763 if (!counter->id) {3336static int mlx5_enable_eth(struct mlx5_ib_dev *dev)
5764 u32 out[MLX5_ST_SZ_DW(alloc_q_counter_out)] = {};3337{
5765 u32 in[MLX5_ST_SZ_DW(alloc_q_counter_in)] = {};3338 int err;
5766 3339
5767 MLX5_SET(alloc_q_counter_in, in, opcode,3340 err = mlx5_nic_vport_enable_roce(dev->mdev);
5768 MLX5_CMD_OP_ALLOC_Q_COUNTER);3341 if (err)
5769 MLX5_SET(alloc_q_counter_in, in, uid, MLX5_SHARED_RESOURCE_UID);3342 return err;
5770 err = mlx5_cmd_exec_inout(dev->mdev, alloc_q_counter, in, out);
5771 if (err)
5772 return err;
5773 counter->id =
5774 MLX5_GET(alloc_q_counter_out, out, counter_set_id);
5775 }
5776 3343
5777 err = mlx5_ib_qp_set_counter(qp, counter);3344 err = mlx5_eth_lag_init(dev);
5778 if (err)3345 if (err)
5779 goto fail_set_counter;3346 goto err_disable_roce;
5780 3347
5781 return 0;3348 return 0;
5782 3349
5783fail_set_counter:3350err_disable_roce:
5784 mlx5_ib_counter_dealloc(counter);3351 mlx5_nic_vport_disable_roce(dev->mdev);
5785 counter->id = 0;
5786 3352
5787 return err;3353 return err;
5788}3354}
5789 3355
5790static int mlx5_ib_counter_unbind_qp(struct ib_qp *qp)3356static void mlx5_disable_eth(struct mlx5_ib_dev *dev)
5791{3357{
5792 return mlx5_ib_qp_set_counter(qp, NULL);3358 mlx5_eth_lag_cleanup(dev);
3359 mlx5_nic_vport_disable_roce(dev->mdev);
5793}3360}
5794 3361
5795static int mlx5_ib_rn_get_params(struct ib_device *device, u8 port_num,3362static int mlx5_ib_rn_get_params(struct ib_device *device, u8 port_num,
@@ -5802,23 +3369,6 @@ static int mlx5_ib_rn_get_params(struct ib_device *device, u8 port_num, · 6 unmodified lines
5802 return mlx5_rdma_rn_get_params(to_mdev(device)->mdev, device, params);3369 return mlx5_rdma_rn_get_params(to_mdev(device)->mdev, device, params);
5803}3370}
5804 3371
5805static void delay_drop_debugfs_cleanup(struct mlx5_ib_dev *dev)
5806{
5807 if (!dev->delay_drop.dir_debugfs)
5808 return;
5809 debugfs_remove_recursive(dev->delay_drop.dir_debugfs);
5810 dev->delay_drop.dir_debugfs = NULL;
5811}
5812
5813static void cancel_delay_drop(struct mlx5_ib_dev *dev)
5814{
5815 if (!(dev->ib_dev.attrs.raw_packet_caps & IB_RAW_PACKET_CAP_DELAY_DROP))
5816 return;
5817
5818 cancel_work_sync(&dev->delay_drop.delay_drop_work);
5819 delay_drop_debugfs_cleanup(dev);
5820}
5821
5822static ssize_t delay_drop_timeout_read(struct file *filp, char __user *buf,3372static ssize_t delay_drop_timeout_read(struct file *filp, char __user *buf,
5823 size_t count, loff_t *pos)3373 size_t count, loff_t *pos)
5824{3374{
@@ -5858,40 +3408,6 @@ static const struct file_operations fops_delay_drop_timeout = { · 33 unmodified lines
5858 .read = delay_drop_timeout_read,3408 .read = delay_drop_timeout_read,
5859};3409};
5860 3410
5861static void delay_drop_debugfs_init(struct mlx5_ib_dev *dev)
5862{
5863 struct dentry *root;
5864
5865 if (!mlx5_debugfs_root)
5866 return;
5867
5868 root = debugfs_create_dir("delay_drop", dev->mdev->priv.dbg_root);
5869 dev->delay_drop.dir_debugfs = root;
5870
5871 debugfs_create_atomic_t("num_timeout_events", 0400, root,
5872 &dev->delay_drop.events_cnt);
5873 debugfs_create_atomic_t("num_rqs", 0400, root,
5874 &dev->delay_drop.rqs_cnt);
5875 debugfs_create_file("timeout", 0600, root, &dev->delay_drop,
5876 &fops_delay_drop_timeout);
5877}
5878
5879static void init_delay_drop(struct mlx5_ib_dev *dev)
5880{
5881 if (!(dev->ib_dev.attrs.raw_packet_caps & IB_RAW_PACKET_CAP_DELAY_DROP))
5882 return;
5883
5884 mutex_init(&dev->delay_drop.lock);
5885 dev->delay_drop.dev = dev;
5886 dev->delay_drop.activate = false;
5887 dev->delay_drop.timeout = MLX5_MAX_DELAY_DROP_TIMEOUT_MS * 1000;
5888 INIT_WORK(&dev->delay_drop.delay_drop_work, delay_drop_handler);
5889 atomic_set(&dev->delay_drop.rqs_cnt, 0);
5890 atomic_set(&dev->delay_drop.events_cnt, 0);
5891
5892 delay_drop_debugfs_init(dev);
5893}
5894
5895static void mlx5_ib_unbind_slave_port(struct mlx5_ib_dev *ibdev,3411static void mlx5_ib_unbind_slave_port(struct mlx5_ib_dev *ibdev,
5896 struct mlx5_ib_multiport_info *mpi)3412 struct mlx5_ib_multiport_info *mpi)
5897{3413{
@@ -6385,90 +3901,32 @@ ADD_UVERBS_ATTRIBUTES_SIMPLE( · 487 unmodified lines
6385 UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_CREATE_FLOW_ACTION_FLAGS,3901 UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_CREATE_FLOW_ACTION_FLAGS,
6386 enum mlx5_ib_uapi_flow_action_flags));3902 enum mlx5_ib_uapi_flow_action_flags));
6387 3903
3904ADD_UVERBS_ATTRIBUTES_SIMPLE(
3905 mlx5_ib_query_context,
3906 UVERBS_OBJECT_DEVICE,
3907 UVERBS_METHOD_QUERY_CONTEXT,
3908 UVERBS_ATTR_PTR_OUT(
3909 MLX5_IB_ATTR_QUERY_CONTEXT_RESP_UCTX,
3910 UVERBS_ATTR_STRUCT(struct mlx5_ib_alloc_ucontext_resp,
3911 dump_fill_mkey),
3912 UA_MANDATORY));
3913
6388static const struct uapi_definition mlx5_ib_defs[] = {3914static const struct uapi_definition mlx5_ib_defs[] = {
6389 UAPI_DEF_CHAIN(mlx5_ib_devx_defs),3915 UAPI_DEF_CHAIN(mlx5_ib_devx_defs),
6390 UAPI_DEF_CHAIN(mlx5_ib_flow_defs),3916 UAPI_DEF_CHAIN(mlx5_ib_flow_defs),
6391 UAPI_DEF_CHAIN(mlx5_ib_qos_defs),3917 UAPI_DEF_CHAIN(mlx5_ib_qos_defs),
3918 UAPI_DEF_CHAIN(mlx5_ib_std_types_defs),
6392 3919
6393 UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_FLOW_ACTION,3920 UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_FLOW_ACTION,
6394 &mlx5_ib_flow_action),3921 &mlx5_ib_flow_action),
6395 UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_DM, &mlx5_ib_dm),3922 UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_DM, &mlx5_ib_dm),
3923 UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_DEVICE, &mlx5_ib_query_context),
6396 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(MLX5_IB_OBJECT_VAR,3924 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(MLX5_IB_OBJECT_VAR,
6397 UAPI_DEF_IS_OBJ_SUPPORTED(var_is_supported)),3925 UAPI_DEF_IS_OBJ_SUPPORTED(var_is_supported)),
6398 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(MLX5_IB_OBJECT_UAR),3926 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(MLX5_IB_OBJECT_UAR),
6399 {}3927 {}
6400};3928};
6401 3929
6402static int mlx5_ib_read_counters(struct ib_counters *counters,
6403 struct ib_counters_read_attr *read_attr,
6404 struct uverbs_attr_bundle *attrs)
6405{
6406 struct mlx5_ib_mcounters *mcounters = to_mcounters(counters);
6407 struct mlx5_read_counters_attr mread_attr = {};
6408 struct mlx5_ib_flow_counters_desc *desc;
6409 int ret, i;
6410
6411 mutex_lock(&mcounters->mcntrs_mutex);
6412 if (mcounters->cntrs_max_index > read_attr->ncounters) {
6413 ret = -EINVAL;
6414 goto err_bound;
6415 }
6416
6417 mread_attr.out = kcalloc(mcounters->counters_num, sizeof(u64),
6418 GFP_KERNEL);
6419 if (!mread_attr.out) {
6420 ret = -ENOMEM;
6421 goto err_bound;
6422 }
6423
6424 mread_attr.hw_cntrs_hndl = mcounters->hw_cntrs_hndl;
6425 mread_attr.flags = read_attr->flags;
6426 ret = mcounters->read_counters(counters->device, &mread_attr);
6427 if (ret)
6428 goto err_read;
6429
6430 /* do the pass over the counters data array to assign according to the
6431 * descriptions and indexing pairs
6432 */
6433 desc = mcounters->counters_data;
6434 for (i = 0; i < mcounters->ncounters; i++)
6435 read_attr->counters_buff[desc[i].index] += mread_attr.out[desc[i].description];
6436
6437err_read:
6438 kfree(mread_attr.out);
6439err_bound:
6440 mutex_unlock(&mcounters->mcntrs_mutex);
6441 return ret;
6442}
6443
6444static int mlx5_ib_destroy_counters(struct ib_counters *counters)
6445{
6446 struct mlx5_ib_mcounters *mcounters = to_mcounters(counters);
6447
6448 counters_clear_description(counters);
6449 if (mcounters->hw_cntrs_hndl)
6450 mlx5_fc_destroy(to_mdev(counters->device)->mdev,
6451 mcounters->hw_cntrs_hndl);
6452
6453 kfree(mcounters);
6454
6455 return 0;
6456}
6457
6458static struct ib_counters *mlx5_ib_create_counters(struct ib_device *device,
6459 struct uverbs_attr_bundle *attrs)
6460{
6461 struct mlx5_ib_mcounters *mcounters;
6462
6463 mcounters = kzalloc(sizeof(*mcounters), GFP_KERNEL);
6464 if (!mcounters)
6465 return ERR_PTR(-ENOMEM);
6466
6467 mutex_init(&mcounters->mcntrs_mutex);
6468
6469 return &mcounters->ibcntrs;
6470}
6471
6472static void mlx5_ib_stage_init_cleanup(struct mlx5_ib_dev *dev)3930static void mlx5_ib_stage_init_cleanup(struct mlx5_ib_dev *dev)
6473{3931{
6474 mlx5_ib_cleanup_multiport_master(dev);3932 mlx5_ib_cleanup_multiport_master(dev);
@@ -6547,21 +4005,16 @@ err_mp: · 72 unmodified lines
6547 return -ENOMEM;4005 return -ENOMEM;
6548}4006}
6549 4007
6550static int mlx5_ib_stage_flow_db_init(struct mlx5_ib_dev *dev)4008static int mlx5_ib_enable_driver(struct ib_device *dev)
6551{4009{
6552 dev->flow_db = kzalloc(sizeof(*dev->flow_db), GFP_KERNEL);4010 struct mlx5_ib_dev *mdev = to_mdev(dev);
6553 4011 int ret;
6554 if (!dev->flow_db)
6555 return -ENOMEM;
6556
6557 mutex_init(&dev->flow_db->lock);
6558 4012
6559 return 0;4013 ret = mlx5_ib_test_wc(mdev);
6560}4014 mlx5_ib_dbg(mdev, "Write-Combining %s",
4015 mdev->wc_support ? "supported" : "not supported");
6561 4016
6562static void mlx5_ib_stage_flow_db_cleanup(struct mlx5_ib_dev *dev)4017 return ret;
6563{
6564 kfree(dev->flow_db);
6565}4018}
6566 4019
6567static const struct ib_device_ops mlx5_ib_dev_ops = {4020static const struct ib_device_ops mlx5_ib_dev_ops = {
@@ -6577,9 +4030,7 @@ static const struct ib_device_ops mlx5_ib_dev_ops = { · 9 unmodified lines
6577 .attach_mcast = mlx5_ib_mcg_attach,4030 .attach_mcast = mlx5_ib_mcg_attach,
6578 .check_mr_status = mlx5_ib_check_mr_status,4031 .check_mr_status = mlx5_ib_check_mr_status,
6579 .create_ah = mlx5_ib_create_ah,4032 .create_ah = mlx5_ib_create_ah,
6580 .create_counters = mlx5_ib_create_counters,
6581 .create_cq = mlx5_ib_create_cq,4033 .create_cq = mlx5_ib_create_cq,
6582 .create_flow = mlx5_ib_create_flow,
6583 .create_qp = mlx5_ib_create_qp,4034 .create_qp = mlx5_ib_create_qp,
6584 .create_srq = mlx5_ib_create_srq,4035 .create_srq = mlx5_ib_create_srq,
6585 .dealloc_pd = mlx5_ib_dealloc_pd,4036 .dealloc_pd = mlx5_ib_dealloc_pd,
@@ -6587,10 +4038,7 @@ static const struct ib_device_ops mlx5_ib_dev_ops = { · 1 unmodified line
6587 .del_gid = mlx5_ib_del_gid,4038 .del_gid = mlx5_ib_del_gid,
6588 .dereg_mr = mlx5_ib_dereg_mr,4039 .dereg_mr = mlx5_ib_dereg_mr,
6589 .destroy_ah = mlx5_ib_destroy_ah,4040 .destroy_ah = mlx5_ib_destroy_ah,
6590 .destroy_counters = mlx5_ib_destroy_counters,
6591 .destroy_cq = mlx5_ib_destroy_cq,4041 .destroy_cq = mlx5_ib_destroy_cq,
6592 .destroy_flow = mlx5_ib_destroy_flow,
6593 .destroy_flow_action = mlx5_ib_destroy_flow_action,
6594 .destroy_qp = mlx5_ib_destroy_qp,4042 .destroy_qp = mlx5_ib_destroy_qp,
6595 .destroy_srq = mlx5_ib_destroy_srq,4043 .destroy_srq = mlx5_ib_destroy_srq,
6596 .detach_mcast = mlx5_ib_mcg_detach,4044 .detach_mcast = mlx5_ib_mcg_detach,
@@ -6598,8 +4046,6 @@ static const struct ib_device_ops mlx5_ib_dev_ops = { · 1 unmodified line
6598 .drain_rq = mlx5_ib_drain_rq,4046 .drain_rq = mlx5_ib_drain_rq,
6599 .drain_sq = mlx5_ib_drain_sq,4047 .drain_sq = mlx5_ib_drain_sq,
6600 .enable_driver = mlx5_ib_enable_driver,4048 .enable_driver = mlx5_ib_enable_driver,
6601 .fill_res_entry = mlx5_ib_fill_res_entry,
6602 .fill_stat_entry = mlx5_ib_fill_stat_entry,
6603 .get_dev_fw_str = get_dev_fw_str,4049 .get_dev_fw_str = get_dev_fw_str,
6604 .get_dma_mr = mlx5_ib_get_dma_mr,4050 .get_dma_mr = mlx5_ib_get_dma_mr,
6605 .get_link_layer = mlx5_ib_port_link_layer,4051 .get_link_layer = mlx5_ib_port_link_layer,
@@ -6623,24 +4069,20 @@ static const struct ib_device_ops mlx5_ib_dev_ops = { · 17 unmodified lines
6623 .query_pkey = mlx5_ib_query_pkey,4069 .query_pkey = mlx5_ib_query_pkey,
6624 .query_qp = mlx5_ib_query_qp,4070 .query_qp = mlx5_ib_query_qp,
6625 .query_srq = mlx5_ib_query_srq,4071 .query_srq = mlx5_ib_query_srq,
6626 .read_counters = mlx5_ib_read_counters,4072 .query_ucontext = mlx5_ib_query_ucontext,
6627 .reg_user_mr = mlx5_ib_reg_user_mr,4073 .reg_user_mr = mlx5_ib_reg_user_mr,
6628 .req_notify_cq = mlx5_ib_arm_cq,4074 .req_notify_cq = mlx5_ib_arm_cq,
6629 .rereg_user_mr = mlx5_ib_rereg_user_mr,4075 .rereg_user_mr = mlx5_ib_rereg_user_mr,
6630 .resize_cq = mlx5_ib_resize_cq,4076 .resize_cq = mlx5_ib_resize_cq,
6631 4077
6632 INIT_RDMA_OBJ_SIZE(ib_ah, mlx5_ib_ah, ibah),4078 INIT_RDMA_OBJ_SIZE(ib_ah, mlx5_ib_ah, ibah),
4079 INIT_RDMA_OBJ_SIZE(ib_counters, mlx5_ib_mcounters, ibcntrs),
6633 INIT_RDMA_OBJ_SIZE(ib_cq, mlx5_ib_cq, ibcq),4080 INIT_RDMA_OBJ_SIZE(ib_cq, mlx5_ib_cq, ibcq),
6634 INIT_RDMA_OBJ_SIZE(ib_pd, mlx5_ib_pd, ibpd),4081 INIT_RDMA_OBJ_SIZE(ib_pd, mlx5_ib_pd, ibpd),
6635 INIT_RDMA_OBJ_SIZE(ib_srq, mlx5_ib_srq, ibsrq),4082 INIT_RDMA_OBJ_SIZE(ib_srq, mlx5_ib_srq, ibsrq),
6636 INIT_RDMA_OBJ_SIZE(ib_ucontext, mlx5_ib_ucontext, ibucontext),4083 INIT_RDMA_OBJ_SIZE(ib_ucontext, mlx5_ib_ucontext, ibucontext),
6637};4084};
6638 4085
6639static const struct ib_device_ops mlx5_ib_dev_flow_ipsec_ops = {
6640 .create_flow_action_esp = mlx5_ib_create_flow_action_esp,
6641 .modify_flow_action_esp = mlx5_ib_modify_flow_action_esp,
6642};
6643
6644static const struct ib_device_ops mlx5_ib_dev_ipoib_enhanced_ops = {4086static const struct ib_device_ops mlx5_ib_dev_ipoib_enhanced_ops = {
6645 .rdma_netdev_get_params = mlx5_ib_rn_get_params,4087 .rdma_netdev_get_params = mlx5_ib_rn_get_params,
6646};4088};
@@ -6661,6 +4103,8 @@ static const struct ib_device_ops mlx5_ib_dev_mw_ops = { · 14 unmodified lines
6661static const struct ib_device_ops mlx5_ib_dev_xrc_ops = {4103static const struct ib_device_ops mlx5_ib_dev_xrc_ops = {
6662 .alloc_xrcd = mlx5_ib_alloc_xrcd,4104 .alloc_xrcd = mlx5_ib_alloc_xrcd,
6663 .dealloc_xrcd = mlx5_ib_dealloc_xrcd,4105 .dealloc_xrcd = mlx5_ib_dealloc_xrcd,
4106
4107 INIT_RDMA_OBJ_SIZE(ib_xrcd, mlx5_ib_xrcd, ibxrcd),
6664};4108};
6665 4109
6666static const struct ib_device_ops mlx5_ib_dev_dm_ops = {4110static const struct ib_device_ops mlx5_ib_dev_dm_ops = {
@@ -6769,9 +4213,6 @@ static int mlx5_ib_stage_caps_init(struct mlx5_ib_dev *dev) · 102 unmodified lines
6769 MLX5_GENERAL_OBJ_TYPES_CAP_SW_ICM)4213 MLX5_GENERAL_OBJ_TYPES_CAP_SW_ICM)
6770 ib_set_device_ops(&dev->ib_dev, &mlx5_ib_dev_dm_ops);4214 ib_set_device_ops(&dev->ib_dev, &mlx5_ib_dev_dm_ops);
6771 4215
6772 if (mlx5_accel_ipsec_device_caps(dev->mdev) &
6773 MLX5_ACCEL_IPSEC_CAP_DEVICE)
6774 ib_set_device_ops(&dev->ib_dev, &mlx5_ib_dev_flow_ipsec_ops);
6775 ib_set_device_ops(&dev->ib_dev, &mlx5_ib_dev_ops);4216 ib_set_device_ops(&dev->ib_dev, &mlx5_ib_dev_ops);
6776 4217
6777 if (IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS))4218 if (IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS))
@@ -6829,65 +4270,36 @@ static const struct ib_device_ops mlx5_ib_dev_common_roce_ops = { · 51 unmodified lines
6829 .modify_wq = mlx5_ib_modify_wq,4270 .modify_wq = mlx5_ib_modify_wq,
6830};4271};
6831 4272
6832static int mlx5_ib_stage_common_roce_init(struct mlx5_ib_dev *dev)4273static int mlx5_ib_roce_init(struct mlx5_ib_dev *dev)
6833{
6834 u8 port_num;
6835
6836 dev->ib_dev.uverbs_ex_cmd_mask |=
6837 (1ull << IB_USER_VERBS_EX_CMD_CREATE_WQ) |
6838 (1ull << IB_USER_VERBS_EX_CMD_MODIFY_WQ) |
6839 (1ull << IB_USER_VERBS_EX_CMD_DESTROY_WQ) |
6840 (1ull << IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL) |
6841 (1ull << IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL);
6842 ib_set_device_ops(&dev->ib_dev, &mlx5_ib_dev_common_roce_ops);
6843
6844 port_num = mlx5_core_native_port_num(dev->mdev) - 1;
6845
6846 /* Register only for native ports */
6847 return mlx5_add_netdev_notifier(dev, port_num);
6848}
6849
6850static void mlx5_ib_stage_common_roce_cleanup(struct mlx5_ib_dev *dev)
6851{
6852 u8 port_num = mlx5_core_native_port_num(dev->mdev) - 1;
6853
6854 mlx5_remove_netdev_notifier(dev, port_num);
6855}
6856
6857static int mlx5_ib_stage_raw_eth_roce_init(struct mlx5_ib_dev *dev)
6858{
6859 struct mlx5_core_dev *mdev = dev->mdev;
6860 enum rdma_link_layer ll;
6861 int port_type_cap;
6862 int err = 0;
6863
6864 port_type_cap = MLX5_CAP_GEN(mdev, port_type);
6865 ll = mlx5_port_type_cap_to_rdma_ll(port_type_cap);
6866
6867 if (ll == IB_LINK_LAYER_ETHERNET)
6868 err = mlx5_ib_stage_common_roce_init(dev);
6869
6870 return err;
6871}
6872
6873static void mlx5_ib_stage_raw_eth_roce_cleanup(struct mlx5_ib_dev *dev)
6874{
6875 mlx5_ib_stage_common_roce_cleanup(dev);
6876}
6877
6878static int mlx5_ib_stage_roce_init(struct mlx5_ib_dev *dev)
6879{4274{
6880 struct mlx5_core_dev *mdev = dev->mdev;4275 struct mlx5_core_dev *mdev = dev->mdev;
6881 enum rdma_link_layer ll;4276 enum rdma_link_layer ll;
6882 int port_type_cap;4277 int port_type_cap;
4278 u8 port_num = 0;
6883 int err;4279 int err;
6884 4280
6885 port_type_cap = MLX5_CAP_GEN(mdev, port_type);4281 port_type_cap = MLX5_CAP_GEN(mdev, port_type);
6886 ll = mlx5_port_type_cap_to_rdma_ll(port_type_cap);4282 ll = mlx5_port_type_cap_to_rdma_ll(port_type_cap);
6887 4283
6888 if (ll == IB_LINK_LAYER_ETHERNET) {4284 if (ll == IB_LINK_LAYER_ETHERNET) {
6889 err = mlx5_ib_stage_common_roce_init(dev);4285 dev->ib_dev.uverbs_ex_cmd_mask |=
6890 if (err)4286 (1ull << IB_USER_VERBS_EX_CMD_CREATE_WQ) |
4287 (1ull << IB_USER_VERBS_EX_CMD_MODIFY_WQ) |
4288 (1ull << IB_USER_VERBS_EX_CMD_DESTROY_WQ) |
4289 (1ull << IB_USER_VERBS_EX_CMD_CREATE_RWQ_IND_TBL) |
4290 (1ull << IB_USER_VERBS_EX_CMD_DESTROY_RWQ_IND_TBL);
4291 ib_set_device_ops(&dev->ib_dev, &mlx5_ib_dev_common_roce_ops);
4292
4293 port_num = mlx5_core_native_port_num(dev->mdev) - 1;
4294
4295 /* Register only for native ports */
4296 err = mlx5_add_netdev_notifier(dev, port_num);
4297 if (err || dev->is_rep || !mlx5_is_roce_enabled(mdev))
4298 /*
4299 * We don't enable ETH interface for
4300 * 1. IB representors
4301 * 2. User disabled ROCE through devlink interface
4302 */
6891 return err;4303 return err;
6892 4304
6893 err = mlx5_enable_eth(dev);4305 err = mlx5_enable_eth(dev);
@@ -6897,71 +4309,27 @@ static int mlx5_ib_stage_roce_init(struct mlx5_ib_dev *dev) · 3 unmodified lines
6897 4309
6898 return 0;4310 return 0;
6899cleanup:4311cleanup:
6900 mlx5_ib_stage_common_roce_cleanup(dev);4312 mlx5_remove_netdev_notifier(dev, port_num);
6901
6902 return err;4313 return err;
6903}4314}
6904 4315
6905static void mlx5_ib_stage_roce_cleanup(struct mlx5_ib_dev *dev)4316static void mlx5_ib_roce_cleanup(struct mlx5_ib_dev *dev)
6906{4317{
6907 struct mlx5_core_dev *mdev = dev->mdev;4318 struct mlx5_core_dev *mdev = dev->mdev;
6908 enum rdma_link_layer ll;4319 enum rdma_link_layer ll;
6909 int port_type_cap;4320 int port_type_cap;
4321 u8 port_num;
6910 4322
6911 port_type_cap = MLX5_CAP_GEN(mdev, port_type);4323 port_type_cap = MLX5_CAP_GEN(mdev, port_type);
6912 ll = mlx5_port_type_cap_to_rdma_ll(port_type_cap);4324 ll = mlx5_port_type_cap_to_rdma_ll(port_type_cap);
6913 4325
6914 if (ll == IB_LINK_LAYER_ETHERNET) {4326 if (ll == IB_LINK_LAYER_ETHERNET) {
6915 mlx5_disable_eth(dev);4327 if (!dev->is_rep)
6916 mlx5_ib_stage_common_roce_cleanup(dev);4328 mlx5_disable_eth(dev);
6917 }
6918}
6919
6920static int mlx5_ib_stage_dev_res_init(struct mlx5_ib_dev *dev)
6921{
6922 return create_dev_resources(&dev->devr);
6923}
6924
6925static void mlx5_ib_stage_dev_res_cleanup(struct mlx5_ib_dev *dev)
6926{
6927 destroy_dev_resources(&dev->devr);
6928}
6929
6930static int mlx5_ib_stage_odp_init(struct mlx5_ib_dev *dev)
6931{
6932 return mlx5_ib_odp_init_one(dev);
6933}
6934
6935static void mlx5_ib_stage_odp_cleanup(struct mlx5_ib_dev *dev)
6936{
6937 mlx5_ib_odp_cleanup_one(dev);
6938}
6939
6940static const struct ib_device_ops mlx5_ib_dev_hw_stats_ops = {
6941 .alloc_hw_stats = mlx5_ib_alloc_hw_stats,
6942 .get_hw_stats = mlx5_ib_get_hw_stats,
6943 .counter_bind_qp = mlx5_ib_counter_bind_qp,
6944 .counter_unbind_qp = mlx5_ib_counter_unbind_qp,
6945 .counter_dealloc = mlx5_ib_counter_dealloc,
6946 .counter_alloc_stats = mlx5_ib_counter_alloc_stats,
6947 .counter_update_stats = mlx5_ib_counter_update_stats,
6948};
6949
6950static int mlx5_ib_stage_counters_init(struct mlx5_ib_dev *dev)
6951{
6952 if (MLX5_CAP_GEN(dev->mdev, max_qp_cnt)) {
6953 ib_set_device_ops(&dev->ib_dev, &mlx5_ib_dev_hw_stats_ops);
6954 4329
6955 return mlx5_ib_alloc_counters(dev);4330 port_num = mlx5_core_native_port_num(dev->mdev) - 1;
4331 mlx5_remove_netdev_notifier(dev, port_num);
6956 }4332 }
6957
6958 return 0;
6959}
6960
6961static void mlx5_ib_stage_counters_cleanup(struct mlx5_ib_dev *dev)
6962{
6963 if (MLX5_CAP_GEN(dev->mdev, max_qp_cnt))
6964 mlx5_ib_dealloc_counters(dev);
6965}4333}
6966 4334
6967static int mlx5_ib_stage_cong_debugfs_init(struct mlx5_ib_dev *dev)4335static int mlx5_ib_stage_cong_debugfs_init(struct mlx5_ib_dev *dev)
@@ -7023,7 +4391,18 @@ static int mlx5_ib_stage_ib_reg_init(struct mlx5_ib_dev *dev) · 55 unmodified lines
7023 4391
7024static void mlx5_ib_stage_pre_ib_reg_umr_cleanup(struct mlx5_ib_dev *dev)4392static void mlx5_ib_stage_pre_ib_reg_umr_cleanup(struct mlx5_ib_dev *dev)
7025{4393{
7026 destroy_umrc_res(dev);4394 int err;
4395
4396 err = mlx5_mr_cache_cleanup(dev);
4397 if (err)
4398 mlx5_ib_warn(dev, "mr cache cleanup failed\n");
4399
4400 if (dev->umrc.qp)
4401 mlx5_ib_destroy_qp(dev->umrc.qp, NULL);
4402 if (dev->umrc.cq)
4403 ib_free_cq(dev->umrc.cq);
4404 if (dev->umrc.pd)
4405 ib_dealloc_pd(dev->umrc.pd);
7027}4406}
7028 4407
7029static void mlx5_ib_stage_ib_reg_cleanup(struct mlx5_ib_dev *dev)4408static void mlx5_ib_stage_ib_reg_cleanup(struct mlx5_ib_dev *dev)
@@ -7031,21 +4410,162 @@ static void mlx5_ib_stage_ib_reg_cleanup(struct mlx5_ib_dev *dev) · 1 unmodified line
7031 ib_unregister_device(&dev->ib_dev);4410 ib_unregister_device(&dev->ib_dev);
7032}4411}
7033 4412
4413enum {
4414 MAX_UMR_WR = 128,
4415};
4416
7034static int mlx5_ib_stage_post_ib_reg_umr_init(struct mlx5_ib_dev *dev)4417static int mlx5_ib_stage_post_ib_reg_umr_init(struct mlx5_ib_dev *dev)
7035{4418{
7036 return create_umr_res(dev);4419 struct ib_qp_init_attr *init_attr = NULL;
4420 struct ib_qp_attr *attr = NULL;
4421 struct ib_pd *pd;
4422 struct ib_cq *cq;
4423 struct ib_qp *qp;
4424 int ret;
4425
4426 attr = kzalloc(sizeof(*attr), GFP_KERNEL);
4427 init_attr = kzalloc(sizeof(*init_attr), GFP_KERNEL);
4428 if (!attr || !init_attr) {
4429 ret = -ENOMEM;
4430 goto error_0;
4431 }
4432
4433 pd = ib_alloc_pd(&dev->ib_dev, 0);
4434 if (IS_ERR(pd)) {
4435 mlx5_ib_dbg(dev, "Couldn't create PD for sync UMR QP\n");
4436 ret = PTR_ERR(pd);
4437 goto error_0;
4438 }
4439
4440 cq = ib_alloc_cq(&dev->ib_dev, NULL, 128, 0, IB_POLL_SOFTIRQ);
4441 if (IS_ERR(cq)) {
4442 mlx5_ib_dbg(dev, "Couldn't create CQ for sync UMR QP\n");
4443 ret = PTR_ERR(cq);
4444 goto error_2;
4445 }
4446
4447 init_attr->send_cq = cq;
4448 init_attr->recv_cq = cq;
4449 init_attr->sq_sig_type = IB_SIGNAL_ALL_WR;
4450 init_attr->cap.max_send_wr = MAX_UMR_WR;
4451 init_attr->cap.max_send_sge = 1;
4452 init_attr->qp_type = MLX5_IB_QPT_REG_UMR;
4453 init_attr->port_num = 1;
4454 qp = mlx5_ib_create_qp(pd, init_attr, NULL);
4455 if (IS_ERR(qp)) {
4456 mlx5_ib_dbg(dev, "Couldn't create sync UMR QP\n");
4457 ret = PTR_ERR(qp);
4458 goto error_3;
4459 }
4460 qp->device = &dev->ib_dev;
4461 qp->real_qp = qp;
4462 qp->uobject = NULL;
4463 qp->qp_type = MLX5_IB_QPT_REG_UMR;
4464 qp->send_cq = init_attr->send_cq;
4465 qp->recv_cq = init_attr->recv_cq;
4466
4467 attr->qp_state = IB_QPS_INIT;
4468 attr->port_num = 1;
4469 ret = mlx5_ib_modify_qp(qp, attr, IB_QP_STATE | IB_QP_PKEY_INDEX |
4470 IB_QP_PORT, NULL);
4471 if (ret) {
4472 mlx5_ib_dbg(dev, "Couldn't modify UMR QP\n");
4473 goto error_4;
4474 }
4475
4476 memset(attr, 0, sizeof(*attr));
4477 attr->qp_state = IB_QPS_RTR;
4478 attr->path_mtu = IB_MTU_256;
4479
4480 ret = mlx5_ib_modify_qp(qp, attr, IB_QP_STATE, NULL);
4481 if (ret) {
4482 mlx5_ib_dbg(dev, "Couldn't modify umr QP to rtr\n");
4483 goto error_4;
4484 }
4485
4486 memset(attr, 0, sizeof(*attr));
4487 attr->qp_state = IB_QPS_RTS;
4488 ret = mlx5_ib_modify_qp(qp, attr, IB_QP_STATE, NULL);
4489 if (ret) {
4490 mlx5_ib_dbg(dev, "Couldn't modify umr QP to rts\n");
4491 goto error_4;
4492 }
4493
4494 dev->umrc.qp = qp;
4495 dev->umrc.cq = cq;
4496 dev->umrc.pd = pd;
4497
4498 sema_init(&dev->umrc.sem, MAX_UMR_WR);
4499 ret = mlx5_mr_cache_init(dev);
4500 if (ret) {
4501 mlx5_ib_warn(dev, "mr cache init failed %d\n", ret);
4502 goto error_4;
4503 }
4504
4505 kfree(attr);
4506 kfree(init_attr);
4507
4508 return 0;
4509
4510error_4:
4511 mlx5_ib_destroy_qp(qp, NULL);
4512 dev->umrc.qp = NULL;
4513
4514error_3:
4515 ib_free_cq(cq);
4516 dev->umrc.cq = NULL;
4517
4518error_2:
4519 ib_dealloc_pd(pd);
4520 dev->umrc.pd = NULL;
4521
4522error_0:
4523 kfree(attr);
4524 kfree(init_attr);
4525 return ret;
7037}4526}
7038 4527
7039static int mlx5_ib_stage_delay_drop_init(struct mlx5_ib_dev *dev)4528static int mlx5_ib_stage_delay_drop_init(struct mlx5_ib_dev *dev)
7040{4529{
7041 init_delay_drop(dev);4530 struct dentry *root;
4531
4532 if (!(dev->ib_dev.attrs.raw_packet_caps & IB_RAW_PACKET_CAP_DELAY_DROP))
4533 return 0;
4534
4535 mutex_init(&dev->delay_drop.lock);
4536 dev->delay_drop.dev = dev;
4537 dev->delay_drop.activate = false;
4538 dev->delay_drop.timeout = MLX5_MAX_DELAY_DROP_TIMEOUT_MS * 1000;
4539 INIT_WORK(&dev->delay_drop.delay_drop_work, delay_drop_handler);
4540 atomic_set(&dev->delay_drop.rqs_cnt, 0);
4541 atomic_set(&dev->delay_drop.events_cnt, 0);
4542
4543 if (!mlx5_debugfs_root)
4544 return 0;
4545
4546 root = debugfs_create_dir("delay_drop", dev->mdev->priv.dbg_root);
4547 dev->delay_drop.dir_debugfs = root;
7042 4548
4549 debugfs_create_atomic_t("num_timeout_events", 0400, root,
4550 &dev->delay_drop.events_cnt);
4551 debugfs_create_atomic_t("num_rqs", 0400, root,
4552 &dev->delay_drop.rqs_cnt);
4553 debugfs_create_file("timeout", 0600, root, &dev->delay_drop,
4554 &fops_delay_drop_timeout);
7043 return 0;4555 return 0;
7044}4556}
7045 4557
7046static void mlx5_ib_stage_delay_drop_cleanup(struct mlx5_ib_dev *dev)4558static void mlx5_ib_stage_delay_drop_cleanup(struct mlx5_ib_dev *dev)
7047{4559{
7048 cancel_delay_drop(dev);4560 if (!(dev->ib_dev.attrs.raw_packet_caps & IB_RAW_PACKET_CAP_DELAY_DROP))
4561 return;
4562
4563 cancel_work_sync(&dev->delay_drop.delay_drop_work);
4564 if (!dev->delay_drop.dir_debugfs)
4565 return;
4566
4567 debugfs_remove_recursive(dev->delay_drop.dir_debugfs);
4568 dev->delay_drop.dir_debugfs = NULL;
7049}4569}
7050 4570
7051static int mlx5_ib_stage_dev_notifier_init(struct mlx5_ib_dev *dev)4571static int mlx5_ib_stage_dev_notifier_init(struct mlx5_ib_dev *dev)
@@ -7060,38 +4580,6 @@ static void mlx5_ib_stage_dev_notifier_cleanup(struct mlx5_ib_dev *dev) · 8 unmodified lines
7060 mlx5_notifier_unregister(dev->mdev, &dev->mdev_events);4580 mlx5_notifier_unregister(dev->mdev, &dev->mdev_events);
7061}4581}
7062 4582
7063static int mlx5_ib_stage_devx_init(struct mlx5_ib_dev *dev)
7064{
7065 int uid;
7066
7067 uid = mlx5_ib_devx_create(dev, false);
7068 if (uid > 0) {
7069 dev->devx_whitelist_uid = uid;
7070 mlx5_ib_devx_init_event_table(dev);
7071 }
7072
7073 return 0;
7074}
7075static void mlx5_ib_stage_devx_cleanup(struct mlx5_ib_dev *dev)
7076{
7077 if (dev->devx_whitelist_uid) {
7078 mlx5_ib_devx_cleanup_event_table(dev);
7079 mlx5_ib_devx_destroy(dev, dev->devx_whitelist_uid);
7080 }
7081}
7082
7083int mlx5_ib_enable_driver(struct ib_device *dev)
7084{
7085 struct mlx5_ib_dev *mdev = to_mdev(dev);
7086 int ret;
7087
7088 ret = mlx5_ib_test_wc(mdev);
7089 mlx5_ib_dbg(mdev, "Write-Combining %s",
7090 mdev->wc_support ? "supported" : "not supported");
7091
7092 return ret;
7093}
7094
7095void __mlx5_ib_remove(struct mlx5_ib_dev *dev,4583void __mlx5_ib_remove(struct mlx5_ib_dev *dev,
7096 const struct mlx5_ib_profile *profile,4584 const struct mlx5_ib_profile *profile,
7097 int stage)4585 int stage)
@@ -7139,9 +4627,9 @@ static const struct mlx5_ib_profile pf_profile = { · 41 unmodified lines
7139 STAGE_CREATE(MLX5_IB_STAGE_INIT,4627 STAGE_CREATE(MLX5_IB_STAGE_INIT,
7140 mlx5_ib_stage_init_init,4628 mlx5_ib_stage_init_init,
7141 mlx5_ib_stage_init_cleanup),4629 mlx5_ib_stage_init_cleanup),
7142 STAGE_CREATE(MLX5_IB_STAGE_FLOW_DB,4630 STAGE_CREATE(MLX5_IB_STAGE_FS,
7143 mlx5_ib_stage_flow_db_init,4631 mlx5_ib_fs_init,
7144 mlx5_ib_stage_flow_db_cleanup),4632 mlx5_ib_fs_cleanup),
7145 STAGE_CREATE(MLX5_IB_STAGE_CAPS,4633 STAGE_CREATE(MLX5_IB_STAGE_CAPS,
7146 mlx5_ib_stage_caps_init,4634 mlx5_ib_stage_caps_init,
7147 mlx5_ib_stage_caps_cleanup),4635 mlx5_ib_stage_caps_cleanup),
@@ -7149,8 +4637,8 @@ static const struct mlx5_ib_profile pf_profile = { · 1 unmodified line
7149 mlx5_ib_stage_non_default_cb,4637 mlx5_ib_stage_non_default_cb,
7150 NULL),4638 NULL),
7151 STAGE_CREATE(MLX5_IB_STAGE_ROCE,4639 STAGE_CREATE(MLX5_IB_STAGE_ROCE,
7152 mlx5_ib_stage_roce_init,4640 mlx5_ib_roce_init,
7153 mlx5_ib_stage_roce_cleanup),4641 mlx5_ib_roce_cleanup),
7154 STAGE_CREATE(MLX5_IB_STAGE_QP,4642 STAGE_CREATE(MLX5_IB_STAGE_QP,
7155 mlx5_init_qp_table,4643 mlx5_init_qp_table,
7156 mlx5_cleanup_qp_table),4644 mlx5_cleanup_qp_table),
@@ -7158,17 +4646,17 @@ static const struct mlx5_ib_profile pf_profile = { · 1 unmodified line
7158 mlx5_init_srq_table,4646 mlx5_init_srq_table,
7159 mlx5_cleanup_srq_table),4647 mlx5_cleanup_srq_table),
7160 STAGE_CREATE(MLX5_IB_STAGE_DEVICE_RESOURCES,4648 STAGE_CREATE(MLX5_IB_STAGE_DEVICE_RESOURCES,
7161 mlx5_ib_stage_dev_res_init,4649 mlx5_ib_dev_res_init,
7162 mlx5_ib_stage_dev_res_cleanup),4650 mlx5_ib_dev_res_cleanup),
7163 STAGE_CREATE(MLX5_IB_STAGE_DEVICE_NOTIFIER,4651 STAGE_CREATE(MLX5_IB_STAGE_DEVICE_NOTIFIER,
7164 mlx5_ib_stage_dev_notifier_init,4652 mlx5_ib_stage_dev_notifier_init,
7165 mlx5_ib_stage_dev_notifier_cleanup),4653 mlx5_ib_stage_dev_notifier_cleanup),
7166 STAGE_CREATE(MLX5_IB_STAGE_ODP,4654 STAGE_CREATE(MLX5_IB_STAGE_ODP,
7167 mlx5_ib_stage_odp_init,4655 mlx5_ib_odp_init_one,
7168 mlx5_ib_stage_odp_cleanup),4656 mlx5_ib_odp_cleanup_one),
7169 STAGE_CREATE(MLX5_IB_STAGE_COUNTERS,4657 STAGE_CREATE(MLX5_IB_STAGE_COUNTERS,
7170 mlx5_ib_stage_counters_init,4658 mlx5_ib_counters_init,
7171 mlx5_ib_stage_counters_cleanup),4659 mlx5_ib_counters_cleanup),
7172 STAGE_CREATE(MLX5_IB_STAGE_CONG_DEBUGFS,4660 STAGE_CREATE(MLX5_IB_STAGE_CONG_DEBUGFS,
7173 mlx5_ib_stage_cong_debugfs_init,4661 mlx5_ib_stage_cong_debugfs_init,
7174 mlx5_ib_stage_cong_debugfs_cleanup),4662 mlx5_ib_stage_cong_debugfs_cleanup),
@@ -7182,8 +4670,8 @@ static const struct mlx5_ib_profile pf_profile = { · 7 unmodified lines
7182 NULL,4670 NULL,
7183 mlx5_ib_stage_pre_ib_reg_umr_cleanup),4671 mlx5_ib_stage_pre_ib_reg_umr_cleanup),
7184 STAGE_CREATE(MLX5_IB_STAGE_WHITELIST_UID,4672 STAGE_CREATE(MLX5_IB_STAGE_WHITELIST_UID,
7185 mlx5_ib_stage_devx_init,4673 mlx5_ib_devx_init,
7186 mlx5_ib_stage_devx_cleanup),4674 mlx5_ib_devx_cleanup),
7187 STAGE_CREATE(MLX5_IB_STAGE_IB_REG,4675 STAGE_CREATE(MLX5_IB_STAGE_IB_REG,
7188 mlx5_ib_stage_ib_reg_init,4676 mlx5_ib_stage_ib_reg_init,
7189 mlx5_ib_stage_ib_reg_cleanup),4677 mlx5_ib_stage_ib_reg_cleanup),
@@ -7193,15 +4681,18 @@ static const struct mlx5_ib_profile pf_profile = { · 3 unmodified lines
7193 STAGE_CREATE(MLX5_IB_STAGE_DELAY_DROP,4681 STAGE_CREATE(MLX5_IB_STAGE_DELAY_DROP,
7194 mlx5_ib_stage_delay_drop_init,4682 mlx5_ib_stage_delay_drop_init,
7195 mlx5_ib_stage_delay_drop_cleanup),4683 mlx5_ib_stage_delay_drop_cleanup),
4684 STAGE_CREATE(MLX5_IB_STAGE_RESTRACK,
4685 mlx5_ib_restrack_init,
4686 NULL),
7196};4687};
7197 4688
7198const struct mlx5_ib_profile raw_eth_profile = {4689const struct mlx5_ib_profile raw_eth_profile = {
7199 STAGE_CREATE(MLX5_IB_STAGE_INIT,4690 STAGE_CREATE(MLX5_IB_STAGE_INIT,
7200 mlx5_ib_stage_init_init,4691 mlx5_ib_stage_init_init,
7201 mlx5_ib_stage_init_cleanup),4692 mlx5_ib_stage_init_cleanup),
7202 STAGE_CREATE(MLX5_IB_STAGE_FLOW_DB,4693 STAGE_CREATE(MLX5_IB_STAGE_FS,
7203 mlx5_ib_stage_flow_db_init,4694 mlx5_ib_fs_init,
7204 mlx5_ib_stage_flow_db_cleanup),4695 mlx5_ib_fs_cleanup),
7205 STAGE_CREATE(MLX5_IB_STAGE_CAPS,4696 STAGE_CREATE(MLX5_IB_STAGE_CAPS,
7206 mlx5_ib_stage_caps_init,4697 mlx5_ib_stage_caps_init,
7207 mlx5_ib_stage_caps_cleanup),4698 mlx5_ib_stage_caps_cleanup),
@@ -7209,8 +4700,8 @@ const struct mlx5_ib_profile raw_eth_profile = { · 1 unmodified line
7209 mlx5_ib_stage_raw_eth_non_default_cb,4700 mlx5_ib_stage_raw_eth_non_default_cb,
7210 NULL),4701 NULL),
7211 STAGE_CREATE(MLX5_IB_STAGE_ROCE,4702 STAGE_CREATE(MLX5_IB_STAGE_ROCE,
7212 mlx5_ib_stage_raw_eth_roce_init,4703 mlx5_ib_roce_init,
7213 mlx5_ib_stage_raw_eth_roce_cleanup),4704 mlx5_ib_roce_cleanup),
7214 STAGE_CREATE(MLX5_IB_STAGE_QP,4705 STAGE_CREATE(MLX5_IB_STAGE_QP,
7215 mlx5_init_qp_table,4706 mlx5_init_qp_table,
7216 mlx5_cleanup_qp_table),4707 mlx5_cleanup_qp_table),
@@ -7218,14 +4709,14 @@ const struct mlx5_ib_profile raw_eth_profile = { · 1 unmodified line
7218 mlx5_init_srq_table,4709 mlx5_init_srq_table,
7219 mlx5_cleanup_srq_table),4710 mlx5_cleanup_srq_table),
7220 STAGE_CREATE(MLX5_IB_STAGE_DEVICE_RESOURCES,4711 STAGE_CREATE(MLX5_IB_STAGE_DEVICE_RESOURCES,
7221 mlx5_ib_stage_dev_res_init,4712 mlx5_ib_dev_res_init,
7222 mlx5_ib_stage_dev_res_cleanup),4713 mlx5_ib_dev_res_cleanup),
7223 STAGE_CREATE(MLX5_IB_STAGE_DEVICE_NOTIFIER,4714 STAGE_CREATE(MLX5_IB_STAGE_DEVICE_NOTIFIER,
7224 mlx5_ib_stage_dev_notifier_init,4715 mlx5_ib_stage_dev_notifier_init,
7225 mlx5_ib_stage_dev_notifier_cleanup),4716 mlx5_ib_stage_dev_notifier_cleanup),
7226 STAGE_CREATE(MLX5_IB_STAGE_COUNTERS,4717 STAGE_CREATE(MLX5_IB_STAGE_COUNTERS,
7227 mlx5_ib_stage_counters_init,4718 mlx5_ib_counters_init,
7228 mlx5_ib_stage_counters_cleanup),4719 mlx5_ib_counters_cleanup),
7229 STAGE_CREATE(MLX5_IB_STAGE_CONG_DEBUGFS,4720 STAGE_CREATE(MLX5_IB_STAGE_CONG_DEBUGFS,
7230 mlx5_ib_stage_cong_debugfs_init,4721 mlx5_ib_stage_cong_debugfs_init,
7231 mlx5_ib_stage_cong_debugfs_cleanup),4722 mlx5_ib_stage_cong_debugfs_cleanup),
@@ -7239,14 +4730,17 @@ const struct mlx5_ib_profile raw_eth_profile = { · 7 unmodified lines
7239 NULL,4730 NULL,
7240 mlx5_ib_stage_pre_ib_reg_umr_cleanup),4731 mlx5_ib_stage_pre_ib_reg_umr_cleanup),
7241 STAGE_CREATE(MLX5_IB_STAGE_WHITELIST_UID,4732 STAGE_CREATE(MLX5_IB_STAGE_WHITELIST_UID,
7242 mlx5_ib_stage_devx_init,4733 mlx5_ib_devx_init,
7243 mlx5_ib_stage_devx_cleanup),4734 mlx5_ib_devx_cleanup),
7244 STAGE_CREATE(MLX5_IB_STAGE_IB_REG,4735 STAGE_CREATE(MLX5_IB_STAGE_IB_REG,
7245 mlx5_ib_stage_ib_reg_init,4736 mlx5_ib_stage_ib_reg_init,
7246 mlx5_ib_stage_ib_reg_cleanup),4737 mlx5_ib_stage_ib_reg_cleanup),
7247 STAGE_CREATE(MLX5_IB_STAGE_POST_IB_REG_UMR,4738 STAGE_CREATE(MLX5_IB_STAGE_POST_IB_REG_UMR,
7248 mlx5_ib_stage_post_ib_reg_umr_init,4739 mlx5_ib_stage_post_ib_reg_umr_init,
7249 NULL),4740 NULL),
4741 STAGE_CREATE(MLX5_IB_STAGE_RESTRACK,
4742 mlx5_ib_restrack_init,
4743 NULL),
7250};4744};
7251 4745
7252static void *mlx5_ib_add_slave_port(struct mlx5_core_dev *mdev)4746static void *mlx5_ib_add_slave_port(struct mlx5_core_dev *mdev)
drivers/infiniband/hw/mlx5/mlx5_ib.h+17−92
@@ -1,33 +1,6 @@
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
1/*2/*
2 * Copyright (c) 2013-2015, Mellanox Technologies. All rights reserved.3 * Copyright (c) 2013-2020, Mellanox Technologies inc. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */4 */
32 5
33#ifndef MLX5_IB_H6#ifndef MLX5_IB_H
@@ -730,8 +703,8 @@ struct mlx5_ib_port_resources { · 696 unmodified lines
730 703
731struct mlx5_ib_resources {704struct mlx5_ib_resources {
732 struct ib_cq *c0;705 struct ib_cq *c0;
733 struct ib_xrcd *x0;706 u32 xrcdn0;
734 struct ib_xrcd *x1;707 u32 xrcdn1;
735 struct ib_pd *p0;708 struct ib_pd *p0;
736 struct ib_srq *s0;709 struct ib_srq *s0;
737 struct ib_srq *s1;710 struct ib_srq *s1;
@@ -832,7 +805,7 @@ struct mlx5_ib_delay_drop { · 94 unmodified lines
832 805
833enum mlx5_ib_stages {806enum mlx5_ib_stages {
834 MLX5_IB_STAGE_INIT,807 MLX5_IB_STAGE_INIT,
835 MLX5_IB_STAGE_FLOW_DB,808 MLX5_IB_STAGE_FS,
836 MLX5_IB_STAGE_CAPS,809 MLX5_IB_STAGE_CAPS,
837 MLX5_IB_STAGE_NON_DEFAULT_CB,810 MLX5_IB_STAGE_NON_DEFAULT_CB,
838 MLX5_IB_STAGE_ROCE,811 MLX5_IB_STAGE_ROCE,
@@ -850,7 +823,7 @@ enum mlx5_ib_stages { · 11 unmodified lines
850 MLX5_IB_STAGE_IB_REG,823 MLX5_IB_STAGE_IB_REG,
851 MLX5_IB_STAGE_POST_IB_REG_UMR,824 MLX5_IB_STAGE_POST_IB_REG_UMR,
852 MLX5_IB_STAGE_DELAY_DROP,825 MLX5_IB_STAGE_DELAY_DROP,
853 MLX5_IB_STAGE_CLASS_ATTR,826 MLX5_IB_STAGE_RESTRACK,
854 MLX5_IB_STAGE_MAX,827 MLX5_IB_STAGE_MAX,
855};828};
856 829
@@ -1078,11 +1051,6 @@ static inline struct mlx5_ib_rwq *to_mibrwq(struct mlx5_core_qp *core_qp) · 221 unmodified lines
1078 return container_of(core_qp, struct mlx5_ib_rwq, core_qp);1051 return container_of(core_qp, struct mlx5_ib_rwq, core_qp);
1079}1052}
1080 1053
1081static inline struct mlx5_ib_mr *to_mibmr(struct mlx5_core_mkey *mmkey)
1082{
1083 return container_of(mmkey, struct mlx5_ib_mr, mmkey);
1084}
1085
1086static inline struct mlx5_ib_pd *to_mpd(struct ib_pd *ibpd)1054static inline struct mlx5_ib_pd *to_mpd(struct ib_pd *ibpd)
1087{1055{
1088 return container_of(ibpd, struct mlx5_ib_pd, ibpd);1056 return container_of(ibpd, struct mlx5_ib_pd, ibpd);
@@ -1210,7 +1178,7 @@ int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start, · 121 unmodified lines
1210 struct ib_pd *pd, struct ib_udata *udata);1178 struct ib_pd *pd, struct ib_udata *udata);
1211int mlx5_ib_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata);1179int mlx5_ib_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata);
1212struct ib_mr *mlx5_ib_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,1180struct ib_mr *mlx5_ib_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
1213 u32 max_num_sg, struct ib_udata *udata);1181 u32 max_num_sg);
1214struct ib_mr *mlx5_ib_alloc_mr_integrity(struct ib_pd *pd,1182struct ib_mr *mlx5_ib_alloc_mr_integrity(struct ib_pd *pd,
1215 u32 max_num_sg,1183 u32 max_num_sg,
1216 u32 max_num_meta_sg);1184 u32 max_num_meta_sg);
@@ -1224,9 +1192,8 @@ int mlx5_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, · 7 unmodified lines
1224 const struct ib_wc *in_wc, const struct ib_grh *in_grh,1192 const struct ib_wc *in_wc, const struct ib_grh *in_grh,
1225 const struct ib_mad *in, struct ib_mad *out,1193 const struct ib_mad *in, struct ib_mad *out,
1226 size_t *out_mad_size, u16 *out_mad_pkey_index);1194 size_t *out_mad_size, u16 *out_mad_pkey_index);
1227struct ib_xrcd *mlx5_ib_alloc_xrcd(struct ib_device *ibdev,1195int mlx5_ib_alloc_xrcd(struct ib_xrcd *xrcd, struct ib_udata *udata);
1228 struct ib_udata *udata);1196void mlx5_ib_dealloc_xrcd(struct ib_xrcd *xrcd, struct ib_udata *udata);
1229int mlx5_ib_dealloc_xrcd(struct ib_xrcd *xrcd, struct ib_udata *udata);
1230int mlx5_ib_get_buf_offset(u64 addr, int page_shift, u32 *offset);1197int mlx5_ib_get_buf_offset(u64 addr, int page_shift, u32 *offset);
1231int mlx5_query_ext_port_caps(struct mlx5_ib_dev *dev, u8 port);1198int mlx5_query_ext_port_caps(struct mlx5_ib_dev *dev, u8 port);
1232int mlx5_query_mad_ifc_smp_attr_node_info(struct ib_device *ibdev,1199int mlx5_query_mad_ifc_smp_attr_node_info(struct ib_device *ibdev,
@@ -1375,46 +1342,12 @@ struct mlx5_core_dev *mlx5_ib_get_native_port_mdev(struct mlx5_ib_dev *dev, · 142 unmodified lines
1375 u8 *native_port_num);1342 u8 *native_port_num);
1376void mlx5_ib_put_native_port_mdev(struct mlx5_ib_dev *dev,1343void mlx5_ib_put_native_port_mdev(struct mlx5_ib_dev *dev,
1377 u8 port_num);1344 u8 port_num);
1378int mlx5_ib_fill_res_entry(struct sk_buff *msg,
1379 struct rdma_restrack_entry *res);
1380int mlx5_ib_fill_stat_entry(struct sk_buff *msg,
1381 struct rdma_restrack_entry *res);
1382 1345
1383extern const struct uapi_definition mlx5_ib_devx_defs[];1346extern const struct uapi_definition mlx5_ib_devx_defs[];
1384extern const struct uapi_definition mlx5_ib_flow_defs[];1347extern const struct uapi_definition mlx5_ib_flow_defs[];
1385extern const struct uapi_definition mlx5_ib_qos_defs[];1348extern const struct uapi_definition mlx5_ib_qos_defs[];
1349extern const struct uapi_definition mlx5_ib_std_types_defs[];
1386 1350
1387#if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS)
1388int mlx5_ib_devx_create(struct mlx5_ib_dev *dev, bool is_user);
1389void mlx5_ib_devx_destroy(struct mlx5_ib_dev *dev, u16 uid);
1390void mlx5_ib_devx_init_event_table(struct mlx5_ib_dev *dev);
1391void mlx5_ib_devx_cleanup_event_table(struct mlx5_ib_dev *dev);
1392struct mlx5_ib_flow_handler *mlx5_ib_raw_fs_rule_add(
1393 struct mlx5_ib_dev *dev, struct mlx5_ib_flow_matcher *fs_matcher,
1394 struct mlx5_flow_context *flow_context,
1395 struct mlx5_flow_act *flow_act, u32 counter_id,
1396 void *cmd_in, int inlen, int dest_id, int dest_type);
1397bool mlx5_ib_devx_is_flow_dest(void *obj, int *dest_id, int *dest_type);
1398bool mlx5_ib_devx_is_flow_counter(void *obj, u32 offset, u32 *counter_id);
1399void mlx5_ib_destroy_flow_action_raw(struct mlx5_ib_flow_action *maction);
1400#else
1401static inline int
1402mlx5_ib_devx_create(struct mlx5_ib_dev *dev,
1403 bool is_user) { return -EOPNOTSUPP; }
1404static inline void mlx5_ib_devx_destroy(struct mlx5_ib_dev *dev, u16 uid) {}
1405static inline void mlx5_ib_devx_init_event_table(struct mlx5_ib_dev *dev) {}
1406static inline void mlx5_ib_devx_cleanup_event_table(struct mlx5_ib_dev *dev) {}
1407static inline bool mlx5_ib_devx_is_flow_dest(void *obj, int *dest_id,
1408 int *dest_type)
1409{
1410 return false;
1411}
1412static inline void
1413mlx5_ib_destroy_flow_action_raw(struct mlx5_ib_flow_action *maction)
1414{
1415 return;
1416};
1417#endif
1418static inline void init_query_mad(struct ib_smp *mad)1351static inline void init_query_mad(struct ib_smp *mad)
1419{1352{
1420 mad->base_version = 1;1353 mad->base_version = 1;
@@ -1423,15 +1356,6 @@ static inline void init_query_mad(struct ib_smp *mad) · 2 unmodified lines
1423 mad->method = IB_MGMT_METHOD_GET;1356 mad->method = IB_MGMT_METHOD_GET;
1424}1357}
1425 1358
1426static inline u8 convert_access(int acc)
1427{
1428 return (acc & IB_ACCESS_REMOTE_ATOMIC ? MLX5_PERM_ATOMIC : 0) |
1429 (acc & IB_ACCESS_REMOTE_WRITE ? MLX5_PERM_REMOTE_WRITE : 0) |
1430 (acc & IB_ACCESS_REMOTE_READ ? MLX5_PERM_REMOTE_READ : 0) |
1431 (acc & IB_ACCESS_LOCAL_WRITE ? MLX5_PERM_LOCAL_WRITE : 0) |
1432 MLX5_PERM_LOCAL_READ;
1433}
1434
1435static inline int is_qp1(enum ib_qp_type qp_type)1359static inline int is_qp1(enum ib_qp_type qp_type)
1436{1360{
1437 return qp_type == MLX5_IB_QPT_HW_GSI;1361 return qp_type == MLX5_IB_QPT_HW_GSI;
@@ -1518,9 +1442,6 @@ int bfregn_to_uar_index(struct mlx5_ib_dev *dev, · 80 unmodified lines
1518 struct mlx5_bfreg_info *bfregi, u32 bfregn,1442 struct mlx5_bfreg_info *bfregi, u32 bfregn,
1519 bool dyn_bfreg);1443 bool dyn_bfreg);
1520 1444
1521int mlx5_ib_qp_set_counter(struct ib_qp *qp, struct rdma_counter *counter);
1522u16 mlx5_ib_get_counters_id(struct mlx5_ib_dev *dev, u8 port_num);
1523
1524static inline bool mlx5_ib_can_use_umr(struct mlx5_ib_dev *dev,1445static inline bool mlx5_ib_can_use_umr(struct mlx5_ib_dev *dev,
1525 bool do_modify_atomic, int access_flags)1446 bool do_modify_atomic, int access_flags)
1526{1447{
@@ -1533,14 +1454,18 @@ static inline bool mlx5_ib_can_use_umr(struct mlx5_ib_dev *dev, · 6 unmodified lines
1533 return false;1454 return false;
1534 1455
1535 if (access_flags & IB_ACCESS_RELAXED_ORDERING &&1456 if (access_flags & IB_ACCESS_RELAXED_ORDERING &&
1536 (MLX5_CAP_GEN(dev->mdev, relaxed_ordering_write) ||1457 MLX5_CAP_GEN(dev->mdev, relaxed_ordering_write) &&
1537 MLX5_CAP_GEN(dev->mdev, relaxed_ordering_read)))1458 !MLX5_CAP_GEN(dev->mdev, relaxed_ordering_write_umr))
1459 return false;
1460
1461 if (access_flags & IB_ACCESS_RELAXED_ORDERING &&
1462 MLX5_CAP_GEN(dev->mdev, relaxed_ordering_read) &&
1463 !MLX5_CAP_GEN(dev->mdev, relaxed_ordering_read_umr))
1538 return false;1464 return false;
1539 1465
1540 return true;1466 return true;
1541}1467}
1542 1468
1543int mlx5_ib_enable_driver(struct ib_device *dev);
1544int mlx5_ib_test_wc(struct mlx5_ib_dev *dev);1469int mlx5_ib_test_wc(struct mlx5_ib_dev *dev);
1545 1470
1546static inline bool mlx5_ib_lag_should_assign_affinity(struct mlx5_ib_dev *dev)1471static inline bool mlx5_ib_lag_should_assign_affinity(struct mlx5_ib_dev *dev)
drivers/infiniband/hw/mlx5/mr.c+1−1
@@ -1961,7 +1961,7 @@ err_free: · 1960 unmodified lines
1961}1961}
1962 1962
1963struct ib_mr *mlx5_ib_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,1963struct ib_mr *mlx5_ib_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
1964 u32 max_num_sg, struct ib_udata *udata)1964 u32 max_num_sg)
1965{1965{
1966 return __mlx5_ib_alloc_mr(pd, mr_type, max_num_sg, 0);1966 return __mlx5_ib_alloc_mr(pd, mr_type, max_num_sg, 0);
1967}1967}
drivers/infiniband/hw/mlx5/odp.c+19−9
@@ -816,6 +816,7 @@ static int pagefault_mr(struct mlx5_ib_mr *mr, u64 io_virt, size_t bcnt, · 815 unmodified lines
816{816{
817 struct ib_umem_odp *odp = to_ib_umem_odp(mr->umem);817 struct ib_umem_odp *odp = to_ib_umem_odp(mr->umem);
818 818
819 lockdep_assert_held(&mr->dev->odp_srcu);
819 if (unlikely(io_virt < mr->mmkey.iova))820 if (unlikely(io_virt < mr->mmkey.iova))
820 return -EFAULT;821 return -EFAULT;
821 822
@@ -929,11 +930,6 @@ next_mr: · 107 unmodified lines
929 if (ret < 0)930 if (ret < 0)
930 goto srcu_unlock;931 goto srcu_unlock;
931 932
932 /*
933 * When prefetching a page, page fault is generated
934 * in order to bring the page to the main memory.
935 * In the current flow, page faults are being counted.
936 */
937 mlx5_update_odp_stats(mr, faults, ret);933 mlx5_update_odp_stats(mr, faults, ret);
938 934
939 npages += ret;935 npages += ret;
@@ -1770,13 +1766,26 @@ static void mlx5_ib_prefetch_mr_work(struct work_struct *w) · 830 unmodified lines
1770{1766{
1771 struct prefetch_mr_work *work =1767 struct prefetch_mr_work *work =
1772 container_of(w, struct prefetch_mr_work, work);1768 container_of(w, struct prefetch_mr_work, work);
1769 struct mlx5_ib_dev *dev;
1773 u32 bytes_mapped = 0;1770 u32 bytes_mapped = 0;
1771 int srcu_key;
1772 int ret;
1774 u32 i;1773 u32 i;
1775 1774
1776 for (i = 0; i < work->num_sge; ++i)1775 /* We rely on IB/core that work is executed if we have num_sge != 0 only. */
1777 pagefault_mr(work->frags[i].mr, work->frags[i].io_virt,1776 WARN_ON(!work->num_sge);
1778 work->frags[i].length, &bytes_mapped,1777 dev = work->frags[0].mr->dev;
1779 work->pf_flags);1778 /* SRCU should be held when calling to mlx5_odp_populate_xlt() */
1779 srcu_key = srcu_read_lock(&dev->odp_srcu);
1780 for (i = 0; i < work->num_sge; ++i) {
1781 ret = pagefault_mr(work->frags[i].mr, work->frags[i].io_virt,
1782 work->frags[i].length, &bytes_mapped,
1783 work->pf_flags);
1784 if (ret <= 0)
1785 continue;
1786 mlx5_update_odp_stats(work->frags[i].mr, prefetch, ret);
1787 }
1788 srcu_read_unlock(&dev->odp_srcu, srcu_key);
1780 1789
1781 destroy_prefetch_work(work);1790 destroy_prefetch_work(work);
1782}1791}
@@ -1832,6 +1841,7 @@ static int mlx5_ib_prefetch_sg_list(struct ib_pd *pd, · 49 unmodified lines
1832 &bytes_mapped, pf_flags);1841 &bytes_mapped, pf_flags);
1833 if (ret < 0)1842 if (ret < 0)
1834 goto out;1843 goto out;
1844 mlx5_update_odp_stats(mr, prefetch, ret);
1835 }1845 }
1836 ret = 0;1846 ret = 0;
1837 1847
drivers/infiniband/hw/mlx5/qp.c+25−46
@@ -38,6 +38,7 @@ · 37 unmodified lines
38#include <linux/mlx5/fs.h>38#include <linux/mlx5/fs.h>
39#include "mlx5_ib.h"39#include "mlx5_ib.h"
40#include "ib_rep.h"40#include "ib_rep.h"
41#include "counters.h"
41#include "cmd.h"42#include "cmd.h"
42#include "qp.h"43#include "qp.h"
43#include "wr.h"44#include "wr.h"
@@ -2031,15 +2032,15 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd, · 1987 unmodified lines
2031 switch (init_attr->qp_type) {2032 switch (init_attr->qp_type) {
2032 case IB_QPT_XRC_INI:2033 case IB_QPT_XRC_INI:
2033 MLX5_SET(qpc, qpc, cqn_rcv, to_mcq(devr->c0)->mcq.cqn);2034 MLX5_SET(qpc, qpc, cqn_rcv, to_mcq(devr->c0)->mcq.cqn);
2034 MLX5_SET(qpc, qpc, xrcd, to_mxrcd(devr->x1)->xrcdn);2035 MLX5_SET(qpc, qpc, xrcd, devr->xrcdn1);
2035 MLX5_SET(qpc, qpc, srqn_rmpn_xrqn, to_msrq(devr->s0)->msrq.srqn);2036 MLX5_SET(qpc, qpc, srqn_rmpn_xrqn, to_msrq(devr->s0)->msrq.srqn);
2036 break;2037 break;
2037 default:2038 default:
2038 if (init_attr->srq) {2039 if (init_attr->srq) {
2039 MLX5_SET(qpc, qpc, xrcd, to_mxrcd(devr->x0)->xrcdn);2040 MLX5_SET(qpc, qpc, xrcd, devr->xrcdn0);
2040 MLX5_SET(qpc, qpc, srqn_rmpn_xrqn, to_msrq(init_attr->srq)->msrq.srqn);2041 MLX5_SET(qpc, qpc, srqn_rmpn_xrqn, to_msrq(init_attr->srq)->msrq.srqn);
2041 } else {2042 } else {
2042 MLX5_SET(qpc, qpc, xrcd, to_mxrcd(devr->x1)->xrcdn);2043 MLX5_SET(qpc, qpc, xrcd, devr->xrcdn1);
2043 MLX5_SET(qpc, qpc, srqn_rmpn_xrqn, to_msrq(devr->s1)->msrq.srqn);2044 MLX5_SET(qpc, qpc, srqn_rmpn_xrqn, to_msrq(devr->s1)->msrq.srqn);
2044 }2045 }
2045 }2046 }
@@ -2178,11 +2179,11 @@ static int create_kernel_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd, · 132 unmodified lines
2178 MLX5_SET(qpc, qpc, no_sq, 1);2179 MLX5_SET(qpc, qpc, no_sq, 1);
2179 2180
2180 if (attr->srq) {2181 if (attr->srq) {
2181 MLX5_SET(qpc, qpc, xrcd, to_mxrcd(devr->x0)->xrcdn);2182 MLX5_SET(qpc, qpc, xrcd, devr->xrcdn0);
2182 MLX5_SET(qpc, qpc, srqn_rmpn_xrqn,2183 MLX5_SET(qpc, qpc, srqn_rmpn_xrqn,
2183 to_msrq(attr->srq)->msrq.srqn);2184 to_msrq(attr->srq)->msrq.srqn);
2184 } else {2185 } else {
2185 MLX5_SET(qpc, qpc, xrcd, to_mxrcd(devr->x1)->xrcdn);2186 MLX5_SET(qpc, qpc, xrcd, devr->xrcdn1);
2186 MLX5_SET(qpc, qpc, srqn_rmpn_xrqn,2187 MLX5_SET(qpc, qpc, srqn_rmpn_xrqn,
2187 to_msrq(devr->s1)->msrq.srqn);2188 to_msrq(devr->s1)->msrq.srqn);
2188 }2189 }
@@ -3554,7 +3555,7 @@ static int modify_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp, · 1365 unmodified lines
3554 switch (raw_qp_param->operation) {3555 switch (raw_qp_param->operation) {
3555 case MLX5_CMD_OP_RST2INIT_QP:3556 case MLX5_CMD_OP_RST2INIT_QP:
3556 rq_state = MLX5_RQC_STATE_RDY;3557 rq_state = MLX5_RQC_STATE_RDY;
3557 sq_state = MLX5_SQC_STATE_RDY;3558 sq_state = MLX5_SQC_STATE_RST;
3558 break;3559 break;
3559 case MLX5_CMD_OP_2ERR_QP:3560 case MLX5_CMD_OP_2ERR_QP:
3560 rq_state = MLX5_RQC_STATE_ERR;3561 rq_state = MLX5_RQC_STATE_ERR;
@@ -3566,13 +3567,11 @@ static int modify_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp, · 5 unmodified lines
3566 break;3567 break;
3567 case MLX5_CMD_OP_RTR2RTS_QP:3568 case MLX5_CMD_OP_RTR2RTS_QP:
3568 case MLX5_CMD_OP_RTS2RTS_QP:3569 case MLX5_CMD_OP_RTS2RTS_QP:
3569 if (raw_qp_param->set_mask ==3570 if (raw_qp_param->set_mask & ~MLX5_RAW_QP_RATE_LIMIT)
3570 MLX5_RAW_QP_RATE_LIMIT) {3571 return -EINVAL;
3571 modify_rq = 0;3572
3572 sq_state = sq->state;3573 modify_rq = 0;
3573 } else {3574 sq_state = MLX5_SQC_STATE_RDY;
3574 return raw_qp_param->set_mask ? -EINVAL : 0;
3575 }
3576 break;3575 break;
3577 case MLX5_CMD_OP_INIT2INIT_QP:3576 case MLX5_CMD_OP_INIT2INIT_QP:
3578 case MLX5_CMD_OP_INIT2RTR_QP:3577 case MLX5_CMD_OP_INIT2RTR_QP:
@@ -4114,9 +4113,9 @@ static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr, · 535 unmodified lines
4114 struct mlx5_ib_qp *qp = to_mqp(ibqp);4113 struct mlx5_ib_qp *qp = to_mqp(ibqp);
4115 struct mlx5_ib_dev *dev = to_mdev(ibqp->device);4114 struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
4116 enum ib_qp_state cur_state, new_state;4115 enum ib_qp_state cur_state, new_state;
4117 int err = 0;
4118 int required = IB_QP_STATE;4116 int required = IB_QP_STATE;
4119 void *dctc;4117 void *dctc;
4118 int err;
4120 4119
4121 if (!(attr_mask & IB_QP_STATE))4120 if (!(attr_mask & IB_QP_STATE))
4122 return -EINVAL;4121 return -EINVAL;
@@ -4208,11 +4207,9 @@ static int mlx5_ib_modify_dct(struct ib_qp *ibqp, struct ib_qp_attr *attr, · 85 unmodified lines
4208 mlx5_ib_warn(dev, "Modify DCT: Invalid transition from %d to %d\n", cur_state, new_state);4207 mlx5_ib_warn(dev, "Modify DCT: Invalid transition from %d to %d\n", cur_state, new_state);
4209 return -EINVAL;4208 return -EINVAL;
4210 }4209 }
4211 if (err)4210
4212 qp->state = IB_QPS_ERR;4211 qp->state = new_state;
4213 else4212 return 0;
4214 qp->state = new_state;
4215 return err;
4216}4213}
4217 4214
4218int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,4215int mlx5_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
@@ -4450,7 +4447,7 @@ static int sqrq_state_to_qp_state(u8 sq_state, u8 rq_state, · 231 unmodified lines
4450 [MLX5_SQ_STATE_NA] = IB_QPS_RESET,4447 [MLX5_SQ_STATE_NA] = IB_QPS_RESET,
4451 },4448 },
4452 [MLX5_RQC_STATE_RDY] = {4449 [MLX5_RQC_STATE_RDY] = {
4453 [MLX5_SQC_STATE_RST] = MLX5_QP_STATE_BAD,4450 [MLX5_SQC_STATE_RST] = MLX5_QP_STATE,
4454 [MLX5_SQC_STATE_RDY] = MLX5_QP_STATE,4451 [MLX5_SQC_STATE_RDY] = MLX5_QP_STATE,
4455 [MLX5_SQC_STATE_ERR] = IB_QPS_SQE,4452 [MLX5_SQC_STATE_ERR] = IB_QPS_SQE,
4456 [MLX5_SQ_STATE_NA] = MLX5_QP_STATE,4453 [MLX5_SQ_STATE_NA] = MLX5_QP_STATE,
@@ -4462,7 +4459,7 @@ static int sqrq_state_to_qp_state(u8 sq_state, u8 rq_state, · 5 unmodified lines
4462 [MLX5_SQ_STATE_NA] = IB_QPS_ERR,4459 [MLX5_SQ_STATE_NA] = IB_QPS_ERR,
4463 },4460 },
4464 [MLX5_RQ_STATE_NA] = {4461 [MLX5_RQ_STATE_NA] = {
4465 [MLX5_SQC_STATE_RST] = IB_QPS_RESET,4462 [MLX5_SQC_STATE_RST] = MLX5_QP_STATE,
4466 [MLX5_SQC_STATE_RDY] = MLX5_QP_STATE,4463 [MLX5_SQC_STATE_RDY] = MLX5_QP_STATE,
4467 [MLX5_SQC_STATE_ERR] = MLX5_QP_STATE,4464 [MLX5_SQC_STATE_ERR] = MLX5_QP_STATE,
4468 [MLX5_SQ_STATE_NA] = MLX5_QP_STATE_BAD,4465 [MLX5_SQ_STATE_NA] = MLX5_QP_STATE_BAD,
@@ -4708,41 +4705,23 @@ out: · 239 unmodified lines
4708 return err;4705 return err;
4709}4706}
4710 4707
4711struct ib_xrcd *mlx5_ib_alloc_xrcd(struct ib_device *ibdev,4708int mlx5_ib_alloc_xrcd(struct ib_xrcd *ibxrcd, struct ib_udata *udata)
4712 struct ib_udata *udata)
4713{4709{
4714 struct mlx5_ib_dev *dev = to_mdev(ibdev);4710 struct mlx5_ib_dev *dev = to_mdev(ibxrcd->device);
4715 struct mlx5_ib_xrcd *xrcd;4711 struct mlx5_ib_xrcd *xrcd = to_mxrcd(ibxrcd);
4716 int err;
4717 4712
4718 if (!MLX5_CAP_GEN(dev->mdev, xrc))4713 if (!MLX5_CAP_GEN(dev->mdev, xrc))
4719 return ERR_PTR(-ENOSYS);4714 return -EOPNOTSUPP;
4720
4721 xrcd = kmalloc(sizeof(*xrcd), GFP_KERNEL);
4722 if (!xrcd)
4723 return ERR_PTR(-ENOMEM);
4724
4725 err = mlx5_cmd_xrcd_alloc(dev->mdev, &xrcd->xrcdn, 0);
4726 if (err) {
4727 kfree(xrcd);
4728 return ERR_PTR(-ENOMEM);
4729 }
4730 4715
4731 return &xrcd->ibxrcd;4716 return mlx5_cmd_xrcd_alloc(dev->mdev, &xrcd->xrcdn, 0);
4732}4717}
4733 4718
4734int mlx5_ib_dealloc_xrcd(struct ib_xrcd *xrcd, struct ib_udata *udata)4719void mlx5_ib_dealloc_xrcd(struct ib_xrcd *xrcd, struct ib_udata *udata)
4735{4720{
4736 struct mlx5_ib_dev *dev = to_mdev(xrcd->device);4721 struct mlx5_ib_dev *dev = to_mdev(xrcd->device);
4737 u32 xrcdn = to_mxrcd(xrcd)->xrcdn;4722 u32 xrcdn = to_mxrcd(xrcd)->xrcdn;
4738 int err;
4739 4723
4740 err = mlx5_cmd_xrcd_dealloc(dev->mdev, xrcdn, 0);4724 mlx5_cmd_xrcd_dealloc(dev->mdev, xrcdn, 0);
4741 if (err)
4742 mlx5_ib_warn(dev, "failed to dealloc xrcdn 0x%x\n", xrcdn);
4743
4744 kfree(xrcd);
4745 return 0;
4746}4725}
4747 4726
4748static void mlx5_ib_wq_event(struct mlx5_core_qp *core_qp, int type)4727static void mlx5_ib_wq_event(struct mlx5_core_qp *core_qp, int type)
drivers/infiniband/hw/mlx5/qp.h+1−0
@@ -43,4 +43,5 @@ void mlx5_core_res_put(struct mlx5_core_rsc_common *res); · 42 unmodified lines
43 43
44int mlx5_core_xrcd_alloc(struct mlx5_ib_dev *dev, u32 *xrcdn);44int mlx5_core_xrcd_alloc(struct mlx5_ib_dev *dev, u32 *xrcdn);
45int mlx5_core_xrcd_dealloc(struct mlx5_ib_dev *dev, u32 xrcdn);45int mlx5_core_xrcd_dealloc(struct mlx5_ib_dev *dev, u32 xrcdn);
46int mlx5_ib_qp_set_counter(struct ib_qp *qp, struct rdma_counter *counter);
46#endif /* _MLX5_IB_QP_H */47#endif /* _MLX5_IB_QP_H */
drivers/infiniband/hw/mlx5/restrack.c+105−16
@@ -1,17 +1,85 @@
1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2/*2/*
3 * Copyright (c) 2019, Mellanox Technologies inc. All rights reserved.3 * Copyright (c) 2019-2020, Mellanox Technologies Ltd. All rights reserved.
4 */4 */
5 5
6#include <uapi/rdma/rdma_netlink.h>6#include <uapi/rdma/rdma_netlink.h>
7#include <linux/mlx5/rsc_dump.h>
7#include <rdma/ib_umem_odp.h>8#include <rdma/ib_umem_odp.h>
8#include <rdma/restrack.h>9#include <rdma/restrack.h>
9#include "mlx5_ib.h"10#include "mlx5_ib.h"
11#include "restrack.h"
10 12
11static int fill_stat_mr_entry(struct sk_buff *msg,13#define MAX_DUMP_SIZE 1024
12 struct rdma_restrack_entry *res)14
15static int dump_rsc(struct mlx5_core_dev *dev, enum mlx5_sgmt_type type,
16 int index, void *data, int *data_len)
17{
18 struct mlx5_core_dev *mdev = dev;
19 struct mlx5_rsc_dump_cmd *cmd;
20 struct mlx5_rsc_key key = {};
21 struct page *page;
22 int offset = 0;
23 int err = 0;
24 int cmd_err;
25 int size;
26
27 page = alloc_page(GFP_KERNEL);
28 if (!page)
29 return -ENOMEM;
30
31 key.size = PAGE_SIZE;
32 key.rsc = type;
33 key.index1 = index;
34 key.num_of_obj1 = 1;
35
36 cmd = mlx5_rsc_dump_cmd_create(mdev, &key);
37 if (IS_ERR(cmd)) {
38 err = PTR_ERR(cmd);
39 goto free_page;
40 }
41
42 do {
43 cmd_err = mlx5_rsc_dump_next(mdev, cmd, page, &size);
44 if (cmd_err < 0 || size + offset > MAX_DUMP_SIZE) {
45 err = cmd_err;
46 goto destroy_cmd;
47 }
48 memcpy(data + offset, page_address(page), size);
49 offset += size;
50 } while (cmd_err > 0);
51 *data_len = offset;
52
53destroy_cmd:
54 mlx5_rsc_dump_cmd_destroy(cmd);
55free_page:
56 __free_page(page);
57 return err;
58}
59
60static int fill_res_raw(struct sk_buff *msg, struct mlx5_ib_dev *dev,
61 enum mlx5_sgmt_type type, u32 key)
62{
63 int len = 0;
64 void *data;
65 int err;
66
67 data = kzalloc(MAX_DUMP_SIZE, GFP_KERNEL);
68 if (!data)
69 return -ENOMEM;
70
71 err = dump_rsc(dev->mdev, type, key, data, &len);
72 if (err)
73 goto out;
74
75 err = nla_put(msg, RDMA_NLDEV_ATTR_RES_RAW, len, data);
76out:
77 kfree(data);
78 return err;
79}
80
81static int fill_stat_mr_entry(struct sk_buff *msg, struct ib_mr *ibmr)
13{82{
14 struct ib_mr *ibmr = container_of(res, struct ib_mr, res);
15 struct mlx5_ib_mr *mr = to_mmr(ibmr);83 struct mlx5_ib_mr *mr = to_mmr(ibmr);
16 struct nlattr *table_attr;84 struct nlattr *table_attr;
17 85
@@ -31,6 +99,9 @@ static int fill_stat_mr_entry(struct sk_buff *msg, · 13 unmodified lines
31 msg, "page_invalidations",99 msg, "page_invalidations",
32 atomic64_read(&mr->odp_stats.invalidations)))100 atomic64_read(&mr->odp_stats.invalidations)))
33 goto err_table;101 goto err_table;
102 if (rdma_nl_stat_hwcounter_entry(msg, "page_prefetch",
103 atomic64_read(&mr->odp_stats.prefetch)))
104 goto err_table;
34 105
35 nla_nest_end(msg, table_attr);106 nla_nest_end(msg, table_attr);
36 return 0;107 return 0;
@@ -41,10 +112,16 @@ err: · 4 unmodified lines
41 return -EMSGSIZE;112 return -EMSGSIZE;
42}113}
43 114
44static int fill_res_mr_entry(struct sk_buff *msg,115static int fill_res_mr_entry_raw(struct sk_buff *msg, struct ib_mr *ibmr)
45 struct rdma_restrack_entry *res)116{
117 struct mlx5_ib_mr *mr = to_mmr(ibmr);
118
119 return fill_res_raw(msg, mr->dev, MLX5_SGMT_TYPE_PRM_QUERY_MKEY,
120 mlx5_mkey_to_idx(mr->mmkey.key));
121}
122
123static int fill_res_mr_entry(struct sk_buff *msg, struct ib_mr *ibmr)
46{124{
47 struct ib_mr *ibmr = container_of(res, struct ib_mr, res);
48 struct mlx5_ib_mr *mr = to_mmr(ibmr);125 struct mlx5_ib_mr *mr = to_mmr(ibmr);
49 struct nlattr *table_attr;126 struct nlattr *table_attr;
50 127
@@ -71,20 +148,32 @@ err: · 20 unmodified lines
71 return -EMSGSIZE;148 return -EMSGSIZE;
72}149}
73 150
74int mlx5_ib_fill_res_entry(struct sk_buff *msg,151static int fill_res_cq_entry_raw(struct sk_buff *msg, struct ib_cq *ibcq)
75 struct rdma_restrack_entry *res)
76{152{
77 if (res->type == RDMA_RESTRACK_MR)153 struct mlx5_ib_dev *dev = to_mdev(ibcq->device);
78 return fill_res_mr_entry(msg, res);154 struct mlx5_ib_cq *cq = to_mcq(ibcq);
79 155
80 return 0;156 return fill_res_raw(msg, dev, MLX5_SGMT_TYPE_PRM_QUERY_CQ, cq->mcq.cqn);
81}157}
82 158
83int mlx5_ib_fill_stat_entry(struct sk_buff *msg,159static int fill_res_qp_entry_raw(struct sk_buff *msg, struct ib_qp *ibqp)
84 struct rdma_restrack_entry *res)
85{160{
86 if (res->type == RDMA_RESTRACK_MR)161 struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
87 return fill_stat_mr_entry(msg, res);162
163 return fill_res_raw(msg, dev, MLX5_SGMT_TYPE_PRM_QUERY_QP,
164 ibqp->qp_num);
165}
88 166
167static const struct ib_device_ops restrack_ops = {
168 .fill_res_cq_entry_raw = fill_res_cq_entry_raw,
169 .fill_res_mr_entry = fill_res_mr_entry,
170 .fill_res_mr_entry_raw = fill_res_mr_entry_raw,
171 .fill_res_qp_entry_raw = fill_res_qp_entry_raw,
172 .fill_stat_mr_entry = fill_stat_mr_entry,
173};
174
175int mlx5_ib_restrack_init(struct mlx5_ib_dev *dev)
176{
177 ib_set_device_ops(&dev->ib_dev, &restrack_ops);
89 return 0;178 return 0;
90}179}
drivers/infiniband/hw/mlx5/restrack.h+13−0
@@ -0,0 +1,13 @@
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
2/*
3 * Copyright (c) 2013-2020, Mellanox Technologies Ltd. All rights reserved.
4 */
5
6#ifndef _MLX5_IB_RESTRACK_H
7#define _MLX5_IB_RESTRACK_H
8
9#include "mlx5_ib.h"
10
11int mlx5_ib_restrack_init(struct mlx5_ib_dev *dev);
12
13#endif /* _MLX5_IB_RESTRACK_H */
drivers/infiniband/hw/mlx5/srq.c+2−2
@@ -274,10 +274,10 @@ int mlx5_ib_create_srq(struct ib_srq *ib_srq, · 273 unmodified lines
274 if (srq->wq_sig)274 if (srq->wq_sig)
275 in.flags |= MLX5_SRQ_FLAG_WQ_SIG;275 in.flags |= MLX5_SRQ_FLAG_WQ_SIG;
276 276
277 if (init_attr->srq_type == IB_SRQT_XRC)277 if (init_attr->srq_type == IB_SRQT_XRC && init_attr->ext.xrc.xrcd)
278 in.xrcd = to_mxrcd(init_attr->ext.xrc.xrcd)->xrcdn;278 in.xrcd = to_mxrcd(init_attr->ext.xrc.xrcd)->xrcdn;
279 else279 else
280 in.xrcd = to_mxrcd(dev->devr.x0)->xrcdn;280 in.xrcd = dev->devr.xrcdn0;
281 281
282 if (init_attr->srq_type == IB_SRQT_TM) {282 if (init_attr->srq_type == IB_SRQT_TM) {
283 in.tm_log_list_size =283 in.tm_log_list_size =
drivers/infiniband/hw/mlx5/std_types.c+45−0
@@ -0,0 +1,45 @@
1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2/*
3 * Copyright (c) 2020, Mellanox Technologies inc. All rights reserved.
4 */
5
6#include <rdma/uverbs_ioctl.h>
7#include <rdma/mlx5_user_ioctl_cmds.h>
8#include <rdma/mlx5_user_ioctl_verbs.h>
9#include <linux/mlx5/driver.h>
10#include "mlx5_ib.h"
11
12#define UVERBS_MODULE_NAME mlx5_ib
13#include <rdma/uverbs_named_ioctl.h>
14
15static int UVERBS_HANDLER(MLX5_IB_METHOD_PD_QUERY)(
16 struct uverbs_attr_bundle *attrs)
17{
18 struct ib_pd *pd =
19 uverbs_attr_get_obj(attrs, MLX5_IB_ATTR_QUERY_PD_HANDLE);
20 struct mlx5_ib_pd *mpd = to_mpd(pd);
21
22 return uverbs_copy_to(attrs, MLX5_IB_ATTR_QUERY_PD_RESP_PDN,
23 &mpd->pdn, sizeof(mpd->pdn));
24}
25
26DECLARE_UVERBS_NAMED_METHOD(
27 MLX5_IB_METHOD_PD_QUERY,
28 UVERBS_ATTR_IDR(MLX5_IB_ATTR_QUERY_PD_HANDLE,
29 UVERBS_OBJECT_PD,
30 UVERBS_ACCESS_READ,
31 UA_MANDATORY),
32 UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_QUERY_PD_RESP_PDN,
33 UVERBS_ATTR_TYPE(u32),
34 UA_MANDATORY));
35
36ADD_UVERBS_METHODS(mlx5_ib_pd,
37 UVERBS_OBJECT_PD,
38 &UVERBS_METHOD(MLX5_IB_METHOD_PD_QUERY));
39
40const struct uapi_definition mlx5_ib_std_types_defs[] = {
41 UAPI_DEF_CHAIN_OBJ_TREE(
42 UVERBS_OBJECT_PD,
43 &mlx5_ib_pd),
44 {},
45};
drivers/infiniband/hw/mlx5/wr.c+50−18
@@ -263,7 +263,9 @@ static __be64 get_umr_update_translation_mask(void) · 262 unmodified lines
263 return cpu_to_be64(result);263 return cpu_to_be64(result);
264}264}
265 265
266static __be64 get_umr_update_access_mask(int atomic)266static __be64 get_umr_update_access_mask(int atomic,
267 int relaxed_ordering_write,
268 int relaxed_ordering_read)
267{269{
268 u64 result;270 u64 result;
269 271
@@ -275,6 +277,12 @@ static __be64 get_umr_update_access_mask(int atomic) · 5 unmodified lines
275 if (atomic)277 if (atomic)
276 result |= MLX5_MKEY_MASK_A;278 result |= MLX5_MKEY_MASK_A;
277 279
280 if (relaxed_ordering_write)
281 result |= MLX5_MKEY_MASK_RELAXED_ORDERING_WRITE;
282
283 if (relaxed_ordering_read)
284 result |= MLX5_MKEY_MASK_RELAXED_ORDERING_READ;
285
278 return cpu_to_be64(result);286 return cpu_to_be64(result);
279}287}
280 288
@@ -289,17 +297,28 @@ static __be64 get_umr_update_pd_mask(void) · 8 unmodified lines
289 297
290static int umr_check_mkey_mask(struct mlx5_ib_dev *dev, u64 mask)298static int umr_check_mkey_mask(struct mlx5_ib_dev *dev, u64 mask)
291{299{
292 if ((mask & MLX5_MKEY_MASK_PAGE_SIZE &&300 if (mask & MLX5_MKEY_MASK_PAGE_SIZE &&
293 MLX5_CAP_GEN(dev->mdev, umr_modify_entity_size_disabled)) ||301 MLX5_CAP_GEN(dev->mdev, umr_modify_entity_size_disabled))
294 (mask & MLX5_MKEY_MASK_A &&
295 MLX5_CAP_GEN(dev->mdev, umr_modify_atomic_disabled)))
296 return -EPERM;302 return -EPERM;
303
304 if (mask & MLX5_MKEY_MASK_A &&
305 MLX5_CAP_GEN(dev->mdev, umr_modify_atomic_disabled))
306 return -EPERM;
307
308 if (mask & MLX5_MKEY_MASK_RELAXED_ORDERING_WRITE &&
309 !MLX5_CAP_GEN(dev->mdev, relaxed_ordering_write_umr))
310 return -EPERM;
311
312 if (mask & MLX5_MKEY_MASK_RELAXED_ORDERING_READ &&
313 !MLX5_CAP_GEN(dev->mdev, relaxed_ordering_read_umr))
314 return -EPERM;
315
297 return 0;316 return 0;
298}317}
299 318
300static int set_reg_umr_segment(struct mlx5_ib_dev *dev,319static int set_reg_umr_segment(struct mlx5_ib_dev *dev,
301 struct mlx5_wqe_umr_ctrl_seg *umr,320 struct mlx5_wqe_umr_ctrl_seg *umr,
302 const struct ib_send_wr *wr, int atomic)321 const struct ib_send_wr *wr)
303{322{
304 const struct mlx5_umr_wr *umrwr = umr_wr(wr);323 const struct mlx5_umr_wr *umrwr = umr_wr(wr);
305 324
@@ -325,7 +344,10 @@ static int set_reg_umr_segment(struct mlx5_ib_dev *dev, · 19 unmodified lines
325 if (wr->send_flags & MLX5_IB_SEND_UMR_UPDATE_TRANSLATION)344 if (wr->send_flags & MLX5_IB_SEND_UMR_UPDATE_TRANSLATION)
326 umr->mkey_mask |= get_umr_update_translation_mask();345 umr->mkey_mask |= get_umr_update_translation_mask();
327 if (wr->send_flags & MLX5_IB_SEND_UMR_UPDATE_PD_ACCESS) {346 if (wr->send_flags & MLX5_IB_SEND_UMR_UPDATE_PD_ACCESS) {
328 umr->mkey_mask |= get_umr_update_access_mask(atomic);347 umr->mkey_mask |= get_umr_update_access_mask(
348 !!(MLX5_CAP_GEN(dev->mdev, atomic)),
349 !!(MLX5_CAP_GEN(dev->mdev, relaxed_ordering_write_umr)),
350 !!(MLX5_CAP_GEN(dev->mdev, relaxed_ordering_read_umr)));
329 umr->mkey_mask |= get_umr_update_pd_mask();351 umr->mkey_mask |= get_umr_update_pd_mask();
330 }352 }
331 if (wr->send_flags & MLX5_IB_SEND_UMR_ENABLE_MR)353 if (wr->send_flags & MLX5_IB_SEND_UMR_ENABLE_MR)
@@ -383,20 +405,31 @@ static void set_reg_mkey_segment(struct mlx5_mkey_seg *seg, · 51 unmodified lines
383 405
384 memset(seg, 0, sizeof(*seg));406 memset(seg, 0, sizeof(*seg));
385 if (wr->send_flags & MLX5_IB_SEND_UMR_DISABLE_MR)407 if (wr->send_flags & MLX5_IB_SEND_UMR_DISABLE_MR)
386 seg->status = MLX5_MKEY_STATUS_FREE;408 MLX5_SET(mkc, seg, free, 1);
409
410 MLX5_SET(mkc, seg, a,
411 !!(umrwr->access_flags & IB_ACCESS_REMOTE_ATOMIC));
412 MLX5_SET(mkc, seg, rw,
413 !!(umrwr->access_flags & IB_ACCESS_REMOTE_WRITE));
414 MLX5_SET(mkc, seg, rr, !!(umrwr->access_flags & IB_ACCESS_REMOTE_READ));
415 MLX5_SET(mkc, seg, lw, !!(umrwr->access_flags & IB_ACCESS_LOCAL_WRITE));
416 MLX5_SET(mkc, seg, lr, 1);
417 MLX5_SET(mkc, seg, relaxed_ordering_write,
418 !!(umrwr->access_flags & IB_ACCESS_RELAXED_ORDERING));
419 MLX5_SET(mkc, seg, relaxed_ordering_read,
420 !!(umrwr->access_flags & IB_ACCESS_RELAXED_ORDERING));
387 421
388 seg->flags = convert_access(umrwr->access_flags);
389 if (umrwr->pd)422 if (umrwr->pd)
390 seg->flags_pd = cpu_to_be32(to_mpd(umrwr->pd)->pdn);423 MLX5_SET(mkc, seg, pd, to_mpd(umrwr->pd)->pdn);
391 if (wr->send_flags & MLX5_IB_SEND_UMR_UPDATE_TRANSLATION &&424 if (wr->send_flags & MLX5_IB_SEND_UMR_UPDATE_TRANSLATION &&
392 !umrwr->length)425 !umrwr->length)
393 seg->flags_pd |= cpu_to_be32(MLX5_MKEY_LEN64);426 MLX5_SET(mkc, seg, length64, 1);
394 427
395 seg->start_addr = cpu_to_be64(umrwr->virt_addr);428 MLX5_SET64(mkc, seg, start_addr, umrwr->virt_addr);
396 seg->len = cpu_to_be64(umrwr->length);429 MLX5_SET64(mkc, seg, len, umrwr->length);
397 seg->log2_page_size = umrwr->page_shift;430 MLX5_SET(mkc, seg, log_page_size, umrwr->page_shift);
398 seg->qpn_mkey7_0 = cpu_to_be32(0xffffff00 |431 MLX5_SET(mkc, seg, qpn, 0xffffff);
399 mlx5_mkey_variant(umrwr->mkey));432 MLX5_SET(mkc, seg, mkey_7_0, mlx5_mkey_variant(umrwr->mkey));
400}433}
401 434
402static void set_reg_data_seg(struct mlx5_wqe_data_seg *dseg,435static void set_reg_data_seg(struct mlx5_wqe_data_seg *dseg,
@@ -1224,8 +1257,7 @@ static int handle_qpt_reg_umr(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp, · 821 unmodified lines
1224 1257
1225 qp->sq.wr_data[idx] = MLX5_IB_WR_UMR;1258 qp->sq.wr_data[idx] = MLX5_IB_WR_UMR;
1226 (*ctrl)->imm = cpu_to_be32(umr_wr(wr)->mkey);1259 (*ctrl)->imm = cpu_to_be32(umr_wr(wr)->mkey);
1227 err = set_reg_umr_segment(dev, *seg, wr,1260 err = set_reg_umr_segment(dev, *seg, wr);
1228 !!(MLX5_CAP_GEN(dev->mdev, atomic)));
1229 if (unlikely(err))1261 if (unlikely(err))
1230 goto out;1262 goto out;
1231 *seg += sizeof(struct mlx5_wqe_umr_ctrl_seg);1263 *seg += sizeof(struct mlx5_wqe_umr_ctrl_seg);
drivers/infiniband/hw/ocrdma/ocrdma_verbs.c+1−1
@@ -2901,7 +2901,7 @@ int ocrdma_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags cq_flags) · 2900 unmodified lines
2901}2901}
2902 2902
2903struct ib_mr *ocrdma_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type,2903struct ib_mr *ocrdma_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type,
2904 u32 max_num_sg, struct ib_udata *udata)2904 u32 max_num_sg)
2905{2905{
2906 int status;2906 int status;
2907 struct ocrdma_mr *mr;2907 struct ocrdma_mr *mr;
drivers/infiniband/hw/ocrdma/ocrdma_verbs.h+1−1
@@ -101,7 +101,7 @@ struct ib_mr *ocrdma_get_dma_mr(struct ib_pd *, int acc); · 100 unmodified lines
101struct ib_mr *ocrdma_reg_user_mr(struct ib_pd *, u64 start, u64 length,101struct ib_mr *ocrdma_reg_user_mr(struct ib_pd *, u64 start, u64 length,
102 u64 virt, int acc, struct ib_udata *);102 u64 virt, int acc, struct ib_udata *);
103struct ib_mr *ocrdma_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,103struct ib_mr *ocrdma_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
104 u32 max_num_sg, struct ib_udata *udata);104 u32 max_num_sg);
105int ocrdma_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,105int ocrdma_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,
106 unsigned int *sg_offset);106 unsigned int *sg_offset);
107 107
drivers/infiniband/hw/qedr/main.c+1−2
@@ -110,7 +110,6 @@ static int qedr_iw_port_immutable(struct ib_device *ibdev, u8 port_num, · 109 unmodified lines
110 if (err)110 if (err)
111 return err;111 return err;
112 112
113 immutable->pkey_tbl_len = 1;
114 immutable->gid_tbl_len = 1;113 immutable->gid_tbl_len = 1;
115 immutable->core_cap_flags = RDMA_CORE_PORT_IWARP;114 immutable->core_cap_flags = RDMA_CORE_PORT_IWARP;
116 immutable->max_mad_size = 0;115 immutable->max_mad_size = 0;
@@ -179,6 +178,7 @@ static int qedr_iw_register_device(struct qedr_dev *dev) · 62 unmodified lines
179 178
180static const struct ib_device_ops qedr_roce_dev_ops = {179static const struct ib_device_ops qedr_roce_dev_ops = {
181 .get_port_immutable = qedr_roce_port_immutable,180 .get_port_immutable = qedr_roce_port_immutable,
181 .query_pkey = qedr_query_pkey,
182};182};
183 183
184static void qedr_roce_register_device(struct qedr_dev *dev)184static void qedr_roce_register_device(struct qedr_dev *dev)
@@ -221,7 +221,6 @@ static const struct ib_device_ops qedr_dev_ops = { · 36 unmodified lines
221 .post_srq_recv = qedr_post_srq_recv,221 .post_srq_recv = qedr_post_srq_recv,
222 .process_mad = qedr_process_mad,222 .process_mad = qedr_process_mad,
223 .query_device = qedr_query_device,223 .query_device = qedr_query_device,
224 .query_pkey = qedr_query_pkey,
225 .query_port = qedr_query_port,224 .query_port = qedr_query_port,
226 .query_qp = qedr_query_qp,225 .query_qp = qedr_query_qp,
227 .query_srq = qedr_query_srq,226 .query_srq = qedr_query_srq,
drivers/infiniband/hw/qedr/qedr.h+3−2
@@ -235,6 +235,7 @@ struct qedr_ucontext { · 234 unmodified lines
235 u32 dpi_size;235 u32 dpi_size;
236 u16 dpi;236 u16 dpi;
237 bool db_rec;237 bool db_rec;
238 u8 edpm_mode;
238};239};
239 240
240union db_prod32 {241union db_prod32 {
@@ -344,10 +345,10 @@ struct qedr_srq_hwq_info { · 103 unmodified lines
344 u32 wqe_prod;345 u32 wqe_prod;
345 u32 sge_prod;346 u32 sge_prod;
346 u32 wr_prod_cnt;347 u32 wr_prod_cnt;
347 u32 wr_cons_cnt;348 atomic_t wr_cons_cnt;
348 u32 num_elems;349 u32 num_elems;
349 350
350 u32 *virt_prod_pair_addr;351 struct rdma_srq_producers *virt_prod_pair_addr;
351 dma_addr_t phy_prod_pair_addr;352 dma_addr_t phy_prod_pair_addr;
352};353};
353 354
drivers/infiniband/hw/qedr/verbs.c+25−20
@@ -239,7 +239,6 @@ int qedr_query_port(struct ib_device *ibdev, u8 port, struct ib_port_attr *attr) · 238 unmodified lines
239 attr->ip_gids = true;239 attr->ip_gids = true;
240 if (rdma_protocol_iwarp(&dev->ibdev, 1)) {240 if (rdma_protocol_iwarp(&dev->ibdev, 1)) {
241 attr->gid_tbl_len = 1;241 attr->gid_tbl_len = 1;
242 attr->pkey_tbl_len = 1;
243 } else {242 } else {
244 attr->gid_tbl_len = QEDR_MAX_SGID;243 attr->gid_tbl_len = QEDR_MAX_SGID;
245 attr->pkey_tbl_len = QEDR_ROCE_PKEY_TABLE_LEN;244 attr->pkey_tbl_len = QEDR_ROCE_PKEY_TABLE_LEN;
@@ -275,7 +274,8 @@ int qedr_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata) · 29 unmodified lines
275 DP_ERR(dev, "Problem copying data from user space\n");274 DP_ERR(dev, "Problem copying data from user space\n");
276 return -EFAULT;275 return -EFAULT;
277 }276 }
278 277 ctx->edpm_mode = !!(ureq.context_flags &
278 QEDR_ALLOC_UCTX_EDPM_MODE);
279 ctx->db_rec = !!(ureq.context_flags & QEDR_ALLOC_UCTX_DB_REC);279 ctx->db_rec = !!(ureq.context_flags & QEDR_ALLOC_UCTX_DB_REC);
280 }280 }
281 281
@@ -316,11 +316,15 @@ int qedr_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata) · 34 unmodified lines
316 uresp.dpm_flags = QEDR_DPM_TYPE_IWARP_LEGACY;316 uresp.dpm_flags = QEDR_DPM_TYPE_IWARP_LEGACY;
317 else317 else
318 uresp.dpm_flags = QEDR_DPM_TYPE_ROCE_ENHANCED |318 uresp.dpm_flags = QEDR_DPM_TYPE_ROCE_ENHANCED |
319 QEDR_DPM_TYPE_ROCE_LEGACY;319 QEDR_DPM_TYPE_ROCE_LEGACY |
320 QEDR_DPM_TYPE_ROCE_EDPM_MODE;
320 321
321 uresp.dpm_flags |= QEDR_DPM_SIZES_SET;322 if (ureq.context_flags & QEDR_SUPPORT_DPM_SIZES) {
322 uresp.ldpm_limit_size = QEDR_LDPM_MAX_SIZE;323 uresp.dpm_flags |= QEDR_DPM_SIZES_SET;
323 uresp.edpm_trans_size = QEDR_EDPM_TRANS_SIZE;324 uresp.ldpm_limit_size = QEDR_LDPM_MAX_SIZE;
325 uresp.edpm_trans_size = QEDR_EDPM_TRANS_SIZE;
326 uresp.edpm_limit_size = QEDR_EDPM_MAX_SIZE;
327 }
324 328
325 uresp.wids_enabled = 1;329 uresp.wids_enabled = 1;
326 uresp.wid_count = oparams.wid_count;330 uresp.wid_count = oparams.wid_count;
@@ -1754,7 +1758,7 @@ static int qedr_create_user_qp(struct qedr_dev *dev, · 1427 unmodified lines
1754 struct qed_rdma_create_qp_out_params out_params;1758 struct qed_rdma_create_qp_out_params out_params;
1755 struct qedr_pd *pd = get_qedr_pd(ibpd);1759 struct qedr_pd *pd = get_qedr_pd(ibpd);
1756 struct qedr_create_qp_uresp uresp;1760 struct qedr_create_qp_uresp uresp;
1757 struct qedr_ucontext *ctx = NULL;1761 struct qedr_ucontext *ctx = pd ? pd->uctx : NULL;
1758 struct qedr_create_qp_ureq ureq;1762 struct qedr_create_qp_ureq ureq;
1759 int alloc_and_init = rdma_protocol_roce(&dev->ibdev, 1);1763 int alloc_and_init = rdma_protocol_roce(&dev->ibdev, 1);
1760 int rc = -EINVAL;1764 int rc = -EINVAL;
@@ -1792,6 +1796,9 @@ static int qedr_create_user_qp(struct qedr_dev *dev, · 31 unmodified lines
1792 in_params.rq_pbl_ptr = qp->urq.pbl_tbl->pa;1796 in_params.rq_pbl_ptr = qp->urq.pbl_tbl->pa;
1793 }1797 }
1794 1798
1799 if (ctx)
1800 SET_FIELD(in_params.flags, QED_ROCE_EDPM_MODE, ctx->edpm_mode);
1801
1795 qp->qed_qp = dev->ops->rdma_create_qp(dev->rdma_ctx,1802 qp->qed_qp = dev->ops->rdma_create_qp(dev->rdma_ctx,
1796 &in_params, &out_params);1803 &in_params, &out_params);
1797 1804
@@ -3004,7 +3011,7 @@ err0: · 1206 unmodified lines
3004}3011}
3005 3012
3006struct ib_mr *qedr_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type,3013struct ib_mr *qedr_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type,
3007 u32 max_num_sg, struct ib_udata *udata)3014 u32 max_num_sg)
3008{3015{
3009 struct qedr_mr *mr;3016 struct qedr_mr *mr;
3010 3017
@@ -3687,7 +3694,7 @@ static u32 qedr_srq_elem_left(struct qedr_srq_hwq_info *hw_srq) · 676 unmodified lines
3687 * count and consumer count and subtract it from max3694 * count and consumer count and subtract it from max
3688 * work request supported so that we get elements left.3695 * work request supported so that we get elements left.
3689 */3696 */
3690 used = hw_srq->wr_prod_cnt - hw_srq->wr_cons_cnt;3697 used = hw_srq->wr_prod_cnt - (u32)atomic_read(&hw_srq->wr_cons_cnt);
3691 3698
3692 return hw_srq->max_wr - used;3699 return hw_srq->max_wr - used;
3693}3700}
@@ -3702,7 +3709,6 @@ int qedr_post_srq_recv(struct ib_srq *ibsrq, const struct ib_recv_wr *wr, · 8 unmodified lines
3702 unsigned long flags;3709 unsigned long flags;
3703 int status = 0;3710 int status = 0;
3704 u32 num_sge;3711 u32 num_sge;
3705 u32 offset;
3706 3712
3707 spin_lock_irqsave(&srq->lock, flags);3713 spin_lock_irqsave(&srq->lock, flags);
3708 3714
@@ -3715,7 +3721,8 @@ int qedr_post_srq_recv(struct ib_srq *ibsrq, const struct ib_recv_wr *wr, · 6 unmodified lines
3715 if (!qedr_srq_elem_left(hw_srq) ||3721 if (!qedr_srq_elem_left(hw_srq) ||
3716 wr->num_sge > srq->hw_srq.max_sges) {3722 wr->num_sge > srq->hw_srq.max_sges) {
3717 DP_ERR(dev, "Can't post WR (%d,%d) || (%d > %d)\n",3723 DP_ERR(dev, "Can't post WR (%d,%d) || (%d > %d)\n",
3718 hw_srq->wr_prod_cnt, hw_srq->wr_cons_cnt,3724 hw_srq->wr_prod_cnt,
3725 atomic_read(&hw_srq->wr_cons_cnt),
3719 wr->num_sge, srq->hw_srq.max_sges);3726 wr->num_sge, srq->hw_srq.max_sges);
3720 status = -ENOMEM;3727 status = -ENOMEM;
3721 *bad_wr = wr;3728 *bad_wr = wr;
@@ -3749,22 +3756,20 @@ int qedr_post_srq_recv(struct ib_srq *ibsrq, const struct ib_recv_wr *wr, · 27 unmodified lines
3749 hw_srq->sge_prod++;3756 hw_srq->sge_prod++;
3750 }3757 }
3751 3758
3752 /* Flush WQE and SGE information before3759 /* Update WQE and SGE information before
3753 * updating producer.3760 * updating producer.
3754 */3761 */
3755 wmb();3762 dma_wmb();
3756 3763
3757 /* SRQ producer is 8 bytes. Need to update SGE producer index3764 /* SRQ producer is 8 bytes. Need to update SGE producer index
3758 * in first 4 bytes and need to update WQE producer in3765 * in first 4 bytes and need to update WQE producer in
3759 * next 4 bytes.3766 * next 4 bytes.
3760 */3767 */
3761 *srq->hw_srq.virt_prod_pair_addr = hw_srq->sge_prod;3768 srq->hw_srq.virt_prod_pair_addr->sge_prod = hw_srq->sge_prod;
3762 offset = offsetof(struct rdma_srq_producers, wqe_prod);3769 /* Make sure sge producer is updated first */
3763 *((u8 *)srq->hw_srq.virt_prod_pair_addr + offset) =3770 dma_wmb();
3764 hw_srq->wqe_prod;3771 srq->hw_srq.virt_prod_pair_addr->wqe_prod = hw_srq->wqe_prod;
3765 3772
3766 /* Flush producer after updating it. */
3767 wmb();
3768 wr = wr->next;3773 wr = wr->next;
3769 }3774 }
3770 3775
@@ -4183,7 +4188,7 @@ static int process_resp_one_srq(struct qedr_dev *dev, struct qedr_qp *qp, · 412 unmodified lines
4183 } else {4188 } else {
4184 __process_resp_one(dev, qp, cq, wc, resp, wr_id);4189 __process_resp_one(dev, qp, cq, wc, resp, wr_id);
4185 }4190 }
4186 srq->hw_srq.wr_cons_cnt++;4191 atomic_inc(&srq->hw_srq.wr_cons_cnt);
4187 4192
4188 return 1;4193 return 1;
4189}4194}
drivers/infiniband/hw/qedr/verbs.h+1−1
@@ -84,7 +84,7 @@ int qedr_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, · 83 unmodified lines
84 int sg_nents, unsigned int *sg_offset);84 int sg_nents, unsigned int *sg_offset);
85 85
86struct ib_mr *qedr_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,86struct ib_mr *qedr_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
87 u32 max_num_sg, struct ib_udata *udata);87 u32 max_num_sg);
88int qedr_poll_cq(struct ib_cq *, int num_entries, struct ib_wc *wc);88int qedr_poll_cq(struct ib_cq *, int num_entries, struct ib_wc *wc);
89int qedr_post_send(struct ib_qp *, const struct ib_send_wr *,89int qedr_post_send(struct ib_qp *, const struct ib_send_wr *,
90 const struct ib_send_wr **bad_wr);90 const struct ib_send_wr **bad_wr);
drivers/infiniband/hw/usnic/usnic_fwd.c+2−2
@@ -214,7 +214,7 @@ usnic_fwd_alloc_flow(struct usnic_fwd_dev *ufdev, struct filter *filter, · 213 unmodified lines
214 if (!flow)214 if (!flow)
215 return ERR_PTR(-ENOMEM);215 return ERR_PTR(-ENOMEM);
216 216
217 tlv = pci_alloc_consistent(pdev, tlv_size, &tlv_pa);217 tlv = dma_alloc_coherent(&pdev->dev, tlv_size, &tlv_pa, GFP_ATOMIC);
218 if (!tlv) {218 if (!tlv) {
219 usnic_err("Failed to allocate memory\n");219 usnic_err("Failed to allocate memory\n");
220 status = -ENOMEM;220 status = -ENOMEM;
@@ -258,7 +258,7 @@ usnic_fwd_alloc_flow(struct usnic_fwd_dev *ufdev, struct filter *filter, · 37 unmodified lines
258 258
259out_free_tlv:259out_free_tlv:
260 spin_unlock(&ufdev->lock);260 spin_unlock(&ufdev->lock);
261 pci_free_consistent(pdev, tlv_size, tlv, tlv_pa);261 dma_free_coherent(&pdev->dev, tlv_size, tlv, tlv_pa);
262 if (!status)262 if (!status)
263 return flow;263 return flow;
264out_free_flow:264out_free_flow:
drivers/infiniband/hw/vmw_pvrdma/pvrdma_mr.c+1−1
@@ -202,7 +202,7 @@ err_umem: · 201 unmodified lines
202 * @return: ib_mr pointer on success, otherwise returns an errno.202 * @return: ib_mr pointer on success, otherwise returns an errno.
203 */203 */
204struct ib_mr *pvrdma_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,204struct ib_mr *pvrdma_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
205 u32 max_num_sg, struct ib_udata *udata)205 u32 max_num_sg)
206{206{
207 struct pvrdma_dev *dev = to_vdev(pd->device);207 struct pvrdma_dev *dev = to_vdev(pd->device);
208 struct pvrdma_user_mr *mr;208 struct pvrdma_user_mr *mr;
drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.h+1−1
@@ -406,7 +406,7 @@ struct ib_mr *pvrdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, · 405 unmodified lines
406 struct ib_udata *udata);406 struct ib_udata *udata);
407int pvrdma_dereg_mr(struct ib_mr *mr, struct ib_udata *udata);407int pvrdma_dereg_mr(struct ib_mr *mr, struct ib_udata *udata);
408struct ib_mr *pvrdma_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,408struct ib_mr *pvrdma_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
409 u32 max_num_sg, struct ib_udata *udata);409 u32 max_num_sg);
410int pvrdma_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg,410int pvrdma_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg,
411 int sg_nents, unsigned int *sg_offset);411 int sg_nents, unsigned int *sg_offset);
412int pvrdma_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,412int pvrdma_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr,
drivers/infiniband/sw/rdmavt/ah.c+1−2
@@ -90,8 +90,7 @@ EXPORT_SYMBOL(rvt_check_ah); · 89 unmodified lines
90/**90/**
91 * rvt_create_ah - create an address handle91 * rvt_create_ah - create an address handle
92 * @ibah: the IB address handle92 * @ibah: the IB address handle
93 * @ah_attr: the attributes of the AH93 * @init_attr: the attributes of the AH
94 * @create_flags: create address handle flags (see enum rdma_create_ah_flags)
95 * @udata: pointer to user's input output buffer information.94 * @udata: pointer to user's input output buffer information.
96 *95 *
97 * This may be called from interrupt context.96 * This may be called from interrupt context.
drivers/infiniband/sw/rdmavt/mr.c+1−1
@@ -576,7 +576,7 @@ out: · 575 unmodified lines
576 * Return: the memory region on success, otherwise return an errno.576 * Return: the memory region on success, otherwise return an errno.
577 */577 */
578struct ib_mr *rvt_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,578struct ib_mr *rvt_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
579 u32 max_num_sg, struct ib_udata *udata)579 u32 max_num_sg)
580{580{
581 struct rvt_mr *mr;581 struct rvt_mr *mr;
582 582
drivers/infiniband/sw/rdmavt/mr.h+1−1
@@ -71,7 +71,7 @@ struct ib_mr *rvt_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, · 70 unmodified lines
71 struct ib_udata *udata);71 struct ib_udata *udata);
72int rvt_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata);72int rvt_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata);
73struct ib_mr *rvt_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,73struct ib_mr *rvt_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
74 u32 max_num_sg, struct ib_udata *udata);74 u32 max_num_sg);
75int rvt_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg,75int rvt_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg,
76 int sg_nents, unsigned int *sg_offset);76 int sg_nents, unsigned int *sg_offset);
77 77
drivers/infiniband/sw/rxe/rxe.c+4−37
@@ -40,14 +40,6 @@ MODULE_AUTHOR("Bob Pearson, Frank Zago, John Groves, Kamal Heib"); · 39 unmodified lines
40MODULE_DESCRIPTION("Soft RDMA transport");40MODULE_DESCRIPTION("Soft RDMA transport");
41MODULE_LICENSE("Dual BSD/GPL");41MODULE_LICENSE("Dual BSD/GPL");
42 42
43/* free resources for all ports on a device */
44static void rxe_cleanup_ports(struct rxe_dev *rxe)
45{
46 kfree(rxe->port.pkey_tbl);
47 rxe->port.pkey_tbl = NULL;
48
49}
50
51/* free resources for a rxe device all objects created for this device must43/* free resources for a rxe device all objects created for this device must
52 * have been destroyed44 * have been destroyed
53 */45 */
@@ -66,8 +58,6 @@ void rxe_dealloc(struct ib_device *ib_dev) · 12 unmodified lines
66 rxe_pool_cleanup(&rxe->mc_grp_pool);58 rxe_pool_cleanup(&rxe->mc_grp_pool);
67 rxe_pool_cleanup(&rxe->mc_elem_pool);59 rxe_pool_cleanup(&rxe->mc_elem_pool);
68 60
69 rxe_cleanup_ports(rxe);
70
71 if (rxe->tfm)61 if (rxe->tfm)
72 crypto_free_shash(rxe->tfm);62 crypto_free_shash(rxe->tfm);
73}63}
@@ -111,7 +101,7 @@ static void rxe_init_device_param(struct rxe_dev *rxe) · 37 unmodified lines
111}101}
112 102
113/* initialize port attributes */103/* initialize port attributes */
114static int rxe_init_port_param(struct rxe_port *port)104static void rxe_init_port_param(struct rxe_port *port)
115{105{
116 port->attr.state = IB_PORT_DOWN;106 port->attr.state = IB_PORT_DOWN;
117 port->attr.max_mtu = IB_MTU_4096;107 port->attr.max_mtu = IB_MTU_4096;
@@ -134,35 +124,19 @@ static int rxe_init_port_param(struct rxe_port *port) · 16 unmodified lines
134 port->attr.phys_state = RXE_PORT_PHYS_STATE;124 port->attr.phys_state = RXE_PORT_PHYS_STATE;
135 port->mtu_cap = ib_mtu_enum_to_int(IB_MTU_256);125 port->mtu_cap = ib_mtu_enum_to_int(IB_MTU_256);
136 port->subnet_prefix = cpu_to_be64(RXE_PORT_SUBNET_PREFIX);126 port->subnet_prefix = cpu_to_be64(RXE_PORT_SUBNET_PREFIX);
137
138 return 0;
139}127}
140 128
141/* initialize port state, note IB convention that HCA ports are always129/* initialize port state, note IB convention that HCA ports are always
142 * numbered from 1130 * numbered from 1
143 */131 */
144static int rxe_init_ports(struct rxe_dev *rxe)132static void rxe_init_ports(struct rxe_dev *rxe)
145{133{
146 struct rxe_port *port = &rxe->port;134 struct rxe_port *port = &rxe->port;
147 135
148 rxe_init_port_param(port);136 rxe_init_port_param(port);
149
150 if (!port->attr.pkey_tbl_len || !port->attr.gid_tbl_len)
151 return -EINVAL;
152
153 port->pkey_tbl = kcalloc(port->attr.pkey_tbl_len,
154 sizeof(*port->pkey_tbl), GFP_KERNEL);
155
156 if (!port->pkey_tbl)
157 return -ENOMEM;
158
159 port->pkey_tbl[0] = 0xffff;
160 addrconf_addr_eui48((unsigned char *)&port->port_guid,137 addrconf_addr_eui48((unsigned char *)&port->port_guid,
161 rxe->ndev->dev_addr);138 rxe->ndev->dev_addr);
162
163 spin_lock_init(&port->port_lock);139 spin_lock_init(&port->port_lock);
164
165 return 0;
166}140}
167 141
168/* init pools of managed objects */142/* init pools of managed objects */
@@ -252,13 +226,11 @@ static int rxe_init(struct rxe_dev *rxe) · 83 unmodified lines
252 /* init default device parameters */226 /* init default device parameters */
253 rxe_init_device_param(rxe);227 rxe_init_device_param(rxe);
254 228
255 err = rxe_init_ports(rxe);229 rxe_init_ports(rxe);
256 if (err)
257 goto err1;
258 230
259 err = rxe_init_pools(rxe);231 err = rxe_init_pools(rxe);
260 if (err)232 if (err)
261 goto err2;233 return err;
262 234
263 /* init pending mmap list */235 /* init pending mmap list */
264 spin_lock_init(&rxe->mmap_offset_lock);236 spin_lock_init(&rxe->mmap_offset_lock);
@@ -268,11 +240,6 @@ static int rxe_init(struct rxe_dev *rxe) · 3 unmodified lines
268 mutex_init(&rxe->usdev_lock);240 mutex_init(&rxe->usdev_lock);
269 241
270 return 0;242 return 0;
271
272err2:
273 rxe_cleanup_ports(rxe);
274err1:
275 return err;
276}243}
277 244
278void rxe_set_mtu(struct rxe_dev *rxe, unsigned int ndev_mtu)245void rxe_set_mtu(struct rxe_dev *rxe, unsigned int ndev_mtu)
drivers/infiniband/sw/rxe/rxe_loc.h+2−6
@@ -103,8 +103,8 @@ enum copy_direction { · 102 unmodified lines
103 from_mem_obj,103 from_mem_obj,
104};104};
105 105
106int rxe_mem_init_dma(struct rxe_pd *pd,106void rxe_mem_init_dma(struct rxe_pd *pd,
107 int access, struct rxe_mem *mem);107 int access, struct rxe_mem *mem);
108 108
109int rxe_mem_init_user(struct rxe_pd *pd, u64 start,109int rxe_mem_init_user(struct rxe_pd *pd, u64 start,
110 u64 length, u64 iova, int access, struct ib_udata *udata,110 u64 length, u64 iova, int access, struct ib_udata *udata,
@@ -132,9 +132,6 @@ struct rxe_mem *lookup_mem(struct rxe_pd *pd, int access, u32 key, · 21 unmodified lines
132 132
133int mem_check_range(struct rxe_mem *mem, u64 iova, size_t length);133int mem_check_range(struct rxe_mem *mem, u64 iova, size_t length);
134 134
135int rxe_mem_map_pages(struct rxe_dev *rxe, struct rxe_mem *mem,
136 u64 *page, int num_pages, u64 iova);
137
138void rxe_mem_cleanup(struct rxe_pool_entry *arg);135void rxe_mem_cleanup(struct rxe_pool_entry *arg);
139 136
140int advance_dma_data(struct rxe_dma_info *dma, unsigned int length);137int advance_dma_data(struct rxe_dma_info *dma, unsigned int length);
@@ -145,7 +142,6 @@ int rxe_send(struct rxe_pkt_info *pkt, struct sk_buff *skb); · 4 unmodified lines
145struct sk_buff *rxe_init_packet(struct rxe_dev *rxe, struct rxe_av *av,142struct sk_buff *rxe_init_packet(struct rxe_dev *rxe, struct rxe_av *av,
146 int paylen, struct rxe_pkt_info *pkt);143 int paylen, struct rxe_pkt_info *pkt);
147int rxe_prepare(struct rxe_pkt_info *pkt, struct sk_buff *skb, u32 *crc);144int rxe_prepare(struct rxe_pkt_info *pkt, struct sk_buff *skb, u32 *crc);
148enum rdma_link_layer rxe_link_layer(struct rxe_dev *rxe, unsigned int port_num);
149const char *rxe_parent_name(struct rxe_dev *rxe, unsigned int port_num);145const char *rxe_parent_name(struct rxe_dev *rxe, unsigned int port_num);
150struct device *rxe_dma_device(struct rxe_dev *rxe);146struct device *rxe_dma_device(struct rxe_dev *rxe);
151int rxe_mcast_add(struct rxe_dev *rxe, union ib_gid *mgid);147int rxe_mcast_add(struct rxe_dev *rxe, union ib_gid *mgid);
drivers/infiniband/sw/rxe/rxe_mr.c+2−48
@@ -144,8 +144,8 @@ err1: · 143 unmodified lines
144 return -ENOMEM;144 return -ENOMEM;
145}145}
146 146
147int rxe_mem_init_dma(struct rxe_pd *pd,147void rxe_mem_init_dma(struct rxe_pd *pd,
148 int access, struct rxe_mem *mem)148 int access, struct rxe_mem *mem)
149{149{
150 rxe_mem_init(access, mem);150 rxe_mem_init(access, mem);
151 151
@@ -153,8 +153,6 @@ int rxe_mem_init_dma(struct rxe_pd *pd, · 1 unmodified line
153 mem->access = access;153 mem->access = access;
154 mem->state = RXE_MEM_STATE_VALID;154 mem->state = RXE_MEM_STATE_VALID;
155 mem->type = RXE_MEM_TYPE_DMA;155 mem->type = RXE_MEM_TYPE_DMA;
156
157 return 0;
158}156}
159 157
160int rxe_mem_init_user(struct rxe_pd *pd, u64 start,158int rxe_mem_init_user(struct rxe_pd *pd, u64 start,
@@ -587,47 +585,3 @@ struct rxe_mem *lookup_mem(struct rxe_pd *pd, int access, u32 key, · 426 unmodified lines
587 585
588 return mem;586 return mem;
589}587}
590
591int rxe_mem_map_pages(struct rxe_dev *rxe, struct rxe_mem *mem,
592 u64 *page, int num_pages, u64 iova)
593{
594 int i;
595 int num_buf;
596 int err;
597 struct rxe_map **map;
598 struct rxe_phys_buf *buf;
599 int page_size;
600
601 if (num_pages > mem->max_buf) {
602 err = -EINVAL;
603 goto err1;
604 }
605
606 num_buf = 0;
607 page_size = 1 << mem->page_shift;
608 map = mem->map;
609 buf = map[0]->buf;
610
611 for (i = 0; i < num_pages; i++) {
612 buf->addr = *page++;
613 buf->size = page_size;
614 buf++;
615 num_buf++;
616
617 if (num_buf == RXE_BUF_PER_MAP) {
618 map++;
619 buf = map[0]->buf;
620 num_buf = 0;
621 }
622 }
623
624 mem->iova = iova;
625 mem->va = iova;
626 mem->length = num_pages << mem->page_shift;
627 mem->state = RXE_MEM_STATE_VALID;
628
629 return 0;
630
631err1:
632 return err;
633}
drivers/infiniband/sw/rxe/rxe_net.c+0−5
@@ -520,11 +520,6 @@ const char *rxe_parent_name(struct rxe_dev *rxe, unsigned int port_num) · 519 unmodified lines
520 return rxe->ndev->name;520 return rxe->ndev->name;
521}521}
522 522
523enum rdma_link_layer rxe_link_layer(struct rxe_dev *rxe, unsigned int port_num)
524{
525 return IB_LINK_LAYER_ETHERNET;
526}
527
528int rxe_net_add(const char *ibdev_name, struct net_device *ndev)523int rxe_net_add(const char *ibdev_name, struct net_device *ndev)
529{524{
530 int err;525 int err;
drivers/infiniband/sw/rxe/rxe_param.h+2−2
@@ -100,7 +100,7 @@ enum rxe_device_param { · 99 unmodified lines
100 RXE_MAX_SRQ_SGE = 27,100 RXE_MAX_SRQ_SGE = 27,
101 RXE_MIN_SRQ_SGE = 1,101 RXE_MIN_SRQ_SGE = 1,
102 RXE_MAX_FMR_PAGE_LIST_LEN = 512,102 RXE_MAX_FMR_PAGE_LIST_LEN = 512,
103 RXE_MAX_PKEYS = 64,103 RXE_MAX_PKEYS = 1,
104 RXE_LOCAL_CA_ACK_DELAY = 15,104 RXE_LOCAL_CA_ACK_DELAY = 15,
105 105
106 RXE_MAX_UCONTEXT = 512,106 RXE_MAX_UCONTEXT = 512,
@@ -148,7 +148,7 @@ enum rxe_port_param { · 41 unmodified lines
148 RXE_PORT_INIT_TYPE_REPLY = 0,148 RXE_PORT_INIT_TYPE_REPLY = 0,
149 RXE_PORT_ACTIVE_WIDTH = IB_WIDTH_1X,149 RXE_PORT_ACTIVE_WIDTH = IB_WIDTH_1X,
150 RXE_PORT_ACTIVE_SPEED = 1,150 RXE_PORT_ACTIVE_SPEED = 1,
151 RXE_PORT_PKEY_TBL_LEN = 64,151 RXE_PORT_PKEY_TBL_LEN = 1,
152 RXE_PORT_PHYS_STATE = IB_PORT_PHYS_STATE_POLLING,152 RXE_PORT_PHYS_STATE = IB_PORT_PHYS_STATE_POLLING,
153 RXE_PORT_SUBNET_PREFIX = 0xfe80000000000000ULL,153 RXE_PORT_SUBNET_PREFIX = 0xfe80000000000000ULL,
154};154};
drivers/infiniband/sw/rxe/rxe_recv.c+9−26
@@ -101,36 +101,15 @@ static void set_qkey_viol_cntr(struct rxe_port *port) · 100 unmodified lines
101static int check_keys(struct rxe_dev *rxe, struct rxe_pkt_info *pkt,101static int check_keys(struct rxe_dev *rxe, struct rxe_pkt_info *pkt,
102 u32 qpn, struct rxe_qp *qp)102 u32 qpn, struct rxe_qp *qp)
103{103{
104 int i;
105 int found_pkey = 0;
106 struct rxe_port *port = &rxe->port;104 struct rxe_port *port = &rxe->port;
107 u16 pkey = bth_pkey(pkt);105 u16 pkey = bth_pkey(pkt);
108 106
109 pkt->pkey_index = 0;107 pkt->pkey_index = 0;
110 108
111 if (qpn == 1) {109 if (!pkey_match(pkey, IB_DEFAULT_PKEY_FULL)) {
112 for (i = 0; i < port->attr.pkey_tbl_len; i++) {110 pr_warn_ratelimited("bad pkey = 0x%x\n", pkey);
113 if (pkey_match(pkey, port->pkey_tbl[i])) {111 set_bad_pkey_cntr(port);
114 pkt->pkey_index = i;112 goto err1;
115 found_pkey = 1;
116 break;
117 }
118 }
119
120 if (!found_pkey) {
121 pr_warn_ratelimited("bad pkey = 0x%x\n", pkey);
122 set_bad_pkey_cntr(port);
123 goto err1;
124 }
125 } else {
126 if (unlikely(!pkey_match(pkey,
127 port->pkey_tbl[qp->attr.pkey_index]
128 ))) {
129 pr_warn_ratelimited("bad pkey = 0x%0x\n", pkey);
130 set_bad_pkey_cntr(port);
131 goto err1;
132 }
133 pkt->pkey_index = qp->attr.pkey_index;
134 }113 }
135 114
136 if ((qp_type(qp) == IB_QPT_UD || qp_type(qp) == IB_QPT_GSI) &&115 if ((qp_type(qp) == IB_QPT_UD || qp_type(qp) == IB_QPT_GSI) &&
@@ -330,10 +309,14 @@ err1: · 193 unmodified lines
330 309
331static int rxe_match_dgid(struct rxe_dev *rxe, struct sk_buff *skb)310static int rxe_match_dgid(struct rxe_dev *rxe, struct sk_buff *skb)
332{311{
312 struct rxe_pkt_info *pkt = SKB_TO_PKT(skb);
333 const struct ib_gid_attr *gid_attr;313 const struct ib_gid_attr *gid_attr;
334 union ib_gid dgid;314 union ib_gid dgid;
335 union ib_gid *pdgid;315 union ib_gid *pdgid;
336 316
317 if (pkt->mask & RXE_LOOPBACK_MASK)
318 return 0;
319
337 if (skb->protocol == htons(ETH_P_IP)) {320 if (skb->protocol == htons(ETH_P_IP)) {
338 ipv6_addr_set_v4mapped(ip_hdr(skb)->daddr,321 ipv6_addr_set_v4mapped(ip_hdr(skb)->daddr,
339 (struct in6_addr *)&dgid);322 (struct in6_addr *)&dgid);
@@ -366,7 +349,7 @@ void rxe_rcv(struct sk_buff *skb) · 26 unmodified lines
366 if (unlikely(skb->len < pkt->offset + RXE_BTH_BYTES))349 if (unlikely(skb->len < pkt->offset + RXE_BTH_BYTES))
367 goto drop;350 goto drop;
368 351
369 if (unlikely(rxe_match_dgid(rxe, skb) < 0)) {352 if (rxe_match_dgid(rxe, skb) < 0) {
370 pr_warn_ratelimited("failed matching dgid\n");353 pr_warn_ratelimited("failed matching dgid\n");
371 goto drop;354 goto drop;
372 }355 }
drivers/infiniband/sw/rxe/rxe_req.c+1−4
@@ -381,7 +381,6 @@ static struct sk_buff *init_req_packet(struct rxe_qp *qp, · 380 unmodified lines
381 struct rxe_pkt_info *pkt)381 struct rxe_pkt_info *pkt)
382{382{
383 struct rxe_dev *rxe = to_rdev(qp->ibqp.device);383 struct rxe_dev *rxe = to_rdev(qp->ibqp.device);
384 struct rxe_port *port = &rxe->port;
385 struct sk_buff *skb;384 struct sk_buff *skb;
386 struct rxe_send_wr *ibwr = &wqe->wr;385 struct rxe_send_wr *ibwr = &wqe->wr;
387 struct rxe_av *av;386 struct rxe_av *av;
@@ -419,9 +418,7 @@ static struct sk_buff *init_req_packet(struct rxe_qp *qp, · 31 unmodified lines
419 (pkt->mask & (RXE_WRITE_MASK | RXE_IMMDT_MASK)) ==418 (pkt->mask & (RXE_WRITE_MASK | RXE_IMMDT_MASK)) ==
420 (RXE_WRITE_MASK | RXE_IMMDT_MASK));419 (RXE_WRITE_MASK | RXE_IMMDT_MASK));
421 420
422 pkey = (qp_type(qp) == IB_QPT_GSI) ?421 pkey = IB_DEFAULT_PKEY_FULL;
423 port->pkey_tbl[ibwr->wr.ud.pkey_index] :
424 port->pkey_tbl[qp->attr.pkey_index];
425 422
426 qp_num = (pkt->mask & RXE_DETH_MASK) ? ibwr->wr.ud.remote_qpn :423 qp_num = (pkt->mask & RXE_DETH_MASK) ? ibwr->wr.ud.remote_qpn :
427 qp->attr.dest_qp_num;424 qp->attr.dest_qp_num;
drivers/infiniband/sw/rxe/rxe_verbs.c+12−36
@@ -83,22 +83,11 @@ static int rxe_query_port(struct ib_device *dev, · 82 unmodified lines
83static int rxe_query_pkey(struct ib_device *device,83static int rxe_query_pkey(struct ib_device *device,
84 u8 port_num, u16 index, u16 *pkey)84 u8 port_num, u16 index, u16 *pkey)
85{85{
86 struct rxe_dev *rxe = to_rdev(device);86 if (index > 0)
87 struct rxe_port *port;87 return -EINVAL;
88
89 port = &rxe->port;
90
91 if (unlikely(index >= port->attr.pkey_tbl_len)) {
92 dev_warn(device->dev.parent, "invalid index = %d\n",
93 index);
94 goto err1;
95 }
96 88
97 *pkey = port->pkey_tbl[index];89 *pkey = IB_DEFAULT_PKEY_FULL;
98 return 0;90 return 0;
99
100err1:
101 return -EINVAL;
102}91}
103 92
104static int rxe_modify_device(struct ib_device *dev,93static int rxe_modify_device(struct ib_device *dev,
@@ -141,9 +130,7 @@ static int rxe_modify_port(struct ib_device *dev, · 36 unmodified lines
141static enum rdma_link_layer rxe_get_link_layer(struct ib_device *dev,130static enum rdma_link_layer rxe_get_link_layer(struct ib_device *dev,
142 u8 port_num)131 u8 port_num)
143{132{
144 struct rxe_dev *rxe = to_rdev(dev);133 return IB_LINK_LAYER_ETHERNET;
145
146 return rxe_link_layer(rxe, port_num);
147}134}
148 135
149static int rxe_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata)136static int rxe_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata)
@@ -684,6 +671,7 @@ static int rxe_post_send_kernel(struct rxe_qp *qp, const struct ib_send_wr *wr, · 534 unmodified lines
684 unsigned int mask;671 unsigned int mask;
685 unsigned int length = 0;672 unsigned int length = 0;
686 int i;673 int i;
674 struct ib_send_wr *next;
687 675
688 while (wr) {676 while (wr) {
689 mask = wr_opcode_mask(wr->opcode, qp);677 mask = wr_opcode_mask(wr->opcode, qp);
@@ -700,6 +688,8 @@ static int rxe_post_send_kernel(struct rxe_qp *qp, const struct ib_send_wr *wr, · 10 unmodified lines
700 break;688 break;
701 }689 }
702 690
691 next = wr->next;
692
703 length = 0;693 length = 0;
704 for (i = 0; i < wr->num_sge; i++)694 for (i = 0; i < wr->num_sge; i++)
705 length += wr->sg_list[i].length;695 length += wr->sg_list[i].length;
@@ -710,7 +700,7 @@ static int rxe_post_send_kernel(struct rxe_qp *qp, const struct ib_send_wr *wr, · 4 unmodified lines
710 *bad_wr = wr;700 *bad_wr = wr;
711 break;701 break;
712 }702 }
713 wr = wr->next;703 wr = next;
714 }704 }
715 705
716 rxe_run_task(&qp->req.task, 1);706 rxe_run_task(&qp->req.task, 1);
@@ -901,30 +891,16 @@ static struct ib_mr *rxe_get_dma_mr(struct ib_pd *ibpd, int access) · 184 unmodified lines
901 struct rxe_dev *rxe = to_rdev(ibpd->device);891 struct rxe_dev *rxe = to_rdev(ibpd->device);
902 struct rxe_pd *pd = to_rpd(ibpd);892 struct rxe_pd *pd = to_rpd(ibpd);
903 struct rxe_mem *mr;893 struct rxe_mem *mr;
904 int err;
905 894
906 mr = rxe_alloc(&rxe->mr_pool);895 mr = rxe_alloc(&rxe->mr_pool);
907 if (!mr) {896 if (!mr)
908 err = -ENOMEM;897 return ERR_PTR(-ENOMEM);
909 goto err1;
910 }
911 898
912 rxe_add_index(mr);899 rxe_add_index(mr);
913
914 rxe_add_ref(pd);900 rxe_add_ref(pd);
915 901 rxe_mem_init_dma(pd, access, mr);
916 err = rxe_mem_init_dma(pd, access, mr);
917 if (err)
918 goto err2;
919 902
920 return &mr->ibmr;903 return &mr->ibmr;
921
922err2:
923 rxe_drop_ref(pd);
924 rxe_drop_index(mr);
925 rxe_drop_ref(mr);
926err1:
927 return ERR_PTR(err);
928}904}
929 905
930static struct ib_mr *rxe_reg_user_mr(struct ib_pd *ibpd,906static struct ib_mr *rxe_reg_user_mr(struct ib_pd *ibpd,
@@ -975,7 +951,7 @@ static int rxe_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata) · 44 unmodified lines
975}951}
976 952
977static struct ib_mr *rxe_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type,953static struct ib_mr *rxe_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type,
978 u32 max_num_sg, struct ib_udata *udata)954 u32 max_num_sg)
979{955{
980 struct rxe_dev *rxe = to_rdev(ibpd->device);956 struct rxe_dev *rxe = to_rdev(ibpd->device);
981 struct rxe_pd *pd = to_rpd(ibpd);957 struct rxe_pd *pd = to_rpd(ibpd);
drivers/infiniband/sw/rxe/rxe_verbs.h+0−1
@@ -371,7 +371,6 @@ struct rxe_mc_elem { · 370 unmodified lines
371 371
372struct rxe_port {372struct rxe_port {
373 struct ib_port_attr attr;373 struct ib_port_attr attr;
374 u16 *pkey_tbl;
375 __be64 port_guid;374 __be64 port_guid;
376 __be64 subnet_prefix;375 __be64 subnet_prefix;
377 spinlock_t port_lock; /* guard port */376 spinlock_t port_lock; /* guard port */
drivers/infiniband/sw/siw/siw_main.c+0−1
@@ -289,7 +289,6 @@ static const struct ib_device_ops siw_device_ops = { · 288 unmodified lines
289 .post_srq_recv = siw_post_srq_recv,289 .post_srq_recv = siw_post_srq_recv,
290 .query_device = siw_query_device,290 .query_device = siw_query_device,
291 .query_gid = siw_query_gid,291 .query_gid = siw_query_gid,
292 .query_pkey = siw_query_pkey,
293 .query_port = siw_query_port,292 .query_port = siw_query_port,
294 .query_qp = siw_query_qp,293 .query_qp = siw_query_qp,
295 .query_srq = siw_query_srq,294 .query_srq = siw_query_srq,
drivers/infiniband/sw/siw/siw_verbs.c+1−10
@@ -176,7 +176,6 @@ int siw_query_port(struct ib_device *base_dev, u8 port, · 175 unmodified lines
176 attr->active_mtu = ib_mtu_int_to_enum(sdev->netdev->mtu);176 attr->active_mtu = ib_mtu_int_to_enum(sdev->netdev->mtu);
177 attr->phys_state = sdev->state == IB_PORT_ACTIVE ?177 attr->phys_state = sdev->state == IB_PORT_ACTIVE ?
178 IB_PORT_PHYS_STATE_LINK_UP : IB_PORT_PHYS_STATE_DISABLED;178 IB_PORT_PHYS_STATE_LINK_UP : IB_PORT_PHYS_STATE_DISABLED;
179 attr->pkey_tbl_len = 1;
180 attr->port_cap_flags = IB_PORT_CM_SUP | IB_PORT_DEVICE_MGMT_SUP;179 attr->port_cap_flags = IB_PORT_CM_SUP | IB_PORT_DEVICE_MGMT_SUP;
181 attr->state = sdev->state;180 attr->state = sdev->state;
182 /*181 /*
@@ -204,20 +203,12 @@ int siw_get_port_immutable(struct ib_device *base_dev, u8 port, · 21 unmodified lines
204 if (rv)203 if (rv)
205 return rv;204 return rv;
206 205
207 port_immutable->pkey_tbl_len = attr.pkey_tbl_len;
208 port_immutable->gid_tbl_len = attr.gid_tbl_len;206 port_immutable->gid_tbl_len = attr.gid_tbl_len;
209 port_immutable->core_cap_flags = RDMA_CORE_PORT_IWARP;207 port_immutable->core_cap_flags = RDMA_CORE_PORT_IWARP;
210 208
211 return 0;209 return 0;
212}210}
213 211
214int siw_query_pkey(struct ib_device *base_dev, u8 port, u16 idx, u16 *pkey)
215{
216 /* Report the default pkey */
217 *pkey = 0xffff;
218 return 0;
219}
220
221int siw_query_gid(struct ib_device *base_dev, u8 port, int idx,212int siw_query_gid(struct ib_device *base_dev, u8 port, int idx,
222 union ib_gid *gid)213 union ib_gid *gid)
223{214{
@@ -1373,7 +1364,7 @@ err_out: · 1149 unmodified lines
1373}1364}
1374 1365
1375struct ib_mr *siw_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,1366struct ib_mr *siw_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
1376 u32 max_sge, struct ib_udata *udata)1367 u32 max_sge)
1377{1368{
1378 struct siw_device *sdev = to_siw_dev(pd->device);1369 struct siw_device *sdev = to_siw_dev(pd->device);
1379 struct siw_mr *mr = NULL;1370 struct siw_mr *mr = NULL;
drivers/infiniband/sw/siw/siw_verbs.h+1−2
@@ -46,7 +46,6 @@ int siw_create_cq(struct ib_cq *base_cq, const struct ib_cq_init_attr *attr, · 45 unmodified lines
46 struct ib_udata *udata);46 struct ib_udata *udata);
47int siw_query_port(struct ib_device *base_dev, u8 port,47int siw_query_port(struct ib_device *base_dev, u8 port,
48 struct ib_port_attr *attr);48 struct ib_port_attr *attr);
49int siw_query_pkey(struct ib_device *base_dev, u8 port, u16 idx, u16 *pkey);
50int siw_query_gid(struct ib_device *base_dev, u8 port, int idx,49int siw_query_gid(struct ib_device *base_dev, u8 port, int idx,
51 union ib_gid *gid);50 union ib_gid *gid);
52int siw_alloc_pd(struct ib_pd *base_pd, struct ib_udata *udata);51int siw_alloc_pd(struct ib_pd *base_pd, struct ib_udata *udata);
@@ -69,7 +68,7 @@ int siw_req_notify_cq(struct ib_cq *base_cq, enum ib_cq_notify_flags flags); · 16 unmodified lines
69struct ib_mr *siw_reg_user_mr(struct ib_pd *base_pd, u64 start, u64 len,68struct ib_mr *siw_reg_user_mr(struct ib_pd *base_pd, u64 start, u64 len,
70 u64 rnic_va, int rights, struct ib_udata *udata);69 u64 rnic_va, int rights, struct ib_udata *udata);
71struct ib_mr *siw_alloc_mr(struct ib_pd *base_pd, enum ib_mr_type mr_type,70struct ib_mr *siw_alloc_mr(struct ib_pd *base_pd, enum ib_mr_type mr_type,
72 u32 max_sge, struct ib_udata *udata);71 u32 max_sge);
73struct ib_mr *siw_get_dma_mr(struct ib_pd *base_pd, int rights);72struct ib_mr *siw_get_dma_mr(struct ib_pd *base_pd, int rights);
74int siw_map_mr_sg(struct ib_mr *base_mr, struct scatterlist *sl, int num_sle,73int siw_map_mr_sg(struct ib_mr *base_mr, struct scatterlist *sl, int num_sle,
75 unsigned int *sg_off);74 unsigned int *sg_off);
drivers/infiniband/ulp/ipoib/ipoib.h+2−2
@@ -515,7 +515,7 @@ void ipoib_ib_dev_cleanup(struct net_device *dev); · 514 unmodified lines
515 515
516int ipoib_ib_dev_open_default(struct net_device *dev);516int ipoib_ib_dev_open_default(struct net_device *dev);
517int ipoib_ib_dev_open(struct net_device *dev);517int ipoib_ib_dev_open(struct net_device *dev);
518int ipoib_ib_dev_stop(struct net_device *dev);518void ipoib_ib_dev_stop(struct net_device *dev);
519void ipoib_ib_dev_up(struct net_device *dev);519void ipoib_ib_dev_up(struct net_device *dev);
520void ipoib_ib_dev_down(struct net_device *dev);520void ipoib_ib_dev_down(struct net_device *dev);
521int ipoib_ib_dev_stop_default(struct net_device *dev);521int ipoib_ib_dev_stop_default(struct net_device *dev);
@@ -527,7 +527,7 @@ void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb); · 5 unmodified lines
527 527
528void ipoib_mcast_restart_task(struct work_struct *work);528void ipoib_mcast_restart_task(struct work_struct *work);
529void ipoib_mcast_start_thread(struct net_device *dev);529void ipoib_mcast_start_thread(struct net_device *dev);
530int ipoib_mcast_stop_thread(struct net_device *dev);530void ipoib_mcast_stop_thread(struct net_device *dev);
531 531
532void ipoib_mcast_dev_down(struct net_device *dev);532void ipoib_mcast_dev_down(struct net_device *dev);
533void ipoib_mcast_dev_flush(struct net_device *dev);533void ipoib_mcast_dev_flush(struct net_device *dev);
drivers/infiniband/ulp/ipoib/ipoib_ib.c+29−38
@@ -670,13 +670,12 @@ int ipoib_send(struct net_device *dev, struct sk_buff *skb, · 669 unmodified lines
670 return rc;670 return rc;
671}671}
672 672
673static void __ipoib_reap_ah(struct net_device *dev)673static void ipoib_reap_dead_ahs(struct ipoib_dev_priv *priv)
674{674{
675 struct ipoib_dev_priv *priv = ipoib_priv(dev);
676 struct ipoib_ah *ah, *tah;675 struct ipoib_ah *ah, *tah;
677 unsigned long flags;676 unsigned long flags;
678 677
679 netif_tx_lock_bh(dev);678 netif_tx_lock_bh(priv->dev);
680 spin_lock_irqsave(&priv->lock, flags);679 spin_lock_irqsave(&priv->lock, flags);
681 680
682 list_for_each_entry_safe(ah, tah, &priv->dead_ahs, list)681 list_for_each_entry_safe(ah, tah, &priv->dead_ahs, list)
@@ -687,37 +686,37 @@ static void __ipoib_reap_ah(struct net_device *dev) · 4 unmodified lines
687 }686 }
688 687
689 spin_unlock_irqrestore(&priv->lock, flags);688 spin_unlock_irqrestore(&priv->lock, flags);
690 netif_tx_unlock_bh(dev);689 netif_tx_unlock_bh(priv->dev);
691}690}
692 691
693void ipoib_reap_ah(struct work_struct *work)692void ipoib_reap_ah(struct work_struct *work)
694{693{
695 struct ipoib_dev_priv *priv =694 struct ipoib_dev_priv *priv =
696 container_of(work, struct ipoib_dev_priv, ah_reap_task.work);695 container_of(work, struct ipoib_dev_priv, ah_reap_task.work);
697 struct net_device *dev = priv->dev;
698 696
699 __ipoib_reap_ah(dev);697 ipoib_reap_dead_ahs(priv);
700 698
701 if (!test_bit(IPOIB_STOP_REAPER, &priv->flags))699 if (!test_bit(IPOIB_STOP_REAPER, &priv->flags))
702 queue_delayed_work(priv->wq, &priv->ah_reap_task,700 queue_delayed_work(priv->wq, &priv->ah_reap_task,
703 round_jiffies_relative(HZ));701 round_jiffies_relative(HZ));
704}702}
705 703
706static void ipoib_flush_ah(struct net_device *dev)704static void ipoib_start_ah_reaper(struct ipoib_dev_priv *priv)
707{705{
708 struct ipoib_dev_priv *priv = ipoib_priv(dev);706 clear_bit(IPOIB_STOP_REAPER, &priv->flags);
709 707 queue_delayed_work(priv->wq, &priv->ah_reap_task,
710 cancel_delayed_work(&priv->ah_reap_task);708 round_jiffies_relative(HZ));
711 flush_workqueue(priv->wq);
712 ipoib_reap_ah(&priv->ah_reap_task.work);
713}709}
714 710
715static void ipoib_stop_ah(struct net_device *dev)711static void ipoib_stop_ah_reaper(struct ipoib_dev_priv *priv)
716{712{
717 struct ipoib_dev_priv *priv = ipoib_priv(dev);
718
719 set_bit(IPOIB_STOP_REAPER, &priv->flags);713 set_bit(IPOIB_STOP_REAPER, &priv->flags);
720 ipoib_flush_ah(dev);714 cancel_delayed_work(&priv->ah_reap_task);
715 /*
716 * After ipoib_stop_ah_reaper() we always go through
717 * ipoib_reap_dead_ahs() which ensures the work is really stopped and
718 * does a final flush out of the dead_ah's list
719 */
721}720}
722 721
723static int recvs_pending(struct net_device *dev)722static int recvs_pending(struct net_device *dev)
@@ -846,18 +845,6 @@ timeout: · 122 unmodified lines
846 return 0;845 return 0;
847}846}
848 847
849int ipoib_ib_dev_stop(struct net_device *dev)
850{
851 struct ipoib_dev_priv *priv = ipoib_priv(dev);
852
853 priv->rn_ops->ndo_stop(dev);
854
855 clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
856 ipoib_flush_ah(dev);
857
858 return 0;
859}
860
861int ipoib_ib_dev_open_default(struct net_device *dev)848int ipoib_ib_dev_open_default(struct net_device *dev)
862{849{
863 struct ipoib_dev_priv *priv = ipoib_priv(dev);850 struct ipoib_dev_priv *priv = ipoib_priv(dev);
@@ -901,10 +888,7 @@ int ipoib_ib_dev_open(struct net_device *dev) · 37 unmodified lines
901 return -1;888 return -1;
902 }889 }
903 890
904 clear_bit(IPOIB_STOP_REAPER, &priv->flags);891 ipoib_start_ah_reaper(priv);
905 queue_delayed_work(priv->wq, &priv->ah_reap_task,
906 round_jiffies_relative(HZ));
907
908 if (priv->rn_ops->ndo_open(dev)) {892 if (priv->rn_ops->ndo_open(dev)) {
909 pr_warn("%s: Failed to open dev\n", dev->name);893 pr_warn("%s: Failed to open dev\n", dev->name);
910 goto dev_stop;894 goto dev_stop;
@@ -915,13 +899,20 @@ int ipoib_ib_dev_open(struct net_device *dev) · 4 unmodified lines
915 return 0;899 return 0;
916 900
917dev_stop:901dev_stop:
918 set_bit(IPOIB_STOP_REAPER, &priv->flags);902 ipoib_stop_ah_reaper(priv);
919 cancel_delayed_work(&priv->ah_reap_task);
920 set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
921 ipoib_ib_dev_stop(dev);
922 return -1;903 return -1;
923}904}
924 905
906void ipoib_ib_dev_stop(struct net_device *dev)
907{
908 struct ipoib_dev_priv *priv = ipoib_priv(dev);
909
910 priv->rn_ops->ndo_stop(dev);
911
912 clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags);
913 ipoib_stop_ah_reaper(priv);
914}
915
925void ipoib_pkey_dev_check_presence(struct net_device *dev)916void ipoib_pkey_dev_check_presence(struct net_device *dev)
926{917{
927 struct ipoib_dev_priv *priv = ipoib_priv(dev);918 struct ipoib_dev_priv *priv = ipoib_priv(dev);
@@ -1232,7 +1223,7 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, · 304 unmodified lines
1232 ipoib_mcast_dev_flush(dev);1223 ipoib_mcast_dev_flush(dev);
1233 if (oper_up)1224 if (oper_up)
1234 set_bit(IPOIB_FLAG_OPER_UP, &priv->flags);1225 set_bit(IPOIB_FLAG_OPER_UP, &priv->flags);
1235 ipoib_flush_ah(dev);1226 ipoib_reap_dead_ahs(priv);
1236 }1227 }
1237 1228
1238 if (level >= IPOIB_FLUSH_NORMAL)1229 if (level >= IPOIB_FLUSH_NORMAL)
@@ -1307,7 +1298,7 @@ void ipoib_ib_dev_cleanup(struct net_device *dev) · 68 unmodified lines
1307 * the neighbor garbage collection is stopped and reaped.1298 * the neighbor garbage collection is stopped and reaped.
1308 * That should all be done now, so make a final ah flush.1299 * That should all be done now, so make a final ah flush.
1309 */1300 */
1310 ipoib_stop_ah(dev);1301 ipoib_reap_dead_ahs(priv);
1311 1302
1312 clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);1303 clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags);
1313 1304
drivers/infiniband/ulp/ipoib/ipoib_main.c+11−2
@@ -1892,8 +1892,15 @@ static void ipoib_child_init(struct net_device *ndev) · 1891 unmodified lines
1892 1892
1893 priv->max_ib_mtu = ppriv->max_ib_mtu;1893 priv->max_ib_mtu = ppriv->max_ib_mtu;
1894 set_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags);1894 set_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags);
1895 memcpy(priv->dev->dev_addr, ppriv->dev->dev_addr, INFINIBAND_ALEN);1895 if (memchr_inv(priv->dev->dev_addr, 0, INFINIBAND_ALEN))
1896 memcpy(&priv->local_gid, &ppriv->local_gid, sizeof(priv->local_gid));1896 memcpy(&priv->local_gid, priv->dev->dev_addr + 4,
1897 sizeof(priv->local_gid));
1898 else {
1899 memcpy(priv->dev->dev_addr, ppriv->dev->dev_addr,
1900 INFINIBAND_ALEN);
1901 memcpy(&priv->local_gid, &ppriv->local_gid,
1902 sizeof(priv->local_gid));
1903 }
1897}1904}
1898 1905
1899static int ipoib_ndo_init(struct net_device *ndev)1906static int ipoib_ndo_init(struct net_device *ndev)
@@ -1976,6 +1983,8 @@ static void ipoib_ndo_uninit(struct net_device *dev) · 76 unmodified lines
1976 1983
1977 /* no more works over the priv->wq */1984 /* no more works over the priv->wq */
1978 if (priv->wq) {1985 if (priv->wq) {
1986 /* See ipoib_mcast_carrier_on_task() */
1987 WARN_ON(test_bit(IPOIB_FLAG_OPER_UP, &priv->flags));
1979 flush_workqueue(priv->wq);1988 flush_workqueue(priv->wq);
1980 destroy_workqueue(priv->wq);1989 destroy_workqueue(priv->wq);
1981 priv->wq = NULL;1990 priv->wq = NULL;
drivers/infiniband/ulp/ipoib/ipoib_multicast.c+1−3
@@ -680,15 +680,13 @@ void ipoib_mcast_start_thread(struct net_device *dev) · 679 unmodified lines
680 spin_unlock_irqrestore(&priv->lock, flags);680 spin_unlock_irqrestore(&priv->lock, flags);
681}681}
682 682
683int ipoib_mcast_stop_thread(struct net_device *dev)683void ipoib_mcast_stop_thread(struct net_device *dev)
684{684{
685 struct ipoib_dev_priv *priv = ipoib_priv(dev);685 struct ipoib_dev_priv *priv = ipoib_priv(dev);
686 686
687 ipoib_dbg_mcast(priv, "stopping multicast thread\n");687 ipoib_dbg_mcast(priv, "stopping multicast thread\n");
688 688
689 cancel_delayed_work_sync(&priv->mcast_task);689 cancel_delayed_work_sync(&priv->mcast_task);
690
691 return 0;
692}690}
693 691
694static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast)692static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast)
drivers/infiniband/ulp/iser/iscsi_iser.h+6−19
@@ -299,18 +299,6 @@ struct iser_conn; · 298 unmodified lines
299struct ib_conn;299struct ib_conn;
300struct iscsi_iser_task;300struct iscsi_iser_task;
301 301
302/**
303 * struct iser_comp - iSER completion context
304 *
305 * @cq: completion queue
306 * @active_qps: Number of active QPs attached
307 * to completion context
308 */
309struct iser_comp {
310 struct ib_cq *cq;
311 int active_qps;
312};
313
314/**302/**
315 * struct iser_device - iSER device handle303 * struct iser_device - iSER device handle
316 *304 *
@@ -320,9 +308,6 @@ struct iser_comp { · 3 unmodified lines
320 * @event_handler: IB events handle routine308 * @event_handler: IB events handle routine
321 * @ig_list: entry in devices list309 * @ig_list: entry in devices list
322 * @refcount: Reference counter, dominated by open iser connections310 * @refcount: Reference counter, dominated by open iser connections
323 * @comps_used: Number of completion contexts used, Min between online
324 * cpus and device max completion vectors
325 * @comps: Dinamically allocated array of completion handlers
326 */311 */
327struct iser_device {312struct iser_device {
328 struct ib_device *ib_device;313 struct ib_device *ib_device;
@@ -330,8 +315,6 @@ struct iser_device { · 1 unmodified line
330 struct ib_event_handler event_handler;315 struct ib_event_handler event_handler;
331 struct list_head ig_list;316 struct list_head ig_list;
332 int refcount;317 int refcount;
333 int comps_used;
334 struct iser_comp *comps;
335};318};
336 319
337/**320/**
@@ -353,6 +336,7 @@ struct iser_reg_resources { · 15 unmodified lines
353 * @list: entry in connection fastreg pool336 * @list: entry in connection fastreg pool
354 * @rsc: data buffer registration resources337 * @rsc: data buffer registration resources
355 * @sig_protected: is region protected indicator338 * @sig_protected: is region protected indicator
339 * @all_list: first and last list members
356 */340 */
357struct iser_fr_desc {341struct iser_fr_desc {
358 struct list_head list;342 struct list_head list;
@@ -367,6 +351,7 @@ struct iser_fr_desc { · 8 unmodified lines
367 * @list: list of fastreg descriptors351 * @list: list of fastreg descriptors
368 * @lock: protects fastreg pool352 * @lock: protects fastreg pool
369 * @size: size of the pool353 * @size: size of the pool
354 * @all_list: first and last list members
370 */355 */
371struct iser_fr_pool {356struct iser_fr_pool {
372 struct list_head list;357 struct list_head list;
@@ -380,11 +365,12 @@ struct iser_fr_pool { · 7 unmodified lines
380 *365 *
381 * @cma_id: rdma_cm connection maneger handle366 * @cma_id: rdma_cm connection maneger handle
382 * @qp: Connection Queue-pair367 * @qp: Connection Queue-pair
368 * @cq: Connection completion queue
369 * @cq_size: The number of max outstanding completions
383 * @post_recv_buf_count: post receive counter370 * @post_recv_buf_count: post receive counter
384 * @sig_count: send work request signal count371 * @sig_count: send work request signal count
385 * @rx_wr: receive work request for batch posts372 * @rx_wr: receive work request for batch posts
386 * @device: reference to iser device373 * @device: reference to iser device
387 * @comp: iser completion context
388 * @fr_pool: connection fast registration poool374 * @fr_pool: connection fast registration poool
389 * @pi_support: Indicate device T10-PI support375 * @pi_support: Indicate device T10-PI support
390 * @reg_cqe: completion handler376 * @reg_cqe: completion handler
@@ -392,11 +378,12 @@ struct iser_fr_pool { · 1 unmodified line
392struct ib_conn {378struct ib_conn {
393 struct rdma_cm_id *cma_id;379 struct rdma_cm_id *cma_id;
394 struct ib_qp *qp;380 struct ib_qp *qp;
381 struct ib_cq *cq;
382 u32 cq_size;
395 int post_recv_buf_count;383 int post_recv_buf_count;
396 u8 sig_count;384 u8 sig_count;
397 struct ib_recv_wr rx_wr[ISER_MIN_POSTED_RX];385 struct ib_recv_wr rx_wr[ISER_MIN_POSTED_RX];
398 struct iser_device *device;386 struct iser_device *device;
399 struct iser_comp *comp;
400 struct iser_fr_pool fr_pool;387 struct iser_fr_pool fr_pool;
401 bool pi_support;388 bool pi_support;
402 struct ib_cqe reg_cqe;389 struct ib_cqe reg_cqe;
drivers/infiniband/ulp/iser/iser_verbs.c+25−87
@@ -68,59 +68,23 @@ static void iser_event_handler(struct ib_event_handler *handler, · 67 unmodified lines
68static int iser_create_device_ib_res(struct iser_device *device)68static int iser_create_device_ib_res(struct iser_device *device)
69{69{
70 struct ib_device *ib_dev = device->ib_device;70 struct ib_device *ib_dev = device->ib_device;
71 int i, max_cqe;
72 71
73 if (!(ib_dev->attrs.device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS)) {72 if (!(ib_dev->attrs.device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS)) {
74 iser_err("IB device does not support memory registrations\n");73 iser_err("IB device does not support memory registrations\n");
75 return -1;74 return -1;
76 }75 }
77 76
78 device->comps_used = min_t(int, num_online_cpus(),
79 ib_dev->num_comp_vectors);
80
81 device->comps = kcalloc(device->comps_used, sizeof(*device->comps),
82 GFP_KERNEL);
83 if (!device->comps)
84 goto comps_err;
85
86 max_cqe = min(ISER_MAX_CQ_LEN, ib_dev->attrs.max_cqe);
87
88 iser_info("using %d CQs, device %s supports %d vectors max_cqe %d\n",
89 device->comps_used, dev_name(&ib_dev->dev),
90 ib_dev->num_comp_vectors, max_cqe);
91
92 device->pd = ib_alloc_pd(ib_dev,77 device->pd = ib_alloc_pd(ib_dev,
93 iser_always_reg ? 0 : IB_PD_UNSAFE_GLOBAL_RKEY);78 iser_always_reg ? 0 : IB_PD_UNSAFE_GLOBAL_RKEY);
94 if (IS_ERR(device->pd))79 if (IS_ERR(device->pd))
95 goto pd_err;80 goto pd_err;
96 81
97 for (i = 0; i < device->comps_used; i++) {
98 struct iser_comp *comp = &device->comps[i];
99
100 comp->cq = ib_alloc_cq(ib_dev, comp, max_cqe, i,
101 IB_POLL_SOFTIRQ);
102 if (IS_ERR(comp->cq)) {
103 comp->cq = NULL;
104 goto cq_err;
105 }
106 }
107
108 INIT_IB_EVENT_HANDLER(&device->event_handler, ib_dev,82 INIT_IB_EVENT_HANDLER(&device->event_handler, ib_dev,
109 iser_event_handler);83 iser_event_handler);
110 ib_register_event_handler(&device->event_handler);84 ib_register_event_handler(&device->event_handler);
111 return 0;85 return 0;
112 86
113cq_err:
114 for (i = 0; i < device->comps_used; i++) {
115 struct iser_comp *comp = &device->comps[i];
116
117 if (comp->cq)
118 ib_free_cq(comp->cq);
119 }
120 ib_dealloc_pd(device->pd);
121pd_err:87pd_err:
122 kfree(device->comps);
123comps_err:
124 iser_err("failed to allocate an IB resource\n");88 iser_err("failed to allocate an IB resource\n");
125 return -1;89 return -1;
126}90}
@@ -131,20 +95,9 @@ comps_err: · 4 unmodified lines
131 */95 */
132static void iser_free_device_ib_res(struct iser_device *device)96static void iser_free_device_ib_res(struct iser_device *device)
133{97{
134 int i;
135
136 for (i = 0; i < device->comps_used; i++) {
137 struct iser_comp *comp = &device->comps[i];
138
139 ib_free_cq(comp->cq);
140 comp->cq = NULL;
141 }
142
143 ib_unregister_event_handler(&device->event_handler);98 ib_unregister_event_handler(&device->event_handler);
144 ib_dealloc_pd(device->pd);99 ib_dealloc_pd(device->pd);
145 100
146 kfree(device->comps);
147 device->comps = NULL;
148 device->pd = NULL;101 device->pd = NULL;
149}102}
150 103
@@ -287,70 +240,57 @@ static int iser_create_ib_conn_res(struct ib_conn *ib_conn) · 136 unmodified lines
287 struct ib_device *ib_dev;240 struct ib_device *ib_dev;
288 struct ib_qp_init_attr init_attr;241 struct ib_qp_init_attr init_attr;
289 int ret = -ENOMEM;242 int ret = -ENOMEM;
290 int index, min_index = 0;243 unsigned int max_send_wr, cq_size;
291 244
292 BUG_ON(ib_conn->device == NULL);245 BUG_ON(ib_conn->device == NULL);
293 246
294 device = ib_conn->device;247 device = ib_conn->device;
295 ib_dev = device->ib_device;248 ib_dev = device->ib_device;
296 249
297 memset(&init_attr, 0, sizeof init_attr);250 if (ib_conn->pi_support)
251 max_send_wr = ISER_QP_SIG_MAX_REQ_DTOS + 1;
252 else
253 max_send_wr = ISER_QP_MAX_REQ_DTOS + 1;
254 max_send_wr = min_t(unsigned int, max_send_wr,
255 (unsigned int)ib_dev->attrs.max_qp_wr);
298 256
299 mutex_lock(&ig.connlist_mutex);257 cq_size = max_send_wr + ISER_QP_MAX_RECV_DTOS;
300 /* select the CQ with the minimal number of usages */258 ib_conn->cq = ib_cq_pool_get(ib_dev, cq_size, -1, IB_POLL_SOFTIRQ);
301 for (index = 0; index < device->comps_used; index++) {259 if (IS_ERR(ib_conn->cq)) {
302 if (device->comps[index].active_qps <260 ret = PTR_ERR(ib_conn->cq);
303 device->comps[min_index].active_qps)261 goto cq_err;
304 min_index = index;
305 }262 }
306 ib_conn->comp = &device->comps[min_index];263 ib_conn->cq_size = cq_size;
307 ib_conn->comp->active_qps++;264
308 mutex_unlock(&ig.connlist_mutex);265 memset(&init_attr, 0, sizeof(init_attr));
309 iser_info("cq index %d used for ib_conn %p\n", min_index, ib_conn);
310 266
311 init_attr.event_handler = iser_qp_event_callback;267 init_attr.event_handler = iser_qp_event_callback;
312 init_attr.qp_context = (void *)ib_conn;268 init_attr.qp_context = (void *)ib_conn;
313 init_attr.send_cq = ib_conn->comp->cq;269 init_attr.send_cq = ib_conn->cq;
314 init_attr.recv_cq = ib_conn->comp->cq;270 init_attr.recv_cq = ib_conn->cq;
315 init_attr.cap.max_recv_wr = ISER_QP_MAX_RECV_DTOS;271 init_attr.cap.max_recv_wr = ISER_QP_MAX_RECV_DTOS;
316 init_attr.cap.max_send_sge = 2;272 init_attr.cap.max_send_sge = 2;
317 init_attr.cap.max_recv_sge = 1;273 init_attr.cap.max_recv_sge = 1;
318 init_attr.sq_sig_type = IB_SIGNAL_REQ_WR;274 init_attr.sq_sig_type = IB_SIGNAL_REQ_WR;
319 init_attr.qp_type = IB_QPT_RC;275 init_attr.qp_type = IB_QPT_RC;
320 if (ib_conn->pi_support) {276 init_attr.cap.max_send_wr = max_send_wr;
321 init_attr.cap.max_send_wr = ISER_QP_SIG_MAX_REQ_DTOS + 1;277 if (ib_conn->pi_support)
322 init_attr.create_flags |= IB_QP_CREATE_INTEGRITY_EN;278 init_attr.create_flags |= IB_QP_CREATE_INTEGRITY_EN;
323 iser_conn->max_cmds =279 iser_conn->max_cmds = ISER_GET_MAX_XMIT_CMDS(max_send_wr - 1);
324 ISER_GET_MAX_XMIT_CMDS(ISER_QP_SIG_MAX_REQ_DTOS);
325 } else {
326 if (ib_dev->attrs.max_qp_wr > ISER_QP_MAX_REQ_DTOS) {
327 init_attr.cap.max_send_wr = ISER_QP_MAX_REQ_DTOS + 1;
328 iser_conn->max_cmds =
329 ISER_GET_MAX_XMIT_CMDS(ISER_QP_MAX_REQ_DTOS);
330 } else {
331 init_attr.cap.max_send_wr = ib_dev->attrs.max_qp_wr;
332 iser_conn->max_cmds =
333 ISER_GET_MAX_XMIT_CMDS(ib_dev->attrs.max_qp_wr);
334 iser_dbg("device %s supports max_send_wr %d\n",
335 dev_name(&device->ib_device->dev),
336 ib_dev->attrs.max_qp_wr);
337 }
338 }
339 280
340 ret = rdma_create_qp(ib_conn->cma_id, device->pd, &init_attr);281 ret = rdma_create_qp(ib_conn->cma_id, device->pd, &init_attr);
341 if (ret)282 if (ret)
342 goto out_err;283 goto out_err;
343 284
344 ib_conn->qp = ib_conn->cma_id->qp;285 ib_conn->qp = ib_conn->cma_id->qp;
345 iser_info("setting conn %p cma_id %p qp %p\n",286 iser_info("setting conn %p cma_id %p qp %p max_send_wr %d\n",
346 ib_conn, ib_conn->cma_id,287 ib_conn, ib_conn->cma_id,
347 ib_conn->cma_id->qp);288 ib_conn->cma_id->qp, max_send_wr);
348 return ret;289 return ret;
349 290
350out_err:291out_err:
351 mutex_lock(&ig.connlist_mutex);292 ib_cq_pool_put(ib_conn->cq, ib_conn->cq_size);
352 ib_conn->comp->active_qps--;293cq_err:
353 mutex_unlock(&ig.connlist_mutex);
354 iser_err("unable to alloc mem or create resource, err %d\n", ret);294 iser_err("unable to alloc mem or create resource, err %d\n", ret);
355 295
356 return ret;296 return ret;
@@ -462,10 +402,8 @@ static void iser_free_ib_conn_res(struct iser_conn *iser_conn, · 105 unmodified lines
462 iser_conn, ib_conn->cma_id, ib_conn->qp);402 iser_conn, ib_conn->cma_id, ib_conn->qp);
463 403
464 if (ib_conn->qp != NULL) {404 if (ib_conn->qp != NULL) {
465 mutex_lock(&ig.connlist_mutex);
466 ib_conn->comp->active_qps--;
467 mutex_unlock(&ig.connlist_mutex);
468 rdma_destroy_qp(ib_conn->cma_id);405 rdma_destroy_qp(ib_conn->cma_id);
406 ib_cq_pool_put(ib_conn->cq, ib_conn->cq_size);
469 ib_conn->qp = NULL;407 ib_conn->qp = NULL;
470 }408 }
471 409
drivers/infiniband/ulp/isert/ib_isert.c+36−139
@@ -24,13 +24,6 @@ · 23 unmodified lines
24 24
25#include "ib_isert.h"25#include "ib_isert.h"
26 26
27#define ISERT_MAX_CONN 8
28#define ISER_MAX_RX_CQ_LEN (ISERT_QP_MAX_RECV_DTOS * ISERT_MAX_CONN)
29#define ISER_MAX_TX_CQ_LEN \
30 ((ISERT_QP_MAX_REQ_DTOS + ISCSI_DEF_XMIT_CMDS_MAX) * ISERT_MAX_CONN)
31#define ISER_MAX_CQ_LEN (ISER_MAX_RX_CQ_LEN + ISER_MAX_TX_CQ_LEN + \
32 ISERT_MAX_CONN)
33
34static int isert_debug_level;27static int isert_debug_level;
35module_param_named(debug_level, isert_debug_level, int, 0644);28module_param_named(debug_level, isert_debug_level, int, 0644);
36MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0 (default:0)");29MODULE_PARM_DESC(debug_level, "Enable debug tracing if > 0 (default:0)");
@@ -82,53 +75,34 @@ isert_qp_event_callback(struct ib_event *e, void *context) · 45 unmodified lines
82 }75 }
83}76}
84 77
85static struct isert_comp *
86isert_comp_get(struct isert_conn *isert_conn)
87{
88 struct isert_device *device = isert_conn->device;
89 struct isert_comp *comp;
90 int i, min = 0;
91
92 mutex_lock(&device_list_mutex);
93 for (i = 0; i < device->comps_used; i++)
94 if (device->comps[i].active_qps <
95 device->comps[min].active_qps)
96 min = i;
97 comp = &device->comps[min];
98 comp->active_qps++;
99 mutex_unlock(&device_list_mutex);
100
101 isert_info("conn %p, using comp %p min_index: %d\n",
102 isert_conn, comp, min);
103
104 return comp;
105}
106
107static void
108isert_comp_put(struct isert_comp *comp)
109{
110 mutex_lock(&device_list_mutex);
111 comp->active_qps--;
112 mutex_unlock(&device_list_mutex);
113}
114
115static struct ib_qp *78static struct ib_qp *
116isert_create_qp(struct isert_conn *isert_conn,79isert_create_qp(struct isert_conn *isert_conn,
117 struct isert_comp *comp,
118 struct rdma_cm_id *cma_id)80 struct rdma_cm_id *cma_id)
119{81{
82 u32 cq_size = ISERT_QP_MAX_REQ_DTOS + ISERT_QP_MAX_RECV_DTOS + 2;
120 struct isert_device *device = isert_conn->device;83 struct isert_device *device = isert_conn->device;
84 struct ib_device *ib_dev = device->ib_device;
121 struct ib_qp_init_attr attr;85 struct ib_qp_init_attr attr;
122 int ret;86 int ret, factor;
87
88 isert_conn->cq = ib_cq_pool_get(ib_dev, cq_size, -1, IB_POLL_WORKQUEUE);
89 if (IS_ERR(isert_conn->cq)) {
90 isert_err("Unable to allocate cq\n");
91 ret = PTR_ERR(isert_conn->cq);
92 return ERR_PTR(ret);
93 }
94 isert_conn->cq_size = cq_size;
123 95
124 memset(&attr, 0, sizeof(struct ib_qp_init_attr));96 memset(&attr, 0, sizeof(struct ib_qp_init_attr));
125 attr.event_handler = isert_qp_event_callback;97 attr.event_handler = isert_qp_event_callback;
126 attr.qp_context = isert_conn;98 attr.qp_context = isert_conn;
127 attr.send_cq = comp->cq;99 attr.send_cq = isert_conn->cq;
128 attr.recv_cq = comp->cq;100 attr.recv_cq = isert_conn->cq;
129 attr.cap.max_send_wr = ISERT_QP_MAX_REQ_DTOS + 1;101 attr.cap.max_send_wr = ISERT_QP_MAX_REQ_DTOS + 1;
130 attr.cap.max_recv_wr = ISERT_QP_MAX_RECV_DTOS + 1;102 attr.cap.max_recv_wr = ISERT_QP_MAX_RECV_DTOS + 1;
131 attr.cap.max_rdma_ctxs = ISCSI_DEF_XMIT_CMDS_MAX;103 factor = rdma_rw_mr_factor(device->ib_device, cma_id->port_num,
104 ISCSI_ISER_MAX_SG_TABLESIZE);
105 attr.cap.max_rdma_ctxs = ISCSI_DEF_XMIT_CMDS_MAX * factor;
132 attr.cap.max_send_sge = device->ib_device->attrs.max_send_sge;106 attr.cap.max_send_sge = device->ib_device->attrs.max_send_sge;
133 attr.cap.max_recv_sge = 1;107 attr.cap.max_recv_sge = 1;
134 attr.sq_sig_type = IB_SIGNAL_REQ_WR;108 attr.sq_sig_type = IB_SIGNAL_REQ_WR;
@@ -139,31 +113,14 @@ isert_create_qp(struct isert_conn *isert_conn, · 4 unmodified lines
139 ret = rdma_create_qp(cma_id, device->pd, &attr);113 ret = rdma_create_qp(cma_id, device->pd, &attr);
140 if (ret) {114 if (ret) {
141 isert_err("rdma_create_qp failed for cma_id %d\n", ret);115 isert_err("rdma_create_qp failed for cma_id %d\n", ret);
116 ib_cq_pool_put(isert_conn->cq, isert_conn->cq_size);
117
142 return ERR_PTR(ret);118 return ERR_PTR(ret);
143 }119 }
144 120
145 return cma_id->qp;121 return cma_id->qp;
146}122}
147 123
148static int
149isert_conn_setup_qp(struct isert_conn *isert_conn, struct rdma_cm_id *cma_id)
150{
151 struct isert_comp *comp;
152 int ret;
153
154 comp = isert_comp_get(isert_conn);
155 isert_conn->qp = isert_create_qp(isert_conn, comp, cma_id);
156 if (IS_ERR(isert_conn->qp)) {
157 ret = PTR_ERR(isert_conn->qp);
158 goto err;
159 }
160
161 return 0;
162err:
163 isert_comp_put(comp);
164 return ret;
165}
166
167static int124static int
168isert_alloc_rx_descriptors(struct isert_conn *isert_conn)125isert_alloc_rx_descriptors(struct isert_conn *isert_conn)
169{126{
@@ -231,61 +188,6 @@ isert_free_rx_descriptors(struct isert_conn *isert_conn) · 61 unmodified lines
231 isert_conn->rx_descs = NULL;188 isert_conn->rx_descs = NULL;
232}189}
233 190
234static void
235isert_free_comps(struct isert_device *device)
236{
237 int i;
238
239 for (i = 0; i < device->comps_used; i++) {
240 struct isert_comp *comp = &device->comps[i];
241
242 if (comp->cq)
243 ib_free_cq(comp->cq);
244 }
245 kfree(device->comps);
246}
247
248static int
249isert_alloc_comps(struct isert_device *device)
250{
251 int i, max_cqe, ret = 0;
252
253 device->comps_used = min(ISERT_MAX_CQ, min_t(int, num_online_cpus(),
254 device->ib_device->num_comp_vectors));
255
256 isert_info("Using %d CQs, %s supports %d vectors support "
257 "pi_capable %d\n",
258 device->comps_used, dev_name(&device->ib_device->dev),
259 device->ib_device->num_comp_vectors,
260 device->pi_capable);
261
262 device->comps = kcalloc(device->comps_used, sizeof(struct isert_comp),
263 GFP_KERNEL);
264 if (!device->comps)
265 return -ENOMEM;
266
267 max_cqe = min(ISER_MAX_CQ_LEN, device->ib_device->attrs.max_cqe);
268
269 for (i = 0; i < device->comps_used; i++) {
270 struct isert_comp *comp = &device->comps[i];
271
272 comp->device = device;
273 comp->cq = ib_alloc_cq(device->ib_device, comp, max_cqe, i,
274 IB_POLL_WORKQUEUE);
275 if (IS_ERR(comp->cq)) {
276 isert_err("Unable to allocate cq\n");
277 ret = PTR_ERR(comp->cq);
278 comp->cq = NULL;
279 goto out_cq;
280 }
281 }
282
283 return 0;
284out_cq:
285 isert_free_comps(device);
286 return ret;
287}
288
289static int191static int
290isert_create_device_ib_res(struct isert_device *device)192isert_create_device_ib_res(struct isert_device *device)
291{193{
@@ -296,16 +198,12 @@ isert_create_device_ib_res(struct isert_device *device) · 4 unmodified lines
296 ib_dev->attrs.max_send_sge, ib_dev->attrs.max_recv_sge);198 ib_dev->attrs.max_send_sge, ib_dev->attrs.max_recv_sge);
297 isert_dbg("devattr->max_sge_rd: %d\n", ib_dev->attrs.max_sge_rd);199 isert_dbg("devattr->max_sge_rd: %d\n", ib_dev->attrs.max_sge_rd);
298 200
299 ret = isert_alloc_comps(device);
300 if (ret)
301 goto out;
302
303 device->pd = ib_alloc_pd(ib_dev, 0);201 device->pd = ib_alloc_pd(ib_dev, 0);
304 if (IS_ERR(device->pd)) {202 if (IS_ERR(device->pd)) {
305 ret = PTR_ERR(device->pd);203 ret = PTR_ERR(device->pd);
306 isert_err("failed to allocate pd, device %p, ret=%d\n",204 isert_err("failed to allocate pd, device %p, ret=%d\n",
307 device, ret);205 device, ret);
308 goto out_cq;206 return ret;
309 }207 }
310 208
311 /* Check signature cap */209 /* Check signature cap */
@@ -313,13 +211,6 @@ isert_create_device_ib_res(struct isert_device *device) · 1 unmodified line
313 IB_DEVICE_INTEGRITY_HANDOVER ? true : false;211 IB_DEVICE_INTEGRITY_HANDOVER ? true : false;
314 212
315 return 0;213 return 0;
316
317out_cq:
318 isert_free_comps(device);
319out:
320 if (ret > 0)
321 ret = -EINVAL;
322 return ret;
323}214}
324 215
325static void216static void
@@ -328,7 +219,6 @@ isert_free_device_ib_res(struct isert_device *device) · 2 unmodified lines
328 isert_info("device %p\n", device);219 isert_info("device %p\n", device);
329 220
330 ib_dealloc_pd(device->pd);221 ib_dealloc_pd(device->pd);
331 isert_free_comps(device);
332}222}
333 223
334static void224static void
@@ -490,6 +380,13 @@ isert_set_nego_params(struct isert_conn *isert_conn, · 155 unmodified lines
490 }380 }
491}381}
492 382
383static void
384isert_destroy_qp(struct isert_conn *isert_conn)
385{
386 ib_destroy_qp(isert_conn->qp);
387 ib_cq_pool_put(isert_conn->cq, isert_conn->cq_size);
388}
389
493static int390static int
494isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)391isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
495{392{
@@ -530,17 +427,19 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) · 34 unmodified lines
530 427
531 isert_set_nego_params(isert_conn, &event->param.conn);428 isert_set_nego_params(isert_conn, &event->param.conn);
532 429
533 ret = isert_conn_setup_qp(isert_conn, cma_id);430 isert_conn->qp = isert_create_qp(isert_conn, cma_id);
534 if (ret)431 if (IS_ERR(isert_conn->qp)) {
432 ret = PTR_ERR(isert_conn->qp);
535 goto out_conn_dev;433 goto out_conn_dev;
434 }
536 435
537 ret = isert_login_post_recv(isert_conn);436 ret = isert_login_post_recv(isert_conn);
538 if (ret)437 if (ret)
539 goto out_conn_dev;438 goto out_destroy_qp;
540 439
541 ret = isert_rdma_accept(isert_conn);440 ret = isert_rdma_accept(isert_conn);
542 if (ret)441 if (ret)
543 goto out_conn_dev;442 goto out_destroy_qp;
544 443
545 mutex_lock(&isert_np->mutex);444 mutex_lock(&isert_np->mutex);
546 list_add_tail(&isert_conn->node, &isert_np->accepted);445 list_add_tail(&isert_conn->node, &isert_np->accepted);
@@ -548,6 +447,8 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) · 1 unmodified line
548 447
549 return 0;448 return 0;
550 449
450out_destroy_qp:
451 isert_destroy_qp(isert_conn);
551out_conn_dev:452out_conn_dev:
552 isert_device_put(device);453 isert_device_put(device);
553out_rsp_dma_map:454out_rsp_dma_map:
@@ -572,12 +473,8 @@ isert_connect_release(struct isert_conn *isert_conn) · 18 unmodified lines
572 !isert_conn->dev_removed)473 !isert_conn->dev_removed)
573 rdma_destroy_id(isert_conn->cm_id);474 rdma_destroy_id(isert_conn->cm_id);
574 475
575 if (isert_conn->qp) {476 if (isert_conn->qp)
576 struct isert_comp *comp = isert_conn->qp->recv_cq->cq_context;477 isert_destroy_qp(isert_conn);
577
578 isert_comp_put(comp);
579 ib_destroy_qp(isert_conn->qp);
580 }
581 478
582 if (isert_conn->login_req_buf)479 if (isert_conn->login_req_buf)
583 isert_free_login_buf(isert_conn);480 isert_free_login_buf(isert_conn);
drivers/infiniband/ulp/isert/ib_isert.h+4−17
@@ -63,7 +63,8 @@ · 62 unmodified lines
63 (ISER_RX_PAYLOAD_SIZE + sizeof(u64) + sizeof(struct ib_sge) + \63 (ISER_RX_PAYLOAD_SIZE + sizeof(u64) + sizeof(struct ib_sge) + \
64 sizeof(struct ib_cqe) + sizeof(bool)))64 sizeof(struct ib_cqe) + sizeof(bool)))
65 65
66#define ISCSI_ISER_SG_TABLESIZE 25666/* Maximum support is 16MB I/O size */
67#define ISCSI_ISER_MAX_SG_TABLESIZE 4096
67 68
68enum isert_desc_type {69enum isert_desc_type {
69 ISCSI_TX_CONTROL,70 ISCSI_TX_CONTROL,
@@ -155,6 +156,8 @@ struct isert_conn { · 85 unmodified lines
155 struct iser_tx_desc login_tx_desc;156 struct iser_tx_desc login_tx_desc;
156 struct rdma_cm_id *cm_id;157 struct rdma_cm_id *cm_id;
157 struct ib_qp *qp;158 struct ib_qp *qp;
159 struct ib_cq *cq;
160 u32 cq_size;
158 struct isert_device *device;161 struct isert_device *device;
159 struct mutex mutex;162 struct mutex mutex;
160 struct kref kref;163 struct kref kref;
@@ -165,22 +168,6 @@ struct isert_conn { · 4 unmodified lines
165 bool dev_removed;168 bool dev_removed;
166};169};
167 170
168#define ISERT_MAX_CQ 64
169
170/**
171 * struct isert_comp - iSER completion context
172 *
173 * @device: pointer to device handle
174 * @cq: completion queue
175 * @active_qps: Number of active QPs attached
176 * to completion context
177 */
178struct isert_comp {
179 struct isert_device *device;
180 struct ib_cq *cq;
181 int active_qps;
182};
183
184struct isert_device {171struct isert_device {
185 bool pi_capable;172 bool pi_capable;
186 int refcount;173 int refcount;
drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h+23−0
@@ -118,12 +118,17 @@ · 117 unmodified lines
118 * struct opa_vesw_info - OPA vnic switch information118 * struct opa_vesw_info - OPA vnic switch information
119 * @fabric_id: 10-bit fabric id119 * @fabric_id: 10-bit fabric id
120 * @vesw_id: 12-bit virtual ethernet switch id120 * @vesw_id: 12-bit virtual ethernet switch id
121 * @rsvd0: reserved bytes
121 * @def_port_mask: bitmask of default ports122 * @def_port_mask: bitmask of default ports
123 * @rsvd1: reserved bytes
122 * @pkey: partition key124 * @pkey: partition key
125 * @rsvd2: reserved bytes
123 * @u_mcast_dlid: unknown multicast dlid126 * @u_mcast_dlid: unknown multicast dlid
124 * @u_ucast_dlid: array of unknown unicast dlids127 * @u_ucast_dlid: array of unknown unicast dlids
128 * @rsvd3: reserved bytes
125 * @rc: routing control129 * @rc: routing control
126 * @eth_mtu: Ethernet MTU130 * @eth_mtu: Ethernet MTU
131 * @rsvd4: reserved bytes
127 */132 */
128struct opa_vesw_info {133struct opa_vesw_info {
129 __be16 fabric_id;134 __be16 fabric_id;
@@ -150,12 +155,14 @@ struct opa_vesw_info { · 20 unmodified lines
150 * struct opa_per_veswport_info - OPA vnic per port information155 * struct opa_per_veswport_info - OPA vnic per port information
151 * @port_num: port number156 * @port_num: port number
152 * @eth_link_status: current ethernet link state157 * @eth_link_status: current ethernet link state
158 * @rsvd0: reserved bytes
153 * @base_mac_addr: base mac address159 * @base_mac_addr: base mac address
154 * @config_state: configured port state160 * @config_state: configured port state
155 * @oper_state: operational port state161 * @oper_state: operational port state
156 * @max_mac_tbl_ent: max number of mac table entries162 * @max_mac_tbl_ent: max number of mac table entries
157 * @max_smac_ent: max smac entries in mac table163 * @max_smac_ent: max smac entries in mac table
158 * @mac_tbl_digest: mac table digest164 * @mac_tbl_digest: mac table digest
165 * @rsvd1: reserved bytes
159 * @encap_slid: base slid for the port166 * @encap_slid: base slid for the port
160 * @pcp_to_sc_uc: sc by pcp index for unicast ethernet packets167 * @pcp_to_sc_uc: sc by pcp index for unicast ethernet packets
161 * @pcp_to_vl_uc: vl by pcp index for unicast ethernet packets168 * @pcp_to_vl_uc: vl by pcp index for unicast ethernet packets
@@ -165,8 +172,10 @@ struct opa_vesw_info { · 3 unmodified lines
165 * @non_vlan_vl_uc: vl for non-vlan unicast ethernet packets172 * @non_vlan_vl_uc: vl for non-vlan unicast ethernet packets
166 * @non_vlan_sc_mc: sc for non-vlan multicast ethernet packets173 * @non_vlan_sc_mc: sc for non-vlan multicast ethernet packets
167 * @non_vlan_vl_mc: vl for non-vlan multicast ethernet packets174 * @non_vlan_vl_mc: vl for non-vlan multicast ethernet packets
175 * @rsvd2: reserved bytes
168 * @uc_macs_gen_count: generation count for unicast macs list176 * @uc_macs_gen_count: generation count for unicast macs list
169 * @mc_macs_gen_count: generation count for multicast macs list177 * @mc_macs_gen_count: generation count for multicast macs list
178 * @rsvd3: reserved bytes
170 */179 */
171struct opa_per_veswport_info {180struct opa_per_veswport_info {
172 __be32 port_num;181 __be32 port_num;
@@ -294,6 +303,7 @@ struct opa_veswport_mactable { · 121 unmodified lines
294 * @rx_512_1023: received packet length is >=512 and < 1023 bytes303 * @rx_512_1023: received packet length is >=512 and < 1023 bytes
295 * @rx_1024_1518: received packet length is >=1024 and < 1518 bytes304 * @rx_1024_1518: received packet length is >=1024 and < 1518 bytes
296 * @rx_1519_max: received packet length >= 1519 bytes305 * @rx_1519_max: received packet length >= 1519 bytes
306 * @reserved: reserved bytes
297 *307 *
298 * All the above are counters of corresponding conditions.308 * All the above are counters of corresponding conditions.
299 */309 */
@@ -347,16 +357,26 @@ struct opa_veswport_summary_counters { · 47 unmodified lines
347 * @veswport_num: virtual ethernet switch port number357 * @veswport_num: virtual ethernet switch port number
348 * @tx_errors: transmit errors358 * @tx_errors: transmit errors
349 * @rx_errors: receive errors359 * @rx_errors: receive errors
360 * @rsvd0: reserved bytes
350 * @tx_smac_filt: smac filter errors361 * @tx_smac_filt: smac filter errors
362 * @rsvd1: reserved bytes
363 * @rsvd2: reserved bytes
364 * @rsvd3: reserved bytes
351 * @tx_dlid_zero: transmit packets with invalid dlid365 * @tx_dlid_zero: transmit packets with invalid dlid
366 * @rsvd4: reserved bytes
352 * @tx_logic: other transmit errors367 * @tx_logic: other transmit errors
368 * @rsvd5: reserved bytes
353 * @tx_drop_state: packet tansmission in non-forward port state369 * @tx_drop_state: packet tansmission in non-forward port state
354 * @rx_bad_veswid: received packet with invalid vesw id370 * @rx_bad_veswid: received packet with invalid vesw id
371 * @rsvd6: reserved bytes
355 * @rx_runt: received ethernet packet with length < 64 bytes372 * @rx_runt: received ethernet packet with length < 64 bytes
356 * @rx_oversize: received ethernet packet with length > MTU size373 * @rx_oversize: received ethernet packet with length > MTU size
374 * @rsvd7: reserved bytes
357 * @rx_eth_down: received packets when interface is down375 * @rx_eth_down: received packets when interface is down
358 * @rx_drop_state: received packets in non-forwarding port state376 * @rx_drop_state: received packets in non-forwarding port state
359 * @rx_logic: other receive errors377 * @rx_logic: other receive errors
378 * @rsvd8: reserved bytes
379 * @rsvd9: reserved bytes
360 *380 *
361 * All the above are counters of corresponding error conditions.381 * All the above are counters of corresponding error conditions.
362 */382 */
@@ -447,6 +467,7 @@ struct opa_veswport_iface_macs { · 84 unmodified lines
447 * struct opa_vnic_vema_mad - Generic VEMA MAD467 * struct opa_vnic_vema_mad - Generic VEMA MAD
448 * @mad_hdr: Generic MAD header468 * @mad_hdr: Generic MAD header
449 * @rmpp_hdr: RMPP header for vendor specific MADs469 * @rmpp_hdr: RMPP header for vendor specific MADs
470 * @reserved: reserved bytes
450 * @oui: Unique org identifier471 * @oui: Unique org identifier
451 * @data: MAD data472 * @data: MAD data
452 */473 */
@@ -467,6 +488,7 @@ struct opa_vnic_vema_mad { · 14 unmodified lines
467 * @trap_num: Trap number488 * @trap_num: Trap number
468 * @toggle_count: Notice toggle bit and count value489 * @toggle_count: Notice toggle bit and count value
469 * @issuer_lid: Trap issuer's lid490 * @issuer_lid: Trap issuer's lid
491 * @reserved: reserved bytes
470 * @issuer_gid: Issuer GID (only if Report method)492 * @issuer_gid: Issuer GID (only if Report method)
471 * @raw_data: Trap message body493 * @raw_data: Trap message body
472 */494 */
@@ -487,6 +509,7 @@ struct opa_vnic_notice_attr { · 14 unmodified lines
487 * struct opa_vnic_vema_mad_trap - Generic VEMA MAD Trap509 * struct opa_vnic_vema_mad_trap - Generic VEMA MAD Trap
488 * @mad_hdr: Generic MAD header510 * @mad_hdr: Generic MAD header
489 * @rmpp_hdr: RMPP header for vendor specific MADs511 * @rmpp_hdr: RMPP header for vendor specific MADs
512 * @reserved: reserved bytes
490 * @oui: Unique org identifier513 * @oui: Unique org identifier
491 * @notice: Notice structure514 * @notice: Notice structure
492 */515 */
drivers/infiniband/ulp/rtrs/rtrs-clt.c+13−3
@@ -12,6 +12,7 @@ · 11 unmodified lines
12 12
13#include <linux/module.h>13#include <linux/module.h>
14#include <linux/rculist.h>14#include <linux/rculist.h>
15#include <linux/random.h>
15 16
16#include "rtrs-clt.h"17#include "rtrs-clt.h"
17#include "rtrs-log.h"18#include "rtrs-log.h"
@@ -23,6 +24,12 @@ · 5 unmodified lines
23 * leads to "false positives" failed reconnect attempts24 * leads to "false positives" failed reconnect attempts
24 */25 */
25#define RTRS_RECONNECT_BACKOFF 100026#define RTRS_RECONNECT_BACKOFF 1000
27/*
28 * Wait for additional random time between 0 and 8 seconds
29 * before starting to reconnect to avoid clients reconnecting
30 * all at once in case of a major network outage
31 */
32#define RTRS_RECONNECT_SEED 8
26 33
27MODULE_DESCRIPTION("RDMA Transport Client");34MODULE_DESCRIPTION("RDMA Transport Client");
28MODULE_LICENSE("GPL");35MODULE_LICENSE("GPL");
@@ -306,7 +313,8 @@ static void rtrs_rdma_error_recovery(struct rtrs_clt_con *con) · 277 unmodified lines
306 */313 */
307 delay_ms = clt->reconnect_delay_sec * 1000;314 delay_ms = clt->reconnect_delay_sec * 1000;
308 queue_delayed_work(rtrs_wq, &sess->reconnect_dwork,315 queue_delayed_work(rtrs_wq, &sess->reconnect_dwork,
309 msecs_to_jiffies(delay_ms));316 msecs_to_jiffies(delay_ms +
317 prandom_u32() % RTRS_RECONNECT_SEED));
310 } else {318 } else {
311 /*319 /*
312 * Error can happen just on establishing new connection,320 * Error can happen just on establishing new connection,
@@ -2503,7 +2511,9 @@ reconnect_again: · 2190 unmodified lines
2503 sess->stats->reconnects.fail_cnt++;2511 sess->stats->reconnects.fail_cnt++;
2504 delay_ms = clt->reconnect_delay_sec * 1000;2512 delay_ms = clt->reconnect_delay_sec * 1000;
2505 queue_delayed_work(rtrs_wq, &sess->reconnect_dwork,2513 queue_delayed_work(rtrs_wq, &sess->reconnect_dwork,
2506 msecs_to_jiffies(delay_ms));2514 msecs_to_jiffies(delay_ms +
2515 prandom_u32() %
2516 RTRS_RECONNECT_SEED));
2507 }2517 }
2508}2518}
2509 2519
@@ -2972,7 +2982,7 @@ static int __init rtrs_client_init(void) · 462 unmodified lines
2972 pr_err("Failed to create rtrs-client dev class\n");2982 pr_err("Failed to create rtrs-client dev class\n");
2973 return PTR_ERR(rtrs_clt_dev_class);2983 return PTR_ERR(rtrs_clt_dev_class);
2974 }2984 }
2975 rtrs_wq = alloc_workqueue("rtrs_client_wq", WQ_MEM_RECLAIM, 0);2985 rtrs_wq = alloc_workqueue("rtrs_client_wq", 0, 0);
2976 if (!rtrs_wq) {2986 if (!rtrs_wq) {
2977 class_destroy(rtrs_clt_dev_class);2987 class_destroy(rtrs_clt_dev_class);
2978 return -ENOMEM;2988 return -ENOMEM;
drivers/infiniband/ulp/rtrs/rtrs-srv.c+1−1
@@ -2150,7 +2150,7 @@ static int __init rtrs_server_init(void) · 2149 unmodified lines
2150 err = PTR_ERR(rtrs_dev_class);2150 err = PTR_ERR(rtrs_dev_class);
2151 goto out_chunk_pool;2151 goto out_chunk_pool;
2152 }2152 }
2153 rtrs_wq = alloc_workqueue("rtrs_server_wq", WQ_MEM_RECLAIM, 0);2153 rtrs_wq = alloc_workqueue("rtrs_server_wq", 0, 0);
2154 if (!rtrs_wq) {2154 if (!rtrs_wq) {
2155 err = -ENOMEM;2155 err = -ENOMEM;
2156 goto out_dev_class;2156 goto out_dev_class;
drivers/infiniband/ulp/srpt/ib_srpt.c+9−11
@@ -869,7 +869,7 @@ static int srpt_zerolength_write(struct srpt_rdma_ch *ch) · 868 unmodified lines
869 869
870static void srpt_zerolength_write_done(struct ib_cq *cq, struct ib_wc *wc)870static void srpt_zerolength_write_done(struct ib_cq *cq, struct ib_wc *wc)
871{871{
872 struct srpt_rdma_ch *ch = cq->cq_context;872 struct srpt_rdma_ch *ch = wc->qp->qp_context;
873 873
874 pr_debug("%s-%d wc->status %d\n", ch->sess_name, ch->qp->qp_num,874 pr_debug("%s-%d wc->status %d\n", ch->sess_name, ch->qp->qp_num,
875 wc->status);875 wc->status);
@@ -1322,7 +1322,7 @@ static int srpt_abort_cmd(struct srpt_send_ioctx *ioctx) · 446 unmodified lines
1322 */1322 */
1323static void srpt_rdma_read_done(struct ib_cq *cq, struct ib_wc *wc)1323static void srpt_rdma_read_done(struct ib_cq *cq, struct ib_wc *wc)
1324{1324{
1325 struct srpt_rdma_ch *ch = cq->cq_context;1325 struct srpt_rdma_ch *ch = wc->qp->qp_context;
1326 struct srpt_send_ioctx *ioctx =1326 struct srpt_send_ioctx *ioctx =
1327 container_of(wc->wr_cqe, struct srpt_send_ioctx, rdma_cqe);1327 container_of(wc->wr_cqe, struct srpt_send_ioctx, rdma_cqe);
1328 1328
@@ -1683,7 +1683,7 @@ push: · 354 unmodified lines
1683 1683
1684static void srpt_recv_done(struct ib_cq *cq, struct ib_wc *wc)1684static void srpt_recv_done(struct ib_cq *cq, struct ib_wc *wc)
1685{1685{
1686 struct srpt_rdma_ch *ch = cq->cq_context;1686 struct srpt_rdma_ch *ch = wc->qp->qp_context;
1687 struct srpt_recv_ioctx *ioctx =1687 struct srpt_recv_ioctx *ioctx =
1688 container_of(wc->wr_cqe, struct srpt_recv_ioctx, ioctx.cqe);1688 container_of(wc->wr_cqe, struct srpt_recv_ioctx, ioctx.cqe);
1689 1689
@@ -1744,7 +1744,7 @@ static void srpt_process_wait_list(struct srpt_rdma_ch *ch) · 54 unmodified lines
1744 */1744 */
1745static void srpt_send_done(struct ib_cq *cq, struct ib_wc *wc)1745static void srpt_send_done(struct ib_cq *cq, struct ib_wc *wc)
1746{1746{
1747 struct srpt_rdma_ch *ch = cq->cq_context;1747 struct srpt_rdma_ch *ch = wc->qp->qp_context;
1748 struct srpt_send_ioctx *ioctx =1748 struct srpt_send_ioctx *ioctx =
1749 container_of(wc->wr_cqe, struct srpt_send_ioctx, ioctx.cqe);1749 container_of(wc->wr_cqe, struct srpt_send_ioctx, ioctx.cqe);
1750 enum srpt_command_state state;1750 enum srpt_command_state state;
@@ -1791,7 +1791,7 @@ static int srpt_create_ch_ib(struct srpt_rdma_ch *ch) · 40 unmodified lines
1791 goto out;1791 goto out;
1792 1792
1793retry:1793retry:
1794 ch->cq = ib_alloc_cq_any(sdev->device, ch, ch->rq_size + sq_size,1794 ch->cq = ib_cq_pool_get(sdev->device, ch->rq_size + sq_size, -1,
1795 IB_POLL_WORKQUEUE);1795 IB_POLL_WORKQUEUE);
1796 if (IS_ERR(ch->cq)) {1796 if (IS_ERR(ch->cq)) {
1797 ret = PTR_ERR(ch->cq);1797 ret = PTR_ERR(ch->cq);
@@ -1799,6 +1799,7 @@ retry: · 1 unmodified line
1799 ch->rq_size + sq_size, ret);1799 ch->rq_size + sq_size, ret);
1800 goto out;1800 goto out;
1801 }1801 }
1802 ch->cq_size = ch->rq_size + sq_size;
1802 1803
1803 qp_init->qp_context = (void *)ch;1804 qp_init->qp_context = (void *)ch;
1804 qp_init->event_handler1805 qp_init->event_handler
@@ -1843,7 +1844,7 @@ retry: · 38 unmodified lines
1843 if (retry) {1844 if (retry) {
1844 pr_debug("failed to create queue pair with sq_size = %d (%d) - retrying\n",1845 pr_debug("failed to create queue pair with sq_size = %d (%d) - retrying\n",
1845 sq_size, ret);1846 sq_size, ret);
1846 ib_free_cq(ch->cq);1847 ib_cq_pool_put(ch->cq, ch->cq_size);
1847 sq_size = max(sq_size / 2, MIN_SRPT_SQ_SIZE);1848 sq_size = max(sq_size / 2, MIN_SRPT_SQ_SIZE);
1848 goto retry;1849 goto retry;
1849 } else {1850 } else {
@@ -1869,14 +1870,14 @@ out: · 19 unmodified lines
1869 1870
1870err_destroy_cq:1871err_destroy_cq:
1871 ch->qp = NULL;1872 ch->qp = NULL;
1872 ib_free_cq(ch->cq);1873 ib_cq_pool_put(ch->cq, ch->cq_size);
1873 goto out;1874 goto out;
1874}1875}
1875 1876
1876static void srpt_destroy_ch_ib(struct srpt_rdma_ch *ch)1877static void srpt_destroy_ch_ib(struct srpt_rdma_ch *ch)
1877{1878{
1878 ib_destroy_qp(ch->qp);1879 ib_destroy_qp(ch->qp);
1879 ib_free_cq(ch->cq);1880 ib_cq_pool_put(ch->cq, ch->cq_size);
1880}1881}
1881 1882
1882/**1883/**
@@ -2156,9 +2157,6 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev, · 273 unmodified lines
2156 2157
2157 WARN_ON_ONCE(irqs_disabled());2158 WARN_ON_ONCE(irqs_disabled());
2158 2159
2159 if (WARN_ON(!sdev || !req))
2160 return -EINVAL;
2161
2162 it_iu_len = be32_to_cpu(req->req_it_iu_len);2160 it_iu_len = be32_to_cpu(req->req_it_iu_len);
2163 2161
2164 pr_info("Received SRP_LOGIN_REQ with i_port_id %pI6, t_port_id %pI6 and it_iu_len %d on port %d (guid=%pI6); pkey %#04x\n",2162 pr_info("Received SRP_LOGIN_REQ with i_port_id %pI6, t_port_id %pI6 and it_iu_len %d on port %d (guid=%pI6); pkey %#04x\n",
drivers/infiniband/ulp/srpt/ib_srpt.h+1−0
@@ -300,6 +300,7 @@ struct srpt_rdma_ch { · 299 unmodified lines
300 } rdma_cm;300 } rdma_cm;
301 };301 };
302 struct ib_cq *cq;302 struct ib_cq *cq;
303 u32 cq_size;
303 struct ib_cqe zw_cqe;304 struct ib_cqe zw_cqe;
304 struct rcu_head rcu;305 struct rcu_head rcu;
305 struct kref kref;306 struct kref kref;
drivers/net/ethernet/mellanox/mlx5/core/alloc.c+9−2
@@ -299,11 +299,18 @@ void mlx5_fill_page_array(struct mlx5_frag_buf *buf, __be64 *pas) · 298 unmodified lines
299}299}
300EXPORT_SYMBOL_GPL(mlx5_fill_page_array);300EXPORT_SYMBOL_GPL(mlx5_fill_page_array);
301 301
302void mlx5_fill_page_frag_array(struct mlx5_frag_buf *buf, __be64 *pas)302void mlx5_fill_page_frag_array_perm(struct mlx5_frag_buf *buf, __be64 *pas, u8 perm)
303{303{
304 int i;304 int i;
305 305
306 WARN_ON(perm & 0xfc);
306 for (i = 0; i < buf->npages; i++)307 for (i = 0; i < buf->npages; i++)
307 pas[i] = cpu_to_be64(buf->frags[i].map);308 pas[i] = cpu_to_be64(buf->frags[i].map | perm);
309}
310EXPORT_SYMBOL_GPL(mlx5_fill_page_frag_array_perm);
311
312void mlx5_fill_page_frag_array(struct mlx5_frag_buf *buf, __be64 *pas)
313{
314 mlx5_fill_page_frag_array_perm(buf, pas, 0);
308}315}
309EXPORT_SYMBOL_GPL(mlx5_fill_page_frag_array);316EXPORT_SYMBOL_GPL(mlx5_fill_page_frag_array);
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c+1−0
@@ -1577,6 +1577,7 @@ static struct mlx5_flow_handle *add_rule_fg(struct mlx5_flow_group *fg, · 1576 unmodified lines
1577static bool counter_is_valid(u32 action)1577static bool counter_is_valid(u32 action)
1578{1578{
1579 return (action & (MLX5_FLOW_CONTEXT_ACTION_DROP |1579 return (action & (MLX5_FLOW_CONTEXT_ACTION_DROP |
1580 MLX5_FLOW_CONTEXT_ACTION_ALLOW |
1580 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST));1581 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST));
1581}1582}
1582 1583
drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c+7−0
@@ -226,13 +226,20 @@ void mlx5i_uninit_underlay_qp(struct mlx5e_priv *priv) · 225 unmodified lines
226 226
227int mlx5i_create_underlay_qp(struct mlx5e_priv *priv)227int mlx5i_create_underlay_qp(struct mlx5e_priv *priv)
228{228{
229 unsigned char *dev_addr = priv->netdev->dev_addr;
229 u32 out[MLX5_ST_SZ_DW(create_qp_out)] = {};230 u32 out[MLX5_ST_SZ_DW(create_qp_out)] = {};
230 u32 in[MLX5_ST_SZ_DW(create_qp_in)] = {};231 u32 in[MLX5_ST_SZ_DW(create_qp_in)] = {};
231 struct mlx5i_priv *ipriv = priv->ppriv;232 struct mlx5i_priv *ipriv = priv->ppriv;
232 void *addr_path;233 void *addr_path;
234 int qpn = 0;
233 int ret = 0;235 int ret = 0;
234 void *qpc;236 void *qpc;
235 237
238 if (MLX5_CAP_GEN(priv->mdev, mkey_by_name)) {
239 qpn = (dev_addr[1] << 16) + (dev_addr[2] << 8) + dev_addr[3];
240 MLX5_SET(create_qp_in, in, input_qpn, qpn);
241 }
242
236 qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);243 qpc = MLX5_ADDR_OF(create_qp_in, in, qpc);
237 MLX5_SET(qpc, qpc, st, MLX5_QP_ST_UD);244 MLX5_SET(qpc, qpc, st, MLX5_QP_ST_UD);
238 MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);245 MLX5_SET(qpc, qpc, pm_state, MLX5_QP_PM_MIGRATED);
drivers/net/ethernet/mellanox/mlx5/core/main.c+3−0
@@ -557,6 +557,9 @@ static int handle_hca_cap(struct mlx5_core_dev *dev, void *set_ctx) · 556 unmodified lines
557 if (MLX5_CAP_GEN_MAX(dev, release_all_pages))557 if (MLX5_CAP_GEN_MAX(dev, release_all_pages))
558 MLX5_SET(cmd_hca_cap, set_hca_cap, release_all_pages, 1);558 MLX5_SET(cmd_hca_cap, set_hca_cap, release_all_pages, 1);
559 559
560 if (MLX5_CAP_GEN_MAX(dev, mkey_by_name))
561 MLX5_SET(cmd_hca_cap, set_hca_cap, mkey_by_name, 1);
562
560 return set_caps(dev, set_ctx, MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE);563 return set_caps(dev, set_ctx, MLX5_SET_HCA_CAP_OP_MOD_GENERAL_DEVICE);
561}564}
562 565
include/linux/mlx5/device.h+5−4
@@ -276,7 +276,9 @@ enum { · 275 unmodified lines
276 MLX5_MKEY_MASK_RW = 1ull << 20,276 MLX5_MKEY_MASK_RW = 1ull << 20,
277 MLX5_MKEY_MASK_A = 1ull << 21,277 MLX5_MKEY_MASK_A = 1ull << 21,
278 MLX5_MKEY_MASK_SMALL_FENCE = 1ull << 23,278 MLX5_MKEY_MASK_SMALL_FENCE = 1ull << 23,
279 MLX5_MKEY_MASK_FREE = 1ull << 29,279 MLX5_MKEY_MASK_RELAXED_ORDERING_WRITE = 1ull << 25,
280 MLX5_MKEY_MASK_FREE = 1ull << 29,
281 MLX5_MKEY_MASK_RELAXED_ORDERING_READ = 1ull << 47,
280};282};
281 283
282enum {284enum {
@@ -1007,7 +1009,6 @@ enum { · 724 unmodified lines
1007 MLX5_MKEY_REMOTE_INVAL = 1 << 24,1009 MLX5_MKEY_REMOTE_INVAL = 1 << 24,
1008 MLX5_MKEY_FLAG_SYNC_UMR = 1 << 29,1010 MLX5_MKEY_FLAG_SYNC_UMR = 1 << 29,
1009 MLX5_MKEY_BSF_EN = 1 << 30,1011 MLX5_MKEY_BSF_EN = 1 << 30,
1010 MLX5_MKEY_LEN64 = 1 << 31,
1011};1012};
1012 1013
1013struct mlx5_mkey_seg {1014struct mlx5_mkey_seg {
@@ -1361,11 +1362,11 @@ enum mlx5_qcam_feature_groups { · 347 unmodified lines
1361 MLX5_ADDR_OF(device_event_cap, (mdev)->caps.hca_cur[MLX5_CAP_DEV_EVENT], cap)1362 MLX5_ADDR_OF(device_event_cap, (mdev)->caps.hca_cur[MLX5_CAP_DEV_EVENT], cap)
1362 1363
1363#define MLX5_CAP_DEV_VDPA_EMULATION(mdev, cap)\1364#define MLX5_CAP_DEV_VDPA_EMULATION(mdev, cap)\
1364 MLX5_GET(device_virtio_emulation_cap, \1365 MLX5_GET(virtio_emulation_cap, \
1365 (mdev)->caps.hca_cur[MLX5_CAP_VDPA_EMULATION], cap)1366 (mdev)->caps.hca_cur[MLX5_CAP_VDPA_EMULATION], cap)
1366 1367
1367#define MLX5_CAP64_DEV_VDPA_EMULATION(mdev, cap)\1368#define MLX5_CAP64_DEV_VDPA_EMULATION(mdev, cap)\
1368 MLX5_GET64(device_virtio_emulation_cap, \1369 MLX5_GET64(virtio_emulation_cap, \
1369 (mdev)->caps.hca_cur[MLX5_CAP_VDPA_EMULATION], cap)1370 (mdev)->caps.hca_cur[MLX5_CAP_VDPA_EMULATION], cap)
1370 1371
1371#define MLX5_CAP_IPSEC(mdev, cap)\1372#define MLX5_CAP_IPSEC(mdev, cap)\
include/linux/mlx5/driver.h+2−0
@@ -975,6 +975,7 @@ void mlx5_register_debugfs(void); · 974 unmodified lines
975void mlx5_unregister_debugfs(void);975void mlx5_unregister_debugfs(void);
976 976
977void mlx5_fill_page_array(struct mlx5_frag_buf *buf, __be64 *pas);977void mlx5_fill_page_array(struct mlx5_frag_buf *buf, __be64 *pas);
978void mlx5_fill_page_frag_array_perm(struct mlx5_frag_buf *buf, __be64 *pas, u8 perm);
978void mlx5_fill_page_frag_array(struct mlx5_frag_buf *frag_buf, __be64 *pas);979void mlx5_fill_page_frag_array(struct mlx5_frag_buf *frag_buf, __be64 *pas);
979int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn,980int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn,
980 unsigned int *irqn);981 unsigned int *irqn);
@@ -1057,6 +1058,7 @@ enum { · 76 unmodified lines
1057enum {1058enum {
1058 MLX5_INTERFACE_PROTOCOL_IB = 0,1059 MLX5_INTERFACE_PROTOCOL_IB = 0,
1059 MLX5_INTERFACE_PROTOCOL_ETH = 1,1060 MLX5_INTERFACE_PROTOCOL_ETH = 1,
1061 MLX5_INTERFACE_PROTOCOL_VDPA = 2,
1060};1062};
1061 1063
1062struct mlx5_interface {1064struct mlx5_interface {
include/linux/mlx5/mlx5_ifc.h+113−16
@@ -93,6 +93,7 @@ enum { · 92 unmodified lines
93 93
94enum {94enum {
95 MLX5_OBJ_TYPE_GENEVE_TLV_OPT = 0x000b,95 MLX5_OBJ_TYPE_GENEVE_TLV_OPT = 0x000b,
96 MLX5_OBJ_TYPE_VIRTIO_NET_Q = 0x000d,
96 MLX5_OBJ_TYPE_MKEY = 0xff01,97 MLX5_OBJ_TYPE_MKEY = 0xff01,
97 MLX5_OBJ_TYPE_QP = 0xff02,98 MLX5_OBJ_TYPE_QP = 0xff02,
98 MLX5_OBJ_TYPE_PSV = 0xff03,99 MLX5_OBJ_TYPE_PSV = 0xff03,
@@ -985,17 +986,40 @@ struct mlx5_ifc_device_event_cap_bits { · 886 unmodified lines
985 u8 user_unaffiliated_events[4][0x40];986 u8 user_unaffiliated_events[4][0x40];
986};987};
987 988
988struct mlx5_ifc_device_virtio_emulation_cap_bits {989struct mlx5_ifc_virtio_emulation_cap_bits {
989 u8 reserved_at_0[0x20];990 u8 desc_tunnel_offload_type[0x1];
991 u8 eth_frame_offload_type[0x1];
992 u8 virtio_version_1_0[0x1];
993 u8 device_features_bits_mask[0xd];
994 u8 event_mode[0x8];
995 u8 virtio_queue_type[0x8];
990 996
991 u8 reserved_at_20[0x13];997 u8 max_tunnel_desc[0x10];
998 u8 reserved_at_30[0x3];
992 u8 log_doorbell_stride[0x5];999 u8 log_doorbell_stride[0x5];
993 u8 reserved_at_38[0x3];1000 u8 reserved_at_38[0x3];
994 u8 log_doorbell_bar_size[0x5];1001 u8 log_doorbell_bar_size[0x5];
995 1002
996 u8 doorbell_bar_offset[0x40];1003 u8 doorbell_bar_offset[0x40];
997 1004
998 u8 reserved_at_80[0x780];1005 u8 max_emulated_devices[0x8];
1006 u8 max_num_virtio_queues[0x18];
1007
1008 u8 reserved_at_a0[0x60];
1009
1010 u8 umem_1_buffer_param_a[0x20];
1011
1012 u8 umem_1_buffer_param_b[0x20];
1013
1014 u8 umem_2_buffer_param_a[0x20];
1015
1016 u8 umem_2_buffer_param_b[0x20];
1017
1018 u8 umem_3_buffer_param_a[0x20];
1019
1020 u8 umem_3_buffer_param_b[0x20];
1021
1022 u8 reserved_at_1c0[0x640];
999};1023};
1000 1024
1001enum {1025enum {
@@ -1220,7 +1244,11 @@ struct mlx5_ifc_cmd_hca_cap_bits { · 218 unmodified lines
1220 1244
1221 u8 max_sgl_for_optimized_performance[0x8];1245 u8 max_sgl_for_optimized_performance[0x8];
1222 u8 log_max_cq_sz[0x8];1246 u8 log_max_cq_sz[0x8];
1223 u8 reserved_at_d0[0xb];1247 u8 relaxed_ordering_write_umr[0x1];
1248 u8 relaxed_ordering_read_umr[0x1];
1249 u8 reserved_at_d2[0x7];
1250 u8 virtio_net_device_emualtion_manager[0x1];
1251 u8 virtio_blk_device_emualtion_manager[0x1];
1224 u8 log_max_cq[0x5];1252 u8 log_max_cq[0x5];
1225 1253
1226 u8 log_max_eq_sz[0x8];1254 u8 log_max_eq_sz[0x8];
@@ -1396,7 +1424,10 @@ struct mlx5_ifc_cmd_hca_cap_bits { · 169 unmodified lines
1396 u8 bf[0x1];1424 u8 bf[0x1];
1397 u8 driver_version[0x1];1425 u8 driver_version[0x1];
1398 u8 pad_tx_eth_packet[0x1];1426 u8 pad_tx_eth_packet[0x1];
1399 u8 reserved_at_263[0x8];1427 u8 reserved_at_263[0x3];
1428 u8 mkey_by_name[0x1];
1429 u8 reserved_at_267[0x4];
1430
1400 u8 log_bf_reg_size[0x5];1431 u8 log_bf_reg_size[0x5];
1401 1432
1402 u8 reserved_at_270[0x8];1433 u8 reserved_at_270[0x8];
@@ -2953,7 +2984,7 @@ union mlx5_ifc_hca_cap_union_bits { · 1550 unmodified lines
2953 struct mlx5_ifc_fpga_cap_bits fpga_cap;2984 struct mlx5_ifc_fpga_cap_bits fpga_cap;
2954 struct mlx5_ifc_tls_cap_bits tls_cap;2985 struct mlx5_ifc_tls_cap_bits tls_cap;
2955 struct mlx5_ifc_device_mem_cap_bits device_mem_cap;2986 struct mlx5_ifc_device_mem_cap_bits device_mem_cap;
2956 struct mlx5_ifc_device_virtio_emulation_cap_bits virtio_emulation_cap;2987 struct mlx5_ifc_virtio_emulation_cap_bits virtio_emulation_cap;
2957 u8 reserved_at_0[0x8000];2988 u8 reserved_at_0[0x8000];
2958};2989};
2959 2990
@@ -3302,15 +3333,18 @@ struct mlx5_ifc_scheduling_context_bits { · 342 unmodified lines
3302};3333};
3303 3334
3304struct mlx5_ifc_rqtc_bits {3335struct mlx5_ifc_rqtc_bits {
3305 u8 reserved_at_0[0xa0];3336 u8 reserved_at_0[0xa0];
3306 3337
3307 u8 reserved_at_a0[0x10];3338 u8 reserved_at_a0[0x5];
3308 u8 rqt_max_size[0x10];3339 u8 list_q_type[0x3];
3340 u8 reserved_at_a8[0x8];
3341 u8 rqt_max_size[0x10];
3309 3342
3310 u8 reserved_at_c0[0x10];3343 u8 rq_vhca_id_format[0x1];
3311 u8 rqt_actual_size[0x10];3344 u8 reserved_at_c1[0xf];
3345 u8 rqt_actual_size[0x10];
3312 3346
3313 u8 reserved_at_e0[0x6a0];3347 u8 reserved_at_e0[0x6a0];
3314 3348
3315 struct mlx5_ifc_rq_num_bits rq_num[];3349 struct mlx5_ifc_rq_num_bits rq_num[];
3316};3350};
@@ -7092,7 +7126,7 @@ struct mlx5_ifc_destroy_mkey_out_bits { · 3775 unmodified lines
7092 7126
7093struct mlx5_ifc_destroy_mkey_in_bits {7127struct mlx5_ifc_destroy_mkey_in_bits {
7094 u8 opcode[0x10];7128 u8 opcode[0x10];
7095 u8 reserved_at_10[0x10];7129 u8 uid[0x10];
7096 7130
7097 u8 reserved_at_20[0x10];7131 u8 reserved_at_20[0x10];
7098 u8 op_mod[0x10];7132 u8 op_mod[0x10];
@@ -7723,8 +7757,10 @@ struct mlx5_ifc_create_qp_in_bits { · 624 unmodified lines
7723 u8 reserved_at_20[0x10];7757 u8 reserved_at_20[0x10];
7724 u8 op_mod[0x10];7758 u8 op_mod[0x10];
7725 7759
7726 u8 reserved_at_40[0x40];7760 u8 reserved_at_40[0x8];
7761 u8 input_qpn[0x18];
7727 7762
7763 u8 reserved_at_60[0x20];
7728 u8 opt_param_mask[0x20];7764 u8 opt_param_mask[0x20];
7729 7765
7730 u8 ece[0x20];7766 u8 ece[0x20];
@@ -7788,7 +7824,7 @@ struct mlx5_ifc_create_mkey_out_bits { · 57 unmodified lines
7788 7824
7789struct mlx5_ifc_create_mkey_in_bits {7825struct mlx5_ifc_create_mkey_in_bits {
7790 u8 opcode[0x10];7826 u8 opcode[0x10];
7791 u8 reserved_at_10[0x10];7827 u8 uid[0x10];
7792 7828
7793 u8 reserved_at_20[0x10];7829 u8 reserved_at_20[0x10];
7794 u8 op_mod[0x10];7830 u8 op_mod[0x10];
@@ -10346,6 +10382,40 @@ struct mlx5_ifc_create_umem_in_bits { · 2551 unmodified lines
10346 struct mlx5_ifc_umem_bits umem;10382 struct mlx5_ifc_umem_bits umem;
10347};10383};
10348 10384
10385struct mlx5_ifc_create_umem_out_bits {
10386 u8 status[0x8];
10387 u8 reserved_at_8[0x18];
10388
10389 u8 syndrome[0x20];
10390
10391 u8 reserved_at_40[0x8];
10392 u8 umem_id[0x18];
10393
10394 u8 reserved_at_60[0x20];
10395};
10396
10397struct mlx5_ifc_destroy_umem_in_bits {
10398 u8 opcode[0x10];
10399 u8 uid[0x10];
10400
10401 u8 reserved_at_20[0x10];
10402 u8 op_mod[0x10];
10403
10404 u8 reserved_at_40[0x8];
10405 u8 umem_id[0x18];
10406
10407 u8 reserved_at_60[0x20];
10408};
10409
10410struct mlx5_ifc_destroy_umem_out_bits {
10411 u8 status[0x8];
10412 u8 reserved_at_8[0x18];
10413
10414 u8 syndrome[0x20];
10415
10416 u8 reserved_at_40[0x40];
10417};
10418
10349struct mlx5_ifc_create_uctx_in_bits {10419struct mlx5_ifc_create_uctx_in_bits {
10350 u8 opcode[0x10];10420 u8 opcode[0x10];
10351 u8 reserved_at_10[0x10];10421 u8 reserved_at_10[0x10];
@@ -10358,6 +10428,18 @@ struct mlx5_ifc_create_uctx_in_bits { · 6 unmodified lines
10358 struct mlx5_ifc_uctx_bits uctx;10428 struct mlx5_ifc_uctx_bits uctx;
10359};10429};
10360 10430
10431struct mlx5_ifc_create_uctx_out_bits {
10432 u8 status[0x8];
10433 u8 reserved_at_8[0x18];
10434
10435 u8 syndrome[0x20];
10436
10437 u8 reserved_at_40[0x10];
10438 u8 uid[0x10];
10439
10440 u8 reserved_at_60[0x20];
10441};
10442
10361struct mlx5_ifc_destroy_uctx_in_bits {10443struct mlx5_ifc_destroy_uctx_in_bits {
10362 u8 opcode[0x10];10444 u8 opcode[0x10];
10363 u8 reserved_at_10[0x10];10445 u8 reserved_at_10[0x10];
@@ -10371,6 +10453,15 @@ struct mlx5_ifc_destroy_uctx_in_bits { · 7 unmodified lines
10371 u8 reserved_at_60[0x20];10453 u8 reserved_at_60[0x20];
10372};10454};
10373 10455
10456struct mlx5_ifc_destroy_uctx_out_bits {
10457 u8 status[0x8];
10458 u8 reserved_at_8[0x18];
10459
10460 u8 syndrome[0x20];
10461
10462 u8 reserved_at_40[0x40];
10463};
10464
10374struct mlx5_ifc_create_sw_icm_in_bits {10465struct mlx5_ifc_create_sw_icm_in_bits {
10375 struct mlx5_ifc_general_obj_in_cmd_hdr_bits hdr;10466 struct mlx5_ifc_general_obj_in_cmd_hdr_bits hdr;
10376 struct mlx5_ifc_sw_icm_bits sw_icm;10467 struct mlx5_ifc_sw_icm_bits sw_icm;
@@ -10687,4 +10778,10 @@ struct mlx5_ifc_tls_progress_params_bits { · 310 unmodified lines
10687 u8 hw_offset_record_number[0x18];10778 u8 hw_offset_record_number[0x18];
10688};10779};
10689 10780
10781enum {
10782 MLX5_MTT_PERM_READ = 1 << 0,
10783 MLX5_MTT_PERM_WRITE = 1 << 1,
10784 MLX5_MTT_PERM_RW = MLX5_MTT_PERM_READ | MLX5_MTT_PERM_WRITE,
10785};
10786
10690#endif /* MLX5_IFC_H */10787#endif /* MLX5_IFC_H */
include/rdma/ib.h+2−29
@@ -1,36 +1,9 @@
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
1/*2/*
2 * Copyright (c) 2010 Intel Corporation. All rights reserved.3 * Copyright (c) 2010 Intel Corporation. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */4 */
32 5
33#if !defined(_RDMA_IB_H)6#ifndef _RDMA_IB_H
34#define _RDMA_IB_H7#define _RDMA_IB_H
35 8
36#include <linux/types.h>9#include <linux/types.h>
include/rdma/ib_addr.h+2−29
@@ -1,37 +1,10 @@
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
1/*2/*
2 * Copyright (c) 2005 Voltaire Inc. All rights reserved.3 * Copyright (c) 2005 Voltaire Inc. All rights reserved.
3 * Copyright (c) 2005 Intel Corporation. All rights reserved.4 * Copyright (c) 2005 Intel Corporation. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */5 */
33 6
34#if !defined(IB_ADDR_H)7#ifndef IB_ADDR_H
35#define IB_ADDR_H8#define IB_ADDR_H
36 9
37#include <linux/in.h>10#include <linux/in.h>
include/rdma/ib_cache.h+1−28
@@ -1,35 +1,8 @@
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
1/*2/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved.3 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Intel Corporation. All rights reserved.4 * Copyright (c) 2005 Intel Corporation. All rights reserved.
4 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.5 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
5 *
6 * This software is available to you under a choice of one of two
7 * licenses. You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer.
19 *
20 * - Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 * SOFTWARE.
33 */6 */
34 7
35#ifndef _IB_CACHE_H8#ifndef _IB_CACHE_H
include/rdma/ib_cm.h+1−0
@@ -6,6 +6,7 @@ · 5 unmodified lines
6 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.6 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
7 * Copyright (c) 2019, Mellanox Technologies inc. All rights reserved.7 * Copyright (c) 2019, Mellanox Technologies inc. All rights reserved.
8 */8 */
9
9#ifndef IB_CM_H10#ifndef IB_CM_H
10#define IB_CM_H11#define IB_CM_H
11 12
include/rdma/ib_hdrs.h+1−43
@@ -1,48 +1,6 @@
1/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
1/*2/*
2 * Copyright(c) 2016 - 2018 Intel Corporation.3 * Copyright(c) 2016 - 2018 Intel Corporation.
3 *
4 * This file is provided under a dual BSD/GPLv2 license. When using or
5 * redistributing this file, you may do so under either license.
6 *
7 * GPL LICENSE SUMMARY
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * BSD LICENSE
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions
22 * are met:
23 *
24 * - Redistributions of source code must retain the above copyright
25 * notice, this list of conditions and the following disclaimer.
26 * - Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in
28 * the documentation and/or other materials provided with the
29 * distribution.
30 * - Neither the name of Intel Corporation nor the names of its
31 * contributors may be used to endorse or promote products derived
32 * from this software without specific prior written permission.
33 *
34 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
35 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
36 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
37 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
38 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
39 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
40 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
41 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
42 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
44 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45 *
46 */4 */
47 5
48#ifndef IB_HDRS_H6#ifndef IB_HDRS_H
include/rdma/ib_mad.h+2−29
@@ -1,40 +1,13 @@
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
1/*2/*
2 * Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved.3 * Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved.
3 * Copyright (c) 2004 Infinicon Corporation. All rights reserved.4 * Copyright (c) 2004 Infinicon Corporation. All rights reserved.
4 * Copyright (c) 2004 Intel Corporation. All rights reserved.5 * Copyright (c) 2004 Intel Corporation. All rights reserved.
5 * Copyright (c) 2004 Topspin Corporation. All rights reserved.6 * Copyright (c) 2004 Topspin Corporation. All rights reserved.
6 * Copyright (c) 2004-2006 Voltaire Corporation. All rights reserved.7 * Copyright (c) 2004-2006 Voltaire Corporation. All rights reserved.
7 *
8 * This software is available to you under a choice of one of two
9 * licenses. You may choose to be licensed under the terms of the GNU
10 * General Public License (GPL) Version 2, available from the file
11 * COPYING in the main directory of this source tree, or the
12 * OpenIB.org BSD license below:
13 *
14 * Redistribution and use in source and binary forms, with or
15 * without modification, are permitted provided that the following
16 * conditions are met:
17 *
18 * - Redistributions of source code must retain the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer.
21 *
22 * - Redistributions in binary form must reproduce the above
23 * copyright notice, this list of conditions and the following
24 * disclaimer in the documentation and/or other materials
25 * provided with the distribution.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
31 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
32 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
33 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34 * SOFTWARE.
35 */8 */
36 9
37#if !defined(IB_MAD_H)10#ifndef IB_MAD_H
38#define IB_MAD_H11#define IB_MAD_H
39 12
40#include <linux/list.h>13#include <linux/list.h>
include/rdma/ib_marshall.h+2−29
@@ -1,36 +1,9 @@
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
1/*2/*
2 * Copyright (c) 2005-2006 Intel Corporation. All rights reserved.3 * Copyright (c) 2005-2006 Intel Corporation. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */4 */
32 5
33#if !defined(IB_USER_MARSHALL_H)6#ifndef IB_USER_MARSHALL_H
34#define IB_USER_MARSHALL_H7#define IB_USER_MARSHALL_H
35 8
36#include <rdma/ib_verbs.h>9#include <rdma/ib_verbs.h>
include/rdma/ib_pack.h+1−28
@@ -1,33 +1,6 @@
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
1/*2/*
2 * Copyright (c) 2004 Topspin Corporation. All rights reserved.3 * Copyright (c) 2004 Topspin Corporation. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */4 */
32 5
33#ifndef IB_PACK_H6#ifndef IB_PACK_H
include/rdma/ib_pma.h+2−29
@@ -1,38 +1,11 @@
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
1/*2/*
2 * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation.3 * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation.
3 * All rights reserved.4 * All rights reserved.
4 * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.5 * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
5 *
6 * This software is available to you under a choice of one of two
7 * licenses. You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer.
19 *
20 * - Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 * SOFTWARE.
33 */6 */
34 7
35#if !defined(IB_PMA_H)8#ifndef IB_PMA_H
36#define IB_PMA_H9#define IB_PMA_H
37 10
38#include <rdma/ib_mad.h>11#include <rdma/ib_mad.h>
include/rdma/ib_sa.h+1−28
@@ -1,35 +1,8 @@
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
1/*2/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved.3 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Voltaire, Inc. All rights reserved.4 * Copyright (c) 2005 Voltaire, Inc. All rights reserved.
4 * Copyright (c) 2006 Intel Corporation. All rights reserved.5 * Copyright (c) 2006 Intel Corporation. All rights reserved.
5 *
6 * This software is available to you under a choice of one of two
7 * licenses. You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer.
19 *
20 * - Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 * SOFTWARE.
33 */6 */
34 7
35#ifndef IB_SA_H8#ifndef IB_SA_H
include/rdma/ib_smi.h+2−29
@@ -1,40 +1,13 @@
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
1/*2/*
2 * Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved.3 * Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved.
3 * Copyright (c) 2004 Infinicon Corporation. All rights reserved.4 * Copyright (c) 2004 Infinicon Corporation. All rights reserved.
4 * Copyright (c) 2004 Intel Corporation. All rights reserved.5 * Copyright (c) 2004 Intel Corporation. All rights reserved.
5 * Copyright (c) 2004 Topspin Corporation. All rights reserved.6 * Copyright (c) 2004 Topspin Corporation. All rights reserved.
6 * Copyright (c) 2004 Voltaire Corporation. All rights reserved.7 * Copyright (c) 2004 Voltaire Corporation. All rights reserved.
7 *
8 * This software is available to you under a choice of one of two
9 * licenses. You may choose to be licensed under the terms of the GNU
10 * General Public License (GPL) Version 2, available from the file
11 * COPYING in the main directory of this source tree, or the
12 * OpenIB.org BSD license below:
13 *
14 * Redistribution and use in source and binary forms, with or
15 * without modification, are permitted provided that the following
16 * conditions are met:
17 *
18 * - Redistributions of source code must retain the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer.
21 *
22 * - Redistributions in binary form must reproduce the above
23 * copyright notice, this list of conditions and the following
24 * disclaimer in the documentation and/or other materials
25 * provided with the distribution.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
31 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
32 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
33 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34 * SOFTWARE.
35 */8 */
36 9
37#if !defined(IB_SMI_H)10#ifndef IB_SMI_H
38#define IB_SMI_H11#define IB_SMI_H
39 12
40#include <rdma/ib_mad.h>13#include <rdma/ib_mad.h>
include/rdma/ib_umem.h+1−28
@@ -1,33 +1,6 @@
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
1/*2/*
2 * Copyright (c) 2007 Cisco Systems. All rights reserved.3 * Copyright (c) 2007 Cisco Systems. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */4 */
32 5
33#ifndef IB_UMEM_H6#ifndef IB_UMEM_H
include/rdma/ib_umem_odp.h+1−28
@@ -1,33 +1,6 @@
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
1/*2/*
2 * Copyright (c) 2014 Mellanox Technologies. All rights reserved.3 * Copyright (c) 2014 Mellanox Technologies. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */4 */
32 5
33#ifndef IB_UMEM_ODP_H6#ifndef IB_UMEM_ODP_H
include/rdma/ib_verbs.h+31−69
@@ -1,3 +1,4 @@
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
1/*2/*
2 * Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved.3 * Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved.
3 * Copyright (c) 2004 Infinicon Corporation. All rights reserved.4 * Copyright (c) 2004 Infinicon Corporation. All rights reserved.
@@ -6,37 +7,9 @@ · 2 unmodified lines
6 * Copyright (c) 2004 Voltaire Corporation. All rights reserved.7 * Copyright (c) 2004 Voltaire Corporation. All rights reserved.
7 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.8 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
8 * Copyright (c) 2005, 2006, 2007 Cisco Systems. All rights reserved.9 * Copyright (c) 2005, 2006, 2007 Cisco Systems. All rights reserved.
9 *
10 * This software is available to you under a choice of one of two
11 * licenses. You may choose to be licensed under the terms of the GNU
12 * General Public License (GPL) Version 2, available from the file
13 * COPYING in the main directory of this source tree, or the
14 * OpenIB.org BSD license below:
15 *
16 * Redistribution and use in source and binary forms, with or
17 * without modification, are permitted provided that the following
18 * conditions are met:
19 *
20 * - Redistributions of source code must retain the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer.
23 *
24 * - Redistributions in binary form must reproduce the above
25 * copyright notice, this list of conditions and the following
26 * disclaimer in the documentation and/or other materials
27 * provided with the distribution.
28 *
29 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
33 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
34 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
35 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
36 * SOFTWARE.
37 */10 */
38 11
39#if !defined(IB_VERBS_H)12#ifndef IB_VERBS_H
40#define IB_VERBS_H13#define IB_VERBS_H
41 14
42#include <linux/types.h>15#include <linux/types.h>
@@ -75,6 +48,7 @@ struct ib_umem_odp; · 32 unmodified lines
75struct ib_uqp_object;48struct ib_uqp_object;
76struct ib_usrq_object;49struct ib_usrq_object;
77struct ib_uwq_object;50struct ib_uwq_object;
51struct rdma_cm_id;
78 52
79extern struct workqueue_struct *ib_wq;53extern struct workqueue_struct *ib_wq;
80extern struct workqueue_struct *ib_comp_wq;54extern struct workqueue_struct *ib_comp_wq;
@@ -1566,9 +1540,8 @@ struct ib_xrcd { · 1485 unmodified lines
1566 struct ib_device *device;1540 struct ib_device *device;
1567 atomic_t usecnt; /* count all exposed resources */1541 atomic_t usecnt; /* count all exposed resources */
1568 struct inode *inode;1542 struct inode *inode;
1569 1543 struct rw_semaphore tgt_qps_rwsem;
1570 struct mutex tgt_qp_mutex;1544 struct xarray tgt_qps;
1571 struct list_head tgt_qp_list;
1572};1545};
1573 1546
1574struct ib_ah {1547struct ib_ah {
@@ -2270,6 +2243,7 @@ struct rdma_netdev_alloc_params { · 695 unmodified lines
2270struct ib_odp_counters {2243struct ib_odp_counters {
2271 atomic64_t faults;2244 atomic64_t faults;
2272 atomic64_t invalidations;2245 atomic64_t invalidations;
2246 atomic64_t prefetch;
2273};2247};
2274 2248
2275struct ib_counters {2249struct ib_counters {
@@ -2476,7 +2450,7 @@ struct ib_device_ops { · 200 unmodified lines
2476 struct ib_pd *pd, struct ib_udata *udata);2450 struct ib_pd *pd, struct ib_udata *udata);
2477 int (*dereg_mr)(struct ib_mr *mr, struct ib_udata *udata);2451 int (*dereg_mr)(struct ib_mr *mr, struct ib_udata *udata);
2478 struct ib_mr *(*alloc_mr)(struct ib_pd *pd, enum ib_mr_type mr_type,2452 struct ib_mr *(*alloc_mr)(struct ib_pd *pd, enum ib_mr_type mr_type,
2479 u32 max_num_sg, struct ib_udata *udata);2453 u32 max_num_sg);
2480 struct ib_mr *(*alloc_mr_integrity)(struct ib_pd *pd,2454 struct ib_mr *(*alloc_mr_integrity)(struct ib_pd *pd,
2481 u32 max_num_data_sg,2455 u32 max_num_data_sg,
2482 u32 max_num_meta_sg);2456 u32 max_num_meta_sg);
@@ -2493,9 +2467,8 @@ struct ib_device_ops { · 10 unmodified lines
2493 int (*dealloc_mw)(struct ib_mw *mw);2467 int (*dealloc_mw)(struct ib_mw *mw);
2494 int (*attach_mcast)(struct ib_qp *qp, union ib_gid *gid, u16 lid);2468 int (*attach_mcast)(struct ib_qp *qp, union ib_gid *gid, u16 lid);
2495 int (*detach_mcast)(struct ib_qp *qp, union ib_gid *gid, u16 lid);2469 int (*detach_mcast)(struct ib_qp *qp, union ib_gid *gid, u16 lid);
2496 struct ib_xrcd *(*alloc_xrcd)(struct ib_device *device,2470 int (*alloc_xrcd)(struct ib_xrcd *xrcd, struct ib_udata *udata);
2497 struct ib_udata *udata);2471 void (*dealloc_xrcd)(struct ib_xrcd *xrcd, struct ib_udata *udata);
2498 int (*dealloc_xrcd)(struct ib_xrcd *xrcd, struct ib_udata *udata);
2499 struct ib_flow *(*create_flow)(struct ib_qp *qp,2472 struct ib_flow *(*create_flow)(struct ib_qp *qp,
2500 struct ib_flow_attr *flow_attr,2473 struct ib_flow_attr *flow_attr,
2501 int domain, struct ib_udata *udata);2474 int domain, struct ib_udata *udata);
@@ -2539,9 +2512,9 @@ struct ib_device_ops { · 37 unmodified lines
2539 struct ib_mr *(*reg_dm_mr)(struct ib_pd *pd, struct ib_dm *dm,2512 struct ib_mr *(*reg_dm_mr)(struct ib_pd *pd, struct ib_dm *dm,
2540 struct ib_dm_mr_attr *attr,2513 struct ib_dm_mr_attr *attr,
2541 struct uverbs_attr_bundle *attrs);2514 struct uverbs_attr_bundle *attrs);
2542 struct ib_counters *(*create_counters)(2515 int (*create_counters)(struct ib_counters *counters,
2543 struct ib_device *device, struct uverbs_attr_bundle *attrs);2516 struct uverbs_attr_bundle *attrs);
2544 int (*destroy_counters)(struct ib_counters *counters);2517 void (*destroy_counters)(struct ib_counters *counters);
2545 int (*read_counters)(struct ib_counters *counters,2518 int (*read_counters)(struct ib_counters *counters,
2546 struct ib_counters_read_attr *counters_read_attr,2519 struct ib_counters_read_attr *counters_read_attr,
2547 struct uverbs_attr_bundle *attrs);2520 struct uverbs_attr_bundle *attrs);
@@ -2581,8 +2554,13 @@ struct ib_device_ops { · 33 unmodified lines
2581 /**2554 /**
2582 * Allows rdma drivers to add their own restrack attributes.2555 * Allows rdma drivers to add their own restrack attributes.
2583 */2556 */
2584 int (*fill_res_entry)(struct sk_buff *msg,2557 int (*fill_res_mr_entry)(struct sk_buff *msg, struct ib_mr *ibmr);
2585 struct rdma_restrack_entry *entry);2558 int (*fill_res_mr_entry_raw)(struct sk_buff *msg, struct ib_mr *ibmr);
2559 int (*fill_res_cq_entry)(struct sk_buff *msg, struct ib_cq *ibcq);
2560 int (*fill_res_cq_entry_raw)(struct sk_buff *msg, struct ib_cq *ibcq);
2561 int (*fill_res_qp_entry)(struct sk_buff *msg, struct ib_qp *ibqp);
2562 int (*fill_res_qp_entry_raw)(struct sk_buff *msg, struct ib_qp *ibqp);
2563 int (*fill_res_cm_id_entry)(struct sk_buff *msg, struct rdma_cm_id *id);
2586 2564
2587 /* Device lifecycle callbacks */2565 /* Device lifecycle callbacks */
2588 /*2566 /*
@@ -2637,14 +2615,19 @@ struct ib_device_ops { · 48 unmodified lines
2637 * Allows rdma drivers to add their own restrack attributes2615 * Allows rdma drivers to add their own restrack attributes
2638 * dumped via 'rdma stat' iproute2 command.2616 * dumped via 'rdma stat' iproute2 command.
2639 */2617 */
2640 int (*fill_stat_entry)(struct sk_buff *msg,2618 int (*fill_stat_mr_entry)(struct sk_buff *msg, struct ib_mr *ibmr);
2641 struct rdma_restrack_entry *entry);2619
2620 /* query driver for its ucontext properties */
2621 int (*query_ucontext)(struct ib_ucontext *context,
2622 struct uverbs_attr_bundle *attrs);
2642 2623
2643 DECLARE_RDMA_OBJ_SIZE(ib_ah);2624 DECLARE_RDMA_OBJ_SIZE(ib_ah);
2625 DECLARE_RDMA_OBJ_SIZE(ib_counters);
2644 DECLARE_RDMA_OBJ_SIZE(ib_cq);2626 DECLARE_RDMA_OBJ_SIZE(ib_cq);
2645 DECLARE_RDMA_OBJ_SIZE(ib_pd);2627 DECLARE_RDMA_OBJ_SIZE(ib_pd);
2646 DECLARE_RDMA_OBJ_SIZE(ib_srq);2628 DECLARE_RDMA_OBJ_SIZE(ib_srq);
2647 DECLARE_RDMA_OBJ_SIZE(ib_ucontext);2629 DECLARE_RDMA_OBJ_SIZE(ib_ucontext);
2630 DECLARE_RDMA_OBJ_SIZE(ib_xrcd);
2648};2631};
2649 2632
2650struct ib_core_device {2633struct ib_core_device {
@@ -4263,14 +4246,8 @@ static inline int ib_dereg_mr(struct ib_mr *mr) · 1612 unmodified lines
4263 return ib_dereg_mr_user(mr, NULL);4246 return ib_dereg_mr_user(mr, NULL);
4264}4247}
4265 4248
4266struct ib_mr *ib_alloc_mr_user(struct ib_pd *pd, enum ib_mr_type mr_type,4249struct ib_mr *ib_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type,
4267 u32 max_num_sg, struct ib_udata *udata);4250 u32 max_num_sg);
4268
4269static inline struct ib_mr *ib_alloc_mr(struct ib_pd *pd,
4270 enum ib_mr_type mr_type, u32 max_num_sg)
4271{
4272 return ib_alloc_mr_user(pd, mr_type, max_num_sg, NULL);
4273}
4274 4251
4275struct ib_mr *ib_alloc_mr_integrity(struct ib_pd *pd,4252struct ib_mr *ib_alloc_mr_integrity(struct ib_pd *pd,
4276 u32 max_num_data_sg,4253 u32 max_num_data_sg,
@@ -4321,21 +4298,9 @@ int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid); · 44 unmodified lines
4321 */4298 */
4322int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid);4299int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid);
4323 4300
4324/**4301struct ib_xrcd *ib_alloc_xrcd_user(struct ib_device *device,
4325 * ib_alloc_xrcd - Allocates an XRC domain.4302 struct inode *inode, struct ib_udata *udata);
4326 * @device: The device on which to allocate the XRC domain.4303int ib_dealloc_xrcd_user(struct ib_xrcd *xrcd, struct ib_udata *udata);
4327 * @caller: Module name for kernel consumers
4328 */
4329struct ib_xrcd *__ib_alloc_xrcd(struct ib_device *device, const char *caller);
4330#define ib_alloc_xrcd(device) \
4331 __ib_alloc_xrcd((device), KBUILD_MODNAME)
4332
4333/**
4334 * ib_dealloc_xrcd - Deallocates an XRC domain.
4335 * @xrcd: The XRC domain to deallocate.
4336 * @udata: Valid user data or NULL for kernel object
4337 */
4338int ib_dealloc_xrcd(struct ib_xrcd *xrcd, struct ib_udata *udata);
4339 4304
4340static inline int ib_check_mr_access(int flags)4305static inline int ib_check_mr_access(int flags)
4341{4306{
@@ -4417,9 +4382,6 @@ struct ib_wq *ib_create_wq(struct ib_pd *pd, · 75 unmodified lines
4417int ib_destroy_wq(struct ib_wq *wq, struct ib_udata *udata);4382int ib_destroy_wq(struct ib_wq *wq, struct ib_udata *udata);
4418int ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *attr,4383int ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *attr,
4419 u32 wq_attr_mask);4384 u32 wq_attr_mask);
4420struct ib_rwq_ind_table *ib_create_rwq_ind_table(struct ib_device *device,
4421 struct ib_rwq_ind_table_init_attr*
4422 wq_ind_table_init_attr);
4423int ib_destroy_rwq_ind_table(struct ib_rwq_ind_table *wq_ind_table);4385int ib_destroy_rwq_ind_table(struct ib_rwq_ind_table *wq_ind_table);
4424 4386
4425int ib_map_mr_sg(struct ib_mr *mr, struct scatterlist *sg, int sg_nents,4387int ib_map_mr_sg(struct ib_mr *mr, struct scatterlist *sg, int sg_nents,
include/rdma/iw_cm.h+2−28
@@ -1,35 +1,9 @@
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
1/*2/*
2 * Copyright (c) 2005 Network Appliance, Inc. All rights reserved.3 * Copyright (c) 2005 Network Appliance, Inc. All rights reserved.
3 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.4 * Copyright (c) 2005 Open Grid Computing, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */5 */
6
33#ifndef IW_CM_H7#ifndef IW_CM_H
34#define IW_CM_H8#define IW_CM_H
35 9
include/rdma/iw_portmap.h+2−28
@@ -1,35 +1,9 @@
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
1/*2/*
2 * Copyright (c) 2014 Intel Corporation. All rights reserved.3 * Copyright (c) 2014 Intel Corporation. All rights reserved.
3 * Copyright (c) 2014 Chelsio, Inc. All rights reserved.4 * Copyright (c) 2014 Chelsio, Inc. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */5 */
6
33#ifndef _IW_PORTMAP_H7#ifndef _IW_PORTMAP_H
34#define _IW_PORTMAP_H8#define _IW_PORTMAP_H
35 9
include/rdma/opa_addr.h+1−43
@@ -1,48 +1,6 @@
1/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
1/*2/*
2 * Copyright(c) 2017 Intel Corporation.3 * Copyright(c) 2017 Intel Corporation.
3 *
4 * This file is provided under a dual BSD/GPLv2 license. When using or
5 * redistributing this file, you may do so under either license.
6 *
7 * GPL LICENSE SUMMARY
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * BSD LICENSE
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions
22 * are met:
23 *
24 * - Redistributions of source code must retain the above copyright
25 * notice, this list of conditions and the following disclaimer.
26 * - Redistributions in binary form must reproduce the above copyright
27 * notice, this list of conditions and the following disclaimer in
28 * the documentation and/or other materials provided with the
29 * distribution.
30 * - Neither the name of Intel Corporation nor the names of its
31 * contributors may be used to endorse or promote products derived
32 * from this software without specific prior written permission.
33 *
34 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
35 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
36 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
37 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
38 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
39 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
40 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
41 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
42 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
43 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
44 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45 *
46 */4 */
47 5
48#ifndef OPA_ADDR_H6#ifndef OPA_ADDR_H
include/rdma/opa_port_info.h+2−29
@@ -1,36 +1,9 @@
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
1/*2/*
2 * Copyright (c) 2014-2020 Intel Corporation. All rights reserved.3 * Copyright (c) 2014-2020 Intel Corporation. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */4 */
32 5
33#if !defined(OPA_PORT_INFO_H)6#ifndef OPA_PORT_INFO_H
34#define OPA_PORT_INFO_H7#define OPA_PORT_INFO_H
35 8
36#include <rdma/opa_smi.h>9#include <rdma/opa_smi.h>
include/rdma/opa_smi.h+2−29
@@ -1,36 +1,9 @@
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
1/*2/*
2 * Copyright (c) 2014 Intel Corporation. All rights reserved.3 * Copyright (c) 2014 Intel Corporation. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */4 */
32 5
33#if !defined(OPA_SMI_H)6#ifndef OPA_SMI_H
34#define OPA_SMI_H7#define OPA_SMI_H
35 8
36#include <rdma/ib_mad.h>9#include <rdma/ib_mad.h>
include/rdma/opa_vnic.h+4−45
@@ -1,52 +1,11 @@
1#ifndef _OPA_VNIC_H1/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
2#define _OPA_VNIC_H
3/*2/*
4 * Copyright(c) 2017 - 2020 Intel Corporation.3 * Copyright(c) 2017 - 2020 Intel Corporation.
5 *
6 * This file is provided under a dual BSD/GPLv2 license. When using or
7 * redistributing this file, you may do so under either license.
8 *
9 * GPL LICENSE SUMMARY
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of version 2 of the GNU General Public License as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * BSD LICENSE
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 *
26 * - Redistributions of source code must retain the above copyright
27 * notice, this list of conditions and the following disclaimer.
28 * - Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in
30 * the documentation and/or other materials provided with the
31 * distribution.
32 * - Neither the name of Intel Corporation nor the names of its
33 * contributors may be used to endorse or promote products derived
34 * from this software without specific prior written permission.
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
37 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
38 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
39 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
40 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
43 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
46 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47 *
48 */4 */
49 5
6#ifndef _OPA_VNIC_H
7#define _OPA_VNIC_H
8
50/*9/*
51 * This file contains Intel Omni-Path (OPA) Virtual Network Interface10 * This file contains Intel Omni-Path (OPA) Virtual Network Interface
52 * Controller (VNIC) specific declarations.11 * Controller (VNIC) specific declarations.
include/rdma/rdma_cm.h+2−29
@@ -1,37 +1,10 @@
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
1/*2/*
2 * Copyright (c) 2005 Voltaire Inc. All rights reserved.3 * Copyright (c) 2005 Voltaire Inc. All rights reserved.
3 * Copyright (c) 2005 Intel Corporation. All rights reserved.4 * Copyright (c) 2005 Intel Corporation. All rights reserved.
4 *
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */5 */
33 6
34#if !defined(RDMA_CM_H)7#ifndef RDMA_CM_H
35#define RDMA_CM_H8#define RDMA_CM_H
36 9
37#include <linux/socket.h>10#include <linux/socket.h>
include/rdma/rdma_cm_ib.h+2−29
@@ -1,36 +1,9 @@
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
1/*2/*
2 * Copyright (c) 2006 Intel Corporation. All rights reserved.3 * Copyright (c) 2006 Intel Corporation. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */4 */
32 5
33#if !defined(RDMA_CM_IB_H)6#ifndef RDMA_CM_IB_H
34#define RDMA_CM_IB_H7#define RDMA_CM_IB_H
35 8
36#include <rdma/rdma_cm.h>9#include <rdma/rdma_cm.h>
include/rdma/rdma_netlink.h+1−1
@@ -1,8 +1,8 @@
1/* SPDX-License-Identifier: GPL-2.0 */1/* SPDX-License-Identifier: GPL-2.0 */
2
2#ifndef _RDMA_NETLINK_H3#ifndef _RDMA_NETLINK_H
3#define _RDMA_NETLINK_H4#define _RDMA_NETLINK_H
4 5
5
6#include <linux/netlink.h>6#include <linux/netlink.h>
7#include <uapi/rdma/rdma_netlink.h>7#include <uapi/rdma/rdma_netlink.h>
8 8
include/rdma/rdma_vt.h+4−46
@@ -1,53 +1,11 @@
1#ifndef DEF_RDMA_VT_H1/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
2#define DEF_RDMA_VT_H
3
4/*2/*
5 * Copyright(c) 2016 - 2019 Intel Corporation.3 * Copyright(c) 2016 - 2019 Intel Corporation.
6 *
7 * This file is provided under a dual BSD/GPLv2 license. When using or
8 * redistributing this file, you may do so under either license.
9 *
10 * GPL LICENSE SUMMARY
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of version 2 of the GNU General Public License as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * BSD LICENSE
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 *
27 * - Redistributions of source code must retain the above copyright
28 * notice, this list of conditions and the following disclaimer.

28 more lines aren’t shown here.

include/rdma/rdmavt_cq.h+4−49

This diff is large: its 61 lines aren’t shown here.

include/rdma/rdmavt_mr.h+4−46

This diff is large: its 58 lines aren’t shown here.

include/rdma/rdmavt_qp.h+4−46

This diff is large: its 58 lines aren’t shown here.

include/rdma/uverbs_ioctl.h+2−28

This diff is large: its 43 lines aren’t shown here.

include/rdma/uverbs_named_ioctl.h+1−28

This diff is large: its 35 lines aren’t shown here.

include/rdma/uverbs_std_types.h+15−28

This diff is large: its 56 lines aren’t shown here.

include/rdma/uverbs_types.h+1−28

This diff is large: its 35 lines aren’t shown here.

include/uapi/rdma/efa-abi.h+14−1

This diff is large: its 35 lines aren’t shown here.

include/uapi/rdma/ib_user_ioctl_cmds.h+15−0

This diff is large: its 43 lines aren’t shown here.

include/uapi/rdma/mlx5_user_ioctl_cmds.h+15−1

This diff is large: its 35 lines aren’t shown here.

include/uapi/rdma/qedr-abi.h+7−3

This diff is large: its 37 lines aren’t shown here.

include/uapi/rdma/rdma_netlink.h+9−0

This diff is large: its 29 lines aren’t shown here.

include/uapi/rdma/rdma_user_ioctl.h+1−1

This diff is large: its 9 lines aren’t shown here.