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