bfa_uf.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  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. /**
  18. * bfa_uf.c BFA unsolicited frame receive implementation
  19. */
  20. #include <bfa.h>
  21. #include <bfa_svc.h>
  22. #include <bfi/bfi_uf.h>
  23. #include <cs/bfa_debug.h>
  24. BFA_TRC_FILE(HAL, UF);
  25. BFA_MODULE(uf);
  26. /*
  27. *****************************************************************************
  28. * Internal functions
  29. *****************************************************************************
  30. */
  31. static void
  32. __bfa_cb_uf_recv(void *cbarg, bfa_boolean_t complete)
  33. {
  34. struct bfa_uf_s *uf = cbarg;
  35. struct bfa_uf_mod_s *ufm = BFA_UF_MOD(uf->bfa);
  36. if (complete)
  37. ufm->ufrecv(ufm->cbarg, uf);
  38. }
  39. static void
  40. claim_uf_pbs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi)
  41. {
  42. u32 uf_pb_tot_sz;
  43. ufm->uf_pbs_kva = (struct bfa_uf_buf_s *) bfa_meminfo_dma_virt(mi);
  44. ufm->uf_pbs_pa = bfa_meminfo_dma_phys(mi);
  45. uf_pb_tot_sz = BFA_ROUNDUP((sizeof(struct bfa_uf_buf_s) * ufm->num_ufs),
  46. BFA_DMA_ALIGN_SZ);
  47. bfa_meminfo_dma_virt(mi) += uf_pb_tot_sz;
  48. bfa_meminfo_dma_phys(mi) += uf_pb_tot_sz;
  49. bfa_os_memset((void *)ufm->uf_pbs_kva, 0, uf_pb_tot_sz);
  50. }
  51. static void
  52. claim_uf_post_msgs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi)
  53. {
  54. struct bfi_uf_buf_post_s *uf_bp_msg;
  55. struct bfi_sge_s *sge;
  56. union bfi_addr_u sga_zero = { {0} };
  57. u16 i;
  58. u16 buf_len;
  59. ufm->uf_buf_posts = (struct bfi_uf_buf_post_s *) bfa_meminfo_kva(mi);
  60. uf_bp_msg = ufm->uf_buf_posts;
  61. for (i = 0, uf_bp_msg = ufm->uf_buf_posts; i < ufm->num_ufs;
  62. i++, uf_bp_msg++) {
  63. bfa_os_memset(uf_bp_msg, 0, sizeof(struct bfi_uf_buf_post_s));
  64. uf_bp_msg->buf_tag = i;
  65. buf_len = sizeof(struct bfa_uf_buf_s);
  66. uf_bp_msg->buf_len = bfa_os_htons(buf_len);
  67. bfi_h2i_set(uf_bp_msg->mh, BFI_MC_UF, BFI_UF_H2I_BUF_POST,
  68. bfa_lpuid(ufm->bfa));
  69. sge = uf_bp_msg->sge;
  70. sge[0].sg_len = buf_len;
  71. sge[0].flags = BFI_SGE_DATA_LAST;
  72. bfa_dma_addr_set(sge[0].sga, ufm_pbs_pa(ufm, i));
  73. bfa_sge_to_be(sge);
  74. sge[1].sg_len = buf_len;
  75. sge[1].flags = BFI_SGE_PGDLEN;
  76. sge[1].sga = sga_zero;
  77. bfa_sge_to_be(&sge[1]);
  78. }
  79. /**
  80. * advance pointer beyond consumed memory
  81. */
  82. bfa_meminfo_kva(mi) = (u8 *) uf_bp_msg;
  83. }
  84. static void
  85. claim_ufs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi)
  86. {
  87. u16 i;
  88. struct bfa_uf_s *uf;
  89. /*
  90. * Claim block of memory for UF list
  91. */
  92. ufm->uf_list = (struct bfa_uf_s *) bfa_meminfo_kva(mi);
  93. /*
  94. * Initialize UFs and queue it in UF free queue
  95. */
  96. for (i = 0, uf = ufm->uf_list; i < ufm->num_ufs; i++, uf++) {
  97. bfa_os_memset(uf, 0, sizeof(struct bfa_uf_s));
  98. uf->bfa = ufm->bfa;
  99. uf->uf_tag = i;
  100. uf->pb_len = sizeof(struct bfa_uf_buf_s);
  101. uf->buf_kva = (void *)&ufm->uf_pbs_kva[i];
  102. uf->buf_pa = ufm_pbs_pa(ufm, i);
  103. list_add_tail(&uf->qe, &ufm->uf_free_q);
  104. }
  105. /**
  106. * advance memory pointer
  107. */
  108. bfa_meminfo_kva(mi) = (u8 *) uf;
  109. }
  110. static void
  111. uf_mem_claim(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi)
  112. {
  113. claim_uf_pbs(ufm, mi);
  114. claim_ufs(ufm, mi);
  115. claim_uf_post_msgs(ufm, mi);
  116. }
  117. static void
  118. bfa_uf_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, u32 *dm_len)
  119. {
  120. u32 num_ufs = cfg->fwcfg.num_uf_bufs;
  121. /*
  122. * dma-able memory for UF posted bufs
  123. */
  124. *dm_len += BFA_ROUNDUP((sizeof(struct bfa_uf_buf_s) * num_ufs),
  125. BFA_DMA_ALIGN_SZ);
  126. /*
  127. * kernel Virtual memory for UFs and UF buf post msg copies
  128. */
  129. *ndm_len += sizeof(struct bfa_uf_s) * num_ufs;
  130. *ndm_len += sizeof(struct bfi_uf_buf_post_s) * num_ufs;
  131. }
  132. static void
  133. bfa_uf_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
  134. struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
  135. {
  136. struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa);
  137. bfa_os_memset(ufm, 0, sizeof(struct bfa_uf_mod_s));
  138. ufm->bfa = bfa;
  139. ufm->num_ufs = cfg->fwcfg.num_uf_bufs;
  140. INIT_LIST_HEAD(&ufm->uf_free_q);
  141. INIT_LIST_HEAD(&ufm->uf_posted_q);
  142. uf_mem_claim(ufm, meminfo);
  143. }
  144. static void
  145. bfa_uf_initdone(struct bfa_s *bfa)
  146. {
  147. }
  148. static void
  149. bfa_uf_detach(struct bfa_s *bfa)
  150. {
  151. }
  152. static struct bfa_uf_s *
  153. bfa_uf_get(struct bfa_uf_mod_s *uf_mod)
  154. {
  155. struct bfa_uf_s *uf;
  156. bfa_q_deq(&uf_mod->uf_free_q, &uf);
  157. return uf;
  158. }
  159. static void
  160. bfa_uf_put(struct bfa_uf_mod_s *uf_mod, struct bfa_uf_s *uf)
  161. {
  162. list_add_tail(&uf->qe, &uf_mod->uf_free_q);
  163. }
  164. static bfa_status_t
  165. bfa_uf_post(struct bfa_uf_mod_s *ufm, struct bfa_uf_s *uf)
  166. {
  167. struct bfi_uf_buf_post_s *uf_post_msg;
  168. uf_post_msg = bfa_reqq_next(ufm->bfa, BFA_REQQ_FCXP);
  169. if (!uf_post_msg)
  170. return BFA_STATUS_FAILED;
  171. bfa_os_memcpy(uf_post_msg, &ufm->uf_buf_posts[uf->uf_tag],
  172. sizeof(struct bfi_uf_buf_post_s));
  173. bfa_reqq_produce(ufm->bfa, BFA_REQQ_FCXP);
  174. bfa_trc(ufm->bfa, uf->uf_tag);
  175. list_add_tail(&uf->qe, &ufm->uf_posted_q);
  176. return BFA_STATUS_OK;
  177. }
  178. static void
  179. bfa_uf_post_all(struct bfa_uf_mod_s *uf_mod)
  180. {
  181. struct bfa_uf_s *uf;
  182. while ((uf = bfa_uf_get(uf_mod)) != NULL) {
  183. if (bfa_uf_post(uf_mod, uf) != BFA_STATUS_OK)
  184. break;
  185. }
  186. }
  187. static void
  188. uf_recv(struct bfa_s *bfa, struct bfi_uf_frm_rcvd_s *m)
  189. {
  190. struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa);
  191. u16 uf_tag = m->buf_tag;
  192. struct bfa_uf_buf_s *uf_buf = &ufm->uf_pbs_kva[uf_tag];
  193. struct bfa_uf_s *uf = &ufm->uf_list[uf_tag];
  194. u8 *buf = &uf_buf->d[0];
  195. struct fchs_s *fchs;
  196. m->frm_len = bfa_os_ntohs(m->frm_len);
  197. m->xfr_len = bfa_os_ntohs(m->xfr_len);
  198. fchs = (struct fchs_s *) uf_buf;
  199. list_del(&uf->qe); /* dequeue from posted queue */
  200. uf->data_ptr = buf;
  201. uf->data_len = m->xfr_len;
  202. bfa_assert(uf->data_len >= sizeof(struct fchs_s));
  203. if (uf->data_len == sizeof(struct fchs_s)) {
  204. bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_UF, BFA_PL_EID_RX,
  205. uf->data_len, (struct fchs_s *) buf);
  206. } else {
  207. u32 pld_w0 = *((u32 *) (buf + sizeof(struct fchs_s)));
  208. bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_UF,
  209. BFA_PL_EID_RX, uf->data_len,
  210. (struct fchs_s *) buf, pld_w0);
  211. }
  212. bfa_cb_queue(bfa, &uf->hcb_qe, __bfa_cb_uf_recv, uf);
  213. }
  214. static void
  215. bfa_uf_stop(struct bfa_s *bfa)
  216. {
  217. }
  218. static void
  219. bfa_uf_iocdisable(struct bfa_s *bfa)
  220. {
  221. struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa);
  222. struct bfa_uf_s *uf;
  223. struct list_head *qe, *qen;
  224. list_for_each_safe(qe, qen, &ufm->uf_posted_q) {
  225. uf = (struct bfa_uf_s *) qe;
  226. list_del(&uf->qe);
  227. bfa_uf_put(ufm, uf);
  228. }
  229. }
  230. static void
  231. bfa_uf_start(struct bfa_s *bfa)
  232. {
  233. bfa_uf_post_all(BFA_UF_MOD(bfa));
  234. }
  235. /**
  236. * bfa_uf_api
  237. */
  238. /**
  239. * Register handler for all unsolicted recieve frames.
  240. *
  241. * @param[in] bfa BFA instance
  242. * @param[in] ufrecv receive handler function
  243. * @param[in] cbarg receive handler arg
  244. */
  245. void
  246. bfa_uf_recv_register(struct bfa_s *bfa, bfa_cb_uf_recv_t ufrecv, void *cbarg)
  247. {
  248. struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa);
  249. ufm->ufrecv = ufrecv;
  250. ufm->cbarg = cbarg;
  251. }
  252. /**
  253. * Free an unsolicited frame back to BFA.
  254. *
  255. * @param[in] uf unsolicited frame to be freed
  256. *
  257. * @return None
  258. */
  259. void
  260. bfa_uf_free(struct bfa_uf_s *uf)
  261. {
  262. bfa_uf_put(BFA_UF_MOD(uf->bfa), uf);
  263. bfa_uf_post_all(BFA_UF_MOD(uf->bfa));
  264. }
  265. /**
  266. * uf_pub BFA uf module public functions
  267. */
  268. void
  269. bfa_uf_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
  270. {
  271. bfa_trc(bfa, msg->mhdr.msg_id);
  272. switch (msg->mhdr.msg_id) {
  273. case BFI_UF_I2H_FRM_RCVD:
  274. uf_recv(bfa, (struct bfi_uf_frm_rcvd_s *) msg);
  275. break;
  276. default:
  277. bfa_trc(bfa, msg->mhdr.msg_id);
  278. bfa_assert(0);
  279. }
  280. }