wr.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284
  1. // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
  2. /*
  3. * Copyright (c) 2020, Mellanox Technologies inc. All rights reserved.
  4. */
  5. #include <linux/gfp.h>
  6. #include <linux/mlx5/qp.h>
  7. #include <linux/mlx5/driver.h>
  8. #include "wr.h"
  9. #include "umr.h"
  10. static const u32 mlx5_ib_opcode[] = {
  11. [IB_WR_SEND] = MLX5_OPCODE_SEND,
  12. [IB_WR_LSO] = MLX5_OPCODE_LSO,
  13. [IB_WR_SEND_WITH_IMM] = MLX5_OPCODE_SEND_IMM,
  14. [IB_WR_RDMA_WRITE] = MLX5_OPCODE_RDMA_WRITE,
  15. [IB_WR_RDMA_WRITE_WITH_IMM] = MLX5_OPCODE_RDMA_WRITE_IMM,
  16. [IB_WR_RDMA_READ] = MLX5_OPCODE_RDMA_READ,
  17. [IB_WR_ATOMIC_CMP_AND_SWP] = MLX5_OPCODE_ATOMIC_CS,
  18. [IB_WR_ATOMIC_FETCH_AND_ADD] = MLX5_OPCODE_ATOMIC_FA,
  19. [IB_WR_SEND_WITH_INV] = MLX5_OPCODE_SEND_INVAL,
  20. [IB_WR_LOCAL_INV] = MLX5_OPCODE_UMR,
  21. [IB_WR_REG_MR] = MLX5_OPCODE_UMR,
  22. [IB_WR_MASKED_ATOMIC_CMP_AND_SWP] = MLX5_OPCODE_ATOMIC_MASKED_CS,
  23. [IB_WR_MASKED_ATOMIC_FETCH_AND_ADD] = MLX5_OPCODE_ATOMIC_MASKED_FA,
  24. [MLX5_IB_WR_UMR] = MLX5_OPCODE_UMR,
  25. };
  26. int mlx5r_wq_overflow(struct mlx5_ib_wq *wq, int nreq, struct ib_cq *ib_cq)
  27. {
  28. struct mlx5_ib_cq *cq;
  29. unsigned int cur;
  30. cur = wq->head - wq->tail;
  31. if (likely(cur + nreq < wq->max_post))
  32. return 0;
  33. cq = to_mcq(ib_cq);
  34. spin_lock(&cq->lock);
  35. cur = wq->head - wq->tail;
  36. spin_unlock(&cq->lock);
  37. return cur + nreq >= wq->max_post;
  38. }
  39. static __always_inline void set_raddr_seg(struct mlx5_wqe_raddr_seg *rseg,
  40. u64 remote_addr, u32 rkey)
  41. {
  42. rseg->raddr = cpu_to_be64(remote_addr);
  43. rseg->rkey = cpu_to_be32(rkey);
  44. rseg->reserved = 0;
  45. }
  46. static void set_eth_seg(const struct ib_send_wr *wr, struct mlx5_ib_qp *qp,
  47. void **seg, int *size, void **cur_edge)
  48. {
  49. struct mlx5_wqe_eth_seg *eseg = *seg;
  50. memset(eseg, 0, sizeof(struct mlx5_wqe_eth_seg));
  51. if (wr->send_flags & IB_SEND_IP_CSUM)
  52. eseg->cs_flags = MLX5_ETH_WQE_L3_CSUM |
  53. MLX5_ETH_WQE_L4_CSUM;
  54. if (wr->opcode == IB_WR_LSO) {
  55. struct ib_ud_wr *ud_wr = container_of(wr, struct ib_ud_wr, wr);
  56. size_t left, copysz;
  57. void *pdata = ud_wr->header;
  58. size_t stride;
  59. left = ud_wr->hlen;
  60. eseg->mss = cpu_to_be16(ud_wr->mss);
  61. eseg->inline_hdr.sz = cpu_to_be16(left);
  62. /* mlx5r_memcpy_send_wqe should get a 16B align address. Hence,
  63. * we first copy up to the current edge and then, if needed,
  64. * continue to mlx5r_memcpy_send_wqe.
  65. */
  66. copysz = min_t(u64, *cur_edge - (void *)eseg->inline_hdr.start,
  67. left);
  68. memcpy(eseg->inline_hdr.start, pdata, copysz);
  69. stride = ALIGN(sizeof(struct mlx5_wqe_eth_seg) -
  70. sizeof(eseg->inline_hdr.start) + copysz, 16);
  71. *size += stride / 16;
  72. *seg += stride;
  73. if (copysz < left) {
  74. handle_post_send_edge(&qp->sq, seg, *size, cur_edge);
  75. left -= copysz;
  76. pdata += copysz;
  77. mlx5r_memcpy_send_wqe(&qp->sq, cur_edge, seg, size,
  78. pdata, left);
  79. }
  80. return;
  81. }
  82. *seg += sizeof(struct mlx5_wqe_eth_seg);
  83. *size += sizeof(struct mlx5_wqe_eth_seg) / 16;
  84. }
  85. static void set_datagram_seg(struct mlx5_wqe_datagram_seg *dseg,
  86. const struct ib_send_wr *wr)
  87. {
  88. memcpy(&dseg->av, &to_mah(ud_wr(wr)->ah)->av, sizeof(struct mlx5_av));
  89. dseg->av.dqp_dct =
  90. cpu_to_be32(ud_wr(wr)->remote_qpn | MLX5_EXTENDED_UD_AV);
  91. dseg->av.key.qkey.qkey = cpu_to_be32(ud_wr(wr)->remote_qkey);
  92. }
  93. static void set_data_ptr_seg(struct mlx5_wqe_data_seg *dseg, struct ib_sge *sg)
  94. {
  95. dseg->byte_count = cpu_to_be32(sg->length);
  96. dseg->lkey = cpu_to_be32(sg->lkey);
  97. dseg->addr = cpu_to_be64(sg->addr);
  98. }
  99. static __be64 frwr_mkey_mask(bool atomic)
  100. {
  101. u64 result;
  102. result = MLX5_MKEY_MASK_LEN |
  103. MLX5_MKEY_MASK_PAGE_SIZE |
  104. MLX5_MKEY_MASK_START_ADDR |
  105. MLX5_MKEY_MASK_EN_RINVAL |
  106. MLX5_MKEY_MASK_KEY |
  107. MLX5_MKEY_MASK_LR |
  108. MLX5_MKEY_MASK_LW |
  109. MLX5_MKEY_MASK_RR |
  110. MLX5_MKEY_MASK_RW |
  111. MLX5_MKEY_MASK_SMALL_FENCE |
  112. MLX5_MKEY_MASK_FREE;
  113. if (atomic)
  114. result |= MLX5_MKEY_MASK_A;
  115. return cpu_to_be64(result);
  116. }
  117. static __be64 sig_mkey_mask(void)
  118. {
  119. u64 result;
  120. result = MLX5_MKEY_MASK_LEN |
  121. MLX5_MKEY_MASK_PAGE_SIZE |
  122. MLX5_MKEY_MASK_START_ADDR |
  123. MLX5_MKEY_MASK_EN_SIGERR |
  124. MLX5_MKEY_MASK_EN_RINVAL |
  125. MLX5_MKEY_MASK_KEY |
  126. MLX5_MKEY_MASK_LR |
  127. MLX5_MKEY_MASK_LW |
  128. MLX5_MKEY_MASK_RR |
  129. MLX5_MKEY_MASK_RW |
  130. MLX5_MKEY_MASK_SMALL_FENCE |
  131. MLX5_MKEY_MASK_FREE |
  132. MLX5_MKEY_MASK_BSF_EN;
  133. return cpu_to_be64(result);
  134. }
  135. static void set_reg_umr_seg(struct mlx5_wqe_umr_ctrl_seg *umr,
  136. struct mlx5_ib_mr *mr, u8 flags, bool atomic)
  137. {
  138. int size = (mr->mmkey.ndescs + mr->meta_ndescs) * mr->desc_size;
  139. memset(umr, 0, sizeof(*umr));
  140. umr->flags = flags;
  141. umr->xlt_octowords = cpu_to_be16(mlx5r_umr_get_xlt_octo(size));
  142. umr->mkey_mask = frwr_mkey_mask(atomic);
  143. }
  144. static void set_linv_umr_seg(struct mlx5_wqe_umr_ctrl_seg *umr)
  145. {
  146. memset(umr, 0, sizeof(*umr));
  147. umr->mkey_mask = cpu_to_be64(MLX5_MKEY_MASK_FREE);
  148. umr->flags = MLX5_UMR_INLINE;
  149. }
  150. static u8 get_umr_flags(int acc)
  151. {
  152. return (acc & IB_ACCESS_REMOTE_ATOMIC ? MLX5_PERM_ATOMIC : 0) |
  153. (acc & IB_ACCESS_REMOTE_WRITE ? MLX5_PERM_REMOTE_WRITE : 0) |
  154. (acc & IB_ACCESS_REMOTE_READ ? MLX5_PERM_REMOTE_READ : 0) |
  155. (acc & IB_ACCESS_LOCAL_WRITE ? MLX5_PERM_LOCAL_WRITE : 0) |
  156. MLX5_PERM_LOCAL_READ | MLX5_PERM_UMR_EN;
  157. }
  158. static void set_reg_mkey_seg(struct mlx5_mkey_seg *seg,
  159. struct mlx5_ib_mr *mr,
  160. u32 key, int access)
  161. {
  162. int ndescs = ALIGN(mr->mmkey.ndescs + mr->meta_ndescs, 8) >> 1;
  163. memset(seg, 0, sizeof(*seg));
  164. if (mr->access_mode == MLX5_MKC_ACCESS_MODE_MTT)
  165. seg->log2_page_size = ilog2(mr->ibmr.page_size);
  166. else if (mr->access_mode == MLX5_MKC_ACCESS_MODE_KLMS)
  167. /* KLMs take twice the size of MTTs */
  168. ndescs *= 2;
  169. seg->flags = get_umr_flags(access) | mr->access_mode;
  170. seg->qpn_mkey7_0 = cpu_to_be32((key & 0xff) | 0xffffff00);
  171. seg->flags_pd = cpu_to_be32(MLX5_MKEY_REMOTE_INVAL);
  172. seg->start_addr = cpu_to_be64(mr->ibmr.iova);
  173. seg->len = cpu_to_be64(mr->ibmr.length);
  174. seg->xlt_oct_size = cpu_to_be32(ndescs);
  175. }
  176. static void set_linv_mkey_seg(struct mlx5_mkey_seg *seg)
  177. {
  178. memset(seg, 0, sizeof(*seg));
  179. seg->status = MLX5_MKEY_STATUS_FREE;
  180. }
  181. static void set_reg_data_seg(struct mlx5_wqe_data_seg *dseg,
  182. struct mlx5_ib_mr *mr,
  183. struct mlx5_ib_pd *pd)
  184. {
  185. int bcount = mr->desc_size * (mr->mmkey.ndescs + mr->meta_ndescs);
  186. dseg->addr = cpu_to_be64(mr->desc_map);
  187. dseg->byte_count = cpu_to_be32(ALIGN(bcount, 64));
  188. dseg->lkey = cpu_to_be32(pd->ibpd.local_dma_lkey);
  189. }
  190. static __be32 send_ieth(const struct ib_send_wr *wr)
  191. {
  192. switch (wr->opcode) {
  193. case IB_WR_SEND_WITH_IMM:
  194. case IB_WR_RDMA_WRITE_WITH_IMM:
  195. return wr->ex.imm_data;
  196. case IB_WR_SEND_WITH_INV:
  197. return cpu_to_be32(wr->ex.invalidate_rkey);
  198. default:
  199. return 0;
  200. }
  201. }
  202. static u8 calc_sig(void *wqe, int size)
  203. {
  204. u8 *p = wqe;
  205. u8 res = 0;
  206. int i;
  207. for (i = 0; i < size; i++)
  208. res ^= p[i];
  209. return ~res;
  210. }
  211. static u8 wq_sig(void *wqe)
  212. {
  213. return calc_sig(wqe, (*((u8 *)wqe + 8) & 0x3f) << 4);
  214. }
  215. static int set_data_inl_seg(struct mlx5_ib_qp *qp, const struct ib_send_wr *wr,
  216. void **wqe, int *wqe_sz, void **cur_edge)
  217. {
  218. struct mlx5_wqe_inline_seg *seg;
  219. size_t offset;
  220. int inl = 0;
  221. int i;
  222. seg = *wqe;
  223. *wqe += sizeof(*seg);
  224. offset = sizeof(*seg);
  225. for (i = 0; i < wr->num_sge; i++) {
  226. size_t len = wr->sg_list[i].length;
  227. void *addr = (void *)(unsigned long)(wr->sg_list[i].addr);
  228. inl += len;
  229. if (unlikely(inl > qp->max_inline_data))
  230. return -ENOMEM;
  231. while (likely(len)) {
  232. size_t leftlen;
  233. size_t copysz;
  234. handle_post_send_edge(&qp->sq, wqe,
  235. *wqe_sz + (offset >> 4),
  236. cur_edge);
  237. leftlen = *cur_edge - *wqe;
  238. copysz = min_t(size_t, leftlen, len);
  239. memcpy(*wqe, addr, copysz);
  240. len -= copysz;
  241. addr += copysz;
  242. *wqe += copysz;
  243. offset += copysz;
  244. }
  245. }
  246. seg->byte_count = cpu_to_be32(inl | MLX5_INLINE_SEG);
  247. *wqe_sz += ALIGN(inl + sizeof(seg->byte_count), 16) / 16;
  248. return 0;
  249. }
  250. static u16 prot_field_size(enum ib_signature_type type)
  251. {
  252. switch (type) {
  253. case IB_SIG_TYPE_T10_DIF:
  254. return MLX5_DIF_SIZE;
  255. default:
  256. return 0;
  257. }
  258. }
  259. static u8 bs_selector(int block_size)
  260. {
  261. switch (block_size) {
  262. case 512: return 0x1;
  263. case 520: return 0x2;
  264. case 4096: return 0x3;
  265. case 4160: return 0x4;
  266. case 1073741824: return 0x5;
  267. default: return 0;
  268. }
  269. }
  270. static void mlx5_fill_inl_bsf(struct ib_sig_domain *domain,
  271. struct mlx5_bsf_inl *inl)
  272. {
  273. /* Valid inline section and allow BSF refresh */
  274. inl->vld_refresh = cpu_to_be16(MLX5_BSF_INL_VALID |
  275. MLX5_BSF_REFRESH_DIF);
  276. inl->dif_apptag = cpu_to_be16(domain->sig.dif.app_tag);
  277. inl->dif_reftag = cpu_to_be32(domain->sig.dif.ref_tag);
  278. /* repeating block */
  279. inl->rp_inv_seed = MLX5_BSF_REPEAT_BLOCK;
  280. inl->sig_type = domain->sig.dif.bg_type == IB_T10DIF_CRC ?
  281. MLX5_DIF_CRC : MLX5_DIF_IPCS;
  282. if (domain->sig.dif.ref_remap)
  283. inl->dif_inc_ref_guard_check |= MLX5_BSF_INC_REFTAG;
  284. if (domain->sig.dif.app_escape) {
  285. if (domain->sig.dif.ref_escape)
  286. inl->dif_inc_ref_guard_check |= MLX5_BSF_APPREF_ESCAPE;
  287. else
  288. inl->dif_inc_ref_guard_check |= MLX5_BSF_APPTAG_ESCAPE;
  289. }
  290. inl->dif_app_bitmask_check =
  291. cpu_to_be16(domain->sig.dif.apptag_check_mask);
  292. }
  293. static int mlx5_set_bsf(struct ib_mr *sig_mr,
  294. struct ib_sig_attrs *sig_attrs,
  295. struct mlx5_bsf *bsf, u32 data_size)
  296. {
  297. struct mlx5_core_sig_ctx *msig = to_mmr(sig_mr)->sig;
  298. struct mlx5_bsf_basic *basic = &bsf->basic;
  299. struct ib_sig_domain *mem = &sig_attrs->mem;
  300. struct ib_sig_domain *wire = &sig_attrs->wire;
  301. memset(bsf, 0, sizeof(*bsf));
  302. /* Basic + Extended + Inline */
  303. basic->bsf_size_sbs = 1 << 7;
  304. /* Input domain check byte mask */
  305. basic->check_byte_mask = sig_attrs->check_mask;
  306. basic->raw_data_size = cpu_to_be32(data_size);
  307. /* Memory domain */
  308. switch (sig_attrs->mem.sig_type) {
  309. case IB_SIG_TYPE_NONE:
  310. break;
  311. case IB_SIG_TYPE_T10_DIF:
  312. basic->mem.bs_selector = bs_selector(mem->sig.dif.pi_interval);
  313. basic->m_bfs_psv = cpu_to_be32(msig->psv_memory.psv_idx);
  314. mlx5_fill_inl_bsf(mem, &bsf->m_inl);
  315. break;
  316. default:
  317. return -EINVAL;
  318. }
  319. /* Wire domain */
  320. switch (sig_attrs->wire.sig_type) {
  321. case IB_SIG_TYPE_NONE:
  322. break;
  323. case IB_SIG_TYPE_T10_DIF:
  324. if (mem->sig.dif.pi_interval == wire->sig.dif.pi_interval &&
  325. mem->sig_type == wire->sig_type) {
  326. /* Same block structure */
  327. basic->bsf_size_sbs |= 1 << 4;
  328. if (mem->sig.dif.bg_type == wire->sig.dif.bg_type)
  329. basic->wire.copy_byte_mask |= MLX5_CPY_GRD_MASK;
  330. if (mem->sig.dif.app_tag == wire->sig.dif.app_tag)
  331. basic->wire.copy_byte_mask |= MLX5_CPY_APP_MASK;
  332. if (mem->sig.dif.ref_tag == wire->sig.dif.ref_tag)
  333. basic->wire.copy_byte_mask |= MLX5_CPY_REF_MASK;
  334. } else
  335. basic->wire.bs_selector =
  336. bs_selector(wire->sig.dif.pi_interval);
  337. basic->w_bfs_psv = cpu_to_be32(msig->psv_wire.psv_idx);
  338. mlx5_fill_inl_bsf(wire, &bsf->w_inl);
  339. break;
  340. default:
  341. return -EINVAL;
  342. }
  343. return 0;
  344. }
  345. static int set_sig_data_segment(const struct ib_send_wr *send_wr,
  346. struct ib_mr *sig_mr,
  347. struct ib_sig_attrs *sig_attrs,
  348. struct mlx5_ib_qp *qp, void **seg, int *size,
  349. void **cur_edge)
  350. {
  351. struct mlx5_bsf *bsf;
  352. u32 data_len;
  353. u32 data_key;
  354. u64 data_va;
  355. u32 prot_len = 0;
  356. u32 prot_key = 0;
  357. u64 prot_va = 0;
  358. bool prot = false;
  359. int ret;
  360. int wqe_size;
  361. struct mlx5_ib_mr *mr = to_mmr(sig_mr);
  362. struct mlx5_ib_mr *pi_mr = mr->pi_mr;
  363. data_len = pi_mr->data_length;
  364. data_key = pi_mr->ibmr.lkey;
  365. data_va = pi_mr->data_iova;
  366. if (pi_mr->meta_ndescs) {
  367. prot_len = pi_mr->meta_length;
  368. prot_key = pi_mr->ibmr.lkey;
  369. prot_va = pi_mr->pi_iova;
  370. prot = true;
  371. }
  372. if (!prot || (data_key == prot_key && data_va == prot_va &&
  373. data_len == prot_len)) {
  374. /**
  375. * Source domain doesn't contain signature information
  376. * or data and protection are interleaved in memory.
  377. * So need construct:
  378. * ------------------
  379. * | data_klm |
  380. * ------------------
  381. * | BSF |
  382. * ------------------
  383. **/
  384. struct mlx5_klm *data_klm = *seg;
  385. data_klm->bcount = cpu_to_be32(data_len);
  386. data_klm->key = cpu_to_be32(data_key);
  387. data_klm->va = cpu_to_be64(data_va);
  388. wqe_size = ALIGN(sizeof(*data_klm), 64);
  389. } else {
  390. /**
  391. * Source domain contains signature information
  392. * So need construct a strided block format:
  393. * ---------------------------
  394. * | stride_block_ctrl |
  395. * ---------------------------
  396. * | data_klm |
  397. * ---------------------------
  398. * | prot_klm |
  399. * ---------------------------
  400. * | BSF |
  401. * ---------------------------
  402. **/
  403. struct mlx5_stride_block_ctrl_seg *sblock_ctrl;
  404. struct mlx5_stride_block_entry *data_sentry;
  405. struct mlx5_stride_block_entry *prot_sentry;
  406. u16 block_size = sig_attrs->mem.sig.dif.pi_interval;
  407. int prot_size;
  408. sblock_ctrl = *seg;
  409. data_sentry = (void *)sblock_ctrl + sizeof(*sblock_ctrl);
  410. prot_sentry = (void *)data_sentry + sizeof(*data_sentry);
  411. prot_size = prot_field_size(sig_attrs->mem.sig_type);
  412. if (!prot_size) {
  413. pr_err("Bad block size given: %u\n", block_size);
  414. return -EINVAL;
  415. }
  416. sblock_ctrl->bcount_per_cycle = cpu_to_be32(block_size +
  417. prot_size);
  418. sblock_ctrl->op = cpu_to_be32(MLX5_STRIDE_BLOCK_OP);
  419. sblock_ctrl->repeat_count = cpu_to_be32(data_len / block_size);
  420. sblock_ctrl->num_entries = cpu_to_be16(2);
  421. data_sentry->bcount = cpu_to_be16(block_size);
  422. data_sentry->key = cpu_to_be32(data_key);
  423. data_sentry->va = cpu_to_be64(data_va);
  424. data_sentry->stride = cpu_to_be16(block_size);
  425. prot_sentry->bcount = cpu_to_be16(prot_size);
  426. prot_sentry->key = cpu_to_be32(prot_key);
  427. prot_sentry->va = cpu_to_be64(prot_va);
  428. prot_sentry->stride = cpu_to_be16(prot_size);
  429. wqe_size = ALIGN(sizeof(*sblock_ctrl) + sizeof(*data_sentry) +
  430. sizeof(*prot_sentry), 64);
  431. }
  432. *seg += wqe_size;
  433. *size += wqe_size / 16;
  434. handle_post_send_edge(&qp->sq, seg, *size, cur_edge);
  435. bsf = *seg;
  436. ret = mlx5_set_bsf(sig_mr, sig_attrs, bsf, data_len);
  437. if (ret)
  438. return -EINVAL;
  439. *seg += sizeof(*bsf);
  440. *size += sizeof(*bsf) / 16;
  441. handle_post_send_edge(&qp->sq, seg, *size, cur_edge);
  442. return 0;
  443. }
  444. static void set_sig_mkey_segment(struct mlx5_mkey_seg *seg,
  445. struct ib_mr *sig_mr, int access_flags,
  446. u32 size, u32 length, u32 pdn)
  447. {
  448. u32 sig_key = sig_mr->rkey;
  449. u8 sigerr = to_mmr(sig_mr)->sig->sigerr_count & 1;
  450. memset(seg, 0, sizeof(*seg));
  451. seg->flags = get_umr_flags(access_flags) | MLX5_MKC_ACCESS_MODE_KLMS;
  452. seg->qpn_mkey7_0 = cpu_to_be32((sig_key & 0xff) | 0xffffff00);
  453. seg->flags_pd = cpu_to_be32(MLX5_MKEY_REMOTE_INVAL | sigerr << 26 |
  454. MLX5_MKEY_BSF_EN | pdn);
  455. seg->len = cpu_to_be64(length);
  456. seg->xlt_oct_size = cpu_to_be32(mlx5r_umr_get_xlt_octo(size));
  457. seg->bsfs_octo_size = cpu_to_be32(MLX5_MKEY_BSF_OCTO_SIZE);
  458. }
  459. static void set_sig_umr_segment(struct mlx5_wqe_umr_ctrl_seg *umr,
  460. u32 size)
  461. {
  462. memset(umr, 0, sizeof(*umr));
  463. umr->flags = MLX5_FLAGS_INLINE | MLX5_FLAGS_CHECK_FREE;
  464. umr->xlt_octowords = cpu_to_be16(mlx5r_umr_get_xlt_octo(size));
  465. umr->bsf_octowords = cpu_to_be16(MLX5_MKEY_BSF_OCTO_SIZE);
  466. umr->mkey_mask = sig_mkey_mask();
  467. }
  468. static int set_pi_umr_wr(const struct ib_send_wr *send_wr,
  469. struct mlx5_ib_qp *qp, void **seg, int *size,
  470. void **cur_edge)
  471. {
  472. const struct ib_reg_wr *wr = reg_wr(send_wr);
  473. struct mlx5_ib_mr *sig_mr = to_mmr(wr->mr);
  474. struct mlx5_ib_mr *pi_mr = sig_mr->pi_mr;
  475. struct ib_sig_attrs *sig_attrs = sig_mr->ibmr.sig_attrs;
  476. u32 pdn = to_mpd(qp->ibqp.pd)->pdn;
  477. u32 xlt_size;
  478. int region_len, ret;
  479. if (unlikely(send_wr->num_sge != 0) ||
  480. unlikely(wr->access & IB_ACCESS_REMOTE_ATOMIC) ||
  481. unlikely(!sig_mr->sig) || unlikely(!qp->ibqp.integrity_en) ||
  482. unlikely(!sig_mr->sig->sig_status_checked))
  483. return -EINVAL;
  484. /* length of the protected region, data + protection */
  485. region_len = pi_mr->ibmr.length;
  486. /**
  487. * KLM octoword size - if protection was provided
  488. * then we use strided block format (3 octowords),
  489. * else we use single KLM (1 octoword)
  490. **/
  491. if (sig_attrs->mem.sig_type != IB_SIG_TYPE_NONE)
  492. xlt_size = 0x30;
  493. else
  494. xlt_size = sizeof(struct mlx5_klm);
  495. set_sig_umr_segment(*seg, xlt_size);
  496. *seg += sizeof(struct mlx5_wqe_umr_ctrl_seg);
  497. *size += sizeof(struct mlx5_wqe_umr_ctrl_seg) / 16;
  498. handle_post_send_edge(&qp->sq, seg, *size, cur_edge);
  499. set_sig_mkey_segment(*seg, wr->mr, wr->access, xlt_size, region_len,
  500. pdn);
  501. *seg += sizeof(struct mlx5_mkey_seg);
  502. *size += sizeof(struct mlx5_mkey_seg) / 16;
  503. handle_post_send_edge(&qp->sq, seg, *size, cur_edge);
  504. ret = set_sig_data_segment(send_wr, wr->mr, sig_attrs, qp, seg, size,
  505. cur_edge);
  506. if (ret)
  507. return ret;
  508. sig_mr->sig->sig_status_checked = false;
  509. return 0;
  510. }
  511. static int set_psv_wr(struct ib_sig_domain *domain,
  512. u32 psv_idx, void **seg, int *size)
  513. {
  514. struct mlx5_seg_set_psv *psv_seg = *seg;
  515. memset(psv_seg, 0, sizeof(*psv_seg));
  516. psv_seg->psv_num = cpu_to_be32(psv_idx);
  517. switch (domain->sig_type) {
  518. case IB_SIG_TYPE_NONE:
  519. break;
  520. case IB_SIG_TYPE_T10_DIF:
  521. psv_seg->transient_sig = cpu_to_be32(domain->sig.dif.bg << 16 |
  522. domain->sig.dif.app_tag);
  523. psv_seg->ref_tag = cpu_to_be32(domain->sig.dif.ref_tag);
  524. break;
  525. default:
  526. pr_err("Bad signature type (%d) is given.\n",
  527. domain->sig_type);
  528. return -EINVAL;
  529. }
  530. *seg += sizeof(*psv_seg);
  531. *size += sizeof(*psv_seg) / 16;
  532. return 0;
  533. }
  534. static int set_reg_wr(struct mlx5_ib_qp *qp,
  535. const struct ib_reg_wr *wr,
  536. void **seg, int *size, void **cur_edge,
  537. bool check_not_free)
  538. {
  539. struct mlx5_ib_mr *mr = to_mmr(wr->mr);
  540. struct mlx5_ib_pd *pd = to_mpd(qp->ibqp.pd);
  541. struct mlx5_ib_dev *dev = to_mdev(pd->ibpd.device);
  542. int mr_list_size = (mr->mmkey.ndescs + mr->meta_ndescs) * mr->desc_size;
  543. bool umr_inline = mr_list_size <= MLX5_IB_SQ_UMR_INLINE_THRESHOLD;
  544. bool atomic = wr->access & IB_ACCESS_REMOTE_ATOMIC;
  545. u8 flags = 0;
  546. /* Matches access in mlx5_set_umr_free_mkey().
  547. * Relaxed Ordering is set implicitly in mlx5_set_umr_free_mkey() and
  548. * kernel ULPs are not aware of it, so we don't set it here.
  549. */
  550. if (!mlx5r_umr_can_reconfig(dev, 0, wr->access)) {
  551. mlx5_ib_warn(
  552. to_mdev(qp->ibqp.device),
  553. "Fast update for MR access flags is not possible\n");
  554. return -EINVAL;
  555. }
  556. if (unlikely(wr->wr.send_flags & IB_SEND_INLINE)) {
  557. mlx5_ib_warn(to_mdev(qp->ibqp.device),
  558. "Invalid IB_SEND_INLINE send flag\n");
  559. return -EINVAL;
  560. }
  561. if (check_not_free)
  562. flags |= MLX5_UMR_CHECK_NOT_FREE;
  563. if (umr_inline)
  564. flags |= MLX5_UMR_INLINE;
  565. set_reg_umr_seg(*seg, mr, flags, atomic);
  566. *seg += sizeof(struct mlx5_wqe_umr_ctrl_seg);
  567. *size += sizeof(struct mlx5_wqe_umr_ctrl_seg) / 16;
  568. handle_post_send_edge(&qp->sq, seg, *size, cur_edge);
  569. set_reg_mkey_seg(*seg, mr, wr->key, wr->access);
  570. *seg += sizeof(struct mlx5_mkey_seg);
  571. *size += sizeof(struct mlx5_mkey_seg) / 16;
  572. handle_post_send_edge(&qp->sq, seg, *size, cur_edge);
  573. if (umr_inline) {
  574. mlx5r_memcpy_send_wqe(&qp->sq, cur_edge, seg, size, mr->descs,
  575. mr_list_size);
  576. *size = ALIGN(*size, MLX5_SEND_WQE_BB >> 4);
  577. } else {
  578. set_reg_data_seg(*seg, mr, pd);
  579. *seg += sizeof(struct mlx5_wqe_data_seg);
  580. *size += (sizeof(struct mlx5_wqe_data_seg) / 16);
  581. }
  582. return 0;
  583. }
  584. static void set_linv_wr(struct mlx5_ib_qp *qp, void **seg, int *size,
  585. void **cur_edge)
  586. {
  587. set_linv_umr_seg(*seg);
  588. *seg += sizeof(struct mlx5_wqe_umr_ctrl_seg);
  589. *size += sizeof(struct mlx5_wqe_umr_ctrl_seg) / 16;
  590. handle_post_send_edge(&qp->sq, seg, *size, cur_edge);
  591. set_linv_mkey_seg(*seg);
  592. *seg += sizeof(struct mlx5_mkey_seg);
  593. *size += sizeof(struct mlx5_mkey_seg) / 16;
  594. handle_post_send_edge(&qp->sq, seg, *size, cur_edge);
  595. }
  596. static void dump_wqe(struct mlx5_ib_qp *qp, u32 idx, int size_16)
  597. {
  598. __be32 *p = NULL;
  599. int i, j;
  600. pr_debug("dump WQE index %u:\n", idx);
  601. for (i = 0, j = 0; i < size_16 * 4; i += 4, j += 4) {
  602. if ((i & 0xf) == 0) {
  603. p = mlx5_frag_buf_get_wqe(&qp->sq.fbc, idx);
  604. pr_debug("WQBB at %p:\n", (void *)p);
  605. j = 0;
  606. idx = (idx + 1) & (qp->sq.wqe_cnt - 1);
  607. }
  608. pr_debug("%08x %08x %08x %08x\n", be32_to_cpu(p[j]),
  609. be32_to_cpu(p[j + 1]), be32_to_cpu(p[j + 2]),
  610. be32_to_cpu(p[j + 3]));
  611. }
  612. }
  613. int mlx5r_begin_wqe(struct mlx5_ib_qp *qp, void **seg,
  614. struct mlx5_wqe_ctrl_seg **ctrl, unsigned int *idx,
  615. int *size, void **cur_edge, int nreq, __be32 general_id,
  616. bool send_signaled, bool solicited)
  617. {
  618. if (unlikely(mlx5r_wq_overflow(&qp->sq, nreq, qp->ibqp.send_cq)))
  619. return -ENOMEM;
  620. *idx = qp->sq.cur_post & (qp->sq.wqe_cnt - 1);
  621. *seg = mlx5_frag_buf_get_wqe(&qp->sq.fbc, *idx);
  622. *ctrl = *seg;
  623. *(uint32_t *)(*seg + 8) = 0;
  624. (*ctrl)->general_id = general_id;
  625. (*ctrl)->fm_ce_se = qp->sq_signal_bits |
  626. (send_signaled ? MLX5_WQE_CTRL_CQ_UPDATE : 0) |
  627. (solicited ? MLX5_WQE_CTRL_SOLICITED : 0);
  628. *seg += sizeof(**ctrl);
  629. *size = sizeof(**ctrl) / 16;
  630. *cur_edge = qp->sq.cur_edge;
  631. return 0;
  632. }
  633. static int begin_wqe(struct mlx5_ib_qp *qp, void **seg,
  634. struct mlx5_wqe_ctrl_seg **ctrl,
  635. const struct ib_send_wr *wr, unsigned int *idx, int *size,
  636. void **cur_edge, int nreq)
  637. {
  638. return mlx5r_begin_wqe(qp, seg, ctrl, idx, size, cur_edge, nreq,
  639. send_ieth(wr), wr->send_flags & IB_SEND_SIGNALED,
  640. wr->send_flags & IB_SEND_SOLICITED);
  641. }
  642. void mlx5r_finish_wqe(struct mlx5_ib_qp *qp, struct mlx5_wqe_ctrl_seg *ctrl,
  643. void *seg, u8 size, void *cur_edge, unsigned int idx,
  644. u64 wr_id, int nreq, u8 fence, u32 mlx5_opcode)
  645. {
  646. u8 opmod = 0;
  647. ctrl->opmod_idx_opcode = cpu_to_be32(((u32)(qp->sq.cur_post) << 8) |
  648. mlx5_opcode | ((u32)opmod << 24));
  649. ctrl->qpn_ds = cpu_to_be32(size | (qp->trans_qp.base.mqp.qpn << 8));
  650. ctrl->fm_ce_se |= fence;
  651. if (unlikely(qp->flags_en & MLX5_QP_FLAG_SIGNATURE))
  652. ctrl->signature = wq_sig(ctrl);
  653. qp->sq.wrid[idx] = wr_id;
  654. qp->sq.w_list[idx].opcode = mlx5_opcode;
  655. qp->sq.wqe_head[idx] = qp->sq.head + nreq;
  656. qp->sq.cur_post += DIV_ROUND_UP(size * 16, MLX5_SEND_WQE_BB);
  657. qp->sq.w_list[idx].next = qp->sq.cur_post;
  658. /* We save the edge which was possibly updated during the WQE
  659. * construction, into SQ's cache.
  660. */
  661. seg = PTR_ALIGN(seg, MLX5_SEND_WQE_BB);
  662. qp->sq.cur_edge = (unlikely(seg == cur_edge)) ?
  663. get_sq_edge(&qp->sq, qp->sq.cur_post &
  664. (qp->sq.wqe_cnt - 1)) :
  665. cur_edge;
  666. }
  667. static void handle_rdma_op(const struct ib_send_wr *wr, void **seg, int *size)
  668. {
  669. set_raddr_seg(*seg, rdma_wr(wr)->remote_addr, rdma_wr(wr)->rkey);
  670. *seg += sizeof(struct mlx5_wqe_raddr_seg);
  671. *size += sizeof(struct mlx5_wqe_raddr_seg) / 16;
  672. }
  673. static void handle_local_inv(struct mlx5_ib_qp *qp, const struct ib_send_wr *wr,
  674. struct mlx5_wqe_ctrl_seg **ctrl, void **seg,
  675. int *size, void **cur_edge, unsigned int idx)
  676. {
  677. qp->sq.wr_data[idx] = IB_WR_LOCAL_INV;
  678. (*ctrl)->imm = cpu_to_be32(wr->ex.invalidate_rkey);
  679. set_linv_wr(qp, seg, size, cur_edge);
  680. }
  681. static int handle_reg_mr(struct mlx5_ib_qp *qp, const struct ib_send_wr *wr,
  682. struct mlx5_wqe_ctrl_seg **ctrl, void **seg, int *size,
  683. void **cur_edge, unsigned int idx)
  684. {
  685. qp->sq.wr_data[idx] = IB_WR_REG_MR;
  686. (*ctrl)->imm = cpu_to_be32(reg_wr(wr)->key);
  687. return set_reg_wr(qp, reg_wr(wr), seg, size, cur_edge, true);
  688. }
  689. static int handle_psv(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
  690. const struct ib_send_wr *wr,
  691. struct mlx5_wqe_ctrl_seg **ctrl, void **seg, int *size,
  692. void **cur_edge, unsigned int *idx, int nreq,
  693. struct ib_sig_domain *domain, u32 psv_index,
  694. u8 next_fence)
  695. {
  696. int err;
  697. /*
  698. * SET_PSV WQEs are not signaled and solicited on error.
  699. */
  700. err = mlx5r_begin_wqe(qp, seg, ctrl, idx, size, cur_edge, nreq,
  701. send_ieth(wr), false, true);
  702. if (unlikely(err)) {
  703. mlx5_ib_warn(dev, "\n");
  704. err = -ENOMEM;
  705. goto out;
  706. }
  707. err = set_psv_wr(domain, psv_index, seg, size);
  708. if (unlikely(err)) {
  709. mlx5_ib_warn(dev, "\n");
  710. goto out;
  711. }
  712. mlx5r_finish_wqe(qp, *ctrl, *seg, *size, *cur_edge, *idx, wr->wr_id,
  713. nreq, next_fence, MLX5_OPCODE_SET_PSV);
  714. out:
  715. return err;
  716. }
  717. static int handle_reg_mr_integrity(struct mlx5_ib_dev *dev,
  718. struct mlx5_ib_qp *qp,
  719. const struct ib_send_wr *wr,
  720. struct mlx5_wqe_ctrl_seg **ctrl, void **seg,
  721. int *size, void **cur_edge,
  722. unsigned int *idx, int nreq, u8 fence,
  723. u8 next_fence)
  724. {
  725. struct mlx5_ib_mr *mr;
  726. struct mlx5_ib_mr *pi_mr;
  727. struct mlx5_ib_mr pa_pi_mr;
  728. struct ib_sig_attrs *sig_attrs;
  729. struct ib_reg_wr reg_pi_wr;
  730. int err;
  731. qp->sq.wr_data[*idx] = IB_WR_REG_MR_INTEGRITY;
  732. mr = to_mmr(reg_wr(wr)->mr);
  733. pi_mr = mr->pi_mr;
  734. if (pi_mr) {
  735. memset(&reg_pi_wr, 0,
  736. sizeof(struct ib_reg_wr));
  737. reg_pi_wr.mr = &pi_mr->ibmr;
  738. reg_pi_wr.access = reg_wr(wr)->access;
  739. reg_pi_wr.key = pi_mr->ibmr.rkey;
  740. (*ctrl)->imm = cpu_to_be32(reg_pi_wr.key);
  741. /* UMR for data + prot registration */
  742. err = set_reg_wr(qp, &reg_pi_wr, seg, size, cur_edge, false);
  743. if (unlikely(err))
  744. goto out;
  745. mlx5r_finish_wqe(qp, *ctrl, *seg, *size, *cur_edge, *idx,
  746. wr->wr_id, nreq, fence, MLX5_OPCODE_UMR);
  747. err = begin_wqe(qp, seg, ctrl, wr, idx, size, cur_edge, nreq);
  748. if (unlikely(err)) {
  749. mlx5_ib_warn(dev, "\n");
  750. err = -ENOMEM;
  751. goto out;
  752. }
  753. } else {
  754. memset(&pa_pi_mr, 0, sizeof(struct mlx5_ib_mr));
  755. /* No UMR, use local_dma_lkey */
  756. pa_pi_mr.ibmr.lkey = mr->ibmr.pd->local_dma_lkey;
  757. pa_pi_mr.mmkey.ndescs = mr->mmkey.ndescs;
  758. pa_pi_mr.data_length = mr->data_length;
  759. pa_pi_mr.data_iova = mr->data_iova;
  760. if (mr->meta_ndescs) {
  761. pa_pi_mr.meta_ndescs = mr->meta_ndescs;
  762. pa_pi_mr.meta_length = mr->meta_length;
  763. pa_pi_mr.pi_iova = mr->pi_iova;
  764. }
  765. pa_pi_mr.ibmr.length = mr->ibmr.length;
  766. mr->pi_mr = &pa_pi_mr;
  767. }
  768. (*ctrl)->imm = cpu_to_be32(mr->ibmr.rkey);
  769. /* UMR for sig MR */
  770. err = set_pi_umr_wr(wr, qp, seg, size, cur_edge);
  771. if (unlikely(err)) {
  772. mlx5_ib_warn(dev, "\n");
  773. goto out;
  774. }
  775. mlx5r_finish_wqe(qp, *ctrl, *seg, *size, *cur_edge, *idx, wr->wr_id,
  776. nreq, fence, MLX5_OPCODE_UMR);
  777. sig_attrs = mr->ibmr.sig_attrs;
  778. err = handle_psv(dev, qp, wr, ctrl, seg, size, cur_edge, idx, nreq,
  779. &sig_attrs->mem, mr->sig->psv_memory.psv_idx,
  780. next_fence);
  781. if (unlikely(err))
  782. goto out;
  783. err = handle_psv(dev, qp, wr, ctrl, seg, size, cur_edge, idx, nreq,
  784. &sig_attrs->wire, mr->sig->psv_wire.psv_idx,
  785. next_fence);
  786. if (unlikely(err))
  787. goto out;
  788. qp->next_fence = MLX5_FENCE_MODE_INITIATOR_SMALL;
  789. out:
  790. return err;
  791. }
  792. static int handle_qpt_rc(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
  793. const struct ib_send_wr *wr,
  794. struct mlx5_wqe_ctrl_seg **ctrl, void **seg, int *size,
  795. void **cur_edge, unsigned int *idx, int nreq, u8 fence,
  796. u8 next_fence, int *num_sge)
  797. {
  798. int err = 0;
  799. switch (wr->opcode) {
  800. case IB_WR_RDMA_READ:
  801. case IB_WR_RDMA_WRITE:
  802. case IB_WR_RDMA_WRITE_WITH_IMM:
  803. handle_rdma_op(wr, seg, size);
  804. break;
  805. case IB_WR_ATOMIC_CMP_AND_SWP:
  806. case IB_WR_ATOMIC_FETCH_AND_ADD:
  807. case IB_WR_MASKED_ATOMIC_CMP_AND_SWP:
  808. mlx5_ib_warn(dev, "Atomic operations are not supported yet\n");
  809. err = -EOPNOTSUPP;
  810. goto out;
  811. case IB_WR_LOCAL_INV:
  812. handle_local_inv(qp, wr, ctrl, seg, size, cur_edge, *idx);
  813. *num_sge = 0;
  814. break;
  815. case IB_WR_REG_MR:
  816. err = handle_reg_mr(qp, wr, ctrl, seg, size, cur_edge, *idx);
  817. if (unlikely(err))
  818. goto out;
  819. *num_sge = 0;
  820. break;
  821. case IB_WR_REG_MR_INTEGRITY:
  822. err = handle_reg_mr_integrity(dev, qp, wr, ctrl, seg, size,
  823. cur_edge, idx, nreq, fence,
  824. next_fence);
  825. if (unlikely(err))
  826. goto out;
  827. *num_sge = 0;
  828. break;
  829. default:
  830. break;
  831. }
  832. out:
  833. return err;
  834. }
  835. static void handle_qpt_uc(const struct ib_send_wr *wr, void **seg, int *size)
  836. {
  837. switch (wr->opcode) {
  838. case IB_WR_RDMA_WRITE:
  839. case IB_WR_RDMA_WRITE_WITH_IMM:
  840. handle_rdma_op(wr, seg, size);
  841. break;
  842. default:
  843. break;
  844. }
  845. }
  846. static void handle_qpt_hw_gsi(struct mlx5_ib_qp *qp,
  847. const struct ib_send_wr *wr, void **seg,
  848. int *size, void **cur_edge)
  849. {
  850. set_datagram_seg(*seg, wr);
  851. *seg += sizeof(struct mlx5_wqe_datagram_seg);
  852. *size += sizeof(struct mlx5_wqe_datagram_seg) / 16;
  853. handle_post_send_edge(&qp->sq, seg, *size, cur_edge);
  854. }
  855. static void handle_qpt_ud(struct mlx5_ib_qp *qp, const struct ib_send_wr *wr,
  856. void **seg, int *size, void **cur_edge)
  857. {
  858. set_datagram_seg(*seg, wr);
  859. *seg += sizeof(struct mlx5_wqe_datagram_seg);
  860. *size += sizeof(struct mlx5_wqe_datagram_seg) / 16;
  861. handle_post_send_edge(&qp->sq, seg, *size, cur_edge);
  862. /* handle qp that supports ud offload */
  863. if (qp->flags & IB_QP_CREATE_IPOIB_UD_LSO) {
  864. struct mlx5_wqe_eth_pad *pad;
  865. pad = *seg;
  866. memset(pad, 0, sizeof(struct mlx5_wqe_eth_pad));
  867. *seg += sizeof(struct mlx5_wqe_eth_pad);
  868. *size += sizeof(struct mlx5_wqe_eth_pad) / 16;
  869. set_eth_seg(wr, qp, seg, size, cur_edge);
  870. handle_post_send_edge(&qp->sq, seg, *size, cur_edge);
  871. }
  872. }
  873. void mlx5r_ring_db(struct mlx5_ib_qp *qp, unsigned int nreq,
  874. struct mlx5_wqe_ctrl_seg *ctrl)
  875. {
  876. struct mlx5_bf *bf = &qp->bf;
  877. qp->sq.head += nreq;
  878. /* Make sure that descriptors are written before
  879. * updating doorbell record and ringing the doorbell
  880. */
  881. wmb();
  882. qp->db.db[MLX5_SND_DBR] = cpu_to_be32(qp->sq.cur_post);
  883. /* Make sure doorbell record is visible to the HCA before
  884. * we hit doorbell.
  885. */
  886. wmb();
  887. mlx5_write64((__be32 *)ctrl, bf->bfreg->map + bf->offset);
  888. /* Make sure doorbells don't leak out of SQ spinlock
  889. * and reach the HCA out of order.
  890. */
  891. bf->offset ^= bf->buf_size;
  892. }
  893. int mlx5_ib_post_send(struct ib_qp *ibqp, const struct ib_send_wr *wr,
  894. const struct ib_send_wr **bad_wr, bool drain)
  895. {
  896. struct mlx5_wqe_ctrl_seg *ctrl = NULL; /* compiler warning */
  897. struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
  898. struct mlx5_core_dev *mdev = dev->mdev;
  899. struct mlx5_ib_qp *qp = to_mqp(ibqp);
  900. struct mlx5_wqe_xrc_seg *xrc;
  901. void *cur_edge;
  902. int size;
  903. unsigned long flags;
  904. unsigned int idx;
  905. int err = 0;
  906. int num_sge;
  907. void *seg;
  908. int nreq;
  909. int i;
  910. u8 next_fence = 0;
  911. u8 fence;
  912. if (unlikely(mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR &&
  913. !drain)) {
  914. *bad_wr = wr;
  915. return -EIO;
  916. }
  917. if (qp->type == IB_QPT_GSI)
  918. return mlx5_ib_gsi_post_send(ibqp, wr, bad_wr);
  919. spin_lock_irqsave(&qp->sq.lock, flags);
  920. for (nreq = 0; wr; nreq++, wr = wr->next) {
  921. if (unlikely(wr->opcode >= ARRAY_SIZE(mlx5_ib_opcode))) {
  922. mlx5_ib_warn(dev, "\n");
  923. err = -EINVAL;
  924. *bad_wr = wr;
  925. goto out;
  926. }
  927. num_sge = wr->num_sge;
  928. if (unlikely(num_sge > qp->sq.max_gs)) {
  929. mlx5_ib_warn(dev, "\n");
  930. err = -EINVAL;
  931. *bad_wr = wr;
  932. goto out;
  933. }
  934. err = begin_wqe(qp, &seg, &ctrl, wr, &idx, &size, &cur_edge,
  935. nreq);
  936. if (err) {
  937. mlx5_ib_warn(dev, "\n");
  938. err = -ENOMEM;
  939. *bad_wr = wr;
  940. goto out;
  941. }
  942. if (wr->opcode == IB_WR_REG_MR ||
  943. wr->opcode == IB_WR_REG_MR_INTEGRITY) {
  944. fence = dev->umr_fence;
  945. next_fence = MLX5_FENCE_MODE_INITIATOR_SMALL;
  946. } else {
  947. if (wr->send_flags & IB_SEND_FENCE) {
  948. if (qp->next_fence)
  949. fence = MLX5_FENCE_MODE_SMALL_AND_FENCE;
  950. else
  951. fence = MLX5_FENCE_MODE_FENCE;
  952. } else {
  953. fence = qp->next_fence;
  954. }
  955. }
  956. switch (qp->type) {
  957. case IB_QPT_XRC_INI:
  958. xrc = seg;
  959. seg += sizeof(*xrc);
  960. size += sizeof(*xrc) / 16;
  961. fallthrough;
  962. case IB_QPT_RC:
  963. err = handle_qpt_rc(dev, qp, wr, &ctrl, &seg, &size,
  964. &cur_edge, &idx, nreq, fence,
  965. next_fence, &num_sge);
  966. if (unlikely(err)) {
  967. *bad_wr = wr;
  968. goto out;
  969. } else if (wr->opcode == IB_WR_REG_MR_INTEGRITY) {
  970. goto skip_psv;
  971. }
  972. break;
  973. case IB_QPT_UC:
  974. handle_qpt_uc(wr, &seg, &size);
  975. break;
  976. case IB_QPT_SMI:
  977. if (unlikely(!dev->port_caps[qp->port - 1].has_smi)) {
  978. mlx5_ib_warn(dev, "Send SMP MADs is not allowed\n");
  979. err = -EPERM;
  980. *bad_wr = wr;
  981. goto out;
  982. }
  983. fallthrough;
  984. case MLX5_IB_QPT_HW_GSI:
  985. handle_qpt_hw_gsi(qp, wr, &seg, &size, &cur_edge);
  986. break;
  987. case IB_QPT_UD:
  988. handle_qpt_ud(qp, wr, &seg, &size, &cur_edge);
  989. break;
  990. default:
  991. break;
  992. }
  993. if (wr->send_flags & IB_SEND_INLINE && num_sge) {
  994. err = set_data_inl_seg(qp, wr, &seg, &size, &cur_edge);
  995. if (unlikely(err)) {
  996. mlx5_ib_warn(dev, "\n");
  997. *bad_wr = wr;
  998. goto out;
  999. }
  1000. } else {
  1001. for (i = 0; i < num_sge; i++) {
  1002. handle_post_send_edge(&qp->sq, &seg, size,
  1003. &cur_edge);
  1004. if (unlikely(!wr->sg_list[i].length))
  1005. continue;
  1006. set_data_ptr_seg(
  1007. (struct mlx5_wqe_data_seg *)seg,
  1008. wr->sg_list + i);
  1009. size += sizeof(struct mlx5_wqe_data_seg) / 16;
  1010. seg += sizeof(struct mlx5_wqe_data_seg);
  1011. }
  1012. }
  1013. qp->next_fence = next_fence;
  1014. mlx5r_finish_wqe(qp, ctrl, seg, size, cur_edge, idx, wr->wr_id,
  1015. nreq, fence, mlx5_ib_opcode[wr->opcode]);
  1016. skip_psv:
  1017. if (0)
  1018. dump_wqe(qp, idx, size);
  1019. }
  1020. out:
  1021. if (likely(nreq))
  1022. mlx5r_ring_db(qp, nreq, ctrl);
  1023. spin_unlock_irqrestore(&qp->sq.lock, flags);
  1024. return err;
  1025. }
  1026. static void set_sig_seg(struct mlx5_rwqe_sig *sig, int max_gs)
  1027. {
  1028. sig->signature = calc_sig(sig, (max_gs + 1) << 2);
  1029. }
  1030. int mlx5_ib_post_recv(struct ib_qp *ibqp, const struct ib_recv_wr *wr,
  1031. const struct ib_recv_wr **bad_wr, bool drain)
  1032. {
  1033. struct mlx5_ib_qp *qp = to_mqp(ibqp);
  1034. struct mlx5_wqe_data_seg *scat;
  1035. struct mlx5_rwqe_sig *sig;
  1036. struct mlx5_ib_dev *dev = to_mdev(ibqp->device);
  1037. struct mlx5_core_dev *mdev = dev->mdev;
  1038. unsigned long flags;
  1039. int err = 0;
  1040. int nreq;
  1041. int ind;
  1042. int i;
  1043. if (unlikely(mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR &&
  1044. !drain)) {
  1045. *bad_wr = wr;
  1046. return -EIO;
  1047. }
  1048. if (qp->type == IB_QPT_GSI)
  1049. return mlx5_ib_gsi_post_recv(ibqp, wr, bad_wr);
  1050. spin_lock_irqsave(&qp->rq.lock, flags);
  1051. ind = qp->rq.head & (qp->rq.wqe_cnt - 1);
  1052. for (nreq = 0; wr; nreq++, wr = wr->next) {
  1053. if (mlx5r_wq_overflow(&qp->rq, nreq, qp->ibqp.recv_cq)) {
  1054. err = -ENOMEM;
  1055. *bad_wr = wr;
  1056. goto out;
  1057. }
  1058. if (unlikely(wr->num_sge > qp->rq.max_gs)) {
  1059. err = -EINVAL;
  1060. *bad_wr = wr;
  1061. goto out;
  1062. }
  1063. scat = mlx5_frag_buf_get_wqe(&qp->rq.fbc, ind);
  1064. if (qp->flags_en & MLX5_QP_FLAG_SIGNATURE)
  1065. scat++;
  1066. for (i = 0; i < wr->num_sge; i++)
  1067. set_data_ptr_seg(scat + i, wr->sg_list + i);
  1068. if (i < qp->rq.max_gs) {
  1069. scat[i].byte_count = 0;
  1070. scat[i].lkey = cpu_to_be32(MLX5_INVALID_LKEY);
  1071. scat[i].addr = 0;
  1072. }
  1073. if (qp->flags_en & MLX5_QP_FLAG_SIGNATURE) {
  1074. sig = (struct mlx5_rwqe_sig *)scat;
  1075. set_sig_seg(sig, qp->rq.max_gs);
  1076. }
  1077. qp->rq.wrid[ind] = wr->wr_id;
  1078. ind = (ind + 1) & (qp->rq.wqe_cnt - 1);
  1079. }
  1080. out:
  1081. if (likely(nreq)) {
  1082. qp->rq.head += nreq;
  1083. /* Make sure that descriptors are written before
  1084. * doorbell record.
  1085. */
  1086. wmb();
  1087. *qp->db.db = cpu_to_be32(qp->rq.head & 0xffff);
  1088. }
  1089. spin_unlock_irqrestore(&qp->rq.lock, flags);
  1090. return err;
  1091. }