xref: /linux/drivers/scsi/bfa/bfa_core.c (revision ca6e0ea71cd0f442875b05357dd51774bd84b418)
17725ccfdSJing Huang /*
2a36c61f9SKrishna Gudipati  * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
37725ccfdSJing Huang  * All rights reserved
47725ccfdSJing Huang  * www.brocade.com
57725ccfdSJing Huang  *
67725ccfdSJing Huang  * Linux driver for Brocade Fibre Channel Host Bus Adapter.
77725ccfdSJing Huang  *
87725ccfdSJing Huang  * This program is free software; you can redistribute it and/or modify it
97725ccfdSJing Huang  * under the terms of the GNU General Public License (GPL) Version 2 as
107725ccfdSJing Huang  * published by the Free Software Foundation
117725ccfdSJing Huang  *
127725ccfdSJing Huang  * This program is distributed in the hope that it will be useful, but
137725ccfdSJing Huang  * WITHOUT ANY WARRANTY; without even the implied warranty of
147725ccfdSJing Huang  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
157725ccfdSJing Huang  * General Public License for more details.
167725ccfdSJing Huang  */
177725ccfdSJing Huang 
18f16a1750SMaggie Zhang #include "bfad_drv.h"
19a36c61f9SKrishna Gudipati #include "bfa_modules.h"
2011189208SKrishna Gudipati #include "bfi_reg.h"
21a36c61f9SKrishna Gudipati 
22a36c61f9SKrishna Gudipati BFA_TRC_FILE(HAL, CORE);
23a36c61f9SKrishna Gudipati 
245fbe25c7SJing Huang /*
25b77ee1fbSMaggie Zhang  * BFA module list terminated by NULL
26b77ee1fbSMaggie Zhang  */
27b77ee1fbSMaggie Zhang static struct bfa_module_s *hal_mods[] = {
283d7fc66dSKrishna Gudipati 	&hal_mod_fcdiag,
29b77ee1fbSMaggie Zhang 	&hal_mod_sgpg,
30b77ee1fbSMaggie Zhang 	&hal_mod_fcport,
31b77ee1fbSMaggie Zhang 	&hal_mod_fcxp,
32b77ee1fbSMaggie Zhang 	&hal_mod_lps,
33b77ee1fbSMaggie Zhang 	&hal_mod_uf,
34b77ee1fbSMaggie Zhang 	&hal_mod_rport,
35e2187d7fSKrishna Gudipati 	&hal_mod_fcp,
36b77ee1fbSMaggie Zhang 	NULL
37b77ee1fbSMaggie Zhang };
38b77ee1fbSMaggie Zhang 
39b77ee1fbSMaggie Zhang /*
40b77ee1fbSMaggie Zhang  * Message handlers for various modules.
41b77ee1fbSMaggie Zhang  */
42b77ee1fbSMaggie Zhang static bfa_isr_func_t  bfa_isrs[BFI_MC_MAX] = {
43b77ee1fbSMaggie Zhang 	bfa_isr_unhandled,	/* NONE */
44b77ee1fbSMaggie Zhang 	bfa_isr_unhandled,	/* BFI_MC_IOC */
453d7fc66dSKrishna Gudipati 	bfa_fcdiag_intr,	/* BFI_MC_DIAG */
46b77ee1fbSMaggie Zhang 	bfa_isr_unhandled,	/* BFI_MC_FLASH */
47b77ee1fbSMaggie Zhang 	bfa_isr_unhandled,	/* BFI_MC_CEE */
48b77ee1fbSMaggie Zhang 	bfa_fcport_isr,		/* BFI_MC_FCPORT */
49b77ee1fbSMaggie Zhang 	bfa_isr_unhandled,	/* BFI_MC_IOCFC */
50b77ee1fbSMaggie Zhang 	bfa_isr_unhandled,	/* BFI_MC_LL */
51b77ee1fbSMaggie Zhang 	bfa_uf_isr,		/* BFI_MC_UF */
52b77ee1fbSMaggie Zhang 	bfa_fcxp_isr,		/* BFI_MC_FCXP */
53b77ee1fbSMaggie Zhang 	bfa_lps_isr,		/* BFI_MC_LPS */
54b77ee1fbSMaggie Zhang 	bfa_rport_isr,		/* BFI_MC_RPORT */
55e2187d7fSKrishna Gudipati 	bfa_itn_isr,		/* BFI_MC_ITN */
56b77ee1fbSMaggie Zhang 	bfa_isr_unhandled,	/* BFI_MC_IOIM_READ */
57b77ee1fbSMaggie Zhang 	bfa_isr_unhandled,	/* BFI_MC_IOIM_WRITE */
58b77ee1fbSMaggie Zhang 	bfa_isr_unhandled,	/* BFI_MC_IOIM_IO */
59b77ee1fbSMaggie Zhang 	bfa_ioim_isr,		/* BFI_MC_IOIM */
60b77ee1fbSMaggie Zhang 	bfa_ioim_good_comp_isr,	/* BFI_MC_IOIM_IOCOM */
61b77ee1fbSMaggie Zhang 	bfa_tskim_isr,		/* BFI_MC_TSKIM */
62b77ee1fbSMaggie Zhang 	bfa_isr_unhandled,	/* BFI_MC_SBOOT */
63b77ee1fbSMaggie Zhang 	bfa_isr_unhandled,	/* BFI_MC_IPFC */
64b77ee1fbSMaggie Zhang 	bfa_isr_unhandled,	/* BFI_MC_PORT */
65b77ee1fbSMaggie Zhang 	bfa_isr_unhandled,	/* --------- */
66b77ee1fbSMaggie Zhang 	bfa_isr_unhandled,	/* --------- */
67b77ee1fbSMaggie Zhang 	bfa_isr_unhandled,	/* --------- */
68b77ee1fbSMaggie Zhang 	bfa_isr_unhandled,	/* --------- */
69b77ee1fbSMaggie Zhang 	bfa_isr_unhandled,	/* --------- */
70b77ee1fbSMaggie Zhang 	bfa_isr_unhandled,	/* --------- */
71b77ee1fbSMaggie Zhang 	bfa_isr_unhandled,	/* --------- */
72b77ee1fbSMaggie Zhang 	bfa_isr_unhandled,	/* --------- */
73b77ee1fbSMaggie Zhang 	bfa_isr_unhandled,	/* --------- */
74b77ee1fbSMaggie Zhang 	bfa_isr_unhandled,	/* --------- */
75b77ee1fbSMaggie Zhang };
76b77ee1fbSMaggie Zhang /*
77b77ee1fbSMaggie Zhang  * Message handlers for mailbox command classes
78b77ee1fbSMaggie Zhang  */
79b77ee1fbSMaggie Zhang static bfa_ioc_mbox_mcfunc_t  bfa_mbox_isrs[BFI_MC_MAX] = {
80b77ee1fbSMaggie Zhang 	NULL,
81b77ee1fbSMaggie Zhang 	NULL,		/* BFI_MC_IOC   */
82b77ee1fbSMaggie Zhang 	NULL,		/* BFI_MC_DIAG  */
83b77ee1fbSMaggie Zhang 	NULL,		/* BFI_MC_FLASH */
84b77ee1fbSMaggie Zhang 	NULL,		/* BFI_MC_CEE   */
85b77ee1fbSMaggie Zhang 	NULL,		/* BFI_MC_PORT  */
86b77ee1fbSMaggie Zhang 	bfa_iocfc_isr,	/* BFI_MC_IOCFC */
87b77ee1fbSMaggie Zhang 	NULL,
88b77ee1fbSMaggie Zhang };
89b77ee1fbSMaggie Zhang 
90b77ee1fbSMaggie Zhang 
91b77ee1fbSMaggie Zhang 
92b77ee1fbSMaggie Zhang static void
934507025dSKrishna Gudipati bfa_com_port_attach(struct bfa_s *bfa)
94b77ee1fbSMaggie Zhang {
95b77ee1fbSMaggie Zhang 	struct bfa_port_s	*port = &bfa->modules.port;
964507025dSKrishna Gudipati 	struct bfa_mem_dma_s	*port_dma = BFA_MEM_PORT_DMA(bfa);
97b77ee1fbSMaggie Zhang 
98b77ee1fbSMaggie Zhang 	bfa_port_attach(port, &bfa->ioc, bfa, bfa->trcmod);
994507025dSKrishna Gudipati 	bfa_port_mem_claim(port, port_dma->kva_curp, port_dma->dma_curp);
100b77ee1fbSMaggie Zhang }
101b77ee1fbSMaggie Zhang 
102b77ee1fbSMaggie Zhang /*
1031a4d8e1bSKrishna Gudipati  * ablk module attach
1041a4d8e1bSKrishna Gudipati  */
1051a4d8e1bSKrishna Gudipati static void
1064507025dSKrishna Gudipati bfa_com_ablk_attach(struct bfa_s *bfa)
1071a4d8e1bSKrishna Gudipati {
1081a4d8e1bSKrishna Gudipati 	struct bfa_ablk_s	*ablk = &bfa->modules.ablk;
1094507025dSKrishna Gudipati 	struct bfa_mem_dma_s	*ablk_dma = BFA_MEM_ABLK_DMA(bfa);
1101a4d8e1bSKrishna Gudipati 
1111a4d8e1bSKrishna Gudipati 	bfa_ablk_attach(ablk, &bfa->ioc);
1124507025dSKrishna Gudipati 	bfa_ablk_memclaim(ablk, ablk_dma->kva_curp, ablk_dma->dma_curp);
1131a4d8e1bSKrishna Gudipati }
1141a4d8e1bSKrishna Gudipati 
115148d6103SKrishna Gudipati static void
116148d6103SKrishna Gudipati bfa_com_cee_attach(struct bfa_s *bfa)
117148d6103SKrishna Gudipati {
118148d6103SKrishna Gudipati 	struct bfa_cee_s	*cee = &bfa->modules.cee;
119148d6103SKrishna Gudipati 	struct bfa_mem_dma_s	*cee_dma = BFA_MEM_CEE_DMA(bfa);
120148d6103SKrishna Gudipati 
121148d6103SKrishna Gudipati 	cee->trcmod = bfa->trcmod;
122148d6103SKrishna Gudipati 	bfa_cee_attach(cee, &bfa->ioc, bfa);
123148d6103SKrishna Gudipati 	bfa_cee_mem_claim(cee, cee_dma->kva_curp, cee_dma->dma_curp);
124148d6103SKrishna Gudipati }
125148d6103SKrishna Gudipati 
12651e569aaSKrishna Gudipati static void
12751e569aaSKrishna Gudipati bfa_com_sfp_attach(struct bfa_s *bfa)
12851e569aaSKrishna Gudipati {
12951e569aaSKrishna Gudipati 	struct bfa_sfp_s	*sfp = BFA_SFP_MOD(bfa);
13051e569aaSKrishna Gudipati 	struct bfa_mem_dma_s	*sfp_dma = BFA_MEM_SFP_DMA(bfa);
13151e569aaSKrishna Gudipati 
13251e569aaSKrishna Gudipati 	bfa_sfp_attach(sfp, &bfa->ioc, bfa, bfa->trcmod);
13351e569aaSKrishna Gudipati 	bfa_sfp_memclaim(sfp, sfp_dma->kva_curp, sfp_dma->dma_curp);
13451e569aaSKrishna Gudipati }
13551e569aaSKrishna Gudipati 
1365a54b1d5SKrishna Gudipati static void
1375a54b1d5SKrishna Gudipati bfa_com_flash_attach(struct bfa_s *bfa, bfa_boolean_t mincfg)
1385a54b1d5SKrishna Gudipati {
1395a54b1d5SKrishna Gudipati 	struct bfa_flash_s	*flash = BFA_FLASH(bfa);
1405a54b1d5SKrishna Gudipati 	struct bfa_mem_dma_s	*flash_dma = BFA_MEM_FLASH_DMA(bfa);
1415a54b1d5SKrishna Gudipati 
1425a54b1d5SKrishna Gudipati 	bfa_flash_attach(flash, &bfa->ioc, bfa, bfa->trcmod, mincfg);
1435a54b1d5SKrishna Gudipati 	bfa_flash_memclaim(flash, flash_dma->kva_curp,
1445a54b1d5SKrishna Gudipati 			   flash_dma->dma_curp, mincfg);
1455a54b1d5SKrishna Gudipati }
1465a54b1d5SKrishna Gudipati 
1473d7fc66dSKrishna Gudipati static void
1483d7fc66dSKrishna Gudipati bfa_com_diag_attach(struct bfa_s *bfa)
1493d7fc66dSKrishna Gudipati {
1503d7fc66dSKrishna Gudipati 	struct bfa_diag_s	*diag = BFA_DIAG_MOD(bfa);
1513d7fc66dSKrishna Gudipati 	struct bfa_mem_dma_s	*diag_dma = BFA_MEM_DIAG_DMA(bfa);
1523d7fc66dSKrishna Gudipati 
1533d7fc66dSKrishna Gudipati 	bfa_diag_attach(diag, &bfa->ioc, bfa, bfa_fcport_beacon, bfa->trcmod);
1543d7fc66dSKrishna Gudipati 	bfa_diag_memclaim(diag, diag_dma->kva_curp, diag_dma->dma_curp);
1553d7fc66dSKrishna Gudipati }
1563d7fc66dSKrishna Gudipati 
1573350d98dSKrishna Gudipati static void
1583350d98dSKrishna Gudipati bfa_com_phy_attach(struct bfa_s *bfa, bfa_boolean_t mincfg)
1593350d98dSKrishna Gudipati {
1603350d98dSKrishna Gudipati 	struct bfa_phy_s	*phy = BFA_PHY(bfa);
1613350d98dSKrishna Gudipati 	struct bfa_mem_dma_s	*phy_dma = BFA_MEM_PHY_DMA(bfa);
1623350d98dSKrishna Gudipati 
1633350d98dSKrishna Gudipati 	bfa_phy_attach(phy, &bfa->ioc, bfa, bfa->trcmod, mincfg);
1643350d98dSKrishna Gudipati 	bfa_phy_memclaim(phy, phy_dma->kva_curp, phy_dma->dma_curp, mincfg);
1653350d98dSKrishna Gudipati }
1663350d98dSKrishna Gudipati 
1671a4d8e1bSKrishna Gudipati /*
168a36c61f9SKrishna Gudipati  * BFA IOC FC related definitions
169a36c61f9SKrishna Gudipati  */
170a36c61f9SKrishna Gudipati 
1715fbe25c7SJing Huang /*
172a36c61f9SKrishna Gudipati  * IOC local definitions
173a36c61f9SKrishna Gudipati  */
174a36c61f9SKrishna Gudipati #define BFA_IOCFC_TOV		5000	/* msecs */
175a36c61f9SKrishna Gudipati 
176a36c61f9SKrishna Gudipati enum {
177a36c61f9SKrishna Gudipati 	BFA_IOCFC_ACT_NONE	= 0,
178a36c61f9SKrishna Gudipati 	BFA_IOCFC_ACT_INIT	= 1,
179a36c61f9SKrishna Gudipati 	BFA_IOCFC_ACT_STOP	= 2,
180a36c61f9SKrishna Gudipati 	BFA_IOCFC_ACT_DISABLE	= 3,
18160138066SKrishna Gudipati 	BFA_IOCFC_ACT_ENABLE	= 4,
182a36c61f9SKrishna Gudipati };
1837725ccfdSJing Huang 
1847725ccfdSJing Huang #define DEF_CFG_NUM_FABRICS		1
1857725ccfdSJing Huang #define DEF_CFG_NUM_LPORTS		256
1867725ccfdSJing Huang #define DEF_CFG_NUM_CQS			4
1877725ccfdSJing Huang #define DEF_CFG_NUM_IOIM_REQS		(BFA_IOIM_MAX)
1887725ccfdSJing Huang #define DEF_CFG_NUM_TSKIM_REQS		128
1897725ccfdSJing Huang #define DEF_CFG_NUM_FCXP_REQS		64
1907725ccfdSJing Huang #define DEF_CFG_NUM_UF_BUFS		64
1917725ccfdSJing Huang #define DEF_CFG_NUM_RPORTS		1024
1927725ccfdSJing Huang #define DEF_CFG_NUM_ITNIMS		(DEF_CFG_NUM_RPORTS)
1937725ccfdSJing Huang #define DEF_CFG_NUM_TINS		256
1947725ccfdSJing Huang 
1957725ccfdSJing Huang #define DEF_CFG_NUM_SGPGS		2048
1967725ccfdSJing Huang #define DEF_CFG_NUM_REQQ_ELEMS		256
1977725ccfdSJing Huang #define DEF_CFG_NUM_RSPQ_ELEMS		64
1987725ccfdSJing Huang #define DEF_CFG_NUM_SBOOT_TGTS		16
1997725ccfdSJing Huang #define DEF_CFG_NUM_SBOOT_LUNS		16
2007725ccfdSJing Huang 
2015fbe25c7SJing Huang /*
202a36c61f9SKrishna Gudipati  * forward declaration for IOC FC functions
203a36c61f9SKrishna Gudipati  */
204a36c61f9SKrishna Gudipati static void bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status);
205a36c61f9SKrishna Gudipati static void bfa_iocfc_disable_cbfn(void *bfa_arg);
206a36c61f9SKrishna Gudipati static void bfa_iocfc_hbfail_cbfn(void *bfa_arg);
207a36c61f9SKrishna Gudipati static void bfa_iocfc_reset_cbfn(void *bfa_arg);
208a36c61f9SKrishna Gudipati static struct bfa_ioc_cbfn_s bfa_iocfc_cbfn;
209a36c61f9SKrishna Gudipati 
2105fbe25c7SJing Huang /*
211a36c61f9SKrishna Gudipati  * BFA Interrupt handling functions
212a36c61f9SKrishna Gudipati  */
213a36c61f9SKrishna Gudipati static void
214a36c61f9SKrishna Gudipati bfa_reqq_resume(struct bfa_s *bfa, int qid)
215a36c61f9SKrishna Gudipati {
216a36c61f9SKrishna Gudipati 	struct list_head *waitq, *qe, *qen;
217a36c61f9SKrishna Gudipati 	struct bfa_reqq_wait_s *wqe;
218a36c61f9SKrishna Gudipati 
219a36c61f9SKrishna Gudipati 	waitq = bfa_reqq(bfa, qid);
220a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, waitq) {
2215fbe25c7SJing Huang 		/*
222a36c61f9SKrishna Gudipati 		 * Callback only as long as there is room in request queue
223a36c61f9SKrishna Gudipati 		 */
224a36c61f9SKrishna Gudipati 		if (bfa_reqq_full(bfa, qid))
225a36c61f9SKrishna Gudipati 			break;
226a36c61f9SKrishna Gudipati 
227a36c61f9SKrishna Gudipati 		list_del(qe);
228a36c61f9SKrishna Gudipati 		wqe = (struct bfa_reqq_wait_s *) qe;
229a36c61f9SKrishna Gudipati 		wqe->qresume(wqe->cbarg);
230a36c61f9SKrishna Gudipati 	}
231a36c61f9SKrishna Gudipati }
232a36c61f9SKrishna Gudipati 
23311189208SKrishna Gudipati static inline void
23411189208SKrishna Gudipati bfa_isr_rspq(struct bfa_s *bfa, int qid)
23511189208SKrishna Gudipati {
23611189208SKrishna Gudipati 	struct bfi_msg_s *m;
23711189208SKrishna Gudipati 	u32	pi, ci;
23811189208SKrishna Gudipati 	struct list_head *waitq;
23911189208SKrishna Gudipati 
24011189208SKrishna Gudipati 	ci = bfa_rspq_ci(bfa, qid);
24111189208SKrishna Gudipati 	pi = bfa_rspq_pi(bfa, qid);
24211189208SKrishna Gudipati 
24311189208SKrishna Gudipati 	while (ci != pi) {
24411189208SKrishna Gudipati 		m = bfa_rspq_elem(bfa, qid, ci);
24511189208SKrishna Gudipati 		WARN_ON(m->mhdr.msg_class >= BFI_MC_MAX);
24611189208SKrishna Gudipati 
24711189208SKrishna Gudipati 		bfa_isrs[m->mhdr.msg_class] (bfa, m);
24811189208SKrishna Gudipati 		CQ_INCR(ci, bfa->iocfc.cfg.drvcfg.num_rspq_elems);
24911189208SKrishna Gudipati 	}
25011189208SKrishna Gudipati 
25111189208SKrishna Gudipati 	/*
252*ca6e0ea7SKrishna Gudipati 	 * acknowledge RME completions and update CI
25311189208SKrishna Gudipati 	 */
254*ca6e0ea7SKrishna Gudipati 	bfa_isr_rspq_ack(bfa, qid, ci);
25511189208SKrishna Gudipati 
25611189208SKrishna Gudipati 	/*
25711189208SKrishna Gudipati 	 * Resume any pending requests in the corresponding reqq.
25811189208SKrishna Gudipati 	 */
25911189208SKrishna Gudipati 	waitq = bfa_reqq(bfa, qid);
26011189208SKrishna Gudipati 	if (!list_empty(waitq))
26111189208SKrishna Gudipati 		bfa_reqq_resume(bfa, qid);
26211189208SKrishna Gudipati }
26311189208SKrishna Gudipati 
26411189208SKrishna Gudipati static inline void
26511189208SKrishna Gudipati bfa_isr_reqq(struct bfa_s *bfa, int qid)
26611189208SKrishna Gudipati {
26711189208SKrishna Gudipati 	struct list_head *waitq;
26811189208SKrishna Gudipati 
2693fd45980SKrishna Gudipati 	bfa_isr_reqq_ack(bfa, qid);
27011189208SKrishna Gudipati 
27111189208SKrishna Gudipati 	/*
27211189208SKrishna Gudipati 	 * Resume any pending requests in the corresponding reqq.
27311189208SKrishna Gudipati 	 */
27411189208SKrishna Gudipati 	waitq = bfa_reqq(bfa, qid);
27511189208SKrishna Gudipati 	if (!list_empty(waitq))
27611189208SKrishna Gudipati 		bfa_reqq_resume(bfa, qid);
27711189208SKrishna Gudipati }
27811189208SKrishna Gudipati 
279a36c61f9SKrishna Gudipati void
280a36c61f9SKrishna Gudipati bfa_msix_all(struct bfa_s *bfa, int vec)
281a36c61f9SKrishna Gudipati {
28210a07379SKrishna Gudipati 	u32	intr, qintr;
28310a07379SKrishna Gudipati 	int	queue;
28410a07379SKrishna Gudipati 
28510a07379SKrishna Gudipati 	intr = readl(bfa->iocfc.bfa_regs.intr_status);
28610a07379SKrishna Gudipati 	if (!intr)
28710a07379SKrishna Gudipati 		return;
28810a07379SKrishna Gudipati 
28910a07379SKrishna Gudipati 	/*
29010a07379SKrishna Gudipati 	 * RME completion queue interrupt
29110a07379SKrishna Gudipati 	 */
29210a07379SKrishna Gudipati 	qintr = intr & __HFN_INT_RME_MASK;
29310a07379SKrishna Gudipati 	if (qintr && bfa->queue_process) {
29410a07379SKrishna Gudipati 		for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++)
29510a07379SKrishna Gudipati 			bfa_isr_rspq(bfa, queue);
29610a07379SKrishna Gudipati 	}
29710a07379SKrishna Gudipati 
29810a07379SKrishna Gudipati 	intr &= ~qintr;
29910a07379SKrishna Gudipati 	if (!intr)
30010a07379SKrishna Gudipati 		return;
30110a07379SKrishna Gudipati 
30210a07379SKrishna Gudipati 	/*
30310a07379SKrishna Gudipati 	 * CPE completion queue interrupt
30410a07379SKrishna Gudipati 	 */
30510a07379SKrishna Gudipati 	qintr = intr & __HFN_INT_CPE_MASK;
30610a07379SKrishna Gudipati 	if (qintr && bfa->queue_process) {
30710a07379SKrishna Gudipati 		for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++)
30810a07379SKrishna Gudipati 			bfa_isr_reqq(bfa, queue);
30910a07379SKrishna Gudipati 	}
31010a07379SKrishna Gudipati 	intr &= ~qintr;
31110a07379SKrishna Gudipati 	if (!intr)
31210a07379SKrishna Gudipati 		return;
31310a07379SKrishna Gudipati 
31410a07379SKrishna Gudipati 	bfa_msix_lpu_err(bfa, intr);
315a36c61f9SKrishna Gudipati }
316a36c61f9SKrishna Gudipati 
317a36c61f9SKrishna Gudipati bfa_boolean_t
318a36c61f9SKrishna Gudipati bfa_intx(struct bfa_s *bfa)
319a36c61f9SKrishna Gudipati {
320a36c61f9SKrishna Gudipati 	u32 intr, qintr;
321a36c61f9SKrishna Gudipati 	int queue;
322a36c61f9SKrishna Gudipati 
32353440260SJing Huang 	intr = readl(bfa->iocfc.bfa_regs.intr_status);
324a36c61f9SKrishna Gudipati 
3253fd45980SKrishna Gudipati 	qintr = intr & (__HFN_INT_RME_MASK | __HFN_INT_CPE_MASK);
3263fd45980SKrishna Gudipati 	if (qintr)
3273fd45980SKrishna Gudipati 		writel(qintr, bfa->iocfc.bfa_regs.intr_status);
3283fd45980SKrishna Gudipati 
3295fbe25c7SJing Huang 	/*
330*ca6e0ea7SKrishna Gudipati 	 * Unconditional RME completion queue interrupt
331a36c61f9SKrishna Gudipati 	 */
332*ca6e0ea7SKrishna Gudipati 	if (bfa->queue_process) {
3333fd45980SKrishna Gudipati 		for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++)
3343fd45980SKrishna Gudipati 			bfa_isr_rspq(bfa, queue);
335a36c61f9SKrishna Gudipati 	}
3363fd45980SKrishna Gudipati 
337a36c61f9SKrishna Gudipati 	if (!intr)
338a36c61f9SKrishna Gudipati 		return BFA_TRUE;
339a36c61f9SKrishna Gudipati 
3405fbe25c7SJing Huang 	/*
341a36c61f9SKrishna Gudipati 	 * CPE completion queue interrupt
342a36c61f9SKrishna Gudipati 	 */
343a36c61f9SKrishna Gudipati 	qintr = intr & __HFN_INT_CPE_MASK;
3443fd45980SKrishna Gudipati 	if (qintr && bfa->queue_process) {
3453fd45980SKrishna Gudipati 		for (queue = 0; queue < BFI_IOC_MAX_CQS; queue++)
3463fd45980SKrishna Gudipati 			bfa_isr_reqq(bfa, queue);
347a36c61f9SKrishna Gudipati 	}
348a36c61f9SKrishna Gudipati 	intr &= ~qintr;
349a36c61f9SKrishna Gudipati 	if (!intr)
350a36c61f9SKrishna Gudipati 		return BFA_TRUE;
351a36c61f9SKrishna Gudipati 
352a36c61f9SKrishna Gudipati 	bfa_msix_lpu_err(bfa, intr);
353a36c61f9SKrishna Gudipati 
354a36c61f9SKrishna Gudipati 	return BFA_TRUE;
355a36c61f9SKrishna Gudipati }
356a36c61f9SKrishna Gudipati 
357a36c61f9SKrishna Gudipati void
358a36c61f9SKrishna Gudipati bfa_isr_enable(struct bfa_s *bfa)
359a36c61f9SKrishna Gudipati {
36011189208SKrishna Gudipati 	u32 umsk;
361a36c61f9SKrishna Gudipati 	int pci_func = bfa_ioc_pcifn(&bfa->ioc);
362a36c61f9SKrishna Gudipati 
363a36c61f9SKrishna Gudipati 	bfa_trc(bfa, pci_func);
364a36c61f9SKrishna Gudipati 
365775c7742SKrishna Gudipati 	bfa_msix_ctrl_install(bfa);
366a36c61f9SKrishna Gudipati 
36711189208SKrishna Gudipati 	if (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id)) {
36811189208SKrishna Gudipati 		umsk = __HFN_INT_ERR_MASK_CT2;
36911189208SKrishna Gudipati 		umsk |= pci_func == 0 ?
37011189208SKrishna Gudipati 			__HFN_INT_FN0_MASK_CT2 : __HFN_INT_FN1_MASK_CT2;
37111189208SKrishna Gudipati 	} else {
37211189208SKrishna Gudipati 		umsk = __HFN_INT_ERR_MASK;
37311189208SKrishna Gudipati 		umsk |= pci_func == 0 ? __HFN_INT_FN0_MASK : __HFN_INT_FN1_MASK;
37411189208SKrishna Gudipati 	}
375a36c61f9SKrishna Gudipati 
37611189208SKrishna Gudipati 	writel(umsk, bfa->iocfc.bfa_regs.intr_status);
37711189208SKrishna Gudipati 	writel(~umsk, bfa->iocfc.bfa_regs.intr_mask);
37811189208SKrishna Gudipati 	bfa->iocfc.intr_mask = ~umsk;
379a36c61f9SKrishna Gudipati 	bfa_isr_mode_set(bfa, bfa->msix.nvecs != 0);
380a36c61f9SKrishna Gudipati }
381a36c61f9SKrishna Gudipati 
382a36c61f9SKrishna Gudipati void
383a36c61f9SKrishna Gudipati bfa_isr_disable(struct bfa_s *bfa)
384a36c61f9SKrishna Gudipati {
385a36c61f9SKrishna Gudipati 	bfa_isr_mode_set(bfa, BFA_FALSE);
38653440260SJing Huang 	writel(-1L, bfa->iocfc.bfa_regs.intr_mask);
387a36c61f9SKrishna Gudipati 	bfa_msix_uninstall(bfa);
388a36c61f9SKrishna Gudipati }
389a36c61f9SKrishna Gudipati 
390a36c61f9SKrishna Gudipati void
39111189208SKrishna Gudipati bfa_msix_reqq(struct bfa_s *bfa, int vec)
392a36c61f9SKrishna Gudipati {
39311189208SKrishna Gudipati 	bfa_isr_reqq(bfa, vec - bfa->iocfc.hwif.cpe_vec_q0);
394a36c61f9SKrishna Gudipati }
395a36c61f9SKrishna Gudipati 
396a36c61f9SKrishna Gudipati void
397a36c61f9SKrishna Gudipati bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m)
398a36c61f9SKrishna Gudipati {
399a36c61f9SKrishna Gudipati 	bfa_trc(bfa, m->mhdr.msg_class);
400a36c61f9SKrishna Gudipati 	bfa_trc(bfa, m->mhdr.msg_id);
401a36c61f9SKrishna Gudipati 	bfa_trc(bfa, m->mhdr.mtag.i2htok);
402d4b671c5SJing Huang 	WARN_ON(1);
403a36c61f9SKrishna Gudipati 	bfa_trc_stop(bfa->trcmod);
404a36c61f9SKrishna Gudipati }
405a36c61f9SKrishna Gudipati 
406a36c61f9SKrishna Gudipati void
40711189208SKrishna Gudipati bfa_msix_rspq(struct bfa_s *bfa, int vec)
408a36c61f9SKrishna Gudipati {
40911189208SKrishna Gudipati 	bfa_isr_rspq(bfa, vec - bfa->iocfc.hwif.rme_vec_q0);
410a36c61f9SKrishna Gudipati }
411a36c61f9SKrishna Gudipati 
412a36c61f9SKrishna Gudipati void
413a36c61f9SKrishna Gudipati bfa_msix_lpu_err(struct bfa_s *bfa, int vec)
414a36c61f9SKrishna Gudipati {
415a36c61f9SKrishna Gudipati 	u32 intr, curr_value;
41611189208SKrishna Gudipati 	bfa_boolean_t lpu_isr, halt_isr, pss_isr;
417a36c61f9SKrishna Gudipati 
41853440260SJing Huang 	intr = readl(bfa->iocfc.bfa_regs.intr_status);
419a36c61f9SKrishna Gudipati 
42011189208SKrishna Gudipati 	if (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id)) {
42111189208SKrishna Gudipati 		halt_isr = intr & __HFN_INT_CPQ_HALT_CT2;
42211189208SKrishna Gudipati 		pss_isr  = intr & __HFN_INT_ERR_PSS_CT2;
42311189208SKrishna Gudipati 		lpu_isr  = intr & (__HFN_INT_MBOX_LPU0_CT2 |
42411189208SKrishna Gudipati 				   __HFN_INT_MBOX_LPU1_CT2);
42511189208SKrishna Gudipati 		intr    &= __HFN_INT_ERR_MASK_CT2;
42611189208SKrishna Gudipati 	} else {
427*ca6e0ea7SKrishna Gudipati 		halt_isr = bfa_asic_id_ct(bfa->ioc.pcidev.device_id) ?
428*ca6e0ea7SKrishna Gudipati 					  (intr & __HFN_INT_LL_HALT) : 0;
42911189208SKrishna Gudipati 		pss_isr  = intr & __HFN_INT_ERR_PSS;
43011189208SKrishna Gudipati 		lpu_isr  = intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1);
43111189208SKrishna Gudipati 		intr    &= __HFN_INT_ERR_MASK;
43211189208SKrishna Gudipati 	}
43311189208SKrishna Gudipati 
43411189208SKrishna Gudipati 	if (lpu_isr)
435f7f73812SMaggie Zhang 		bfa_ioc_mbox_isr(&bfa->ioc);
436a36c61f9SKrishna Gudipati 
437a36c61f9SKrishna Gudipati 	if (intr) {
43811189208SKrishna Gudipati 		if (halt_isr) {
4395fbe25c7SJing Huang 			/*
440a36c61f9SKrishna Gudipati 			 * If LL_HALT bit is set then FW Init Halt LL Port
441a36c61f9SKrishna Gudipati 			 * Register needs to be cleared as well so Interrupt
442a36c61f9SKrishna Gudipati 			 * Status Register will be cleared.
443a36c61f9SKrishna Gudipati 			 */
44453440260SJing Huang 			curr_value = readl(bfa->ioc.ioc_regs.ll_halt);
445a36c61f9SKrishna Gudipati 			curr_value &= ~__FW_INIT_HALT_P;
44653440260SJing Huang 			writel(curr_value, bfa->ioc.ioc_regs.ll_halt);
447a36c61f9SKrishna Gudipati 		}
448a36c61f9SKrishna Gudipati 
44911189208SKrishna Gudipati 		if (pss_isr) {
4505fbe25c7SJing Huang 			/*
451a36c61f9SKrishna Gudipati 			 * ERR_PSS bit needs to be cleared as well in case
452a36c61f9SKrishna Gudipati 			 * interrups are shared so driver's interrupt handler is
453a36c61f9SKrishna Gudipati 			 * still called even though it is already masked out.
454a36c61f9SKrishna Gudipati 			 */
45553440260SJing Huang 			curr_value = readl(
456a36c61f9SKrishna Gudipati 					bfa->ioc.ioc_regs.pss_err_status_reg);
45753440260SJing Huang 			writel(curr_value,
45853440260SJing Huang 				bfa->ioc.ioc_regs.pss_err_status_reg);
459a36c61f9SKrishna Gudipati 		}
460a36c61f9SKrishna Gudipati 
46153440260SJing Huang 		writel(intr, bfa->iocfc.bfa_regs.intr_status);
462f7f73812SMaggie Zhang 		bfa_ioc_error_isr(&bfa->ioc);
463a36c61f9SKrishna Gudipati 	}
464a36c61f9SKrishna Gudipati }
465a36c61f9SKrishna Gudipati 
4665fbe25c7SJing Huang /*
467a36c61f9SKrishna Gudipati  * BFA IOC FC related functions
468a36c61f9SKrishna Gudipati  */
469a36c61f9SKrishna Gudipati 
4705fbe25c7SJing Huang /*
471df0f1933SMaggie Zhang  *  BFA IOC private functions
472a36c61f9SKrishna Gudipati  */
473a36c61f9SKrishna Gudipati 
4745fbe25c7SJing Huang /*
475a36c61f9SKrishna Gudipati  * Use the Mailbox interface to send BFI_IOCFC_H2I_CFG_REQ
476a36c61f9SKrishna Gudipati  */
477a36c61f9SKrishna Gudipati static void
478a36c61f9SKrishna Gudipati bfa_iocfc_send_cfg(void *bfa_arg)
479a36c61f9SKrishna Gudipati {
480a36c61f9SKrishna Gudipati 	struct bfa_s *bfa = bfa_arg;
481a36c61f9SKrishna Gudipati 	struct bfa_iocfc_s *iocfc = &bfa->iocfc;
482a36c61f9SKrishna Gudipati 	struct bfi_iocfc_cfg_req_s cfg_req;
483a36c61f9SKrishna Gudipati 	struct bfi_iocfc_cfg_s *cfg_info = iocfc->cfginfo;
484a36c61f9SKrishna Gudipati 	struct bfa_iocfc_cfg_s	*cfg = &iocfc->cfg;
485a36c61f9SKrishna Gudipati 	int		i;
486a36c61f9SKrishna Gudipati 
487d4b671c5SJing Huang 	WARN_ON(cfg->fwcfg.num_cqs > BFI_IOC_MAX_CQS);
488a36c61f9SKrishna Gudipati 	bfa_trc(bfa, cfg->fwcfg.num_cqs);
489a36c61f9SKrishna Gudipati 
490a36c61f9SKrishna Gudipati 	bfa_iocfc_reset_queues(bfa);
491a36c61f9SKrishna Gudipati 
4925fbe25c7SJing Huang 	/*
493a36c61f9SKrishna Gudipati 	 * initialize IOC configuration info
494a36c61f9SKrishna Gudipati 	 */
49510a07379SKrishna Gudipati 	cfg_info->single_msix_vec = 0;
49610a07379SKrishna Gudipati 	if (bfa->msix.nvecs == 1)
49710a07379SKrishna Gudipati 		cfg_info->single_msix_vec = 1;
498a36c61f9SKrishna Gudipati 	cfg_info->endian_sig = BFI_IOC_ENDIAN_SIG;
499a36c61f9SKrishna Gudipati 	cfg_info->num_cqs = cfg->fwcfg.num_cqs;
500e2187d7fSKrishna Gudipati 	cfg_info->num_ioim_reqs = cpu_to_be16(cfg->fwcfg.num_ioim_reqs);
501e2187d7fSKrishna Gudipati 	cfg_info->num_fwtio_reqs = cpu_to_be16(cfg->fwcfg.num_fwtio_reqs);
502a36c61f9SKrishna Gudipati 
503a36c61f9SKrishna Gudipati 	bfa_dma_be_addr_set(cfg_info->cfgrsp_addr, iocfc->cfgrsp_dma.pa);
5045fbe25c7SJing Huang 	/*
505a36c61f9SKrishna Gudipati 	 * dma map REQ and RSP circular queues and shadow pointers
506a36c61f9SKrishna Gudipati 	 */
507a36c61f9SKrishna Gudipati 	for (i = 0; i < cfg->fwcfg.num_cqs; i++) {
508a36c61f9SKrishna Gudipati 		bfa_dma_be_addr_set(cfg_info->req_cq_ba[i],
509a36c61f9SKrishna Gudipati 				    iocfc->req_cq_ba[i].pa);
510a36c61f9SKrishna Gudipati 		bfa_dma_be_addr_set(cfg_info->req_shadow_ci[i],
511a36c61f9SKrishna Gudipati 				    iocfc->req_cq_shadow_ci[i].pa);
512a36c61f9SKrishna Gudipati 		cfg_info->req_cq_elems[i] =
513ba816ea8SJing Huang 			cpu_to_be16(cfg->drvcfg.num_reqq_elems);
514a36c61f9SKrishna Gudipati 
515a36c61f9SKrishna Gudipati 		bfa_dma_be_addr_set(cfg_info->rsp_cq_ba[i],
516a36c61f9SKrishna Gudipati 				    iocfc->rsp_cq_ba[i].pa);
517a36c61f9SKrishna Gudipati 		bfa_dma_be_addr_set(cfg_info->rsp_shadow_pi[i],
518a36c61f9SKrishna Gudipati 				    iocfc->rsp_cq_shadow_pi[i].pa);
519a36c61f9SKrishna Gudipati 		cfg_info->rsp_cq_elems[i] =
520ba816ea8SJing Huang 			cpu_to_be16(cfg->drvcfg.num_rspq_elems);
521a36c61f9SKrishna Gudipati 	}
522a36c61f9SKrishna Gudipati 
5235fbe25c7SJing Huang 	/*
524a36c61f9SKrishna Gudipati 	 * Enable interrupt coalescing if it is driver init path
525a36c61f9SKrishna Gudipati 	 * and not ioc disable/enable path.
526a36c61f9SKrishna Gudipati 	 */
527a36c61f9SKrishna Gudipati 	if (!iocfc->cfgdone)
528a36c61f9SKrishna Gudipati 		cfg_info->intr_attr.coalesce = BFA_TRUE;
529a36c61f9SKrishna Gudipati 
530a36c61f9SKrishna Gudipati 	iocfc->cfgdone = BFA_FALSE;
531a36c61f9SKrishna Gudipati 
5325fbe25c7SJing Huang 	/*
533a36c61f9SKrishna Gudipati 	 * dma map IOC configuration itself
534a36c61f9SKrishna Gudipati 	 */
535a36c61f9SKrishna Gudipati 	bfi_h2i_set(cfg_req.mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_CFG_REQ,
5363fd45980SKrishna Gudipati 		    bfa_fn_lpu(bfa));
537a36c61f9SKrishna Gudipati 	bfa_dma_be_addr_set(cfg_req.ioc_cfg_dma_addr, iocfc->cfg_info.pa);
538a36c61f9SKrishna Gudipati 
539a36c61f9SKrishna Gudipati 	bfa_ioc_mbox_send(&bfa->ioc, &cfg_req,
540a36c61f9SKrishna Gudipati 			  sizeof(struct bfi_iocfc_cfg_req_s));
541a36c61f9SKrishna Gudipati }
542a36c61f9SKrishna Gudipati 
543a36c61f9SKrishna Gudipati static void
544a36c61f9SKrishna Gudipati bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
545a36c61f9SKrishna Gudipati 		   struct bfa_pcidev_s *pcidev)
546a36c61f9SKrishna Gudipati {
547a36c61f9SKrishna Gudipati 	struct bfa_iocfc_s	*iocfc = &bfa->iocfc;
548a36c61f9SKrishna Gudipati 
549a36c61f9SKrishna Gudipati 	bfa->bfad = bfad;
550a36c61f9SKrishna Gudipati 	iocfc->bfa = bfa;
551a36c61f9SKrishna Gudipati 	iocfc->action = BFA_IOCFC_ACT_NONE;
552a36c61f9SKrishna Gudipati 
5536a18b167SJing Huang 	iocfc->cfg = *cfg;
554a36c61f9SKrishna Gudipati 
5555fbe25c7SJing Huang 	/*
556a36c61f9SKrishna Gudipati 	 * Initialize chip specific handlers.
557a36c61f9SKrishna Gudipati 	 */
55811189208SKrishna Gudipati 	if (bfa_asic_id_ctc(bfa_ioc_devid(&bfa->ioc))) {
559a36c61f9SKrishna Gudipati 		iocfc->hwif.hw_reginit = bfa_hwct_reginit;
560a36c61f9SKrishna Gudipati 		iocfc->hwif.hw_reqq_ack = bfa_hwct_reqq_ack;
561a36c61f9SKrishna Gudipati 		iocfc->hwif.hw_rspq_ack = bfa_hwct_rspq_ack;
562a36c61f9SKrishna Gudipati 		iocfc->hwif.hw_msix_init = bfa_hwct_msix_init;
563775c7742SKrishna Gudipati 		iocfc->hwif.hw_msix_ctrl_install = bfa_hwct_msix_ctrl_install;
564775c7742SKrishna Gudipati 		iocfc->hwif.hw_msix_queue_install = bfa_hwct_msix_queue_install;
565a36c61f9SKrishna Gudipati 		iocfc->hwif.hw_msix_uninstall = bfa_hwct_msix_uninstall;
566a36c61f9SKrishna Gudipati 		iocfc->hwif.hw_isr_mode_set = bfa_hwct_isr_mode_set;
567a36c61f9SKrishna Gudipati 		iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs;
568a36c61f9SKrishna Gudipati 		iocfc->hwif.hw_msix_get_rme_range = bfa_hwct_msix_get_rme_range;
56911189208SKrishna Gudipati 		iocfc->hwif.rme_vec_q0 = BFI_MSIX_RME_QMIN_CT;
57011189208SKrishna Gudipati 		iocfc->hwif.cpe_vec_q0 = BFI_MSIX_CPE_QMIN_CT;
571a36c61f9SKrishna Gudipati 	} else {
572a36c61f9SKrishna Gudipati 		iocfc->hwif.hw_reginit = bfa_hwcb_reginit;
5733fd45980SKrishna Gudipati 		iocfc->hwif.hw_reqq_ack = NULL;
574*ca6e0ea7SKrishna Gudipati 		iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack;
575a36c61f9SKrishna Gudipati 		iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init;
576775c7742SKrishna Gudipati 		iocfc->hwif.hw_msix_ctrl_install = bfa_hwcb_msix_ctrl_install;
577775c7742SKrishna Gudipati 		iocfc->hwif.hw_msix_queue_install = bfa_hwcb_msix_queue_install;
578a36c61f9SKrishna Gudipati 		iocfc->hwif.hw_msix_uninstall = bfa_hwcb_msix_uninstall;
579a36c61f9SKrishna Gudipati 		iocfc->hwif.hw_isr_mode_set = bfa_hwcb_isr_mode_set;
580a36c61f9SKrishna Gudipati 		iocfc->hwif.hw_msix_getvecs = bfa_hwcb_msix_getvecs;
581a36c61f9SKrishna Gudipati 		iocfc->hwif.hw_msix_get_rme_range = bfa_hwcb_msix_get_rme_range;
58211189208SKrishna Gudipati 		iocfc->hwif.rme_vec_q0 = BFI_MSIX_RME_QMIN_CB +
58311189208SKrishna Gudipati 			bfa_ioc_pcifn(&bfa->ioc) * BFI_IOC_MAX_CQS;
58411189208SKrishna Gudipati 		iocfc->hwif.cpe_vec_q0 = BFI_MSIX_CPE_QMIN_CB +
58511189208SKrishna Gudipati 			bfa_ioc_pcifn(&bfa->ioc) * BFI_IOC_MAX_CQS;
58611189208SKrishna Gudipati 	}
58711189208SKrishna Gudipati 
58811189208SKrishna Gudipati 	if (bfa_asic_id_ct2(bfa_ioc_devid(&bfa->ioc))) {
58911189208SKrishna Gudipati 		iocfc->hwif.hw_reginit = bfa_hwct2_reginit;
59011189208SKrishna Gudipati 		iocfc->hwif.hw_isr_mode_set = NULL;
591*ca6e0ea7SKrishna Gudipati 		iocfc->hwif.hw_rspq_ack = bfa_hwct2_rspq_ack;
592a36c61f9SKrishna Gudipati 	}
593a36c61f9SKrishna Gudipati 
594a36c61f9SKrishna Gudipati 	iocfc->hwif.hw_reginit(bfa);
595a36c61f9SKrishna Gudipati 	bfa->msix.nvecs = 0;
596a36c61f9SKrishna Gudipati }
597a36c61f9SKrishna Gudipati 
598a36c61f9SKrishna Gudipati static void
5994507025dSKrishna Gudipati bfa_iocfc_mem_claim(struct bfa_s *bfa, struct bfa_iocfc_cfg_s *cfg)
600a36c61f9SKrishna Gudipati {
6014507025dSKrishna Gudipati 	u8	*dm_kva = NULL;
6024507025dSKrishna Gudipati 	u64	dm_pa = 0;
6034507025dSKrishna Gudipati 	int	i, per_reqq_sz, per_rspq_sz, dbgsz;
604a36c61f9SKrishna Gudipati 	struct bfa_iocfc_s  *iocfc = &bfa->iocfc;
6054507025dSKrishna Gudipati 	struct bfa_mem_dma_s *ioc_dma = BFA_MEM_IOC_DMA(bfa);
6064507025dSKrishna Gudipati 	struct bfa_mem_dma_s *iocfc_dma = BFA_MEM_IOCFC_DMA(bfa);
6074507025dSKrishna Gudipati 	struct bfa_mem_dma_s *reqq_dma, *rspq_dma;
608a36c61f9SKrishna Gudipati 
6094507025dSKrishna Gudipati 	/* First allocate dma memory for IOC */
6104507025dSKrishna Gudipati 	bfa_ioc_mem_claim(&bfa->ioc, bfa_mem_dma_virt(ioc_dma),
6114507025dSKrishna Gudipati 			bfa_mem_dma_phys(ioc_dma));
612a36c61f9SKrishna Gudipati 
6134507025dSKrishna Gudipati 	/* Claim DMA-able memory for the request/response queues */
614a36c61f9SKrishna Gudipati 	per_reqq_sz = BFA_ROUNDUP((cfg->drvcfg.num_reqq_elems * BFI_LMSG_SZ),
615a36c61f9SKrishna Gudipati 				BFA_DMA_ALIGN_SZ);
616a36c61f9SKrishna Gudipati 	per_rspq_sz = BFA_ROUNDUP((cfg->drvcfg.num_rspq_elems * BFI_LMSG_SZ),
617a36c61f9SKrishna Gudipati 				BFA_DMA_ALIGN_SZ);
618a36c61f9SKrishna Gudipati 
619a36c61f9SKrishna Gudipati 	for (i = 0; i < cfg->fwcfg.num_cqs; i++) {
6204507025dSKrishna Gudipati 		reqq_dma = BFA_MEM_REQQ_DMA(bfa, i);
6214507025dSKrishna Gudipati 		iocfc->req_cq_ba[i].kva = bfa_mem_dma_virt(reqq_dma);
6224507025dSKrishna Gudipati 		iocfc->req_cq_ba[i].pa = bfa_mem_dma_phys(reqq_dma);
6234507025dSKrishna Gudipati 		memset(iocfc->req_cq_ba[i].kva, 0, per_reqq_sz);
624a36c61f9SKrishna Gudipati 
6254507025dSKrishna Gudipati 		rspq_dma = BFA_MEM_RSPQ_DMA(bfa, i);
6264507025dSKrishna Gudipati 		iocfc->rsp_cq_ba[i].kva = bfa_mem_dma_virt(rspq_dma);
6274507025dSKrishna Gudipati 		iocfc->rsp_cq_ba[i].pa = bfa_mem_dma_phys(rspq_dma);
6284507025dSKrishna Gudipati 		memset(iocfc->rsp_cq_ba[i].kva, 0, per_rspq_sz);
629a36c61f9SKrishna Gudipati 	}
630a36c61f9SKrishna Gudipati 
6314507025dSKrishna Gudipati 	/* Claim IOCFC dma memory - for shadow CI/PI */
6324507025dSKrishna Gudipati 	dm_kva = bfa_mem_dma_virt(iocfc_dma);
6334507025dSKrishna Gudipati 	dm_pa  = bfa_mem_dma_phys(iocfc_dma);
6344507025dSKrishna Gudipati 
635a36c61f9SKrishna Gudipati 	for (i = 0; i < cfg->fwcfg.num_cqs; i++) {
636a36c61f9SKrishna Gudipati 		iocfc->req_cq_shadow_ci[i].kva = dm_kva;
637a36c61f9SKrishna Gudipati 		iocfc->req_cq_shadow_ci[i].pa = dm_pa;
638a36c61f9SKrishna Gudipati 		dm_kva += BFA_CACHELINE_SZ;
639a36c61f9SKrishna Gudipati 		dm_pa += BFA_CACHELINE_SZ;
640a36c61f9SKrishna Gudipati 
641a36c61f9SKrishna Gudipati 		iocfc->rsp_cq_shadow_pi[i].kva = dm_kva;
642a36c61f9SKrishna Gudipati 		iocfc->rsp_cq_shadow_pi[i].pa = dm_pa;
643a36c61f9SKrishna Gudipati 		dm_kva += BFA_CACHELINE_SZ;
644a36c61f9SKrishna Gudipati 		dm_pa += BFA_CACHELINE_SZ;
645a36c61f9SKrishna Gudipati 	}
646a36c61f9SKrishna Gudipati 
6474507025dSKrishna Gudipati 	/* Claim IOCFC dma memory - for the config info page */
648a36c61f9SKrishna Gudipati 	bfa->iocfc.cfg_info.kva = dm_kva;
649a36c61f9SKrishna Gudipati 	bfa->iocfc.cfg_info.pa = dm_pa;
650a36c61f9SKrishna Gudipati 	bfa->iocfc.cfginfo = (struct bfi_iocfc_cfg_s *) dm_kva;
651a36c61f9SKrishna Gudipati 	dm_kva += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s), BFA_CACHELINE_SZ);
652a36c61f9SKrishna Gudipati 	dm_pa += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s), BFA_CACHELINE_SZ);
653a36c61f9SKrishna Gudipati 
6544507025dSKrishna Gudipati 	/* Claim IOCFC dma memory - for the config response */
655a36c61f9SKrishna Gudipati 	bfa->iocfc.cfgrsp_dma.kva = dm_kva;
656a36c61f9SKrishna Gudipati 	bfa->iocfc.cfgrsp_dma.pa = dm_pa;
657a36c61f9SKrishna Gudipati 	bfa->iocfc.cfgrsp = (struct bfi_iocfc_cfgrsp_s *) dm_kva;
6584507025dSKrishna Gudipati 	dm_kva += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s),
659a36c61f9SKrishna Gudipati 			BFA_CACHELINE_SZ);
660a36c61f9SKrishna Gudipati 	dm_pa += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s),
661a36c61f9SKrishna Gudipati 			BFA_CACHELINE_SZ);
662a36c61f9SKrishna Gudipati 
6634507025dSKrishna Gudipati 	/* Claim IOCFC kva memory */
664f7f73812SMaggie Zhang 	dbgsz = (bfa_auto_recover) ? BFA_DBG_FWTRC_LEN : 0;
665a36c61f9SKrishna Gudipati 	if (dbgsz > 0) {
6664507025dSKrishna Gudipati 		bfa_ioc_debug_memclaim(&bfa->ioc, bfa_mem_kva_curp(iocfc));
6674507025dSKrishna Gudipati 		bfa_mem_kva_curp(iocfc) += dbgsz;
668a36c61f9SKrishna Gudipati 	}
669a36c61f9SKrishna Gudipati }
670a36c61f9SKrishna Gudipati 
6715fbe25c7SJing Huang /*
672a36c61f9SKrishna Gudipati  * Start BFA submodules.
673a36c61f9SKrishna Gudipati  */
674a36c61f9SKrishna Gudipati static void
675a36c61f9SKrishna Gudipati bfa_iocfc_start_submod(struct bfa_s *bfa)
676a36c61f9SKrishna Gudipati {
677a36c61f9SKrishna Gudipati 	int		i;
678a36c61f9SKrishna Gudipati 
679775c7742SKrishna Gudipati 	bfa->queue_process = BFA_TRUE;
68011189208SKrishna Gudipati 	for (i = 0; i < BFI_IOC_MAX_CQS; i++)
681*ca6e0ea7SKrishna Gudipati 		bfa_isr_rspq_ack(bfa, i, bfa_rspq_ci(bfa, i));
682a36c61f9SKrishna Gudipati 
683a36c61f9SKrishna Gudipati 	for (i = 0; hal_mods[i]; i++)
684a36c61f9SKrishna Gudipati 		hal_mods[i]->start(bfa);
685a36c61f9SKrishna Gudipati }
686a36c61f9SKrishna Gudipati 
6875fbe25c7SJing Huang /*
688a36c61f9SKrishna Gudipati  * Disable BFA submodules.
689a36c61f9SKrishna Gudipati  */
690a36c61f9SKrishna Gudipati static void
691a36c61f9SKrishna Gudipati bfa_iocfc_disable_submod(struct bfa_s *bfa)
692a36c61f9SKrishna Gudipati {
693a36c61f9SKrishna Gudipati 	int		i;
694a36c61f9SKrishna Gudipati 
695a36c61f9SKrishna Gudipati 	for (i = 0; hal_mods[i]; i++)
696a36c61f9SKrishna Gudipati 		hal_mods[i]->iocdisable(bfa);
697a36c61f9SKrishna Gudipati }
698a36c61f9SKrishna Gudipati 
699a36c61f9SKrishna Gudipati static void
700a36c61f9SKrishna Gudipati bfa_iocfc_init_cb(void *bfa_arg, bfa_boolean_t complete)
701a36c61f9SKrishna Gudipati {
702a36c61f9SKrishna Gudipati 	struct bfa_s	*bfa = bfa_arg;
703a36c61f9SKrishna Gudipati 
704a36c61f9SKrishna Gudipati 	if (complete) {
705a36c61f9SKrishna Gudipati 		if (bfa->iocfc.cfgdone)
706a36c61f9SKrishna Gudipati 			bfa_cb_init(bfa->bfad, BFA_STATUS_OK);
707a36c61f9SKrishna Gudipati 		else
708a36c61f9SKrishna Gudipati 			bfa_cb_init(bfa->bfad, BFA_STATUS_FAILED);
709a36c61f9SKrishna Gudipati 	} else {
710a36c61f9SKrishna Gudipati 		if (bfa->iocfc.cfgdone)
711a36c61f9SKrishna Gudipati 			bfa->iocfc.action = BFA_IOCFC_ACT_NONE;
712a36c61f9SKrishna Gudipati 	}
713a36c61f9SKrishna Gudipati }
714a36c61f9SKrishna Gudipati 
715a36c61f9SKrishna Gudipati static void
716a36c61f9SKrishna Gudipati bfa_iocfc_stop_cb(void *bfa_arg, bfa_boolean_t compl)
717a36c61f9SKrishna Gudipati {
718a36c61f9SKrishna Gudipati 	struct bfa_s  *bfa = bfa_arg;
719a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = bfa->bfad;
720a36c61f9SKrishna Gudipati 
721a36c61f9SKrishna Gudipati 	if (compl)
722a36c61f9SKrishna Gudipati 		complete(&bfad->comp);
723a36c61f9SKrishna Gudipati 	else
724a36c61f9SKrishna Gudipati 		bfa->iocfc.action = BFA_IOCFC_ACT_NONE;
725a36c61f9SKrishna Gudipati }
726a36c61f9SKrishna Gudipati 
727a36c61f9SKrishna Gudipati static void
72860138066SKrishna Gudipati bfa_iocfc_enable_cb(void *bfa_arg, bfa_boolean_t compl)
72960138066SKrishna Gudipati {
73060138066SKrishna Gudipati 	struct bfa_s	*bfa = bfa_arg;
73160138066SKrishna Gudipati 	struct bfad_s *bfad = bfa->bfad;
73260138066SKrishna Gudipati 
73360138066SKrishna Gudipati 	if (compl)
73460138066SKrishna Gudipati 		complete(&bfad->enable_comp);
73560138066SKrishna Gudipati }
73660138066SKrishna Gudipati 
73760138066SKrishna Gudipati static void
738a36c61f9SKrishna Gudipati bfa_iocfc_disable_cb(void *bfa_arg, bfa_boolean_t compl)
739a36c61f9SKrishna Gudipati {
740a36c61f9SKrishna Gudipati 	struct bfa_s  *bfa = bfa_arg;
741a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = bfa->bfad;
742a36c61f9SKrishna Gudipati 
743a36c61f9SKrishna Gudipati 	if (compl)
744a36c61f9SKrishna Gudipati 		complete(&bfad->disable_comp);
745a36c61f9SKrishna Gudipati }
746a36c61f9SKrishna Gudipati 
74711189208SKrishna Gudipati /**
74811189208SKrishna Gudipati  * configure queue registers from firmware response
74911189208SKrishna Gudipati  */
75011189208SKrishna Gudipati static void
75111189208SKrishna Gudipati bfa_iocfc_qreg(struct bfa_s *bfa, struct bfi_iocfc_qreg_s *qreg)
75211189208SKrishna Gudipati {
75311189208SKrishna Gudipati 	int     i;
75411189208SKrishna Gudipati 	struct bfa_iocfc_regs_s *r = &bfa->iocfc.bfa_regs;
75511189208SKrishna Gudipati 	void __iomem *kva = bfa_ioc_bar0(&bfa->ioc);
75611189208SKrishna Gudipati 
75711189208SKrishna Gudipati 	for (i = 0; i < BFI_IOC_MAX_CQS; i++) {
7583fd45980SKrishna Gudipati 		bfa->iocfc.hw_qid[i] = qreg->hw_qid[i];
75911189208SKrishna Gudipati 		r->cpe_q_ci[i] = kva + be32_to_cpu(qreg->cpe_q_ci_off[i]);
76011189208SKrishna Gudipati 		r->cpe_q_pi[i] = kva + be32_to_cpu(qreg->cpe_q_pi_off[i]);
76111189208SKrishna Gudipati 		r->cpe_q_ctrl[i] = kva + be32_to_cpu(qreg->cpe_qctl_off[i]);
76211189208SKrishna Gudipati 		r->rme_q_ci[i] = kva + be32_to_cpu(qreg->rme_q_ci_off[i]);
76311189208SKrishna Gudipati 		r->rme_q_pi[i] = kva + be32_to_cpu(qreg->rme_q_pi_off[i]);
76411189208SKrishna Gudipati 		r->rme_q_ctrl[i] = kva + be32_to_cpu(qreg->rme_qctl_off[i]);
76511189208SKrishna Gudipati 	}
76611189208SKrishna Gudipati }
76711189208SKrishna Gudipati 
7683fd45980SKrishna Gudipati static void
7693fd45980SKrishna Gudipati bfa_iocfc_res_recfg(struct bfa_s *bfa, struct bfa_iocfc_fwcfg_s *fwcfg)
7703fd45980SKrishna Gudipati {
7713fd45980SKrishna Gudipati 	bfa_fcxp_res_recfg(bfa, fwcfg->num_fcxp_reqs);
7723fd45980SKrishna Gudipati 	bfa_uf_res_recfg(bfa, fwcfg->num_uf_bufs);
7733fd45980SKrishna Gudipati 	bfa_rport_res_recfg(bfa, fwcfg->num_rports);
7743fd45980SKrishna Gudipati 	bfa_fcp_res_recfg(bfa, fwcfg->num_ioim_reqs);
7753fd45980SKrishna Gudipati 	bfa_tskim_res_recfg(bfa, fwcfg->num_tskim_reqs);
7763fd45980SKrishna Gudipati }
7773fd45980SKrishna Gudipati 
7785fbe25c7SJing Huang /*
779a36c61f9SKrishna Gudipati  * Update BFA configuration from firmware configuration.
780a36c61f9SKrishna Gudipati  */
781a36c61f9SKrishna Gudipati static void
782a36c61f9SKrishna Gudipati bfa_iocfc_cfgrsp(struct bfa_s *bfa)
783a36c61f9SKrishna Gudipati {
784a36c61f9SKrishna Gudipati 	struct bfa_iocfc_s		*iocfc	 = &bfa->iocfc;
785a36c61f9SKrishna Gudipati 	struct bfi_iocfc_cfgrsp_s	*cfgrsp	 = iocfc->cfgrsp;
786a36c61f9SKrishna Gudipati 	struct bfa_iocfc_fwcfg_s	*fwcfg	 = &cfgrsp->fwcfg;
787a36c61f9SKrishna Gudipati 
788a36c61f9SKrishna Gudipati 	fwcfg->num_cqs	      = fwcfg->num_cqs;
789ba816ea8SJing Huang 	fwcfg->num_ioim_reqs  = be16_to_cpu(fwcfg->num_ioim_reqs);
790e2187d7fSKrishna Gudipati 	fwcfg->num_fwtio_reqs = be16_to_cpu(fwcfg->num_fwtio_reqs);
791ba816ea8SJing Huang 	fwcfg->num_tskim_reqs = be16_to_cpu(fwcfg->num_tskim_reqs);
792ba816ea8SJing Huang 	fwcfg->num_fcxp_reqs  = be16_to_cpu(fwcfg->num_fcxp_reqs);
793ba816ea8SJing Huang 	fwcfg->num_uf_bufs    = be16_to_cpu(fwcfg->num_uf_bufs);
794ba816ea8SJing Huang 	fwcfg->num_rports     = be16_to_cpu(fwcfg->num_rports);
795a36c61f9SKrishna Gudipati 
796a36c61f9SKrishna Gudipati 	iocfc->cfgdone = BFA_TRUE;
797a36c61f9SKrishna Gudipati 
7985fbe25c7SJing Huang 	/*
79911189208SKrishna Gudipati 	 * configure queue register offsets as learnt from firmware
80011189208SKrishna Gudipati 	 */
80111189208SKrishna Gudipati 	bfa_iocfc_qreg(bfa, &cfgrsp->qreg);
80211189208SKrishna Gudipati 
80311189208SKrishna Gudipati 	/*
8043fd45980SKrishna Gudipati 	 * Re-configure resources as learnt from Firmware
8053fd45980SKrishna Gudipati 	 */
8063fd45980SKrishna Gudipati 	bfa_iocfc_res_recfg(bfa, fwcfg);
8073fd45980SKrishna Gudipati 
8083fd45980SKrishna Gudipati 	/*
809775c7742SKrishna Gudipati 	 * Install MSIX queue handlers
810775c7742SKrishna Gudipati 	 */
811775c7742SKrishna Gudipati 	bfa_msix_queue_install(bfa);
812775c7742SKrishna Gudipati 
813775c7742SKrishna Gudipati 	/*
814a36c61f9SKrishna Gudipati 	 * Configuration is complete - initialize/start submodules
815a36c61f9SKrishna Gudipati 	 */
816a36c61f9SKrishna Gudipati 	bfa_fcport_init(bfa);
817a36c61f9SKrishna Gudipati 
818a36c61f9SKrishna Gudipati 	if (iocfc->action == BFA_IOCFC_ACT_INIT)
819a36c61f9SKrishna Gudipati 		bfa_cb_queue(bfa, &iocfc->init_hcb_qe, bfa_iocfc_init_cb, bfa);
82060138066SKrishna Gudipati 	else {
82160138066SKrishna Gudipati 		if (bfa->iocfc.action == BFA_IOCFC_ACT_ENABLE)
82260138066SKrishna Gudipati 			bfa_cb_queue(bfa, &bfa->iocfc.en_hcb_qe,
82360138066SKrishna Gudipati 					bfa_iocfc_enable_cb, bfa);
824a36c61f9SKrishna Gudipati 		bfa_iocfc_start_submod(bfa);
825a36c61f9SKrishna Gudipati 	}
82660138066SKrishna Gudipati }
827a36c61f9SKrishna Gudipati void
828a36c61f9SKrishna Gudipati bfa_iocfc_reset_queues(struct bfa_s *bfa)
829a36c61f9SKrishna Gudipati {
830a36c61f9SKrishna Gudipati 	int		q;
831a36c61f9SKrishna Gudipati 
832a36c61f9SKrishna Gudipati 	for (q = 0; q < BFI_IOC_MAX_CQS; q++) {
833a36c61f9SKrishna Gudipati 		bfa_reqq_ci(bfa, q) = 0;
834a36c61f9SKrishna Gudipati 		bfa_reqq_pi(bfa, q) = 0;
835a36c61f9SKrishna Gudipati 		bfa_rspq_ci(bfa, q) = 0;
836a36c61f9SKrishna Gudipati 		bfa_rspq_pi(bfa, q) = 0;
837a36c61f9SKrishna Gudipati 	}
838a36c61f9SKrishna Gudipati }
839a36c61f9SKrishna Gudipati 
840a714134aSKrishna Gudipati /* Fabric Assigned Address specific functions */
841a714134aSKrishna Gudipati 
842a714134aSKrishna Gudipati /*
843a714134aSKrishna Gudipati  *	Check whether IOC is ready before sending command down
844a714134aSKrishna Gudipati  */
845a714134aSKrishna Gudipati static bfa_status_t
846a714134aSKrishna Gudipati bfa_faa_validate_request(struct bfa_s *bfa)
847a714134aSKrishna Gudipati {
848a714134aSKrishna Gudipati 	enum bfa_ioc_type_e	ioc_type = bfa_get_type(bfa);
849a714134aSKrishna Gudipati 	u32	card_type = bfa->ioc.attr->card_type;
850a714134aSKrishna Gudipati 
851a714134aSKrishna Gudipati 	if (bfa_ioc_is_operational(&bfa->ioc)) {
852a714134aSKrishna Gudipati 		if ((ioc_type != BFA_IOC_TYPE_FC) || bfa_mfg_is_mezz(card_type))
853a714134aSKrishna Gudipati 			return BFA_STATUS_FEATURE_NOT_SUPPORTED;
854a714134aSKrishna Gudipati 	} else {
855a714134aSKrishna Gudipati 		if (!bfa_ioc_is_acq_addr(&bfa->ioc))
856a714134aSKrishna Gudipati 			return BFA_STATUS_IOC_NON_OP;
857a714134aSKrishna Gudipati 	}
858a714134aSKrishna Gudipati 
859a714134aSKrishna Gudipati 	return BFA_STATUS_OK;
860a714134aSKrishna Gudipati }
861a714134aSKrishna Gudipati 
862a714134aSKrishna Gudipati bfa_status_t
863a714134aSKrishna Gudipati bfa_faa_enable(struct bfa_s *bfa, bfa_cb_iocfc_t cbfn, void *cbarg)
864a714134aSKrishna Gudipati {
865a714134aSKrishna Gudipati 	struct bfi_faa_en_dis_s faa_enable_req;
866a714134aSKrishna Gudipati 	struct bfa_iocfc_s	*iocfc = &bfa->iocfc;
867a714134aSKrishna Gudipati 	bfa_status_t		status;
868a714134aSKrishna Gudipati 
869a714134aSKrishna Gudipati 	iocfc->faa_args.faa_cb.faa_cbfn = cbfn;
870a714134aSKrishna Gudipati 	iocfc->faa_args.faa_cb.faa_cbarg = cbarg;
871a714134aSKrishna Gudipati 
872a714134aSKrishna Gudipati 	status = bfa_faa_validate_request(bfa);
873a714134aSKrishna Gudipati 	if (status != BFA_STATUS_OK)
874a714134aSKrishna Gudipati 		return status;
875a714134aSKrishna Gudipati 
876a714134aSKrishna Gudipati 	if (iocfc->faa_args.busy == BFA_TRUE)
877a714134aSKrishna Gudipati 		return BFA_STATUS_DEVBUSY;
878a714134aSKrishna Gudipati 
879a714134aSKrishna Gudipati 	if (iocfc->faa_args.faa_state == BFA_FAA_ENABLED)
880a714134aSKrishna Gudipati 		return BFA_STATUS_FAA_ENABLED;
881a714134aSKrishna Gudipati 
882a714134aSKrishna Gudipati 	if (bfa_fcport_is_trunk_enabled(bfa))
883a714134aSKrishna Gudipati 		return BFA_STATUS_ERROR_TRUNK_ENABLED;
884a714134aSKrishna Gudipati 
885a714134aSKrishna Gudipati 	bfa_fcport_cfg_faa(bfa, BFA_FAA_ENABLED);
886a714134aSKrishna Gudipati 	iocfc->faa_args.busy = BFA_TRUE;
887a714134aSKrishna Gudipati 
888a714134aSKrishna Gudipati 	memset(&faa_enable_req, 0, sizeof(struct bfi_faa_en_dis_s));
889a714134aSKrishna Gudipati 	bfi_h2i_set(faa_enable_req.mh, BFI_MC_IOCFC,
8903fd45980SKrishna Gudipati 		BFI_IOCFC_H2I_FAA_ENABLE_REQ, bfa_fn_lpu(bfa));
891a714134aSKrishna Gudipati 
892a714134aSKrishna Gudipati 	bfa_ioc_mbox_send(&bfa->ioc, &faa_enable_req,
893a714134aSKrishna Gudipati 			sizeof(struct bfi_faa_en_dis_s));
894a714134aSKrishna Gudipati 
895a714134aSKrishna Gudipati 	return BFA_STATUS_OK;
896a714134aSKrishna Gudipati }
897a714134aSKrishna Gudipati 
898a714134aSKrishna Gudipati bfa_status_t
899a714134aSKrishna Gudipati bfa_faa_disable(struct bfa_s *bfa, bfa_cb_iocfc_t cbfn,
900a714134aSKrishna Gudipati 		void *cbarg)
901a714134aSKrishna Gudipati {
902a714134aSKrishna Gudipati 	struct bfi_faa_en_dis_s faa_disable_req;
903a714134aSKrishna Gudipati 	struct bfa_iocfc_s	*iocfc = &bfa->iocfc;
904a714134aSKrishna Gudipati 	bfa_status_t		status;
905a714134aSKrishna Gudipati 
906a714134aSKrishna Gudipati 	iocfc->faa_args.faa_cb.faa_cbfn = cbfn;
907a714134aSKrishna Gudipati 	iocfc->faa_args.faa_cb.faa_cbarg = cbarg;
908a714134aSKrishna Gudipati 
909a714134aSKrishna Gudipati 	status = bfa_faa_validate_request(bfa);
910a714134aSKrishna Gudipati 	if (status != BFA_STATUS_OK)
911a714134aSKrishna Gudipati 		return status;
912a714134aSKrishna Gudipati 
913a714134aSKrishna Gudipati 	if (iocfc->faa_args.busy == BFA_TRUE)
914a714134aSKrishna Gudipati 		return BFA_STATUS_DEVBUSY;
915a714134aSKrishna Gudipati 
916a714134aSKrishna Gudipati 	if (iocfc->faa_args.faa_state == BFA_FAA_DISABLED)
917a714134aSKrishna Gudipati 		return BFA_STATUS_FAA_DISABLED;
918a714134aSKrishna Gudipati 
919a714134aSKrishna Gudipati 	bfa_fcport_cfg_faa(bfa, BFA_FAA_DISABLED);
920a714134aSKrishna Gudipati 	iocfc->faa_args.busy = BFA_TRUE;
921a714134aSKrishna Gudipati 
922a714134aSKrishna Gudipati 	memset(&faa_disable_req, 0, sizeof(struct bfi_faa_en_dis_s));
923a714134aSKrishna Gudipati 	bfi_h2i_set(faa_disable_req.mh, BFI_MC_IOCFC,
9243fd45980SKrishna Gudipati 		BFI_IOCFC_H2I_FAA_DISABLE_REQ, bfa_fn_lpu(bfa));
925a714134aSKrishna Gudipati 
926a714134aSKrishna Gudipati 	bfa_ioc_mbox_send(&bfa->ioc, &faa_disable_req,
927a714134aSKrishna Gudipati 		sizeof(struct bfi_faa_en_dis_s));
928a714134aSKrishna Gudipati 
929a714134aSKrishna Gudipati 	return BFA_STATUS_OK;
930a714134aSKrishna Gudipati }
931a714134aSKrishna Gudipati 
932a714134aSKrishna Gudipati bfa_status_t
933a714134aSKrishna Gudipati bfa_faa_query(struct bfa_s *bfa, struct bfa_faa_attr_s *attr,
934a714134aSKrishna Gudipati 		bfa_cb_iocfc_t cbfn, void *cbarg)
935a714134aSKrishna Gudipati {
936a714134aSKrishna Gudipati 	struct bfi_faa_query_s  faa_attr_req;
937a714134aSKrishna Gudipati 	struct bfa_iocfc_s      *iocfc = &bfa->iocfc;
938a714134aSKrishna Gudipati 	bfa_status_t            status;
939a714134aSKrishna Gudipati 
940a714134aSKrishna Gudipati 	iocfc->faa_args.faa_attr = attr;
941a714134aSKrishna Gudipati 	iocfc->faa_args.faa_cb.faa_cbfn = cbfn;
942a714134aSKrishna Gudipati 	iocfc->faa_args.faa_cb.faa_cbarg = cbarg;
943a714134aSKrishna Gudipati 
944a714134aSKrishna Gudipati 	status = bfa_faa_validate_request(bfa);
945a714134aSKrishna Gudipati 	if (status != BFA_STATUS_OK)
946a714134aSKrishna Gudipati 		return status;
947a714134aSKrishna Gudipati 
948a714134aSKrishna Gudipati 	if (iocfc->faa_args.busy == BFA_TRUE)
949a714134aSKrishna Gudipati 		return BFA_STATUS_DEVBUSY;
950a714134aSKrishna Gudipati 
951a714134aSKrishna Gudipati 	iocfc->faa_args.busy = BFA_TRUE;
952a714134aSKrishna Gudipati 	memset(&faa_attr_req, 0, sizeof(struct bfi_faa_query_s));
953a714134aSKrishna Gudipati 	bfi_h2i_set(faa_attr_req.mh, BFI_MC_IOCFC,
9543fd45980SKrishna Gudipati 		BFI_IOCFC_H2I_FAA_QUERY_REQ, bfa_fn_lpu(bfa));
955a714134aSKrishna Gudipati 
956a714134aSKrishna Gudipati 	bfa_ioc_mbox_send(&bfa->ioc, &faa_attr_req,
957a714134aSKrishna Gudipati 		sizeof(struct bfi_faa_query_s));
958a714134aSKrishna Gudipati 
959a714134aSKrishna Gudipati 	return BFA_STATUS_OK;
960a714134aSKrishna Gudipati }
961a714134aSKrishna Gudipati 
962a714134aSKrishna Gudipati /*
963a714134aSKrishna Gudipati  *	FAA enable response
964a714134aSKrishna Gudipati  */
965a714134aSKrishna Gudipati static void
966a714134aSKrishna Gudipati bfa_faa_enable_reply(struct bfa_iocfc_s *iocfc,
967a714134aSKrishna Gudipati 		struct bfi_faa_en_dis_rsp_s *rsp)
968a714134aSKrishna Gudipati {
969a714134aSKrishna Gudipati 	void	*cbarg = iocfc->faa_args.faa_cb.faa_cbarg;
970a714134aSKrishna Gudipati 	bfa_status_t	status = rsp->status;
971a714134aSKrishna Gudipati 
972a714134aSKrishna Gudipati 	WARN_ON(!iocfc->faa_args.faa_cb.faa_cbfn);
973a714134aSKrishna Gudipati 
974a714134aSKrishna Gudipati 	iocfc->faa_args.faa_cb.faa_cbfn(cbarg, status);
975a714134aSKrishna Gudipati 	iocfc->faa_args.busy = BFA_FALSE;
976a714134aSKrishna Gudipati }
977a714134aSKrishna Gudipati 
978a714134aSKrishna Gudipati /*
979a714134aSKrishna Gudipati  *	FAA disable response
980a714134aSKrishna Gudipati  */
981a714134aSKrishna Gudipati static void
982a714134aSKrishna Gudipati bfa_faa_disable_reply(struct bfa_iocfc_s *iocfc,
983a714134aSKrishna Gudipati 		struct bfi_faa_en_dis_rsp_s *rsp)
984a714134aSKrishna Gudipati {
985a714134aSKrishna Gudipati 	void	*cbarg = iocfc->faa_args.faa_cb.faa_cbarg;
986a714134aSKrishna Gudipati 	bfa_status_t	status = rsp->status;
987a714134aSKrishna Gudipati 
988a714134aSKrishna Gudipati 	WARN_ON(!iocfc->faa_args.faa_cb.faa_cbfn);
989a714134aSKrishna Gudipati 
990a714134aSKrishna Gudipati 	iocfc->faa_args.faa_cb.faa_cbfn(cbarg, status);
991a714134aSKrishna Gudipati 	iocfc->faa_args.busy = BFA_FALSE;
992a714134aSKrishna Gudipati }
993a714134aSKrishna Gudipati 
994a714134aSKrishna Gudipati /*
995a714134aSKrishna Gudipati  *	FAA query response
996a714134aSKrishna Gudipati  */
997a714134aSKrishna Gudipati static void
998a714134aSKrishna Gudipati bfa_faa_query_reply(struct bfa_iocfc_s *iocfc,
999a714134aSKrishna Gudipati 		bfi_faa_query_rsp_t *rsp)
1000a714134aSKrishna Gudipati {
1001a714134aSKrishna Gudipati 	void	*cbarg = iocfc->faa_args.faa_cb.faa_cbarg;
1002a714134aSKrishna Gudipati 
1003a714134aSKrishna Gudipati 	if (iocfc->faa_args.faa_attr) {
1004a714134aSKrishna Gudipati 		iocfc->faa_args.faa_attr->faa = rsp->faa;
1005a714134aSKrishna Gudipati 		iocfc->faa_args.faa_attr->faa_state = rsp->faa_status;
1006a714134aSKrishna Gudipati 		iocfc->faa_args.faa_attr->pwwn_source = rsp->addr_source;
1007a714134aSKrishna Gudipati 	}
1008a714134aSKrishna Gudipati 
1009a714134aSKrishna Gudipati 	WARN_ON(!iocfc->faa_args.faa_cb.faa_cbfn);
1010a714134aSKrishna Gudipati 
1011a714134aSKrishna Gudipati 	iocfc->faa_args.faa_cb.faa_cbfn(cbarg, BFA_STATUS_OK);
1012a714134aSKrishna Gudipati 	iocfc->faa_args.busy = BFA_FALSE;
1013a714134aSKrishna Gudipati }
1014a714134aSKrishna Gudipati 
10155fbe25c7SJing Huang /*
1016a36c61f9SKrishna Gudipati  * IOC enable request is complete
1017a36c61f9SKrishna Gudipati  */
1018a36c61f9SKrishna Gudipati static void
1019a36c61f9SKrishna Gudipati bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status)
1020a36c61f9SKrishna Gudipati {
1021a36c61f9SKrishna Gudipati 	struct bfa_s	*bfa = bfa_arg;
1022a36c61f9SKrishna Gudipati 
1023a714134aSKrishna Gudipati 	if (status == BFA_STATUS_FAA_ACQ_ADDR) {
1024a714134aSKrishna Gudipati 		bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe,
1025a714134aSKrishna Gudipati 				bfa_iocfc_init_cb, bfa);
1026a714134aSKrishna Gudipati 		return;
1027a714134aSKrishna Gudipati 	}
1028a714134aSKrishna Gudipati 
1029a36c61f9SKrishna Gudipati 	if (status != BFA_STATUS_OK) {
1030a36c61f9SKrishna Gudipati 		bfa_isr_disable(bfa);
1031a36c61f9SKrishna Gudipati 		if (bfa->iocfc.action == BFA_IOCFC_ACT_INIT)
1032a36c61f9SKrishna Gudipati 			bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe,
1033a36c61f9SKrishna Gudipati 				     bfa_iocfc_init_cb, bfa);
103460138066SKrishna Gudipati 		else if (bfa->iocfc.action == BFA_IOCFC_ACT_ENABLE)
103560138066SKrishna Gudipati 			bfa_cb_queue(bfa, &bfa->iocfc.en_hcb_qe,
103660138066SKrishna Gudipati 					bfa_iocfc_enable_cb, bfa);
1037a36c61f9SKrishna Gudipati 		return;
1038a36c61f9SKrishna Gudipati 	}
1039a36c61f9SKrishna Gudipati 
1040a36c61f9SKrishna Gudipati 	bfa_iocfc_send_cfg(bfa);
1041a36c61f9SKrishna Gudipati }
1042a36c61f9SKrishna Gudipati 
10435fbe25c7SJing Huang /*
1044a36c61f9SKrishna Gudipati  * IOC disable request is complete
1045a36c61f9SKrishna Gudipati  */
1046a36c61f9SKrishna Gudipati static void
1047a36c61f9SKrishna Gudipati bfa_iocfc_disable_cbfn(void *bfa_arg)
1048a36c61f9SKrishna Gudipati {
1049a36c61f9SKrishna Gudipati 	struct bfa_s	*bfa = bfa_arg;
1050a36c61f9SKrishna Gudipati 
1051a36c61f9SKrishna Gudipati 	bfa_isr_disable(bfa);
1052a36c61f9SKrishna Gudipati 	bfa_iocfc_disable_submod(bfa);
1053a36c61f9SKrishna Gudipati 
1054a36c61f9SKrishna Gudipati 	if (bfa->iocfc.action == BFA_IOCFC_ACT_STOP)
1055a36c61f9SKrishna Gudipati 		bfa_cb_queue(bfa, &bfa->iocfc.stop_hcb_qe, bfa_iocfc_stop_cb,
1056a36c61f9SKrishna Gudipati 			     bfa);
1057a36c61f9SKrishna Gudipati 	else {
1058d4b671c5SJing Huang 		WARN_ON(bfa->iocfc.action != BFA_IOCFC_ACT_DISABLE);
1059a36c61f9SKrishna Gudipati 		bfa_cb_queue(bfa, &bfa->iocfc.dis_hcb_qe, bfa_iocfc_disable_cb,
1060a36c61f9SKrishna Gudipati 			     bfa);
1061a36c61f9SKrishna Gudipati 	}
1062a36c61f9SKrishna Gudipati }
1063a36c61f9SKrishna Gudipati 
10645fbe25c7SJing Huang /*
1065a36c61f9SKrishna Gudipati  * Notify sub-modules of hardware failure.
1066a36c61f9SKrishna Gudipati  */
1067a36c61f9SKrishna Gudipati static void
1068a36c61f9SKrishna Gudipati bfa_iocfc_hbfail_cbfn(void *bfa_arg)
1069a36c61f9SKrishna Gudipati {
1070a36c61f9SKrishna Gudipati 	struct bfa_s	*bfa = bfa_arg;
1071a36c61f9SKrishna Gudipati 
1072775c7742SKrishna Gudipati 	bfa->queue_process = BFA_FALSE;
1073a36c61f9SKrishna Gudipati 
1074a36c61f9SKrishna Gudipati 	bfa_isr_disable(bfa);
1075a36c61f9SKrishna Gudipati 	bfa_iocfc_disable_submod(bfa);
1076a36c61f9SKrishna Gudipati 
1077a36c61f9SKrishna Gudipati 	if (bfa->iocfc.action == BFA_IOCFC_ACT_INIT)
1078a36c61f9SKrishna Gudipati 		bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe, bfa_iocfc_init_cb,
1079a36c61f9SKrishna Gudipati 			     bfa);
1080a36c61f9SKrishna Gudipati }
1081a36c61f9SKrishna Gudipati 
10825fbe25c7SJing Huang /*
1083a36c61f9SKrishna Gudipati  * Actions on chip-reset completion.
1084a36c61f9SKrishna Gudipati  */
1085a36c61f9SKrishna Gudipati static void
1086a36c61f9SKrishna Gudipati bfa_iocfc_reset_cbfn(void *bfa_arg)
1087a36c61f9SKrishna Gudipati {
1088a36c61f9SKrishna Gudipati 	struct bfa_s	*bfa = bfa_arg;
1089a36c61f9SKrishna Gudipati 
1090a36c61f9SKrishna Gudipati 	bfa_iocfc_reset_queues(bfa);
1091a36c61f9SKrishna Gudipati 	bfa_isr_enable(bfa);
1092a36c61f9SKrishna Gudipati }
1093a36c61f9SKrishna Gudipati 
1094a36c61f9SKrishna Gudipati 
10955fbe25c7SJing Huang /*
1096a36c61f9SKrishna Gudipati  * Query IOC memory requirement information.
1097a36c61f9SKrishna Gudipati  */
1098a36c61f9SKrishna Gudipati void
10994507025dSKrishna Gudipati bfa_iocfc_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,
11004507025dSKrishna Gudipati 		  struct bfa_s *bfa)
1101a36c61f9SKrishna Gudipati {
11024507025dSKrishna Gudipati 	int q, per_reqq_sz, per_rspq_sz;
11034507025dSKrishna Gudipati 	struct bfa_mem_dma_s *ioc_dma = BFA_MEM_IOC_DMA(bfa);
11044507025dSKrishna Gudipati 	struct bfa_mem_dma_s *iocfc_dma = BFA_MEM_IOCFC_DMA(bfa);
11054507025dSKrishna Gudipati 	struct bfa_mem_kva_s *iocfc_kva = BFA_MEM_IOCFC_KVA(bfa);
11064507025dSKrishna Gudipati 	u32	dm_len = 0;
1107a36c61f9SKrishna Gudipati 
11084507025dSKrishna Gudipati 	/* dma memory setup for IOC */
11094507025dSKrishna Gudipati 	bfa_mem_dma_setup(meminfo, ioc_dma,
11104507025dSKrishna Gudipati 		BFA_ROUNDUP(sizeof(struct bfi_ioc_attr_s), BFA_DMA_ALIGN_SZ));
11114507025dSKrishna Gudipati 
11124507025dSKrishna Gudipati 	/* dma memory setup for REQ/RSP queues */
11134507025dSKrishna Gudipati 	per_reqq_sz = BFA_ROUNDUP((cfg->drvcfg.num_reqq_elems * BFI_LMSG_SZ),
11144507025dSKrishna Gudipati 				BFA_DMA_ALIGN_SZ);
11154507025dSKrishna Gudipati 	per_rspq_sz = BFA_ROUNDUP((cfg->drvcfg.num_rspq_elems * BFI_LMSG_SZ),
11164507025dSKrishna Gudipati 				BFA_DMA_ALIGN_SZ);
11174507025dSKrishna Gudipati 
11184507025dSKrishna Gudipati 	for (q = 0; q < cfg->fwcfg.num_cqs; q++) {
11194507025dSKrishna Gudipati 		bfa_mem_dma_setup(meminfo, BFA_MEM_REQQ_DMA(bfa, q),
11204507025dSKrishna Gudipati 				per_reqq_sz);
11214507025dSKrishna Gudipati 		bfa_mem_dma_setup(meminfo, BFA_MEM_RSPQ_DMA(bfa, q),
11224507025dSKrishna Gudipati 				per_rspq_sz);
11234507025dSKrishna Gudipati 	}
11244507025dSKrishna Gudipati 
11254507025dSKrishna Gudipati 	/* IOCFC dma memory - calculate Shadow CI/PI size */
11264507025dSKrishna Gudipati 	for (q = 0; q < cfg->fwcfg.num_cqs; q++)
11274507025dSKrishna Gudipati 		dm_len += (2 * BFA_CACHELINE_SZ);
11284507025dSKrishna Gudipati 
11294507025dSKrishna Gudipati 	/* IOCFC dma memory - calculate config info / rsp size */
11304507025dSKrishna Gudipati 	dm_len += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s), BFA_CACHELINE_SZ);
11314507025dSKrishna Gudipati 	dm_len += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s),
11324507025dSKrishna Gudipati 			BFA_CACHELINE_SZ);
11334507025dSKrishna Gudipati 
11344507025dSKrishna Gudipati 	/* dma memory setup for IOCFC */
11354507025dSKrishna Gudipati 	bfa_mem_dma_setup(meminfo, iocfc_dma, dm_len);
11364507025dSKrishna Gudipati 
11374507025dSKrishna Gudipati 	/* kva memory setup for IOCFC */
11384507025dSKrishna Gudipati 	bfa_mem_kva_setup(meminfo, iocfc_kva,
11394507025dSKrishna Gudipati 			((bfa_auto_recover) ? BFA_DBG_FWTRC_LEN : 0));
1140a36c61f9SKrishna Gudipati }
1141a36c61f9SKrishna Gudipati 
11425fbe25c7SJing Huang /*
1143a36c61f9SKrishna Gudipati  * Query IOC memory requirement information.
1144a36c61f9SKrishna Gudipati  */
1145a36c61f9SKrishna Gudipati void
1146a36c61f9SKrishna Gudipati bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
11474507025dSKrishna Gudipati 		 struct bfa_pcidev_s *pcidev)
1148a36c61f9SKrishna Gudipati {
1149a36c61f9SKrishna Gudipati 	int		i;
1150a36c61f9SKrishna Gudipati 	struct bfa_ioc_s *ioc = &bfa->ioc;
1151a36c61f9SKrishna Gudipati 
1152a36c61f9SKrishna Gudipati 	bfa_iocfc_cbfn.enable_cbfn = bfa_iocfc_enable_cbfn;
1153a36c61f9SKrishna Gudipati 	bfa_iocfc_cbfn.disable_cbfn = bfa_iocfc_disable_cbfn;
1154a36c61f9SKrishna Gudipati 	bfa_iocfc_cbfn.hbfail_cbfn = bfa_iocfc_hbfail_cbfn;
1155a36c61f9SKrishna Gudipati 	bfa_iocfc_cbfn.reset_cbfn = bfa_iocfc_reset_cbfn;
1156a36c61f9SKrishna Gudipati 
1157a36c61f9SKrishna Gudipati 	ioc->trcmod = bfa->trcmod;
1158a36c61f9SKrishna Gudipati 	bfa_ioc_attach(&bfa->ioc, bfa, &bfa_iocfc_cbfn, &bfa->timer_mod);
1159a36c61f9SKrishna Gudipati 
1160d37779f8SKrishna Gudipati 	bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_PCIFN_CLASS_FC);
1161a36c61f9SKrishna Gudipati 	bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs);
1162a36c61f9SKrishna Gudipati 
1163a36c61f9SKrishna Gudipati 	bfa_iocfc_init_mem(bfa, bfad, cfg, pcidev);
11644507025dSKrishna Gudipati 	bfa_iocfc_mem_claim(bfa, cfg);
1165f7f73812SMaggie Zhang 	INIT_LIST_HEAD(&bfa->timer_mod.timer_q);
1166a36c61f9SKrishna Gudipati 
1167a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&bfa->comp_q);
1168a36c61f9SKrishna Gudipati 	for (i = 0; i < BFI_IOC_MAX_CQS; i++)
1169a36c61f9SKrishna Gudipati 		INIT_LIST_HEAD(&bfa->reqq_waitq[i]);
1170a36c61f9SKrishna Gudipati }
1171a36c61f9SKrishna Gudipati 
11725fbe25c7SJing Huang /*
1173a36c61f9SKrishna Gudipati  * Query IOC memory requirement information.
1174a36c61f9SKrishna Gudipati  */
1175a36c61f9SKrishna Gudipati void
1176a36c61f9SKrishna Gudipati bfa_iocfc_init(struct bfa_s *bfa)
1177a36c61f9SKrishna Gudipati {
1178a36c61f9SKrishna Gudipati 	bfa->iocfc.action = BFA_IOCFC_ACT_INIT;
1179a36c61f9SKrishna Gudipati 	bfa_ioc_enable(&bfa->ioc);
1180a36c61f9SKrishna Gudipati }
1181a36c61f9SKrishna Gudipati 
11825fbe25c7SJing Huang /*
1183a36c61f9SKrishna Gudipati  * IOC start called from bfa_start(). Called to start IOC operations
1184a36c61f9SKrishna Gudipati  * at driver instantiation for this instance.
1185a36c61f9SKrishna Gudipati  */
1186a36c61f9SKrishna Gudipati void
1187a36c61f9SKrishna Gudipati bfa_iocfc_start(struct bfa_s *bfa)
1188a36c61f9SKrishna Gudipati {
1189a36c61f9SKrishna Gudipati 	if (bfa->iocfc.cfgdone)
1190a36c61f9SKrishna Gudipati 		bfa_iocfc_start_submod(bfa);
1191a36c61f9SKrishna Gudipati }
1192a36c61f9SKrishna Gudipati 
11935fbe25c7SJing Huang /*
1194a36c61f9SKrishna Gudipati  * IOC stop called from bfa_stop(). Called only when driver is unloaded
1195a36c61f9SKrishna Gudipati  * for this instance.
1196a36c61f9SKrishna Gudipati  */
1197a36c61f9SKrishna Gudipati void
1198a36c61f9SKrishna Gudipati bfa_iocfc_stop(struct bfa_s *bfa)
1199a36c61f9SKrishna Gudipati {
1200a36c61f9SKrishna Gudipati 	bfa->iocfc.action = BFA_IOCFC_ACT_STOP;
1201a36c61f9SKrishna Gudipati 
1202775c7742SKrishna Gudipati 	bfa->queue_process = BFA_FALSE;
1203a36c61f9SKrishna Gudipati 	bfa_ioc_disable(&bfa->ioc);
1204a36c61f9SKrishna Gudipati }
1205a36c61f9SKrishna Gudipati 
1206a36c61f9SKrishna Gudipati void
1207a36c61f9SKrishna Gudipati bfa_iocfc_isr(void *bfaarg, struct bfi_mbmsg_s *m)
1208a36c61f9SKrishna Gudipati {
1209a36c61f9SKrishna Gudipati 	struct bfa_s		*bfa = bfaarg;
1210a36c61f9SKrishna Gudipati 	struct bfa_iocfc_s	*iocfc = &bfa->iocfc;
1211a36c61f9SKrishna Gudipati 	union bfi_iocfc_i2h_msg_u	*msg;
1212a36c61f9SKrishna Gudipati 
1213a36c61f9SKrishna Gudipati 	msg = (union bfi_iocfc_i2h_msg_u *) m;
1214a36c61f9SKrishna Gudipati 	bfa_trc(bfa, msg->mh.msg_id);
1215a36c61f9SKrishna Gudipati 
1216a36c61f9SKrishna Gudipati 	switch (msg->mh.msg_id) {
1217a36c61f9SKrishna Gudipati 	case BFI_IOCFC_I2H_CFG_REPLY:
1218a36c61f9SKrishna Gudipati 		bfa_iocfc_cfgrsp(bfa);
1219a36c61f9SKrishna Gudipati 		break;
1220a36c61f9SKrishna Gudipati 	case BFI_IOCFC_I2H_UPDATEQ_RSP:
1221a36c61f9SKrishna Gudipati 		iocfc->updateq_cbfn(iocfc->updateq_cbarg, BFA_STATUS_OK);
1222a36c61f9SKrishna Gudipati 		break;
1223a714134aSKrishna Gudipati 	case BFI_IOCFC_I2H_FAA_ENABLE_RSP:
1224a714134aSKrishna Gudipati 		bfa_faa_enable_reply(iocfc,
1225a714134aSKrishna Gudipati 			(struct bfi_faa_en_dis_rsp_s *)msg);
1226a714134aSKrishna Gudipati 		break;
1227a714134aSKrishna Gudipati 	case BFI_IOCFC_I2H_FAA_DISABLE_RSP:
1228a714134aSKrishna Gudipati 		bfa_faa_disable_reply(iocfc,
1229a714134aSKrishna Gudipati 			(struct bfi_faa_en_dis_rsp_s *)msg);
1230a714134aSKrishna Gudipati 		break;
1231a714134aSKrishna Gudipati 	case BFI_IOCFC_I2H_FAA_QUERY_RSP:
1232a714134aSKrishna Gudipati 		bfa_faa_query_reply(iocfc, (bfi_faa_query_rsp_t *)msg);
1233a714134aSKrishna Gudipati 		break;
1234a36c61f9SKrishna Gudipati 	default:
1235d4b671c5SJing Huang 		WARN_ON(1);
1236a36c61f9SKrishna Gudipati 	}
1237a36c61f9SKrishna Gudipati }
1238a36c61f9SKrishna Gudipati 
1239a36c61f9SKrishna Gudipati void
1240a36c61f9SKrishna Gudipati bfa_iocfc_get_attr(struct bfa_s *bfa, struct bfa_iocfc_attr_s *attr)
1241a36c61f9SKrishna Gudipati {
1242a36c61f9SKrishna Gudipati 	struct bfa_iocfc_s	*iocfc = &bfa->iocfc;
1243a36c61f9SKrishna Gudipati 
1244a36c61f9SKrishna Gudipati 	attr->intr_attr.coalesce = iocfc->cfginfo->intr_attr.coalesce;
1245a36c61f9SKrishna Gudipati 
1246a36c61f9SKrishna Gudipati 	attr->intr_attr.delay = iocfc->cfginfo->intr_attr.delay ?
1247ba816ea8SJing Huang 				be16_to_cpu(iocfc->cfginfo->intr_attr.delay) :
1248ba816ea8SJing Huang 				be16_to_cpu(iocfc->cfgrsp->intr_attr.delay);
1249a36c61f9SKrishna Gudipati 
1250a36c61f9SKrishna Gudipati 	attr->intr_attr.latency = iocfc->cfginfo->intr_attr.latency ?
1251ba816ea8SJing Huang 			be16_to_cpu(iocfc->cfginfo->intr_attr.latency) :
1252ba816ea8SJing Huang 			be16_to_cpu(iocfc->cfgrsp->intr_attr.latency);
1253a36c61f9SKrishna Gudipati 
1254a36c61f9SKrishna Gudipati 	attr->config	= iocfc->cfg;
1255a36c61f9SKrishna Gudipati }
1256a36c61f9SKrishna Gudipati 
1257a36c61f9SKrishna Gudipati bfa_status_t
1258a36c61f9SKrishna Gudipati bfa_iocfc_israttr_set(struct bfa_s *bfa, struct bfa_iocfc_intr_attr_s *attr)
1259a36c61f9SKrishna Gudipati {
1260a36c61f9SKrishna Gudipati 	struct bfa_iocfc_s		*iocfc = &bfa->iocfc;
1261a36c61f9SKrishna Gudipati 	struct bfi_iocfc_set_intr_req_s *m;
1262a36c61f9SKrishna Gudipati 
1263a36c61f9SKrishna Gudipati 	iocfc->cfginfo->intr_attr.coalesce = attr->coalesce;
1264ba816ea8SJing Huang 	iocfc->cfginfo->intr_attr.delay = cpu_to_be16(attr->delay);
1265ba816ea8SJing Huang 	iocfc->cfginfo->intr_attr.latency = cpu_to_be16(attr->latency);
1266a36c61f9SKrishna Gudipati 
1267a36c61f9SKrishna Gudipati 	if (!bfa_iocfc_is_operational(bfa))
1268a36c61f9SKrishna Gudipati 		return BFA_STATUS_OK;
1269a36c61f9SKrishna Gudipati 
1270a36c61f9SKrishna Gudipati 	m = bfa_reqq_next(bfa, BFA_REQQ_IOC);
1271a36c61f9SKrishna Gudipati 	if (!m)
1272a36c61f9SKrishna Gudipati 		return BFA_STATUS_DEVBUSY;
1273a36c61f9SKrishna Gudipati 
1274a36c61f9SKrishna Gudipati 	bfi_h2i_set(m->mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_SET_INTR_REQ,
12753fd45980SKrishna Gudipati 		    bfa_fn_lpu(bfa));
1276a36c61f9SKrishna Gudipati 	m->coalesce = iocfc->cfginfo->intr_attr.coalesce;
1277a36c61f9SKrishna Gudipati 	m->delay    = iocfc->cfginfo->intr_attr.delay;
1278a36c61f9SKrishna Gudipati 	m->latency  = iocfc->cfginfo->intr_attr.latency;
1279a36c61f9SKrishna Gudipati 
1280a36c61f9SKrishna Gudipati 	bfa_trc(bfa, attr->delay);
1281a36c61f9SKrishna Gudipati 	bfa_trc(bfa, attr->latency);
1282a36c61f9SKrishna Gudipati 
12833fd45980SKrishna Gudipati 	bfa_reqq_produce(bfa, BFA_REQQ_IOC, m->mh);
1284a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
1285a36c61f9SKrishna Gudipati }
1286a36c61f9SKrishna Gudipati 
1287a36c61f9SKrishna Gudipati void
12884507025dSKrishna Gudipati bfa_iocfc_set_snsbase(struct bfa_s *bfa, int seg_no, u64 snsbase_pa)
1289a36c61f9SKrishna Gudipati {
1290a36c61f9SKrishna Gudipati 	struct bfa_iocfc_s	*iocfc = &bfa->iocfc;
1291a36c61f9SKrishna Gudipati 
1292a36c61f9SKrishna Gudipati 	iocfc->cfginfo->sense_buf_len = (BFI_IOIM_SNSLEN - 1);
12934507025dSKrishna Gudipati 	bfa_dma_be_addr_set(iocfc->cfginfo->ioim_snsbase[seg_no], snsbase_pa);
1294a36c61f9SKrishna Gudipati }
12955fbe25c7SJing Huang /*
1296a36c61f9SKrishna Gudipati  * Enable IOC after it is disabled.
1297a36c61f9SKrishna Gudipati  */
1298a36c61f9SKrishna Gudipati void
1299a36c61f9SKrishna Gudipati bfa_iocfc_enable(struct bfa_s *bfa)
1300a36c61f9SKrishna Gudipati {
1301a36c61f9SKrishna Gudipati 	bfa_plog_str(bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_MISC, 0,
1302a36c61f9SKrishna Gudipati 		     "IOC Enable");
130360138066SKrishna Gudipati 	bfa->iocfc.action = BFA_IOCFC_ACT_ENABLE;
1304a36c61f9SKrishna Gudipati 	bfa_ioc_enable(&bfa->ioc);
1305a36c61f9SKrishna Gudipati }
1306a36c61f9SKrishna Gudipati 
1307a36c61f9SKrishna Gudipati void
1308a36c61f9SKrishna Gudipati bfa_iocfc_disable(struct bfa_s *bfa)
1309a36c61f9SKrishna Gudipati {
1310a36c61f9SKrishna Gudipati 	bfa_plog_str(bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_MISC, 0,
1311a36c61f9SKrishna Gudipati 		     "IOC Disable");
1312a36c61f9SKrishna Gudipati 	bfa->iocfc.action = BFA_IOCFC_ACT_DISABLE;
1313a36c61f9SKrishna Gudipati 
1314775c7742SKrishna Gudipati 	bfa->queue_process = BFA_FALSE;
1315a36c61f9SKrishna Gudipati 	bfa_ioc_disable(&bfa->ioc);
1316a36c61f9SKrishna Gudipati }
1317a36c61f9SKrishna Gudipati 
1318a36c61f9SKrishna Gudipati 
1319a36c61f9SKrishna Gudipati bfa_boolean_t
1320a36c61f9SKrishna Gudipati bfa_iocfc_is_operational(struct bfa_s *bfa)
1321a36c61f9SKrishna Gudipati {
1322a36c61f9SKrishna Gudipati 	return bfa_ioc_is_operational(&bfa->ioc) && bfa->iocfc.cfgdone;
1323a36c61f9SKrishna Gudipati }
1324a36c61f9SKrishna Gudipati 
13255fbe25c7SJing Huang /*
1326a36c61f9SKrishna Gudipati  * Return boot target port wwns -- read from boot information in flash.
1327a36c61f9SKrishna Gudipati  */
1328a36c61f9SKrishna Gudipati void
1329a36c61f9SKrishna Gudipati bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t *wwns)
1330a36c61f9SKrishna Gudipati {
1331a36c61f9SKrishna Gudipati 	struct bfa_iocfc_s *iocfc = &bfa->iocfc;
1332a36c61f9SKrishna Gudipati 	struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
1333a36c61f9SKrishna Gudipati 	int i;
1334a36c61f9SKrishna Gudipati 
1335a36c61f9SKrishna Gudipati 	if (cfgrsp->pbc_cfg.boot_enabled && cfgrsp->pbc_cfg.nbluns) {
1336a36c61f9SKrishna Gudipati 		bfa_trc(bfa, cfgrsp->pbc_cfg.nbluns);
1337a36c61f9SKrishna Gudipati 		*nwwns = cfgrsp->pbc_cfg.nbluns;
1338a36c61f9SKrishna Gudipati 		for (i = 0; i < cfgrsp->pbc_cfg.nbluns; i++)
1339a36c61f9SKrishna Gudipati 			wwns[i] = cfgrsp->pbc_cfg.blun[i].tgt_pwwn;
1340a36c61f9SKrishna Gudipati 
1341a36c61f9SKrishna Gudipati 		return;
1342a36c61f9SKrishna Gudipati 	}
1343a36c61f9SKrishna Gudipati 
1344a36c61f9SKrishna Gudipati 	*nwwns = cfgrsp->bootwwns.nwwns;
1345a36c61f9SKrishna Gudipati 	memcpy(wwns, cfgrsp->bootwwns.wwn, sizeof(cfgrsp->bootwwns.wwn));
1346a36c61f9SKrishna Gudipati }
1347a36c61f9SKrishna Gudipati 
1348a36c61f9SKrishna Gudipati int
1349a36c61f9SKrishna Gudipati bfa_iocfc_get_pbc_vports(struct bfa_s *bfa, struct bfi_pbc_vport_s *pbc_vport)
1350a36c61f9SKrishna Gudipati {
1351a36c61f9SKrishna Gudipati 	struct bfa_iocfc_s *iocfc = &bfa->iocfc;
1352a36c61f9SKrishna Gudipati 	struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
1353a36c61f9SKrishna Gudipati 
1354a36c61f9SKrishna Gudipati 	memcpy(pbc_vport, cfgrsp->pbc_cfg.vport, sizeof(cfgrsp->pbc_cfg.vport));
1355a36c61f9SKrishna Gudipati 	return cfgrsp->pbc_cfg.nvports;
1356a36c61f9SKrishna Gudipati }
1357a36c61f9SKrishna Gudipati 
1358a36c61f9SKrishna Gudipati 
13595fbe25c7SJing Huang /*
13607725ccfdSJing Huang  * Use this function query the memory requirement of the BFA library.
13617725ccfdSJing Huang  * This function needs to be called before bfa_attach() to get the
13627725ccfdSJing Huang  * memory required of the BFA layer for a given driver configuration.
13637725ccfdSJing Huang  *
13647725ccfdSJing Huang  * This call will fail, if the cap is out of range compared to pre-defined
13657725ccfdSJing Huang  * values within the BFA library
13667725ccfdSJing Huang  *
13677725ccfdSJing Huang  * @param[in] cfg -	pointer to bfa_ioc_cfg_t. Driver layer should indicate
13687725ccfdSJing Huang  *			its configuration in this structure.
13697725ccfdSJing Huang  *			The default values for struct bfa_iocfc_cfg_s can be
13707725ccfdSJing Huang  *			fetched using bfa_cfg_get_default() API.
13717725ccfdSJing Huang  *
13727725ccfdSJing Huang  *			If cap's boundary check fails, the library will use
13737725ccfdSJing Huang  *			the default bfa_cap_t values (and log a warning msg).
13747725ccfdSJing Huang  *
13757725ccfdSJing Huang  * @param[out] meminfo - pointer to bfa_meminfo_t. This content
13767725ccfdSJing Huang  *			indicates the memory type (see bfa_mem_type_t) and
13777725ccfdSJing Huang  *			amount of memory required.
13787725ccfdSJing Huang  *
13797725ccfdSJing Huang  *			Driver should allocate the memory, populate the
13807725ccfdSJing Huang  *			starting address for each block and provide the same
13817725ccfdSJing Huang  *			structure as input parameter to bfa_attach() call.
13827725ccfdSJing Huang  *
13834507025dSKrishna Gudipati  * @param[in] bfa -	pointer to the bfa structure, used while fetching the
13844507025dSKrishna Gudipati  *			dma, kva memory information of the bfa sub-modules.
13854507025dSKrishna Gudipati  *
13867725ccfdSJing Huang  * @return void
13877725ccfdSJing Huang  *
13887725ccfdSJing Huang  * Special Considerations: @note
13897725ccfdSJing Huang  */
13907725ccfdSJing Huang void
13914507025dSKrishna Gudipati bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,
13924507025dSKrishna Gudipati 		struct bfa_s *bfa)
13937725ccfdSJing Huang {
13947725ccfdSJing Huang 	int		i;
13954507025dSKrishna Gudipati 	struct bfa_mem_dma_s *port_dma = BFA_MEM_PORT_DMA(bfa);
13964507025dSKrishna Gudipati 	struct bfa_mem_dma_s *ablk_dma = BFA_MEM_ABLK_DMA(bfa);
1397148d6103SKrishna Gudipati 	struct bfa_mem_dma_s *cee_dma = BFA_MEM_CEE_DMA(bfa);
139851e569aaSKrishna Gudipati 	struct bfa_mem_dma_s *sfp_dma = BFA_MEM_SFP_DMA(bfa);
13995a54b1d5SKrishna Gudipati 	struct bfa_mem_dma_s *flash_dma = BFA_MEM_FLASH_DMA(bfa);
14003d7fc66dSKrishna Gudipati 	struct bfa_mem_dma_s *diag_dma = BFA_MEM_DIAG_DMA(bfa);
14013350d98dSKrishna Gudipati 	struct bfa_mem_dma_s *phy_dma = BFA_MEM_PHY_DMA(bfa);
14027725ccfdSJing Huang 
1403d4b671c5SJing Huang 	WARN_ON((cfg == NULL) || (meminfo == NULL));
14047725ccfdSJing Huang 
14056a18b167SJing Huang 	memset((void *)meminfo, 0, sizeof(struct bfa_meminfo_s));
14067725ccfdSJing Huang 
14074507025dSKrishna Gudipati 	/* Initialize the DMA & KVA meminfo queues */
14084507025dSKrishna Gudipati 	INIT_LIST_HEAD(&meminfo->dma_info.qe);
14094507025dSKrishna Gudipati 	INIT_LIST_HEAD(&meminfo->kva_info.qe);
14104507025dSKrishna Gudipati 
14114507025dSKrishna Gudipati 	bfa_iocfc_meminfo(cfg, meminfo, bfa);
14127725ccfdSJing Huang 
14137725ccfdSJing Huang 	for (i = 0; hal_mods[i]; i++)
14144507025dSKrishna Gudipati 		hal_mods[i]->meminfo(cfg, meminfo, bfa);
14157725ccfdSJing Huang 
14164507025dSKrishna Gudipati 	/* dma info setup */
14174507025dSKrishna Gudipati 	bfa_mem_dma_setup(meminfo, port_dma, bfa_port_meminfo());
14184507025dSKrishna Gudipati 	bfa_mem_dma_setup(meminfo, ablk_dma, bfa_ablk_meminfo());
1419148d6103SKrishna Gudipati 	bfa_mem_dma_setup(meminfo, cee_dma, bfa_cee_meminfo());
142051e569aaSKrishna Gudipati 	bfa_mem_dma_setup(meminfo, sfp_dma, bfa_sfp_meminfo());
14215a54b1d5SKrishna Gudipati 	bfa_mem_dma_setup(meminfo, flash_dma,
14225a54b1d5SKrishna Gudipati 			  bfa_flash_meminfo(cfg->drvcfg.min_cfg));
14233d7fc66dSKrishna Gudipati 	bfa_mem_dma_setup(meminfo, diag_dma, bfa_diag_meminfo());
14243350d98dSKrishna Gudipati 	bfa_mem_dma_setup(meminfo, phy_dma,
14253350d98dSKrishna Gudipati 			  bfa_phy_meminfo(cfg->drvcfg.min_cfg));
14267725ccfdSJing Huang }
14277725ccfdSJing Huang 
14285fbe25c7SJing Huang /*
14297725ccfdSJing Huang  * Use this function to do attach the driver instance with the BFA
14307725ccfdSJing Huang  * library. This function will not trigger any HW initialization
14317725ccfdSJing Huang  * process (which will be done in bfa_init() call)
14327725ccfdSJing Huang  *
14337725ccfdSJing Huang  * This call will fail, if the cap is out of range compared to
14347725ccfdSJing Huang  * pre-defined values within the BFA library
14357725ccfdSJing Huang  *
14367725ccfdSJing Huang  * @param[out]	bfa	Pointer to bfa_t.
14377725ccfdSJing Huang  * @param[in]	bfad	Opaque handle back to the driver's IOC structure
14387725ccfdSJing Huang  * @param[in]	cfg	Pointer to bfa_ioc_cfg_t. Should be same structure
14397725ccfdSJing Huang  *			that was used in bfa_cfg_get_meminfo().
14407725ccfdSJing Huang  * @param[in]	meminfo	Pointer to bfa_meminfo_t. The driver should
14417725ccfdSJing Huang  *			use the bfa_cfg_get_meminfo() call to
14427725ccfdSJing Huang  *			find the memory blocks required, allocate the
14437725ccfdSJing Huang  *			required memory and provide the starting addresses.
14447725ccfdSJing Huang  * @param[in]	pcidev	pointer to struct bfa_pcidev_s
14457725ccfdSJing Huang  *
14467725ccfdSJing Huang  * @return
14477725ccfdSJing Huang  * void
14487725ccfdSJing Huang  *
14497725ccfdSJing Huang  * Special Considerations:
14507725ccfdSJing Huang  *
14517725ccfdSJing Huang  * @note
14527725ccfdSJing Huang  *
14537725ccfdSJing Huang  */
14547725ccfdSJing Huang void
14557725ccfdSJing Huang bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
14567725ccfdSJing Huang 	       struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
14577725ccfdSJing Huang {
14587725ccfdSJing Huang 	int	i;
14594507025dSKrishna Gudipati 	struct bfa_mem_dma_s *dma_info, *dma_elem;
14604507025dSKrishna Gudipati 	struct bfa_mem_kva_s *kva_info, *kva_elem;
14614507025dSKrishna Gudipati 	struct list_head *dm_qe, *km_qe;
14627725ccfdSJing Huang 
14637725ccfdSJing Huang 	bfa->fcs = BFA_FALSE;
14647725ccfdSJing Huang 
1465d4b671c5SJing Huang 	WARN_ON((cfg == NULL) || (meminfo == NULL));
14667725ccfdSJing Huang 
14674507025dSKrishna Gudipati 	/* Initialize memory pointers for iterative allocation */
14684507025dSKrishna Gudipati 	dma_info = &meminfo->dma_info;
14694507025dSKrishna Gudipati 	dma_info->kva_curp = dma_info->kva;
14704507025dSKrishna Gudipati 	dma_info->dma_curp = dma_info->dma;
14714507025dSKrishna Gudipati 
14724507025dSKrishna Gudipati 	kva_info = &meminfo->kva_info;
14734507025dSKrishna Gudipati 	kva_info->kva_curp = kva_info->kva;
14744507025dSKrishna Gudipati 
14754507025dSKrishna Gudipati 	list_for_each(dm_qe, &dma_info->qe) {
14764507025dSKrishna Gudipati 		dma_elem = (struct bfa_mem_dma_s *) dm_qe;
14774507025dSKrishna Gudipati 		dma_elem->kva_curp = dma_elem->kva;
14784507025dSKrishna Gudipati 		dma_elem->dma_curp = dma_elem->dma;
14797725ccfdSJing Huang 	}
14807725ccfdSJing Huang 
14814507025dSKrishna Gudipati 	list_for_each(km_qe, &kva_info->qe) {
14824507025dSKrishna Gudipati 		kva_elem = (struct bfa_mem_kva_s *) km_qe;
14834507025dSKrishna Gudipati 		kva_elem->kva_curp = kva_elem->kva;
14844507025dSKrishna Gudipati 	}
14854507025dSKrishna Gudipati 
14864507025dSKrishna Gudipati 	bfa_iocfc_attach(bfa, bfad, cfg, pcidev);
14877725ccfdSJing Huang 
14887725ccfdSJing Huang 	for (i = 0; hal_mods[i]; i++)
14894507025dSKrishna Gudipati 		hal_mods[i]->attach(bfa, bfad, cfg, pcidev);
14907725ccfdSJing Huang 
14914507025dSKrishna Gudipati 	bfa_com_port_attach(bfa);
14924507025dSKrishna Gudipati 	bfa_com_ablk_attach(bfa);
1493148d6103SKrishna Gudipati 	bfa_com_cee_attach(bfa);
149451e569aaSKrishna Gudipati 	bfa_com_sfp_attach(bfa);
14955a54b1d5SKrishna Gudipati 	bfa_com_flash_attach(bfa, cfg->drvcfg.min_cfg);
14963d7fc66dSKrishna Gudipati 	bfa_com_diag_attach(bfa);
14973350d98dSKrishna Gudipati 	bfa_com_phy_attach(bfa, cfg->drvcfg.min_cfg);
14987725ccfdSJing Huang }
14997725ccfdSJing Huang 
15005fbe25c7SJing Huang /*
15017725ccfdSJing Huang  * Use this function to delete a BFA IOC. IOC should be stopped (by
15027725ccfdSJing Huang  * calling bfa_stop()) before this function call.
15037725ccfdSJing Huang  *
15047725ccfdSJing Huang  * @param[in] bfa - pointer to bfa_t.
15057725ccfdSJing Huang  *
15067725ccfdSJing Huang  * @return
15077725ccfdSJing Huang  * void
15087725ccfdSJing Huang  *
15097725ccfdSJing Huang  * Special Considerations:
15107725ccfdSJing Huang  *
15117725ccfdSJing Huang  * @note
15127725ccfdSJing Huang  */
15137725ccfdSJing Huang void
15147725ccfdSJing Huang bfa_detach(struct bfa_s *bfa)
15157725ccfdSJing Huang {
15167725ccfdSJing Huang 	int	i;
15177725ccfdSJing Huang 
15187725ccfdSJing Huang 	for (i = 0; hal_mods[i]; i++)
15197725ccfdSJing Huang 		hal_mods[i]->detach(bfa);
1520f7f73812SMaggie Zhang 	bfa_ioc_detach(&bfa->ioc);
15217725ccfdSJing Huang }
15227725ccfdSJing Huang 
15237725ccfdSJing Huang void
15247725ccfdSJing Huang bfa_comp_deq(struct bfa_s *bfa, struct list_head *comp_q)
15257725ccfdSJing Huang {
15267725ccfdSJing Huang 	INIT_LIST_HEAD(comp_q);
15277725ccfdSJing Huang 	list_splice_tail_init(&bfa->comp_q, comp_q);
15287725ccfdSJing Huang }
15297725ccfdSJing Huang 
15307725ccfdSJing Huang void
15317725ccfdSJing Huang bfa_comp_process(struct bfa_s *bfa, struct list_head *comp_q)
15327725ccfdSJing Huang {
15337725ccfdSJing Huang 	struct list_head		*qe;
15347725ccfdSJing Huang 	struct list_head		*qen;
15357725ccfdSJing Huang 	struct bfa_cb_qe_s	*hcb_qe;
15367725ccfdSJing Huang 
15377725ccfdSJing Huang 	list_for_each_safe(qe, qen, comp_q) {
15387725ccfdSJing Huang 		hcb_qe = (struct bfa_cb_qe_s *) qe;
15397725ccfdSJing Huang 		hcb_qe->cbfn(hcb_qe->cbarg, BFA_TRUE);
15407725ccfdSJing Huang 	}
15417725ccfdSJing Huang }
15427725ccfdSJing Huang 
15437725ccfdSJing Huang void
15447725ccfdSJing Huang bfa_comp_free(struct bfa_s *bfa, struct list_head *comp_q)
15457725ccfdSJing Huang {
15467725ccfdSJing Huang 	struct list_head		*qe;
15477725ccfdSJing Huang 	struct bfa_cb_qe_s	*hcb_qe;
15487725ccfdSJing Huang 
15497725ccfdSJing Huang 	while (!list_empty(comp_q)) {
15507725ccfdSJing Huang 		bfa_q_deq(comp_q, &qe);
15517725ccfdSJing Huang 		hcb_qe = (struct bfa_cb_qe_s *) qe;
15527725ccfdSJing Huang 		hcb_qe->cbfn(hcb_qe->cbarg, BFA_FALSE);
15537725ccfdSJing Huang 	}
15547725ccfdSJing Huang }
15557725ccfdSJing Huang 
15567725ccfdSJing Huang 
15575fbe25c7SJing Huang /*
15587725ccfdSJing Huang  * Return the list of PCI vendor/device id lists supported by this
15597725ccfdSJing Huang  * BFA instance.
15607725ccfdSJing Huang  */
15617725ccfdSJing Huang void
15627725ccfdSJing Huang bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids)
15637725ccfdSJing Huang {
15647725ccfdSJing Huang 	static struct bfa_pciid_s __pciids[] = {
15657725ccfdSJing Huang 		{BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G2P},
15667725ccfdSJing Huang 		{BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G1P},
15677725ccfdSJing Huang 		{BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_CT},
1568293f82d5SJing Huang 		{BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_CT_FC},
15697725ccfdSJing Huang 	};
15707725ccfdSJing Huang 
1571a36c61f9SKrishna Gudipati 	*npciids = sizeof(__pciids) / sizeof(__pciids[0]);
15727725ccfdSJing Huang 	*pciids = __pciids;
15737725ccfdSJing Huang }
15747725ccfdSJing Huang 
15755fbe25c7SJing Huang /*
15767725ccfdSJing Huang  * Use this function query the default struct bfa_iocfc_cfg_s value (compiled
15777725ccfdSJing Huang  * into BFA layer). The OS driver can then turn back and overwrite entries that
15787725ccfdSJing Huang  * have been configured by the user.
15797725ccfdSJing Huang  *
15807725ccfdSJing Huang  * @param[in] cfg - pointer to bfa_ioc_cfg_t
15817725ccfdSJing Huang  *
15827725ccfdSJing Huang  * @return
15837725ccfdSJing Huang  *	void
15847725ccfdSJing Huang  *
15857725ccfdSJing Huang  * Special Considerations:
15867725ccfdSJing Huang  * note
15877725ccfdSJing Huang  */
15887725ccfdSJing Huang void
15897725ccfdSJing Huang bfa_cfg_get_default(struct bfa_iocfc_cfg_s *cfg)
15907725ccfdSJing Huang {
15917725ccfdSJing Huang 	cfg->fwcfg.num_fabrics = DEF_CFG_NUM_FABRICS;
15927725ccfdSJing Huang 	cfg->fwcfg.num_lports = DEF_CFG_NUM_LPORTS;
15937725ccfdSJing Huang 	cfg->fwcfg.num_rports = DEF_CFG_NUM_RPORTS;
15947725ccfdSJing Huang 	cfg->fwcfg.num_ioim_reqs = DEF_CFG_NUM_IOIM_REQS;
15957725ccfdSJing Huang 	cfg->fwcfg.num_tskim_reqs = DEF_CFG_NUM_TSKIM_REQS;
15967725ccfdSJing Huang 	cfg->fwcfg.num_fcxp_reqs = DEF_CFG_NUM_FCXP_REQS;
15977725ccfdSJing Huang 	cfg->fwcfg.num_uf_bufs = DEF_CFG_NUM_UF_BUFS;
15987725ccfdSJing Huang 	cfg->fwcfg.num_cqs = DEF_CFG_NUM_CQS;
1599e2187d7fSKrishna Gudipati 	cfg->fwcfg.num_fwtio_reqs = 0;
16007725ccfdSJing Huang 
16017725ccfdSJing Huang 	cfg->drvcfg.num_reqq_elems = DEF_CFG_NUM_REQQ_ELEMS;
16027725ccfdSJing Huang 	cfg->drvcfg.num_rspq_elems = DEF_CFG_NUM_RSPQ_ELEMS;
16037725ccfdSJing Huang 	cfg->drvcfg.num_sgpgs = DEF_CFG_NUM_SGPGS;
16047725ccfdSJing Huang 	cfg->drvcfg.num_sboot_tgts = DEF_CFG_NUM_SBOOT_TGTS;
16057725ccfdSJing Huang 	cfg->drvcfg.num_sboot_luns = DEF_CFG_NUM_SBOOT_LUNS;
16067725ccfdSJing Huang 	cfg->drvcfg.path_tov = BFA_FCPIM_PATHTOV_DEF;
16077725ccfdSJing Huang 	cfg->drvcfg.ioc_recover = BFA_FALSE;
16087725ccfdSJing Huang 	cfg->drvcfg.delay_comp = BFA_FALSE;
16097725ccfdSJing Huang 
16107725ccfdSJing Huang }
16117725ccfdSJing Huang 
16127725ccfdSJing Huang void
16137725ccfdSJing Huang bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg)
16147725ccfdSJing Huang {
16157725ccfdSJing Huang 	bfa_cfg_get_default(cfg);
16167725ccfdSJing Huang 	cfg->fwcfg.num_ioim_reqs   = BFA_IOIM_MIN;
16177725ccfdSJing Huang 	cfg->fwcfg.num_tskim_reqs  = BFA_TSKIM_MIN;
16187725ccfdSJing Huang 	cfg->fwcfg.num_fcxp_reqs   = BFA_FCXP_MIN;
16197725ccfdSJing Huang 	cfg->fwcfg.num_uf_bufs     = BFA_UF_MIN;
16207725ccfdSJing Huang 	cfg->fwcfg.num_rports      = BFA_RPORT_MIN;
1621e2187d7fSKrishna Gudipati 	cfg->fwcfg.num_fwtio_reqs = 0;
16227725ccfdSJing Huang 
16237725ccfdSJing Huang 	cfg->drvcfg.num_sgpgs      = BFA_SGPG_MIN;
16247725ccfdSJing Huang 	cfg->drvcfg.num_reqq_elems = BFA_REQQ_NELEMS_MIN;
16257725ccfdSJing Huang 	cfg->drvcfg.num_rspq_elems = BFA_RSPQ_NELEMS_MIN;
16267725ccfdSJing Huang 	cfg->drvcfg.min_cfg	   = BFA_TRUE;
16277725ccfdSJing Huang }
1628