tree-wide: fix assorted typos all over the place
[safe/jmp/linux-2.6] / drivers / scsi / bfa / bfa_fcxp.c
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 #include <bfa.h>
19 #include <bfi/bfi_uf.h>
20 #include <cs/bfa_debug.h>
21
22 BFA_TRC_FILE(HAL, FCXP);
23 BFA_MODULE(fcxp);
24
25 /**
26  * forward declarations
27  */
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);
36
37 /**
38  *  fcxp_pvt BFA FCXP private functions
39  */
40
41 static void
42 claim_fcxp_req_rsp_mem(struct bfa_fcxp_mod_s *mod, struct bfa_meminfo_s *mi)
43 {
44         u8        *dm_kva = NULL;
45         u64        dm_pa;
46         u32        buf_pool_sz;
47
48         dm_kva = bfa_meminfo_dma_virt(mi);
49         dm_pa = bfa_meminfo_dma_phys(mi);
50
51         buf_pool_sz = mod->req_pld_sz * mod->num_fcxps;
52
53         /*
54          * Initialize the fcxp req payload list
55          */
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);
61
62         /*
63          * Initialize the fcxp rsp payload list
64          */
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);
71
72         bfa_meminfo_dma_virt(mi) = dm_kva;
73         bfa_meminfo_dma_phys(mi) = dm_pa;
74 }
75
76 static void
77 claim_fcxps_mem(struct bfa_fcxp_mod_s *mod, struct bfa_meminfo_s *mi)
78 {
79         u16        i;
80         struct bfa_fcxp_s *fcxp;
81
82         fcxp = (struct bfa_fcxp_s *) bfa_meminfo_kva(mi);
83         bfa_os_memset(fcxp, 0, sizeof(struct bfa_fcxp_s) * mod->num_fcxps);
84
85         INIT_LIST_HEAD(&mod->fcxp_free_q);
86         INIT_LIST_HEAD(&mod->fcxp_active_q);
87
88         mod->fcxp_list = fcxp;
89
90         for (i = 0; i < mod->num_fcxps; i++) {
91                 fcxp->fcxp_mod = mod;
92                 fcxp->fcxp_tag = i;
93
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;
97
98                 fcxp = fcxp + 1;
99         }
100
101         bfa_meminfo_kva(mi) = (void *)fcxp;
102 }
103
104 static void
105 bfa_fcxp_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
106                 u32 *dm_len)
107 {
108         u16        num_fcxp_reqs = cfg->fwcfg.num_fcxp_reqs;
109
110         if (num_fcxp_reqs == 0)
111                 return;
112
113         /*
114          * Account for req/rsp payload
115          */
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;
121
122         /*
123          * Account for fcxp structs
124          */
125         *ndm_len += sizeof(struct bfa_fcxp_s) * num_fcxp_reqs;
126 }
127
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)
131 {
132         struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
133
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;
137
138         /**
139          * Initialize FCXP request and response payload sizes.
140          */
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;
144
145         INIT_LIST_HEAD(&mod->wait_q);
146
147         claim_fcxp_req_rsp_mem(mod, meminfo);
148         claim_fcxps_mem(mod, meminfo);
149 }
150
151 static void
152 bfa_fcxp_initdone(struct bfa_s *bfa)
153 {
154 }
155
156 static void
157 bfa_fcxp_detach(struct bfa_s *bfa)
158 {
159 }
160
161 static void
162 bfa_fcxp_start(struct bfa_s *bfa)
163 {
164 }
165
166 static void
167 bfa_fcxp_stop(struct bfa_s *bfa)
168 {
169 }
170
171 static void
172 bfa_fcxp_iocdisable(struct bfa_s *bfa)
173 {
174         struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
175         struct bfa_fcxp_s *fcxp;
176         struct list_head        *qe, *qen;
177
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);
188                 }
189         }
190 }
191
192 static struct bfa_fcxp_s *
193 bfa_fcxp_get(struct bfa_fcxp_mod_s *fm)
194 {
195         struct bfa_fcxp_s *fcxp;
196
197         bfa_q_deq(&fm->fcxp_free_q, &fcxp);
198
199         if (fcxp)
200                 list_add_tail(&fcxp->qe, &fm->fcxp_active_q);
201
202         return (fcxp);
203 }
204
205 static void
206 bfa_fcxp_put(struct bfa_fcxp_s *fcxp)
207 {
208         struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
209         struct bfa_fcxp_wqe_s *wqe;
210
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;
216         }
217
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);
221 }
222
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)
227 {
228         /**discarded fcxp completion */
229 }
230
231 static void
232 __bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete)
233 {
234         struct bfa_fcxp_s *fcxp = cbarg;
235
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);
242         }
243 }
244
245 static void
246 hal_fcxp_send_comp(struct bfa_s *bfa, struct bfi_fcxp_send_rsp_s *fcxp_rsp)
247 {
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);
251
252         bfa_trc(bfa, fcxp_tag);
253
254         fcxp_rsp->rsp_len = bfa_os_ntohl(fcxp_rsp->rsp_len);
255
256         /**
257          * @todo f/w should not set residue to non-0 when everything
258          *       is received.
259          */
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);
264
265         fcxp = BFA_FCXP_FROM_TAG(mod, fcxp_tag);
266
267         bfa_assert(fcxp->send_cbfn != NULL);
268
269         hal_fcxp_rx_plog(mod->bfa, fcxp, fcxp_rsp);
270
271         if (fcxp->send_cbfn != NULL) {
272                 if (fcxp->caller == NULL) {
273                         bfa_trc(mod->bfa, fcxp->fcxp_tag);
274
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);
278                         /*
279                          * fcxp automatically freed on return from the callback
280                          */
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;
288
289                         bfa_cb_queue(bfa, &fcxp->hcb_qe,
290                                       __bfa_fcxp_send_cbfn, fcxp);
291                 }
292         } else {
293                 bfa_trc(bfa, fcxp_tag);
294         }
295 }
296
297 static void
298 hal_fcxp_set_local_sges(struct bfi_sge_s *sge, u32 reqlen, u64 req_pa)
299 {
300         union bfi_addr_u      sga_zero = { {0} };
301
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++;
307
308         sge->sga = sga_zero;
309         sge->sg_len = reqlen;
310         sge->flags = BFI_SGE_PGDLEN;
311         bfa_sge_to_be(sge);
312 }
313
314 static void
315 hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen, struct bfa_fcxp_s *fcxp,
316                  struct fchs_s *fchs)
317 {
318         /*
319          * TODO: TX ox_id
320          */
321         if (reqlen > 0) {
322                 if (fcxp->use_ireqbuf) {
323                         u32        pld_w0 =
324                                 *((u32 *) BFA_FCXP_REQ_PLD(fcxp));
325
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);
333                 }
334         } else {
335                 bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_TX,
336                                reqlen + sizeof(struct fchs_s), fchs);
337         }
338 }
339
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)
343 {
344         if (fcxp_rsp->rsp_len > 0) {
345                 if (fcxp->use_irspbuf) {
346                         u32        pld_w0 =
347                                 *((u32 *) BFA_FCXP_RSP_PLD(fcxp));
348
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);
358                 }
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);
362         }
363 }
364
365 /**
366  * Handler to resume sending fcxp when space in available in cpe queue.
367  */
368 static void
369 bfa_fcxp_qresume(void *cbarg)
370 {
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;
374
375         fcxp->reqq_waiting = BFA_FALSE;
376         send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP);
377         bfa_fcxp_queue(fcxp, send_req);
378 }
379
380 /**
381  * Queue fcxp send request to foimrware.
382  */
383 static void
384 bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req)
385 {
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;
390
391         bfi_h2i_set(send_req->mh, BFI_MC_FCXP, BFI_FCXP_H2I_SEND_REQ,
392                         bfa_lpuid(bfa));
393
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);
403         }
404
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;
411
412         send_req->req_len = bfa_os_htonl(reqi->req_tot_len);
413         send_req->rsp_maxlen = bfa_os_htonl(rspi->rsp_maxlen);
414
415         /*
416          * setup req sgles
417          */
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);
431                 }
432         }
433
434         /*
435          * setup rsp sgles
436          */
437         if (fcxp->use_irspbuf == 1) {
438                 bfa_assert(rspi->rsp_maxlen <= BFA_FCXP_MAX_LBUF_SZ);
439
440                 hal_fcxp_set_local_sges(send_req->rsp_sge, rspi->rsp_maxlen,
441                                         BFA_FCXP_RSP_PLD_PA(fcxp));
442
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);
453                 }
454         }
455
456         hal_fcxp_tx_plog(bfa, reqi->req_tot_len, fcxp, &reqi->fchs);
457
458         bfa_reqq_produce(bfa, BFA_REQQ_FCXP);
459
460         bfa_trc(bfa, bfa_reqq_pi(bfa, BFA_REQQ_FCXP));
461         bfa_trc(bfa, bfa_reqq_ci(bfa, BFA_REQQ_FCXP));
462 }
463
464
465 /**
466  *  hal_fcxp_api BFA FCXP API
467  */
468
469 /**
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.
472  *
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).
489  *
490  * @return FCXP instance. NULL on failure.
491  */
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)
498 {
499         struct bfa_fcxp_s *fcxp = NULL;
500         u32        nreq_sgpg, nrsp_sgpg;
501
502         bfa_assert(bfa != NULL);
503
504         fcxp = bfa_fcxp_get(BFA_FCXP_MOD(bfa));
505         if (fcxp == NULL)
506                 return (NULL);
507
508         bfa_trc(bfa, fcxp->fcxp_tag);
509
510         fcxp->caller = caller;
511
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);
517
518                 fcxp->use_ireqbuf = 0;
519                 fcxp->req_sga_cbfn = req_sga_cbfn;
520                 fcxp->req_sglen_cbfn = req_sglen_cbfn;
521
522                 fcxp->nreq_sgles = nreq_sgles;
523
524                 /*
525                  * alloc required sgpgs
526                  */
527                 if (nreq_sgles > BFI_SGE_INLINE) {
528                         nreq_sgpg = BFA_SGPG_NPAGE(nreq_sgles);
529
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); */
535                                 /*
536                                  * TODO
537                                  */
538                         }
539                 }
540         }
541
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);
547
548                 fcxp->use_irspbuf = 0;
549                 fcxp->rsp_sga_cbfn = rsp_sga_cbfn;
550                 fcxp->rsp_sglen_cbfn = rsp_sglen_cbfn;
551
552                 fcxp->nrsp_sgles = nrsp_sgles;
553                 /*
554                  * alloc required sgpgs
555                  */
556                 if (nrsp_sgles > BFI_SGE_INLINE) {
557                         nrsp_sgpg = BFA_SGPG_NPAGE(nreq_sgles);
558
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); */
564                                 /*
565                                  * TODO
566                                  */
567                         }
568                 }
569         }
570
571         return (fcxp);
572 }
573
574 /**
575  * Get the internal request buffer pointer
576  *
577  * @param[in]   fcxp    BFA fcxp pointer
578  *
579  * @return              pointer to the internal request buffer
580  */
581 void *
582 bfa_fcxp_get_reqbuf(struct bfa_fcxp_s *fcxp)
583 {
584         struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
585         void    *reqbuf;
586
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;
591 }
592
593 u32
594 bfa_fcxp_get_reqbufsz(struct bfa_fcxp_s *fcxp)
595 {
596         struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
597
598         return mod->req_pld_sz;
599 }
600
601 /**
602  * Get the internal response buffer pointer
603  *
604  * @param[in]   fcxp    BFA fcxp pointer
605  *
606  * @return              pointer to the internal request buffer
607  */
608 void *
609 bfa_fcxp_get_rspbuf(struct bfa_fcxp_s *fcxp)
610 {
611         struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
612         void    *rspbuf;
613
614         bfa_assert(fcxp->use_irspbuf == 1);
615
616         rspbuf = ((u8 *)mod->rsp_pld_list_kva) +
617                         fcxp->fcxp_tag * mod->rsp_pld_sz;
618         return rspbuf;
619 }
620
621 /**
622  *              Free the BFA FCXP
623  *
624  * @param[in]   fcxp                    BFA fcxp pointer
625  *
626  * @return              void
627  */
628 void
629 bfa_fcxp_free(struct bfa_fcxp_s *fcxp)
630 {
631         struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
632
633         bfa_assert(fcxp != NULL);
634         bfa_trc(mod->bfa, fcxp->fcxp_tag);
635         bfa_fcxp_put(fcxp);
636 }
637
638 /**
639  * Send a FCXP request
640  *
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.
650  *
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
656  *
657  * @return              bfa_status_t
658  */
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)
664 {
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;
669
670         bfa_trc(bfa, fcxp->fcxp_tag);
671
672         /**
673          * setup request/response info
674          */
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;
686
687         /**
688          * If no room in CPE queue, wait for
689          */
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;
696         }
697
698         bfa_fcxp_queue(fcxp, send_req);
699 }
700
701 /**
702  * Abort a BFA FCXP
703  *
704  * @param[in]   fcxp    BFA fcxp pointer
705  *
706  * @return              void
707  */
708 bfa_status_t
709 bfa_fcxp_abort(struct bfa_fcxp_s *fcxp)
710 {
711         bfa_assert(0);
712         return (BFA_STATUS_OK);
713 }
714
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)
718 {
719         struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
720
721         bfa_assert(list_empty(&mod->fcxp_free_q));
722
723         wqe->alloc_cbfn = alloc_cbfn;
724         wqe->alloc_cbarg = alloc_cbarg;
725         list_add_tail(&wqe->qe, &mod->wait_q);
726 }
727
728 void
729 bfa_fcxp_walloc_cancel(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe)
730 {
731         struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
732
733         bfa_assert(bfa_q_is_on_q(&mod->wait_q, wqe));
734         list_del(&wqe->qe);
735 }
736
737 void
738 bfa_fcxp_discard(struct bfa_fcxp_s *fcxp)
739 {
740         /**
741          * If waiting for room in request queue, cancel reqq wait
742          * and free fcxp.
743          */
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;
749         }
750
751         fcxp->send_cbfn = bfa_fcxp_null_comp;
752 }
753
754
755
756 /**
757  *  hal_fcxp_public BFA FCXP public functions
758  */
759
760 void
761 bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
762 {
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;
767
768         default:
769                 bfa_trc(bfa, msg->mhdr.msg_id);
770                 bfa_assert(0);
771         }
772 }
773
774 u32
775 bfa_fcxp_get_maxrsp(struct bfa_s *bfa)
776 {
777         struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
778
779         return mod->rsp_pld_sz;
780 }
781
782