2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
18 #include <cs/bfa_debug.h>
20 #include <log/bfa_log_hal.h>
21 #include <bfi/bfi_boot.h>
22 #include <bfi/bfi_cbreg.h>
23 #include <aen/bfa_aen_ioc.h>
24 #include <defs/bfa_defs_iocfc.h>
25 #include <defs/bfa_defs_pci.h>
26 #include "bfa_callback_priv.h"
29 BFA_TRC_FILE(HAL
, IOCFC
);
32 * IOC local definitions
34 #define BFA_IOCFC_TOV 5000 /* msecs */
37 BFA_IOCFC_ACT_NONE
= 0,
38 BFA_IOCFC_ACT_INIT
= 1,
39 BFA_IOCFC_ACT_STOP
= 2,
40 BFA_IOCFC_ACT_DISABLE
= 3,
44 * forward declarations
46 static void bfa_iocfc_enable_cbfn(void *bfa_arg
, enum bfa_status status
);
47 static void bfa_iocfc_disable_cbfn(void *bfa_arg
);
48 static void bfa_iocfc_hbfail_cbfn(void *bfa_arg
);
49 static void bfa_iocfc_reset_cbfn(void *bfa_arg
);
50 static void bfa_iocfc_stats_clear(void *bfa_arg
);
51 static void bfa_iocfc_stats_swap(struct bfa_fw_stats_s
*d
,
52 struct bfa_fw_stats_s
*s
);
53 static void bfa_iocfc_stats_clr_cb(void *bfa_arg
, bfa_boolean_t complete
);
54 static void bfa_iocfc_stats_clr_timeout(void *bfa_arg
);
55 static void bfa_iocfc_stats_cb(void *bfa_arg
, bfa_boolean_t complete
);
56 static void bfa_iocfc_stats_timeout(void *bfa_arg
);
58 static struct bfa_ioc_cbfn_s bfa_iocfc_cbfn
;
61 * bfa_ioc_pvt BFA IOC private functions
65 bfa_iocfc_cqs_sz(struct bfa_iocfc_cfg_s
*cfg
, u32
*dm_len
)
67 int i
, per_reqq_sz
, per_rspq_sz
;
69 per_reqq_sz
= BFA_ROUNDUP((cfg
->drvcfg
.num_reqq_elems
* BFI_LMSG_SZ
),
71 per_rspq_sz
= BFA_ROUNDUP((cfg
->drvcfg
.num_rspq_elems
* BFI_LMSG_SZ
),
77 for (i
= 0; i
< cfg
->fwcfg
.num_cqs
; i
++) {
78 *dm_len
= *dm_len
+ per_reqq_sz
;
79 *dm_len
= *dm_len
+ per_rspq_sz
;
83 * Calculate Shadow CI/PI size
85 for (i
= 0; i
< cfg
->fwcfg
.num_cqs
; i
++)
86 *dm_len
+= (2 * BFA_CACHELINE_SZ
);
90 bfa_iocfc_fw_cfg_sz(struct bfa_iocfc_cfg_s
*cfg
, u32
*dm_len
)
93 BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s
), BFA_CACHELINE_SZ
);
95 BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s
),
97 *dm_len
+= BFA_ROUNDUP(sizeof(struct bfa_fw_stats_s
), BFA_CACHELINE_SZ
);
101 * Use the Mailbox interface to send BFI_IOCFC_H2I_CFG_REQ
104 bfa_iocfc_send_cfg(void *bfa_arg
)
106 struct bfa_s
*bfa
= bfa_arg
;
107 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
108 struct bfi_iocfc_cfg_req_s cfg_req
;
109 struct bfi_iocfc_cfg_s
*cfg_info
= iocfc
->cfginfo
;
110 struct bfa_iocfc_cfg_s
*cfg
= &iocfc
->cfg
;
113 bfa_assert(cfg
->fwcfg
.num_cqs
<= BFI_IOC_MAX_CQS
);
114 bfa_trc(bfa
, cfg
->fwcfg
.num_cqs
);
116 iocfc
->cfgdone
= BFA_FALSE
;
117 bfa_iocfc_reset_queues(bfa
);
120 * initialize IOC configuration info
122 cfg_info
->endian_sig
= BFI_IOC_ENDIAN_SIG
;
123 cfg_info
->num_cqs
= cfg
->fwcfg
.num_cqs
;
125 bfa_dma_be_addr_set(cfg_info
->cfgrsp_addr
, iocfc
->cfgrsp_dma
.pa
);
126 bfa_dma_be_addr_set(cfg_info
->stats_addr
, iocfc
->stats_pa
);
129 * dma map REQ and RSP circular queues and shadow pointers
131 for (i
= 0; i
< cfg
->fwcfg
.num_cqs
; i
++) {
132 bfa_dma_be_addr_set(cfg_info
->req_cq_ba
[i
],
133 iocfc
->req_cq_ba
[i
].pa
);
134 bfa_dma_be_addr_set(cfg_info
->req_shadow_ci
[i
],
135 iocfc
->req_cq_shadow_ci
[i
].pa
);
136 cfg_info
->req_cq_elems
[i
] =
137 bfa_os_htons(cfg
->drvcfg
.num_reqq_elems
);
139 bfa_dma_be_addr_set(cfg_info
->rsp_cq_ba
[i
],
140 iocfc
->rsp_cq_ba
[i
].pa
);
141 bfa_dma_be_addr_set(cfg_info
->rsp_shadow_pi
[i
],
142 iocfc
->rsp_cq_shadow_pi
[i
].pa
);
143 cfg_info
->rsp_cq_elems
[i
] =
144 bfa_os_htons(cfg
->drvcfg
.num_rspq_elems
);
148 * dma map IOC configuration itself
150 bfi_h2i_set(cfg_req
.mh
, BFI_MC_IOCFC
, BFI_IOCFC_H2I_CFG_REQ
,
152 bfa_dma_be_addr_set(cfg_req
.ioc_cfg_dma_addr
, iocfc
->cfg_info
.pa
);
154 bfa_ioc_mbox_send(&bfa
->ioc
, &cfg_req
,
155 sizeof(struct bfi_iocfc_cfg_req_s
));
159 bfa_iocfc_init_mem(struct bfa_s
*bfa
, void *bfad
, struct bfa_iocfc_cfg_s
*cfg
,
160 struct bfa_pcidev_s
*pcidev
)
162 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
166 iocfc
->action
= BFA_IOCFC_ACT_NONE
;
168 bfa_os_assign(iocfc
->cfg
, *cfg
);
171 * Initialize chip specific handlers.
173 if (bfa_ioc_devid(&bfa
->ioc
) == BFA_PCI_DEVICE_ID_CT
) {
174 iocfc
->hwif
.hw_reginit
= bfa_hwct_reginit
;
175 iocfc
->hwif
.hw_reqq_ack
= bfa_hwct_reqq_ack
;
176 iocfc
->hwif
.hw_rspq_ack
= bfa_hwct_rspq_ack
;
177 iocfc
->hwif
.hw_msix_init
= bfa_hwct_msix_init
;
178 iocfc
->hwif
.hw_msix_install
= bfa_hwct_msix_install
;
179 iocfc
->hwif
.hw_msix_uninstall
= bfa_hwct_msix_uninstall
;
180 iocfc
->hwif
.hw_isr_mode_set
= bfa_hwct_isr_mode_set
;
181 iocfc
->hwif
.hw_msix_getvecs
= bfa_hwct_msix_getvecs
;
183 iocfc
->hwif
.hw_reginit
= bfa_hwcb_reginit
;
184 iocfc
->hwif
.hw_reqq_ack
= bfa_hwcb_reqq_ack
;
185 iocfc
->hwif
.hw_rspq_ack
= bfa_hwcb_rspq_ack
;
186 iocfc
->hwif
.hw_msix_init
= bfa_hwcb_msix_init
;
187 iocfc
->hwif
.hw_msix_install
= bfa_hwcb_msix_install
;
188 iocfc
->hwif
.hw_msix_uninstall
= bfa_hwcb_msix_uninstall
;
189 iocfc
->hwif
.hw_isr_mode_set
= bfa_hwcb_isr_mode_set
;
190 iocfc
->hwif
.hw_msix_getvecs
= bfa_hwcb_msix_getvecs
;
193 iocfc
->hwif
.hw_reginit(bfa
);
198 bfa_iocfc_mem_claim(struct bfa_s
*bfa
, struct bfa_iocfc_cfg_s
*cfg
,
199 struct bfa_meminfo_s
*meminfo
)
203 int i
, per_reqq_sz
, per_rspq_sz
;
204 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
207 dm_kva
= bfa_meminfo_dma_virt(meminfo
);
208 dm_pa
= bfa_meminfo_dma_phys(meminfo
);
211 * First allocate dma memory for IOC.
213 bfa_ioc_mem_claim(&bfa
->ioc
, dm_kva
, dm_pa
);
214 dm_kva
+= bfa_ioc_meminfo();
215 dm_pa
+= bfa_ioc_meminfo();
218 * Claim DMA-able memory for the request/response queues and for shadow
221 per_reqq_sz
= BFA_ROUNDUP((cfg
->drvcfg
.num_reqq_elems
* BFI_LMSG_SZ
),
223 per_rspq_sz
= BFA_ROUNDUP((cfg
->drvcfg
.num_rspq_elems
* BFI_LMSG_SZ
),
226 for (i
= 0; i
< cfg
->fwcfg
.num_cqs
; i
++) {
227 iocfc
->req_cq_ba
[i
].kva
= dm_kva
;
228 iocfc
->req_cq_ba
[i
].pa
= dm_pa
;
229 bfa_os_memset(dm_kva
, 0, per_reqq_sz
);
230 dm_kva
+= per_reqq_sz
;
231 dm_pa
+= per_reqq_sz
;
233 iocfc
->rsp_cq_ba
[i
].kva
= dm_kva
;
234 iocfc
->rsp_cq_ba
[i
].pa
= dm_pa
;
235 bfa_os_memset(dm_kva
, 0, per_rspq_sz
);
236 dm_kva
+= per_rspq_sz
;
237 dm_pa
+= per_rspq_sz
;
240 for (i
= 0; i
< cfg
->fwcfg
.num_cqs
; i
++) {
241 iocfc
->req_cq_shadow_ci
[i
].kva
= dm_kva
;
242 iocfc
->req_cq_shadow_ci
[i
].pa
= dm_pa
;
243 dm_kva
+= BFA_CACHELINE_SZ
;
244 dm_pa
+= BFA_CACHELINE_SZ
;
246 iocfc
->rsp_cq_shadow_pi
[i
].kva
= dm_kva
;
247 iocfc
->rsp_cq_shadow_pi
[i
].pa
= dm_pa
;
248 dm_kva
+= BFA_CACHELINE_SZ
;
249 dm_pa
+= BFA_CACHELINE_SZ
;
253 * Claim DMA-able memory for the config info page
255 bfa
->iocfc
.cfg_info
.kva
= dm_kva
;
256 bfa
->iocfc
.cfg_info
.pa
= dm_pa
;
257 bfa
->iocfc
.cfginfo
= (struct bfi_iocfc_cfg_s
*) dm_kva
;
258 dm_kva
+= BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s
), BFA_CACHELINE_SZ
);
259 dm_pa
+= BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s
), BFA_CACHELINE_SZ
);
262 * Claim DMA-able memory for the config response
264 bfa
->iocfc
.cfgrsp_dma
.kva
= dm_kva
;
265 bfa
->iocfc
.cfgrsp_dma
.pa
= dm_pa
;
266 bfa
->iocfc
.cfgrsp
= (struct bfi_iocfc_cfgrsp_s
*) dm_kva
;
269 BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s
),
271 dm_pa
+= BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s
),
275 * Claim DMA-able memory for iocfc stats
277 bfa
->iocfc
.stats_kva
= dm_kva
;
278 bfa
->iocfc
.stats_pa
= dm_pa
;
279 bfa
->iocfc
.fw_stats
= (struct bfa_fw_stats_s
*) dm_kva
;
280 dm_kva
+= BFA_ROUNDUP(sizeof(struct bfa_fw_stats_s
), BFA_CACHELINE_SZ
);
281 dm_pa
+= BFA_ROUNDUP(sizeof(struct bfa_fw_stats_s
), BFA_CACHELINE_SZ
);
283 bfa_meminfo_dma_virt(meminfo
) = dm_kva
;
284 bfa_meminfo_dma_phys(meminfo
) = dm_pa
;
286 dbgsz
= bfa_ioc_debug_trcsz(bfa_auto_recover
);
288 bfa_ioc_debug_memclaim(&bfa
->ioc
, bfa_meminfo_kva(meminfo
));
289 bfa_meminfo_kva(meminfo
) += dbgsz
;
294 * BFA submodules initialization completion notification.
297 bfa_iocfc_initdone_submod(struct bfa_s
*bfa
)
301 for (i
= 0; hal_mods
[i
]; i
++)
302 hal_mods
[i
]->initdone(bfa
);
306 * Start BFA submodules.
309 bfa_iocfc_start_submod(struct bfa_s
*bfa
)
313 bfa
->rme_process
= BFA_TRUE
;
315 for (i
= 0; hal_mods
[i
]; i
++)
316 hal_mods
[i
]->start(bfa
);
320 * Disable BFA submodules.
323 bfa_iocfc_disable_submod(struct bfa_s
*bfa
)
327 for (i
= 0; hal_mods
[i
]; i
++)
328 hal_mods
[i
]->iocdisable(bfa
);
332 bfa_iocfc_init_cb(void *bfa_arg
, bfa_boolean_t complete
)
334 struct bfa_s
*bfa
= bfa_arg
;
337 if (bfa
->iocfc
.cfgdone
)
338 bfa_cb_init(bfa
->bfad
, BFA_STATUS_OK
);
340 bfa_cb_init(bfa
->bfad
, BFA_STATUS_FAILED
);
342 if (bfa
->iocfc
.cfgdone
)
343 bfa
->iocfc
.action
= BFA_IOCFC_ACT_NONE
;
348 bfa_iocfc_stop_cb(void *bfa_arg
, bfa_boolean_t
compl)
350 struct bfa_s
*bfa
= bfa_arg
;
351 struct bfad_s
*bfad
= bfa
->bfad
;
354 complete(&bfad
->comp
);
357 bfa
->iocfc
.action
= BFA_IOCFC_ACT_NONE
;
361 bfa_iocfc_disable_cb(void *bfa_arg
, bfa_boolean_t
compl)
363 struct bfa_s
*bfa
= bfa_arg
;
364 struct bfad_s
*bfad
= bfa
->bfad
;
367 complete(&bfad
->disable_comp
);
371 * Update BFA configuration from firmware configuration.
374 bfa_iocfc_cfgrsp(struct bfa_s
*bfa
)
376 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
377 struct bfi_iocfc_cfgrsp_s
*cfgrsp
= iocfc
->cfgrsp
;
378 struct bfa_iocfc_fwcfg_s
*fwcfg
= &cfgrsp
->fwcfg
;
379 struct bfi_iocfc_cfg_s
*cfginfo
= iocfc
->cfginfo
;
381 fwcfg
->num_cqs
= fwcfg
->num_cqs
;
382 fwcfg
->num_ioim_reqs
= bfa_os_ntohs(fwcfg
->num_ioim_reqs
);
383 fwcfg
->num_tskim_reqs
= bfa_os_ntohs(fwcfg
->num_tskim_reqs
);
384 fwcfg
->num_fcxp_reqs
= bfa_os_ntohs(fwcfg
->num_fcxp_reqs
);
385 fwcfg
->num_uf_bufs
= bfa_os_ntohs(fwcfg
->num_uf_bufs
);
386 fwcfg
->num_rports
= bfa_os_ntohs(fwcfg
->num_rports
);
388 cfginfo
->intr_attr
.coalesce
= cfgrsp
->intr_attr
.coalesce
;
389 cfginfo
->intr_attr
.delay
= bfa_os_ntohs(cfgrsp
->intr_attr
.delay
);
390 cfginfo
->intr_attr
.latency
= bfa_os_ntohs(cfgrsp
->intr_attr
.latency
);
392 iocfc
->cfgdone
= BFA_TRUE
;
395 * Configuration is complete - initialize/start submodules
397 if (iocfc
->action
== BFA_IOCFC_ACT_INIT
)
398 bfa_cb_queue(bfa
, &iocfc
->init_hcb_qe
, bfa_iocfc_init_cb
, bfa
);
400 bfa_iocfc_start_submod(bfa
);
404 bfa_iocfc_stats_clear(void *bfa_arg
)
406 struct bfa_s
*bfa
= bfa_arg
;
407 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
408 struct bfi_iocfc_stats_req_s stats_req
;
410 bfa_timer_start(bfa
, &iocfc
->stats_timer
,
411 bfa_iocfc_stats_clr_timeout
, bfa
,
414 bfi_h2i_set(stats_req
.mh
, BFI_MC_IOCFC
, BFI_IOCFC_H2I_CLEAR_STATS_REQ
,
416 bfa_ioc_mbox_send(&bfa
->ioc
, &stats_req
,
417 sizeof(struct bfi_iocfc_stats_req_s
));
421 bfa_iocfc_stats_swap(struct bfa_fw_stats_s
*d
, struct bfa_fw_stats_s
*s
)
423 u32
*dip
= (u32
*) d
;
424 u32
*sip
= (u32
*) s
;
427 for (i
= 0; i
< (sizeof(struct bfa_fw_stats_s
) / sizeof(u32
)); i
++)
428 dip
[i
] = bfa_os_ntohl(sip
[i
]);
432 bfa_iocfc_stats_clr_cb(void *bfa_arg
, bfa_boolean_t complete
)
434 struct bfa_s
*bfa
= bfa_arg
;
435 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
438 bfa_ioc_clr_stats(&bfa
->ioc
);
439 iocfc
->stats_cbfn(iocfc
->stats_cbarg
, iocfc
->stats_status
);
441 iocfc
->stats_busy
= BFA_FALSE
;
442 iocfc
->stats_status
= BFA_STATUS_OK
;
447 bfa_iocfc_stats_clr_timeout(void *bfa_arg
)
449 struct bfa_s
*bfa
= bfa_arg
;
450 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
454 iocfc
->stats_status
= BFA_STATUS_ETIMER
;
455 bfa_cb_queue(bfa
, &iocfc
->stats_hcb_qe
, bfa_iocfc_stats_clr_cb
, bfa
);
459 bfa_iocfc_stats_cb(void *bfa_arg
, bfa_boolean_t complete
)
461 struct bfa_s
*bfa
= bfa_arg
;
462 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
465 if (iocfc
->stats_status
== BFA_STATUS_OK
) {
466 bfa_os_memset(iocfc
->stats_ret
, 0,
467 sizeof(*iocfc
->stats_ret
));
468 bfa_iocfc_stats_swap(&iocfc
->stats_ret
->fw_stats
,
471 iocfc
->stats_cbfn(iocfc
->stats_cbarg
, iocfc
->stats_status
);
473 iocfc
->stats_busy
= BFA_FALSE
;
474 iocfc
->stats_status
= BFA_STATUS_OK
;
479 bfa_iocfc_stats_timeout(void *bfa_arg
)
481 struct bfa_s
*bfa
= bfa_arg
;
482 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
486 iocfc
->stats_status
= BFA_STATUS_ETIMER
;
487 bfa_cb_queue(bfa
, &iocfc
->stats_hcb_qe
, bfa_iocfc_stats_cb
, bfa
);
491 bfa_iocfc_stats_query(struct bfa_s
*bfa
)
493 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
494 struct bfi_iocfc_stats_req_s stats_req
;
496 bfa_timer_start(bfa
, &iocfc
->stats_timer
,
497 bfa_iocfc_stats_timeout
, bfa
, BFA_IOCFC_TOV
);
499 bfi_h2i_set(stats_req
.mh
, BFI_MC_IOCFC
, BFI_IOCFC_H2I_GET_STATS_REQ
,
501 bfa_ioc_mbox_send(&bfa
->ioc
, &stats_req
,
502 sizeof(struct bfi_iocfc_stats_req_s
));
506 bfa_iocfc_reset_queues(struct bfa_s
*bfa
)
510 for (q
= 0; q
< BFI_IOC_MAX_CQS
; q
++) {
511 bfa_reqq_ci(bfa
, q
) = 0;
512 bfa_reqq_pi(bfa
, q
) = 0;
513 bfa_rspq_ci(bfa
, q
) = 0;
514 bfa_rspq_pi(bfa
, q
) = 0;
519 * IOC enable request is complete
522 bfa_iocfc_enable_cbfn(void *bfa_arg
, enum bfa_status status
)
524 struct bfa_s
*bfa
= bfa_arg
;
526 if (status
!= BFA_STATUS_OK
) {
527 bfa_isr_disable(bfa
);
528 if (bfa
->iocfc
.action
== BFA_IOCFC_ACT_INIT
)
529 bfa_cb_queue(bfa
, &bfa
->iocfc
.init_hcb_qe
,
530 bfa_iocfc_init_cb
, bfa
);
534 bfa_iocfc_initdone_submod(bfa
);
535 bfa_iocfc_send_cfg(bfa
);
539 * IOC disable request is complete
542 bfa_iocfc_disable_cbfn(void *bfa_arg
)
544 struct bfa_s
*bfa
= bfa_arg
;
546 bfa_isr_disable(bfa
);
547 bfa_iocfc_disable_submod(bfa
);
549 if (bfa
->iocfc
.action
== BFA_IOCFC_ACT_STOP
)
550 bfa_cb_queue(bfa
, &bfa
->iocfc
.stop_hcb_qe
, bfa_iocfc_stop_cb
,
553 bfa_assert(bfa
->iocfc
.action
== BFA_IOCFC_ACT_DISABLE
);
554 bfa_cb_queue(bfa
, &bfa
->iocfc
.dis_hcb_qe
, bfa_iocfc_disable_cb
,
560 * Notify sub-modules of hardware failure.
563 bfa_iocfc_hbfail_cbfn(void *bfa_arg
)
565 struct bfa_s
*bfa
= bfa_arg
;
567 bfa
->rme_process
= BFA_FALSE
;
569 bfa_isr_disable(bfa
);
570 bfa_iocfc_disable_submod(bfa
);
572 if (bfa
->iocfc
.action
== BFA_IOCFC_ACT_INIT
)
573 bfa_cb_queue(bfa
, &bfa
->iocfc
.init_hcb_qe
, bfa_iocfc_init_cb
,
578 * Actions on chip-reset completion.
581 bfa_iocfc_reset_cbfn(void *bfa_arg
)
583 struct bfa_s
*bfa
= bfa_arg
;
585 bfa_iocfc_reset_queues(bfa
);
596 * Query IOC memory requirement information.
599 bfa_iocfc_meminfo(struct bfa_iocfc_cfg_s
*cfg
, u32
*km_len
,
602 /* dma memory for IOC */
603 *dm_len
+= bfa_ioc_meminfo();
605 bfa_iocfc_fw_cfg_sz(cfg
, dm_len
);
606 bfa_iocfc_cqs_sz(cfg
, dm_len
);
607 *km_len
+= bfa_ioc_debug_trcsz(bfa_auto_recover
);
611 * Query IOC memory requirement information.
614 bfa_iocfc_attach(struct bfa_s
*bfa
, void *bfad
, struct bfa_iocfc_cfg_s
*cfg
,
615 struct bfa_meminfo_s
*meminfo
, struct bfa_pcidev_s
*pcidev
)
619 bfa_iocfc_cbfn
.enable_cbfn
= bfa_iocfc_enable_cbfn
;
620 bfa_iocfc_cbfn
.disable_cbfn
= bfa_iocfc_disable_cbfn
;
621 bfa_iocfc_cbfn
.hbfail_cbfn
= bfa_iocfc_hbfail_cbfn
;
622 bfa_iocfc_cbfn
.reset_cbfn
= bfa_iocfc_reset_cbfn
;
624 bfa_ioc_attach(&bfa
->ioc
, bfa
, &bfa_iocfc_cbfn
, &bfa
->timer_mod
,
625 bfa
->trcmod
, bfa
->aen
, bfa
->logm
);
628 * Choose FC (ssid: 0x1C) v/s FCoE (ssid: 0x14) mode.
631 bfa_ioc_set_fcmode(&bfa
->ioc
);
633 bfa_ioc_pci_init(&bfa
->ioc
, pcidev
, BFI_MC_IOCFC
);
634 bfa_ioc_mbox_register(&bfa
->ioc
, bfa_mbox_isrs
);
636 bfa_iocfc_init_mem(bfa
, bfad
, cfg
, pcidev
);
637 bfa_iocfc_mem_claim(bfa
, cfg
, meminfo
);
638 bfa_timer_init(&bfa
->timer_mod
);
640 INIT_LIST_HEAD(&bfa
->comp_q
);
641 for (i
= 0; i
< BFI_IOC_MAX_CQS
; i
++)
642 INIT_LIST_HEAD(&bfa
->reqq_waitq
[i
]);
646 * Query IOC memory requirement information.
649 bfa_iocfc_detach(struct bfa_s
*bfa
)
651 bfa_ioc_detach(&bfa
->ioc
);
655 * Query IOC memory requirement information.
658 bfa_iocfc_init(struct bfa_s
*bfa
)
660 bfa
->iocfc
.action
= BFA_IOCFC_ACT_INIT
;
661 bfa_ioc_enable(&bfa
->ioc
);
665 * IOC start called from bfa_start(). Called to start IOC operations
666 * at driver instantiation for this instance.
669 bfa_iocfc_start(struct bfa_s
*bfa
)
671 if (bfa
->iocfc
.cfgdone
)
672 bfa_iocfc_start_submod(bfa
);
676 * IOC stop called from bfa_stop(). Called only when driver is unloaded
680 bfa_iocfc_stop(struct bfa_s
*bfa
)
682 bfa
->iocfc
.action
= BFA_IOCFC_ACT_STOP
;
684 bfa
->rme_process
= BFA_FALSE
;
685 bfa_ioc_disable(&bfa
->ioc
);
689 bfa_iocfc_isr(void *bfaarg
, struct bfi_mbmsg_s
*m
)
691 struct bfa_s
*bfa
= bfaarg
;
692 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
693 union bfi_iocfc_i2h_msg_u
*msg
;
695 msg
= (union bfi_iocfc_i2h_msg_u
*) m
;
696 bfa_trc(bfa
, msg
->mh
.msg_id
);
698 switch (msg
->mh
.msg_id
) {
699 case BFI_IOCFC_I2H_CFG_REPLY
:
700 iocfc
->cfg_reply
= &msg
->cfg_reply
;
701 bfa_iocfc_cfgrsp(bfa
);
704 case BFI_IOCFC_I2H_GET_STATS_RSP
:
705 if (iocfc
->stats_busy
== BFA_FALSE
706 || iocfc
->stats_status
== BFA_STATUS_ETIMER
)
709 bfa_timer_stop(&iocfc
->stats_timer
);
710 iocfc
->stats_status
= BFA_STATUS_OK
;
711 bfa_cb_queue(bfa
, &iocfc
->stats_hcb_qe
, bfa_iocfc_stats_cb
,
714 case BFI_IOCFC_I2H_CLEAR_STATS_RSP
:
716 * check for timer pop before processing the rsp
718 if (iocfc
->stats_busy
== BFA_FALSE
719 || iocfc
->stats_status
== BFA_STATUS_ETIMER
)
722 bfa_timer_stop(&iocfc
->stats_timer
);
723 iocfc
->stats_status
= BFA_STATUS_OK
;
724 bfa_cb_queue(bfa
, &iocfc
->stats_hcb_qe
,
725 bfa_iocfc_stats_clr_cb
, bfa
);
727 case BFI_IOCFC_I2H_UPDATEQ_RSP
:
728 iocfc
->updateq_cbfn(iocfc
->updateq_cbarg
, BFA_STATUS_OK
);
735 #ifndef BFA_BIOS_BUILD
737 bfa_adapter_get_attr(struct bfa_s
*bfa
, struct bfa_adapter_attr_s
*ad_attr
)
739 bfa_ioc_get_adapter_attr(&bfa
->ioc
, ad_attr
);
743 bfa_adapter_get_id(struct bfa_s
*bfa
)
745 return bfa_ioc_get_adid(&bfa
->ioc
);
749 bfa_iocfc_get_attr(struct bfa_s
*bfa
, struct bfa_iocfc_attr_s
*attr
)
751 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
753 attr
->intr_attr
= iocfc
->cfginfo
->intr_attr
;
754 attr
->config
= iocfc
->cfg
;
758 bfa_iocfc_israttr_set(struct bfa_s
*bfa
, struct bfa_iocfc_intr_attr_s
*attr
)
760 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
761 struct bfi_iocfc_set_intr_req_s
*m
;
763 iocfc
->cfginfo
->intr_attr
= *attr
;
764 if (!bfa_iocfc_is_operational(bfa
))
765 return BFA_STATUS_OK
;
767 m
= bfa_reqq_next(bfa
, BFA_REQQ_IOC
);
769 return BFA_STATUS_DEVBUSY
;
771 bfi_h2i_set(m
->mh
, BFI_MC_IOCFC
, BFI_IOCFC_H2I_SET_INTR_REQ
,
773 m
->coalesce
= attr
->coalesce
;
774 m
->delay
= bfa_os_htons(attr
->delay
);
775 m
->latency
= bfa_os_htons(attr
->latency
);
777 bfa_trc(bfa
, attr
->delay
);
778 bfa_trc(bfa
, attr
->latency
);
780 bfa_reqq_produce(bfa
, BFA_REQQ_IOC
);
781 return BFA_STATUS_OK
;
785 bfa_iocfc_set_snsbase(struct bfa_s
*bfa
, u64 snsbase_pa
)
787 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
789 iocfc
->cfginfo
->sense_buf_len
= (BFI_IOIM_SNSLEN
- 1);
790 bfa_dma_be_addr_set(iocfc
->cfginfo
->ioim_snsbase
, snsbase_pa
);
794 bfa_iocfc_get_stats(struct bfa_s
*bfa
, struct bfa_iocfc_stats_s
*stats
,
795 bfa_cb_ioc_t cbfn
, void *cbarg
)
797 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
799 if (iocfc
->stats_busy
) {
800 bfa_trc(bfa
, iocfc
->stats_busy
);
801 return BFA_STATUS_DEVBUSY
;
804 if (!bfa_iocfc_is_operational(bfa
)) {
806 return BFA_STATUS_IOC_NON_OP
;
809 iocfc
->stats_busy
= BFA_TRUE
;
810 iocfc
->stats_ret
= stats
;
811 iocfc
->stats_cbfn
= cbfn
;
812 iocfc
->stats_cbarg
= cbarg
;
814 bfa_iocfc_stats_query(bfa
);
816 return BFA_STATUS_OK
;
820 bfa_iocfc_clear_stats(struct bfa_s
*bfa
, bfa_cb_ioc_t cbfn
, void *cbarg
)
822 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
824 if (iocfc
->stats_busy
) {
825 bfa_trc(bfa
, iocfc
->stats_busy
);
826 return BFA_STATUS_DEVBUSY
;
829 if (!bfa_iocfc_is_operational(bfa
)) {
831 return BFA_STATUS_IOC_NON_OP
;
834 iocfc
->stats_busy
= BFA_TRUE
;
835 iocfc
->stats_cbfn
= cbfn
;
836 iocfc
->stats_cbarg
= cbarg
;
838 bfa_iocfc_stats_clear(bfa
);
839 return BFA_STATUS_OK
;
843 * Enable IOC after it is disabled.
846 bfa_iocfc_enable(struct bfa_s
*bfa
)
848 bfa_plog_str(bfa
->plog
, BFA_PL_MID_HAL
, BFA_PL_EID_MISC
, 0,
850 bfa_ioc_enable(&bfa
->ioc
);
854 bfa_iocfc_disable(struct bfa_s
*bfa
)
856 bfa_plog_str(bfa
->plog
, BFA_PL_MID_HAL
, BFA_PL_EID_MISC
, 0,
858 bfa
->iocfc
.action
= BFA_IOCFC_ACT_DISABLE
;
860 bfa
->rme_process
= BFA_FALSE
;
861 bfa_ioc_disable(&bfa
->ioc
);
866 bfa_iocfc_is_operational(struct bfa_s
*bfa
)
868 return bfa_ioc_is_operational(&bfa
->ioc
) && bfa
->iocfc
.cfgdone
;
872 * Return boot target port wwns -- read from boot information in flash.
875 bfa_iocfc_get_bootwwns(struct bfa_s
*bfa
, u8
*nwwns
, wwn_t
**wwns
)
877 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
878 struct bfi_iocfc_cfgrsp_s
*cfgrsp
= iocfc
->cfgrsp
;
880 *nwwns
= cfgrsp
->bootwwns
.nwwns
;
881 *wwns
= cfgrsp
->bootwwns
.wwn
;