[SCSI] bfa: Added HBA diagnostics support.
[firefly-linux-kernel-4.4.55.git] / drivers / scsi / bfa / bfa_core.c
1 /*
2  * Copyright (c) 2005-2010 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 "bfad_drv.h"
19 #include "bfa_modules.h"
20 #include "bfi_reg.h"
21
22 BFA_TRC_FILE(HAL, CORE);
23
24 /*
25  * BFA module list terminated by NULL
26  */
27 static struct bfa_module_s *hal_mods[] = {
28         &hal_mod_fcdiag,
29         &hal_mod_sgpg,
30         &hal_mod_fcport,
31         &hal_mod_fcxp,
32         &hal_mod_lps,
33         &hal_mod_uf,
34         &hal_mod_rport,
35         &hal_mod_fcp,
36         NULL
37 };
38
39 /*
40  * Message handlers for various modules.
41  */
42 static bfa_isr_func_t  bfa_isrs[BFI_MC_MAX] = {
43         bfa_isr_unhandled,      /* NONE */
44         bfa_isr_unhandled,      /* BFI_MC_IOC */
45         bfa_fcdiag_intr,        /* BFI_MC_DIAG */
46         bfa_isr_unhandled,      /* BFI_MC_FLASH */
47         bfa_isr_unhandled,      /* BFI_MC_CEE */
48         bfa_fcport_isr,         /* BFI_MC_FCPORT */
49         bfa_isr_unhandled,      /* BFI_MC_IOCFC */
50         bfa_isr_unhandled,      /* BFI_MC_LL */
51         bfa_uf_isr,             /* BFI_MC_UF */
52         bfa_fcxp_isr,           /* BFI_MC_FCXP */
53         bfa_lps_isr,            /* BFI_MC_LPS */
54         bfa_rport_isr,          /* BFI_MC_RPORT */
55         bfa_itn_isr,            /* BFI_MC_ITN */
56         bfa_isr_unhandled,      /* BFI_MC_IOIM_READ */
57         bfa_isr_unhandled,      /* BFI_MC_IOIM_WRITE */
58         bfa_isr_unhandled,      /* BFI_MC_IOIM_IO */
59         bfa_ioim_isr,           /* BFI_MC_IOIM */
60         bfa_ioim_good_comp_isr, /* BFI_MC_IOIM_IOCOM */
61         bfa_tskim_isr,          /* BFI_MC_TSKIM */
62         bfa_isr_unhandled,      /* BFI_MC_SBOOT */
63         bfa_isr_unhandled,      /* BFI_MC_IPFC */
64         bfa_isr_unhandled,      /* BFI_MC_PORT */
65         bfa_isr_unhandled,      /* --------- */
66         bfa_isr_unhandled,      /* --------- */
67         bfa_isr_unhandled,      /* --------- */
68         bfa_isr_unhandled,      /* --------- */
69         bfa_isr_unhandled,      /* --------- */
70         bfa_isr_unhandled,      /* --------- */
71         bfa_isr_unhandled,      /* --------- */
72         bfa_isr_unhandled,      /* --------- */
73         bfa_isr_unhandled,      /* --------- */
74         bfa_isr_unhandled,      /* --------- */
75 };
76 /*
77  * Message handlers for mailbox command classes
78  */
79 static bfa_ioc_mbox_mcfunc_t  bfa_mbox_isrs[BFI_MC_MAX] = {
80         NULL,
81         NULL,           /* BFI_MC_IOC   */
82         NULL,           /* BFI_MC_DIAG  */
83         NULL,           /* BFI_MC_FLASH */
84         NULL,           /* BFI_MC_CEE   */
85         NULL,           /* BFI_MC_PORT  */
86         bfa_iocfc_isr,  /* BFI_MC_IOCFC */
87         NULL,
88 };
89
90
91
92 static void
93 bfa_com_port_attach(struct bfa_s *bfa)
94 {
95         struct bfa_port_s       *port = &bfa->modules.port;
96         struct bfa_mem_dma_s    *port_dma = BFA_MEM_PORT_DMA(bfa);
97
98         bfa_port_attach(port, &bfa->ioc, bfa, bfa->trcmod);
99         bfa_port_mem_claim(port, port_dma->kva_curp, port_dma->dma_curp);
100 }
101
102 /*
103  * ablk module attach
104  */
105 static void
106 bfa_com_ablk_attach(struct bfa_s *bfa)
107 {
108         struct bfa_ablk_s       *ablk = &bfa->modules.ablk;
109         struct bfa_mem_dma_s    *ablk_dma = BFA_MEM_ABLK_DMA(bfa);
110
111         bfa_ablk_attach(ablk, &bfa->ioc);
112         bfa_ablk_memclaim(ablk, ablk_dma->kva_curp, ablk_dma->dma_curp);
113 }
114
115 static void
116 bfa_com_cee_attach(struct bfa_s *bfa)
117 {
118         struct bfa_cee_s        *cee = &bfa->modules.cee;
119         struct bfa_mem_dma_s    *cee_dma = BFA_MEM_CEE_DMA(bfa);
120
121         cee->trcmod = bfa->trcmod;
122         bfa_cee_attach(cee, &bfa->ioc, bfa);
123         bfa_cee_mem_claim(cee, cee_dma->kva_curp, cee_dma->dma_curp);
124 }
125
126 static void
127 bfa_com_sfp_attach(struct bfa_s *bfa)
128 {
129         struct bfa_sfp_s        *sfp = BFA_SFP_MOD(bfa);
130         struct bfa_mem_dma_s    *sfp_dma = BFA_MEM_SFP_DMA(bfa);
131
132         bfa_sfp_attach(sfp, &bfa->ioc, bfa, bfa->trcmod);
133         bfa_sfp_memclaim(sfp, sfp_dma->kva_curp, sfp_dma->dma_curp);
134 }
135
136 static void
137 bfa_com_flash_attach(struct bfa_s *bfa, bfa_boolean_t mincfg)
138 {
139         struct bfa_flash_s      *flash = BFA_FLASH(bfa);
140         struct bfa_mem_dma_s    *flash_dma = BFA_MEM_FLASH_DMA(bfa);
141
142         bfa_flash_attach(flash, &bfa->ioc, bfa, bfa->trcmod, mincfg);
143         bfa_flash_memclaim(flash, flash_dma->kva_curp,
144                            flash_dma->dma_curp, mincfg);
145 }
146
147 static void
148 bfa_com_diag_attach(struct bfa_s *bfa)
149 {
150         struct bfa_diag_s       *diag = BFA_DIAG_MOD(bfa);
151         struct bfa_mem_dma_s    *diag_dma = BFA_MEM_DIAG_DMA(bfa);
152
153         bfa_diag_attach(diag, &bfa->ioc, bfa, bfa_fcport_beacon, bfa->trcmod);
154         bfa_diag_memclaim(diag, diag_dma->kva_curp, diag_dma->dma_curp);
155 }
156
157 /*
158  * BFA IOC FC related definitions
159  */
160
161 /*
162  * IOC local definitions
163  */
164 #define BFA_IOCFC_TOV           5000    /* msecs */
165
166 enum {
167         BFA_IOCFC_ACT_NONE      = 0,
168         BFA_IOCFC_ACT_INIT      = 1,
169         BFA_IOCFC_ACT_STOP      = 2,
170         BFA_IOCFC_ACT_DISABLE   = 3,
171         BFA_IOCFC_ACT_ENABLE    = 4,
172 };
173
174 #define DEF_CFG_NUM_FABRICS             1
175 #define DEF_CFG_NUM_LPORTS              256
176 #define DEF_CFG_NUM_CQS                 4
177 #define DEF_CFG_NUM_IOIM_REQS           (BFA_IOIM_MAX)
178 #define DEF_CFG_NUM_TSKIM_REQS          128
179 #define DEF_CFG_NUM_FCXP_REQS           64
180 #define DEF_CFG_NUM_UF_BUFS             64
181 #define DEF_CFG_NUM_RPORTS              1024
182 #define DEF_CFG_NUM_ITNIMS              (DEF_CFG_NUM_RPORTS)
183 #define DEF_CFG_NUM_TINS                256
184
185 #define DEF_CFG_NUM_SGPGS               2048
186 #define DEF_CFG_NUM_REQQ_ELEMS          256
187 #define DEF_CFG_NUM_RSPQ_ELEMS          64
188 #define DEF_CFG_NUM_SBOOT_TGTS          16
189 #define DEF_CFG_NUM_SBOOT_LUNS          16
190
191 /*
192  * forward declaration for IOC FC functions
193  */
194 static void bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status);
195 static void bfa_iocfc_disable_cbfn(void *bfa_arg);
196 static void bfa_iocfc_hbfail_cbfn(void *bfa_arg);
197 static void bfa_iocfc_reset_cbfn(void *bfa_arg);
198 static struct bfa_ioc_cbfn_s bfa_iocfc_cbfn;
199
200 /*
201  * BFA Interrupt handling functions
202  */
203 static void
204 bfa_reqq_resume(struct bfa_s *bfa, int qid)
205 {
206         struct list_head *waitq, *qe, *qen;
207         struct bfa_reqq_wait_s *wqe;
208
209         waitq = bfa_reqq(bfa, qid);
210         list_for_each_safe(qe, qen, waitq) {
211                 /*
212                  * Callback only as long as there is room in request queue
213                  */
214                 if (bfa_reqq_full(bfa, qid))
215                         break;
216
217                 list_del(qe);
218                 wqe = (struct bfa_reqq_wait_s *) qe;
219                 wqe->qresume(wqe->cbarg);
220         }
221 }
222
223 static inline void
224 bfa_isr_rspq(struct bfa_s *bfa, int qid)
225 {
226         struct bfi_msg_s *m;
227         u32     pi, ci;
228         struct list_head *waitq;
229
230         bfa_isr_rspq_ack(bfa, qid);
231
232         ci = bfa_rspq_ci(bfa, qid);
233         pi = bfa_rspq_pi(bfa, qid);
234
235         while (ci != pi) {
236                 m = bfa_rspq_elem(bfa, qid, ci);
237                 WARN_ON(m->mhdr.msg_class >= BFI_MC_MAX);
238
239                 bfa_isrs[m->mhdr.msg_class] (bfa, m);
240                 CQ_INCR(ci, bfa->iocfc.cfg.drvcfg.num_rspq_elems);
241         }
242
243         /*
244          * update CI
245          */
246         bfa_rspq_ci(bfa, qid) = pi;
247         writel(pi, bfa->iocfc.bfa_regs.rme_q_ci[qid]);
248         mmiowb();
249
250         /*
251          * Resume any pending requests in the corresponding reqq.
252          */
253         waitq = bfa_reqq(bfa, qid);
254         if (!list_empty(waitq))
255                 bfa_reqq_resume(bfa, qid);
256 }
257
258 static inline void
259 bfa_isr_reqq(struct bfa_s *bfa, int qid)
260 {
261         struct list_head *waitq;
262
263         bfa_isr_reqq_ack(bfa, qid);
264
265         /*
266          * Resume any pending requests in the corresponding reqq.
267          */
268         waitq = bfa_reqq(bfa, qid);
269         if (!list_empty(waitq))
270                 bfa_reqq_resume(bfa, qid);
271 }
272
273 void
274 bfa_msix_all(struct bfa_s *bfa, int vec)
275 {
276         u32     intr, qintr;
277         int     queue;
278
279         intr = readl(bfa->iocfc.bfa_regs.intr_status);
280         if (!intr)
281                 return;
282
283         /*
284          * RME completion queue interrupt
285          */
286         qintr = intr & __HFN_INT_RME_MASK;
287         if (qintr && bfa->queue_process) {
288                 for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++)
289                         bfa_isr_rspq(bfa, queue);
290         }
291
292         intr &= ~qintr;
293         if (!intr)
294                 return;
295
296         /*
297          * CPE completion queue interrupt
298          */
299         qintr = intr & __HFN_INT_CPE_MASK;
300         if (qintr && bfa->queue_process) {
301                 for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++)
302                         bfa_isr_reqq(bfa, queue);
303         }
304         intr &= ~qintr;
305         if (!intr)
306                 return;
307
308         bfa_msix_lpu_err(bfa, intr);
309 }
310
311 bfa_boolean_t
312 bfa_intx(struct bfa_s *bfa)
313 {
314         u32 intr, qintr;
315         int queue;
316
317         intr = readl(bfa->iocfc.bfa_regs.intr_status);
318         if (!intr)
319                 return BFA_FALSE;
320
321         qintr = intr & (__HFN_INT_RME_MASK | __HFN_INT_CPE_MASK);
322         if (qintr)
323                 writel(qintr, bfa->iocfc.bfa_regs.intr_status);
324
325         /*
326          * RME completion queue interrupt
327          */
328         qintr = intr & __HFN_INT_RME_MASK;
329         if (qintr && bfa->queue_process) {
330                 for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++)
331                         bfa_isr_rspq(bfa, queue);
332         }
333
334         intr &= ~qintr;
335         if (!intr)
336                 return BFA_TRUE;
337
338         /*
339          * CPE completion queue interrupt
340          */
341         qintr = intr & __HFN_INT_CPE_MASK;
342         if (qintr && bfa->queue_process) {
343                 for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++)
344                         bfa_isr_reqq(bfa, queue);
345         }
346         intr &= ~qintr;
347         if (!intr)
348                 return BFA_TRUE;
349
350         bfa_msix_lpu_err(bfa, intr);
351
352         return BFA_TRUE;
353 }
354
355 void
356 bfa_isr_enable(struct bfa_s *bfa)
357 {
358         u32 umsk;
359         int pci_func = bfa_ioc_pcifn(&bfa->ioc);
360
361         bfa_trc(bfa, pci_func);
362
363         bfa_msix_ctrl_install(bfa);
364
365         if (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id)) {
366                 umsk = __HFN_INT_ERR_MASK_CT2;
367                 umsk |= pci_func == 0 ?
368                         __HFN_INT_FN0_MASK_CT2 : __HFN_INT_FN1_MASK_CT2;
369         } else {
370                 umsk = __HFN_INT_ERR_MASK;
371                 umsk |= pci_func == 0 ? __HFN_INT_FN0_MASK : __HFN_INT_FN1_MASK;
372         }
373
374         writel(umsk, bfa->iocfc.bfa_regs.intr_status);
375         writel(~umsk, bfa->iocfc.bfa_regs.intr_mask);
376         bfa->iocfc.intr_mask = ~umsk;
377         bfa_isr_mode_set(bfa, bfa->msix.nvecs != 0);
378 }
379
380 void
381 bfa_isr_disable(struct bfa_s *bfa)
382 {
383         bfa_isr_mode_set(bfa, BFA_FALSE);
384         writel(-1L, bfa->iocfc.bfa_regs.intr_mask);
385         bfa_msix_uninstall(bfa);
386 }
387
388 void
389 bfa_msix_reqq(struct bfa_s *bfa, int vec)
390 {
391         bfa_isr_reqq(bfa, vec - bfa->iocfc.hwif.cpe_vec_q0);
392 }
393
394 void
395 bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m)
396 {
397         bfa_trc(bfa, m->mhdr.msg_class);
398         bfa_trc(bfa, m->mhdr.msg_id);
399         bfa_trc(bfa, m->mhdr.mtag.i2htok);
400         WARN_ON(1);
401         bfa_trc_stop(bfa->trcmod);
402 }
403
404 void
405 bfa_msix_rspq(struct bfa_s *bfa, int vec)
406 {
407         bfa_isr_rspq(bfa, vec - bfa->iocfc.hwif.rme_vec_q0);
408 }
409
410 void
411 bfa_msix_lpu_err(struct bfa_s *bfa, int vec)
412 {
413         u32 intr, curr_value;
414         bfa_boolean_t lpu_isr, halt_isr, pss_isr;
415
416         intr = readl(bfa->iocfc.bfa_regs.intr_status);
417
418         if (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id)) {
419                 halt_isr = intr & __HFN_INT_CPQ_HALT_CT2;
420                 pss_isr  = intr & __HFN_INT_ERR_PSS_CT2;
421                 lpu_isr  = intr & (__HFN_INT_MBOX_LPU0_CT2 |
422                                    __HFN_INT_MBOX_LPU1_CT2);
423                 intr    &= __HFN_INT_ERR_MASK_CT2;
424         } else {
425                 halt_isr = intr & __HFN_INT_LL_HALT;
426                 pss_isr  = intr & __HFN_INT_ERR_PSS;
427                 lpu_isr  = intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1);
428                 intr    &= __HFN_INT_ERR_MASK;
429         }
430
431         if (lpu_isr)
432                 bfa_ioc_mbox_isr(&bfa->ioc);
433
434         if (intr) {
435                 if (halt_isr) {
436                         /*
437                          * If LL_HALT bit is set then FW Init Halt LL Port
438                          * Register needs to be cleared as well so Interrupt
439                          * Status Register will be cleared.
440                          */
441                         curr_value = readl(bfa->ioc.ioc_regs.ll_halt);
442                         curr_value &= ~__FW_INIT_HALT_P;
443                         writel(curr_value, bfa->ioc.ioc_regs.ll_halt);
444                 }
445
446                 if (pss_isr) {
447                         /*
448                          * ERR_PSS bit needs to be cleared as well in case
449                          * interrups are shared so driver's interrupt handler is
450                          * still called even though it is already masked out.
451                          */
452                         curr_value = readl(
453                                         bfa->ioc.ioc_regs.pss_err_status_reg);
454                         writel(curr_value,
455                                 bfa->ioc.ioc_regs.pss_err_status_reg);
456                 }
457
458                 writel(intr, bfa->iocfc.bfa_regs.intr_status);
459                 bfa_ioc_error_isr(&bfa->ioc);
460         }
461 }
462
463 /*
464  * BFA IOC FC related functions
465  */
466
467 /*
468  *  BFA IOC private functions
469  */
470
471 /*
472  * Use the Mailbox interface to send BFI_IOCFC_H2I_CFG_REQ
473  */
474 static void
475 bfa_iocfc_send_cfg(void *bfa_arg)
476 {
477         struct bfa_s *bfa = bfa_arg;
478         struct bfa_iocfc_s *iocfc = &bfa->iocfc;
479         struct bfi_iocfc_cfg_req_s cfg_req;
480         struct bfi_iocfc_cfg_s *cfg_info = iocfc->cfginfo;
481         struct bfa_iocfc_cfg_s  *cfg = &iocfc->cfg;
482         int             i;
483
484         WARN_ON(cfg->fwcfg.num_cqs > BFI_IOC_MAX_CQS);
485         bfa_trc(bfa, cfg->fwcfg.num_cqs);
486
487         bfa_iocfc_reset_queues(bfa);
488
489         /*
490          * initialize IOC configuration info
491          */
492         cfg_info->single_msix_vec = 0;
493         if (bfa->msix.nvecs == 1)
494                 cfg_info->single_msix_vec = 1;
495         cfg_info->endian_sig = BFI_IOC_ENDIAN_SIG;
496         cfg_info->num_cqs = cfg->fwcfg.num_cqs;
497         cfg_info->num_ioim_reqs = cpu_to_be16(cfg->fwcfg.num_ioim_reqs);
498         cfg_info->num_fwtio_reqs = cpu_to_be16(cfg->fwcfg.num_fwtio_reqs);
499
500         bfa_dma_be_addr_set(cfg_info->cfgrsp_addr, iocfc->cfgrsp_dma.pa);
501         /*
502          * dma map REQ and RSP circular queues and shadow pointers
503          */
504         for (i = 0; i < cfg->fwcfg.num_cqs; i++) {
505                 bfa_dma_be_addr_set(cfg_info->req_cq_ba[i],
506                                     iocfc->req_cq_ba[i].pa);
507                 bfa_dma_be_addr_set(cfg_info->req_shadow_ci[i],
508                                     iocfc->req_cq_shadow_ci[i].pa);
509                 cfg_info->req_cq_elems[i] =
510                         cpu_to_be16(cfg->drvcfg.num_reqq_elems);
511
512                 bfa_dma_be_addr_set(cfg_info->rsp_cq_ba[i],
513                                     iocfc->rsp_cq_ba[i].pa);
514                 bfa_dma_be_addr_set(cfg_info->rsp_shadow_pi[i],
515                                     iocfc->rsp_cq_shadow_pi[i].pa);
516                 cfg_info->rsp_cq_elems[i] =
517                         cpu_to_be16(cfg->drvcfg.num_rspq_elems);
518         }
519
520         /*
521          * Enable interrupt coalescing if it is driver init path
522          * and not ioc disable/enable path.
523          */
524         if (!iocfc->cfgdone)
525                 cfg_info->intr_attr.coalesce = BFA_TRUE;
526
527         iocfc->cfgdone = BFA_FALSE;
528
529         /*
530          * dma map IOC configuration itself
531          */
532         bfi_h2i_set(cfg_req.mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_CFG_REQ,
533                     bfa_fn_lpu(bfa));
534         bfa_dma_be_addr_set(cfg_req.ioc_cfg_dma_addr, iocfc->cfg_info.pa);
535
536         bfa_ioc_mbox_send(&bfa->ioc, &cfg_req,
537                           sizeof(struct bfi_iocfc_cfg_req_s));
538 }
539
540 static void
541 bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
542                    struct bfa_pcidev_s *pcidev)
543 {
544         struct bfa_iocfc_s      *iocfc = &bfa->iocfc;
545
546         bfa->bfad = bfad;
547         iocfc->bfa = bfa;
548         iocfc->action = BFA_IOCFC_ACT_NONE;
549
550         iocfc->cfg = *cfg;
551
552         /*
553          * Initialize chip specific handlers.
554          */
555         if (bfa_asic_id_ctc(bfa_ioc_devid(&bfa->ioc))) {
556                 iocfc->hwif.hw_reginit = bfa_hwct_reginit;
557                 iocfc->hwif.hw_reqq_ack = bfa_hwct_reqq_ack;
558                 iocfc->hwif.hw_rspq_ack = bfa_hwct_rspq_ack;
559                 iocfc->hwif.hw_msix_init = bfa_hwct_msix_init;
560                 iocfc->hwif.hw_msix_ctrl_install = bfa_hwct_msix_ctrl_install;
561                 iocfc->hwif.hw_msix_queue_install = bfa_hwct_msix_queue_install;
562                 iocfc->hwif.hw_msix_uninstall = bfa_hwct_msix_uninstall;
563                 iocfc->hwif.hw_isr_mode_set = bfa_hwct_isr_mode_set;
564                 iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs;
565                 iocfc->hwif.hw_msix_get_rme_range = bfa_hwct_msix_get_rme_range;
566                 iocfc->hwif.rme_vec_q0 = BFI_MSIX_RME_QMIN_CT;
567                 iocfc->hwif.cpe_vec_q0 = BFI_MSIX_CPE_QMIN_CT;
568         } else {
569                 iocfc->hwif.hw_reginit = bfa_hwcb_reginit;
570                 iocfc->hwif.hw_reqq_ack = NULL;
571                 iocfc->hwif.hw_rspq_ack = NULL;
572                 iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init;
573                 iocfc->hwif.hw_msix_ctrl_install = bfa_hwcb_msix_ctrl_install;
574                 iocfc->hwif.hw_msix_queue_install = bfa_hwcb_msix_queue_install;
575                 iocfc->hwif.hw_msix_uninstall = bfa_hwcb_msix_uninstall;
576                 iocfc->hwif.hw_isr_mode_set = bfa_hwcb_isr_mode_set;
577                 iocfc->hwif.hw_msix_getvecs = bfa_hwcb_msix_getvecs;
578                 iocfc->hwif.hw_msix_get_rme_range = bfa_hwcb_msix_get_rme_range;
579                 iocfc->hwif.rme_vec_q0 = BFI_MSIX_RME_QMIN_CB +
580                         bfa_ioc_pcifn(&bfa->ioc) * BFI_IOC_MAX_CQS;
581                 iocfc->hwif.cpe_vec_q0 = BFI_MSIX_CPE_QMIN_CB +
582                         bfa_ioc_pcifn(&bfa->ioc) * BFI_IOC_MAX_CQS;
583         }
584
585         if (bfa_asic_id_ct2(bfa_ioc_devid(&bfa->ioc))) {
586                 iocfc->hwif.hw_reginit = bfa_hwct2_reginit;
587                 iocfc->hwif.hw_isr_mode_set = NULL;
588                 iocfc->hwif.hw_rspq_ack = NULL;
589         }
590
591         iocfc->hwif.hw_reginit(bfa);
592         bfa->msix.nvecs = 0;
593 }
594
595 static void
596 bfa_iocfc_mem_claim(struct bfa_s *bfa, struct bfa_iocfc_cfg_s *cfg)
597 {
598         u8      *dm_kva = NULL;
599         u64     dm_pa = 0;
600         int     i, per_reqq_sz, per_rspq_sz, dbgsz;
601         struct bfa_iocfc_s  *iocfc = &bfa->iocfc;
602         struct bfa_mem_dma_s *ioc_dma = BFA_MEM_IOC_DMA(bfa);
603         struct bfa_mem_dma_s *iocfc_dma = BFA_MEM_IOCFC_DMA(bfa);
604         struct bfa_mem_dma_s *reqq_dma, *rspq_dma;
605
606         /* First allocate dma memory for IOC */
607         bfa_ioc_mem_claim(&bfa->ioc, bfa_mem_dma_virt(ioc_dma),
608                         bfa_mem_dma_phys(ioc_dma));
609
610         /* Claim DMA-able memory for the request/response queues */
611         per_reqq_sz = BFA_ROUNDUP((cfg->drvcfg.num_reqq_elems * BFI_LMSG_SZ),
612                                 BFA_DMA_ALIGN_SZ);
613         per_rspq_sz = BFA_ROUNDUP((cfg->drvcfg.num_rspq_elems * BFI_LMSG_SZ),
614                                 BFA_DMA_ALIGN_SZ);
615
616         for (i = 0; i < cfg->fwcfg.num_cqs; i++) {
617                 reqq_dma = BFA_MEM_REQQ_DMA(bfa, i);
618                 iocfc->req_cq_ba[i].kva = bfa_mem_dma_virt(reqq_dma);
619                 iocfc->req_cq_ba[i].pa = bfa_mem_dma_phys(reqq_dma);
620                 memset(iocfc->req_cq_ba[i].kva, 0, per_reqq_sz);
621
622                 rspq_dma = BFA_MEM_RSPQ_DMA(bfa, i);
623                 iocfc->rsp_cq_ba[i].kva = bfa_mem_dma_virt(rspq_dma);
624                 iocfc->rsp_cq_ba[i].pa = bfa_mem_dma_phys(rspq_dma);
625                 memset(iocfc->rsp_cq_ba[i].kva, 0, per_rspq_sz);
626         }
627
628         /* Claim IOCFC dma memory - for shadow CI/PI */
629         dm_kva = bfa_mem_dma_virt(iocfc_dma);
630         dm_pa  = bfa_mem_dma_phys(iocfc_dma);
631
632         for (i = 0; i < cfg->fwcfg.num_cqs; i++) {
633                 iocfc->req_cq_shadow_ci[i].kva = dm_kva;
634                 iocfc->req_cq_shadow_ci[i].pa = dm_pa;
635                 dm_kva += BFA_CACHELINE_SZ;
636                 dm_pa += BFA_CACHELINE_SZ;
637
638                 iocfc->rsp_cq_shadow_pi[i].kva = dm_kva;
639                 iocfc->rsp_cq_shadow_pi[i].pa = dm_pa;
640                 dm_kva += BFA_CACHELINE_SZ;
641                 dm_pa += BFA_CACHELINE_SZ;
642         }
643
644         /* Claim IOCFC dma memory - for the config info page */
645         bfa->iocfc.cfg_info.kva = dm_kva;
646         bfa->iocfc.cfg_info.pa = dm_pa;
647         bfa->iocfc.cfginfo = (struct bfi_iocfc_cfg_s *) dm_kva;
648         dm_kva += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s), BFA_CACHELINE_SZ);
649         dm_pa += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s), BFA_CACHELINE_SZ);
650
651         /* Claim IOCFC dma memory - for the config response */
652         bfa->iocfc.cfgrsp_dma.kva = dm_kva;
653         bfa->iocfc.cfgrsp_dma.pa = dm_pa;
654         bfa->iocfc.cfgrsp = (struct bfi_iocfc_cfgrsp_s *) dm_kva;
655         dm_kva += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s),
656                         BFA_CACHELINE_SZ);
657         dm_pa += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s),
658                         BFA_CACHELINE_SZ);
659
660         /* Claim IOCFC kva memory */
661         dbgsz = (bfa_auto_recover) ? BFA_DBG_FWTRC_LEN : 0;
662         if (dbgsz > 0) {
663                 bfa_ioc_debug_memclaim(&bfa->ioc, bfa_mem_kva_curp(iocfc));
664                 bfa_mem_kva_curp(iocfc) += dbgsz;
665         }
666 }
667
668 /*
669  * Start BFA submodules.
670  */
671 static void
672 bfa_iocfc_start_submod(struct bfa_s *bfa)
673 {
674         int             i;
675
676         bfa->queue_process = BFA_TRUE;
677         for (i = 0; i < BFI_IOC_MAX_CQS; i++)
678                 bfa_isr_rspq_ack(bfa, i);
679
680         for (i = 0; hal_mods[i]; i++)
681                 hal_mods[i]->start(bfa);
682 }
683
684 /*
685  * Disable BFA submodules.
686  */
687 static void
688 bfa_iocfc_disable_submod(struct bfa_s *bfa)
689 {
690         int             i;
691
692         for (i = 0; hal_mods[i]; i++)
693                 hal_mods[i]->iocdisable(bfa);
694 }
695
696 static void
697 bfa_iocfc_init_cb(void *bfa_arg, bfa_boolean_t complete)
698 {
699         struct bfa_s    *bfa = bfa_arg;
700
701         if (complete) {
702                 if (bfa->iocfc.cfgdone)
703                         bfa_cb_init(bfa->bfad, BFA_STATUS_OK);
704                 else
705                         bfa_cb_init(bfa->bfad, BFA_STATUS_FAILED);
706         } else {
707                 if (bfa->iocfc.cfgdone)
708                         bfa->iocfc.action = BFA_IOCFC_ACT_NONE;
709         }
710 }
711
712 static void
713 bfa_iocfc_stop_cb(void *bfa_arg, bfa_boolean_t compl)
714 {
715         struct bfa_s  *bfa = bfa_arg;
716         struct bfad_s *bfad = bfa->bfad;
717
718         if (compl)
719                 complete(&bfad->comp);
720         else
721                 bfa->iocfc.action = BFA_IOCFC_ACT_NONE;
722 }
723
724 static void
725 bfa_iocfc_enable_cb(void *bfa_arg, bfa_boolean_t compl)
726 {
727         struct bfa_s    *bfa = bfa_arg;
728         struct bfad_s *bfad = bfa->bfad;
729
730         if (compl)
731                 complete(&bfad->enable_comp);
732 }
733
734 static void
735 bfa_iocfc_disable_cb(void *bfa_arg, bfa_boolean_t compl)
736 {
737         struct bfa_s  *bfa = bfa_arg;
738         struct bfad_s *bfad = bfa->bfad;
739
740         if (compl)
741                 complete(&bfad->disable_comp);
742 }
743
744 /**
745  * configure queue registers from firmware response
746  */
747 static void
748 bfa_iocfc_qreg(struct bfa_s *bfa, struct bfi_iocfc_qreg_s *qreg)
749 {
750         int     i;
751         struct bfa_iocfc_regs_s *r = &bfa->iocfc.bfa_regs;
752         void __iomem *kva = bfa_ioc_bar0(&bfa->ioc);
753
754         for (i = 0; i < BFI_IOC_MAX_CQS; i++) {
755                 bfa->iocfc.hw_qid[i] = qreg->hw_qid[i];
756                 r->cpe_q_ci[i] = kva + be32_to_cpu(qreg->cpe_q_ci_off[i]);
757                 r->cpe_q_pi[i] = kva + be32_to_cpu(qreg->cpe_q_pi_off[i]);
758                 r->cpe_q_ctrl[i] = kva + be32_to_cpu(qreg->cpe_qctl_off[i]);
759                 r->rme_q_ci[i] = kva + be32_to_cpu(qreg->rme_q_ci_off[i]);
760                 r->rme_q_pi[i] = kva + be32_to_cpu(qreg->rme_q_pi_off[i]);
761                 r->rme_q_ctrl[i] = kva + be32_to_cpu(qreg->rme_qctl_off[i]);
762         }
763 }
764
765 static void
766 bfa_iocfc_res_recfg(struct bfa_s *bfa, struct bfa_iocfc_fwcfg_s *fwcfg)
767 {
768         bfa_fcxp_res_recfg(bfa, fwcfg->num_fcxp_reqs);
769         bfa_uf_res_recfg(bfa, fwcfg->num_uf_bufs);
770         bfa_rport_res_recfg(bfa, fwcfg->num_rports);
771         bfa_fcp_res_recfg(bfa, fwcfg->num_ioim_reqs);
772         bfa_tskim_res_recfg(bfa, fwcfg->num_tskim_reqs);
773 }
774
775 /*
776  * Update BFA configuration from firmware configuration.
777  */
778 static void
779 bfa_iocfc_cfgrsp(struct bfa_s *bfa)
780 {
781         struct bfa_iocfc_s              *iocfc   = &bfa->iocfc;
782         struct bfi_iocfc_cfgrsp_s       *cfgrsp  = iocfc->cfgrsp;
783         struct bfa_iocfc_fwcfg_s        *fwcfg   = &cfgrsp->fwcfg;
784
785         fwcfg->num_cqs        = fwcfg->num_cqs;
786         fwcfg->num_ioim_reqs  = be16_to_cpu(fwcfg->num_ioim_reqs);
787         fwcfg->num_fwtio_reqs = be16_to_cpu(fwcfg->num_fwtio_reqs);
788         fwcfg->num_tskim_reqs = be16_to_cpu(fwcfg->num_tskim_reqs);
789         fwcfg->num_fcxp_reqs  = be16_to_cpu(fwcfg->num_fcxp_reqs);
790         fwcfg->num_uf_bufs    = be16_to_cpu(fwcfg->num_uf_bufs);
791         fwcfg->num_rports     = be16_to_cpu(fwcfg->num_rports);
792
793         iocfc->cfgdone = BFA_TRUE;
794
795         /*
796          * configure queue register offsets as learnt from firmware
797          */
798         bfa_iocfc_qreg(bfa, &cfgrsp->qreg);
799
800         /*
801          * Re-configure resources as learnt from Firmware
802          */
803         bfa_iocfc_res_recfg(bfa, fwcfg);
804
805         /*
806          * Install MSIX queue handlers
807          */
808         bfa_msix_queue_install(bfa);
809
810         /*
811          * Configuration is complete - initialize/start submodules
812          */
813         bfa_fcport_init(bfa);
814
815         if (iocfc->action == BFA_IOCFC_ACT_INIT)
816                 bfa_cb_queue(bfa, &iocfc->init_hcb_qe, bfa_iocfc_init_cb, bfa);
817         else {
818                 if (bfa->iocfc.action == BFA_IOCFC_ACT_ENABLE)
819                         bfa_cb_queue(bfa, &bfa->iocfc.en_hcb_qe,
820                                         bfa_iocfc_enable_cb, bfa);
821                 bfa_iocfc_start_submod(bfa);
822         }
823 }
824 void
825 bfa_iocfc_reset_queues(struct bfa_s *bfa)
826 {
827         int             q;
828
829         for (q = 0; q < BFI_IOC_MAX_CQS; q++) {
830                 bfa_reqq_ci(bfa, q) = 0;
831                 bfa_reqq_pi(bfa, q) = 0;
832                 bfa_rspq_ci(bfa, q) = 0;
833                 bfa_rspq_pi(bfa, q) = 0;
834         }
835 }
836
837 /* Fabric Assigned Address specific functions */
838
839 /*
840  *      Check whether IOC is ready before sending command down
841  */
842 static bfa_status_t
843 bfa_faa_validate_request(struct bfa_s *bfa)
844 {
845         enum bfa_ioc_type_e     ioc_type = bfa_get_type(bfa);
846         u32     card_type = bfa->ioc.attr->card_type;
847
848         if (bfa_ioc_is_operational(&bfa->ioc)) {
849                 if ((ioc_type != BFA_IOC_TYPE_FC) || bfa_mfg_is_mezz(card_type))
850                         return BFA_STATUS_FEATURE_NOT_SUPPORTED;
851         } else {
852                 if (!bfa_ioc_is_acq_addr(&bfa->ioc))
853                         return BFA_STATUS_IOC_NON_OP;
854         }
855
856         return BFA_STATUS_OK;
857 }
858
859 bfa_status_t
860 bfa_faa_enable(struct bfa_s *bfa, bfa_cb_iocfc_t cbfn, void *cbarg)
861 {
862         struct bfi_faa_en_dis_s faa_enable_req;
863         struct bfa_iocfc_s      *iocfc = &bfa->iocfc;
864         bfa_status_t            status;
865
866         iocfc->faa_args.faa_cb.faa_cbfn = cbfn;
867         iocfc->faa_args.faa_cb.faa_cbarg = cbarg;
868
869         status = bfa_faa_validate_request(bfa);
870         if (status != BFA_STATUS_OK)
871                 return status;
872
873         if (iocfc->faa_args.busy == BFA_TRUE)
874                 return BFA_STATUS_DEVBUSY;
875
876         if (iocfc->faa_args.faa_state == BFA_FAA_ENABLED)
877                 return BFA_STATUS_FAA_ENABLED;
878
879         if (bfa_fcport_is_trunk_enabled(bfa))
880                 return BFA_STATUS_ERROR_TRUNK_ENABLED;
881
882         bfa_fcport_cfg_faa(bfa, BFA_FAA_ENABLED);
883         iocfc->faa_args.busy = BFA_TRUE;
884
885         memset(&faa_enable_req, 0, sizeof(struct bfi_faa_en_dis_s));
886         bfi_h2i_set(faa_enable_req.mh, BFI_MC_IOCFC,
887                 BFI_IOCFC_H2I_FAA_ENABLE_REQ, bfa_fn_lpu(bfa));
888
889         bfa_ioc_mbox_send(&bfa->ioc, &faa_enable_req,
890                         sizeof(struct bfi_faa_en_dis_s));
891
892         return BFA_STATUS_OK;
893 }
894
895 bfa_status_t
896 bfa_faa_disable(struct bfa_s *bfa, bfa_cb_iocfc_t cbfn,
897                 void *cbarg)
898 {
899         struct bfi_faa_en_dis_s faa_disable_req;
900         struct bfa_iocfc_s      *iocfc = &bfa->iocfc;
901         bfa_status_t            status;
902
903         iocfc->faa_args.faa_cb.faa_cbfn = cbfn;
904         iocfc->faa_args.faa_cb.faa_cbarg = cbarg;
905
906         status = bfa_faa_validate_request(bfa);
907         if (status != BFA_STATUS_OK)
908                 return status;
909
910         if (iocfc->faa_args.busy == BFA_TRUE)
911                 return BFA_STATUS_DEVBUSY;
912
913         if (iocfc->faa_args.faa_state == BFA_FAA_DISABLED)
914                 return BFA_STATUS_FAA_DISABLED;
915
916         bfa_fcport_cfg_faa(bfa, BFA_FAA_DISABLED);
917         iocfc->faa_args.busy = BFA_TRUE;
918
919         memset(&faa_disable_req, 0, sizeof(struct bfi_faa_en_dis_s));
920         bfi_h2i_set(faa_disable_req.mh, BFI_MC_IOCFC,
921                 BFI_IOCFC_H2I_FAA_DISABLE_REQ, bfa_fn_lpu(bfa));
922
923         bfa_ioc_mbox_send(&bfa->ioc, &faa_disable_req,
924                 sizeof(struct bfi_faa_en_dis_s));
925
926         return BFA_STATUS_OK;
927 }
928
929 bfa_status_t
930 bfa_faa_query(struct bfa_s *bfa, struct bfa_faa_attr_s *attr,
931                 bfa_cb_iocfc_t cbfn, void *cbarg)
932 {
933         struct bfi_faa_query_s  faa_attr_req;
934         struct bfa_iocfc_s      *iocfc = &bfa->iocfc;
935         bfa_status_t            status;
936
937         iocfc->faa_args.faa_attr = attr;
938         iocfc->faa_args.faa_cb.faa_cbfn = cbfn;
939         iocfc->faa_args.faa_cb.faa_cbarg = cbarg;
940
941         status = bfa_faa_validate_request(bfa);
942         if (status != BFA_STATUS_OK)
943                 return status;
944
945         if (iocfc->faa_args.busy == BFA_TRUE)
946                 return BFA_STATUS_DEVBUSY;
947
948         iocfc->faa_args.busy = BFA_TRUE;
949         memset(&faa_attr_req, 0, sizeof(struct bfi_faa_query_s));
950         bfi_h2i_set(faa_attr_req.mh, BFI_MC_IOCFC,
951                 BFI_IOCFC_H2I_FAA_QUERY_REQ, bfa_fn_lpu(bfa));
952
953         bfa_ioc_mbox_send(&bfa->ioc, &faa_attr_req,
954                 sizeof(struct bfi_faa_query_s));
955
956         return BFA_STATUS_OK;
957 }
958
959 /*
960  *      FAA enable response
961  */
962 static void
963 bfa_faa_enable_reply(struct bfa_iocfc_s *iocfc,
964                 struct bfi_faa_en_dis_rsp_s *rsp)
965 {
966         void    *cbarg = iocfc->faa_args.faa_cb.faa_cbarg;
967         bfa_status_t    status = rsp->status;
968
969         WARN_ON(!iocfc->faa_args.faa_cb.faa_cbfn);
970
971         iocfc->faa_args.faa_cb.faa_cbfn(cbarg, status);
972         iocfc->faa_args.busy = BFA_FALSE;
973 }
974
975 /*
976  *      FAA disable response
977  */
978 static void
979 bfa_faa_disable_reply(struct bfa_iocfc_s *iocfc,
980                 struct bfi_faa_en_dis_rsp_s *rsp)
981 {
982         void    *cbarg = iocfc->faa_args.faa_cb.faa_cbarg;
983         bfa_status_t    status = rsp->status;
984
985         WARN_ON(!iocfc->faa_args.faa_cb.faa_cbfn);
986
987         iocfc->faa_args.faa_cb.faa_cbfn(cbarg, status);
988         iocfc->faa_args.busy = BFA_FALSE;
989 }
990
991 /*
992  *      FAA query response
993  */
994 static void
995 bfa_faa_query_reply(struct bfa_iocfc_s *iocfc,
996                 bfi_faa_query_rsp_t *rsp)
997 {
998         void    *cbarg = iocfc->faa_args.faa_cb.faa_cbarg;
999
1000         if (iocfc->faa_args.faa_attr) {
1001                 iocfc->faa_args.faa_attr->faa = rsp->faa;
1002                 iocfc->faa_args.faa_attr->faa_state = rsp->faa_status;
1003                 iocfc->faa_args.faa_attr->pwwn_source = rsp->addr_source;
1004         }
1005
1006         WARN_ON(!iocfc->faa_args.faa_cb.faa_cbfn);
1007
1008         iocfc->faa_args.faa_cb.faa_cbfn(cbarg, BFA_STATUS_OK);
1009         iocfc->faa_args.busy = BFA_FALSE;
1010 }
1011
1012 /*
1013  * IOC enable request is complete
1014  */
1015 static void
1016 bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status)
1017 {
1018         struct bfa_s    *bfa = bfa_arg;
1019
1020         if (status == BFA_STATUS_FAA_ACQ_ADDR) {
1021                 bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe,
1022                                 bfa_iocfc_init_cb, bfa);
1023                 return;
1024         }
1025
1026         if (status != BFA_STATUS_OK) {
1027                 bfa_isr_disable(bfa);
1028                 if (bfa->iocfc.action == BFA_IOCFC_ACT_INIT)
1029                         bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe,
1030                                      bfa_iocfc_init_cb, bfa);
1031                 else if (bfa->iocfc.action == BFA_IOCFC_ACT_ENABLE)
1032                         bfa_cb_queue(bfa, &bfa->iocfc.en_hcb_qe,
1033                                         bfa_iocfc_enable_cb, bfa);
1034                 return;
1035         }
1036
1037         bfa_iocfc_send_cfg(bfa);
1038 }
1039
1040 /*
1041  * IOC disable request is complete
1042  */
1043 static void
1044 bfa_iocfc_disable_cbfn(void *bfa_arg)
1045 {
1046         struct bfa_s    *bfa = bfa_arg;
1047
1048         bfa_isr_disable(bfa);
1049         bfa_iocfc_disable_submod(bfa);
1050
1051         if (bfa->iocfc.action == BFA_IOCFC_ACT_STOP)
1052                 bfa_cb_queue(bfa, &bfa->iocfc.stop_hcb_qe, bfa_iocfc_stop_cb,
1053                              bfa);
1054         else {
1055                 WARN_ON(bfa->iocfc.action != BFA_IOCFC_ACT_DISABLE);
1056                 bfa_cb_queue(bfa, &bfa->iocfc.dis_hcb_qe, bfa_iocfc_disable_cb,
1057                              bfa);
1058         }
1059 }
1060
1061 /*
1062  * Notify sub-modules of hardware failure.
1063  */
1064 static void
1065 bfa_iocfc_hbfail_cbfn(void *bfa_arg)
1066 {
1067         struct bfa_s    *bfa = bfa_arg;
1068
1069         bfa->queue_process = BFA_FALSE;
1070
1071         bfa_isr_disable(bfa);
1072         bfa_iocfc_disable_submod(bfa);
1073
1074         if (bfa->iocfc.action == BFA_IOCFC_ACT_INIT)
1075                 bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe, bfa_iocfc_init_cb,
1076                              bfa);
1077 }
1078
1079 /*
1080  * Actions on chip-reset completion.
1081  */
1082 static void
1083 bfa_iocfc_reset_cbfn(void *bfa_arg)
1084 {
1085         struct bfa_s    *bfa = bfa_arg;
1086
1087         bfa_iocfc_reset_queues(bfa);
1088         bfa_isr_enable(bfa);
1089 }
1090
1091
1092 /*
1093  * Query IOC memory requirement information.
1094  */
1095 void
1096 bfa_iocfc_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,
1097                   struct bfa_s *bfa)
1098 {
1099         int q, per_reqq_sz, per_rspq_sz;
1100         struct bfa_mem_dma_s *ioc_dma = BFA_MEM_IOC_DMA(bfa);
1101         struct bfa_mem_dma_s *iocfc_dma = BFA_MEM_IOCFC_DMA(bfa);
1102         struct bfa_mem_kva_s *iocfc_kva = BFA_MEM_IOCFC_KVA(bfa);
1103         u32     dm_len = 0;
1104
1105         /* dma memory setup for IOC */
1106         bfa_mem_dma_setup(meminfo, ioc_dma,
1107                 BFA_ROUNDUP(sizeof(struct bfi_ioc_attr_s), BFA_DMA_ALIGN_SZ));
1108
1109         /* dma memory setup for REQ/RSP queues */
1110         per_reqq_sz = BFA_ROUNDUP((cfg->drvcfg.num_reqq_elems * BFI_LMSG_SZ),
1111                                 BFA_DMA_ALIGN_SZ);
1112         per_rspq_sz = BFA_ROUNDUP((cfg->drvcfg.num_rspq_elems * BFI_LMSG_SZ),
1113                                 BFA_DMA_ALIGN_SZ);
1114
1115         for (q = 0; q < cfg->fwcfg.num_cqs; q++) {
1116                 bfa_mem_dma_setup(meminfo, BFA_MEM_REQQ_DMA(bfa, q),
1117                                 per_reqq_sz);
1118                 bfa_mem_dma_setup(meminfo, BFA_MEM_RSPQ_DMA(bfa, q),
1119                                 per_rspq_sz);
1120         }
1121
1122         /* IOCFC dma memory - calculate Shadow CI/PI size */
1123         for (q = 0; q < cfg->fwcfg.num_cqs; q++)
1124                 dm_len += (2 * BFA_CACHELINE_SZ);
1125
1126         /* IOCFC dma memory - calculate config info / rsp size */
1127         dm_len += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s), BFA_CACHELINE_SZ);
1128         dm_len += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s),
1129                         BFA_CACHELINE_SZ);
1130
1131         /* dma memory setup for IOCFC */
1132         bfa_mem_dma_setup(meminfo, iocfc_dma, dm_len);
1133
1134         /* kva memory setup for IOCFC */
1135         bfa_mem_kva_setup(meminfo, iocfc_kva,
1136                         ((bfa_auto_recover) ? BFA_DBG_FWTRC_LEN : 0));
1137 }
1138
1139 /*
1140  * Query IOC memory requirement information.
1141  */
1142 void
1143 bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
1144                  struct bfa_pcidev_s *pcidev)
1145 {
1146         int             i;
1147         struct bfa_ioc_s *ioc = &bfa->ioc;
1148
1149         bfa_iocfc_cbfn.enable_cbfn = bfa_iocfc_enable_cbfn;
1150         bfa_iocfc_cbfn.disable_cbfn = bfa_iocfc_disable_cbfn;
1151         bfa_iocfc_cbfn.hbfail_cbfn = bfa_iocfc_hbfail_cbfn;
1152         bfa_iocfc_cbfn.reset_cbfn = bfa_iocfc_reset_cbfn;
1153
1154         ioc->trcmod = bfa->trcmod;
1155         bfa_ioc_attach(&bfa->ioc, bfa, &bfa_iocfc_cbfn, &bfa->timer_mod);
1156
1157         bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_PCIFN_CLASS_FC);
1158         bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs);
1159
1160         bfa_iocfc_init_mem(bfa, bfad, cfg, pcidev);
1161         bfa_iocfc_mem_claim(bfa, cfg);
1162         INIT_LIST_HEAD(&bfa->timer_mod.timer_q);
1163
1164         INIT_LIST_HEAD(&bfa->comp_q);
1165         for (i = 0; i < BFI_IOC_MAX_CQS; i++)
1166                 INIT_LIST_HEAD(&bfa->reqq_waitq[i]);
1167 }
1168
1169 /*
1170  * Query IOC memory requirement information.
1171  */
1172 void
1173 bfa_iocfc_init(struct bfa_s *bfa)
1174 {
1175         bfa->iocfc.action = BFA_IOCFC_ACT_INIT;
1176         bfa_ioc_enable(&bfa->ioc);
1177 }
1178
1179 /*
1180  * IOC start called from bfa_start(). Called to start IOC operations
1181  * at driver instantiation for this instance.
1182  */
1183 void
1184 bfa_iocfc_start(struct bfa_s *bfa)
1185 {
1186         if (bfa->iocfc.cfgdone)
1187                 bfa_iocfc_start_submod(bfa);
1188 }
1189
1190 /*
1191  * IOC stop called from bfa_stop(). Called only when driver is unloaded
1192  * for this instance.
1193  */
1194 void
1195 bfa_iocfc_stop(struct bfa_s *bfa)
1196 {
1197         bfa->iocfc.action = BFA_IOCFC_ACT_STOP;
1198
1199         bfa->queue_process = BFA_FALSE;
1200         bfa_ioc_disable(&bfa->ioc);
1201 }
1202
1203 void
1204 bfa_iocfc_isr(void *bfaarg, struct bfi_mbmsg_s *m)
1205 {
1206         struct bfa_s            *bfa = bfaarg;
1207         struct bfa_iocfc_s      *iocfc = &bfa->iocfc;
1208         union bfi_iocfc_i2h_msg_u       *msg;
1209
1210         msg = (union bfi_iocfc_i2h_msg_u *) m;
1211         bfa_trc(bfa, msg->mh.msg_id);
1212
1213         switch (msg->mh.msg_id) {
1214         case BFI_IOCFC_I2H_CFG_REPLY:
1215                 bfa_iocfc_cfgrsp(bfa);
1216                 break;
1217         case BFI_IOCFC_I2H_UPDATEQ_RSP:
1218                 iocfc->updateq_cbfn(iocfc->updateq_cbarg, BFA_STATUS_OK);
1219                 break;
1220         case BFI_IOCFC_I2H_FAA_ENABLE_RSP:
1221                 bfa_faa_enable_reply(iocfc,
1222                         (struct bfi_faa_en_dis_rsp_s *)msg);
1223                 break;
1224         case BFI_IOCFC_I2H_FAA_DISABLE_RSP:
1225                 bfa_faa_disable_reply(iocfc,
1226                         (struct bfi_faa_en_dis_rsp_s *)msg);
1227                 break;
1228         case BFI_IOCFC_I2H_FAA_QUERY_RSP:
1229                 bfa_faa_query_reply(iocfc, (bfi_faa_query_rsp_t *)msg);
1230                 break;
1231         default:
1232                 WARN_ON(1);
1233         }
1234 }
1235
1236 void
1237 bfa_iocfc_get_attr(struct bfa_s *bfa, struct bfa_iocfc_attr_s *attr)
1238 {
1239         struct bfa_iocfc_s      *iocfc = &bfa->iocfc;
1240
1241         attr->intr_attr.coalesce = iocfc->cfginfo->intr_attr.coalesce;
1242
1243         attr->intr_attr.delay = iocfc->cfginfo->intr_attr.delay ?
1244                                 be16_to_cpu(iocfc->cfginfo->intr_attr.delay) :
1245                                 be16_to_cpu(iocfc->cfgrsp->intr_attr.delay);
1246
1247         attr->intr_attr.latency = iocfc->cfginfo->intr_attr.latency ?
1248                         be16_to_cpu(iocfc->cfginfo->intr_attr.latency) :
1249                         be16_to_cpu(iocfc->cfgrsp->intr_attr.latency);
1250
1251         attr->config    = iocfc->cfg;
1252 }
1253
1254 bfa_status_t
1255 bfa_iocfc_israttr_set(struct bfa_s *bfa, struct bfa_iocfc_intr_attr_s *attr)
1256 {
1257         struct bfa_iocfc_s              *iocfc = &bfa->iocfc;
1258         struct bfi_iocfc_set_intr_req_s *m;
1259
1260         iocfc->cfginfo->intr_attr.coalesce = attr->coalesce;
1261         iocfc->cfginfo->intr_attr.delay = cpu_to_be16(attr->delay);
1262         iocfc->cfginfo->intr_attr.latency = cpu_to_be16(attr->latency);
1263
1264         if (!bfa_iocfc_is_operational(bfa))
1265                 return BFA_STATUS_OK;
1266
1267         m = bfa_reqq_next(bfa, BFA_REQQ_IOC);
1268         if (!m)
1269                 return BFA_STATUS_DEVBUSY;
1270
1271         bfi_h2i_set(m->mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_SET_INTR_REQ,
1272                     bfa_fn_lpu(bfa));
1273         m->coalesce = iocfc->cfginfo->intr_attr.coalesce;
1274         m->delay    = iocfc->cfginfo->intr_attr.delay;
1275         m->latency  = iocfc->cfginfo->intr_attr.latency;
1276
1277         bfa_trc(bfa, attr->delay);
1278         bfa_trc(bfa, attr->latency);
1279
1280         bfa_reqq_produce(bfa, BFA_REQQ_IOC, m->mh);
1281         return BFA_STATUS_OK;
1282 }
1283
1284 void
1285 bfa_iocfc_set_snsbase(struct bfa_s *bfa, int seg_no, u64 snsbase_pa)
1286 {
1287         struct bfa_iocfc_s      *iocfc = &bfa->iocfc;
1288
1289         iocfc->cfginfo->sense_buf_len = (BFI_IOIM_SNSLEN - 1);
1290         bfa_dma_be_addr_set(iocfc->cfginfo->ioim_snsbase[seg_no], snsbase_pa);
1291 }
1292 /*
1293  * Enable IOC after it is disabled.
1294  */
1295 void
1296 bfa_iocfc_enable(struct bfa_s *bfa)
1297 {
1298         bfa_plog_str(bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_MISC, 0,
1299                      "IOC Enable");
1300         bfa->iocfc.action = BFA_IOCFC_ACT_ENABLE;
1301         bfa_ioc_enable(&bfa->ioc);
1302 }
1303
1304 void
1305 bfa_iocfc_disable(struct bfa_s *bfa)
1306 {
1307         bfa_plog_str(bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_MISC, 0,
1308                      "IOC Disable");
1309         bfa->iocfc.action = BFA_IOCFC_ACT_DISABLE;
1310
1311         bfa->queue_process = BFA_FALSE;
1312         bfa_ioc_disable(&bfa->ioc);
1313 }
1314
1315
1316 bfa_boolean_t
1317 bfa_iocfc_is_operational(struct bfa_s *bfa)
1318 {
1319         return bfa_ioc_is_operational(&bfa->ioc) && bfa->iocfc.cfgdone;
1320 }
1321
1322 /*
1323  * Return boot target port wwns -- read from boot information in flash.
1324  */
1325 void
1326 bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t *wwns)
1327 {
1328         struct bfa_iocfc_s *iocfc = &bfa->iocfc;
1329         struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
1330         int i;
1331
1332         if (cfgrsp->pbc_cfg.boot_enabled && cfgrsp->pbc_cfg.nbluns) {
1333                 bfa_trc(bfa, cfgrsp->pbc_cfg.nbluns);
1334                 *nwwns = cfgrsp->pbc_cfg.nbluns;
1335                 for (i = 0; i < cfgrsp->pbc_cfg.nbluns; i++)
1336                         wwns[i] = cfgrsp->pbc_cfg.blun[i].tgt_pwwn;
1337
1338                 return;
1339         }
1340
1341         *nwwns = cfgrsp->bootwwns.nwwns;
1342         memcpy(wwns, cfgrsp->bootwwns.wwn, sizeof(cfgrsp->bootwwns.wwn));
1343 }
1344
1345 int
1346 bfa_iocfc_get_pbc_vports(struct bfa_s *bfa, struct bfi_pbc_vport_s *pbc_vport)
1347 {
1348         struct bfa_iocfc_s *iocfc = &bfa->iocfc;
1349         struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
1350
1351         memcpy(pbc_vport, cfgrsp->pbc_cfg.vport, sizeof(cfgrsp->pbc_cfg.vport));
1352         return cfgrsp->pbc_cfg.nvports;
1353 }
1354
1355
1356 /*
1357  * Use this function query the memory requirement of the BFA library.
1358  * This function needs to be called before bfa_attach() to get the
1359  * memory required of the BFA layer for a given driver configuration.
1360  *
1361  * This call will fail, if the cap is out of range compared to pre-defined
1362  * values within the BFA library
1363  *
1364  * @param[in] cfg -     pointer to bfa_ioc_cfg_t. Driver layer should indicate
1365  *                      its configuration in this structure.
1366  *                      The default values for struct bfa_iocfc_cfg_s can be
1367  *                      fetched using bfa_cfg_get_default() API.
1368  *
1369  *                      If cap's boundary check fails, the library will use
1370  *                      the default bfa_cap_t values (and log a warning msg).
1371  *
1372  * @param[out] meminfo - pointer to bfa_meminfo_t. This content
1373  *                      indicates the memory type (see bfa_mem_type_t) and
1374  *                      amount of memory required.
1375  *
1376  *                      Driver should allocate the memory, populate the
1377  *                      starting address for each block and provide the same
1378  *                      structure as input parameter to bfa_attach() call.
1379  *
1380  * @param[in] bfa -     pointer to the bfa structure, used while fetching the
1381  *                      dma, kva memory information of the bfa sub-modules.
1382  *
1383  * @return void
1384  *
1385  * Special Considerations: @note
1386  */
1387 void
1388 bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,
1389                 struct bfa_s *bfa)
1390 {
1391         int             i;
1392         struct bfa_mem_dma_s *port_dma = BFA_MEM_PORT_DMA(bfa);
1393         struct bfa_mem_dma_s *ablk_dma = BFA_MEM_ABLK_DMA(bfa);
1394         struct bfa_mem_dma_s *cee_dma = BFA_MEM_CEE_DMA(bfa);
1395         struct bfa_mem_dma_s *sfp_dma = BFA_MEM_SFP_DMA(bfa);
1396         struct bfa_mem_dma_s *flash_dma = BFA_MEM_FLASH_DMA(bfa);
1397         struct bfa_mem_dma_s *diag_dma = BFA_MEM_DIAG_DMA(bfa);
1398
1399         WARN_ON((cfg == NULL) || (meminfo == NULL));
1400
1401         memset((void *)meminfo, 0, sizeof(struct bfa_meminfo_s));
1402
1403         /* Initialize the DMA & KVA meminfo queues */
1404         INIT_LIST_HEAD(&meminfo->dma_info.qe);
1405         INIT_LIST_HEAD(&meminfo->kva_info.qe);
1406
1407         bfa_iocfc_meminfo(cfg, meminfo, bfa);
1408
1409         for (i = 0; hal_mods[i]; i++)
1410                 hal_mods[i]->meminfo(cfg, meminfo, bfa);
1411
1412         /* dma info setup */
1413         bfa_mem_dma_setup(meminfo, port_dma, bfa_port_meminfo());
1414         bfa_mem_dma_setup(meminfo, ablk_dma, bfa_ablk_meminfo());
1415         bfa_mem_dma_setup(meminfo, cee_dma, bfa_cee_meminfo());
1416         bfa_mem_dma_setup(meminfo, sfp_dma, bfa_sfp_meminfo());
1417         bfa_mem_dma_setup(meminfo, flash_dma,
1418                           bfa_flash_meminfo(cfg->drvcfg.min_cfg));
1419         bfa_mem_dma_setup(meminfo, diag_dma, bfa_diag_meminfo());
1420 }
1421
1422 /*
1423  * Use this function to do attach the driver instance with the BFA
1424  * library. This function will not trigger any HW initialization
1425  * process (which will be done in bfa_init() call)
1426  *
1427  * This call will fail, if the cap is out of range compared to
1428  * pre-defined values within the BFA library
1429  *
1430  * @param[out]  bfa     Pointer to bfa_t.
1431  * @param[in]   bfad    Opaque handle back to the driver's IOC structure
1432  * @param[in]   cfg     Pointer to bfa_ioc_cfg_t. Should be same structure
1433  *                      that was used in bfa_cfg_get_meminfo().
1434  * @param[in]   meminfo Pointer to bfa_meminfo_t. The driver should
1435  *                      use the bfa_cfg_get_meminfo() call to
1436  *                      find the memory blocks required, allocate the
1437  *                      required memory and provide the starting addresses.
1438  * @param[in]   pcidev  pointer to struct bfa_pcidev_s
1439  *
1440  * @return
1441  * void
1442  *
1443  * Special Considerations:
1444  *
1445  * @note
1446  *
1447  */
1448 void
1449 bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
1450                struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
1451 {
1452         int     i;
1453         struct bfa_mem_dma_s *dma_info, *dma_elem;
1454         struct bfa_mem_kva_s *kva_info, *kva_elem;
1455         struct list_head *dm_qe, *km_qe;
1456
1457         bfa->fcs = BFA_FALSE;
1458
1459         WARN_ON((cfg == NULL) || (meminfo == NULL));
1460
1461         /* Initialize memory pointers for iterative allocation */
1462         dma_info = &meminfo->dma_info;
1463         dma_info->kva_curp = dma_info->kva;
1464         dma_info->dma_curp = dma_info->dma;
1465
1466         kva_info = &meminfo->kva_info;
1467         kva_info->kva_curp = kva_info->kva;
1468
1469         list_for_each(dm_qe, &dma_info->qe) {
1470                 dma_elem = (struct bfa_mem_dma_s *) dm_qe;
1471                 dma_elem->kva_curp = dma_elem->kva;
1472                 dma_elem->dma_curp = dma_elem->dma;
1473         }
1474
1475         list_for_each(km_qe, &kva_info->qe) {
1476                 kva_elem = (struct bfa_mem_kva_s *) km_qe;
1477                 kva_elem->kva_curp = kva_elem->kva;
1478         }
1479
1480         bfa_iocfc_attach(bfa, bfad, cfg, pcidev);
1481
1482         for (i = 0; hal_mods[i]; i++)
1483                 hal_mods[i]->attach(bfa, bfad, cfg, pcidev);
1484
1485         bfa_com_port_attach(bfa);
1486         bfa_com_ablk_attach(bfa);
1487         bfa_com_cee_attach(bfa);
1488         bfa_com_sfp_attach(bfa);
1489         bfa_com_flash_attach(bfa, cfg->drvcfg.min_cfg);
1490         bfa_com_diag_attach(bfa);
1491 }
1492
1493 /*
1494  * Use this function to delete a BFA IOC. IOC should be stopped (by
1495  * calling bfa_stop()) before this function call.
1496  *
1497  * @param[in] bfa - pointer to bfa_t.
1498  *
1499  * @return
1500  * void
1501  *
1502  * Special Considerations:
1503  *
1504  * @note
1505  */
1506 void
1507 bfa_detach(struct bfa_s *bfa)
1508 {
1509         int     i;
1510
1511         for (i = 0; hal_mods[i]; i++)
1512                 hal_mods[i]->detach(bfa);
1513         bfa_ioc_detach(&bfa->ioc);
1514 }
1515
1516 void
1517 bfa_comp_deq(struct bfa_s *bfa, struct list_head *comp_q)
1518 {
1519         INIT_LIST_HEAD(comp_q);
1520         list_splice_tail_init(&bfa->comp_q, comp_q);
1521 }
1522
1523 void
1524 bfa_comp_process(struct bfa_s *bfa, struct list_head *comp_q)
1525 {
1526         struct list_head                *qe;
1527         struct list_head                *qen;
1528         struct bfa_cb_qe_s      *hcb_qe;
1529
1530         list_for_each_safe(qe, qen, comp_q) {
1531                 hcb_qe = (struct bfa_cb_qe_s *) qe;
1532                 hcb_qe->cbfn(hcb_qe->cbarg, BFA_TRUE);
1533         }
1534 }
1535
1536 void
1537 bfa_comp_free(struct bfa_s *bfa, struct list_head *comp_q)
1538 {
1539         struct list_head                *qe;
1540         struct bfa_cb_qe_s      *hcb_qe;
1541
1542         while (!list_empty(comp_q)) {
1543                 bfa_q_deq(comp_q, &qe);
1544                 hcb_qe = (struct bfa_cb_qe_s *) qe;
1545                 hcb_qe->cbfn(hcb_qe->cbarg, BFA_FALSE);
1546         }
1547 }
1548
1549
1550 /*
1551  * Return the list of PCI vendor/device id lists supported by this
1552  * BFA instance.
1553  */
1554 void
1555 bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids)
1556 {
1557         static struct bfa_pciid_s __pciids[] = {
1558                 {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G2P},
1559                 {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G1P},
1560                 {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_CT},
1561                 {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_CT_FC},
1562         };
1563
1564         *npciids = sizeof(__pciids) / sizeof(__pciids[0]);
1565         *pciids = __pciids;
1566 }
1567
1568 /*
1569  * Use this function query the default struct bfa_iocfc_cfg_s value (compiled
1570  * into BFA layer). The OS driver can then turn back and overwrite entries that
1571  * have been configured by the user.
1572  *
1573  * @param[in] cfg - pointer to bfa_ioc_cfg_t
1574  *
1575  * @return
1576  *      void
1577  *
1578  * Special Considerations:
1579  * note
1580  */
1581 void
1582 bfa_cfg_get_default(struct bfa_iocfc_cfg_s *cfg)
1583 {
1584         cfg->fwcfg.num_fabrics = DEF_CFG_NUM_FABRICS;
1585         cfg->fwcfg.num_lports = DEF_CFG_NUM_LPORTS;
1586         cfg->fwcfg.num_rports = DEF_CFG_NUM_RPORTS;
1587         cfg->fwcfg.num_ioim_reqs = DEF_CFG_NUM_IOIM_REQS;
1588         cfg->fwcfg.num_tskim_reqs = DEF_CFG_NUM_TSKIM_REQS;
1589         cfg->fwcfg.num_fcxp_reqs = DEF_CFG_NUM_FCXP_REQS;
1590         cfg->fwcfg.num_uf_bufs = DEF_CFG_NUM_UF_BUFS;
1591         cfg->fwcfg.num_cqs = DEF_CFG_NUM_CQS;
1592         cfg->fwcfg.num_fwtio_reqs = 0;
1593
1594         cfg->drvcfg.num_reqq_elems = DEF_CFG_NUM_REQQ_ELEMS;
1595         cfg->drvcfg.num_rspq_elems = DEF_CFG_NUM_RSPQ_ELEMS;
1596         cfg->drvcfg.num_sgpgs = DEF_CFG_NUM_SGPGS;
1597         cfg->drvcfg.num_sboot_tgts = DEF_CFG_NUM_SBOOT_TGTS;
1598         cfg->drvcfg.num_sboot_luns = DEF_CFG_NUM_SBOOT_LUNS;
1599         cfg->drvcfg.path_tov = BFA_FCPIM_PATHTOV_DEF;
1600         cfg->drvcfg.ioc_recover = BFA_FALSE;
1601         cfg->drvcfg.delay_comp = BFA_FALSE;
1602
1603 }
1604
1605 void
1606 bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg)
1607 {
1608         bfa_cfg_get_default(cfg);
1609         cfg->fwcfg.num_ioim_reqs   = BFA_IOIM_MIN;
1610         cfg->fwcfg.num_tskim_reqs  = BFA_TSKIM_MIN;
1611         cfg->fwcfg.num_fcxp_reqs   = BFA_FCXP_MIN;
1612         cfg->fwcfg.num_uf_bufs     = BFA_UF_MIN;
1613         cfg->fwcfg.num_rports      = BFA_RPORT_MIN;
1614         cfg->fwcfg.num_fwtio_reqs = 0;
1615
1616         cfg->drvcfg.num_sgpgs      = BFA_SGPG_MIN;
1617         cfg->drvcfg.num_reqq_elems = BFA_REQQ_NELEMS_MIN;
1618         cfg->drvcfg.num_rspq_elems = BFA_RSPQ_NELEMS_MIN;
1619         cfg->drvcfg.min_cfg        = BFA_TRUE;
1620 }