qplib_sp.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838
  1. /*
  2. * Broadcom NetXtreme-E RoCE driver.
  3. *
  4. * Copyright (c) 2016 - 2017, Broadcom. All rights reserved. The term
  5. * Broadcom refers to Broadcom Limited and/or its subsidiaries.
  6. *
  7. * This software is available to you under a choice of one of two
  8. * licenses. You may choose to be licensed under the terms of the GNU
  9. * General Public License (GPL) Version 2, available from the file
  10. * COPYING in the main directory of this source tree, or the
  11. * BSD license below:
  12. *
  13. * Redistribution and use in source and binary forms, with or without
  14. * modification, are permitted provided that the following conditions
  15. * are met:
  16. *
  17. * 1. Redistributions of source code must retain the above copyright
  18. * notice, this list of conditions and the following disclaimer.
  19. * 2. Redistributions in binary form must reproduce the above copyright
  20. * notice, this list of conditions and the following disclaimer in
  21. * the documentation and/or other materials provided with the
  22. * distribution.
  23. *
  24. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
  25. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  26. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  27. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
  28. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  29. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  30. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  31. * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  32. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  33. * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  34. * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35. *
  36. * Description: Slow Path Operators
  37. */
  38. #include <linux/interrupt.h>
  39. #include <linux/spinlock.h>
  40. #include <linux/sched.h>
  41. #include <linux/pci.h>
  42. #include "roce_hsi.h"
  43. #include "qplib_res.h"
  44. #include "qplib_rcfw.h"
  45. #include "qplib_sp.h"
  46. const struct bnxt_qplib_gid bnxt_qplib_gid_zero = {{ 0, 0, 0, 0, 0, 0, 0, 0,
  47. 0, 0, 0, 0, 0, 0, 0, 0 } };
  48. /* Device */
  49. int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw,
  50. struct bnxt_qplib_dev_attr *attr)
  51. {
  52. struct cmdq_query_func req;
  53. struct creq_query_func_resp *resp;
  54. struct creq_query_func_resp_sb *sb;
  55. u16 cmd_flags = 0;
  56. u32 temp;
  57. u8 *tqm_alloc;
  58. int i;
  59. RCFW_CMD_PREP(req, QUERY_FUNC, cmd_flags);
  60. req.resp_size = sizeof(*sb) / BNXT_QPLIB_CMDQE_UNITS;
  61. resp = (struct creq_query_func_resp *)
  62. bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void **)&sb,
  63. 0);
  64. if (!resp) {
  65. dev_err(&rcfw->pdev->dev, "QPLIB: SP: QUERY_FUNC send failed");
  66. return -EINVAL;
  67. }
  68. if (!bnxt_qplib_rcfw_wait_for_resp(rcfw, le16_to_cpu(req.cookie))) {
  69. /* Cmd timed out */
  70. dev_err(&rcfw->pdev->dev, "QPLIB: SP: QUERY_FUNC timed out");
  71. return -ETIMEDOUT;
  72. }
  73. if (resp->status ||
  74. le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
  75. dev_err(&rcfw->pdev->dev, "QPLIB: SP: QUERY_FUNC failed ");
  76. dev_err(&rcfw->pdev->dev,
  77. "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
  78. resp->status, le16_to_cpu(req.cookie),
  79. le16_to_cpu(resp->cookie));
  80. return -EINVAL;
  81. }
  82. /* Extract the context from the side buffer */
  83. attr->max_qp = le32_to_cpu(sb->max_qp);
  84. attr->max_qp_rd_atom =
  85. sb->max_qp_rd_atom > BNXT_QPLIB_MAX_OUT_RD_ATOM ?
  86. BNXT_QPLIB_MAX_OUT_RD_ATOM : sb->max_qp_rd_atom;
  87. attr->max_qp_init_rd_atom =
  88. sb->max_qp_init_rd_atom > BNXT_QPLIB_MAX_OUT_RD_ATOM ?
  89. BNXT_QPLIB_MAX_OUT_RD_ATOM : sb->max_qp_init_rd_atom;
  90. attr->max_qp_wqes = le16_to_cpu(sb->max_qp_wr);
  91. attr->max_qp_sges = sb->max_sge;
  92. attr->max_cq = le32_to_cpu(sb->max_cq);
  93. attr->max_cq_wqes = le32_to_cpu(sb->max_cqe);
  94. attr->max_cq_sges = attr->max_qp_sges;
  95. attr->max_mr = le32_to_cpu(sb->max_mr);
  96. attr->max_mw = le32_to_cpu(sb->max_mw);
  97. attr->max_mr_size = le64_to_cpu(sb->max_mr_size);
  98. attr->max_pd = 64 * 1024;
  99. attr->max_raw_ethy_qp = le32_to_cpu(sb->max_raw_eth_qp);
  100. attr->max_ah = le32_to_cpu(sb->max_ah);
  101. attr->max_fmr = le32_to_cpu(sb->max_fmr);
  102. attr->max_map_per_fmr = sb->max_map_per_fmr;
  103. attr->max_srq = le16_to_cpu(sb->max_srq);
  104. attr->max_srq_wqes = le32_to_cpu(sb->max_srq_wr) - 1;
  105. attr->max_srq_sges = sb->max_srq_sge;
  106. /* Bono only reports 1 PKEY for now, but it can support > 1 */
  107. attr->max_pkey = le32_to_cpu(sb->max_pkeys);
  108. attr->max_inline_data = le32_to_cpu(sb->max_inline_data);
  109. attr->l2_db_size = (sb->l2_db_space_size + 1) * PAGE_SIZE;
  110. attr->max_sgid = le32_to_cpu(sb->max_gid);
  111. strlcpy(attr->fw_ver, "20.6.28.0", sizeof(attr->fw_ver));
  112. for (i = 0; i < MAX_TQM_ALLOC_REQ / 4; i++) {
  113. temp = le32_to_cpu(sb->tqm_alloc_reqs[i]);
  114. tqm_alloc = (u8 *)&temp;
  115. attr->tqm_alloc_reqs[i * 4] = *tqm_alloc;
  116. attr->tqm_alloc_reqs[i * 4 + 1] = *(++tqm_alloc);
  117. attr->tqm_alloc_reqs[i * 4 + 2] = *(++tqm_alloc);
  118. attr->tqm_alloc_reqs[i * 4 + 3] = *(++tqm_alloc);
  119. }
  120. return 0;
  121. }
  122. /* SGID */
  123. int bnxt_qplib_get_sgid(struct bnxt_qplib_res *res,
  124. struct bnxt_qplib_sgid_tbl *sgid_tbl, int index,
  125. struct bnxt_qplib_gid *gid)
  126. {
  127. if (index > sgid_tbl->max) {
  128. dev_err(&res->pdev->dev,
  129. "QPLIB: Index %d exceeded SGID table max (%d)",
  130. index, sgid_tbl->max);
  131. return -EINVAL;
  132. }
  133. memcpy(gid, &sgid_tbl->tbl[index], sizeof(*gid));
  134. return 0;
  135. }
  136. int bnxt_qplib_del_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
  137. struct bnxt_qplib_gid *gid, bool update)
  138. {
  139. struct bnxt_qplib_res *res = to_bnxt_qplib(sgid_tbl,
  140. struct bnxt_qplib_res,
  141. sgid_tbl);
  142. struct bnxt_qplib_rcfw *rcfw = res->rcfw;
  143. int index;
  144. if (!sgid_tbl) {
  145. dev_err(&res->pdev->dev, "QPLIB: SGID table not allocated");
  146. return -EINVAL;
  147. }
  148. /* Do we need a sgid_lock here? */
  149. if (!sgid_tbl->active) {
  150. dev_err(&res->pdev->dev,
  151. "QPLIB: SGID table has no active entries");
  152. return -ENOMEM;
  153. }
  154. for (index = 0; index < sgid_tbl->max; index++) {
  155. if (!memcmp(&sgid_tbl->tbl[index], gid, sizeof(*gid)))
  156. break;
  157. }
  158. if (index == sgid_tbl->max) {
  159. dev_warn(&res->pdev->dev, "GID not found in the SGID table");
  160. return 0;
  161. }
  162. /* Remove GID from the SGID table */
  163. if (update) {
  164. struct cmdq_delete_gid req;
  165. struct creq_delete_gid_resp *resp;
  166. u16 cmd_flags = 0;
  167. RCFW_CMD_PREP(req, DELETE_GID, cmd_flags);
  168. if (sgid_tbl->hw_id[index] == 0xFFFF) {
  169. dev_err(&res->pdev->dev,
  170. "QPLIB: GID entry contains an invalid HW id");
  171. return -EINVAL;
  172. }
  173. req.gid_index = cpu_to_le16(sgid_tbl->hw_id[index]);
  174. resp = (struct creq_delete_gid_resp *)
  175. bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, NULL,
  176. 0);
  177. if (!resp) {
  178. dev_err(&res->pdev->dev,
  179. "QPLIB: SP: DELETE_GID send failed");
  180. return -EINVAL;
  181. }
  182. if (!bnxt_qplib_rcfw_wait_for_resp(rcfw,
  183. le16_to_cpu(req.cookie))) {
  184. /* Cmd timed out */
  185. dev_err(&res->pdev->dev,
  186. "QPLIB: SP: DELETE_GID timed out");
  187. return -ETIMEDOUT;
  188. }
  189. if (resp->status ||
  190. le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
  191. dev_err(&res->pdev->dev,
  192. "QPLIB: SP: DELETE_GID failed ");
  193. dev_err(&res->pdev->dev,
  194. "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
  195. resp->status, le16_to_cpu(req.cookie),
  196. le16_to_cpu(resp->cookie));
  197. return -EINVAL;
  198. }
  199. }
  200. memcpy(&sgid_tbl->tbl[index], &bnxt_qplib_gid_zero,
  201. sizeof(bnxt_qplib_gid_zero));
  202. sgid_tbl->active--;
  203. dev_dbg(&res->pdev->dev,
  204. "QPLIB: SGID deleted hw_id[0x%x] = 0x%x active = 0x%x",
  205. index, sgid_tbl->hw_id[index], sgid_tbl->active);
  206. sgid_tbl->hw_id[index] = (u16)-1;
  207. /* unlock */
  208. return 0;
  209. }
  210. int bnxt_qplib_add_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
  211. struct bnxt_qplib_gid *gid, u8 *smac, u16 vlan_id,
  212. bool update, u32 *index)
  213. {
  214. struct bnxt_qplib_res *res = to_bnxt_qplib(sgid_tbl,
  215. struct bnxt_qplib_res,
  216. sgid_tbl);
  217. struct bnxt_qplib_rcfw *rcfw = res->rcfw;
  218. int i, free_idx, rc = 0;
  219. if (!sgid_tbl) {
  220. dev_err(&res->pdev->dev, "QPLIB: SGID table not allocated");
  221. return -EINVAL;
  222. }
  223. /* Do we need a sgid_lock here? */
  224. if (sgid_tbl->active == sgid_tbl->max) {
  225. dev_err(&res->pdev->dev, "QPLIB: SGID table is full");
  226. return -ENOMEM;
  227. }
  228. free_idx = sgid_tbl->max;
  229. for (i = 0; i < sgid_tbl->max; i++) {
  230. if (!memcmp(&sgid_tbl->tbl[i], gid, sizeof(*gid))) {
  231. dev_dbg(&res->pdev->dev,
  232. "QPLIB: SGID entry already exist in entry %d!",
  233. i);
  234. *index = i;
  235. return -EALREADY;
  236. } else if (!memcmp(&sgid_tbl->tbl[i], &bnxt_qplib_gid_zero,
  237. sizeof(bnxt_qplib_gid_zero)) &&
  238. free_idx == sgid_tbl->max) {
  239. free_idx = i;
  240. }
  241. }
  242. if (free_idx == sgid_tbl->max) {
  243. dev_err(&res->pdev->dev,
  244. "QPLIB: SGID table is FULL but count is not MAX??");
  245. return -ENOMEM;
  246. }
  247. if (update) {
  248. struct cmdq_add_gid req;
  249. struct creq_add_gid_resp *resp;
  250. u16 cmd_flags = 0;
  251. u32 temp32[4];
  252. u16 temp16[3];
  253. RCFW_CMD_PREP(req, ADD_GID, cmd_flags);
  254. memcpy(temp32, gid->data, sizeof(struct bnxt_qplib_gid));
  255. req.gid[0] = cpu_to_be32(temp32[3]);
  256. req.gid[1] = cpu_to_be32(temp32[2]);
  257. req.gid[2] = cpu_to_be32(temp32[1]);
  258. req.gid[3] = cpu_to_be32(temp32[0]);
  259. if (vlan_id != 0xFFFF)
  260. req.vlan = cpu_to_le16((vlan_id &
  261. CMDQ_ADD_GID_VLAN_VLAN_ID_MASK) |
  262. CMDQ_ADD_GID_VLAN_TPID_TPID_8100 |
  263. CMDQ_ADD_GID_VLAN_VLAN_EN);
  264. /* MAC in network format */
  265. memcpy(temp16, smac, 6);
  266. req.src_mac[0] = cpu_to_be16(temp16[0]);
  267. req.src_mac[1] = cpu_to_be16(temp16[1]);
  268. req.src_mac[2] = cpu_to_be16(temp16[2]);
  269. resp = (struct creq_add_gid_resp *)
  270. bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
  271. NULL, 0);
  272. if (!resp) {
  273. dev_err(&res->pdev->dev,
  274. "QPLIB: SP: ADD_GID send failed");
  275. return -EINVAL;
  276. }
  277. if (!bnxt_qplib_rcfw_wait_for_resp(rcfw,
  278. le16_to_cpu(req.cookie))) {
  279. /* Cmd timed out */
  280. dev_err(&res->pdev->dev,
  281. "QPIB: SP: ADD_GID timed out");
  282. return -ETIMEDOUT;
  283. }
  284. if (resp->status ||
  285. le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
  286. dev_err(&res->pdev->dev, "QPLIB: SP: ADD_GID failed ");
  287. dev_err(&res->pdev->dev,
  288. "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
  289. resp->status, le16_to_cpu(req.cookie),
  290. le16_to_cpu(resp->cookie));
  291. return -EINVAL;
  292. }
  293. sgid_tbl->hw_id[free_idx] = le32_to_cpu(resp->xid);
  294. }
  295. /* Add GID to the sgid_tbl */
  296. memcpy(&sgid_tbl->tbl[free_idx], gid, sizeof(*gid));
  297. sgid_tbl->active++;
  298. dev_dbg(&res->pdev->dev,
  299. "QPLIB: SGID added hw_id[0x%x] = 0x%x active = 0x%x",
  300. free_idx, sgid_tbl->hw_id[free_idx], sgid_tbl->active);
  301. *index = free_idx;
  302. /* unlock */
  303. return rc;
  304. }
  305. /* pkeys */
  306. int bnxt_qplib_get_pkey(struct bnxt_qplib_res *res,
  307. struct bnxt_qplib_pkey_tbl *pkey_tbl, u16 index,
  308. u16 *pkey)
  309. {
  310. if (index == 0xFFFF) {
  311. *pkey = 0xFFFF;
  312. return 0;
  313. }
  314. if (index > pkey_tbl->max) {
  315. dev_err(&res->pdev->dev,
  316. "QPLIB: Index %d exceeded PKEY table max (%d)",
  317. index, pkey_tbl->max);
  318. return -EINVAL;
  319. }
  320. memcpy(pkey, &pkey_tbl->tbl[index], sizeof(*pkey));
  321. return 0;
  322. }
  323. int bnxt_qplib_del_pkey(struct bnxt_qplib_res *res,
  324. struct bnxt_qplib_pkey_tbl *pkey_tbl, u16 *pkey,
  325. bool update)
  326. {
  327. int i, rc = 0;
  328. if (!pkey_tbl) {
  329. dev_err(&res->pdev->dev, "QPLIB: PKEY table not allocated");
  330. return -EINVAL;
  331. }
  332. /* Do we need a pkey_lock here? */
  333. if (!pkey_tbl->active) {
  334. dev_err(&res->pdev->dev,
  335. "QPLIB: PKEY table has no active entries");
  336. return -ENOMEM;
  337. }
  338. for (i = 0; i < pkey_tbl->max; i++) {
  339. if (!memcmp(&pkey_tbl->tbl[i], pkey, sizeof(*pkey)))
  340. break;
  341. }
  342. if (i == pkey_tbl->max) {
  343. dev_err(&res->pdev->dev,
  344. "QPLIB: PKEY 0x%04x not found in the pkey table",
  345. *pkey);
  346. return -ENOMEM;
  347. }
  348. memset(&pkey_tbl->tbl[i], 0, sizeof(*pkey));
  349. pkey_tbl->active--;
  350. /* unlock */
  351. return rc;
  352. }
  353. int bnxt_qplib_add_pkey(struct bnxt_qplib_res *res,
  354. struct bnxt_qplib_pkey_tbl *pkey_tbl, u16 *pkey,
  355. bool update)
  356. {
  357. int i, free_idx, rc = 0;
  358. if (!pkey_tbl) {
  359. dev_err(&res->pdev->dev, "QPLIB: PKEY table not allocated");
  360. return -EINVAL;
  361. }
  362. /* Do we need a pkey_lock here? */
  363. if (pkey_tbl->active == pkey_tbl->max) {
  364. dev_err(&res->pdev->dev, "QPLIB: PKEY table is full");
  365. return -ENOMEM;
  366. }
  367. free_idx = pkey_tbl->max;
  368. for (i = 0; i < pkey_tbl->max; i++) {
  369. if (!memcmp(&pkey_tbl->tbl[i], pkey, sizeof(*pkey)))
  370. return -EALREADY;
  371. else if (!pkey_tbl->tbl[i] && free_idx == pkey_tbl->max)
  372. free_idx = i;
  373. }
  374. if (free_idx == pkey_tbl->max) {
  375. dev_err(&res->pdev->dev,
  376. "QPLIB: PKEY table is FULL but count is not MAX??");
  377. return -ENOMEM;
  378. }
  379. /* Add PKEY to the pkey_tbl */
  380. memcpy(&pkey_tbl->tbl[free_idx], pkey, sizeof(*pkey));
  381. pkey_tbl->active++;
  382. /* unlock */
  383. return rc;
  384. }
  385. /* AH */
  386. int bnxt_qplib_create_ah(struct bnxt_qplib_res *res, struct bnxt_qplib_ah *ah)
  387. {
  388. struct bnxt_qplib_rcfw *rcfw = res->rcfw;
  389. struct cmdq_create_ah req;
  390. struct creq_create_ah_resp *resp;
  391. u16 cmd_flags = 0;
  392. u32 temp32[4];
  393. u16 temp16[3];
  394. RCFW_CMD_PREP(req, CREATE_AH, cmd_flags);
  395. memcpy(temp32, ah->dgid.data, sizeof(struct bnxt_qplib_gid));
  396. req.dgid[0] = cpu_to_le32(temp32[0]);
  397. req.dgid[1] = cpu_to_le32(temp32[1]);
  398. req.dgid[2] = cpu_to_le32(temp32[2]);
  399. req.dgid[3] = cpu_to_le32(temp32[3]);
  400. req.type = ah->nw_type;
  401. req.hop_limit = ah->hop_limit;
  402. req.sgid_index = cpu_to_le16(res->sgid_tbl.hw_id[ah->sgid_index]);
  403. req.dest_vlan_id_flow_label = cpu_to_le32((ah->flow_label &
  404. CMDQ_CREATE_AH_FLOW_LABEL_MASK) |
  405. CMDQ_CREATE_AH_DEST_VLAN_ID_MASK);
  406. req.pd_id = cpu_to_le32(ah->pd->id);
  407. req.traffic_class = ah->traffic_class;
  408. /* MAC in network format */
  409. memcpy(temp16, ah->dmac, 6);
  410. req.dest_mac[0] = cpu_to_le16(temp16[0]);
  411. req.dest_mac[1] = cpu_to_le16(temp16[1]);
  412. req.dest_mac[2] = cpu_to_le16(temp16[2]);
  413. resp = (struct creq_create_ah_resp *)
  414. bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
  415. NULL, 1);
  416. if (!resp) {
  417. dev_err(&rcfw->pdev->dev, "QPLIB: SP: CREATE_AH send failed");
  418. return -EINVAL;
  419. }
  420. if (!bnxt_qplib_rcfw_block_for_resp(rcfw, le16_to_cpu(req.cookie))) {
  421. /* Cmd timed out */
  422. dev_err(&rcfw->pdev->dev, "QPLIB: SP: CREATE_AH timed out");
  423. return -ETIMEDOUT;
  424. }
  425. if (resp->status ||
  426. le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
  427. dev_err(&rcfw->pdev->dev, "QPLIB: SP: CREATE_AH failed ");
  428. dev_err(&rcfw->pdev->dev,
  429. "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
  430. resp->status, le16_to_cpu(req.cookie),
  431. le16_to_cpu(resp->cookie));
  432. return -EINVAL;
  433. }
  434. ah->id = le32_to_cpu(resp->xid);
  435. return 0;
  436. }
  437. int bnxt_qplib_destroy_ah(struct bnxt_qplib_res *res, struct bnxt_qplib_ah *ah)
  438. {
  439. struct bnxt_qplib_rcfw *rcfw = res->rcfw;
  440. struct cmdq_destroy_ah req;
  441. struct creq_destroy_ah_resp *resp;
  442. u16 cmd_flags = 0;
  443. /* Clean up the AH table in the device */
  444. RCFW_CMD_PREP(req, DESTROY_AH, cmd_flags);
  445. req.ah_cid = cpu_to_le32(ah->id);
  446. resp = (struct creq_destroy_ah_resp *)
  447. bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
  448. NULL, 1);
  449. if (!resp) {
  450. dev_err(&rcfw->pdev->dev, "QPLIB: SP: DESTROY_AH send failed");
  451. return -EINVAL;
  452. }
  453. if (!bnxt_qplib_rcfw_block_for_resp(rcfw, le16_to_cpu(req.cookie))) {
  454. /* Cmd timed out */
  455. dev_err(&rcfw->pdev->dev, "QPLIB: SP: DESTROY_AH timed out");
  456. return -ETIMEDOUT;
  457. }
  458. if (resp->status ||
  459. le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
  460. dev_err(&rcfw->pdev->dev, "QPLIB: SP: DESTROY_AH failed ");
  461. dev_err(&rcfw->pdev->dev,
  462. "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
  463. resp->status, le16_to_cpu(req.cookie),
  464. le16_to_cpu(resp->cookie));
  465. return -EINVAL;
  466. }
  467. return 0;
  468. }
  469. /* MRW */
  470. int bnxt_qplib_free_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw)
  471. {
  472. struct bnxt_qplib_rcfw *rcfw = res->rcfw;
  473. struct cmdq_deallocate_key req;
  474. struct creq_deallocate_key_resp *resp;
  475. u16 cmd_flags = 0;
  476. if (mrw->lkey == 0xFFFFFFFF) {
  477. dev_info(&res->pdev->dev,
  478. "QPLIB: SP: Free a reserved lkey MRW");
  479. return 0;
  480. }
  481. RCFW_CMD_PREP(req, DEALLOCATE_KEY, cmd_flags);
  482. req.mrw_flags = mrw->type;
  483. if ((mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE1) ||
  484. (mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2A) ||
  485. (mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2B))
  486. req.key = cpu_to_le32(mrw->rkey);
  487. else
  488. req.key = cpu_to_le32(mrw->lkey);
  489. resp = (struct creq_deallocate_key_resp *)
  490. bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
  491. NULL, 0);
  492. if (!resp) {
  493. dev_err(&res->pdev->dev, "QPLIB: SP: FREE_MR send failed");
  494. return -EINVAL;
  495. }
  496. if (!bnxt_qplib_rcfw_wait_for_resp(rcfw, le16_to_cpu(req.cookie))) {
  497. /* Cmd timed out */
  498. dev_err(&res->pdev->dev, "QPLIB: SP: FREE_MR timed out");
  499. return -ETIMEDOUT;
  500. }
  501. if (resp->status ||
  502. le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
  503. dev_err(&res->pdev->dev, "QPLIB: SP: FREE_MR failed ");
  504. dev_err(&res->pdev->dev,
  505. "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
  506. resp->status, le16_to_cpu(req.cookie),
  507. le16_to_cpu(resp->cookie));
  508. return -EINVAL;
  509. }
  510. /* Free the qplib's MRW memory */
  511. if (mrw->hwq.max_elements)
  512. bnxt_qplib_free_hwq(res->pdev, &mrw->hwq);
  513. return 0;
  514. }
  515. int bnxt_qplib_alloc_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw)
  516. {
  517. struct bnxt_qplib_rcfw *rcfw = res->rcfw;
  518. struct cmdq_allocate_mrw req;
  519. struct creq_allocate_mrw_resp *resp;
  520. u16 cmd_flags = 0;
  521. unsigned long tmp;
  522. RCFW_CMD_PREP(req, ALLOCATE_MRW, cmd_flags);
  523. req.pd_id = cpu_to_le32(mrw->pd->id);
  524. req.mrw_flags = mrw->type;
  525. if ((mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_PMR &&
  526. mrw->flags & BNXT_QPLIB_FR_PMR) ||
  527. mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2A ||
  528. mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2B)
  529. req.access = CMDQ_ALLOCATE_MRW_ACCESS_CONSUMER_OWNED_KEY;
  530. tmp = (unsigned long)mrw;
  531. req.mrw_handle = cpu_to_le64(tmp);
  532. resp = (struct creq_allocate_mrw_resp *)
  533. bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
  534. NULL, 0);
  535. if (!resp) {
  536. dev_err(&rcfw->pdev->dev, "QPLIB: SP: ALLOC_MRW send failed");
  537. return -EINVAL;
  538. }
  539. if (!bnxt_qplib_rcfw_wait_for_resp(rcfw, le16_to_cpu(req.cookie))) {
  540. /* Cmd timed out */
  541. dev_err(&rcfw->pdev->dev, "QPLIB: SP: ALLOC_MRW timed out");
  542. return -ETIMEDOUT;
  543. }
  544. if (resp->status ||
  545. le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
  546. dev_err(&rcfw->pdev->dev, "QPLIB: SP: ALLOC_MRW failed ");
  547. dev_err(&rcfw->pdev->dev,
  548. "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
  549. resp->status, le16_to_cpu(req.cookie),
  550. le16_to_cpu(resp->cookie));
  551. return -EINVAL;
  552. }
  553. if ((mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE1) ||
  554. (mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2A) ||
  555. (mrw->type == CMDQ_ALLOCATE_MRW_MRW_FLAGS_MW_TYPE2B))
  556. mrw->rkey = le32_to_cpu(resp->xid);
  557. else
  558. mrw->lkey = le32_to_cpu(resp->xid);
  559. return 0;
  560. }
  561. int bnxt_qplib_dereg_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw,
  562. bool block)
  563. {
  564. struct bnxt_qplib_rcfw *rcfw = res->rcfw;
  565. struct cmdq_deregister_mr req;
  566. struct creq_deregister_mr_resp *resp;
  567. u16 cmd_flags = 0;
  568. int rc;
  569. RCFW_CMD_PREP(req, DEREGISTER_MR, cmd_flags);
  570. req.lkey = cpu_to_le32(mrw->lkey);
  571. resp = (struct creq_deregister_mr_resp *)
  572. bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
  573. NULL, block);
  574. if (!resp) {
  575. dev_err(&rcfw->pdev->dev, "QPLIB: SP: DEREG_MR send failed");
  576. return -EINVAL;
  577. }
  578. if (block)
  579. rc = bnxt_qplib_rcfw_block_for_resp(rcfw,
  580. le16_to_cpu(req.cookie));
  581. else
  582. rc = bnxt_qplib_rcfw_wait_for_resp(rcfw,
  583. le16_to_cpu(req.cookie));
  584. if (!rc) {
  585. /* Cmd timed out */
  586. dev_err(&res->pdev->dev, "QPLIB: SP: DEREG_MR timed out");
  587. return -ETIMEDOUT;
  588. }
  589. if (resp->status ||
  590. le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
  591. dev_err(&rcfw->pdev->dev, "QPLIB: SP: DEREG_MR failed ");
  592. dev_err(&rcfw->pdev->dev,
  593. "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
  594. resp->status, le16_to_cpu(req.cookie),
  595. le16_to_cpu(resp->cookie));
  596. return -EINVAL;
  597. }
  598. /* Free the qplib's MR memory */
  599. if (mrw->hwq.max_elements) {
  600. mrw->va = 0;
  601. mrw->total_size = 0;
  602. bnxt_qplib_free_hwq(res->pdev, &mrw->hwq);
  603. }
  604. return 0;
  605. }
  606. int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr,
  607. u64 *pbl_tbl, int num_pbls, bool block)
  608. {
  609. struct bnxt_qplib_rcfw *rcfw = res->rcfw;
  610. struct cmdq_register_mr req;
  611. struct creq_register_mr_resp *resp;
  612. u16 cmd_flags = 0, level;
  613. int pg_ptrs, pages, i, rc;
  614. dma_addr_t **pbl_ptr;
  615. u32 pg_size;
  616. if (num_pbls) {
  617. pg_ptrs = roundup_pow_of_two(num_pbls);
  618. pages = pg_ptrs >> MAX_PBL_LVL_1_PGS_SHIFT;
  619. if (!pages)
  620. pages++;
  621. if (pages > MAX_PBL_LVL_1_PGS) {
  622. dev_err(&res->pdev->dev, "QPLIB: SP: Reg MR pages ");
  623. dev_err(&res->pdev->dev,
  624. "requested (0x%x) exceeded max (0x%x)",
  625. pages, MAX_PBL_LVL_1_PGS);
  626. return -ENOMEM;
  627. }
  628. /* Free the hwq if it already exist, must be a rereg */
  629. if (mr->hwq.max_elements)
  630. bnxt_qplib_free_hwq(res->pdev, &mr->hwq);
  631. mr->hwq.max_elements = pages;
  632. rc = bnxt_qplib_alloc_init_hwq(res->pdev, &mr->hwq, NULL, 0,
  633. &mr->hwq.max_elements,
  634. PAGE_SIZE, 0, PAGE_SIZE,
  635. HWQ_TYPE_CTX);
  636. if (rc) {
  637. dev_err(&res->pdev->dev,
  638. "SP: Reg MR memory allocation failed");
  639. return -ENOMEM;
  640. }
  641. /* Write to the hwq */
  642. pbl_ptr = (dma_addr_t **)mr->hwq.pbl_ptr;
  643. for (i = 0; i < num_pbls; i++)
  644. pbl_ptr[PTR_PG(i)][PTR_IDX(i)] =
  645. (pbl_tbl[i] & PAGE_MASK) | PTU_PTE_VALID;
  646. }
  647. RCFW_CMD_PREP(req, REGISTER_MR, cmd_flags);
  648. /* Configure the request */
  649. if (mr->hwq.level == PBL_LVL_MAX) {
  650. level = 0;
  651. req.pbl = 0;
  652. pg_size = PAGE_SIZE;
  653. } else {
  654. level = mr->hwq.level + 1;
  655. req.pbl = cpu_to_le64(mr->hwq.pbl[PBL_LVL_0].pg_map_arr[0]);
  656. pg_size = mr->hwq.pbl[PBL_LVL_0].pg_size;
  657. }
  658. req.log2_pg_size_lvl = (level << CMDQ_REGISTER_MR_LVL_SFT) |
  659. ((ilog2(pg_size) <<
  660. CMDQ_REGISTER_MR_LOG2_PG_SIZE_SFT) &
  661. CMDQ_REGISTER_MR_LOG2_PG_SIZE_MASK);
  662. req.access = (mr->flags & 0xFFFF);
  663. req.va = cpu_to_le64(mr->va);
  664. req.key = cpu_to_le32(mr->lkey);
  665. req.mr_size = cpu_to_le64(mr->total_size);
  666. resp = (struct creq_register_mr_resp *)
  667. bnxt_qplib_rcfw_send_message(rcfw, (void *)&req,
  668. NULL, block);
  669. if (!resp) {
  670. dev_err(&res->pdev->dev, "SP: REG_MR send failed");
  671. rc = -EINVAL;
  672. goto fail;
  673. }
  674. if (block)
  675. rc = bnxt_qplib_rcfw_block_for_resp(rcfw,
  676. le16_to_cpu(req.cookie));
  677. else
  678. rc = bnxt_qplib_rcfw_wait_for_resp(rcfw,
  679. le16_to_cpu(req.cookie));
  680. if (!rc) {
  681. /* Cmd timed out */
  682. dev_err(&res->pdev->dev, "SP: REG_MR timed out");
  683. rc = -ETIMEDOUT;
  684. goto fail;
  685. }
  686. if (resp->status ||
  687. le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
  688. dev_err(&res->pdev->dev, "QPLIB: SP: REG_MR failed ");
  689. dev_err(&res->pdev->dev,
  690. "QPLIB: SP: with status 0x%x cmdq 0x%x resp 0x%x",
  691. resp->status, le16_to_cpu(req.cookie),
  692. le16_to_cpu(resp->cookie));
  693. rc = -EINVAL;
  694. goto fail;
  695. }
  696. return 0;
  697. fail:
  698. if (mr->hwq.max_elements)
  699. bnxt_qplib_free_hwq(res->pdev, &mr->hwq);
  700. return rc;
  701. }
  702. int bnxt_qplib_alloc_fast_reg_page_list(struct bnxt_qplib_res *res,
  703. struct bnxt_qplib_frpl *frpl,
  704. int max_pg_ptrs)
  705. {
  706. int pg_ptrs, pages, rc;
  707. /* Re-calculate the max to fit the HWQ allocation model */
  708. pg_ptrs = roundup_pow_of_two(max_pg_ptrs);
  709. pages = pg_ptrs >> MAX_PBL_LVL_1_PGS_SHIFT;
  710. if (!pages)
  711. pages++;
  712. if (pages > MAX_PBL_LVL_1_PGS)
  713. return -ENOMEM;
  714. frpl->hwq.max_elements = pages;
  715. rc = bnxt_qplib_alloc_init_hwq(res->pdev, &frpl->hwq, NULL, 0,
  716. &frpl->hwq.max_elements, PAGE_SIZE, 0,
  717. PAGE_SIZE, HWQ_TYPE_CTX);
  718. if (!rc)
  719. frpl->max_pg_ptrs = pg_ptrs;
  720. return rc;
  721. }
  722. int bnxt_qplib_free_fast_reg_page_list(struct bnxt_qplib_res *res,
  723. struct bnxt_qplib_frpl *frpl)
  724. {
  725. bnxt_qplib_free_hwq(res->pdev, &frpl->hwq);
  726. return 0;
  727. }
  728. int bnxt_qplib_map_tc2cos(struct bnxt_qplib_res *res, u16 *cids)
  729. {
  730. struct bnxt_qplib_rcfw *rcfw = res->rcfw;
  731. struct cmdq_map_tc_to_cos req;
  732. struct creq_map_tc_to_cos_resp *resp;
  733. u16 cmd_flags = 0;
  734. int tleft;
  735. RCFW_CMD_PREP(req, MAP_TC_TO_COS, cmd_flags);
  736. req.cos0 = cpu_to_le16(cids[0]);
  737. req.cos1 = cpu_to_le16(cids[1]);
  738. resp = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, NULL, 0);
  739. if (!resp) {
  740. dev_err(&res->pdev->dev, "QPLIB: SP: MAP_TC2COS send failed");
  741. return -EINVAL;
  742. }
  743. tleft = bnxt_qplib_rcfw_block_for_resp(rcfw, le16_to_cpu(req.cookie));
  744. if (!tleft) {
  745. dev_err(&res->pdev->dev, "QPLIB: SP: MAP_TC2COS timed out");
  746. return -ETIMEDOUT;
  747. }
  748. if (resp->status ||
  749. le16_to_cpu(resp->cookie) != le16_to_cpu(req.cookie)) {
  750. dev_err(&res->pdev->dev, "QPLIB: SP: MAP_TC2COS failed ");
  751. dev_err(&res->pdev->dev,
  752. "QPLIB: with status 0x%x cmdq 0x%x resp 0x%x",
  753. resp->status, le16_to_cpu(req.cookie),
  754. le16_to_cpu(resp->cookie));
  755. return -EINVAL;
  756. }
  757. return 0;
  758. }