bfa_fcxp.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  1. /*
  2. * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
  3. * All rights reserved
  4. * www.brocade.com
  5. *
  6. * Linux driver for Brocade Fibre Channel Host Bus Adapter.
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License (GPL) Version 2 as
  10. * published by the Free Software Foundation
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. */
  17. #include <bfa.h>
  18. #include <bfi/bfi_uf.h>
  19. #include <cs/bfa_debug.h>
  20. BFA_TRC_FILE(HAL, FCXP);
  21. BFA_MODULE(fcxp);
  22. /**
  23. * forward declarations
  24. */
  25. static void __bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete);
  26. static void hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp,
  27. struct bfi_fcxp_send_rsp_s *fcxp_rsp);
  28. static void hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen,
  29. struct bfa_fcxp_s *fcxp, struct fchs_s *fchs);
  30. static void bfa_fcxp_qresume(void *cbarg);
  31. static void bfa_fcxp_queue(struct bfa_fcxp_s *fcxp,
  32. struct bfi_fcxp_send_req_s *send_req);
  33. /**
  34. * fcxp_pvt BFA FCXP private functions
  35. */
  36. static void
  37. claim_fcxp_req_rsp_mem(struct bfa_fcxp_mod_s *mod, struct bfa_meminfo_s *mi)
  38. {
  39. u8 *dm_kva = NULL;
  40. u64 dm_pa;
  41. u32 buf_pool_sz;
  42. dm_kva = bfa_meminfo_dma_virt(mi);
  43. dm_pa = bfa_meminfo_dma_phys(mi);
  44. buf_pool_sz = mod->req_pld_sz * mod->num_fcxps;
  45. /*
  46. * Initialize the fcxp req payload list
  47. */
  48. mod->req_pld_list_kva = dm_kva;
  49. mod->req_pld_list_pa = dm_pa;
  50. dm_kva += buf_pool_sz;
  51. dm_pa += buf_pool_sz;
  52. bfa_os_memset(mod->req_pld_list_kva, 0, buf_pool_sz);
  53. /*
  54. * Initialize the fcxp rsp payload list
  55. */
  56. buf_pool_sz = mod->rsp_pld_sz * mod->num_fcxps;
  57. mod->rsp_pld_list_kva = dm_kva;
  58. mod->rsp_pld_list_pa = dm_pa;
  59. dm_kva += buf_pool_sz;
  60. dm_pa += buf_pool_sz;
  61. bfa_os_memset(mod->rsp_pld_list_kva, 0, buf_pool_sz);
  62. bfa_meminfo_dma_virt(mi) = dm_kva;
  63. bfa_meminfo_dma_phys(mi) = dm_pa;
  64. }
  65. static void
  66. claim_fcxps_mem(struct bfa_fcxp_mod_s *mod, struct bfa_meminfo_s *mi)
  67. {
  68. u16 i;
  69. struct bfa_fcxp_s *fcxp;
  70. fcxp = (struct bfa_fcxp_s *) bfa_meminfo_kva(mi);
  71. bfa_os_memset(fcxp, 0, sizeof(struct bfa_fcxp_s) * mod->num_fcxps);
  72. INIT_LIST_HEAD(&mod->fcxp_free_q);
  73. INIT_LIST_HEAD(&mod->fcxp_active_q);
  74. mod->fcxp_list = fcxp;
  75. for (i = 0; i < mod->num_fcxps; i++) {
  76. fcxp->fcxp_mod = mod;
  77. fcxp->fcxp_tag = i;
  78. list_add_tail(&fcxp->qe, &mod->fcxp_free_q);
  79. bfa_reqq_winit(&fcxp->reqq_wqe, bfa_fcxp_qresume, fcxp);
  80. fcxp->reqq_waiting = BFA_FALSE;
  81. fcxp = fcxp + 1;
  82. }
  83. bfa_meminfo_kva(mi) = (void *)fcxp;
  84. }
  85. static void
  86. bfa_fcxp_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
  87. u32 *dm_len)
  88. {
  89. u16 num_fcxp_reqs = cfg->fwcfg.num_fcxp_reqs;
  90. if (num_fcxp_reqs == 0)
  91. return;
  92. /*
  93. * Account for req/rsp payload
  94. */
  95. *dm_len += BFA_FCXP_MAX_IBUF_SZ * num_fcxp_reqs;
  96. if (cfg->drvcfg.min_cfg)
  97. *dm_len += BFA_FCXP_MAX_IBUF_SZ * num_fcxp_reqs;
  98. else
  99. *dm_len += BFA_FCXP_MAX_LBUF_SZ * num_fcxp_reqs;
  100. /*
  101. * Account for fcxp structs
  102. */
  103. *ndm_len += sizeof(struct bfa_fcxp_s) * num_fcxp_reqs;
  104. }
  105. static void
  106. bfa_fcxp_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
  107. struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
  108. {
  109. struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
  110. bfa_os_memset(mod, 0, sizeof(struct bfa_fcxp_mod_s));
  111. mod->bfa = bfa;
  112. mod->num_fcxps = cfg->fwcfg.num_fcxp_reqs;
  113. /**
  114. * Initialize FCXP request and response payload sizes.
  115. */
  116. mod->req_pld_sz = mod->rsp_pld_sz = BFA_FCXP_MAX_IBUF_SZ;
  117. if (!cfg->drvcfg.min_cfg)
  118. mod->rsp_pld_sz = BFA_FCXP_MAX_LBUF_SZ;
  119. INIT_LIST_HEAD(&mod->wait_q);
  120. claim_fcxp_req_rsp_mem(mod, meminfo);
  121. claim_fcxps_mem(mod, meminfo);
  122. }
  123. static void
  124. bfa_fcxp_detach(struct bfa_s *bfa)
  125. {
  126. }
  127. static void
  128. bfa_fcxp_start(struct bfa_s *bfa)
  129. {
  130. }
  131. static void
  132. bfa_fcxp_stop(struct bfa_s *bfa)
  133. {
  134. }
  135. static void
  136. bfa_fcxp_iocdisable(struct bfa_s *bfa)
  137. {
  138. struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
  139. struct bfa_fcxp_s *fcxp;
  140. struct list_head *qe, *qen;
  141. list_for_each_safe(qe, qen, &mod->fcxp_active_q) {
  142. fcxp = (struct bfa_fcxp_s *) qe;
  143. if (fcxp->caller == NULL) {
  144. fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg,
  145. BFA_STATUS_IOC_FAILURE, 0, 0, NULL);
  146. bfa_fcxp_free(fcxp);
  147. } else {
  148. fcxp->rsp_status = BFA_STATUS_IOC_FAILURE;
  149. bfa_cb_queue(bfa, &fcxp->hcb_qe,
  150. __bfa_fcxp_send_cbfn, fcxp);
  151. }
  152. }
  153. }
  154. static struct bfa_fcxp_s *
  155. bfa_fcxp_get(struct bfa_fcxp_mod_s *fm)
  156. {
  157. struct bfa_fcxp_s *fcxp;
  158. bfa_q_deq(&fm->fcxp_free_q, &fcxp);
  159. if (fcxp)
  160. list_add_tail(&fcxp->qe, &fm->fcxp_active_q);
  161. return fcxp;
  162. }
  163. static void
  164. bfa_fcxp_put(struct bfa_fcxp_s *fcxp)
  165. {
  166. struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
  167. struct bfa_fcxp_wqe_s *wqe;
  168. bfa_q_deq(&mod->wait_q, &wqe);
  169. if (wqe) {
  170. bfa_trc(mod->bfa, fcxp->fcxp_tag);
  171. wqe->alloc_cbfn(wqe->alloc_cbarg, fcxp);
  172. return;
  173. }
  174. bfa_assert(bfa_q_is_on_q(&mod->fcxp_active_q, fcxp));
  175. list_del(&fcxp->qe);
  176. list_add_tail(&fcxp->qe, &mod->fcxp_free_q);
  177. }
  178. static void
  179. bfa_fcxp_null_comp(void *bfad_fcxp, struct bfa_fcxp_s *fcxp, void *cbarg,
  180. bfa_status_t req_status, u32 rsp_len,
  181. u32 resid_len, struct fchs_s *rsp_fchs)
  182. {
  183. /* discarded fcxp completion */
  184. }
  185. static void
  186. __bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete)
  187. {
  188. struct bfa_fcxp_s *fcxp = cbarg;
  189. if (complete) {
  190. fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg,
  191. fcxp->rsp_status, fcxp->rsp_len,
  192. fcxp->residue_len, &fcxp->rsp_fchs);
  193. } else {
  194. bfa_fcxp_free(fcxp);
  195. }
  196. }
  197. static void
  198. hal_fcxp_send_comp(struct bfa_s *bfa, struct bfi_fcxp_send_rsp_s *fcxp_rsp)
  199. {
  200. struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
  201. struct bfa_fcxp_s *fcxp;
  202. u16 fcxp_tag = bfa_os_ntohs(fcxp_rsp->fcxp_tag);
  203. bfa_trc(bfa, fcxp_tag);
  204. fcxp_rsp->rsp_len = bfa_os_ntohl(fcxp_rsp->rsp_len);
  205. /**
  206. * @todo f/w should not set residue to non-0 when everything
  207. * is received.
  208. */
  209. if (fcxp_rsp->req_status == BFA_STATUS_OK)
  210. fcxp_rsp->residue_len = 0;
  211. else
  212. fcxp_rsp->residue_len = bfa_os_ntohl(fcxp_rsp->residue_len);
  213. fcxp = BFA_FCXP_FROM_TAG(mod, fcxp_tag);
  214. bfa_assert(fcxp->send_cbfn != NULL);
  215. hal_fcxp_rx_plog(mod->bfa, fcxp, fcxp_rsp);
  216. if (fcxp->send_cbfn != NULL) {
  217. if (fcxp->caller == NULL) {
  218. bfa_trc(mod->bfa, fcxp->fcxp_tag);
  219. fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg,
  220. fcxp_rsp->req_status, fcxp_rsp->rsp_len,
  221. fcxp_rsp->residue_len, &fcxp_rsp->fchs);
  222. /*
  223. * fcxp automatically freed on return from the callback
  224. */
  225. bfa_fcxp_free(fcxp);
  226. } else {
  227. bfa_trc(mod->bfa, fcxp->fcxp_tag);
  228. fcxp->rsp_status = fcxp_rsp->req_status;
  229. fcxp->rsp_len = fcxp_rsp->rsp_len;
  230. fcxp->residue_len = fcxp_rsp->residue_len;
  231. fcxp->rsp_fchs = fcxp_rsp->fchs;
  232. bfa_cb_queue(bfa, &fcxp->hcb_qe,
  233. __bfa_fcxp_send_cbfn, fcxp);
  234. }
  235. } else {
  236. bfa_trc(bfa, fcxp_tag);
  237. }
  238. }
  239. static void
  240. hal_fcxp_set_local_sges(struct bfi_sge_s *sge, u32 reqlen, u64 req_pa)
  241. {
  242. union bfi_addr_u sga_zero = { {0} };
  243. sge->sg_len = reqlen;
  244. sge->flags = BFI_SGE_DATA_LAST;
  245. bfa_dma_addr_set(sge[0].sga, req_pa);
  246. bfa_sge_to_be(sge);
  247. sge++;
  248. sge->sga = sga_zero;
  249. sge->sg_len = reqlen;
  250. sge->flags = BFI_SGE_PGDLEN;
  251. bfa_sge_to_be(sge);
  252. }
  253. static void
  254. hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen, struct bfa_fcxp_s *fcxp,
  255. struct fchs_s *fchs)
  256. {
  257. /*
  258. * TODO: TX ox_id
  259. */
  260. if (reqlen > 0) {
  261. if (fcxp->use_ireqbuf) {
  262. u32 pld_w0 =
  263. *((u32 *) BFA_FCXP_REQ_PLD(fcxp));
  264. bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP,
  265. BFA_PL_EID_TX,
  266. reqlen + sizeof(struct fchs_s), fchs, pld_w0);
  267. } else {
  268. bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP,
  269. BFA_PL_EID_TX, reqlen + sizeof(struct fchs_s),
  270. fchs);
  271. }
  272. } else {
  273. bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_TX,
  274. reqlen + sizeof(struct fchs_s), fchs);
  275. }
  276. }
  277. static void
  278. hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp,
  279. struct bfi_fcxp_send_rsp_s *fcxp_rsp)
  280. {
  281. if (fcxp_rsp->rsp_len > 0) {
  282. if (fcxp->use_irspbuf) {
  283. u32 pld_w0 =
  284. *((u32 *) BFA_FCXP_RSP_PLD(fcxp));
  285. bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP,
  286. BFA_PL_EID_RX,
  287. (u16) fcxp_rsp->rsp_len,
  288. &fcxp_rsp->fchs, pld_w0);
  289. } else {
  290. bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP,
  291. BFA_PL_EID_RX,
  292. (u16) fcxp_rsp->rsp_len,
  293. &fcxp_rsp->fchs);
  294. }
  295. } else {
  296. bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_RX,
  297. (u16) fcxp_rsp->rsp_len, &fcxp_rsp->fchs);
  298. }
  299. }
  300. /**
  301. * Handler to resume sending fcxp when space in available in cpe queue.
  302. */
  303. static void
  304. bfa_fcxp_qresume(void *cbarg)
  305. {
  306. struct bfa_fcxp_s *fcxp = cbarg;
  307. struct bfa_s *bfa = fcxp->fcxp_mod->bfa;
  308. struct bfi_fcxp_send_req_s *send_req;
  309. fcxp->reqq_waiting = BFA_FALSE;
  310. send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP);
  311. bfa_fcxp_queue(fcxp, send_req);
  312. }
  313. /**
  314. * Queue fcxp send request to foimrware.
  315. */
  316. static void
  317. bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req)
  318. {
  319. struct bfa_s *bfa = fcxp->fcxp_mod->bfa;
  320. struct bfa_fcxp_req_info_s *reqi = &fcxp->req_info;
  321. struct bfa_fcxp_rsp_info_s *rspi = &fcxp->rsp_info;
  322. struct bfa_rport_s *rport = reqi->bfa_rport;
  323. bfi_h2i_set(send_req->mh, BFI_MC_FCXP, BFI_FCXP_H2I_SEND_REQ,
  324. bfa_lpuid(bfa));
  325. send_req->fcxp_tag = bfa_os_htons(fcxp->fcxp_tag);
  326. if (rport) {
  327. send_req->rport_fw_hndl = rport->fw_handle;
  328. send_req->max_frmsz = bfa_os_htons(rport->rport_info.max_frmsz);
  329. if (send_req->max_frmsz == 0)
  330. send_req->max_frmsz = bfa_os_htons(FC_MAX_PDUSZ);
  331. } else {
  332. send_req->rport_fw_hndl = 0;
  333. send_req->max_frmsz = bfa_os_htons(FC_MAX_PDUSZ);
  334. }
  335. send_req->vf_id = bfa_os_htons(reqi->vf_id);
  336. send_req->lp_tag = reqi->lp_tag;
  337. send_req->class = reqi->class;
  338. send_req->rsp_timeout = rspi->rsp_timeout;
  339. send_req->cts = reqi->cts;
  340. send_req->fchs = reqi->fchs;
  341. send_req->req_len = bfa_os_htonl(reqi->req_tot_len);
  342. send_req->rsp_maxlen = bfa_os_htonl(rspi->rsp_maxlen);
  343. /*
  344. * setup req sgles
  345. */
  346. if (fcxp->use_ireqbuf == 1) {
  347. hal_fcxp_set_local_sges(send_req->req_sge, reqi->req_tot_len,
  348. BFA_FCXP_REQ_PLD_PA(fcxp));
  349. } else {
  350. if (fcxp->nreq_sgles > 0) {
  351. bfa_assert(fcxp->nreq_sgles == 1);
  352. hal_fcxp_set_local_sges(send_req->req_sge,
  353. reqi->req_tot_len,
  354. fcxp->req_sga_cbfn(fcxp->caller,
  355. 0));
  356. } else {
  357. bfa_assert(reqi->req_tot_len == 0);
  358. hal_fcxp_set_local_sges(send_req->rsp_sge, 0, 0);
  359. }
  360. }
  361. /*
  362. * setup rsp sgles
  363. */
  364. if (fcxp->use_irspbuf == 1) {
  365. bfa_assert(rspi->rsp_maxlen <= BFA_FCXP_MAX_LBUF_SZ);
  366. hal_fcxp_set_local_sges(send_req->rsp_sge, rspi->rsp_maxlen,
  367. BFA_FCXP_RSP_PLD_PA(fcxp));
  368. } else {
  369. if (fcxp->nrsp_sgles > 0) {
  370. bfa_assert(fcxp->nrsp_sgles == 1);
  371. hal_fcxp_set_local_sges(send_req->rsp_sge,
  372. rspi->rsp_maxlen,
  373. fcxp->rsp_sga_cbfn(fcxp->caller,
  374. 0));
  375. } else {
  376. bfa_assert(rspi->rsp_maxlen == 0);
  377. hal_fcxp_set_local_sges(send_req->rsp_sge, 0, 0);
  378. }
  379. }
  380. hal_fcxp_tx_plog(bfa, reqi->req_tot_len, fcxp, &reqi->fchs);
  381. bfa_reqq_produce(bfa, BFA_REQQ_FCXP);
  382. bfa_trc(bfa, bfa_reqq_pi(bfa, BFA_REQQ_FCXP));
  383. bfa_trc(bfa, bfa_reqq_ci(bfa, BFA_REQQ_FCXP));
  384. }
  385. /**
  386. * hal_fcxp_api BFA FCXP API
  387. */
  388. /**
  389. * Allocate an FCXP instance to send a response or to send a request
  390. * that has a response. Request/response buffers are allocated by caller.
  391. *
  392. * @param[in] bfa BFA bfa instance
  393. * @param[in] nreq_sgles Number of SG elements required for request
  394. * buffer. 0, if fcxp internal buffers are used.
  395. * Use bfa_fcxp_get_reqbuf() to get the
  396. * internal req buffer.
  397. * @param[in] req_sgles SG elements describing request buffer. Will be
  398. * copied in by BFA and hence can be freed on
  399. * return from this function.
  400. * @param[in] get_req_sga function ptr to be called to get a request SG
  401. * Address (given the sge index).
  402. * @param[in] get_req_sglen function ptr to be called to get a request SG
  403. * len (given the sge index).
  404. * @param[in] get_rsp_sga function ptr to be called to get a response SG
  405. * Address (given the sge index).
  406. * @param[in] get_rsp_sglen function ptr to be called to get a response SG
  407. * len (given the sge index).
  408. *
  409. * @return FCXP instance. NULL on failure.
  410. */
  411. struct bfa_fcxp_s *
  412. bfa_fcxp_alloc(void *caller, struct bfa_s *bfa, int nreq_sgles,
  413. int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn,
  414. bfa_fcxp_get_sglen_t req_sglen_cbfn,
  415. bfa_fcxp_get_sgaddr_t rsp_sga_cbfn,
  416. bfa_fcxp_get_sglen_t rsp_sglen_cbfn)
  417. {
  418. struct bfa_fcxp_s *fcxp = NULL;
  419. u32 nreq_sgpg, nrsp_sgpg;
  420. bfa_assert(bfa != NULL);
  421. fcxp = bfa_fcxp_get(BFA_FCXP_MOD(bfa));
  422. if (fcxp == NULL)
  423. return NULL;
  424. bfa_trc(bfa, fcxp->fcxp_tag);
  425. fcxp->caller = caller;
  426. if (nreq_sgles == 0) {
  427. fcxp->use_ireqbuf = 1;
  428. } else {
  429. bfa_assert(req_sga_cbfn != NULL);
  430. bfa_assert(req_sglen_cbfn != NULL);
  431. fcxp->use_ireqbuf = 0;
  432. fcxp->req_sga_cbfn = req_sga_cbfn;
  433. fcxp->req_sglen_cbfn = req_sglen_cbfn;
  434. fcxp->nreq_sgles = nreq_sgles;
  435. /*
  436. * alloc required sgpgs
  437. */
  438. if (nreq_sgles > BFI_SGE_INLINE) {
  439. nreq_sgpg = BFA_SGPG_NPAGE(nreq_sgles);
  440. if (bfa_sgpg_malloc(bfa, &fcxp->req_sgpg_q, nreq_sgpg)
  441. != BFA_STATUS_OK) {
  442. /*
  443. * TODO
  444. */
  445. }
  446. }
  447. }
  448. if (nrsp_sgles == 0) {
  449. fcxp->use_irspbuf = 1;
  450. } else {
  451. bfa_assert(rsp_sga_cbfn != NULL);
  452. bfa_assert(rsp_sglen_cbfn != NULL);
  453. fcxp->use_irspbuf = 0;
  454. fcxp->rsp_sga_cbfn = rsp_sga_cbfn;
  455. fcxp->rsp_sglen_cbfn = rsp_sglen_cbfn;
  456. fcxp->nrsp_sgles = nrsp_sgles;
  457. /*
  458. * alloc required sgpgs
  459. */
  460. if (nrsp_sgles > BFI_SGE_INLINE) {
  461. nrsp_sgpg = BFA_SGPG_NPAGE(nreq_sgles);
  462. if (bfa_sgpg_malloc
  463. (bfa, &fcxp->rsp_sgpg_q, nrsp_sgpg)
  464. != BFA_STATUS_OK) {
  465. /* bfa_sgpg_wait(bfa, &fcxp->rsp_sgpg_wqe,
  466. nrsp_sgpg); */
  467. /*
  468. * TODO
  469. */
  470. }
  471. }
  472. }
  473. return fcxp;
  474. }
  475. /**
  476. * Get the internal request buffer pointer
  477. *
  478. * @param[in] fcxp BFA fcxp pointer
  479. *
  480. * @return pointer to the internal request buffer
  481. */
  482. void *
  483. bfa_fcxp_get_reqbuf(struct bfa_fcxp_s *fcxp)
  484. {
  485. struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
  486. void *reqbuf;
  487. bfa_assert(fcxp->use_ireqbuf == 1);
  488. reqbuf = ((u8 *)mod->req_pld_list_kva) +
  489. fcxp->fcxp_tag * mod->req_pld_sz;
  490. return reqbuf;
  491. }
  492. u32
  493. bfa_fcxp_get_reqbufsz(struct bfa_fcxp_s *fcxp)
  494. {
  495. struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
  496. return mod->req_pld_sz;
  497. }
  498. /**
  499. * Get the internal response buffer pointer
  500. *
  501. * @param[in] fcxp BFA fcxp pointer
  502. *
  503. * @return pointer to the internal request buffer
  504. */
  505. void *
  506. bfa_fcxp_get_rspbuf(struct bfa_fcxp_s *fcxp)
  507. {
  508. struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
  509. void *rspbuf;
  510. bfa_assert(fcxp->use_irspbuf == 1);
  511. rspbuf = ((u8 *)mod->rsp_pld_list_kva) +
  512. fcxp->fcxp_tag * mod->rsp_pld_sz;
  513. return rspbuf;
  514. }
  515. /**
  516. * Free the BFA FCXP
  517. *
  518. * @param[in] fcxp BFA fcxp pointer
  519. *
  520. * @return void
  521. */
  522. void
  523. bfa_fcxp_free(struct bfa_fcxp_s *fcxp)
  524. {
  525. struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
  526. bfa_assert(fcxp != NULL);
  527. bfa_trc(mod->bfa, fcxp->fcxp_tag);
  528. bfa_fcxp_put(fcxp);
  529. }
  530. /**
  531. * Send a FCXP request
  532. *
  533. * @param[in] fcxp BFA fcxp pointer
  534. * @param[in] rport BFA rport pointer. Could be left NULL for WKA rports
  535. * @param[in] vf_id virtual Fabric ID
  536. * @param[in] lp_tag lport tag
  537. * @param[in] cts use Continous sequence
  538. * @param[in] cos fc Class of Service
  539. * @param[in] reqlen request length, does not include FCHS length
  540. * @param[in] fchs fc Header Pointer. The header content will be copied
  541. * in by BFA.
  542. *
  543. * @param[in] cbfn call back function to be called on receiving
  544. * the response
  545. * @param[in] cbarg arg for cbfn
  546. * @param[in] rsp_timeout
  547. * response timeout
  548. *
  549. * @return bfa_status_t
  550. */
  551. void
  552. bfa_fcxp_send(struct bfa_fcxp_s *fcxp, struct bfa_rport_s *rport,
  553. u16 vf_id, u8 lp_tag, bfa_boolean_t cts, enum fc_cos cos,
  554. u32 reqlen, struct fchs_s *fchs, bfa_cb_fcxp_send_t cbfn,
  555. void *cbarg, u32 rsp_maxlen, u8 rsp_timeout)
  556. {
  557. struct bfa_s *bfa = fcxp->fcxp_mod->bfa;
  558. struct bfa_fcxp_req_info_s *reqi = &fcxp->req_info;
  559. struct bfa_fcxp_rsp_info_s *rspi = &fcxp->rsp_info;
  560. struct bfi_fcxp_send_req_s *send_req;
  561. bfa_trc(bfa, fcxp->fcxp_tag);
  562. /**
  563. * setup request/response info
  564. */
  565. reqi->bfa_rport = rport;
  566. reqi->vf_id = vf_id;
  567. reqi->lp_tag = lp_tag;
  568. reqi->class = cos;
  569. rspi->rsp_timeout = rsp_timeout;
  570. reqi->cts = cts;
  571. reqi->fchs = *fchs;
  572. reqi->req_tot_len = reqlen;
  573. rspi->rsp_maxlen = rsp_maxlen;
  574. fcxp->send_cbfn = cbfn ? cbfn : bfa_fcxp_null_comp;
  575. fcxp->send_cbarg = cbarg;
  576. /**
  577. * If no room in CPE queue, wait for space in request queue
  578. */
  579. send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP);
  580. if (!send_req) {
  581. bfa_trc(bfa, fcxp->fcxp_tag);
  582. fcxp->reqq_waiting = BFA_TRUE;
  583. bfa_reqq_wait(bfa, BFA_REQQ_FCXP, &fcxp->reqq_wqe);
  584. return;
  585. }
  586. bfa_fcxp_queue(fcxp, send_req);
  587. }
  588. /**
  589. * Abort a BFA FCXP
  590. *
  591. * @param[in] fcxp BFA fcxp pointer
  592. *
  593. * @return void
  594. */
  595. bfa_status_t
  596. bfa_fcxp_abort(struct bfa_fcxp_s *fcxp)
  597. {
  598. bfa_assert(0);
  599. return BFA_STATUS_OK;
  600. }
  601. void
  602. bfa_fcxp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe,
  603. bfa_fcxp_alloc_cbfn_t alloc_cbfn, void *alloc_cbarg)
  604. {
  605. struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
  606. bfa_assert(list_empty(&mod->fcxp_free_q));
  607. wqe->alloc_cbfn = alloc_cbfn;
  608. wqe->alloc_cbarg = alloc_cbarg;
  609. list_add_tail(&wqe->qe, &mod->wait_q);
  610. }
  611. void
  612. bfa_fcxp_walloc_cancel(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe)
  613. {
  614. struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
  615. bfa_assert(bfa_q_is_on_q(&mod->wait_q, wqe));
  616. list_del(&wqe->qe);
  617. }
  618. void
  619. bfa_fcxp_discard(struct bfa_fcxp_s *fcxp)
  620. {
  621. /**
  622. * If waiting for room in request queue, cancel reqq wait
  623. * and free fcxp.
  624. */
  625. if (fcxp->reqq_waiting) {
  626. fcxp->reqq_waiting = BFA_FALSE;
  627. bfa_reqq_wcancel(&fcxp->reqq_wqe);
  628. bfa_fcxp_free(fcxp);
  629. return;
  630. }
  631. fcxp->send_cbfn = bfa_fcxp_null_comp;
  632. }
  633. /**
  634. * hal_fcxp_public BFA FCXP public functions
  635. */
  636. void
  637. bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
  638. {
  639. switch (msg->mhdr.msg_id) {
  640. case BFI_FCXP_I2H_SEND_RSP:
  641. hal_fcxp_send_comp(bfa, (struct bfi_fcxp_send_rsp_s *) msg);
  642. break;
  643. default:
  644. bfa_trc(bfa, msg->mhdr.msg_id);
  645. bfa_assert(0);
  646. }
  647. }
  648. u32
  649. bfa_fcxp_get_maxrsp(struct bfa_s *bfa)
  650. {
  651. struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
  652. return mod->rsp_pld_sz;
  653. }