aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bfa/bfa_core.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-10-29 04:02:15 -0400
committerIngo Molnar <mingo@elte.hu>2009-10-29 04:02:20 -0400
commit9de09ace8d518141a4375e1d216ab64db4377799 (patch)
treeda8e7a77f4ea91eb3bb73fc6da72ecf8c99e1c16 /drivers/scsi/bfa/bfa_core.c
parent1beee96bae0daf7f491356777c3080cc436950f5 (diff)
parent6d3f1e12f46a2f9a1bb7e7aa433df8dd31ce5647 (diff)
Merge branch 'tracing/urgent' into tracing/core
Merge reason: Pick up fixes and move base from -rc1 to -rc5. Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/scsi/bfa/bfa_core.c')
-rw-r--r--drivers/scsi/bfa/bfa_core.c402
1 files changed, 402 insertions, 0 deletions
diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c
new file mode 100644
index 000000000000..44e2d1155c51
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_core.c
@@ -0,0 +1,402 @@
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 */
68void
69bfa_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 */
118void
119bfa_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 */
158void
159bfa_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
170void
171bfa_init_trc(struct bfa_s *bfa, struct bfa_trc_mod_s *trcmod)
172{
173 bfa->trcmod = trcmod;
174}
175
176
177void
178bfa_init_log(struct bfa_s *bfa, struct bfa_log_mod_s *logmod)
179{
180 bfa->logm = logmod;
181}
182
183
184void
185bfa_init_aen(struct bfa_s *bfa, struct bfa_aen_s *aen)
186{
187 bfa->aen = aen;
188}
189
190void
191bfa_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 */
213void
214bfa_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 */
227void
228bfa_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 */
248void
249bfa_stop(struct bfa_s *bfa)
250{
251 bfa_iocfc_stop(bfa);
252}
253
254void
255bfa_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
261void
262bfa_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
274void
275bfa_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
287void
288bfa_attach_fcs(struct bfa_s *bfa)
289{
290 bfa->fcs = BFA_TRUE;
291}
292
293/**
294 * Periodic timer heart beat from driver
295 */
296void
297bfa_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 */
307void
308bfa_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 */
333void
334bfa_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
356void
357bfa_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
372void
373bfa_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 */
381bfa_status_t
382bfa_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 */
397bfa_status_t
398bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen)
399{
400 return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen);
401}
402#endif