bfa_fcxp.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782
  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_initdone(struct bfa_s *bfa)
  125. {
  126. }
  127. static void
  128. bfa_fcxp_detach(struct bfa_s *bfa)
  129. {
  130. }
  131. static void
  132. bfa_fcxp_start(struct bfa_s *bfa)
  133. {
  134. }
  135. static void
  136. bfa_fcxp_stop(struct bfa_s *bfa)
  137. {
  138. }
  139. static void
  140. bfa_fcxp_iocdisable(struct bfa_s *bfa)
  141. {
  142. struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
  143. struct bfa_fcxp_s *fcxp;
  144. struct list_head *qe, *qen;
  145. list_for_each_safe(qe, qen, &mod->fcxp_active_q) {
  146. fcxp = (struct bfa_fcxp_s *) qe;
  147. if (fcxp->caller == NULL) {
  148. fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg,
  149. BFA_STATUS_IOC_FAILURE, 0, 0, NULL);
  150. bfa_fcxp_free(fcxp);
  151. } else {
  152. fcxp->rsp_status = BFA_STATUS_IOC_FAILURE;
  153. bfa_cb_queue(bfa, &fcxp->hcb_qe,
  154. __bfa_fcxp_send_cbfn, fcxp);
  155. }
  156. }
  157. }
  158. static struct bfa_fcxp_s *
  159. bfa_fcxp_get(struct bfa_fcxp_mod_s *fm)
  160. {
  161. struct bfa_fcxp_s *fcxp;
  162. bfa_q_deq(&fm->fcxp_free_q, &fcxp);
  163. if (fcxp)
  164. list_add_tail(&fcxp->qe, &fm->fcxp_active_q);
  165. return fcxp;
  166. }
  167. static void
  168. bfa_fcxp_put(struct bfa_fcxp_s *fcxp)
  169. {
  170. struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
  171. struct bfa_fcxp_wqe_s *wqe;
  172. bfa_q_deq(&mod->wait_q, &wqe);
  173. if (wqe) {
  174. bfa_trc(mod->bfa, fcxp->fcxp_tag);
  175. wqe->alloc_cbfn(wqe->alloc_cbarg, fcxp);
  176. return;
  177. }
  178. bfa_assert(bfa_q_is_on_q(&mod->fcxp_active_q, fcxp));
  179. list_del(&fcxp->qe);
  180. list_add_tail(&fcxp->qe, &mod->fcxp_free_q);
  181. }
  182. static void
  183. bfa_fcxp_null_comp(void *bfad_fcxp, struct bfa_fcxp_s *fcxp, void *cbarg,
  184. bfa_status_t req_status, u32 rsp_len,
  185. u32 resid_len, struct fchs_s *rsp_fchs)
  186. {
  187. /**discarded fcxp completion */
  188. }
  189. static void
  190. __bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete)
  191. {
  192. struct bfa_fcxp_s *fcxp = cbarg;
  193. if (complete) {
  194. fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg,
  195. fcxp->rsp_status, fcxp->rsp_len,
  196. fcxp->residue_len, &fcxp->rsp_fchs);
  197. } else {
  198. bfa_fcxp_free(fcxp);
  199. }
  200. }
  201. static void
  202. hal_fcxp_send_comp(struct bfa_s *bfa, struct bfi_fcxp_send_rsp_s *fcxp_rsp)
  203. {
  204. struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
  205. struct bfa_fcxp_s *fcxp;
  206. u16 fcxp_tag = bfa_os_ntohs(fcxp_rsp->fcxp_tag);
  207. bfa_trc(bfa, fcxp_tag);
  208. fcxp_rsp->rsp_len = bfa_os_ntohl(fcxp_rsp->rsp_len);
  209. /**
  210. * @todo f/w should not set residue to non-0 when everything
  211. * is received.
  212. */
  213. if (fcxp_rsp->req_status == BFA_STATUS_OK)
  214. fcxp_rsp->residue_len = 0;
  215. else
  216. fcxp_rsp->residue_len = bfa_os_ntohl(fcxp_rsp->residue_len);
  217. fcxp = BFA_FCXP_FROM_TAG(mod, fcxp_tag);
  218. bfa_assert(fcxp->send_cbfn != NULL);
  219. hal_fcxp_rx_plog(mod->bfa, fcxp, fcxp_rsp);
  220. if (fcxp->send_cbfn != NULL) {
  221. if (fcxp->caller == NULL) {
  222. bfa_trc(mod->bfa, fcxp->fcxp_tag);
  223. fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg,
  224. fcxp_rsp->req_status, fcxp_rsp->rsp_len,
  225. fcxp_rsp->residue_len, &fcxp_rsp->fchs);
  226. /*
  227. * fcxp automatically freed on return from the callback
  228. */
  229. bfa_fcxp_free(fcxp);
  230. } else {
  231. bfa_trc(mod->bfa, fcxp->fcxp_tag);
  232. fcxp->rsp_status = fcxp_rsp->req_status;
  233. fcxp->rsp_len = fcxp_rsp->rsp_len;
  234. fcxp->residue_len = fcxp_rsp->residue_len;
  235. fcxp->rsp_fchs = fcxp_rsp->fchs;
  236. bfa_cb_queue(bfa, &fcxp->hcb_qe,
  237. __bfa_fcxp_send_cbfn, fcxp);
  238. }
  239. } else {
  240. bfa_trc(bfa, fcxp_tag);
  241. }
  242. }
  243. static void
  244. hal_fcxp_set_local_sges(struct bfi_sge_s *sge, u32 reqlen, u64 req_pa)
  245. {
  246. union bfi_addr_u sga_zero = { {0} };
  247. sge->sg_len = reqlen;
  248. sge->flags = BFI_SGE_DATA_LAST;
  249. bfa_dma_addr_set(sge[0].sga, req_pa);
  250. bfa_sge_to_be(sge);
  251. sge++;
  252. sge->sga = sga_zero;
  253. sge->sg_len = reqlen;
  254. sge->flags = BFI_SGE_PGDLEN;
  255. bfa_sge_to_be(sge);
  256. }
  257. static void
  258. hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen, struct bfa_fcxp_s *fcxp,
  259. struct fchs_s *fchs)
  260. {
  261. /*
  262. * TODO: TX ox_id
  263. */
  264. if (reqlen > 0) {
  265. if (fcxp->use_ireqbuf) {
  266. u32 pld_w0 =
  267. *((u32 *) BFA_FCXP_REQ_PLD(fcxp));
  268. bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP,
  269. BFA_PL_EID_TX,
  270. reqlen + sizeof(struct fchs_s), fchs, pld_w0);
  271. } else {
  272. bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP,
  273. BFA_PL_EID_TX, reqlen + sizeof(struct fchs_s),
  274. fchs);
  275. }
  276. } else {
  277. bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_TX,
  278. reqlen + sizeof(struct fchs_s), fchs);
  279. }
  280. }
  281. static void
  282. hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp,
  283. struct bfi_fcxp_send_rsp_s *fcxp_rsp)
  284. {
  285. if (fcxp_rsp->rsp_len > 0) {
  286. if (fcxp->use_irspbuf) {
  287. u32 pld_w0 =
  288. *((u32 *) BFA_FCXP_RSP_PLD(fcxp));
  289. bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP,
  290. BFA_PL_EID_RX,
  291. (u16) fcxp_rsp->rsp_len,
  292. &fcxp_rsp->fchs, pld_w0);
  293. } else {
  294. bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP,
  295. BFA_PL_EID_RX,
  296. (u16) fcxp_rsp->rsp_len,
  297. &fcxp_rsp->fchs);
  298. }
  299. } else {
  300. bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_RX,
  301. (u16) fcxp_rsp->rsp_len, &fcxp_rsp->fchs);
  302. }
  303. }
  304. /**
  305. * Handler to resume sending fcxp when space in available in cpe queue.
  306. */
  307. static void
  308. bfa_fcxp_qresume(void *cbarg)
  309. {
  310. struct bfa_fcxp_s *fcxp = cbarg;
  311. struct bfa_s *bfa = fcxp->fcxp_mod->bfa;
  312. struct bfi_fcxp_send_req_s *send_req;
  313. fcxp->reqq_waiting = BFA_FALSE;
  314. send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP);
  315. bfa_fcxp_queue(fcxp, send_req);
  316. }
  317. /**
  318. * Queue fcxp send request to foimrware.
  319. */
  320. static void
  321. bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req)
  322. {
  323. struct bfa_s *bfa = fcxp->fcxp_mod->bfa;
  324. struct bfa_fcxp_req_info_s *reqi = &fcxp->req_info;
  325. struct bfa_fcxp_rsp_info_s *rspi = &fcxp->rsp_info;
  326. struct bfa_rport_s *rport = reqi->bfa_rport;
  327. bfi_h2i_set(send_req->mh, BFI_MC_FCXP, BFI_FCXP_H2I_SEND_REQ,
  328. bfa_lpuid(bfa));
  329. send_req->fcxp_tag = bfa_os_htons(fcxp->fcxp_tag);
  330. if (rport) {
  331. send_req->rport_fw_hndl = rport->fw_handle;
  332. send_req->max_frmsz = bfa_os_htons(rport->rport_info.max_frmsz);
  333. if (send_req->max_frmsz == 0)
  334. send_req->max_frmsz = bfa_os_htons(FC_MAX_PDUSZ);
  335. } else {
  336. send_req->rport_fw_hndl = 0;
  337. send_req->max_frmsz = bfa_os_htons(FC_MAX_PDUSZ);
  338. }
  339. send_req->vf_id = bfa_os_htons(reqi->vf_id);
  340. send_req->lp_tag = reqi->lp_tag;
  341. send_req->class = reqi->class;
  342. send_req->rsp_timeout = rspi->rsp_timeout;
  343. send_req->cts = reqi->cts;
  344. send_req->fchs = reqi->fchs;
  345. send_req->req_len = bfa_os_htonl(reqi->req_tot_len);
  346. send_req->rsp_maxlen = bfa_os_htonl(rspi->rsp_maxlen);
  347. /*
  348. * setup req sgles
  349. */
  350. if (fcxp->use_ireqbuf == 1) {
  351. hal_fcxp_set_local_sges(send_req->req_sge, reqi->req_tot_len,
  352. BFA_FCXP_REQ_PLD_PA(fcxp));
  353. } else {
  354. if (fcxp->nreq_sgles > 0) {
  355. bfa_assert(fcxp->nreq_sgles == 1);
  356. hal_fcxp_set_local_sges(send_req->req_sge,
  357. reqi->req_tot_len,
  358. fcxp->req_sga_cbfn(fcxp->caller,
  359. 0));
  360. } else {
  361. bfa_assert(reqi->req_tot_len == 0);
  362. hal_fcxp_set_local_sges(send_req->rsp_sge, 0, 0);
  363. }
  364. }
  365. /*
  366. * setup rsp sgles
  367. */
  368. if (fcxp->use_irspbuf == 1) {
  369. bfa_assert(rspi->rsp_maxlen <= BFA_FCXP_MAX_LBUF_SZ);
  370. hal_fcxp_set_local_sges(send_req->rsp_sge, rspi->rsp_maxlen,
  371. BFA_FCXP_RSP_PLD_PA(fcxp));
  372. } else {
  373. if (fcxp->nrsp_sgles > 0) {
  374. bfa_assert(fcxp->nrsp_sgles == 1);
  375. hal_fcxp_set_local_sges(send_req->rsp_sge,
  376. rspi->rsp_maxlen,
  377. fcxp->rsp_sga_cbfn(fcxp->caller,
  378. 0));
  379. } else {
  380. bfa_assert(rspi->rsp_maxlen == 0);
  381. hal_fcxp_set_local_sges(send_req->rsp_sge, 0, 0);
  382. }
  383. }
  384. hal_fcxp_tx_plog(bfa, reqi->req_tot_len, fcxp, &reqi->fchs);
  385. bfa_reqq_produce(bfa, BFA_REQQ_FCXP);
  386. bfa_trc(bfa, bfa_reqq_pi(bfa, BFA_REQQ_FCXP));
  387. bfa_trc(bfa, bfa_reqq_ci(bfa, BFA_REQQ_FCXP));
  388. }
  389. /**
  390. * hal_fcxp_api BFA FCXP API
  391. */
  392. /**
  393. * Allocate an FCXP instance to send a response or to send a request
  394. * that has a response. Request/response buffers are allocated by caller.
  395. *
  396. * @param[in] bfa BFA bfa instance
  397. * @param[in] nreq_sgles Number of SG elements required for request
  398. * buffer. 0, if fcxp internal buffers are used.
  399. * Use bfa_fcxp_get_reqbuf() to get the
  400. * internal req buffer.
  401. * @param[in] req_sgles SG elements describing request buffer. Will be
  402. * copied in by BFA and hence can be freed on
  403. * return from this function.
  404. * @param[in] get_req_sga function ptr to be called to get a request SG
  405. * Address (given the sge index).
  406. * @param[in] get_req_sglen function ptr to be called to get a request SG
  407. * len (given the sge index).
  408. * @param[in] get_rsp_sga function ptr to be called to get a response SG
  409. * Address (given the sge index).
  410. * @param[in] get_rsp_sglen function ptr to be called to get a response SG
  411. * len (given the sge index).
  412. *
  413. * @return FCXP instance. NULL on failure.
  414. */
  415. struct bfa_fcxp_s *
  416. bfa_fcxp_alloc(void *caller, struct bfa_s *bfa, int nreq_sgles,
  417. int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn,
  418. bfa_fcxp_get_sglen_t req_sglen_cbfn,
  419. bfa_fcxp_get_sgaddr_t rsp_sga_cbfn,
  420. bfa_fcxp_get_sglen_t rsp_sglen_cbfn)
  421. {
  422. struct bfa_fcxp_s *fcxp = NULL;
  423. u32 nreq_sgpg, nrsp_sgpg;
  424. bfa_assert(bfa != NULL);
  425. fcxp = bfa_fcxp_get(BFA_FCXP_MOD(bfa));
  426. if (fcxp == NULL)
  427. return NULL;
  428. bfa_trc(bfa, fcxp->fcxp_tag);
  429. fcxp->caller = caller;
  430. if (nreq_sgles == 0) {
  431. fcxp->use_ireqbuf = 1;
  432. } else {
  433. bfa_assert(req_sga_cbfn != NULL);
  434. bfa_assert(req_sglen_cbfn != NULL);
  435. fcxp->use_ireqbuf = 0;
  436. fcxp->req_sga_cbfn = req_sga_cbfn;
  437. fcxp->req_sglen_cbfn = req_sglen_cbfn;
  438. fcxp->nreq_sgles = nreq_sgles;
  439. /*
  440. * alloc required sgpgs
  441. */
  442. if (nreq_sgles > BFI_SGE_INLINE) {
  443. nreq_sgpg = BFA_SGPG_NPAGE(nreq_sgles);
  444. if (bfa_sgpg_malloc
  445. (bfa, &fcxp->req_sgpg_q, nreq_sgpg)
  446. != BFA_STATUS_OK) {
  447. /* bfa_sgpg_wait(bfa, &fcxp->req_sgpg_wqe,
  448. nreq_sgpg); */
  449. /*
  450. * TODO
  451. */
  452. }
  453. }
  454. }
  455. if (nrsp_sgles == 0) {
  456. fcxp->use_irspbuf = 1;
  457. } else {
  458. bfa_assert(rsp_sga_cbfn != NULL);
  459. bfa_assert(rsp_sglen_cbfn != NULL);
  460. fcxp->use_irspbuf = 0;
  461. fcxp->rsp_sga_cbfn = rsp_sga_cbfn;
  462. fcxp->rsp_sglen_cbfn = rsp_sglen_cbfn;
  463. fcxp->nrsp_sgles = nrsp_sgles;
  464. /*
  465. * alloc required sgpgs
  466. */
  467. if (nrsp_sgles > BFI_SGE_INLINE) {
  468. nrsp_sgpg = BFA_SGPG_NPAGE(nreq_sgles);
  469. if (bfa_sgpg_malloc
  470. (bfa, &fcxp->rsp_sgpg_q, nrsp_sgpg)
  471. != BFA_STATUS_OK) {
  472. /* bfa_sgpg_wait(bfa, &fcxp->rsp_sgpg_wqe,
  473. nrsp_sgpg); */
  474. /*
  475. * TODO
  476. */
  477. }
  478. }
  479. }
  480. return fcxp;
  481. }
  482. /**
  483. * Get the internal request buffer pointer
  484. *
  485. * @param[in] fcxp BFA fcxp pointer
  486. *
  487. * @return pointer to the internal request buffer
  488. */
  489. void *
  490. bfa_fcxp_get_reqbuf(struct bfa_fcxp_s *fcxp)
  491. {
  492. struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
  493. void *reqbuf;
  494. bfa_assert(fcxp->use_ireqbuf == 1);
  495. reqbuf = ((u8 *)mod->req_pld_list_kva) +
  496. fcxp->fcxp_tag * mod->req_pld_sz;
  497. return reqbuf;
  498. }
  499. u32
  500. bfa_fcxp_get_reqbufsz(struct bfa_fcxp_s *fcxp)
  501. {
  502. struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
  503. return mod->req_pld_sz;
  504. }
  505. /**
  506. * Get the internal response buffer pointer
  507. *
  508. * @param[in] fcxp BFA fcxp pointer
  509. *
  510. * @return pointer to the internal request buffer
  511. */
  512. void *
  513. bfa_fcxp_get_rspbuf(struct bfa_fcxp_s *fcxp)
  514. {
  515. struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
  516. void *rspbuf;
  517. bfa_assert(fcxp->use_irspbuf == 1);
  518. rspbuf = ((u8 *)mod->rsp_pld_list_kva) +
  519. fcxp->fcxp_tag * mod->rsp_pld_sz;
  520. return rspbuf;
  521. }
  522. /**
  523. * Free the BFA FCXP
  524. *
  525. * @param[in] fcxp BFA fcxp pointer
  526. *
  527. * @return void
  528. */
  529. void
  530. bfa_fcxp_free(struct bfa_fcxp_s *fcxp)
  531. {
  532. struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
  533. bfa_assert(fcxp != NULL);
  534. bfa_trc(mod->bfa, fcxp->fcxp_tag);
  535. bfa_fcxp_put(fcxp);
  536. }
  537. /**
  538. * Send a FCXP request
  539. *
  540. * @param[in] fcxp BFA fcxp pointer
  541. * @param[in] rport BFA rport pointer. Could be left NULL for WKA rports
  542. * @param[in] vf_id virtual Fabric ID
  543. * @param[in] lp_tag lport tag
  544. * @param[in] cts use Continous sequence
  545. * @param[in] cos fc Class of Service
  546. * @param[in] reqlen request length, does not include FCHS length
  547. * @param[in] fchs fc Header Pointer. The header content will be copied
  548. * in by BFA.
  549. *
  550. * @param[in] cbfn call back function to be called on receiving
  551. * the response
  552. * @param[in] cbarg arg for cbfn
  553. * @param[in] rsp_timeout
  554. * response timeout
  555. *
  556. * @return bfa_status_t
  557. */
  558. void
  559. bfa_fcxp_send(struct bfa_fcxp_s *fcxp, struct bfa_rport_s *rport,
  560. u16 vf_id, u8 lp_tag, bfa_boolean_t cts, enum fc_cos cos,
  561. u32 reqlen, struct fchs_s *fchs, bfa_cb_fcxp_send_t cbfn,
  562. void *cbarg, u32 rsp_maxlen, u8 rsp_timeout)
  563. {
  564. struct bfa_s *bfa = fcxp->fcxp_mod->bfa;
  565. struct bfa_fcxp_req_info_s *reqi = &fcxp->req_info;
  566. struct bfa_fcxp_rsp_info_s *rspi = &fcxp->rsp_info;
  567. struct bfi_fcxp_send_req_s *send_req;
  568. bfa_trc(bfa, fcxp->fcxp_tag);
  569. /**
  570. * setup request/response info
  571. */
  572. reqi->bfa_rport = rport;
  573. reqi->vf_id = vf_id;
  574. reqi->lp_tag = lp_tag;
  575. reqi->class = cos;
  576. rspi->rsp_timeout = rsp_timeout;
  577. reqi->cts = cts;
  578. reqi->fchs = *fchs;
  579. reqi->req_tot_len = reqlen;
  580. rspi->rsp_maxlen = rsp_maxlen;
  581. fcxp->send_cbfn = cbfn ? cbfn : bfa_fcxp_null_comp;
  582. fcxp->send_cbarg = cbarg;
  583. /**
  584. * If no room in CPE queue, wait for
  585. */
  586. send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP);
  587. if (!send_req) {
  588. bfa_trc(bfa, fcxp->fcxp_tag);
  589. fcxp->reqq_waiting = BFA_TRUE;
  590. bfa_reqq_wait(bfa, BFA_REQQ_FCXP, &fcxp->reqq_wqe);
  591. return;
  592. }
  593. bfa_fcxp_queue(fcxp, send_req);
  594. }
  595. /**
  596. * Abort a BFA FCXP
  597. *
  598. * @param[in] fcxp BFA fcxp pointer
  599. *
  600. * @return void
  601. */
  602. bfa_status_t
  603. bfa_fcxp_abort(struct bfa_fcxp_s *fcxp)
  604. {
  605. bfa_assert(0);
  606. return BFA_STATUS_OK;
  607. }
  608. void
  609. bfa_fcxp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe,
  610. bfa_fcxp_alloc_cbfn_t alloc_cbfn, void *alloc_cbarg)
  611. {
  612. struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
  613. bfa_assert(list_empty(&mod->fcxp_free_q));
  614. wqe->alloc_cbfn = alloc_cbfn;
  615. wqe->alloc_cbarg = alloc_cbarg;
  616. list_add_tail(&wqe->qe, &mod->wait_q);
  617. }
  618. void
  619. bfa_fcxp_walloc_cancel(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe)
  620. {
  621. struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
  622. bfa_assert(bfa_q_is_on_q(&mod->wait_q, wqe));
  623. list_del(&wqe->qe);
  624. }
  625. void
  626. bfa_fcxp_discard(struct bfa_fcxp_s *fcxp)
  627. {
  628. /**
  629. * If waiting for room in request queue, cancel reqq wait
  630. * and free fcxp.
  631. */
  632. if (fcxp->reqq_waiting) {
  633. fcxp->reqq_waiting = BFA_FALSE;
  634. bfa_reqq_wcancel(&fcxp->reqq_wqe);
  635. bfa_fcxp_free(fcxp);
  636. return;
  637. }
  638. fcxp->send_cbfn = bfa_fcxp_null_comp;
  639. }
  640. /**
  641. * hal_fcxp_public BFA FCXP public functions
  642. */
  643. void
  644. bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
  645. {
  646. switch (msg->mhdr.msg_id) {
  647. case BFI_FCXP_I2H_SEND_RSP:
  648. hal_fcxp_send_comp(bfa, (struct bfi_fcxp_send_rsp_s *) msg);
  649. break;
  650. default:
  651. bfa_trc(bfa, msg->mhdr.msg_id);
  652. bfa_assert(0);
  653. }
  654. }
  655. u32
  656. bfa_fcxp_get_maxrsp(struct bfa_s *bfa)
  657. {
  658. struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
  659. return mod->rsp_pld_sz;
  660. }