mem.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812
  1. /*
  2. * Copyright (c) 2009-2010 Chelsio, 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. */
  32. #include <rdma/ib_umem.h>
  33. #include <asm/atomic.h>
  34. #include "iw_cxgb4.h"
  35. #define T4_ULPTX_MIN_IO 32
  36. #define C4IW_MAX_INLINE_SIZE 96
  37. static int write_adapter_mem(struct c4iw_rdev *rdev, u32 addr, u32 len,
  38. void *data)
  39. {
  40. struct sk_buff *skb;
  41. struct ulp_mem_io *req;
  42. struct ulptx_idata *sc;
  43. u8 wr_len, *to_dp, *from_dp;
  44. int copy_len, num_wqe, i, ret = 0;
  45. struct c4iw_wr_wait wr_wait;
  46. addr &= 0x7FFFFFF;
  47. PDBG("%s addr 0x%x len %u\n", __func__, addr, len);
  48. num_wqe = DIV_ROUND_UP(len, C4IW_MAX_INLINE_SIZE);
  49. c4iw_init_wr_wait(&wr_wait);
  50. for (i = 0; i < num_wqe; i++) {
  51. copy_len = len > C4IW_MAX_INLINE_SIZE ? C4IW_MAX_INLINE_SIZE :
  52. len;
  53. wr_len = roundup(sizeof *req + sizeof *sc +
  54. roundup(copy_len, T4_ULPTX_MIN_IO), 16);
  55. skb = alloc_skb(wr_len, GFP_KERNEL);
  56. if (!skb)
  57. return -ENOMEM;
  58. set_wr_txq(skb, CPL_PRIORITY_CONTROL, 0);
  59. req = (struct ulp_mem_io *)__skb_put(skb, wr_len);
  60. memset(req, 0, wr_len);
  61. INIT_ULPTX_WR(req, wr_len, 0, 0);
  62. if (i == (num_wqe-1)) {
  63. req->wr.wr_hi = cpu_to_be32(FW_WR_OP(FW_ULPTX_WR) |
  64. FW_WR_COMPL(1));
  65. req->wr.wr_lo = (__force __be64)&wr_wait;
  66. } else
  67. req->wr.wr_hi = cpu_to_be32(FW_WR_OP(FW_ULPTX_WR));
  68. req->wr.wr_mid = cpu_to_be32(
  69. FW_WR_LEN16(DIV_ROUND_UP(wr_len, 16)));
  70. req->cmd = cpu_to_be32(ULPTX_CMD(ULP_TX_MEM_WRITE) | (1<<23));
  71. req->dlen = cpu_to_be32(ULP_MEMIO_DATA_LEN(
  72. DIV_ROUND_UP(copy_len, T4_ULPTX_MIN_IO)));
  73. req->len16 = cpu_to_be32(DIV_ROUND_UP(wr_len-sizeof(req->wr),
  74. 16));
  75. req->lock_addr = cpu_to_be32(ULP_MEMIO_ADDR(addr + i * 3));
  76. sc = (struct ulptx_idata *)(req + 1);
  77. sc->cmd_more = cpu_to_be32(ULPTX_CMD(ULP_TX_SC_IMM));
  78. sc->len = cpu_to_be32(roundup(copy_len, T4_ULPTX_MIN_IO));
  79. to_dp = (u8 *)(sc + 1);
  80. from_dp = (u8 *)data + i * C4IW_MAX_INLINE_SIZE;
  81. if (data)
  82. memcpy(to_dp, from_dp, copy_len);
  83. else
  84. memset(to_dp, 0, copy_len);
  85. if (copy_len % T4_ULPTX_MIN_IO)
  86. memset(to_dp + copy_len, 0, T4_ULPTX_MIN_IO -
  87. (copy_len % T4_ULPTX_MIN_IO));
  88. ret = c4iw_ofld_send(rdev, skb);
  89. if (ret)
  90. return ret;
  91. len -= C4IW_MAX_INLINE_SIZE;
  92. }
  93. wait_event_timeout(wr_wait.wait, wr_wait.done, C4IW_WR_TO);
  94. if (!wr_wait.done) {
  95. printk(KERN_ERR MOD "Device %s not responding!\n",
  96. pci_name(rdev->lldi.pdev));
  97. rdev->flags = T4_FATAL_ERROR;
  98. ret = -EIO;
  99. } else
  100. ret = wr_wait.ret;
  101. return ret;
  102. }
  103. /*
  104. * Build and write a TPT entry.
  105. * IN: stag key, pdid, perm, bind_enabled, zbva, to, len, page_size,
  106. * pbl_size and pbl_addr
  107. * OUT: stag index
  108. */
  109. static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry,
  110. u32 *stag, u8 stag_state, u32 pdid,
  111. enum fw_ri_stag_type type, enum fw_ri_mem_perms perm,
  112. int bind_enabled, u32 zbva, u64 to,
  113. u64 len, u8 page_size, u32 pbl_size, u32 pbl_addr)
  114. {
  115. int err;
  116. struct fw_ri_tpte tpt;
  117. u32 stag_idx;
  118. static atomic_t key;
  119. if (c4iw_fatal_error(rdev))
  120. return -EIO;
  121. stag_state = stag_state > 0;
  122. stag_idx = (*stag) >> 8;
  123. if ((!reset_tpt_entry) && (*stag == T4_STAG_UNSET)) {
  124. stag_idx = c4iw_get_resource(&rdev->resource.tpt_fifo,
  125. &rdev->resource.tpt_fifo_lock);
  126. if (!stag_idx)
  127. return -ENOMEM;
  128. *stag = (stag_idx << 8) | (atomic_inc_return(&key) & 0xff);
  129. }
  130. PDBG("%s stag_state 0x%0x type 0x%0x pdid 0x%0x, stag_idx 0x%x\n",
  131. __func__, stag_state, type, pdid, stag_idx);
  132. /* write TPT entry */
  133. if (reset_tpt_entry)
  134. memset(&tpt, 0, sizeof(tpt));
  135. else {
  136. tpt.valid_to_pdid = cpu_to_be32(F_FW_RI_TPTE_VALID |
  137. V_FW_RI_TPTE_STAGKEY((*stag & M_FW_RI_TPTE_STAGKEY)) |
  138. V_FW_RI_TPTE_STAGSTATE(stag_state) |
  139. V_FW_RI_TPTE_STAGTYPE(type) | V_FW_RI_TPTE_PDID(pdid));
  140. tpt.locread_to_qpid = cpu_to_be32(V_FW_RI_TPTE_PERM(perm) |
  141. (bind_enabled ? F_FW_RI_TPTE_MWBINDEN : 0) |
  142. V_FW_RI_TPTE_ADDRTYPE((zbva ? FW_RI_ZERO_BASED_TO :
  143. FW_RI_VA_BASED_TO))|
  144. V_FW_RI_TPTE_PS(page_size));
  145. tpt.nosnoop_pbladdr = !pbl_size ? 0 : cpu_to_be32(
  146. V_FW_RI_TPTE_PBLADDR(PBL_OFF(rdev, pbl_addr)>>3));
  147. tpt.len_lo = cpu_to_be32((u32)(len & 0xffffffffUL));
  148. tpt.va_hi = cpu_to_be32((u32)(to >> 32));
  149. tpt.va_lo_fbo = cpu_to_be32((u32)(to & 0xffffffffUL));
  150. tpt.dca_mwbcnt_pstag = cpu_to_be32(0);
  151. tpt.len_hi = cpu_to_be32((u32)(len >> 32));
  152. }
  153. err = write_adapter_mem(rdev, stag_idx +
  154. (rdev->lldi.vr->stag.start >> 5),
  155. sizeof(tpt), &tpt);
  156. if (reset_tpt_entry)
  157. c4iw_put_resource(&rdev->resource.tpt_fifo, stag_idx,
  158. &rdev->resource.tpt_fifo_lock);
  159. return err;
  160. }
  161. static int write_pbl(struct c4iw_rdev *rdev, __be64 *pbl,
  162. u32 pbl_addr, u32 pbl_size)
  163. {
  164. int err;
  165. PDBG("%s *pdb_addr 0x%x, pbl_base 0x%x, pbl_size %d\n",
  166. __func__, pbl_addr, rdev->lldi.vr->pbl.start,
  167. pbl_size);
  168. err = write_adapter_mem(rdev, pbl_addr >> 5, pbl_size << 3, pbl);
  169. return err;
  170. }
  171. static int dereg_mem(struct c4iw_rdev *rdev, u32 stag, u32 pbl_size,
  172. u32 pbl_addr)
  173. {
  174. return write_tpt_entry(rdev, 1, &stag, 0, 0, 0, 0, 0, 0, 0UL, 0, 0,
  175. pbl_size, pbl_addr);
  176. }
  177. static int allocate_window(struct c4iw_rdev *rdev, u32 * stag, u32 pdid)
  178. {
  179. *stag = T4_STAG_UNSET;
  180. return write_tpt_entry(rdev, 0, stag, 0, pdid, FW_RI_STAG_MW, 0, 0, 0,
  181. 0UL, 0, 0, 0, 0);
  182. }
  183. static int deallocate_window(struct c4iw_rdev *rdev, u32 stag)
  184. {
  185. return write_tpt_entry(rdev, 1, &stag, 0, 0, 0, 0, 0, 0, 0UL, 0, 0, 0,
  186. 0);
  187. }
  188. static int allocate_stag(struct c4iw_rdev *rdev, u32 *stag, u32 pdid,
  189. u32 pbl_size, u32 pbl_addr)
  190. {
  191. *stag = T4_STAG_UNSET;
  192. return write_tpt_entry(rdev, 0, stag, 0, pdid, FW_RI_STAG_NSMR, 0, 0, 0,
  193. 0UL, 0, 0, pbl_size, pbl_addr);
  194. }
  195. static int finish_mem_reg(struct c4iw_mr *mhp, u32 stag)
  196. {
  197. u32 mmid;
  198. mhp->attr.state = 1;
  199. mhp->attr.stag = stag;
  200. mmid = stag >> 8;
  201. mhp->ibmr.rkey = mhp->ibmr.lkey = stag;
  202. PDBG("%s mmid 0x%x mhp %p\n", __func__, mmid, mhp);
  203. return insert_handle(mhp->rhp, &mhp->rhp->mmidr, mhp, mmid);
  204. }
  205. static int register_mem(struct c4iw_dev *rhp, struct c4iw_pd *php,
  206. struct c4iw_mr *mhp, int shift)
  207. {
  208. u32 stag = T4_STAG_UNSET;
  209. int ret;
  210. ret = write_tpt_entry(&rhp->rdev, 0, &stag, 1, mhp->attr.pdid,
  211. FW_RI_STAG_NSMR, mhp->attr.perms,
  212. mhp->attr.mw_bind_enable, mhp->attr.zbva,
  213. mhp->attr.va_fbo, mhp->attr.len, shift - 12,
  214. mhp->attr.pbl_size, mhp->attr.pbl_addr);
  215. if (ret)
  216. return ret;
  217. ret = finish_mem_reg(mhp, stag);
  218. if (ret)
  219. dereg_mem(&rhp->rdev, mhp->attr.stag, mhp->attr.pbl_size,
  220. mhp->attr.pbl_addr);
  221. return ret;
  222. }
  223. static int reregister_mem(struct c4iw_dev *rhp, struct c4iw_pd *php,
  224. struct c4iw_mr *mhp, int shift, int npages)
  225. {
  226. u32 stag;
  227. int ret;
  228. if (npages > mhp->attr.pbl_size)
  229. return -ENOMEM;
  230. stag = mhp->attr.stag;
  231. ret = write_tpt_entry(&rhp->rdev, 0, &stag, 1, mhp->attr.pdid,
  232. FW_RI_STAG_NSMR, mhp->attr.perms,
  233. mhp->attr.mw_bind_enable, mhp->attr.zbva,
  234. mhp->attr.va_fbo, mhp->attr.len, shift - 12,
  235. mhp->attr.pbl_size, mhp->attr.pbl_addr);
  236. if (ret)
  237. return ret;
  238. ret = finish_mem_reg(mhp, stag);
  239. if (ret)
  240. dereg_mem(&rhp->rdev, mhp->attr.stag, mhp->attr.pbl_size,
  241. mhp->attr.pbl_addr);
  242. return ret;
  243. }
  244. static int alloc_pbl(struct c4iw_mr *mhp, int npages)
  245. {
  246. mhp->attr.pbl_addr = c4iw_pblpool_alloc(&mhp->rhp->rdev,
  247. npages << 3);
  248. if (!mhp->attr.pbl_addr)
  249. return -ENOMEM;
  250. mhp->attr.pbl_size = npages;
  251. return 0;
  252. }
  253. static int build_phys_page_list(struct ib_phys_buf *buffer_list,
  254. int num_phys_buf, u64 *iova_start,
  255. u64 *total_size, int *npages,
  256. int *shift, __be64 **page_list)
  257. {
  258. u64 mask;
  259. int i, j, n;
  260. mask = 0;
  261. *total_size = 0;
  262. for (i = 0; i < num_phys_buf; ++i) {
  263. if (i != 0 && buffer_list[i].addr & ~PAGE_MASK)
  264. return -EINVAL;
  265. if (i != 0 && i != num_phys_buf - 1 &&
  266. (buffer_list[i].size & ~PAGE_MASK))
  267. return -EINVAL;
  268. *total_size += buffer_list[i].size;
  269. if (i > 0)
  270. mask |= buffer_list[i].addr;
  271. else
  272. mask |= buffer_list[i].addr & PAGE_MASK;
  273. if (i != num_phys_buf - 1)
  274. mask |= buffer_list[i].addr + buffer_list[i].size;
  275. else
  276. mask |= (buffer_list[i].addr + buffer_list[i].size +
  277. PAGE_SIZE - 1) & PAGE_MASK;
  278. }
  279. if (*total_size > 0xFFFFFFFFULL)
  280. return -ENOMEM;
  281. /* Find largest page shift we can use to cover buffers */
  282. for (*shift = PAGE_SHIFT; *shift < 27; ++(*shift))
  283. if ((1ULL << *shift) & mask)
  284. break;
  285. buffer_list[0].size += buffer_list[0].addr & ((1ULL << *shift) - 1);
  286. buffer_list[0].addr &= ~0ull << *shift;
  287. *npages = 0;
  288. for (i = 0; i < num_phys_buf; ++i)
  289. *npages += (buffer_list[i].size +
  290. (1ULL << *shift) - 1) >> *shift;
  291. if (!*npages)
  292. return -EINVAL;
  293. *page_list = kmalloc(sizeof(u64) * *npages, GFP_KERNEL);
  294. if (!*page_list)
  295. return -ENOMEM;
  296. n = 0;
  297. for (i = 0; i < num_phys_buf; ++i)
  298. for (j = 0;
  299. j < (buffer_list[i].size + (1ULL << *shift) - 1) >> *shift;
  300. ++j)
  301. (*page_list)[n++] = cpu_to_be64(buffer_list[i].addr +
  302. ((u64) j << *shift));
  303. PDBG("%s va 0x%llx mask 0x%llx shift %d len %lld pbl_size %d\n",
  304. __func__, (unsigned long long)*iova_start,
  305. (unsigned long long)mask, *shift, (unsigned long long)*total_size,
  306. *npages);
  307. return 0;
  308. }
  309. int c4iw_reregister_phys_mem(struct ib_mr *mr, int mr_rereg_mask,
  310. struct ib_pd *pd, struct ib_phys_buf *buffer_list,
  311. int num_phys_buf, int acc, u64 *iova_start)
  312. {
  313. struct c4iw_mr mh, *mhp;
  314. struct c4iw_pd *php;
  315. struct c4iw_dev *rhp;
  316. __be64 *page_list = NULL;
  317. int shift = 0;
  318. u64 total_size;
  319. int npages;
  320. int ret;
  321. PDBG("%s ib_mr %p ib_pd %p\n", __func__, mr, pd);
  322. /* There can be no memory windows */
  323. if (atomic_read(&mr->usecnt))
  324. return -EINVAL;
  325. mhp = to_c4iw_mr(mr);
  326. rhp = mhp->rhp;
  327. php = to_c4iw_pd(mr->pd);
  328. /* make sure we are on the same adapter */
  329. if (rhp != php->rhp)
  330. return -EINVAL;
  331. memcpy(&mh, mhp, sizeof *mhp);
  332. if (mr_rereg_mask & IB_MR_REREG_PD)
  333. php = to_c4iw_pd(pd);
  334. if (mr_rereg_mask & IB_MR_REREG_ACCESS) {
  335. mh.attr.perms = c4iw_ib_to_tpt_access(acc);
  336. mh.attr.mw_bind_enable = (acc & IB_ACCESS_MW_BIND) ==
  337. IB_ACCESS_MW_BIND;
  338. }
  339. if (mr_rereg_mask & IB_MR_REREG_TRANS) {
  340. ret = build_phys_page_list(buffer_list, num_phys_buf,
  341. iova_start,
  342. &total_size, &npages,
  343. &shift, &page_list);
  344. if (ret)
  345. return ret;
  346. }
  347. ret = reregister_mem(rhp, php, &mh, shift, npages);
  348. kfree(page_list);
  349. if (ret)
  350. return ret;
  351. if (mr_rereg_mask & IB_MR_REREG_PD)
  352. mhp->attr.pdid = php->pdid;
  353. if (mr_rereg_mask & IB_MR_REREG_ACCESS)
  354. mhp->attr.perms = c4iw_ib_to_tpt_access(acc);
  355. if (mr_rereg_mask & IB_MR_REREG_TRANS) {
  356. mhp->attr.zbva = 0;
  357. mhp->attr.va_fbo = *iova_start;
  358. mhp->attr.page_size = shift - 12;
  359. mhp->attr.len = (u32) total_size;
  360. mhp->attr.pbl_size = npages;
  361. }
  362. return 0;
  363. }
  364. struct ib_mr *c4iw_register_phys_mem(struct ib_pd *pd,
  365. struct ib_phys_buf *buffer_list,
  366. int num_phys_buf, int acc, u64 *iova_start)
  367. {
  368. __be64 *page_list;
  369. int shift;
  370. u64 total_size;
  371. int npages;
  372. struct c4iw_dev *rhp;
  373. struct c4iw_pd *php;
  374. struct c4iw_mr *mhp;
  375. int ret;
  376. PDBG("%s ib_pd %p\n", __func__, pd);
  377. php = to_c4iw_pd(pd);
  378. rhp = php->rhp;
  379. mhp = kzalloc(sizeof(*mhp), GFP_KERNEL);
  380. if (!mhp)
  381. return ERR_PTR(-ENOMEM);
  382. mhp->rhp = rhp;
  383. /* First check that we have enough alignment */
  384. if ((*iova_start & ~PAGE_MASK) != (buffer_list[0].addr & ~PAGE_MASK)) {
  385. ret = -EINVAL;
  386. goto err;
  387. }
  388. if (num_phys_buf > 1 &&
  389. ((buffer_list[0].addr + buffer_list[0].size) & ~PAGE_MASK)) {
  390. ret = -EINVAL;
  391. goto err;
  392. }
  393. ret = build_phys_page_list(buffer_list, num_phys_buf, iova_start,
  394. &total_size, &npages, &shift,
  395. &page_list);
  396. if (ret)
  397. goto err;
  398. ret = alloc_pbl(mhp, npages);
  399. if (ret) {
  400. kfree(page_list);
  401. goto err_pbl;
  402. }
  403. ret = write_pbl(&mhp->rhp->rdev, page_list, mhp->attr.pbl_addr,
  404. npages);
  405. kfree(page_list);
  406. if (ret)
  407. goto err_pbl;
  408. mhp->attr.pdid = php->pdid;
  409. mhp->attr.zbva = 0;
  410. mhp->attr.perms = c4iw_ib_to_tpt_access(acc);
  411. mhp->attr.va_fbo = *iova_start;
  412. mhp->attr.page_size = shift - 12;
  413. mhp->attr.len = (u32) total_size;
  414. mhp->attr.pbl_size = npages;
  415. ret = register_mem(rhp, php, mhp, shift);
  416. if (ret)
  417. goto err_pbl;
  418. return &mhp->ibmr;
  419. err_pbl:
  420. c4iw_pblpool_free(&mhp->rhp->rdev, mhp->attr.pbl_addr,
  421. mhp->attr.pbl_size << 3);
  422. err:
  423. kfree(mhp);
  424. return ERR_PTR(ret);
  425. }
  426. struct ib_mr *c4iw_get_dma_mr(struct ib_pd *pd, int acc)
  427. {
  428. struct c4iw_dev *rhp;
  429. struct c4iw_pd *php;
  430. struct c4iw_mr *mhp;
  431. int ret;
  432. u32 stag = T4_STAG_UNSET;
  433. PDBG("%s ib_pd %p\n", __func__, pd);
  434. php = to_c4iw_pd(pd);
  435. rhp = php->rhp;
  436. mhp = kzalloc(sizeof(*mhp), GFP_KERNEL);
  437. if (!mhp)
  438. return ERR_PTR(-ENOMEM);
  439. mhp->rhp = rhp;
  440. mhp->attr.pdid = php->pdid;
  441. mhp->attr.perms = c4iw_ib_to_tpt_access(acc);
  442. mhp->attr.mw_bind_enable = (acc&IB_ACCESS_MW_BIND) == IB_ACCESS_MW_BIND;
  443. mhp->attr.zbva = 0;
  444. mhp->attr.va_fbo = 0;
  445. mhp->attr.page_size = 0;
  446. mhp->attr.len = ~0UL;
  447. mhp->attr.pbl_size = 0;
  448. ret = write_tpt_entry(&rhp->rdev, 0, &stag, 1, php->pdid,
  449. FW_RI_STAG_NSMR, mhp->attr.perms,
  450. mhp->attr.mw_bind_enable, 0, 0, ~0UL, 0, 0, 0);
  451. if (ret)
  452. goto err1;
  453. ret = finish_mem_reg(mhp, stag);
  454. if (ret)
  455. goto err2;
  456. return &mhp->ibmr;
  457. err2:
  458. dereg_mem(&rhp->rdev, mhp->attr.stag, mhp->attr.pbl_size,
  459. mhp->attr.pbl_addr);
  460. err1:
  461. kfree(mhp);
  462. return ERR_PTR(ret);
  463. }
  464. struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
  465. u64 virt, int acc, struct ib_udata *udata)
  466. {
  467. __be64 *pages;
  468. int shift, n, len;
  469. int i, j, k;
  470. int err = 0;
  471. struct ib_umem_chunk *chunk;
  472. struct c4iw_dev *rhp;
  473. struct c4iw_pd *php;
  474. struct c4iw_mr *mhp;
  475. PDBG("%s ib_pd %p\n", __func__, pd);
  476. if (length == ~0ULL)
  477. return ERR_PTR(-EINVAL);
  478. if ((length + start) < start)
  479. return ERR_PTR(-EINVAL);
  480. php = to_c4iw_pd(pd);
  481. rhp = php->rhp;
  482. mhp = kzalloc(sizeof(*mhp), GFP_KERNEL);
  483. if (!mhp)
  484. return ERR_PTR(-ENOMEM);
  485. mhp->rhp = rhp;
  486. mhp->umem = ib_umem_get(pd->uobject->context, start, length, acc, 0);
  487. if (IS_ERR(mhp->umem)) {
  488. err = PTR_ERR(mhp->umem);
  489. kfree(mhp);
  490. return ERR_PTR(err);
  491. }
  492. shift = ffs(mhp->umem->page_size) - 1;
  493. n = 0;
  494. list_for_each_entry(chunk, &mhp->umem->chunk_list, list)
  495. n += chunk->nents;
  496. err = alloc_pbl(mhp, n);
  497. if (err)
  498. goto err;
  499. pages = (__be64 *) __get_free_page(GFP_KERNEL);
  500. if (!pages) {
  501. err = -ENOMEM;
  502. goto err_pbl;
  503. }
  504. i = n = 0;
  505. list_for_each_entry(chunk, &mhp->umem->chunk_list, list)
  506. for (j = 0; j < chunk->nmap; ++j) {
  507. len = sg_dma_len(&chunk->page_list[j]) >> shift;
  508. for (k = 0; k < len; ++k) {
  509. pages[i++] = cpu_to_be64(sg_dma_address(
  510. &chunk->page_list[j]) +
  511. mhp->umem->page_size * k);
  512. if (i == PAGE_SIZE / sizeof *pages) {
  513. err = write_pbl(&mhp->rhp->rdev,
  514. pages,
  515. mhp->attr.pbl_addr + (n << 3), i);
  516. if (err)
  517. goto pbl_done;
  518. n += i;
  519. i = 0;
  520. }
  521. }
  522. }
  523. if (i)
  524. err = write_pbl(&mhp->rhp->rdev, pages,
  525. mhp->attr.pbl_addr + (n << 3), i);
  526. pbl_done:
  527. free_page((unsigned long) pages);
  528. if (err)
  529. goto err_pbl;
  530. mhp->attr.pdid = php->pdid;
  531. mhp->attr.zbva = 0;
  532. mhp->attr.perms = c4iw_ib_to_tpt_access(acc);
  533. mhp->attr.va_fbo = virt;
  534. mhp->attr.page_size = shift - 12;
  535. mhp->attr.len = (u32) length;
  536. err = register_mem(rhp, php, mhp, shift);
  537. if (err)
  538. goto err_pbl;
  539. return &mhp->ibmr;
  540. err_pbl:
  541. c4iw_pblpool_free(&mhp->rhp->rdev, mhp->attr.pbl_addr,
  542. mhp->attr.pbl_size << 3);
  543. err:
  544. ib_umem_release(mhp->umem);
  545. kfree(mhp);
  546. return ERR_PTR(err);
  547. }
  548. struct ib_mw *c4iw_alloc_mw(struct ib_pd *pd)
  549. {
  550. struct c4iw_dev *rhp;
  551. struct c4iw_pd *php;
  552. struct c4iw_mw *mhp;
  553. u32 mmid;
  554. u32 stag = 0;
  555. int ret;
  556. php = to_c4iw_pd(pd);
  557. rhp = php->rhp;
  558. mhp = kzalloc(sizeof(*mhp), GFP_KERNEL);
  559. if (!mhp)
  560. return ERR_PTR(-ENOMEM);
  561. ret = allocate_window(&rhp->rdev, &stag, php->pdid);
  562. if (ret) {
  563. kfree(mhp);
  564. return ERR_PTR(ret);
  565. }
  566. mhp->rhp = rhp;
  567. mhp->attr.pdid = php->pdid;
  568. mhp->attr.type = FW_RI_STAG_MW;
  569. mhp->attr.stag = stag;
  570. mmid = (stag) >> 8;
  571. mhp->ibmw.rkey = stag;
  572. if (insert_handle(rhp, &rhp->mmidr, mhp, mmid)) {
  573. deallocate_window(&rhp->rdev, mhp->attr.stag);
  574. kfree(mhp);
  575. return ERR_PTR(-ENOMEM);
  576. }
  577. PDBG("%s mmid 0x%x mhp %p stag 0x%x\n", __func__, mmid, mhp, stag);
  578. return &(mhp->ibmw);
  579. }
  580. int c4iw_dealloc_mw(struct ib_mw *mw)
  581. {
  582. struct c4iw_dev *rhp;
  583. struct c4iw_mw *mhp;
  584. u32 mmid;
  585. mhp = to_c4iw_mw(mw);
  586. rhp = mhp->rhp;
  587. mmid = (mw->rkey) >> 8;
  588. deallocate_window(&rhp->rdev, mhp->attr.stag);
  589. remove_handle(rhp, &rhp->mmidr, mmid);
  590. kfree(mhp);
  591. PDBG("%s ib_mw %p mmid 0x%x ptr %p\n", __func__, mw, mmid, mhp);
  592. return 0;
  593. }
  594. struct ib_mr *c4iw_alloc_fast_reg_mr(struct ib_pd *pd, int pbl_depth)
  595. {
  596. struct c4iw_dev *rhp;
  597. struct c4iw_pd *php;
  598. struct c4iw_mr *mhp;
  599. u32 mmid;
  600. u32 stag = 0;
  601. int ret = 0;
  602. php = to_c4iw_pd(pd);
  603. rhp = php->rhp;
  604. mhp = kzalloc(sizeof(*mhp), GFP_KERNEL);
  605. if (!mhp) {
  606. ret = -ENOMEM;
  607. goto err;
  608. }
  609. mhp->rhp = rhp;
  610. ret = alloc_pbl(mhp, pbl_depth);
  611. if (ret)
  612. goto err1;
  613. mhp->attr.pbl_size = pbl_depth;
  614. ret = allocate_stag(&rhp->rdev, &stag, php->pdid,
  615. mhp->attr.pbl_size, mhp->attr.pbl_addr);
  616. if (ret)
  617. goto err2;
  618. mhp->attr.pdid = php->pdid;
  619. mhp->attr.type = FW_RI_STAG_NSMR;
  620. mhp->attr.stag = stag;
  621. mhp->attr.state = 1;
  622. mmid = (stag) >> 8;
  623. mhp->ibmr.rkey = mhp->ibmr.lkey = stag;
  624. if (insert_handle(rhp, &rhp->mmidr, mhp, mmid)) {
  625. ret = -ENOMEM;
  626. goto err3;
  627. }
  628. PDBG("%s mmid 0x%x mhp %p stag 0x%x\n", __func__, mmid, mhp, stag);
  629. return &(mhp->ibmr);
  630. err3:
  631. dereg_mem(&rhp->rdev, stag, mhp->attr.pbl_size,
  632. mhp->attr.pbl_addr);
  633. err2:
  634. c4iw_pblpool_free(&mhp->rhp->rdev, mhp->attr.pbl_addr,
  635. mhp->attr.pbl_size << 3);
  636. err1:
  637. kfree(mhp);
  638. err:
  639. return ERR_PTR(ret);
  640. }
  641. struct ib_fast_reg_page_list *c4iw_alloc_fastreg_pbl(struct ib_device *device,
  642. int page_list_len)
  643. {
  644. struct c4iw_fr_page_list *c4pl;
  645. struct c4iw_dev *dev = to_c4iw_dev(device);
  646. dma_addr_t dma_addr;
  647. int size = sizeof *c4pl + page_list_len * sizeof(u64);
  648. c4pl = dma_alloc_coherent(&dev->rdev.lldi.pdev->dev, size,
  649. &dma_addr, GFP_KERNEL);
  650. if (!c4pl)
  651. return ERR_PTR(-ENOMEM);
  652. dma_unmap_addr_set(c4pl, mapping, dma_addr);
  653. c4pl->dma_addr = dma_addr;
  654. c4pl->dev = dev;
  655. c4pl->size = size;
  656. c4pl->ibpl.page_list = (u64 *)(c4pl + 1);
  657. c4pl->ibpl.max_page_list_len = page_list_len;
  658. return &c4pl->ibpl;
  659. }
  660. void c4iw_free_fastreg_pbl(struct ib_fast_reg_page_list *ibpl)
  661. {
  662. struct c4iw_fr_page_list *c4pl = to_c4iw_fr_page_list(ibpl);
  663. dma_free_coherent(&c4pl->dev->rdev.lldi.pdev->dev, c4pl->size,
  664. c4pl, dma_unmap_addr(c4pl, mapping));
  665. }
  666. int c4iw_dereg_mr(struct ib_mr *ib_mr)
  667. {
  668. struct c4iw_dev *rhp;
  669. struct c4iw_mr *mhp;
  670. u32 mmid;
  671. PDBG("%s ib_mr %p\n", __func__, ib_mr);
  672. /* There can be no memory windows */
  673. if (atomic_read(&ib_mr->usecnt))
  674. return -EINVAL;
  675. mhp = to_c4iw_mr(ib_mr);
  676. rhp = mhp->rhp;
  677. mmid = mhp->attr.stag >> 8;
  678. dereg_mem(&rhp->rdev, mhp->attr.stag, mhp->attr.pbl_size,
  679. mhp->attr.pbl_addr);
  680. if (mhp->attr.pbl_size)
  681. c4iw_pblpool_free(&mhp->rhp->rdev, mhp->attr.pbl_addr,
  682. mhp->attr.pbl_size << 3);
  683. remove_handle(rhp, &rhp->mmidr, mmid);
  684. if (mhp->kva)
  685. kfree((void *) (unsigned long) mhp->kva);
  686. if (mhp->umem)
  687. ib_umem_release(mhp->umem);
  688. PDBG("%s mmid 0x%x ptr %p\n", __func__, mmid, mhp);
  689. kfree(mhp);
  690. return 0;
  691. }