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_rspq_ack
= bfa_hwct_rspq_ack
;
176 iocfc
->hwif
.hw_msix_init
= bfa_hwct_msix_init
;
177 iocfc
->hwif
.hw_msix_install
= bfa_hwct_msix_install
;
178 iocfc
->hwif
.hw_msix_uninstall
= bfa_hwct_msix_uninstall
;
179 iocfc
->hwif
.hw_isr_mode_set
= bfa_hwct_isr_mode_set
;
180 iocfc
->hwif
.hw_msix_getvecs
= bfa_hwct_msix_getvecs
;
182 iocfc
->hwif
.hw_reginit
= bfa_hwcb_reginit
;
183 iocfc
->hwif
.hw_rspq_ack
= bfa_hwcb_rspq_ack
;
184 iocfc
->hwif
.hw_msix_init
= bfa_hwcb_msix_init
;
185 iocfc
->hwif
.hw_msix_install
= bfa_hwcb_msix_install
;
186 iocfc
->hwif
.hw_msix_uninstall
= bfa_hwcb_msix_uninstall
;
187 iocfc
->hwif
.hw_isr_mode_set
= bfa_hwcb_isr_mode_set
;
188 iocfc
->hwif
.hw_msix_getvecs
= bfa_hwcb_msix_getvecs
;
191 iocfc
->hwif
.hw_reginit(bfa
);
196 bfa_iocfc_mem_claim(struct bfa_s
*bfa
, struct bfa_iocfc_cfg_s
*cfg
,
197 struct bfa_meminfo_s
*meminfo
)
201 int i
, per_reqq_sz
, per_rspq_sz
;
202 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
205 dm_kva
= bfa_meminfo_dma_virt(meminfo
);
206 dm_pa
= bfa_meminfo_dma_phys(meminfo
);
209 * First allocate dma memory for IOC.
211 bfa_ioc_mem_claim(&bfa
->ioc
, dm_kva
, dm_pa
);
212 dm_kva
+= bfa_ioc_meminfo();
213 dm_pa
+= bfa_ioc_meminfo();
216 * Claim DMA-able memory for the request/response queues and for shadow
219 per_reqq_sz
= BFA_ROUNDUP((cfg
->drvcfg
.num_reqq_elems
* BFI_LMSG_SZ
),
221 per_rspq_sz
= BFA_ROUNDUP((cfg
->drvcfg
.num_rspq_elems
* BFI_LMSG_SZ
),
224 for (i
= 0; i
< cfg
->fwcfg
.num_cqs
; i
++) {
225 iocfc
->req_cq_ba
[i
].kva
= dm_kva
;
226 iocfc
->req_cq_ba
[i
].pa
= dm_pa
;
227 bfa_os_memset(dm_kva
, 0, per_reqq_sz
);
228 dm_kva
+= per_reqq_sz
;
229 dm_pa
+= per_reqq_sz
;
231 iocfc
->rsp_cq_ba
[i
].kva
= dm_kva
;
232 iocfc
->rsp_cq_ba
[i
].pa
= dm_pa
;
233 bfa_os_memset(dm_kva
, 0, per_rspq_sz
);
234 dm_kva
+= per_rspq_sz
;
235 dm_pa
+= per_rspq_sz
;
238 for (i
= 0; i
< cfg
->fwcfg
.num_cqs
; i
++) {
239 iocfc
->req_cq_shadow_ci
[i
].kva
= dm_kva
;
240 iocfc
->req_cq_shadow_ci
[i
].pa
= dm_pa
;
241 dm_kva
+= BFA_CACHELINE_SZ
;
242 dm_pa
+= BFA_CACHELINE_SZ
;
244 iocfc
->rsp_cq_shadow_pi
[i
].kva
= dm_kva
;
245 iocfc
->rsp_cq_shadow_pi
[i
].pa
= dm_pa
;
246 dm_kva
+= BFA_CACHELINE_SZ
;
247 dm_pa
+= BFA_CACHELINE_SZ
;
251 * Claim DMA-able memory for the config info page
253 bfa
->iocfc
.cfg_info
.kva
= dm_kva
;
254 bfa
->iocfc
.cfg_info
.pa
= dm_pa
;
255 bfa
->iocfc
.cfginfo
= (struct bfi_iocfc_cfg_s
*) dm_kva
;
256 dm_kva
+= BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s
), BFA_CACHELINE_SZ
);
257 dm_pa
+= BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s
), BFA_CACHELINE_SZ
);
260 * Claim DMA-able memory for the config response
262 bfa
->iocfc
.cfgrsp_dma
.kva
= dm_kva
;
263 bfa
->iocfc
.cfgrsp_dma
.pa
= dm_pa
;
264 bfa
->iocfc
.cfgrsp
= (struct bfi_iocfc_cfgrsp_s
*) dm_kva
;
267 BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s
),
269 dm_pa
+= BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s
),
273 * Claim DMA-able memory for iocfc stats
275 bfa
->iocfc
.stats_kva
= dm_kva
;
276 bfa
->iocfc
.stats_pa
= dm_pa
;
277 bfa
->iocfc
.fw_stats
= (struct bfa_fw_stats_s
*) dm_kva
;
278 dm_kva
+= BFA_ROUNDUP(sizeof(struct bfa_fw_stats_s
), BFA_CACHELINE_SZ
);
279 dm_pa
+= BFA_ROUNDUP(sizeof(struct bfa_fw_stats_s
), BFA_CACHELINE_SZ
);
281 bfa_meminfo_dma_virt(meminfo
) = dm_kva
;
282 bfa_meminfo_dma_phys(meminfo
) = dm_pa
;
284 dbgsz
= bfa_ioc_debug_trcsz(bfa_auto_recover
);
286 bfa_ioc_debug_memclaim(&bfa
->ioc
, bfa_meminfo_kva(meminfo
));
287 bfa_meminfo_kva(meminfo
) += dbgsz
;
292 * BFA submodules initialization completion notification.
295 bfa_iocfc_initdone_submod(struct bfa_s
*bfa
)
299 for (i
= 0; hal_mods
[i
]; i
++)
300 hal_mods
[i
]->initdone(bfa
);
304 * Start BFA submodules.
307 bfa_iocfc_start_submod(struct bfa_s
*bfa
)
311 bfa
->rme_process
= BFA_TRUE
;
313 for (i
= 0; hal_mods
[i
]; i
++)
314 hal_mods
[i
]->start(bfa
);
318 * Disable BFA submodules.
321 bfa_iocfc_disable_submod(struct bfa_s
*bfa
)
325 for (i
= 0; hal_mods
[i
]; i
++)
326 hal_mods
[i
]->iocdisable(bfa
);
330 bfa_iocfc_init_cb(void *bfa_arg
, bfa_boolean_t complete
)
332 struct bfa_s
*bfa
= bfa_arg
;
335 if (bfa
->iocfc
.cfgdone
)
336 bfa_cb_init(bfa
->bfad
, BFA_STATUS_OK
);
338 bfa_cb_init(bfa
->bfad
, BFA_STATUS_FAILED
);
340 bfa
->iocfc
.action
= BFA_IOCFC_ACT_NONE
;
344 bfa_iocfc_stop_cb(void *bfa_arg
, bfa_boolean_t
compl)
346 struct bfa_s
*bfa
= bfa_arg
;
347 struct bfad_s
*bfad
= bfa
->bfad
;
350 complete(&bfad
->comp
);
353 bfa
->iocfc
.action
= BFA_IOCFC_ACT_NONE
;
357 bfa_iocfc_disable_cb(void *bfa_arg
, bfa_boolean_t
compl)
359 struct bfa_s
*bfa
= bfa_arg
;
360 struct bfad_s
*bfad
= bfa
->bfad
;
363 complete(&bfad
->disable_comp
);
367 * Update BFA configuration from firmware configuration.
370 bfa_iocfc_cfgrsp(struct bfa_s
*bfa
)
372 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
373 struct bfi_iocfc_cfgrsp_s
*cfgrsp
= iocfc
->cfgrsp
;
374 struct bfa_iocfc_fwcfg_s
*fwcfg
= &cfgrsp
->fwcfg
;
375 struct bfi_iocfc_cfg_s
*cfginfo
= iocfc
->cfginfo
;
377 fwcfg
->num_cqs
= fwcfg
->num_cqs
;
378 fwcfg
->num_ioim_reqs
= bfa_os_ntohs(fwcfg
->num_ioim_reqs
);
379 fwcfg
->num_tskim_reqs
= bfa_os_ntohs(fwcfg
->num_tskim_reqs
);
380 fwcfg
->num_fcxp_reqs
= bfa_os_ntohs(fwcfg
->num_fcxp_reqs
);
381 fwcfg
->num_uf_bufs
= bfa_os_ntohs(fwcfg
->num_uf_bufs
);
382 fwcfg
->num_rports
= bfa_os_ntohs(fwcfg
->num_rports
);
384 cfginfo
->intr_attr
.coalesce
= cfgrsp
->intr_attr
.coalesce
;
385 cfginfo
->intr_attr
.delay
= bfa_os_ntohs(cfgrsp
->intr_attr
.delay
);
386 cfginfo
->intr_attr
.latency
= bfa_os_ntohs(cfgrsp
->intr_attr
.latency
);
388 iocfc
->cfgdone
= BFA_TRUE
;
391 * Configuration is complete - initialize/start submodules
393 if (iocfc
->action
== BFA_IOCFC_ACT_INIT
)
394 bfa_cb_queue(bfa
, &iocfc
->init_hcb_qe
, bfa_iocfc_init_cb
, bfa
);
396 bfa_iocfc_start_submod(bfa
);
400 bfa_iocfc_stats_clear(void *bfa_arg
)
402 struct bfa_s
*bfa
= bfa_arg
;
403 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
404 struct bfi_iocfc_stats_req_s stats_req
;
406 bfa_timer_start(bfa
, &iocfc
->stats_timer
,
407 bfa_iocfc_stats_clr_timeout
, bfa
,
410 bfi_h2i_set(stats_req
.mh
, BFI_MC_IOCFC
, BFI_IOCFC_H2I_CLEAR_STATS_REQ
,
412 bfa_ioc_mbox_send(&bfa
->ioc
, &stats_req
,
413 sizeof(struct bfi_iocfc_stats_req_s
));
417 bfa_iocfc_stats_swap(struct bfa_fw_stats_s
*d
, struct bfa_fw_stats_s
*s
)
419 u32
*dip
= (u32
*) d
;
420 u32
*sip
= (u32
*) s
;
423 for (i
= 0; i
< (sizeof(struct bfa_fw_stats_s
) / sizeof(u32
)); i
++)
424 dip
[i
] = bfa_os_ntohl(sip
[i
]);
428 bfa_iocfc_stats_clr_cb(void *bfa_arg
, bfa_boolean_t complete
)
430 struct bfa_s
*bfa
= bfa_arg
;
431 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
434 bfa_ioc_clr_stats(&bfa
->ioc
);
435 iocfc
->stats_cbfn(iocfc
->stats_cbarg
, iocfc
->stats_status
);
437 iocfc
->stats_busy
= BFA_FALSE
;
438 iocfc
->stats_status
= BFA_STATUS_OK
;
443 bfa_iocfc_stats_clr_timeout(void *bfa_arg
)
445 struct bfa_s
*bfa
= bfa_arg
;
446 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
450 iocfc
->stats_status
= BFA_STATUS_ETIMER
;
451 bfa_cb_queue(bfa
, &iocfc
->stats_hcb_qe
, bfa_iocfc_stats_clr_cb
, bfa
);
455 bfa_iocfc_stats_cb(void *bfa_arg
, bfa_boolean_t complete
)
457 struct bfa_s
*bfa
= bfa_arg
;
458 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
461 if (iocfc
->stats_status
== BFA_STATUS_OK
) {
462 bfa_os_memset(iocfc
->stats_ret
, 0,
463 sizeof(*iocfc
->stats_ret
));
464 bfa_iocfc_stats_swap(&iocfc
->stats_ret
->fw_stats
,
467 iocfc
->stats_cbfn(iocfc
->stats_cbarg
, iocfc
->stats_status
);
469 iocfc
->stats_busy
= BFA_FALSE
;
470 iocfc
->stats_status
= BFA_STATUS_OK
;
475 bfa_iocfc_stats_timeout(void *bfa_arg
)
477 struct bfa_s
*bfa
= bfa_arg
;
478 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
482 iocfc
->stats_status
= BFA_STATUS_ETIMER
;
483 bfa_cb_queue(bfa
, &iocfc
->stats_hcb_qe
, bfa_iocfc_stats_cb
, bfa
);
487 bfa_iocfc_stats_query(struct bfa_s
*bfa
)
489 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
490 struct bfi_iocfc_stats_req_s stats_req
;
492 bfa_timer_start(bfa
, &iocfc
->stats_timer
,
493 bfa_iocfc_stats_timeout
, bfa
, BFA_IOCFC_TOV
);
495 bfi_h2i_set(stats_req
.mh
, BFI_MC_IOCFC
, BFI_IOCFC_H2I_GET_STATS_REQ
,
497 bfa_ioc_mbox_send(&bfa
->ioc
, &stats_req
,
498 sizeof(struct bfi_iocfc_stats_req_s
));
502 bfa_iocfc_reset_queues(struct bfa_s
*bfa
)
506 for (q
= 0; q
< BFI_IOC_MAX_CQS
; q
++) {
507 bfa_reqq_ci(bfa
, q
) = 0;
508 bfa_reqq_pi(bfa
, q
) = 0;
509 bfa_rspq_ci(bfa
, q
) = 0;
510 bfa_rspq_pi(bfa
, q
) = 0;
515 * IOC enable request is complete
518 bfa_iocfc_enable_cbfn(void *bfa_arg
, enum bfa_status status
)
520 struct bfa_s
*bfa
= bfa_arg
;
522 if (status
!= BFA_STATUS_OK
) {
523 bfa_isr_disable(bfa
);
524 if (bfa
->iocfc
.action
== BFA_IOCFC_ACT_INIT
)
525 bfa_cb_queue(bfa
, &bfa
->iocfc
.init_hcb_qe
,
526 bfa_iocfc_init_cb
, bfa
);
530 bfa_iocfc_initdone_submod(bfa
);
531 bfa_iocfc_send_cfg(bfa
);
535 * IOC disable request is complete
538 bfa_iocfc_disable_cbfn(void *bfa_arg
)
540 struct bfa_s
*bfa
= bfa_arg
;
542 bfa_isr_disable(bfa
);
543 bfa_iocfc_disable_submod(bfa
);
545 if (bfa
->iocfc
.action
== BFA_IOCFC_ACT_STOP
)
546 bfa_cb_queue(bfa
, &bfa
->iocfc
.stop_hcb_qe
, bfa_iocfc_stop_cb
,
549 bfa_assert(bfa
->iocfc
.action
== BFA_IOCFC_ACT_DISABLE
);
550 bfa_cb_queue(bfa
, &bfa
->iocfc
.dis_hcb_qe
, bfa_iocfc_disable_cb
,
556 * Notify sub-modules of hardware failure.
559 bfa_iocfc_hbfail_cbfn(void *bfa_arg
)
561 struct bfa_s
*bfa
= bfa_arg
;
563 bfa
->rme_process
= BFA_FALSE
;
565 bfa_isr_disable(bfa
);
566 bfa_iocfc_disable_submod(bfa
);
568 if (bfa
->iocfc
.action
== BFA_IOCFC_ACT_INIT
)
569 bfa_cb_queue(bfa
, &bfa
->iocfc
.init_hcb_qe
, bfa_iocfc_init_cb
,
574 * Actions on chip-reset completion.
577 bfa_iocfc_reset_cbfn(void *bfa_arg
)
579 struct bfa_s
*bfa
= bfa_arg
;
581 bfa_iocfc_reset_queues(bfa
);
592 * Query IOC memory requirement information.
595 bfa_iocfc_meminfo(struct bfa_iocfc_cfg_s
*cfg
, u32
*km_len
,
598 /* dma memory for IOC */
599 *dm_len
+= bfa_ioc_meminfo();
601 bfa_iocfc_fw_cfg_sz(cfg
, dm_len
);
602 bfa_iocfc_cqs_sz(cfg
, dm_len
);
603 *km_len
+= bfa_ioc_debug_trcsz(bfa_auto_recover
);
607 * Query IOC memory requirement information.
610 bfa_iocfc_attach(struct bfa_s
*bfa
, void *bfad
, struct bfa_iocfc_cfg_s
*cfg
,
611 struct bfa_meminfo_s
*meminfo
, struct bfa_pcidev_s
*pcidev
)
615 bfa_iocfc_cbfn
.enable_cbfn
= bfa_iocfc_enable_cbfn
;
616 bfa_iocfc_cbfn
.disable_cbfn
= bfa_iocfc_disable_cbfn
;
617 bfa_iocfc_cbfn
.hbfail_cbfn
= bfa_iocfc_hbfail_cbfn
;
618 bfa_iocfc_cbfn
.reset_cbfn
= bfa_iocfc_reset_cbfn
;
620 bfa_ioc_attach(&bfa
->ioc
, bfa
, &bfa_iocfc_cbfn
, &bfa
->timer_mod
,
621 bfa
->trcmod
, bfa
->aen
, bfa
->logm
);
622 bfa_ioc_pci_init(&bfa
->ioc
, pcidev
, BFI_MC_IOCFC
);
623 bfa_ioc_mbox_register(&bfa
->ioc
, bfa_mbox_isrs
);
626 * Choose FC (ssid: 0x1C) v/s FCoE (ssid: 0x14) mode.
629 bfa_ioc_set_fcmode(&bfa
->ioc
);
631 bfa_iocfc_init_mem(bfa
, bfad
, cfg
, pcidev
);
632 bfa_iocfc_mem_claim(bfa
, cfg
, meminfo
);
633 bfa_timer_init(&bfa
->timer_mod
);
635 INIT_LIST_HEAD(&bfa
->comp_q
);
636 for (i
= 0; i
< BFI_IOC_MAX_CQS
; i
++)
637 INIT_LIST_HEAD(&bfa
->reqq_waitq
[i
]);
641 * Query IOC memory requirement information.
644 bfa_iocfc_detach(struct bfa_s
*bfa
)
646 bfa_ioc_detach(&bfa
->ioc
);
650 * Query IOC memory requirement information.
653 bfa_iocfc_init(struct bfa_s
*bfa
)
655 bfa
->iocfc
.action
= BFA_IOCFC_ACT_INIT
;
656 bfa_ioc_enable(&bfa
->ioc
);
657 bfa_msix_install(bfa
);
661 * IOC start called from bfa_start(). Called to start IOC operations
662 * at driver instantiation for this instance.
665 bfa_iocfc_start(struct bfa_s
*bfa
)
667 if (bfa
->iocfc
.cfgdone
)
668 bfa_iocfc_start_submod(bfa
);
672 * IOC stop called from bfa_stop(). Called only when driver is unloaded
676 bfa_iocfc_stop(struct bfa_s
*bfa
)
678 bfa
->iocfc
.action
= BFA_IOCFC_ACT_STOP
;
680 bfa
->rme_process
= BFA_FALSE
;
681 bfa_ioc_disable(&bfa
->ioc
);
685 bfa_iocfc_isr(void *bfaarg
, struct bfi_mbmsg_s
*m
)
687 struct bfa_s
*bfa
= bfaarg
;
688 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
689 union bfi_iocfc_i2h_msg_u
*msg
;
691 msg
= (union bfi_iocfc_i2h_msg_u
*) m
;
692 bfa_trc(bfa
, msg
->mh
.msg_id
);
694 switch (msg
->mh
.msg_id
) {
695 case BFI_IOCFC_I2H_CFG_REPLY
:
696 iocfc
->cfg_reply
= &msg
->cfg_reply
;
697 bfa_iocfc_cfgrsp(bfa
);
700 case BFI_IOCFC_I2H_GET_STATS_RSP
:
701 if (iocfc
->stats_busy
== BFA_FALSE
702 || iocfc
->stats_status
== BFA_STATUS_ETIMER
)
705 bfa_timer_stop(&iocfc
->stats_timer
);
706 iocfc
->stats_status
= BFA_STATUS_OK
;
707 bfa_cb_queue(bfa
, &iocfc
->stats_hcb_qe
, bfa_iocfc_stats_cb
,
710 case BFI_IOCFC_I2H_CLEAR_STATS_RSP
:
712 * check for timer pop before processing the rsp
714 if (iocfc
->stats_busy
== BFA_FALSE
715 || iocfc
->stats_status
== BFA_STATUS_ETIMER
)
718 bfa_timer_stop(&iocfc
->stats_timer
);
719 iocfc
->stats_status
= BFA_STATUS_OK
;
720 bfa_cb_queue(bfa
, &iocfc
->stats_hcb_qe
,
721 bfa_iocfc_stats_clr_cb
, bfa
);
723 case BFI_IOCFC_I2H_UPDATEQ_RSP
:
724 iocfc
->updateq_cbfn(iocfc
->updateq_cbarg
, BFA_STATUS_OK
);
731 #ifndef BFA_BIOS_BUILD
733 bfa_adapter_get_attr(struct bfa_s
*bfa
, struct bfa_adapter_attr_s
*ad_attr
)
735 bfa_ioc_get_adapter_attr(&bfa
->ioc
, ad_attr
);
739 bfa_adapter_get_id(struct bfa_s
*bfa
)
741 return bfa_ioc_get_adid(&bfa
->ioc
);
745 bfa_iocfc_get_attr(struct bfa_s
*bfa
, struct bfa_iocfc_attr_s
*attr
)
747 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
749 attr
->intr_attr
= iocfc
->cfginfo
->intr_attr
;
750 attr
->config
= iocfc
->cfg
;
754 bfa_iocfc_israttr_set(struct bfa_s
*bfa
, struct bfa_iocfc_intr_attr_s
*attr
)
756 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
757 struct bfi_iocfc_set_intr_req_s
*m
;
759 iocfc
->cfginfo
->intr_attr
= *attr
;
760 if (!bfa_iocfc_is_operational(bfa
))
761 return BFA_STATUS_OK
;
763 m
= bfa_reqq_next(bfa
, BFA_REQQ_IOC
);
765 return BFA_STATUS_DEVBUSY
;
767 bfi_h2i_set(m
->mh
, BFI_MC_IOCFC
, BFI_IOCFC_H2I_SET_INTR_REQ
,
769 m
->coalesce
= attr
->coalesce
;
770 m
->delay
= bfa_os_htons(attr
->delay
);
771 m
->latency
= bfa_os_htons(attr
->latency
);
773 bfa_trc(bfa
, attr
->delay
);
774 bfa_trc(bfa
, attr
->latency
);
776 bfa_reqq_produce(bfa
, BFA_REQQ_IOC
);
777 return BFA_STATUS_OK
;
781 bfa_iocfc_set_snsbase(struct bfa_s
*bfa
, u64 snsbase_pa
)
783 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
785 iocfc
->cfginfo
->sense_buf_len
= (BFI_IOIM_SNSLEN
- 1);
786 bfa_dma_be_addr_set(iocfc
->cfginfo
->ioim_snsbase
, snsbase_pa
);
790 bfa_iocfc_get_stats(struct bfa_s
*bfa
, struct bfa_iocfc_stats_s
*stats
,
791 bfa_cb_ioc_t cbfn
, void *cbarg
)
793 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
795 if (iocfc
->stats_busy
) {
796 bfa_trc(bfa
, iocfc
->stats_busy
);
797 return (BFA_STATUS_DEVBUSY
);
800 iocfc
->stats_busy
= BFA_TRUE
;
801 iocfc
->stats_ret
= stats
;
802 iocfc
->stats_cbfn
= cbfn
;
803 iocfc
->stats_cbarg
= cbarg
;
805 bfa_iocfc_stats_query(bfa
);
807 return (BFA_STATUS_OK
);
811 bfa_iocfc_clear_stats(struct bfa_s
*bfa
, bfa_cb_ioc_t cbfn
, void *cbarg
)
813 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
815 if (iocfc
->stats_busy
) {
816 bfa_trc(bfa
, iocfc
->stats_busy
);
817 return (BFA_STATUS_DEVBUSY
);
820 iocfc
->stats_busy
= BFA_TRUE
;
821 iocfc
->stats_cbfn
= cbfn
;
822 iocfc
->stats_cbarg
= cbarg
;
824 bfa_iocfc_stats_clear(bfa
);
825 return (BFA_STATUS_OK
);
829 * Enable IOC after it is disabled.
832 bfa_iocfc_enable(struct bfa_s
*bfa
)
834 bfa_plog_str(bfa
->plog
, BFA_PL_MID_HAL
, BFA_PL_EID_MISC
, 0,
836 bfa_ioc_enable(&bfa
->ioc
);
840 bfa_iocfc_disable(struct bfa_s
*bfa
)
842 bfa_plog_str(bfa
->plog
, BFA_PL_MID_HAL
, BFA_PL_EID_MISC
, 0,
844 bfa
->iocfc
.action
= BFA_IOCFC_ACT_DISABLE
;
846 bfa
->rme_process
= BFA_FALSE
;
847 bfa_ioc_disable(&bfa
->ioc
);
852 bfa_iocfc_is_operational(struct bfa_s
*bfa
)
854 return bfa_ioc_is_operational(&bfa
->ioc
) && bfa
->iocfc
.cfgdone
;
858 * Return boot target port wwns -- read from boot information in flash.
861 bfa_iocfc_get_bootwwns(struct bfa_s
*bfa
, u8
*nwwns
, wwn_t
**wwns
)
863 struct bfa_iocfc_s
*iocfc
= &bfa
->iocfc
;
864 struct bfi_iocfc_cfgrsp_s
*cfgrsp
= iocfc
->cfgrsp
;
866 *nwwns
= cfgrsp
->bootwwns
.nwwns
;
867 *wwns
= cfgrsp
->bootwwns
.wwn
;