Commit | Line | Data |
---|---|---|
7725ccfd JH |
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 | } | |
0a20de44 KG |
402 | |
403 | /** | |
404 | * Reset hw semaphore & usage cnt regs and initialize. | |
405 | */ | |
406 | void | |
407 | bfa_chip_reset(struct bfa_s *bfa) | |
408 | { | |
409 | bfa_ioc_ownership_reset(&bfa->ioc); | |
410 | bfa_ioc_pll_init(&bfa->ioc); | |
411 | } | |
7725ccfd | 412 | #endif |