xref: /openbmc/linux/drivers/scsi/bfa/bfa_core.c (revision b6dcefde)
1 /*
2  * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3  * All rights reserved
4  * www.brocade.com
5  *
6  * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License (GPL) Version 2 as
10  * published by the Free Software Foundation
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  */
17 
18 #include <bfa.h>
19 #include <defs/bfa_defs_pci.h>
20 #include <cs/bfa_debug.h>
21 #include <bfa_iocfc.h>
22 
23 #define DEF_CFG_NUM_FABRICS         1
24 #define DEF_CFG_NUM_LPORTS          256
25 #define DEF_CFG_NUM_CQS             4
26 #define DEF_CFG_NUM_IOIM_REQS       (BFA_IOIM_MAX)
27 #define DEF_CFG_NUM_TSKIM_REQS      128
28 #define DEF_CFG_NUM_FCXP_REQS       64
29 #define DEF_CFG_NUM_UF_BUFS         64
30 #define DEF_CFG_NUM_RPORTS          1024
31 #define DEF_CFG_NUM_ITNIMS          (DEF_CFG_NUM_RPORTS)
32 #define DEF_CFG_NUM_TINS            256
33 
34 #define DEF_CFG_NUM_SGPGS           2048
35 #define DEF_CFG_NUM_REQQ_ELEMS      256
36 #define DEF_CFG_NUM_RSPQ_ELEMS      64
37 #define DEF_CFG_NUM_SBOOT_TGTS      16
38 #define DEF_CFG_NUM_SBOOT_LUNS      16
39 
40 /**
41  * Use this function query the memory requirement of the BFA library.
42  * This function needs to be called before bfa_attach() to get the
43  * memory required of the BFA layer for a given driver configuration.
44  *
45  * This call will fail, if the cap is out of range compared to pre-defined
46  * values within the BFA library
47  *
48  * @param[in] cfg - 	pointer to bfa_ioc_cfg_t. Driver layer should indicate
49  * 			its configuration in this structure.
50  *			The default values for struct bfa_iocfc_cfg_s can be
51  *			fetched using bfa_cfg_get_default() API.
52  *
53  * 			If cap's boundary check fails, the library will use
54  *			the default bfa_cap_t values (and log a warning msg).
55  *
56  * @param[out] meminfo - pointer to bfa_meminfo_t. This content
57  * 			indicates the memory type (see bfa_mem_type_t) and
58  *			amount of memory required.
59  *
60  *			Driver should allocate the memory, populate the
61  *			starting address for each block and provide the same
62  *			structure as input parameter to bfa_attach() call.
63  *
64  * @return void
65  *
66  * Special Considerations: @note
67  */
68 void
69 bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo)
70 {
71 	int             i;
72 	u32        km_len = 0, dm_len = 0;
73 
74 	bfa_assert((cfg != NULL) && (meminfo != NULL));
75 
76 	bfa_os_memset((void *)meminfo, 0, sizeof(struct bfa_meminfo_s));
77 	meminfo->meminfo[BFA_MEM_TYPE_KVA - 1].mem_type =
78 		BFA_MEM_TYPE_KVA;
79 	meminfo->meminfo[BFA_MEM_TYPE_DMA - 1].mem_type =
80 		BFA_MEM_TYPE_DMA;
81 
82 	bfa_iocfc_meminfo(cfg, &km_len, &dm_len);
83 
84 	for (i = 0; hal_mods[i]; i++)
85 		hal_mods[i]->meminfo(cfg, &km_len, &dm_len);
86 
87 
88 	meminfo->meminfo[BFA_MEM_TYPE_KVA - 1].mem_len = km_len;
89 	meminfo->meminfo[BFA_MEM_TYPE_DMA - 1].mem_len = dm_len;
90 }
91 
92 /**
93  * Use this function to do attach the driver instance with the BFA
94  * library. This function will not trigger any HW initialization
95  * process (which will be done in bfa_init() call)
96  *
97  * This call will fail, if the cap is out of range compared to
98  * pre-defined values within the BFA library
99  *
100  * @param[out]	bfa	Pointer to bfa_t.
101  * @param[in]	bfad 	Opaque handle back to the driver's IOC structure
102  * @param[in]	cfg	Pointer to bfa_ioc_cfg_t. Should be same structure
103  * 			that was used in bfa_cfg_get_meminfo().
104  * @param[in] 	meminfo Pointer to bfa_meminfo_t. The driver should
105  * 			use the bfa_cfg_get_meminfo() call to
106  * 			find the memory blocks required, allocate the
107  * 			required memory and provide the starting addresses.
108  * @param[in] 	pcidev	pointer to struct bfa_pcidev_s
109  *
110  * @return
111  * void
112  *
113  * Special Considerations:
114  *
115  * @note
116  *
117  */
118 void
119 bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
120 	       struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
121 {
122 	int             i;
123 	struct bfa_mem_elem_s *melem;
124 
125 	bfa->fcs = BFA_FALSE;
126 
127 	bfa_assert((cfg != NULL) && (meminfo != NULL));
128 
129 	/**
130 	 * initialize all memory pointers for iterative allocation
131 	 */
132 	for (i = 0; i < BFA_MEM_TYPE_MAX; i++) {
133 		melem = meminfo->meminfo + i;
134 		melem->kva_curp = melem->kva;
135 		melem->dma_curp = melem->dma;
136 	}
137 
138 	bfa_iocfc_attach(bfa, bfad, cfg, meminfo, pcidev);
139 
140 	for (i = 0; hal_mods[i]; i++)
141 		hal_mods[i]->attach(bfa, bfad, cfg, meminfo, pcidev);
142 
143 }
144 
145 /**
146  * Use this function to delete a BFA IOC. IOC should be stopped (by
147  * calling bfa_stop()) before this function call.
148  *
149  * @param[in] bfa - pointer to bfa_t.
150  *
151  * @return
152  * void
153  *
154  * Special Considerations:
155  *
156  * @note
157  */
158 void
159 bfa_detach(struct bfa_s *bfa)
160 {
161 	int	i;
162 
163 	for (i = 0; hal_mods[i]; i++)
164 		hal_mods[i]->detach(bfa);
165 
166 	bfa_iocfc_detach(bfa);
167 }
168 
169 
170 void
171 bfa_init_trc(struct bfa_s *bfa, struct bfa_trc_mod_s *trcmod)
172 {
173 	bfa->trcmod = trcmod;
174 }
175 
176 
177 void
178 bfa_init_log(struct bfa_s *bfa, struct bfa_log_mod_s *logmod)
179 {
180 	bfa->logm = logmod;
181 }
182 
183 
184 void
185 bfa_init_aen(struct bfa_s *bfa, struct bfa_aen_s *aen)
186 {
187 	bfa->aen = aen;
188 }
189 
190 void
191 bfa_init_plog(struct bfa_s *bfa, struct bfa_plog_s *plog)
192 {
193 	bfa->plog = plog;
194 }
195 
196 /**
197  * Initialize IOC.
198  *
199  * This function will return immediately, when the IOC initialization is
200  * completed, the bfa_cb_init() will be called.
201  *
202  * @param[in]	bfa	instance
203  *
204  * @return void
205  *
206  * Special Considerations:
207  *
208  * @note
209  * When this function returns, the driver should register the interrupt service
210  * routine(s) and enable the device interrupts. If this is not done,
211  * bfa_cb_init() will never get called
212  */
213 void
214 bfa_init(struct bfa_s *bfa)
215 {
216 	bfa_iocfc_init(bfa);
217 }
218 
219 /**
220  * Use this function initiate the IOC configuration setup. This function
221  * will return immediately.
222  *
223  * @param[in]	bfa	instance
224  *
225  * @return None
226  */
227 void
228 bfa_start(struct bfa_s *bfa)
229 {
230 	bfa_iocfc_start(bfa);
231 }
232 
233 /**
234  * Use this function quiese the IOC. This function will return immediately,
235  * when the IOC is actually stopped, the bfa_cb_stop() will be called.
236  *
237  * @param[in] 	bfa - pointer to bfa_t.
238  *
239  * @return None
240  *
241  * Special Considerations:
242  * bfa_cb_stop() could be called before or after bfa_stop() returns.
243  *
244  * @note
245  * In case of any failure, we could handle it automatically by doing a
246  * reset and then succeed the bfa_stop() call.
247  */
248 void
249 bfa_stop(struct bfa_s *bfa)
250 {
251 	bfa_iocfc_stop(bfa);
252 }
253 
254 void
255 bfa_comp_deq(struct bfa_s *bfa, struct list_head *comp_q)
256 {
257 	INIT_LIST_HEAD(comp_q);
258 	list_splice_tail_init(&bfa->comp_q, comp_q);
259 }
260 
261 void
262 bfa_comp_process(struct bfa_s *bfa, struct list_head *comp_q)
263 {
264 	struct list_head        *qe;
265 	struct list_head        *qen;
266 	struct bfa_cb_qe_s   *hcb_qe;
267 
268 	list_for_each_safe(qe, qen, comp_q) {
269 		hcb_qe = (struct bfa_cb_qe_s *) qe;
270 		hcb_qe->cbfn(hcb_qe->cbarg, BFA_TRUE);
271 	}
272 }
273 
274 void
275 bfa_comp_free(struct bfa_s *bfa, struct list_head *comp_q)
276 {
277 	struct list_head        *qe;
278 	struct bfa_cb_qe_s   *hcb_qe;
279 
280 	while (!list_empty(comp_q)) {
281 		bfa_q_deq(comp_q, &qe);
282 		hcb_qe = (struct bfa_cb_qe_s *) qe;
283 		hcb_qe->cbfn(hcb_qe->cbarg, BFA_FALSE);
284 	}
285 }
286 
287 void
288 bfa_attach_fcs(struct bfa_s *bfa)
289 {
290 	bfa->fcs = BFA_TRUE;
291 }
292 
293 /**
294  * Periodic timer heart beat from driver
295  */
296 void
297 bfa_timer_tick(struct bfa_s *bfa)
298 {
299 	bfa_timer_beat(&bfa->timer_mod);
300 }
301 
302 #ifndef BFA_BIOS_BUILD
303 /**
304  * Return the list of PCI vendor/device id lists supported by this
305  * BFA instance.
306  */
307 void
308 bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids)
309 {
310 	static struct bfa_pciid_s __pciids[] = {
311 		{BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G2P},
312 		{BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G1P},
313 		{BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_CT},
314 	};
315 
316 	*npciids = sizeof(__pciids) / sizeof(__pciids[0]);
317 	*pciids = __pciids;
318 }
319 
320 /**
321  * Use this function query the default struct bfa_iocfc_cfg_s value (compiled
322  * into BFA layer). The OS driver can then turn back and overwrite entries that
323  * have been configured by the user.
324  *
325  * @param[in] cfg - pointer to bfa_ioc_cfg_t
326  *
327  * @return
328  *	void
329  *
330  * Special Considerations:
331  * 	note
332  */
333 void
334 bfa_cfg_get_default(struct bfa_iocfc_cfg_s *cfg)
335 {
336 	cfg->fwcfg.num_fabrics = DEF_CFG_NUM_FABRICS;
337 	cfg->fwcfg.num_lports = DEF_CFG_NUM_LPORTS;
338 	cfg->fwcfg.num_rports = DEF_CFG_NUM_RPORTS;
339 	cfg->fwcfg.num_ioim_reqs = DEF_CFG_NUM_IOIM_REQS;
340 	cfg->fwcfg.num_tskim_reqs = DEF_CFG_NUM_TSKIM_REQS;
341 	cfg->fwcfg.num_fcxp_reqs = DEF_CFG_NUM_FCXP_REQS;
342 	cfg->fwcfg.num_uf_bufs = DEF_CFG_NUM_UF_BUFS;
343 	cfg->fwcfg.num_cqs = DEF_CFG_NUM_CQS;
344 
345 	cfg->drvcfg.num_reqq_elems = DEF_CFG_NUM_REQQ_ELEMS;
346 	cfg->drvcfg.num_rspq_elems = DEF_CFG_NUM_RSPQ_ELEMS;
347 	cfg->drvcfg.num_sgpgs = DEF_CFG_NUM_SGPGS;
348 	cfg->drvcfg.num_sboot_tgts = DEF_CFG_NUM_SBOOT_TGTS;
349 	cfg->drvcfg.num_sboot_luns = DEF_CFG_NUM_SBOOT_LUNS;
350 	cfg->drvcfg.path_tov = BFA_FCPIM_PATHTOV_DEF;
351 	cfg->drvcfg.ioc_recover = BFA_FALSE;
352 	cfg->drvcfg.delay_comp = BFA_FALSE;
353 
354 }
355 
356 void
357 bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg)
358 {
359 	bfa_cfg_get_default(cfg);
360 	cfg->fwcfg.num_ioim_reqs   = BFA_IOIM_MIN;
361 	cfg->fwcfg.num_tskim_reqs  = BFA_TSKIM_MIN;
362 	cfg->fwcfg.num_fcxp_reqs   = BFA_FCXP_MIN;
363 	cfg->fwcfg.num_uf_bufs     = BFA_UF_MIN;
364 	cfg->fwcfg.num_rports      = BFA_RPORT_MIN;
365 
366 	cfg->drvcfg.num_sgpgs      = BFA_SGPG_MIN;
367 	cfg->drvcfg.num_reqq_elems = BFA_REQQ_NELEMS_MIN;
368 	cfg->drvcfg.num_rspq_elems = BFA_RSPQ_NELEMS_MIN;
369 	cfg->drvcfg.min_cfg        = BFA_TRUE;
370 }
371 
372 void
373 bfa_get_attr(struct bfa_s *bfa, struct bfa_ioc_attr_s *ioc_attr)
374 {
375 	bfa_ioc_get_attr(&bfa->ioc, ioc_attr);
376 }
377 
378 /**
379  * Retrieve firmware trace information on IOC failure.
380  */
381 bfa_status_t
382 bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen)
383 {
384 	return bfa_ioc_debug_fwsave(&bfa->ioc, trcdata, trclen);
385 }
386 
387 /**
388  * 		Fetch firmware trace data.
389  *
390  * @param[in]		bfa			BFA instance
391  * @param[out]		trcdata		Firmware trace buffer
392  * @param[in,out]	trclen		Firmware trace buffer len
393  *
394  * @retval BFA_STATUS_OK			Firmware trace is fetched.
395  * @retval BFA_STATUS_INPROGRESS	Firmware trace fetch is in progress.
396  */
397 bfa_status_t
398 bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen)
399 {
400 	return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen);
401 }
402 #endif
403