hns_roce_hem.c 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055
  1. /*
  2. * Copyright (c) 2016 Hisilicon Limited.
  3. * Copyright (c) 2007, 2008 Mellanox Technologies. 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. */
  33. #include <linux/platform_device.h>
  34. #include "hns_roce_device.h"
  35. #include "hns_roce_hem.h"
  36. #include "hns_roce_common.h"
  37. #define DMA_ADDR_T_SHIFT 12
  38. #define BT_BA_SHIFT 32
  39. bool hns_roce_check_whether_mhop(struct hns_roce_dev *hr_dev, u32 type)
  40. {
  41. if ((hr_dev->caps.qpc_hop_num && type == HEM_TYPE_QPC) ||
  42. (hr_dev->caps.mpt_hop_num && type == HEM_TYPE_MTPT) ||
  43. (hr_dev->caps.cqc_hop_num && type == HEM_TYPE_CQC) ||
  44. (hr_dev->caps.srqc_hop_num && type == HEM_TYPE_SRQC) ||
  45. (hr_dev->caps.cqe_hop_num && type == HEM_TYPE_CQE) ||
  46. (hr_dev->caps.mtt_hop_num && type == HEM_TYPE_MTT))
  47. return true;
  48. return false;
  49. }
  50. EXPORT_SYMBOL_GPL(hns_roce_check_whether_mhop);
  51. static bool hns_roce_check_hem_null(struct hns_roce_hem **hem, u64 start_idx,
  52. u32 bt_chunk_num)
  53. {
  54. int i;
  55. for (i = 0; i < bt_chunk_num; i++)
  56. if (hem[start_idx + i])
  57. return false;
  58. return true;
  59. }
  60. static bool hns_roce_check_bt_null(u64 **bt, u64 start_idx, u32 bt_chunk_num)
  61. {
  62. int i;
  63. for (i = 0; i < bt_chunk_num; i++)
  64. if (bt[start_idx + i])
  65. return false;
  66. return true;
  67. }
  68. static int hns_roce_get_bt_num(u32 table_type, u32 hop_num)
  69. {
  70. if (check_whether_bt_num_3(table_type, hop_num))
  71. return 3;
  72. else if (check_whether_bt_num_2(table_type, hop_num))
  73. return 2;
  74. else if (check_whether_bt_num_1(table_type, hop_num))
  75. return 1;
  76. else
  77. return 0;
  78. }
  79. int hns_roce_calc_hem_mhop(struct hns_roce_dev *hr_dev,
  80. struct hns_roce_hem_table *table, unsigned long *obj,
  81. struct hns_roce_hem_mhop *mhop)
  82. {
  83. struct device *dev = hr_dev->dev;
  84. u32 chunk_ba_num;
  85. u32 table_idx;
  86. u32 bt_num;
  87. u32 chunk_size;
  88. switch (table->type) {
  89. case HEM_TYPE_QPC:
  90. mhop->buf_chunk_size = 1 << (hr_dev->caps.qpc_buf_pg_sz
  91. + PAGE_SHIFT);
  92. mhop->bt_chunk_size = 1 << (hr_dev->caps.qpc_ba_pg_sz
  93. + PAGE_SHIFT);
  94. mhop->ba_l0_num = hr_dev->caps.qpc_bt_num;
  95. mhop->hop_num = hr_dev->caps.qpc_hop_num;
  96. break;
  97. case HEM_TYPE_MTPT:
  98. mhop->buf_chunk_size = 1 << (hr_dev->caps.mpt_buf_pg_sz
  99. + PAGE_SHIFT);
  100. mhop->bt_chunk_size = 1 << (hr_dev->caps.mpt_ba_pg_sz
  101. + PAGE_SHIFT);
  102. mhop->ba_l0_num = hr_dev->caps.mpt_bt_num;
  103. mhop->hop_num = hr_dev->caps.mpt_hop_num;
  104. break;
  105. case HEM_TYPE_CQC:
  106. mhop->buf_chunk_size = 1 << (hr_dev->caps.cqc_buf_pg_sz
  107. + PAGE_SHIFT);
  108. mhop->bt_chunk_size = 1 << (hr_dev->caps.cqc_ba_pg_sz
  109. + PAGE_SHIFT);
  110. mhop->ba_l0_num = hr_dev->caps.cqc_bt_num;
  111. mhop->hop_num = hr_dev->caps.cqc_hop_num;
  112. break;
  113. case HEM_TYPE_SRQC:
  114. mhop->buf_chunk_size = 1 << (hr_dev->caps.srqc_buf_pg_sz
  115. + PAGE_SHIFT);
  116. mhop->bt_chunk_size = 1 << (hr_dev->caps.srqc_ba_pg_sz
  117. + PAGE_SHIFT);
  118. mhop->ba_l0_num = hr_dev->caps.srqc_bt_num;
  119. mhop->hop_num = hr_dev->caps.srqc_hop_num;
  120. break;
  121. case HEM_TYPE_MTT:
  122. mhop->buf_chunk_size = 1 << (hr_dev->caps.mtt_buf_pg_sz
  123. + PAGE_SHIFT);
  124. mhop->bt_chunk_size = 1 << (hr_dev->caps.mtt_ba_pg_sz
  125. + PAGE_SHIFT);
  126. mhop->ba_l0_num = mhop->bt_chunk_size / 8;
  127. mhop->hop_num = hr_dev->caps.mtt_hop_num;
  128. break;
  129. case HEM_TYPE_CQE:
  130. mhop->buf_chunk_size = 1 << (hr_dev->caps.cqe_buf_pg_sz
  131. + PAGE_SHIFT);
  132. mhop->bt_chunk_size = 1 << (hr_dev->caps.cqe_ba_pg_sz
  133. + PAGE_SHIFT);
  134. mhop->ba_l0_num = mhop->bt_chunk_size / 8;
  135. mhop->hop_num = hr_dev->caps.cqe_hop_num;
  136. break;
  137. default:
  138. dev_err(dev, "Table %d not support multi-hop addressing!\n",
  139. table->type);
  140. return -EINVAL;
  141. }
  142. if (!obj)
  143. return 0;
  144. /*
  145. * QPC/MTPT/CQC/SRQC alloc hem for buffer pages.
  146. * MTT/CQE alloc hem for bt pages.
  147. */
  148. bt_num = hns_roce_get_bt_num(table->type, mhop->hop_num);
  149. chunk_ba_num = mhop->bt_chunk_size / 8;
  150. chunk_size = table->type < HEM_TYPE_MTT ? mhop->buf_chunk_size :
  151. mhop->bt_chunk_size;
  152. table_idx = (*obj & (table->num_obj - 1)) /
  153. (chunk_size / table->obj_size);
  154. switch (bt_num) {
  155. case 3:
  156. mhop->l2_idx = table_idx & (chunk_ba_num - 1);
  157. mhop->l1_idx = table_idx / chunk_ba_num & (chunk_ba_num - 1);
  158. mhop->l0_idx = (table_idx / chunk_ba_num) / chunk_ba_num;
  159. break;
  160. case 2:
  161. mhop->l1_idx = table_idx & (chunk_ba_num - 1);
  162. mhop->l0_idx = table_idx / chunk_ba_num;
  163. break;
  164. case 1:
  165. mhop->l0_idx = table_idx;
  166. break;
  167. default:
  168. dev_err(dev, "Table %d not support hop_num = %d!\n",
  169. table->type, mhop->hop_num);
  170. return -EINVAL;
  171. }
  172. if (mhop->l0_idx >= mhop->ba_l0_num)
  173. mhop->l0_idx %= mhop->ba_l0_num;
  174. return 0;
  175. }
  176. EXPORT_SYMBOL_GPL(hns_roce_calc_hem_mhop);
  177. static struct hns_roce_hem *hns_roce_alloc_hem(struct hns_roce_dev *hr_dev,
  178. int npages,
  179. unsigned long hem_alloc_size,
  180. gfp_t gfp_mask)
  181. {
  182. struct hns_roce_hem_chunk *chunk = NULL;
  183. struct hns_roce_hem *hem;
  184. struct scatterlist *mem;
  185. int order;
  186. void *buf;
  187. WARN_ON(gfp_mask & __GFP_HIGHMEM);
  188. hem = kmalloc(sizeof(*hem),
  189. gfp_mask & ~(__GFP_HIGHMEM | __GFP_NOWARN));
  190. if (!hem)
  191. return NULL;
  192. hem->refcount = 0;
  193. INIT_LIST_HEAD(&hem->chunk_list);
  194. order = get_order(hem_alloc_size);
  195. while (npages > 0) {
  196. if (!chunk) {
  197. chunk = kmalloc(sizeof(*chunk),
  198. gfp_mask & ~(__GFP_HIGHMEM | __GFP_NOWARN));
  199. if (!chunk)
  200. goto fail;
  201. sg_init_table(chunk->mem, HNS_ROCE_HEM_CHUNK_LEN);
  202. chunk->npages = 0;
  203. chunk->nsg = 0;
  204. memset(chunk->buf, 0, sizeof(chunk->buf));
  205. list_add_tail(&chunk->list, &hem->chunk_list);
  206. }
  207. while (1 << order > npages)
  208. --order;
  209. /*
  210. * Alloc memory one time. If failed, don't alloc small block
  211. * memory, directly return fail.
  212. */
  213. mem = &chunk->mem[chunk->npages];
  214. buf = dma_alloc_coherent(hr_dev->dev, PAGE_SIZE << order,
  215. &sg_dma_address(mem), gfp_mask);
  216. if (!buf)
  217. goto fail;
  218. chunk->buf[chunk->npages] = buf;
  219. sg_dma_len(mem) = PAGE_SIZE << order;
  220. ++chunk->npages;
  221. ++chunk->nsg;
  222. npages -= 1 << order;
  223. }
  224. return hem;
  225. fail:
  226. hns_roce_free_hem(hr_dev, hem);
  227. return NULL;
  228. }
  229. void hns_roce_free_hem(struct hns_roce_dev *hr_dev, struct hns_roce_hem *hem)
  230. {
  231. struct hns_roce_hem_chunk *chunk, *tmp;
  232. int i;
  233. if (!hem)
  234. return;
  235. list_for_each_entry_safe(chunk, tmp, &hem->chunk_list, list) {
  236. for (i = 0; i < chunk->npages; ++i)
  237. dma_free_coherent(hr_dev->dev,
  238. sg_dma_len(&chunk->mem[i]),
  239. chunk->buf[i],
  240. sg_dma_address(&chunk->mem[i]));
  241. kfree(chunk);
  242. }
  243. kfree(hem);
  244. }
  245. static int hns_roce_set_hem(struct hns_roce_dev *hr_dev,
  246. struct hns_roce_hem_table *table, unsigned long obj)
  247. {
  248. spinlock_t *lock = &hr_dev->bt_cmd_lock;
  249. struct device *dev = hr_dev->dev;
  250. unsigned long end = 0;
  251. unsigned long flags;
  252. struct hns_roce_hem_iter iter;
  253. void __iomem *bt_cmd;
  254. u32 bt_cmd_h_val = 0;
  255. u32 bt_cmd_val[2];
  256. u32 bt_cmd_l = 0;
  257. u64 bt_ba = 0;
  258. int ret = 0;
  259. /* Find the HEM(Hardware Entry Memory) entry */
  260. unsigned long i = (obj & (table->num_obj - 1)) /
  261. (table->table_chunk_size / table->obj_size);
  262. switch (table->type) {
  263. case HEM_TYPE_QPC:
  264. roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
  265. ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, HEM_TYPE_QPC);
  266. break;
  267. case HEM_TYPE_MTPT:
  268. roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
  269. ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S,
  270. HEM_TYPE_MTPT);
  271. break;
  272. case HEM_TYPE_CQC:
  273. roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
  274. ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S, HEM_TYPE_CQC);
  275. break;
  276. case HEM_TYPE_SRQC:
  277. roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_M,
  278. ROCEE_BT_CMD_H_ROCEE_BT_CMD_MDF_S,
  279. HEM_TYPE_SRQC);
  280. break;
  281. default:
  282. return ret;
  283. }
  284. roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_M,
  285. ROCEE_BT_CMD_H_ROCEE_BT_CMD_IN_MDF_S, obj);
  286. roce_set_bit(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_S, 0);
  287. roce_set_bit(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_HW_SYNS_S, 1);
  288. /* Currently iter only a chunk */
  289. for (hns_roce_hem_first(table->hem[i], &iter);
  290. !hns_roce_hem_last(&iter); hns_roce_hem_next(&iter)) {
  291. bt_ba = hns_roce_hem_addr(&iter) >> DMA_ADDR_T_SHIFT;
  292. spin_lock_irqsave(lock, flags);
  293. bt_cmd = hr_dev->reg_base + ROCEE_BT_CMD_H_REG;
  294. end = msecs_to_jiffies(HW_SYNC_TIMEOUT_MSECS) + jiffies;
  295. while (1) {
  296. if (readl(bt_cmd) >> BT_CMD_SYNC_SHIFT) {
  297. if (!(time_before(jiffies, end))) {
  298. dev_err(dev, "Write bt_cmd err,hw_sync is not zero.\n");
  299. spin_unlock_irqrestore(lock, flags);
  300. return -EBUSY;
  301. }
  302. } else {
  303. break;
  304. }
  305. mdelay(HW_SYNC_SLEEP_TIME_INTERVAL);
  306. }
  307. bt_cmd_l = (u32)bt_ba;
  308. roce_set_field(bt_cmd_h_val, ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_M,
  309. ROCEE_BT_CMD_H_ROCEE_BT_CMD_BA_H_S,
  310. bt_ba >> BT_BA_SHIFT);
  311. bt_cmd_val[0] = bt_cmd_l;
  312. bt_cmd_val[1] = bt_cmd_h_val;
  313. hns_roce_write64_k(bt_cmd_val,
  314. hr_dev->reg_base + ROCEE_BT_CMD_L_REG);
  315. spin_unlock_irqrestore(lock, flags);
  316. }
  317. return ret;
  318. }
  319. static int hns_roce_table_mhop_get(struct hns_roce_dev *hr_dev,
  320. struct hns_roce_hem_table *table,
  321. unsigned long obj)
  322. {
  323. struct device *dev = hr_dev->dev;
  324. struct hns_roce_hem_mhop mhop;
  325. struct hns_roce_hem_iter iter;
  326. u32 buf_chunk_size;
  327. u32 bt_chunk_size;
  328. u32 chunk_ba_num;
  329. u32 hop_num;
  330. u32 size;
  331. u32 bt_num;
  332. u64 hem_idx;
  333. u64 bt_l1_idx = 0;
  334. u64 bt_l0_idx = 0;
  335. u64 bt_ba;
  336. unsigned long mhop_obj = obj;
  337. int bt_l1_allocated = 0;
  338. int bt_l0_allocated = 0;
  339. int step_idx;
  340. int ret;
  341. ret = hns_roce_calc_hem_mhop(hr_dev, table, &mhop_obj, &mhop);
  342. if (ret)
  343. return ret;
  344. buf_chunk_size = mhop.buf_chunk_size;
  345. bt_chunk_size = mhop.bt_chunk_size;
  346. hop_num = mhop.hop_num;
  347. chunk_ba_num = bt_chunk_size / 8;
  348. bt_num = hns_roce_get_bt_num(table->type, hop_num);
  349. switch (bt_num) {
  350. case 3:
  351. hem_idx = mhop.l0_idx * chunk_ba_num * chunk_ba_num +
  352. mhop.l1_idx * chunk_ba_num + mhop.l2_idx;
  353. bt_l1_idx = mhop.l0_idx * chunk_ba_num + mhop.l1_idx;
  354. bt_l0_idx = mhop.l0_idx;
  355. break;
  356. case 2:
  357. hem_idx = mhop.l0_idx * chunk_ba_num + mhop.l1_idx;
  358. bt_l0_idx = mhop.l0_idx;
  359. break;
  360. case 1:
  361. hem_idx = mhop.l0_idx;
  362. break;
  363. default:
  364. dev_err(dev, "Table %d not support hop_num = %d!\n",
  365. table->type, hop_num);
  366. return -EINVAL;
  367. }
  368. mutex_lock(&table->mutex);
  369. if (table->hem[hem_idx]) {
  370. ++table->hem[hem_idx]->refcount;
  371. goto out;
  372. }
  373. /* alloc L1 BA's chunk */
  374. if ((check_whether_bt_num_3(table->type, hop_num) ||
  375. check_whether_bt_num_2(table->type, hop_num)) &&
  376. !table->bt_l0[bt_l0_idx]) {
  377. table->bt_l0[bt_l0_idx] = dma_alloc_coherent(dev, bt_chunk_size,
  378. &(table->bt_l0_dma_addr[bt_l0_idx]),
  379. GFP_KERNEL);
  380. if (!table->bt_l0[bt_l0_idx]) {
  381. ret = -ENOMEM;
  382. goto out;
  383. }
  384. bt_l0_allocated = 1;
  385. /* set base address to hardware */
  386. if (table->type < HEM_TYPE_MTT) {
  387. step_idx = 0;
  388. if (hr_dev->hw->set_hem(hr_dev, table, obj, step_idx)) {
  389. ret = -ENODEV;
  390. dev_err(dev, "set HEM base address to HW failed!\n");
  391. goto err_dma_alloc_l1;
  392. }
  393. }
  394. }
  395. /* alloc L2 BA's chunk */
  396. if (check_whether_bt_num_3(table->type, hop_num) &&
  397. !table->bt_l1[bt_l1_idx]) {
  398. table->bt_l1[bt_l1_idx] = dma_alloc_coherent(dev, bt_chunk_size,
  399. &(table->bt_l1_dma_addr[bt_l1_idx]),
  400. GFP_KERNEL);
  401. if (!table->bt_l1[bt_l1_idx]) {
  402. ret = -ENOMEM;
  403. goto err_dma_alloc_l1;
  404. }
  405. bt_l1_allocated = 1;
  406. *(table->bt_l0[bt_l0_idx] + mhop.l1_idx) =
  407. table->bt_l1_dma_addr[bt_l1_idx];
  408. /* set base address to hardware */
  409. step_idx = 1;
  410. if (hr_dev->hw->set_hem(hr_dev, table, obj, step_idx)) {
  411. ret = -ENODEV;
  412. dev_err(dev, "set HEM base address to HW failed!\n");
  413. goto err_alloc_hem_buf;
  414. }
  415. }
  416. /*
  417. * alloc buffer space chunk for QPC/MTPT/CQC/SRQC.
  418. * alloc bt space chunk for MTT/CQE.
  419. */
  420. size = table->type < HEM_TYPE_MTT ? buf_chunk_size : bt_chunk_size;
  421. table->hem[hem_idx] = hns_roce_alloc_hem(hr_dev,
  422. size >> PAGE_SHIFT,
  423. size,
  424. (table->lowmem ? GFP_KERNEL :
  425. GFP_HIGHUSER) | __GFP_NOWARN);
  426. if (!table->hem[hem_idx]) {
  427. ret = -ENOMEM;
  428. goto err_alloc_hem_buf;
  429. }
  430. hns_roce_hem_first(table->hem[hem_idx], &iter);
  431. bt_ba = hns_roce_hem_addr(&iter);
  432. if (table->type < HEM_TYPE_MTT) {
  433. if (hop_num == 2) {
  434. *(table->bt_l1[bt_l1_idx] + mhop.l2_idx) = bt_ba;
  435. step_idx = 2;
  436. } else if (hop_num == 1) {
  437. *(table->bt_l0[bt_l0_idx] + mhop.l1_idx) = bt_ba;
  438. step_idx = 1;
  439. } else if (hop_num == HNS_ROCE_HOP_NUM_0) {
  440. step_idx = 0;
  441. } else {
  442. ret = -EINVAL;
  443. goto err_dma_alloc_l1;
  444. }
  445. /* set HEM base address to hardware */
  446. if (hr_dev->hw->set_hem(hr_dev, table, obj, step_idx)) {
  447. ret = -ENODEV;
  448. dev_err(dev, "set HEM base address to HW failed!\n");
  449. goto err_alloc_hem_buf;
  450. }
  451. } else if (hop_num == 2) {
  452. *(table->bt_l0[bt_l0_idx] + mhop.l1_idx) = bt_ba;
  453. }
  454. ++table->hem[hem_idx]->refcount;
  455. goto out;
  456. err_alloc_hem_buf:
  457. if (bt_l1_allocated) {
  458. dma_free_coherent(dev, bt_chunk_size, table->bt_l1[bt_l1_idx],
  459. table->bt_l1_dma_addr[bt_l1_idx]);
  460. table->bt_l1[bt_l1_idx] = NULL;
  461. }
  462. err_dma_alloc_l1:
  463. if (bt_l0_allocated) {
  464. dma_free_coherent(dev, bt_chunk_size, table->bt_l0[bt_l0_idx],
  465. table->bt_l0_dma_addr[bt_l0_idx]);
  466. table->bt_l0[bt_l0_idx] = NULL;
  467. }
  468. out:
  469. mutex_unlock(&table->mutex);
  470. return ret;
  471. }
  472. int hns_roce_table_get(struct hns_roce_dev *hr_dev,
  473. struct hns_roce_hem_table *table, unsigned long obj)
  474. {
  475. struct device *dev = hr_dev->dev;
  476. int ret = 0;
  477. unsigned long i;
  478. if (hns_roce_check_whether_mhop(hr_dev, table->type))
  479. return hns_roce_table_mhop_get(hr_dev, table, obj);
  480. i = (obj & (table->num_obj - 1)) / (table->table_chunk_size /
  481. table->obj_size);
  482. mutex_lock(&table->mutex);
  483. if (table->hem[i]) {
  484. ++table->hem[i]->refcount;
  485. goto out;
  486. }
  487. table->hem[i] = hns_roce_alloc_hem(hr_dev,
  488. table->table_chunk_size >> PAGE_SHIFT,
  489. table->table_chunk_size,
  490. (table->lowmem ? GFP_KERNEL :
  491. GFP_HIGHUSER) | __GFP_NOWARN);
  492. if (!table->hem[i]) {
  493. ret = -ENOMEM;
  494. goto out;
  495. }
  496. /* Set HEM base address(128K/page, pa) to Hardware */
  497. if (hns_roce_set_hem(hr_dev, table, obj)) {
  498. hns_roce_free_hem(hr_dev, table->hem[i]);
  499. table->hem[i] = NULL;
  500. ret = -ENODEV;
  501. dev_err(dev, "set HEM base address to HW failed.\n");
  502. goto out;
  503. }
  504. ++table->hem[i]->refcount;
  505. out:
  506. mutex_unlock(&table->mutex);
  507. return ret;
  508. }
  509. static void hns_roce_table_mhop_put(struct hns_roce_dev *hr_dev,
  510. struct hns_roce_hem_table *table,
  511. unsigned long obj,
  512. int check_refcount)
  513. {
  514. struct device *dev = hr_dev->dev;
  515. struct hns_roce_hem_mhop mhop;
  516. unsigned long mhop_obj = obj;
  517. u32 bt_chunk_size;
  518. u32 chunk_ba_num;
  519. u32 hop_num;
  520. u32 start_idx;
  521. u32 bt_num;
  522. u64 hem_idx;
  523. u64 bt_l1_idx = 0;
  524. int ret;
  525. ret = hns_roce_calc_hem_mhop(hr_dev, table, &mhop_obj, &mhop);
  526. if (ret)
  527. return;
  528. bt_chunk_size = mhop.bt_chunk_size;
  529. hop_num = mhop.hop_num;
  530. chunk_ba_num = bt_chunk_size / 8;
  531. bt_num = hns_roce_get_bt_num(table->type, hop_num);
  532. switch (bt_num) {
  533. case 3:
  534. hem_idx = mhop.l0_idx * chunk_ba_num * chunk_ba_num +
  535. mhop.l1_idx * chunk_ba_num + mhop.l2_idx;
  536. bt_l1_idx = mhop.l0_idx * chunk_ba_num + mhop.l1_idx;
  537. break;
  538. case 2:
  539. hem_idx = mhop.l0_idx * chunk_ba_num + mhop.l1_idx;
  540. break;
  541. case 1:
  542. hem_idx = mhop.l0_idx;
  543. break;
  544. default:
  545. dev_err(dev, "Table %d not support hop_num = %d!\n",
  546. table->type, hop_num);
  547. return;
  548. }
  549. mutex_lock(&table->mutex);
  550. if (check_refcount && (--table->hem[hem_idx]->refcount > 0)) {
  551. mutex_unlock(&table->mutex);
  552. return;
  553. }
  554. if (table->type < HEM_TYPE_MTT && hop_num == 1) {
  555. if (hr_dev->hw->clear_hem(hr_dev, table, obj, 1))
  556. dev_warn(dev, "Clear HEM base address failed.\n");
  557. } else if (table->type < HEM_TYPE_MTT && hop_num == 2) {
  558. if (hr_dev->hw->clear_hem(hr_dev, table, obj, 2))
  559. dev_warn(dev, "Clear HEM base address failed.\n");
  560. } else if (table->type < HEM_TYPE_MTT &&
  561. hop_num == HNS_ROCE_HOP_NUM_0) {
  562. if (hr_dev->hw->clear_hem(hr_dev, table, obj, 0))
  563. dev_warn(dev, "Clear HEM base address failed.\n");
  564. }
  565. /*
  566. * free buffer space chunk for QPC/MTPT/CQC/SRQC.
  567. * free bt space chunk for MTT/CQE.
  568. */
  569. hns_roce_free_hem(hr_dev, table->hem[hem_idx]);
  570. table->hem[hem_idx] = NULL;
  571. if (check_whether_bt_num_2(table->type, hop_num)) {
  572. start_idx = mhop.l0_idx * chunk_ba_num;
  573. if (hns_roce_check_hem_null(table->hem, start_idx,
  574. chunk_ba_num)) {
  575. if (table->type < HEM_TYPE_MTT &&
  576. hr_dev->hw->clear_hem(hr_dev, table, obj, 0))
  577. dev_warn(dev, "Clear HEM base address failed.\n");
  578. dma_free_coherent(dev, bt_chunk_size,
  579. table->bt_l0[mhop.l0_idx],
  580. table->bt_l0_dma_addr[mhop.l0_idx]);
  581. table->bt_l0[mhop.l0_idx] = NULL;
  582. }
  583. } else if (check_whether_bt_num_3(table->type, hop_num)) {
  584. start_idx = mhop.l0_idx * chunk_ba_num * chunk_ba_num +
  585. mhop.l1_idx * chunk_ba_num;
  586. if (hns_roce_check_hem_null(table->hem, start_idx,
  587. chunk_ba_num)) {
  588. if (hr_dev->hw->clear_hem(hr_dev, table, obj, 1))
  589. dev_warn(dev, "Clear HEM base address failed.\n");
  590. dma_free_coherent(dev, bt_chunk_size,
  591. table->bt_l1[bt_l1_idx],
  592. table->bt_l1_dma_addr[bt_l1_idx]);
  593. table->bt_l1[bt_l1_idx] = NULL;
  594. start_idx = mhop.l0_idx * chunk_ba_num;
  595. if (hns_roce_check_bt_null(table->bt_l1, start_idx,
  596. chunk_ba_num)) {
  597. if (hr_dev->hw->clear_hem(hr_dev, table, obj,
  598. 0))
  599. dev_warn(dev, "Clear HEM base address failed.\n");
  600. dma_free_coherent(dev, bt_chunk_size,
  601. table->bt_l0[mhop.l0_idx],
  602. table->bt_l0_dma_addr[mhop.l0_idx]);
  603. table->bt_l0[mhop.l0_idx] = NULL;
  604. }
  605. }
  606. }
  607. mutex_unlock(&table->mutex);
  608. }
  609. void hns_roce_table_put(struct hns_roce_dev *hr_dev,
  610. struct hns_roce_hem_table *table, unsigned long obj)
  611. {
  612. struct device *dev = hr_dev->dev;
  613. unsigned long i;
  614. if (hns_roce_check_whether_mhop(hr_dev, table->type)) {
  615. hns_roce_table_mhop_put(hr_dev, table, obj, 1);
  616. return;
  617. }
  618. i = (obj & (table->num_obj - 1)) /
  619. (table->table_chunk_size / table->obj_size);
  620. mutex_lock(&table->mutex);
  621. if (--table->hem[i]->refcount == 0) {
  622. /* Clear HEM base address */
  623. if (hr_dev->hw->clear_hem(hr_dev, table, obj, 0))
  624. dev_warn(dev, "Clear HEM base address failed.\n");
  625. hns_roce_free_hem(hr_dev, table->hem[i]);
  626. table->hem[i] = NULL;
  627. }
  628. mutex_unlock(&table->mutex);
  629. }
  630. void *hns_roce_table_find(struct hns_roce_dev *hr_dev,
  631. struct hns_roce_hem_table *table,
  632. unsigned long obj, dma_addr_t *dma_handle)
  633. {
  634. struct hns_roce_hem_chunk *chunk;
  635. struct hns_roce_hem_mhop mhop;
  636. struct hns_roce_hem *hem;
  637. void *addr = NULL;
  638. unsigned long mhop_obj = obj;
  639. unsigned long obj_per_chunk;
  640. unsigned long idx_offset;
  641. int offset, dma_offset;
  642. int length;
  643. int i, j;
  644. u32 hem_idx = 0;
  645. if (!table->lowmem)
  646. return NULL;
  647. mutex_lock(&table->mutex);
  648. if (!hns_roce_check_whether_mhop(hr_dev, table->type)) {
  649. obj_per_chunk = table->table_chunk_size / table->obj_size;
  650. hem = table->hem[(obj & (table->num_obj - 1)) / obj_per_chunk];
  651. idx_offset = (obj & (table->num_obj - 1)) % obj_per_chunk;
  652. dma_offset = offset = idx_offset * table->obj_size;
  653. } else {
  654. hns_roce_calc_hem_mhop(hr_dev, table, &mhop_obj, &mhop);
  655. /* mtt mhop */
  656. i = mhop.l0_idx;
  657. j = mhop.l1_idx;
  658. if (mhop.hop_num == 2)
  659. hem_idx = i * (mhop.bt_chunk_size / 8) + j;
  660. else if (mhop.hop_num == 1 ||
  661. mhop.hop_num == HNS_ROCE_HOP_NUM_0)
  662. hem_idx = i;
  663. hem = table->hem[hem_idx];
  664. dma_offset = offset = (obj & (table->num_obj - 1)) *
  665. table->obj_size % mhop.bt_chunk_size;
  666. if (mhop.hop_num == 2)
  667. dma_offset = offset = 0;
  668. }
  669. if (!hem)
  670. goto out;
  671. list_for_each_entry(chunk, &hem->chunk_list, list) {
  672. for (i = 0; i < chunk->npages; ++i) {
  673. length = sg_dma_len(&chunk->mem[i]);
  674. if (dma_handle && dma_offset >= 0) {
  675. if (length > (u32)dma_offset)
  676. *dma_handle = sg_dma_address(
  677. &chunk->mem[i]) + dma_offset;
  678. dma_offset -= length;
  679. }
  680. if (length > (u32)offset) {
  681. addr = chunk->buf[i] + offset;
  682. goto out;
  683. }
  684. offset -= length;
  685. }
  686. }
  687. out:
  688. mutex_unlock(&table->mutex);
  689. return addr;
  690. }
  691. EXPORT_SYMBOL_GPL(hns_roce_table_find);
  692. int hns_roce_table_get_range(struct hns_roce_dev *hr_dev,
  693. struct hns_roce_hem_table *table,
  694. unsigned long start, unsigned long end)
  695. {
  696. struct hns_roce_hem_mhop mhop;
  697. unsigned long inc = table->table_chunk_size / table->obj_size;
  698. unsigned long i;
  699. int ret;
  700. if (hns_roce_check_whether_mhop(hr_dev, table->type)) {
  701. hns_roce_calc_hem_mhop(hr_dev, table, NULL, &mhop);
  702. inc = mhop.bt_chunk_size / table->obj_size;
  703. }
  704. /* Allocate MTT entry memory according to chunk(128K) */
  705. for (i = start; i <= end; i += inc) {
  706. ret = hns_roce_table_get(hr_dev, table, i);
  707. if (ret)
  708. goto fail;
  709. }
  710. return 0;
  711. fail:
  712. while (i > start) {
  713. i -= inc;
  714. hns_roce_table_put(hr_dev, table, i);
  715. }
  716. return ret;
  717. }
  718. void hns_roce_table_put_range(struct hns_roce_dev *hr_dev,
  719. struct hns_roce_hem_table *table,
  720. unsigned long start, unsigned long end)
  721. {
  722. struct hns_roce_hem_mhop mhop;
  723. unsigned long inc = table->table_chunk_size / table->obj_size;
  724. unsigned long i;
  725. if (hns_roce_check_whether_mhop(hr_dev, table->type)) {
  726. hns_roce_calc_hem_mhop(hr_dev, table, NULL, &mhop);
  727. inc = mhop.bt_chunk_size / table->obj_size;
  728. }
  729. for (i = start; i <= end; i += inc)
  730. hns_roce_table_put(hr_dev, table, i);
  731. }
  732. int hns_roce_init_hem_table(struct hns_roce_dev *hr_dev,
  733. struct hns_roce_hem_table *table, u32 type,
  734. unsigned long obj_size, unsigned long nobj,
  735. int use_lowmem)
  736. {
  737. struct device *dev = hr_dev->dev;
  738. unsigned long obj_per_chunk;
  739. unsigned long num_hem;
  740. if (!hns_roce_check_whether_mhop(hr_dev, type)) {
  741. table->table_chunk_size = hr_dev->caps.chunk_sz;
  742. obj_per_chunk = table->table_chunk_size / obj_size;
  743. num_hem = (nobj + obj_per_chunk - 1) / obj_per_chunk;
  744. table->hem = kcalloc(num_hem, sizeof(*table->hem), GFP_KERNEL);
  745. if (!table->hem)
  746. return -ENOMEM;
  747. } else {
  748. unsigned long buf_chunk_size;
  749. unsigned long bt_chunk_size;
  750. unsigned long bt_chunk_num;
  751. unsigned long num_bt_l0 = 0;
  752. u32 hop_num;
  753. switch (type) {
  754. case HEM_TYPE_QPC:
  755. buf_chunk_size = 1 << (hr_dev->caps.qpc_buf_pg_sz
  756. + PAGE_SHIFT);
  757. bt_chunk_size = 1 << (hr_dev->caps.qpc_ba_pg_sz
  758. + PAGE_SHIFT);
  759. num_bt_l0 = hr_dev->caps.qpc_bt_num;
  760. hop_num = hr_dev->caps.qpc_hop_num;
  761. break;
  762. case HEM_TYPE_MTPT:
  763. buf_chunk_size = 1 << (hr_dev->caps.mpt_buf_pg_sz
  764. + PAGE_SHIFT);
  765. bt_chunk_size = 1 << (hr_dev->caps.mpt_ba_pg_sz
  766. + PAGE_SHIFT);
  767. num_bt_l0 = hr_dev->caps.mpt_bt_num;
  768. hop_num = hr_dev->caps.mpt_hop_num;
  769. break;
  770. case HEM_TYPE_CQC:
  771. buf_chunk_size = 1 << (hr_dev->caps.cqc_buf_pg_sz
  772. + PAGE_SHIFT);
  773. bt_chunk_size = 1 << (hr_dev->caps.cqc_ba_pg_sz
  774. + PAGE_SHIFT);
  775. num_bt_l0 = hr_dev->caps.cqc_bt_num;
  776. hop_num = hr_dev->caps.cqc_hop_num;
  777. break;
  778. case HEM_TYPE_SRQC:
  779. buf_chunk_size = 1 << (hr_dev->caps.srqc_buf_pg_sz
  780. + PAGE_SHIFT);
  781. bt_chunk_size = 1 << (hr_dev->caps.srqc_ba_pg_sz
  782. + PAGE_SHIFT);
  783. num_bt_l0 = hr_dev->caps.srqc_bt_num;
  784. hop_num = hr_dev->caps.srqc_hop_num;
  785. break;
  786. case HEM_TYPE_MTT:
  787. buf_chunk_size = 1 << (hr_dev->caps.mtt_ba_pg_sz
  788. + PAGE_SHIFT);
  789. bt_chunk_size = buf_chunk_size;
  790. hop_num = hr_dev->caps.mtt_hop_num;
  791. break;
  792. case HEM_TYPE_CQE:
  793. buf_chunk_size = 1 << (hr_dev->caps.cqe_ba_pg_sz
  794. + PAGE_SHIFT);
  795. bt_chunk_size = buf_chunk_size;
  796. hop_num = hr_dev->caps.cqe_hop_num;
  797. break;
  798. default:
  799. dev_err(dev,
  800. "Table %d not support to init hem table here!\n",
  801. type);
  802. return -EINVAL;
  803. }
  804. obj_per_chunk = buf_chunk_size / obj_size;
  805. num_hem = (nobj + obj_per_chunk - 1) / obj_per_chunk;
  806. bt_chunk_num = bt_chunk_size / 8;
  807. if (type >= HEM_TYPE_MTT)
  808. num_bt_l0 = bt_chunk_num;
  809. table->hem = kcalloc(num_hem, sizeof(*table->hem),
  810. GFP_KERNEL);
  811. if (!table->hem)
  812. goto err_kcalloc_hem_buf;
  813. if (check_whether_bt_num_3(type, hop_num)) {
  814. unsigned long num_bt_l1;
  815. num_bt_l1 = (num_hem + bt_chunk_num - 1) /
  816. bt_chunk_num;
  817. table->bt_l1 = kcalloc(num_bt_l1,
  818. sizeof(*table->bt_l1),
  819. GFP_KERNEL);
  820. if (!table->bt_l1)
  821. goto err_kcalloc_bt_l1;
  822. table->bt_l1_dma_addr = kcalloc(num_bt_l1,
  823. sizeof(*table->bt_l1_dma_addr),
  824. GFP_KERNEL);
  825. if (!table->bt_l1_dma_addr)
  826. goto err_kcalloc_l1_dma;
  827. }
  828. if (check_whether_bt_num_2(type, hop_num) ||
  829. check_whether_bt_num_3(type, hop_num)) {
  830. table->bt_l0 = kcalloc(num_bt_l0, sizeof(*table->bt_l0),
  831. GFP_KERNEL);
  832. if (!table->bt_l0)
  833. goto err_kcalloc_bt_l0;
  834. table->bt_l0_dma_addr = kcalloc(num_bt_l0,
  835. sizeof(*table->bt_l0_dma_addr),
  836. GFP_KERNEL);
  837. if (!table->bt_l0_dma_addr)
  838. goto err_kcalloc_l0_dma;
  839. }
  840. }
  841. table->type = type;
  842. table->num_hem = num_hem;
  843. table->num_obj = nobj;
  844. table->obj_size = obj_size;
  845. table->lowmem = use_lowmem;
  846. mutex_init(&table->mutex);
  847. return 0;
  848. err_kcalloc_l0_dma:
  849. kfree(table->bt_l0);
  850. table->bt_l0 = NULL;
  851. err_kcalloc_bt_l0:
  852. kfree(table->bt_l1_dma_addr);
  853. table->bt_l1_dma_addr = NULL;
  854. err_kcalloc_l1_dma:
  855. kfree(table->bt_l1);
  856. table->bt_l1 = NULL;
  857. err_kcalloc_bt_l1:
  858. kfree(table->hem);
  859. table->hem = NULL;
  860. err_kcalloc_hem_buf:
  861. return -ENOMEM;
  862. }
  863. static void hns_roce_cleanup_mhop_hem_table(struct hns_roce_dev *hr_dev,
  864. struct hns_roce_hem_table *table)
  865. {
  866. struct hns_roce_hem_mhop mhop;
  867. u32 buf_chunk_size;
  868. int i;
  869. u64 obj;
  870. hns_roce_calc_hem_mhop(hr_dev, table, NULL, &mhop);
  871. buf_chunk_size = table->type < HEM_TYPE_MTT ? mhop.buf_chunk_size :
  872. mhop.bt_chunk_size;
  873. for (i = 0; i < table->num_hem; ++i) {
  874. obj = i * buf_chunk_size / table->obj_size;
  875. if (table->hem[i])
  876. hns_roce_table_mhop_put(hr_dev, table, obj, 0);
  877. }
  878. kfree(table->hem);
  879. table->hem = NULL;
  880. kfree(table->bt_l1);
  881. table->bt_l1 = NULL;
  882. kfree(table->bt_l1_dma_addr);
  883. table->bt_l1_dma_addr = NULL;
  884. kfree(table->bt_l0);
  885. table->bt_l0 = NULL;
  886. kfree(table->bt_l0_dma_addr);
  887. table->bt_l0_dma_addr = NULL;
  888. }
  889. void hns_roce_cleanup_hem_table(struct hns_roce_dev *hr_dev,
  890. struct hns_roce_hem_table *table)
  891. {
  892. struct device *dev = hr_dev->dev;
  893. unsigned long i;
  894. if (hns_roce_check_whether_mhop(hr_dev, table->type)) {
  895. hns_roce_cleanup_mhop_hem_table(hr_dev, table);
  896. return;
  897. }
  898. for (i = 0; i < table->num_hem; ++i)
  899. if (table->hem[i]) {
  900. if (hr_dev->hw->clear_hem(hr_dev, table,
  901. i * table->table_chunk_size / table->obj_size, 0))
  902. dev_err(dev, "Clear HEM base address failed.\n");
  903. hns_roce_free_hem(hr_dev, table->hem[i]);
  904. }
  905. kfree(table->hem);
  906. }
  907. void hns_roce_cleanup_hem(struct hns_roce_dev *hr_dev)
  908. {
  909. hns_roce_cleanup_hem_table(hr_dev, &hr_dev->cq_table.table);
  910. if (hr_dev->caps.trrl_entry_sz)
  911. hns_roce_cleanup_hem_table(hr_dev,
  912. &hr_dev->qp_table.trrl_table);
  913. hns_roce_cleanup_hem_table(hr_dev, &hr_dev->qp_table.irrl_table);
  914. hns_roce_cleanup_hem_table(hr_dev, &hr_dev->qp_table.qp_table);
  915. hns_roce_cleanup_hem_table(hr_dev, &hr_dev->mr_table.mtpt_table);
  916. if (hns_roce_check_whether_mhop(hr_dev, HEM_TYPE_CQE))
  917. hns_roce_cleanup_hem_table(hr_dev,
  918. &hr_dev->mr_table.mtt_cqe_table);
  919. hns_roce_cleanup_hem_table(hr_dev, &hr_dev->mr_table.mtt_table);
  920. }