Full support for Ginger Console
[linux-ginger.git] / drivers / scsi / bfa / bfa_fcxp.c
blob4754a0e9006a0b1aec814cc1e15e278fc2b72690
1 /*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
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
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.
18 #include <bfa.h>
19 #include <bfi/bfi_uf.h>
20 #include <cs/bfa_debug.h>
22 BFA_TRC_FILE(HAL, FCXP);
23 BFA_MODULE(fcxp);
25 /**
26 * forward declarations
28 static void __bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete);
29 static void hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp,
30 struct bfi_fcxp_send_rsp_s *fcxp_rsp);
31 static void hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen,
32 struct bfa_fcxp_s *fcxp, struct fchs_s *fchs);
33 static void bfa_fcxp_qresume(void *cbarg);
34 static void bfa_fcxp_queue(struct bfa_fcxp_s *fcxp,
35 struct bfi_fcxp_send_req_s *send_req);
37 /**
38 * fcxp_pvt BFA FCXP private functions
41 static void
42 claim_fcxp_req_rsp_mem(struct bfa_fcxp_mod_s *mod, struct bfa_meminfo_s *mi)
44 u8 *dm_kva = NULL;
45 u64 dm_pa;
46 u32 buf_pool_sz;
48 dm_kva = bfa_meminfo_dma_virt(mi);
49 dm_pa = bfa_meminfo_dma_phys(mi);
51 buf_pool_sz = mod->req_pld_sz * mod->num_fcxps;
54 * Initialize the fcxp req payload list
56 mod->req_pld_list_kva = dm_kva;
57 mod->req_pld_list_pa = dm_pa;
58 dm_kva += buf_pool_sz;
59 dm_pa += buf_pool_sz;
60 bfa_os_memset(mod->req_pld_list_kva, 0, buf_pool_sz);
63 * Initialize the fcxp rsp payload list
65 buf_pool_sz = mod->rsp_pld_sz * mod->num_fcxps;
66 mod->rsp_pld_list_kva = dm_kva;
67 mod->rsp_pld_list_pa = dm_pa;
68 dm_kva += buf_pool_sz;
69 dm_pa += buf_pool_sz;
70 bfa_os_memset(mod->rsp_pld_list_kva, 0, buf_pool_sz);
72 bfa_meminfo_dma_virt(mi) = dm_kva;
73 bfa_meminfo_dma_phys(mi) = dm_pa;
76 static void
77 claim_fcxps_mem(struct bfa_fcxp_mod_s *mod, struct bfa_meminfo_s *mi)
79 u16 i;
80 struct bfa_fcxp_s *fcxp;
82 fcxp = (struct bfa_fcxp_s *) bfa_meminfo_kva(mi);
83 bfa_os_memset(fcxp, 0, sizeof(struct bfa_fcxp_s) * mod->num_fcxps);
85 INIT_LIST_HEAD(&mod->fcxp_free_q);
86 INIT_LIST_HEAD(&mod->fcxp_active_q);
88 mod->fcxp_list = fcxp;
90 for (i = 0; i < mod->num_fcxps; i++) {
91 fcxp->fcxp_mod = mod;
92 fcxp->fcxp_tag = i;
94 list_add_tail(&fcxp->qe, &mod->fcxp_free_q);
95 bfa_reqq_winit(&fcxp->reqq_wqe, bfa_fcxp_qresume, fcxp);
96 fcxp->reqq_waiting = BFA_FALSE;
98 fcxp = fcxp + 1;
101 bfa_meminfo_kva(mi) = (void *)fcxp;
104 static void
105 bfa_fcxp_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
106 u32 *dm_len)
108 u16 num_fcxp_reqs = cfg->fwcfg.num_fcxp_reqs;
110 if (num_fcxp_reqs == 0)
111 return;
114 * Account for req/rsp payload
116 *dm_len += BFA_FCXP_MAX_IBUF_SZ * num_fcxp_reqs;
117 if (cfg->drvcfg.min_cfg)
118 *dm_len += BFA_FCXP_MAX_IBUF_SZ * num_fcxp_reqs;
119 else
120 *dm_len += BFA_FCXP_MAX_LBUF_SZ * num_fcxp_reqs;
123 * Account for fcxp structs
125 *ndm_len += sizeof(struct bfa_fcxp_s) * num_fcxp_reqs;
128 static void
129 bfa_fcxp_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
130 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
132 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
134 bfa_os_memset(mod, 0, sizeof(struct bfa_fcxp_mod_s));
135 mod->bfa = bfa;
136 mod->num_fcxps = cfg->fwcfg.num_fcxp_reqs;
139 * Initialize FCXP request and response payload sizes.
141 mod->req_pld_sz = mod->rsp_pld_sz = BFA_FCXP_MAX_IBUF_SZ;
142 if (!cfg->drvcfg.min_cfg)
143 mod->rsp_pld_sz = BFA_FCXP_MAX_LBUF_SZ;
145 INIT_LIST_HEAD(&mod->wait_q);
147 claim_fcxp_req_rsp_mem(mod, meminfo);
148 claim_fcxps_mem(mod, meminfo);
151 static void
152 bfa_fcxp_initdone(struct bfa_s *bfa)
156 static void
157 bfa_fcxp_detach(struct bfa_s *bfa)
161 static void
162 bfa_fcxp_start(struct bfa_s *bfa)
166 static void
167 bfa_fcxp_stop(struct bfa_s *bfa)
171 static void
172 bfa_fcxp_iocdisable(struct bfa_s *bfa)
174 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
175 struct bfa_fcxp_s *fcxp;
176 struct list_head *qe, *qen;
178 list_for_each_safe(qe, qen, &mod->fcxp_active_q) {
179 fcxp = (struct bfa_fcxp_s *) qe;
180 if (fcxp->caller == NULL) {
181 fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg,
182 BFA_STATUS_IOC_FAILURE, 0, 0, NULL);
183 bfa_fcxp_free(fcxp);
184 } else {
185 fcxp->rsp_status = BFA_STATUS_IOC_FAILURE;
186 bfa_cb_queue(bfa, &fcxp->hcb_qe,
187 __bfa_fcxp_send_cbfn, fcxp);
192 static struct bfa_fcxp_s *
193 bfa_fcxp_get(struct bfa_fcxp_mod_s *fm)
195 struct bfa_fcxp_s *fcxp;
197 bfa_q_deq(&fm->fcxp_free_q, &fcxp);
199 if (fcxp)
200 list_add_tail(&fcxp->qe, &fm->fcxp_active_q);
202 return (fcxp);
205 static void
206 bfa_fcxp_put(struct bfa_fcxp_s *fcxp)
208 struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
209 struct bfa_fcxp_wqe_s *wqe;
211 bfa_q_deq(&mod->wait_q, &wqe);
212 if (wqe) {
213 bfa_trc(mod->bfa, fcxp->fcxp_tag);
214 wqe->alloc_cbfn(wqe->alloc_cbarg, fcxp);
215 return;
218 bfa_assert(bfa_q_is_on_q(&mod->fcxp_active_q, fcxp));
219 list_del(&fcxp->qe);
220 list_add_tail(&fcxp->qe, &mod->fcxp_free_q);
223 static void
224 bfa_fcxp_null_comp(void *bfad_fcxp, struct bfa_fcxp_s *fcxp, void *cbarg,
225 bfa_status_t req_status, u32 rsp_len,
226 u32 resid_len, struct fchs_s *rsp_fchs)
228 /**discarded fcxp completion */
231 static void
232 __bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete)
234 struct bfa_fcxp_s *fcxp = cbarg;
236 if (complete) {
237 fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg,
238 fcxp->rsp_status, fcxp->rsp_len,
239 fcxp->residue_len, &fcxp->rsp_fchs);
240 } else {
241 bfa_fcxp_free(fcxp);
245 static void
246 hal_fcxp_send_comp(struct bfa_s *bfa, struct bfi_fcxp_send_rsp_s *fcxp_rsp)
248 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
249 struct bfa_fcxp_s *fcxp;
250 u16 fcxp_tag = bfa_os_ntohs(fcxp_rsp->fcxp_tag);
252 bfa_trc(bfa, fcxp_tag);
254 fcxp_rsp->rsp_len = bfa_os_ntohl(fcxp_rsp->rsp_len);
257 * @todo f/w should not set residue to non-0 when everything
258 * is received.
260 if (fcxp_rsp->req_status == BFA_STATUS_OK)
261 fcxp_rsp->residue_len = 0;
262 else
263 fcxp_rsp->residue_len = bfa_os_ntohl(fcxp_rsp->residue_len);
265 fcxp = BFA_FCXP_FROM_TAG(mod, fcxp_tag);
267 bfa_assert(fcxp->send_cbfn != NULL);
269 hal_fcxp_rx_plog(mod->bfa, fcxp, fcxp_rsp);
271 if (fcxp->send_cbfn != NULL) {
272 if (fcxp->caller == NULL) {
273 bfa_trc(mod->bfa, fcxp->fcxp_tag);
275 fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg,
276 fcxp_rsp->req_status, fcxp_rsp->rsp_len,
277 fcxp_rsp->residue_len, &fcxp_rsp->fchs);
279 * fcxp automatically freed on return from the callback
281 bfa_fcxp_free(fcxp);
282 } else {
283 bfa_trc(mod->bfa, fcxp->fcxp_tag);
284 fcxp->rsp_status = fcxp_rsp->req_status;
285 fcxp->rsp_len = fcxp_rsp->rsp_len;
286 fcxp->residue_len = fcxp_rsp->residue_len;
287 fcxp->rsp_fchs = fcxp_rsp->fchs;
289 bfa_cb_queue(bfa, &fcxp->hcb_qe,
290 __bfa_fcxp_send_cbfn, fcxp);
292 } else {
293 bfa_trc(bfa, fcxp_tag);
297 static void
298 hal_fcxp_set_local_sges(struct bfi_sge_s *sge, u32 reqlen, u64 req_pa)
300 union bfi_addr_u sga_zero = { {0} };
302 sge->sg_len = reqlen;
303 sge->flags = BFI_SGE_DATA_LAST;
304 bfa_dma_addr_set(sge[0].sga, req_pa);
305 bfa_sge_to_be(sge);
306 sge++;
308 sge->sga = sga_zero;
309 sge->sg_len = reqlen;
310 sge->flags = BFI_SGE_PGDLEN;
311 bfa_sge_to_be(sge);
314 static void
315 hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen, struct bfa_fcxp_s *fcxp,
316 struct fchs_s *fchs)
319 * TODO: TX ox_id
321 if (reqlen > 0) {
322 if (fcxp->use_ireqbuf) {
323 u32 pld_w0 =
324 *((u32 *) BFA_FCXP_REQ_PLD(fcxp));
326 bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP,
327 BFA_PL_EID_TX,
328 reqlen + sizeof(struct fchs_s), fchs, pld_w0);
329 } else {
330 bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP,
331 BFA_PL_EID_TX, reqlen + sizeof(struct fchs_s),
332 fchs);
334 } else {
335 bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_TX,
336 reqlen + sizeof(struct fchs_s), fchs);
340 static void
341 hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp,
342 struct bfi_fcxp_send_rsp_s *fcxp_rsp)
344 if (fcxp_rsp->rsp_len > 0) {
345 if (fcxp->use_irspbuf) {
346 u32 pld_w0 =
347 *((u32 *) BFA_FCXP_RSP_PLD(fcxp));
349 bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP,
350 BFA_PL_EID_RX,
351 (u16) fcxp_rsp->rsp_len,
352 &fcxp_rsp->fchs, pld_w0);
353 } else {
354 bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP,
355 BFA_PL_EID_RX,
356 (u16) fcxp_rsp->rsp_len,
357 &fcxp_rsp->fchs);
359 } else {
360 bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_RX,
361 (u16) fcxp_rsp->rsp_len, &fcxp_rsp->fchs);
366 * Handler to resume sending fcxp when space in available in cpe queue.
368 static void
369 bfa_fcxp_qresume(void *cbarg)
371 struct bfa_fcxp_s *fcxp = cbarg;
372 struct bfa_s *bfa = fcxp->fcxp_mod->bfa;
373 struct bfi_fcxp_send_req_s *send_req;
375 fcxp->reqq_waiting = BFA_FALSE;
376 send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP);
377 bfa_fcxp_queue(fcxp, send_req);
381 * Queue fcxp send request to foimrware.
383 static void
384 bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req)
386 struct bfa_s *bfa = fcxp->fcxp_mod->bfa;
387 struct bfa_fcxp_req_info_s *reqi = &fcxp->req_info;
388 struct bfa_fcxp_rsp_info_s *rspi = &fcxp->rsp_info;
389 struct bfa_rport_s *rport = reqi->bfa_rport;
391 bfi_h2i_set(send_req->mh, BFI_MC_FCXP, BFI_FCXP_H2I_SEND_REQ,
392 bfa_lpuid(bfa));
394 send_req->fcxp_tag = bfa_os_htons(fcxp->fcxp_tag);
395 if (rport) {
396 send_req->rport_fw_hndl = rport->fw_handle;
397 send_req->max_frmsz = bfa_os_htons(rport->rport_info.max_frmsz);
398 if (send_req->max_frmsz == 0)
399 send_req->max_frmsz = bfa_os_htons(FC_MAX_PDUSZ);
400 } else {
401 send_req->rport_fw_hndl = 0;
402 send_req->max_frmsz = bfa_os_htons(FC_MAX_PDUSZ);
405 send_req->vf_id = bfa_os_htons(reqi->vf_id);
406 send_req->lp_tag = reqi->lp_tag;
407 send_req->class = reqi->class;
408 send_req->rsp_timeout = rspi->rsp_timeout;
409 send_req->cts = reqi->cts;
410 send_req->fchs = reqi->fchs;
412 send_req->req_len = bfa_os_htonl(reqi->req_tot_len);
413 send_req->rsp_maxlen = bfa_os_htonl(rspi->rsp_maxlen);
416 * setup req sgles
418 if (fcxp->use_ireqbuf == 1) {
419 hal_fcxp_set_local_sges(send_req->req_sge, reqi->req_tot_len,
420 BFA_FCXP_REQ_PLD_PA(fcxp));
421 } else {
422 if (fcxp->nreq_sgles > 0) {
423 bfa_assert(fcxp->nreq_sgles == 1);
424 hal_fcxp_set_local_sges(send_req->req_sge,
425 reqi->req_tot_len,
426 fcxp->req_sga_cbfn(fcxp->caller,
427 0));
428 } else {
429 bfa_assert(reqi->req_tot_len == 0);
430 hal_fcxp_set_local_sges(send_req->rsp_sge, 0, 0);
435 * setup rsp sgles
437 if (fcxp->use_irspbuf == 1) {
438 bfa_assert(rspi->rsp_maxlen <= BFA_FCXP_MAX_LBUF_SZ);
440 hal_fcxp_set_local_sges(send_req->rsp_sge, rspi->rsp_maxlen,
441 BFA_FCXP_RSP_PLD_PA(fcxp));
443 } else {
444 if (fcxp->nrsp_sgles > 0) {
445 bfa_assert(fcxp->nrsp_sgles == 1);
446 hal_fcxp_set_local_sges(send_req->rsp_sge,
447 rspi->rsp_maxlen,
448 fcxp->rsp_sga_cbfn(fcxp->caller,
449 0));
450 } else {
451 bfa_assert(rspi->rsp_maxlen == 0);
452 hal_fcxp_set_local_sges(send_req->rsp_sge, 0, 0);
456 hal_fcxp_tx_plog(bfa, reqi->req_tot_len, fcxp, &reqi->fchs);
458 bfa_reqq_produce(bfa, BFA_REQQ_FCXP);
460 bfa_trc(bfa, bfa_reqq_pi(bfa, BFA_REQQ_FCXP));
461 bfa_trc(bfa, bfa_reqq_ci(bfa, BFA_REQQ_FCXP));
466 * hal_fcxp_api BFA FCXP API
470 * Allocate an FCXP instance to send a response or to send a request
471 * that has a response. Request/response buffers are allocated by caller.
473 * @param[in] bfa BFA bfa instance
474 * @param[in] nreq_sgles Number of SG elements required for request
475 * buffer. 0, if fcxp internal buffers are used.
476 * Use bfa_fcxp_get_reqbuf() to get the
477 * internal req buffer.
478 * @param[in] req_sgles SG elements describing request buffer. Will be
479 * copied in by BFA and hence can be freed on
480 * return from this function.
481 * @param[in] get_req_sga function ptr to be called to get a request SG
482 * Address (given the sge index).
483 * @param[in] get_req_sglen function ptr to be called to get a request SG
484 * len (given the sge index).
485 * @param[in] get_rsp_sga function ptr to be called to get a response SG
486 * Address (given the sge index).
487 * @param[in] get_rsp_sglen function ptr to be called to get a response SG
488 * len (given the sge index).
490 * @return FCXP instance. NULL on failure.
492 struct bfa_fcxp_s *
493 bfa_fcxp_alloc(void *caller, struct bfa_s *bfa, int nreq_sgles,
494 int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn,
495 bfa_fcxp_get_sglen_t req_sglen_cbfn,
496 bfa_fcxp_get_sgaddr_t rsp_sga_cbfn,
497 bfa_fcxp_get_sglen_t rsp_sglen_cbfn)
499 struct bfa_fcxp_s *fcxp = NULL;
500 u32 nreq_sgpg, nrsp_sgpg;
502 bfa_assert(bfa != NULL);
504 fcxp = bfa_fcxp_get(BFA_FCXP_MOD(bfa));
505 if (fcxp == NULL)
506 return (NULL);
508 bfa_trc(bfa, fcxp->fcxp_tag);
510 fcxp->caller = caller;
512 if (nreq_sgles == 0) {
513 fcxp->use_ireqbuf = 1;
514 } else {
515 bfa_assert(req_sga_cbfn != NULL);
516 bfa_assert(req_sglen_cbfn != NULL);
518 fcxp->use_ireqbuf = 0;
519 fcxp->req_sga_cbfn = req_sga_cbfn;
520 fcxp->req_sglen_cbfn = req_sglen_cbfn;
522 fcxp->nreq_sgles = nreq_sgles;
525 * alloc required sgpgs
527 if (nreq_sgles > BFI_SGE_INLINE) {
528 nreq_sgpg = BFA_SGPG_NPAGE(nreq_sgles);
530 if (bfa_sgpg_malloc
531 (bfa, &fcxp->req_sgpg_q, nreq_sgpg)
532 != BFA_STATUS_OK) {
533 /* bfa_sgpg_wait(bfa, &fcxp->req_sgpg_wqe,
534 nreq_sgpg); */
536 * TODO
542 if (nrsp_sgles == 0) {
543 fcxp->use_irspbuf = 1;
544 } else {
545 bfa_assert(rsp_sga_cbfn != NULL);
546 bfa_assert(rsp_sglen_cbfn != NULL);
548 fcxp->use_irspbuf = 0;
549 fcxp->rsp_sga_cbfn = rsp_sga_cbfn;
550 fcxp->rsp_sglen_cbfn = rsp_sglen_cbfn;
552 fcxp->nrsp_sgles = nrsp_sgles;
554 * alloc required sgpgs
556 if (nrsp_sgles > BFI_SGE_INLINE) {
557 nrsp_sgpg = BFA_SGPG_NPAGE(nreq_sgles);
559 if (bfa_sgpg_malloc
560 (bfa, &fcxp->rsp_sgpg_q, nrsp_sgpg)
561 != BFA_STATUS_OK) {
562 /* bfa_sgpg_wait(bfa, &fcxp->rsp_sgpg_wqe,
563 nrsp_sgpg); */
565 * TODO
571 return (fcxp);
575 * Get the internal request buffer pointer
577 * @param[in] fcxp BFA fcxp pointer
579 * @return pointer to the internal request buffer
581 void *
582 bfa_fcxp_get_reqbuf(struct bfa_fcxp_s *fcxp)
584 struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
585 void *reqbuf;
587 bfa_assert(fcxp->use_ireqbuf == 1);
588 reqbuf = ((u8 *)mod->req_pld_list_kva) +
589 fcxp->fcxp_tag * mod->req_pld_sz;
590 return reqbuf;
594 bfa_fcxp_get_reqbufsz(struct bfa_fcxp_s *fcxp)
596 struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
598 return mod->req_pld_sz;
602 * Get the internal response buffer pointer
604 * @param[in] fcxp BFA fcxp pointer
606 * @return pointer to the internal request buffer
608 void *
609 bfa_fcxp_get_rspbuf(struct bfa_fcxp_s *fcxp)
611 struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
612 void *rspbuf;
614 bfa_assert(fcxp->use_irspbuf == 1);
616 rspbuf = ((u8 *)mod->rsp_pld_list_kva) +
617 fcxp->fcxp_tag * mod->rsp_pld_sz;
618 return rspbuf;
622 * Free the BFA FCXP
624 * @param[in] fcxp BFA fcxp pointer
626 * @return void
628 void
629 bfa_fcxp_free(struct bfa_fcxp_s *fcxp)
631 struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
633 bfa_assert(fcxp != NULL);
634 bfa_trc(mod->bfa, fcxp->fcxp_tag);
635 bfa_fcxp_put(fcxp);
639 * Send a FCXP request
641 * @param[in] fcxp BFA fcxp pointer
642 * @param[in] rport BFA rport pointer. Could be left NULL for WKA rports
643 * @param[in] vf_id virtual Fabric ID
644 * @param[in] lp_tag lport tag
645 * @param[in] cts use Continous sequence
646 * @param[in] cos fc Class of Service
647 * @param[in] reqlen request length, does not include FCHS length
648 * @param[in] fchs fc Header Pointer. The header content will be copied
649 * in by BFA.
651 * @param[in] cbfn call back function to be called on receiving
652 * the response
653 * @param[in] cbarg arg for cbfn
654 * @param[in] rsp_timeout
655 * response timeout
657 * @return bfa_status_t
659 void
660 bfa_fcxp_send(struct bfa_fcxp_s *fcxp, struct bfa_rport_s *rport,
661 u16 vf_id, u8 lp_tag, bfa_boolean_t cts, enum fc_cos cos,
662 u32 reqlen, struct fchs_s *fchs, bfa_cb_fcxp_send_t cbfn,
663 void *cbarg, u32 rsp_maxlen, u8 rsp_timeout)
665 struct bfa_s *bfa = fcxp->fcxp_mod->bfa;
666 struct bfa_fcxp_req_info_s *reqi = &fcxp->req_info;
667 struct bfa_fcxp_rsp_info_s *rspi = &fcxp->rsp_info;
668 struct bfi_fcxp_send_req_s *send_req;
670 bfa_trc(bfa, fcxp->fcxp_tag);
673 * setup request/response info
675 reqi->bfa_rport = rport;
676 reqi->vf_id = vf_id;
677 reqi->lp_tag = lp_tag;
678 reqi->class = cos;
679 rspi->rsp_timeout = rsp_timeout;
680 reqi->cts = cts;
681 reqi->fchs = *fchs;
682 reqi->req_tot_len = reqlen;
683 rspi->rsp_maxlen = rsp_maxlen;
684 fcxp->send_cbfn = cbfn ? cbfn : bfa_fcxp_null_comp;
685 fcxp->send_cbarg = cbarg;
688 * If no room in CPE queue, wait for
690 send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP);
691 if (!send_req) {
692 bfa_trc(bfa, fcxp->fcxp_tag);
693 fcxp->reqq_waiting = BFA_TRUE;
694 bfa_reqq_wait(bfa, BFA_REQQ_FCXP, &fcxp->reqq_wqe);
695 return;
698 bfa_fcxp_queue(fcxp, send_req);
702 * Abort a BFA FCXP
704 * @param[in] fcxp BFA fcxp pointer
706 * @return void
708 bfa_status_t
709 bfa_fcxp_abort(struct bfa_fcxp_s *fcxp)
711 bfa_assert(0);
712 return (BFA_STATUS_OK);
715 void
716 bfa_fcxp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe,
717 bfa_fcxp_alloc_cbfn_t alloc_cbfn, void *alloc_cbarg)
719 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
721 bfa_assert(list_empty(&mod->fcxp_free_q));
723 wqe->alloc_cbfn = alloc_cbfn;
724 wqe->alloc_cbarg = alloc_cbarg;
725 list_add_tail(&wqe->qe, &mod->wait_q);
728 void
729 bfa_fcxp_walloc_cancel(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe)
731 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
733 bfa_assert(bfa_q_is_on_q(&mod->wait_q, wqe));
734 list_del(&wqe->qe);
737 void
738 bfa_fcxp_discard(struct bfa_fcxp_s *fcxp)
741 * If waiting for room in request queue, cancel reqq wait
742 * and free fcxp.
744 if (fcxp->reqq_waiting) {
745 fcxp->reqq_waiting = BFA_FALSE;
746 bfa_reqq_wcancel(&fcxp->reqq_wqe);
747 bfa_fcxp_free(fcxp);
748 return;
751 fcxp->send_cbfn = bfa_fcxp_null_comp;
757 * hal_fcxp_public BFA FCXP public functions
760 void
761 bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
763 switch (msg->mhdr.msg_id) {
764 case BFI_FCXP_I2H_SEND_RSP:
765 hal_fcxp_send_comp(bfa, (struct bfi_fcxp_send_rsp_s *) msg);
766 break;
768 default:
769 bfa_trc(bfa, msg->mhdr.msg_id);
770 bfa_assert(0);
775 bfa_fcxp_get_maxrsp(struct bfa_s *bfa)
777 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
779 return mod->rsp_pld_sz;