1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. |
4 | * Copyright (c) 2014- QLogic Corporation. |
5 | * All rights reserved |
6 | * www.qlogic.com |
7 | * |
8 | * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter. |
9 | */ |
10 | |
11 | /* |
12 | * bfad.c Linux driver PCI interface module. |
13 | */ |
14 | #include <linux/module.h> |
15 | #include <linux/kthread.h> |
16 | #include <linux/errno.h> |
17 | #include <linux/sched.h> |
18 | #include <linux/init.h> |
19 | #include <linux/fs.h> |
20 | #include <linux/pci.h> |
21 | #include <linux/firmware.h> |
22 | #include <linux/uaccess.h> |
23 | #include <asm/fcntl.h> |
24 | |
25 | #include "bfad_drv.h" |
26 | #include "bfad_im.h" |
27 | #include "bfa_fcs.h" |
28 | #include "bfa_defs.h" |
29 | #include "bfa.h" |
30 | |
31 | BFA_TRC_FILE(LDRV, BFAD); |
32 | DEFINE_MUTEX(bfad_mutex); |
33 | LIST_HEAD(bfad_list); |
34 | |
35 | static int bfad_inst; |
36 | static int num_sgpgs_parm; |
37 | int supported_fc4s; |
38 | char *host_name, *os_name, *os_patch; |
39 | int num_rports, num_ios, num_tms; |
40 | int num_fcxps, num_ufbufs; |
41 | int reqq_size, rspq_size, num_sgpgs; |
42 | int rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT; |
43 | int bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH; |
44 | int bfa_io_max_sge = BFAD_IO_MAX_SGE; |
45 | int bfa_log_level = 3; /* WARNING log level */ |
46 | int ioc_auto_recover = BFA_TRUE; |
47 | int bfa_linkup_delay = -1; |
48 | int fdmi_enable = BFA_TRUE; |
49 | int pcie_max_read_reqsz; |
50 | int bfa_debugfs_enable = 1; |
51 | int msix_disable_cb = 0, msix_disable_ct = 0; |
52 | int max_xfer_size = BFAD_MAX_SECTORS >> 1; |
53 | static int max_rport_logins = BFA_FCS_MAX_RPORT_LOGINS; |
54 | |
55 | /* Firmware releated */ |
56 | u32 bfi_image_cb_size, bfi_image_ct_size, bfi_image_ct2_size; |
57 | u32 *bfi_image_cb, *bfi_image_ct, *bfi_image_ct2; |
58 | |
59 | #define BFAD_FW_FILE_CB "cbfw-3.2.5.1.bin" |
60 | #define BFAD_FW_FILE_CT "ctfw-3.2.5.1.bin" |
61 | #define BFAD_FW_FILE_CT2 "ct2fw-3.2.5.1.bin" |
62 | |
63 | static u32 *bfad_load_fwimg(struct pci_dev *pdev); |
64 | static void bfad_free_fwimg(void); |
65 | static void bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image, |
66 | u32 *bfi_image_size, char *fw_name); |
67 | |
68 | static const char *msix_name_ct[] = { |
69 | "ctrl" , |
70 | "cpe0" , "cpe1" , "cpe2" , "cpe3" , |
71 | "rme0" , "rme1" , "rme2" , "rme3" }; |
72 | |
73 | static const char *msix_name_cb[] = { |
74 | "cpe0" , "cpe1" , "cpe2" , "cpe3" , |
75 | "rme0" , "rme1" , "rme2" , "rme3" , |
76 | "eemc" , "elpu0" , "elpu1" , "epss" , "mlpu" }; |
77 | |
78 | MODULE_FIRMWARE(BFAD_FW_FILE_CB); |
79 | MODULE_FIRMWARE(BFAD_FW_FILE_CT); |
80 | MODULE_FIRMWARE(BFAD_FW_FILE_CT2); |
81 | |
82 | module_param(os_name, charp, S_IRUGO | S_IWUSR); |
83 | MODULE_PARM_DESC(os_name, "OS name of the hba host machine" ); |
84 | module_param(os_patch, charp, S_IRUGO | S_IWUSR); |
85 | MODULE_PARM_DESC(os_patch, "OS patch level of the hba host machine" ); |
86 | module_param(host_name, charp, S_IRUGO | S_IWUSR); |
87 | MODULE_PARM_DESC(host_name, "Hostname of the hba host machine" ); |
88 | module_param(num_rports, int, S_IRUGO | S_IWUSR); |
89 | MODULE_PARM_DESC(num_rports, "Max number of rports supported per port " |
90 | "(physical/logical), default=1024" ); |
91 | module_param(num_ios, int, S_IRUGO | S_IWUSR); |
92 | MODULE_PARM_DESC(num_ios, "Max number of ioim requests, default=2000" ); |
93 | module_param(num_tms, int, S_IRUGO | S_IWUSR); |
94 | MODULE_PARM_DESC(num_tms, "Max number of task im requests, default=128" ); |
95 | module_param(num_fcxps, int, S_IRUGO | S_IWUSR); |
96 | MODULE_PARM_DESC(num_fcxps, "Max number of fcxp requests, default=64" ); |
97 | module_param(num_ufbufs, int, S_IRUGO | S_IWUSR); |
98 | MODULE_PARM_DESC(num_ufbufs, "Max number of unsolicited frame " |
99 | "buffers, default=64" ); |
100 | module_param(reqq_size, int, S_IRUGO | S_IWUSR); |
101 | MODULE_PARM_DESC(reqq_size, "Max number of request queue elements, " |
102 | "default=256" ); |
103 | module_param(rspq_size, int, S_IRUGO | S_IWUSR); |
104 | MODULE_PARM_DESC(rspq_size, "Max number of response queue elements, " |
105 | "default=64" ); |
106 | module_param(num_sgpgs, int, S_IRUGO | S_IWUSR); |
107 | MODULE_PARM_DESC(num_sgpgs, "Number of scatter/gather pages, default=2048" ); |
108 | module_param(rport_del_timeout, int, S_IRUGO | S_IWUSR); |
109 | MODULE_PARM_DESC(rport_del_timeout, "Rport delete timeout, default=90 secs, " |
110 | "Range[>0]" ); |
111 | module_param(bfa_lun_queue_depth, int, S_IRUGO | S_IWUSR); |
112 | MODULE_PARM_DESC(bfa_lun_queue_depth, "Lun queue depth, default=32, Range[>0]" ); |
113 | module_param(bfa_io_max_sge, int, S_IRUGO | S_IWUSR); |
114 | MODULE_PARM_DESC(bfa_io_max_sge, "Max io scatter/gather elements, default=255" ); |
115 | module_param(bfa_log_level, int, S_IRUGO | S_IWUSR); |
116 | MODULE_PARM_DESC(bfa_log_level, "Driver log level, default=3, " |
117 | "Range[Critical:1|Error:2|Warning:3|Info:4]" ); |
118 | module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR); |
119 | MODULE_PARM_DESC(ioc_auto_recover, "IOC auto recovery, default=1, " |
120 | "Range[off:0|on:1]" ); |
121 | module_param(bfa_linkup_delay, int, S_IRUGO | S_IWUSR); |
122 | MODULE_PARM_DESC(bfa_linkup_delay, "Link up delay, default=30 secs for " |
123 | "boot port. Otherwise 10 secs in RHEL4 & 0 for " |
124 | "[RHEL5, SLES10, ESX40] Range[>0]" ); |
125 | module_param(msix_disable_cb, int, S_IRUGO | S_IWUSR); |
126 | MODULE_PARM_DESC(msix_disable_cb, "Disable Message Signaled Interrupts for QLogic-415/425/815/825 cards, default=0 Range[false:0|true:1]" ); |
127 | module_param(msix_disable_ct, int, S_IRUGO | S_IWUSR); |
128 | MODULE_PARM_DESC(msix_disable_ct, "Disable Message Signaled Interrupts if possible for QLogic-1010/1020/804/1007/902/1741 cards, default=0, Range[false:0|true:1]" ); |
129 | module_param(fdmi_enable, int, S_IRUGO | S_IWUSR); |
130 | MODULE_PARM_DESC(fdmi_enable, "Enables fdmi registration, default=1, " |
131 | "Range[false:0|true:1]" ); |
132 | module_param(pcie_max_read_reqsz, int, S_IRUGO | S_IWUSR); |
133 | MODULE_PARM_DESC(pcie_max_read_reqsz, "PCIe max read request size, default=0 " |
134 | "(use system setting), Range[128|256|512|1024|2048|4096]" ); |
135 | module_param(bfa_debugfs_enable, int, S_IRUGO | S_IWUSR); |
136 | MODULE_PARM_DESC(bfa_debugfs_enable, "Enables debugfs feature, default=1," |
137 | " Range[false:0|true:1]" ); |
138 | module_param(max_xfer_size, int, S_IRUGO | S_IWUSR); |
139 | MODULE_PARM_DESC(max_xfer_size, "default=32MB," |
140 | " Range[64k|128k|256k|512k|1024k|2048k]" ); |
141 | module_param(max_rport_logins, int, S_IRUGO | S_IWUSR); |
142 | MODULE_PARM_DESC(max_rport_logins, "Max number of logins to initiator and target rports on a port (physical/logical), default=1024" ); |
143 | |
144 | static void |
145 | bfad_sm_uninit(struct bfad_s *bfad, enum bfad_sm_event event); |
146 | static void |
147 | bfad_sm_created(struct bfad_s *bfad, enum bfad_sm_event event); |
148 | static void |
149 | bfad_sm_initializing(struct bfad_s *bfad, enum bfad_sm_event event); |
150 | static void |
151 | bfad_sm_operational(struct bfad_s *bfad, enum bfad_sm_event event); |
152 | static void |
153 | bfad_sm_stopping(struct bfad_s *bfad, enum bfad_sm_event event); |
154 | static void |
155 | bfad_sm_failed(struct bfad_s *bfad, enum bfad_sm_event event); |
156 | static void |
157 | bfad_sm_fcs_exit(struct bfad_s *bfad, enum bfad_sm_event event); |
158 | |
159 | /* |
160 | * Beginning state for the driver instance, awaiting the pci_probe event |
161 | */ |
162 | static void |
163 | bfad_sm_uninit(struct bfad_s *bfad, enum bfad_sm_event event) |
164 | { |
165 | bfa_trc(bfad, event); |
166 | |
167 | switch (event) { |
168 | case BFAD_E_CREATE: |
169 | bfa_sm_set_state(bfad, bfad_sm_created); |
170 | bfad->bfad_tsk = kthread_create(bfad_worker, (void *) bfad, |
171 | "%s" , "bfad_worker" ); |
172 | if (IS_ERR(ptr: bfad->bfad_tsk)) { |
173 | printk(KERN_INFO "bfad[%d]: Kernel thread " |
174 | "creation failed!\n" , bfad->inst_no); |
175 | bfa_sm_send_event(bfad, BFAD_E_KTHREAD_CREATE_FAILED); |
176 | } |
177 | bfa_sm_send_event(bfad, BFAD_E_INIT); |
178 | break; |
179 | |
180 | case BFAD_E_STOP: |
181 | /* Ignore stop; already in uninit */ |
182 | break; |
183 | |
184 | default: |
185 | bfa_sm_fault(bfad, event); |
186 | } |
187 | } |
188 | |
189 | /* |
190 | * Driver Instance is created, awaiting event INIT to initialize the bfad |
191 | */ |
192 | static void |
193 | bfad_sm_created(struct bfad_s *bfad, enum bfad_sm_event event) |
194 | { |
195 | unsigned long flags; |
196 | bfa_status_t ret; |
197 | |
198 | bfa_trc(bfad, event); |
199 | |
200 | switch (event) { |
201 | case BFAD_E_INIT: |
202 | bfa_sm_set_state(bfad, bfad_sm_initializing); |
203 | |
204 | init_completion(x: &bfad->comp); |
205 | |
206 | /* Enable Interrupt and wait bfa_init completion */ |
207 | if (bfad_setup_intr(bfad)) { |
208 | printk(KERN_WARNING "bfad%d: bfad_setup_intr failed\n" , |
209 | bfad->inst_no); |
210 | bfa_sm_send_event(bfad, BFAD_E_INIT_FAILED); |
211 | break; |
212 | } |
213 | |
214 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
215 | bfa_iocfc_init(bfa: &bfad->bfa); |
216 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
217 | |
218 | /* Set up interrupt handler for each vectors */ |
219 | if ((bfad->bfad_flags & BFAD_MSIX_ON) && |
220 | bfad_install_msix_handler(bfad)) { |
221 | printk(KERN_WARNING "%s: install_msix failed, bfad%d\n" , |
222 | __func__, bfad->inst_no); |
223 | } |
224 | |
225 | bfad_init_timer(bfad); |
226 | |
227 | wait_for_completion(&bfad->comp); |
228 | |
229 | if ((bfad->bfad_flags & BFAD_HAL_INIT_DONE)) { |
230 | bfa_sm_send_event(bfad, BFAD_E_INIT_SUCCESS); |
231 | } else { |
232 | printk(KERN_WARNING |
233 | "bfa %s: bfa init failed\n" , |
234 | bfad->pci_name); |
235 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
236 | bfa_fcs_init(fcs: &bfad->bfa_fcs); |
237 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
238 | |
239 | ret = bfad_cfg_pport(bfad, role: BFA_LPORT_ROLE_FCP_IM); |
240 | if (ret != BFA_STATUS_OK) { |
241 | init_completion(x: &bfad->comp); |
242 | |
243 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
244 | bfad->pport.flags |= BFAD_PORT_DELETE; |
245 | bfa_fcs_exit(fcs: &bfad->bfa_fcs); |
246 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
247 | |
248 | wait_for_completion(&bfad->comp); |
249 | |
250 | bfa_sm_send_event(bfad, BFAD_E_INIT_FAILED); |
251 | break; |
252 | } |
253 | bfad->bfad_flags |= BFAD_HAL_INIT_FAIL; |
254 | bfa_sm_send_event(bfad, BFAD_E_HAL_INIT_FAILED); |
255 | } |
256 | |
257 | break; |
258 | |
259 | case BFAD_E_KTHREAD_CREATE_FAILED: |
260 | bfa_sm_set_state(bfad, bfad_sm_uninit); |
261 | break; |
262 | |
263 | default: |
264 | bfa_sm_fault(bfad, event); |
265 | } |
266 | } |
267 | |
268 | static void |
269 | bfad_sm_initializing(struct bfad_s *bfad, enum bfad_sm_event event) |
270 | { |
271 | int retval; |
272 | unsigned long flags; |
273 | |
274 | bfa_trc(bfad, event); |
275 | |
276 | switch (event) { |
277 | case BFAD_E_INIT_SUCCESS: |
278 | kthread_stop(k: bfad->bfad_tsk); |
279 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
280 | bfad->bfad_tsk = NULL; |
281 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
282 | |
283 | retval = bfad_start_ops(bfad); |
284 | if (retval != BFA_STATUS_OK) { |
285 | bfa_sm_set_state(bfad, bfad_sm_failed); |
286 | break; |
287 | } |
288 | bfa_sm_set_state(bfad, bfad_sm_operational); |
289 | break; |
290 | |
291 | case BFAD_E_INIT_FAILED: |
292 | bfa_sm_set_state(bfad, bfad_sm_uninit); |
293 | kthread_stop(k: bfad->bfad_tsk); |
294 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
295 | bfad->bfad_tsk = NULL; |
296 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
297 | break; |
298 | |
299 | case BFAD_E_HAL_INIT_FAILED: |
300 | bfa_sm_set_state(bfad, bfad_sm_failed); |
301 | break; |
302 | default: |
303 | bfa_sm_fault(bfad, event); |
304 | } |
305 | } |
306 | |
307 | static void |
308 | bfad_sm_failed(struct bfad_s *bfad, enum bfad_sm_event event) |
309 | { |
310 | int retval; |
311 | |
312 | bfa_trc(bfad, event); |
313 | |
314 | switch (event) { |
315 | case BFAD_E_INIT_SUCCESS: |
316 | retval = bfad_start_ops(bfad); |
317 | if (retval != BFA_STATUS_OK) |
318 | break; |
319 | bfa_sm_set_state(bfad, bfad_sm_operational); |
320 | break; |
321 | |
322 | case BFAD_E_STOP: |
323 | bfa_sm_set_state(bfad, bfad_sm_fcs_exit); |
324 | bfa_sm_send_event(bfad, BFAD_E_FCS_EXIT_COMP); |
325 | break; |
326 | |
327 | case BFAD_E_EXIT_COMP: |
328 | bfa_sm_set_state(bfad, bfad_sm_uninit); |
329 | bfad_remove_intr(bfad); |
330 | del_timer_sync(timer: &bfad->hal_tmo); |
331 | break; |
332 | |
333 | default: |
334 | bfa_sm_fault(bfad, event); |
335 | } |
336 | } |
337 | |
338 | static void |
339 | bfad_sm_operational(struct bfad_s *bfad, enum bfad_sm_event event) |
340 | { |
341 | bfa_trc(bfad, event); |
342 | |
343 | switch (event) { |
344 | case BFAD_E_STOP: |
345 | bfa_sm_set_state(bfad, bfad_sm_fcs_exit); |
346 | bfad_fcs_stop(bfad); |
347 | break; |
348 | |
349 | default: |
350 | bfa_sm_fault(bfad, event); |
351 | } |
352 | } |
353 | |
354 | static void |
355 | bfad_sm_fcs_exit(struct bfad_s *bfad, enum bfad_sm_event event) |
356 | { |
357 | bfa_trc(bfad, event); |
358 | |
359 | switch (event) { |
360 | case BFAD_E_FCS_EXIT_COMP: |
361 | bfa_sm_set_state(bfad, bfad_sm_stopping); |
362 | bfad_stop(bfad); |
363 | break; |
364 | |
365 | default: |
366 | bfa_sm_fault(bfad, event); |
367 | } |
368 | } |
369 | |
370 | static void |
371 | bfad_sm_stopping(struct bfad_s *bfad, enum bfad_sm_event event) |
372 | { |
373 | bfa_trc(bfad, event); |
374 | |
375 | switch (event) { |
376 | case BFAD_E_EXIT_COMP: |
377 | bfa_sm_set_state(bfad, bfad_sm_uninit); |
378 | bfad_remove_intr(bfad); |
379 | del_timer_sync(timer: &bfad->hal_tmo); |
380 | bfad_im_probe_undo(bfad); |
381 | bfad->bfad_flags &= ~BFAD_FC4_PROBE_DONE; |
382 | bfad_uncfg_pport(bfad); |
383 | break; |
384 | |
385 | default: |
386 | bfa_sm_fault(bfad, event); |
387 | break; |
388 | } |
389 | } |
390 | |
391 | /* |
392 | * BFA callbacks |
393 | */ |
394 | void |
395 | bfad_hcb_comp(void *arg, bfa_status_t status) |
396 | { |
397 | struct bfad_hal_comp *fcomp = (struct bfad_hal_comp *)arg; |
398 | |
399 | fcomp->status = status; |
400 | complete(&fcomp->comp); |
401 | } |
402 | |
403 | /* |
404 | * bfa_init callback |
405 | */ |
406 | void |
407 | bfa_cb_init(void *drv, bfa_status_t init_status) |
408 | { |
409 | struct bfad_s *bfad = drv; |
410 | |
411 | if (init_status == BFA_STATUS_OK) { |
412 | bfad->bfad_flags |= BFAD_HAL_INIT_DONE; |
413 | |
414 | /* |
415 | * If BFAD_HAL_INIT_FAIL flag is set: |
416 | * Wake up the kernel thread to start |
417 | * the bfad operations after HAL init done |
418 | */ |
419 | if ((bfad->bfad_flags & BFAD_HAL_INIT_FAIL)) { |
420 | bfad->bfad_flags &= ~BFAD_HAL_INIT_FAIL; |
421 | wake_up_process(tsk: bfad->bfad_tsk); |
422 | } |
423 | } |
424 | |
425 | complete(&bfad->comp); |
426 | } |
427 | |
428 | /* |
429 | * BFA_FCS callbacks |
430 | */ |
431 | struct bfad_port_s * |
432 | bfa_fcb_lport_new(struct bfad_s *bfad, struct bfa_fcs_lport_s *port, |
433 | enum bfa_lport_role roles, struct bfad_vf_s *vf_drv, |
434 | struct bfad_vport_s *vp_drv) |
435 | { |
436 | bfa_status_t rc; |
437 | struct bfad_port_s *port_drv; |
438 | |
439 | if (!vp_drv && !vf_drv) { |
440 | port_drv = &bfad->pport; |
441 | port_drv->pvb_type = BFAD_PORT_PHYS_BASE; |
442 | } else if (!vp_drv && vf_drv) { |
443 | port_drv = &vf_drv->base_port; |
444 | port_drv->pvb_type = BFAD_PORT_VF_BASE; |
445 | } else if (vp_drv && !vf_drv) { |
446 | port_drv = &vp_drv->drv_port; |
447 | port_drv->pvb_type = BFAD_PORT_PHYS_VPORT; |
448 | } else { |
449 | port_drv = &vp_drv->drv_port; |
450 | port_drv->pvb_type = BFAD_PORT_VF_VPORT; |
451 | } |
452 | |
453 | port_drv->fcs_port = port; |
454 | port_drv->roles = roles; |
455 | |
456 | if (roles & BFA_LPORT_ROLE_FCP_IM) { |
457 | rc = bfad_im_port_new(bfad, port: port_drv); |
458 | if (rc != BFA_STATUS_OK) { |
459 | bfad_im_port_delete(bfad, port: port_drv); |
460 | port_drv = NULL; |
461 | } |
462 | } |
463 | |
464 | return port_drv; |
465 | } |
466 | |
467 | /* |
468 | * FCS RPORT alloc callback, after successful PLOGI by FCS |
469 | */ |
470 | bfa_status_t |
471 | bfa_fcb_rport_alloc(struct bfad_s *bfad, struct bfa_fcs_rport_s **rport, |
472 | struct bfad_rport_s **rport_drv) |
473 | { |
474 | bfa_status_t rc = BFA_STATUS_OK; |
475 | |
476 | *rport_drv = kzalloc(size: sizeof(struct bfad_rport_s), GFP_ATOMIC); |
477 | if (*rport_drv == NULL) { |
478 | rc = BFA_STATUS_ENOMEM; |
479 | goto ext; |
480 | } |
481 | |
482 | *rport = &(*rport_drv)->fcs_rport; |
483 | |
484 | ext: |
485 | return rc; |
486 | } |
487 | |
488 | /* |
489 | * FCS PBC VPORT Create |
490 | */ |
491 | void |
492 | bfa_fcb_pbc_vport_create(struct bfad_s *bfad, struct bfi_pbc_vport_s pbc_vport) |
493 | { |
494 | |
495 | struct bfa_lport_cfg_s port_cfg = {0}; |
496 | struct bfad_vport_s *vport; |
497 | int rc; |
498 | |
499 | vport = kzalloc(size: sizeof(struct bfad_vport_s), GFP_ATOMIC); |
500 | if (!vport) { |
501 | bfa_trc(bfad, 0); |
502 | return; |
503 | } |
504 | |
505 | vport->drv_port.bfad = bfad; |
506 | port_cfg.roles = BFA_LPORT_ROLE_FCP_IM; |
507 | port_cfg.pwwn = pbc_vport.vp_pwwn; |
508 | port_cfg.nwwn = pbc_vport.vp_nwwn; |
509 | port_cfg.preboot_vp = BFA_TRUE; |
510 | |
511 | rc = bfa_fcs_pbc_vport_create(vport: &vport->fcs_vport, fcs: &bfad->bfa_fcs, vf_id: 0, |
512 | port_cfg: &port_cfg, vport_drv: vport); |
513 | |
514 | if (rc != BFA_STATUS_OK) { |
515 | bfa_trc(bfad, 0); |
516 | return; |
517 | } |
518 | |
519 | list_add_tail(new: &vport->list_entry, head: &bfad->pbc_vport_list); |
520 | } |
521 | |
522 | void |
523 | bfad_hal_mem_release(struct bfad_s *bfad) |
524 | { |
525 | struct bfa_meminfo_s *hal_meminfo = &bfad->meminfo; |
526 | struct bfa_mem_dma_s *dma_info, *dma_elem; |
527 | struct bfa_mem_kva_s *kva_info, *kva_elem; |
528 | struct list_head *dm_qe, *km_qe; |
529 | |
530 | dma_info = &hal_meminfo->dma_info; |
531 | kva_info = &hal_meminfo->kva_info; |
532 | |
533 | /* Iterate through the KVA meminfo queue */ |
534 | list_for_each(km_qe, &kva_info->qe) { |
535 | kva_elem = (struct bfa_mem_kva_s *) km_qe; |
536 | vfree(addr: kva_elem->kva); |
537 | } |
538 | |
539 | /* Iterate through the DMA meminfo queue */ |
540 | list_for_each(dm_qe, &dma_info->qe) { |
541 | dma_elem = (struct bfa_mem_dma_s *) dm_qe; |
542 | dma_free_coherent(dev: &bfad->pcidev->dev, |
543 | size: dma_elem->mem_len, cpu_addr: dma_elem->kva, |
544 | dma_handle: (dma_addr_t) dma_elem->dma); |
545 | } |
546 | |
547 | memset(hal_meminfo, 0, sizeof(struct bfa_meminfo_s)); |
548 | } |
549 | |
550 | void |
551 | bfad_update_hal_cfg(struct bfa_iocfc_cfg_s *bfa_cfg) |
552 | { |
553 | if (num_rports > 0) |
554 | bfa_cfg->fwcfg.num_rports = num_rports; |
555 | if (num_ios > 0) |
556 | bfa_cfg->fwcfg.num_ioim_reqs = num_ios; |
557 | if (num_tms > 0) |
558 | bfa_cfg->fwcfg.num_tskim_reqs = num_tms; |
559 | if (num_fcxps > 0 && num_fcxps <= BFA_FCXP_MAX) |
560 | bfa_cfg->fwcfg.num_fcxp_reqs = num_fcxps; |
561 | if (num_ufbufs > 0 && num_ufbufs <= BFA_UF_MAX) |
562 | bfa_cfg->fwcfg.num_uf_bufs = num_ufbufs; |
563 | if (reqq_size > 0) |
564 | bfa_cfg->drvcfg.num_reqq_elems = reqq_size; |
565 | if (rspq_size > 0) |
566 | bfa_cfg->drvcfg.num_rspq_elems = rspq_size; |
567 | if (num_sgpgs > 0 && num_sgpgs <= BFA_SGPG_MAX) |
568 | bfa_cfg->drvcfg.num_sgpgs = num_sgpgs; |
569 | |
570 | /* |
571 | * populate the hal values back to the driver for sysfs use. |
572 | * otherwise, the default values will be shown as 0 in sysfs |
573 | */ |
574 | num_rports = bfa_cfg->fwcfg.num_rports; |
575 | num_ios = bfa_cfg->fwcfg.num_ioim_reqs; |
576 | num_tms = bfa_cfg->fwcfg.num_tskim_reqs; |
577 | num_fcxps = bfa_cfg->fwcfg.num_fcxp_reqs; |
578 | num_ufbufs = bfa_cfg->fwcfg.num_uf_bufs; |
579 | reqq_size = bfa_cfg->drvcfg.num_reqq_elems; |
580 | rspq_size = bfa_cfg->drvcfg.num_rspq_elems; |
581 | num_sgpgs = bfa_cfg->drvcfg.num_sgpgs; |
582 | } |
583 | |
584 | bfa_status_t |
585 | bfad_hal_mem_alloc(struct bfad_s *bfad) |
586 | { |
587 | struct bfa_meminfo_s *hal_meminfo = &bfad->meminfo; |
588 | struct bfa_mem_dma_s *dma_info, *dma_elem; |
589 | struct bfa_mem_kva_s *kva_info, *kva_elem; |
590 | struct list_head *dm_qe, *km_qe; |
591 | bfa_status_t rc = BFA_STATUS_OK; |
592 | dma_addr_t phys_addr; |
593 | |
594 | bfa_cfg_get_default(cfg: &bfad->ioc_cfg); |
595 | bfad_update_hal_cfg(bfa_cfg: &bfad->ioc_cfg); |
596 | bfad->cfg_data.ioc_queue_depth = bfad->ioc_cfg.fwcfg.num_ioim_reqs; |
597 | bfa_cfg_get_meminfo(cfg: &bfad->ioc_cfg, meminfo: hal_meminfo, bfa: &bfad->bfa); |
598 | |
599 | dma_info = &hal_meminfo->dma_info; |
600 | kva_info = &hal_meminfo->kva_info; |
601 | |
602 | /* Iterate through the KVA meminfo queue */ |
603 | list_for_each(km_qe, &kva_info->qe) { |
604 | kva_elem = (struct bfa_mem_kva_s *) km_qe; |
605 | kva_elem->kva = vzalloc(size: kva_elem->mem_len); |
606 | if (kva_elem->kva == NULL) { |
607 | bfad_hal_mem_release(bfad); |
608 | rc = BFA_STATUS_ENOMEM; |
609 | goto ext; |
610 | } |
611 | } |
612 | |
613 | /* Iterate through the DMA meminfo queue */ |
614 | list_for_each(dm_qe, &dma_info->qe) { |
615 | dma_elem = (struct bfa_mem_dma_s *) dm_qe; |
616 | dma_elem->kva = dma_alloc_coherent(dev: &bfad->pcidev->dev, |
617 | size: dma_elem->mem_len, |
618 | dma_handle: &phys_addr, GFP_KERNEL); |
619 | if (dma_elem->kva == NULL) { |
620 | bfad_hal_mem_release(bfad); |
621 | rc = BFA_STATUS_ENOMEM; |
622 | goto ext; |
623 | } |
624 | dma_elem->dma = phys_addr; |
625 | memset(dma_elem->kva, 0, dma_elem->mem_len); |
626 | } |
627 | ext: |
628 | return rc; |
629 | } |
630 | |
631 | /* |
632 | * Create a vport under a vf. |
633 | */ |
634 | bfa_status_t |
635 | bfad_vport_create(struct bfad_s *bfad, u16 vf_id, |
636 | struct bfa_lport_cfg_s *port_cfg, struct device *dev) |
637 | { |
638 | struct bfad_vport_s *vport; |
639 | int rc = BFA_STATUS_OK; |
640 | unsigned long flags; |
641 | struct completion fcomp; |
642 | |
643 | vport = kzalloc(size: sizeof(struct bfad_vport_s), GFP_KERNEL); |
644 | if (!vport) { |
645 | rc = BFA_STATUS_ENOMEM; |
646 | goto ext; |
647 | } |
648 | |
649 | vport->drv_port.bfad = bfad; |
650 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
651 | rc = bfa_fcs_vport_create(vport: &vport->fcs_vport, fcs: &bfad->bfa_fcs, vf_id, |
652 | port_cfg, vport_drv: vport); |
653 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
654 | |
655 | if (rc != BFA_STATUS_OK) |
656 | goto ext_free_vport; |
657 | |
658 | if (port_cfg->roles & BFA_LPORT_ROLE_FCP_IM) { |
659 | rc = bfad_im_scsi_host_alloc(bfad, im_port: vport->drv_port.im_port, |
660 | dev); |
661 | if (rc != BFA_STATUS_OK) |
662 | goto ext_free_fcs_vport; |
663 | } |
664 | |
665 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
666 | bfa_fcs_vport_start(vport: &vport->fcs_vport); |
667 | list_add_tail(new: &vport->list_entry, head: &bfad->vport_list); |
668 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
669 | |
670 | return BFA_STATUS_OK; |
671 | |
672 | ext_free_fcs_vport: |
673 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
674 | vport->comp_del = &fcomp; |
675 | init_completion(x: vport->comp_del); |
676 | bfa_fcs_vport_delete(vport: &vport->fcs_vport); |
677 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
678 | wait_for_completion(vport->comp_del); |
679 | ext_free_vport: |
680 | kfree(objp: vport); |
681 | ext: |
682 | return rc; |
683 | } |
684 | |
685 | void |
686 | bfad_bfa_tmo(struct timer_list *t) |
687 | { |
688 | struct bfad_s *bfad = from_timer(bfad, t, hal_tmo); |
689 | unsigned long flags; |
690 | struct list_head doneq; |
691 | |
692 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
693 | |
694 | bfa_timer_beat(mod: &bfad->bfa.timer_mod); |
695 | |
696 | bfa_comp_deq(bfa: &bfad->bfa, comp_q: &doneq); |
697 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
698 | |
699 | if (!list_empty(head: &doneq)) { |
700 | bfa_comp_process(bfa: &bfad->bfa, comp_q: &doneq); |
701 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
702 | bfa_comp_free(bfa: &bfad->bfa, comp_q: &doneq); |
703 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
704 | } |
705 | |
706 | mod_timer(timer: &bfad->hal_tmo, |
707 | expires: jiffies + msecs_to_jiffies(BFA_TIMER_FREQ)); |
708 | } |
709 | |
710 | void |
711 | bfad_init_timer(struct bfad_s *bfad) |
712 | { |
713 | timer_setup(&bfad->hal_tmo, bfad_bfa_tmo, 0); |
714 | |
715 | mod_timer(timer: &bfad->hal_tmo, |
716 | expires: jiffies + msecs_to_jiffies(BFA_TIMER_FREQ)); |
717 | } |
718 | |
719 | int |
720 | bfad_pci_init(struct pci_dev *pdev, struct bfad_s *bfad) |
721 | { |
722 | int rc = -ENODEV; |
723 | |
724 | if (pci_enable_device(dev: pdev)) { |
725 | printk(KERN_ERR "pci_enable_device fail %p\n" , pdev); |
726 | goto out; |
727 | } |
728 | |
729 | if (pci_request_regions(pdev, BFAD_DRIVER_NAME)) |
730 | goto out_disable_device; |
731 | |
732 | pci_set_master(dev: pdev); |
733 | |
734 | rc = dma_set_mask_and_coherent(dev: &pdev->dev, DMA_BIT_MASK(64)); |
735 | if (rc) { |
736 | rc = -ENODEV; |
737 | printk(KERN_ERR "dma_set_mask_and_coherent fail %p\n" , pdev); |
738 | goto out_release_region; |
739 | } |
740 | |
741 | bfad->pci_bar0_kva = pci_iomap(dev: pdev, bar: 0, pci_resource_len(pdev, 0)); |
742 | bfad->pci_bar2_kva = pci_iomap(dev: pdev, bar: 2, pci_resource_len(pdev, 2)); |
743 | |
744 | if (bfad->pci_bar0_kva == NULL) { |
745 | printk(KERN_ERR "Fail to map bar0\n" ); |
746 | rc = -ENODEV; |
747 | goto out_release_region; |
748 | } |
749 | |
750 | bfad->hal_pcidev.pci_slot = PCI_SLOT(pdev->devfn); |
751 | bfad->hal_pcidev.pci_func = PCI_FUNC(pdev->devfn); |
752 | bfad->hal_pcidev.pci_bar_kva = bfad->pci_bar0_kva; |
753 | bfad->hal_pcidev.device_id = pdev->device; |
754 | bfad->hal_pcidev.ssid = pdev->subsystem_device; |
755 | bfad->pci_name = pci_name(pdev); |
756 | |
757 | bfad->pci_attr.vendor_id = pdev->vendor; |
758 | bfad->pci_attr.device_id = pdev->device; |
759 | bfad->pci_attr.ssid = pdev->subsystem_device; |
760 | bfad->pci_attr.ssvid = pdev->subsystem_vendor; |
761 | bfad->pci_attr.pcifn = PCI_FUNC(pdev->devfn); |
762 | |
763 | bfad->pcidev = pdev; |
764 | |
765 | /* Adjust PCIe Maximum Read Request Size */ |
766 | if (pci_is_pcie(dev: pdev) && pcie_max_read_reqsz) { |
767 | if (pcie_max_read_reqsz >= 128 && |
768 | pcie_max_read_reqsz <= 4096 && |
769 | is_power_of_2(n: pcie_max_read_reqsz)) { |
770 | int max_rq = pcie_get_readrq(dev: pdev); |
771 | printk(KERN_WARNING "BFA[%s]: " |
772 | "pcie_max_read_request_size is %d, " |
773 | "reset to %d\n" , bfad->pci_name, max_rq, |
774 | pcie_max_read_reqsz); |
775 | pcie_set_readrq(dev: pdev, rq: pcie_max_read_reqsz); |
776 | } else { |
777 | printk(KERN_WARNING "BFA[%s]: invalid " |
778 | "pcie_max_read_request_size %d ignored\n" , |
779 | bfad->pci_name, pcie_max_read_reqsz); |
780 | } |
781 | } |
782 | |
783 | pci_save_state(dev: pdev); |
784 | |
785 | return 0; |
786 | |
787 | out_release_region: |
788 | pci_release_regions(pdev); |
789 | out_disable_device: |
790 | pci_disable_device(dev: pdev); |
791 | out: |
792 | return rc; |
793 | } |
794 | |
795 | void |
796 | bfad_pci_uninit(struct pci_dev *pdev, struct bfad_s *bfad) |
797 | { |
798 | pci_iounmap(dev: pdev, bfad->pci_bar0_kva); |
799 | pci_iounmap(dev: pdev, bfad->pci_bar2_kva); |
800 | pci_release_regions(pdev); |
801 | pci_disable_device(dev: pdev); |
802 | } |
803 | |
804 | bfa_status_t |
805 | bfad_drv_init(struct bfad_s *bfad) |
806 | { |
807 | bfa_status_t rc; |
808 | unsigned long flags; |
809 | |
810 | bfad->cfg_data.rport_del_timeout = rport_del_timeout; |
811 | bfad->cfg_data.lun_queue_depth = bfa_lun_queue_depth; |
812 | bfad->cfg_data.io_max_sge = bfa_io_max_sge; |
813 | bfad->cfg_data.binding_method = FCP_PWWN_BINDING; |
814 | |
815 | rc = bfad_hal_mem_alloc(bfad); |
816 | if (rc != BFA_STATUS_OK) { |
817 | printk(KERN_WARNING "bfad%d bfad_hal_mem_alloc failure\n" , |
818 | bfad->inst_no); |
819 | printk(KERN_WARNING |
820 | "Not enough memory to attach all QLogic BR-series HBA ports. System may need more memory.\n" ); |
821 | return BFA_STATUS_FAILED; |
822 | } |
823 | |
824 | bfad->bfa.trcmod = bfad->trcmod; |
825 | bfad->bfa.plog = &bfad->plog_buf; |
826 | bfa_plog_init(plog: &bfad->plog_buf); |
827 | bfa_plog_str(plog: &bfad->plog_buf, mid: BFA_PL_MID_DRVR, event: BFA_PL_EID_DRIVER_START, |
828 | misc: 0, log_str: "Driver Attach" ); |
829 | |
830 | bfa_attach(bfa: &bfad->bfa, bfad, cfg: &bfad->ioc_cfg, meminfo: &bfad->meminfo, |
831 | pcidev: &bfad->hal_pcidev); |
832 | |
833 | /* FCS INIT */ |
834 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
835 | bfad->bfa_fcs.trcmod = bfad->trcmod; |
836 | bfa_fcs_attach(fcs: &bfad->bfa_fcs, bfa: &bfad->bfa, bfad, min_cfg: BFA_FALSE); |
837 | bfad->bfa_fcs.fdmi_enabled = fdmi_enable; |
838 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
839 | |
840 | bfad->bfad_flags |= BFAD_DRV_INIT_DONE; |
841 | |
842 | return BFA_STATUS_OK; |
843 | } |
844 | |
845 | void |
846 | bfad_drv_uninit(struct bfad_s *bfad) |
847 | { |
848 | unsigned long flags; |
849 | |
850 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
851 | init_completion(x: &bfad->comp); |
852 | bfa_iocfc_stop(bfa: &bfad->bfa); |
853 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
854 | wait_for_completion(&bfad->comp); |
855 | |
856 | del_timer_sync(timer: &bfad->hal_tmo); |
857 | bfa_isr_disable(bfa: &bfad->bfa); |
858 | bfa_detach(bfa: &bfad->bfa); |
859 | bfad_remove_intr(bfad); |
860 | bfad_hal_mem_release(bfad); |
861 | |
862 | bfad->bfad_flags &= ~BFAD_DRV_INIT_DONE; |
863 | } |
864 | |
865 | void |
866 | bfad_drv_start(struct bfad_s *bfad) |
867 | { |
868 | unsigned long flags; |
869 | |
870 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
871 | bfa_iocfc_start(bfa: &bfad->bfa); |
872 | bfa_fcs_pbc_vport_init(fcs: &bfad->bfa_fcs); |
873 | bfa_fcs_fabric_modstart(fcs: &bfad->bfa_fcs); |
874 | bfad->bfad_flags |= BFAD_HAL_START_DONE; |
875 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
876 | |
877 | if (bfad->im) |
878 | flush_workqueue(bfad->im->drv_workq); |
879 | } |
880 | |
881 | void |
882 | bfad_fcs_stop(struct bfad_s *bfad) |
883 | { |
884 | unsigned long flags; |
885 | |
886 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
887 | init_completion(x: &bfad->comp); |
888 | bfad->pport.flags |= BFAD_PORT_DELETE; |
889 | bfa_fcs_exit(fcs: &bfad->bfa_fcs); |
890 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
891 | wait_for_completion(&bfad->comp); |
892 | |
893 | bfa_sm_send_event(bfad, BFAD_E_FCS_EXIT_COMP); |
894 | } |
895 | |
896 | void |
897 | bfad_stop(struct bfad_s *bfad) |
898 | { |
899 | unsigned long flags; |
900 | |
901 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
902 | init_completion(x: &bfad->comp); |
903 | bfa_iocfc_stop(bfa: &bfad->bfa); |
904 | bfad->bfad_flags &= ~BFAD_HAL_START_DONE; |
905 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
906 | wait_for_completion(&bfad->comp); |
907 | |
908 | bfa_sm_send_event(bfad, BFAD_E_EXIT_COMP); |
909 | } |
910 | |
911 | bfa_status_t |
912 | bfad_cfg_pport(struct bfad_s *bfad, enum bfa_lport_role role) |
913 | { |
914 | int rc = BFA_STATUS_OK; |
915 | |
916 | /* Allocate scsi_host for the physical port */ |
917 | if ((supported_fc4s & BFA_LPORT_ROLE_FCP_IM) && |
918 | (role & BFA_LPORT_ROLE_FCP_IM)) { |
919 | if (bfad->pport.im_port == NULL) { |
920 | rc = BFA_STATUS_FAILED; |
921 | goto out; |
922 | } |
923 | |
924 | rc = bfad_im_scsi_host_alloc(bfad, im_port: bfad->pport.im_port, |
925 | dev: &bfad->pcidev->dev); |
926 | if (rc != BFA_STATUS_OK) |
927 | goto out; |
928 | |
929 | bfad->pport.roles |= BFA_LPORT_ROLE_FCP_IM; |
930 | } |
931 | |
932 | bfad->bfad_flags |= BFAD_CFG_PPORT_DONE; |
933 | |
934 | out: |
935 | return rc; |
936 | } |
937 | |
938 | void |
939 | bfad_uncfg_pport(struct bfad_s *bfad) |
940 | { |
941 | if ((supported_fc4s & BFA_LPORT_ROLE_FCP_IM) && |
942 | (bfad->pport.roles & BFA_LPORT_ROLE_FCP_IM)) { |
943 | bfad_im_scsi_host_free(bfad, im_port: bfad->pport.im_port); |
944 | bfad_im_port_clean(im_port: bfad->pport.im_port); |
945 | kfree(objp: bfad->pport.im_port); |
946 | bfad->pport.roles &= ~BFA_LPORT_ROLE_FCP_IM; |
947 | } |
948 | |
949 | bfad->bfad_flags &= ~BFAD_CFG_PPORT_DONE; |
950 | } |
951 | |
952 | bfa_status_t |
953 | bfad_start_ops(struct bfad_s *bfad) { |
954 | |
955 | int retval; |
956 | unsigned long flags; |
957 | struct bfad_vport_s *vport, *vport_new; |
958 | struct bfa_fcs_driver_info_s driver_info; |
959 | |
960 | /* Limit min/max. xfer size to [64k-32MB] */ |
961 | if (max_xfer_size < BFAD_MIN_SECTORS >> 1) |
962 | max_xfer_size = BFAD_MIN_SECTORS >> 1; |
963 | if (max_xfer_size > BFAD_MAX_SECTORS >> 1) |
964 | max_xfer_size = BFAD_MAX_SECTORS >> 1; |
965 | |
966 | /* Fill the driver_info info to fcs*/ |
967 | memset(&driver_info, 0, sizeof(driver_info)); |
968 | strscpy(p: driver_info.version, BFAD_DRIVER_VERSION, |
969 | size: sizeof(driver_info.version)); |
970 | if (host_name) |
971 | strscpy(p: driver_info.host_machine_name, q: host_name, |
972 | size: sizeof(driver_info.host_machine_name)); |
973 | if (os_name) |
974 | strscpy(p: driver_info.host_os_name, q: os_name, |
975 | size: sizeof(driver_info.host_os_name)); |
976 | if (os_patch) |
977 | strscpy(p: driver_info.host_os_patch, q: os_patch, |
978 | size: sizeof(driver_info.host_os_patch)); |
979 | |
980 | strscpy(p: driver_info.os_device_name, q: bfad->pci_name, |
981 | size: sizeof(driver_info.os_device_name)); |
982 | |
983 | /* FCS driver info init */ |
984 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
985 | bfa_fcs_driver_info_init(fcs: &bfad->bfa_fcs, driver_info: &driver_info); |
986 | |
987 | if (bfad->bfad_flags & BFAD_CFG_PPORT_DONE) |
988 | bfa_fcs_update_cfg(fcs: &bfad->bfa_fcs); |
989 | else |
990 | bfa_fcs_init(fcs: &bfad->bfa_fcs); |
991 | |
992 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
993 | |
994 | if (!(bfad->bfad_flags & BFAD_CFG_PPORT_DONE)) { |
995 | retval = bfad_cfg_pport(bfad, role: BFA_LPORT_ROLE_FCP_IM); |
996 | if (retval != BFA_STATUS_OK) |
997 | return BFA_STATUS_FAILED; |
998 | } |
999 | |
1000 | /* Setup fc host fixed attribute if the lk supports */ |
1001 | bfad_fc_host_init(im_port: bfad->pport.im_port); |
1002 | |
1003 | /* BFAD level FC4 IM specific resource allocation */ |
1004 | retval = bfad_im_probe(bfad); |
1005 | if (retval != BFA_STATUS_OK) { |
1006 | printk(KERN_WARNING "bfad_im_probe failed\n" ); |
1007 | if (bfa_sm_cmp_state(bfad, bfad_sm_initializing)) |
1008 | bfa_sm_set_state(bfad, bfad_sm_failed); |
1009 | return BFA_STATUS_FAILED; |
1010 | } else |
1011 | bfad->bfad_flags |= BFAD_FC4_PROBE_DONE; |
1012 | |
1013 | bfad_drv_start(bfad); |
1014 | |
1015 | /* Complete pbc vport create */ |
1016 | list_for_each_entry_safe(vport, vport_new, &bfad->pbc_vport_list, |
1017 | list_entry) { |
1018 | struct fc_vport_identifiers vid; |
1019 | struct fc_vport *fc_vport; |
1020 | char pwwn_buf[BFA_STRING_32]; |
1021 | |
1022 | memset(&vid, 0, sizeof(vid)); |
1023 | vid.roles = FC_PORT_ROLE_FCP_INITIATOR; |
1024 | vid.vport_type = FC_PORTTYPE_NPIV; |
1025 | vid.disable = false; |
1026 | vid.node_name = wwn_to_u64(wwn: (u8 *) |
1027 | (&((vport->fcs_vport).lport.port_cfg.nwwn))); |
1028 | vid.port_name = wwn_to_u64(wwn: (u8 *) |
1029 | (&((vport->fcs_vport).lport.port_cfg.pwwn))); |
1030 | fc_vport = fc_vport_create(shost: bfad->pport.im_port->shost, channel: 0, &vid); |
1031 | if (!fc_vport) { |
1032 | wwn2str(wwn_str: pwwn_buf, wwn: vid.port_name); |
1033 | printk(KERN_WARNING "bfad%d: failed to create pbc vport" |
1034 | " %s\n" , bfad->inst_no, pwwn_buf); |
1035 | } |
1036 | list_del(entry: &vport->list_entry); |
1037 | kfree(objp: vport); |
1038 | } |
1039 | |
1040 | /* |
1041 | * If bfa_linkup_delay is set to -1 default; try to retrive the |
1042 | * value using the bfad_get_linkup_delay(); else use the |
1043 | * passed in module param value as the bfa_linkup_delay. |
1044 | */ |
1045 | if (bfa_linkup_delay < 0) { |
1046 | bfa_linkup_delay = bfad_get_linkup_delay(bfad); |
1047 | bfad_rport_online_wait(bfad); |
1048 | bfa_linkup_delay = -1; |
1049 | } else |
1050 | bfad_rport_online_wait(bfad); |
1051 | |
1052 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, "bfa device claimed\n" ); |
1053 | |
1054 | return BFA_STATUS_OK; |
1055 | } |
1056 | |
1057 | int |
1058 | bfad_worker(void *ptr) |
1059 | { |
1060 | struct bfad_s *bfad = ptr; |
1061 | unsigned long flags; |
1062 | |
1063 | if (kthread_should_stop()) |
1064 | return 0; |
1065 | |
1066 | /* Send event BFAD_E_INIT_SUCCESS */ |
1067 | bfa_sm_send_event(bfad, BFAD_E_INIT_SUCCESS); |
1068 | |
1069 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1070 | bfad->bfad_tsk = NULL; |
1071 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1072 | |
1073 | return 0; |
1074 | } |
1075 | |
1076 | /* |
1077 | * BFA driver interrupt functions |
1078 | */ |
1079 | irqreturn_t |
1080 | bfad_intx(int irq, void *dev_id) |
1081 | { |
1082 | struct bfad_s *bfad = dev_id; |
1083 | struct list_head doneq; |
1084 | unsigned long flags; |
1085 | bfa_boolean_t rc; |
1086 | |
1087 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1088 | rc = bfa_intx(bfa: &bfad->bfa); |
1089 | if (!rc) { |
1090 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1091 | return IRQ_NONE; |
1092 | } |
1093 | |
1094 | bfa_comp_deq(bfa: &bfad->bfa, comp_q: &doneq); |
1095 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1096 | |
1097 | if (!list_empty(head: &doneq)) { |
1098 | bfa_comp_process(bfa: &bfad->bfa, comp_q: &doneq); |
1099 | |
1100 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1101 | bfa_comp_free(bfa: &bfad->bfa, comp_q: &doneq); |
1102 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1103 | } |
1104 | |
1105 | return IRQ_HANDLED; |
1106 | |
1107 | } |
1108 | |
1109 | static irqreturn_t |
1110 | bfad_msix(int irq, void *dev_id) |
1111 | { |
1112 | struct bfad_msix_s *vec = dev_id; |
1113 | struct bfad_s *bfad = vec->bfad; |
1114 | struct list_head doneq; |
1115 | unsigned long flags; |
1116 | |
1117 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1118 | |
1119 | bfa_msix(&bfad->bfa, vec->msix.entry); |
1120 | bfa_comp_deq(bfa: &bfad->bfa, comp_q: &doneq); |
1121 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1122 | |
1123 | if (!list_empty(head: &doneq)) { |
1124 | bfa_comp_process(bfa: &bfad->bfa, comp_q: &doneq); |
1125 | |
1126 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1127 | bfa_comp_free(bfa: &bfad->bfa, comp_q: &doneq); |
1128 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1129 | } |
1130 | |
1131 | return IRQ_HANDLED; |
1132 | } |
1133 | |
1134 | /* |
1135 | * Initialize the MSIX entry table. |
1136 | */ |
1137 | static void |
1138 | bfad_init_msix_entry(struct bfad_s *bfad, struct msix_entry *msix_entries, |
1139 | int mask, int max_bit) |
1140 | { |
1141 | int i; |
1142 | int match = 0x00000001; |
1143 | |
1144 | for (i = 0, bfad->nvec = 0; i < MAX_MSIX_ENTRY; i++) { |
1145 | if (mask & match) { |
1146 | bfad->msix_tab[bfad->nvec].msix.entry = i; |
1147 | bfad->msix_tab[bfad->nvec].bfad = bfad; |
1148 | msix_entries[bfad->nvec].entry = i; |
1149 | bfad->nvec++; |
1150 | } |
1151 | |
1152 | match <<= 1; |
1153 | } |
1154 | |
1155 | } |
1156 | |
1157 | int |
1158 | bfad_install_msix_handler(struct bfad_s *bfad) |
1159 | { |
1160 | int i, error = 0; |
1161 | |
1162 | for (i = 0; i < bfad->nvec; i++) { |
1163 | sprintf(buf: bfad->msix_tab[i].name, fmt: "bfa-%s-%s" , |
1164 | bfad->pci_name, |
1165 | ((bfa_asic_id_cb(bfad->hal_pcidev.device_id)) ? |
1166 | msix_name_cb[i] : msix_name_ct[i])); |
1167 | |
1168 | error = request_irq(irq: bfad->msix_tab[i].msix.vector, |
1169 | handler: (irq_handler_t) bfad_msix, flags: 0, |
1170 | name: bfad->msix_tab[i].name, dev: &bfad->msix_tab[i]); |
1171 | bfa_trc(bfad, i); |
1172 | bfa_trc(bfad, bfad->msix_tab[i].msix.vector); |
1173 | if (error) { |
1174 | int j; |
1175 | |
1176 | for (j = 0; j < i; j++) |
1177 | free_irq(bfad->msix_tab[j].msix.vector, |
1178 | &bfad->msix_tab[j]); |
1179 | |
1180 | bfad->bfad_flags &= ~BFAD_MSIX_ON; |
1181 | pci_disable_msix(dev: bfad->pcidev); |
1182 | |
1183 | return 1; |
1184 | } |
1185 | } |
1186 | |
1187 | return 0; |
1188 | } |
1189 | |
1190 | /* |
1191 | * Setup MSIX based interrupt. |
1192 | */ |
1193 | int |
1194 | bfad_setup_intr(struct bfad_s *bfad) |
1195 | { |
1196 | int error; |
1197 | u32 mask = 0, i, num_bit = 0, max_bit = 0; |
1198 | struct msix_entry msix_entries[MAX_MSIX_ENTRY]; |
1199 | struct pci_dev *pdev = bfad->pcidev; |
1200 | u16 reg; |
1201 | |
1202 | /* Call BFA to get the msix map for this PCI function. */ |
1203 | bfa_msix_getvecs(&bfad->bfa, &mask, &num_bit, &max_bit); |
1204 | |
1205 | /* Set up the msix entry table */ |
1206 | bfad_init_msix_entry(bfad, msix_entries, mask, max_bit); |
1207 | |
1208 | if ((bfa_asic_id_ctc(pdev->device) && !msix_disable_ct) || |
1209 | (bfa_asic_id_cb(pdev->device) && !msix_disable_cb)) { |
1210 | |
1211 | error = pci_enable_msix_exact(dev: bfad->pcidev, |
1212 | entries: msix_entries, nvec: bfad->nvec); |
1213 | /* In CT1 & CT2, try to allocate just one vector */ |
1214 | if (error == -ENOSPC && bfa_asic_id_ctc(pdev->device)) { |
1215 | printk(KERN_WARNING "bfa %s: trying one msix " |
1216 | "vector failed to allocate %d[%d]\n" , |
1217 | bfad->pci_name, bfad->nvec, error); |
1218 | bfad->nvec = 1; |
1219 | error = pci_enable_msix_exact(dev: bfad->pcidev, |
1220 | entries: msix_entries, nvec: 1); |
1221 | } |
1222 | |
1223 | if (error) { |
1224 | printk(KERN_WARNING "bfad%d: " |
1225 | "pci_enable_msix_exact failed (%d), " |
1226 | "use line based.\n" , |
1227 | bfad->inst_no, error); |
1228 | goto line_based; |
1229 | } |
1230 | |
1231 | /* Disable INTX in MSI-X mode */ |
1232 | pci_read_config_word(dev: pdev, PCI_COMMAND, val: ®); |
1233 | |
1234 | if (!(reg & PCI_COMMAND_INTX_DISABLE)) |
1235 | pci_write_config_word(dev: pdev, PCI_COMMAND, |
1236 | val: reg | PCI_COMMAND_INTX_DISABLE); |
1237 | |
1238 | /* Save the vectors */ |
1239 | for (i = 0; i < bfad->nvec; i++) { |
1240 | bfa_trc(bfad, msix_entries[i].vector); |
1241 | bfad->msix_tab[i].msix.vector = msix_entries[i].vector; |
1242 | } |
1243 | |
1244 | bfa_msix_init(&bfad->bfa, bfad->nvec); |
1245 | |
1246 | bfad->bfad_flags |= BFAD_MSIX_ON; |
1247 | |
1248 | return 0; |
1249 | } |
1250 | |
1251 | line_based: |
1252 | error = request_irq(irq: bfad->pcidev->irq, handler: (irq_handler_t)bfad_intx, |
1253 | BFAD_IRQ_FLAGS, BFAD_DRIVER_NAME, dev: bfad); |
1254 | if (error) |
1255 | return error; |
1256 | |
1257 | bfad->bfad_flags |= BFAD_INTX_ON; |
1258 | |
1259 | return 0; |
1260 | } |
1261 | |
1262 | void |
1263 | bfad_remove_intr(struct bfad_s *bfad) |
1264 | { |
1265 | int i; |
1266 | |
1267 | if (bfad->bfad_flags & BFAD_MSIX_ON) { |
1268 | for (i = 0; i < bfad->nvec; i++) |
1269 | free_irq(bfad->msix_tab[i].msix.vector, |
1270 | &bfad->msix_tab[i]); |
1271 | |
1272 | pci_disable_msix(dev: bfad->pcidev); |
1273 | bfad->bfad_flags &= ~BFAD_MSIX_ON; |
1274 | } else if (bfad->bfad_flags & BFAD_INTX_ON) { |
1275 | free_irq(bfad->pcidev->irq, bfad); |
1276 | } |
1277 | } |
1278 | |
1279 | /* |
1280 | * PCI probe entry. |
1281 | */ |
1282 | int |
1283 | bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid) |
1284 | { |
1285 | struct bfad_s *bfad; |
1286 | int error = -ENODEV, retval, i; |
1287 | |
1288 | /* For single port cards - only claim function 0 */ |
1289 | if ((pdev->device == BFA_PCI_DEVICE_ID_FC_8G1P) && |
1290 | (PCI_FUNC(pdev->devfn) != 0)) |
1291 | return -ENODEV; |
1292 | |
1293 | bfad = kzalloc(size: sizeof(struct bfad_s), GFP_KERNEL); |
1294 | if (!bfad) { |
1295 | error = -ENOMEM; |
1296 | goto out; |
1297 | } |
1298 | |
1299 | bfad->trcmod = kzalloc(size: sizeof(struct bfa_trc_mod_s), GFP_KERNEL); |
1300 | if (!bfad->trcmod) { |
1301 | printk(KERN_WARNING "Error alloc trace buffer!\n" ); |
1302 | error = -ENOMEM; |
1303 | goto out_alloc_trace_failure; |
1304 | } |
1305 | |
1306 | /* TRACE INIT */ |
1307 | bfa_trc_init(trcm: bfad->trcmod); |
1308 | bfa_trc(bfad, bfad_inst); |
1309 | |
1310 | /* AEN INIT */ |
1311 | INIT_LIST_HEAD(list: &bfad->free_aen_q); |
1312 | INIT_LIST_HEAD(list: &bfad->active_aen_q); |
1313 | for (i = 0; i < BFA_AEN_MAX_ENTRY; i++) |
1314 | list_add_tail(new: &bfad->aen_list[i].qe, head: &bfad->free_aen_q); |
1315 | |
1316 | if (!(bfad_load_fwimg(pdev))) { |
1317 | kfree(objp: bfad->trcmod); |
1318 | goto out_alloc_trace_failure; |
1319 | } |
1320 | |
1321 | retval = bfad_pci_init(pdev, bfad); |
1322 | if (retval) { |
1323 | printk(KERN_WARNING "bfad_pci_init failure!\n" ); |
1324 | error = retval; |
1325 | goto out_pci_init_failure; |
1326 | } |
1327 | |
1328 | mutex_lock(&bfad_mutex); |
1329 | bfad->inst_no = bfad_inst++; |
1330 | list_add_tail(new: &bfad->list_entry, head: &bfad_list); |
1331 | mutex_unlock(lock: &bfad_mutex); |
1332 | |
1333 | /* Initializing the state machine: State set to uninit */ |
1334 | bfa_sm_set_state(bfad, bfad_sm_uninit); |
1335 | |
1336 | spin_lock_init(&bfad->bfad_lock); |
1337 | spin_lock_init(&bfad->bfad_aen_spinlock); |
1338 | |
1339 | pci_set_drvdata(pdev, data: bfad); |
1340 | |
1341 | bfad->ref_count = 0; |
1342 | bfad->pport.bfad = bfad; |
1343 | INIT_LIST_HEAD(list: &bfad->pbc_vport_list); |
1344 | INIT_LIST_HEAD(list: &bfad->vport_list); |
1345 | |
1346 | /* Setup the debugfs node for this bfad */ |
1347 | if (bfa_debugfs_enable) |
1348 | bfad_debugfs_init(port: &bfad->pport); |
1349 | |
1350 | retval = bfad_drv_init(bfad); |
1351 | if (retval != BFA_STATUS_OK) |
1352 | goto out_drv_init_failure; |
1353 | |
1354 | bfa_sm_send_event(bfad, BFAD_E_CREATE); |
1355 | |
1356 | if (bfa_sm_cmp_state(bfad, bfad_sm_uninit)) |
1357 | goto out_bfad_sm_failure; |
1358 | |
1359 | return 0; |
1360 | |
1361 | out_bfad_sm_failure: |
1362 | bfad_hal_mem_release(bfad); |
1363 | out_drv_init_failure: |
1364 | /* Remove the debugfs node for this bfad */ |
1365 | kfree(objp: bfad->regdata); |
1366 | bfad_debugfs_exit(port: &bfad->pport); |
1367 | mutex_lock(&bfad_mutex); |
1368 | bfad_inst--; |
1369 | list_del(entry: &bfad->list_entry); |
1370 | mutex_unlock(lock: &bfad_mutex); |
1371 | bfad_pci_uninit(pdev, bfad); |
1372 | out_pci_init_failure: |
1373 | kfree(objp: bfad->trcmod); |
1374 | out_alloc_trace_failure: |
1375 | kfree(objp: bfad); |
1376 | out: |
1377 | return error; |
1378 | } |
1379 | |
1380 | /* |
1381 | * PCI remove entry. |
1382 | */ |
1383 | void |
1384 | bfad_pci_remove(struct pci_dev *pdev) |
1385 | { |
1386 | struct bfad_s *bfad = pci_get_drvdata(pdev); |
1387 | unsigned long flags; |
1388 | |
1389 | bfa_trc(bfad, bfad->inst_no); |
1390 | |
1391 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1392 | if (bfad->bfad_tsk != NULL) { |
1393 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1394 | kthread_stop(k: bfad->bfad_tsk); |
1395 | } else { |
1396 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1397 | } |
1398 | |
1399 | /* Send Event BFAD_E_STOP */ |
1400 | bfa_sm_send_event(bfad, BFAD_E_STOP); |
1401 | |
1402 | /* Driver detach and dealloc mem */ |
1403 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1404 | bfa_detach(bfa: &bfad->bfa); |
1405 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1406 | bfad_hal_mem_release(bfad); |
1407 | |
1408 | /* Remove the debugfs node for this bfad */ |
1409 | kfree(objp: bfad->regdata); |
1410 | bfad_debugfs_exit(port: &bfad->pport); |
1411 | |
1412 | /* Cleaning the BFAD instance */ |
1413 | mutex_lock(&bfad_mutex); |
1414 | bfad_inst--; |
1415 | list_del(entry: &bfad->list_entry); |
1416 | mutex_unlock(lock: &bfad_mutex); |
1417 | bfad_pci_uninit(pdev, bfad); |
1418 | |
1419 | kfree(objp: bfad->trcmod); |
1420 | kfree(objp: bfad); |
1421 | } |
1422 | |
1423 | /* |
1424 | * PCI Error Recovery entry, error detected. |
1425 | */ |
1426 | static pci_ers_result_t |
1427 | bfad_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) |
1428 | { |
1429 | struct bfad_s *bfad = pci_get_drvdata(pdev); |
1430 | unsigned long flags; |
1431 | pci_ers_result_t ret = PCI_ERS_RESULT_NONE; |
1432 | |
1433 | dev_printk(KERN_ERR, &pdev->dev, |
1434 | "error detected state: %d - flags: 0x%x\n" , |
1435 | state, bfad->bfad_flags); |
1436 | |
1437 | switch (state) { |
1438 | case pci_channel_io_normal: /* non-fatal error */ |
1439 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1440 | bfad->bfad_flags &= ~BFAD_EEH_BUSY; |
1441 | /* Suspend/fail all bfa operations */ |
1442 | bfa_ioc_suspend(ioc: &bfad->bfa.ioc); |
1443 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1444 | del_timer_sync(timer: &bfad->hal_tmo); |
1445 | ret = PCI_ERS_RESULT_CAN_RECOVER; |
1446 | break; |
1447 | case pci_channel_io_frozen: /* fatal error */ |
1448 | init_completion(x: &bfad->comp); |
1449 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1450 | bfad->bfad_flags |= BFAD_EEH_BUSY; |
1451 | /* Suspend/fail all bfa operations */ |
1452 | bfa_ioc_suspend(ioc: &bfad->bfa.ioc); |
1453 | bfa_fcs_stop(fcs: &bfad->bfa_fcs); |
1454 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1455 | wait_for_completion(&bfad->comp); |
1456 | |
1457 | bfad_remove_intr(bfad); |
1458 | del_timer_sync(timer: &bfad->hal_tmo); |
1459 | pci_disable_device(dev: pdev); |
1460 | ret = PCI_ERS_RESULT_NEED_RESET; |
1461 | break; |
1462 | case pci_channel_io_perm_failure: /* PCI Card is DEAD */ |
1463 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1464 | bfad->bfad_flags |= BFAD_EEH_BUSY | |
1465 | BFAD_EEH_PCI_CHANNEL_IO_PERM_FAILURE; |
1466 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1467 | |
1468 | /* If the error_detected handler is called with the reason |
1469 | * pci_channel_io_perm_failure - it will subsequently call |
1470 | * pci_remove() entry point to remove the pci device from the |
1471 | * system - So defer the cleanup to pci_remove(); cleaning up |
1472 | * here causes inconsistent state during pci_remove(). |
1473 | */ |
1474 | ret = PCI_ERS_RESULT_DISCONNECT; |
1475 | break; |
1476 | default: |
1477 | WARN_ON(1); |
1478 | } |
1479 | |
1480 | return ret; |
1481 | } |
1482 | |
1483 | static int restart_bfa(struct bfad_s *bfad) |
1484 | { |
1485 | unsigned long flags; |
1486 | struct pci_dev *pdev = bfad->pcidev; |
1487 | |
1488 | bfa_attach(bfa: &bfad->bfa, bfad, cfg: &bfad->ioc_cfg, |
1489 | meminfo: &bfad->meminfo, pcidev: &bfad->hal_pcidev); |
1490 | |
1491 | /* Enable Interrupt and wait bfa_init completion */ |
1492 | if (bfad_setup_intr(bfad)) { |
1493 | dev_printk(KERN_WARNING, &pdev->dev, |
1494 | "%s: bfad_setup_intr failed\n" , bfad->pci_name); |
1495 | bfa_sm_send_event(bfad, BFAD_E_INIT_FAILED); |
1496 | return -1; |
1497 | } |
1498 | |
1499 | init_completion(x: &bfad->comp); |
1500 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1501 | bfa_iocfc_init(bfa: &bfad->bfa); |
1502 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1503 | |
1504 | /* Set up interrupt handler for each vectors */ |
1505 | if ((bfad->bfad_flags & BFAD_MSIX_ON) && |
1506 | bfad_install_msix_handler(bfad)) |
1507 | dev_printk(KERN_WARNING, &pdev->dev, |
1508 | "%s: install_msix failed.\n" , bfad->pci_name); |
1509 | |
1510 | bfad_init_timer(bfad); |
1511 | wait_for_completion(&bfad->comp); |
1512 | bfad_drv_start(bfad); |
1513 | |
1514 | return 0; |
1515 | } |
1516 | |
1517 | /* |
1518 | * PCI Error Recovery entry, re-initialize the chip. |
1519 | */ |
1520 | static pci_ers_result_t |
1521 | bfad_pci_slot_reset(struct pci_dev *pdev) |
1522 | { |
1523 | struct bfad_s *bfad = pci_get_drvdata(pdev); |
1524 | u8 byte; |
1525 | int rc; |
1526 | |
1527 | dev_printk(KERN_ERR, &pdev->dev, |
1528 | "bfad_pci_slot_reset flags: 0x%x\n" , bfad->bfad_flags); |
1529 | |
1530 | if (pci_enable_device(dev: pdev)) { |
1531 | dev_printk(KERN_ERR, &pdev->dev, "Cannot re-enable " |
1532 | "PCI device after reset.\n" ); |
1533 | return PCI_ERS_RESULT_DISCONNECT; |
1534 | } |
1535 | |
1536 | pci_restore_state(dev: pdev); |
1537 | |
1538 | /* |
1539 | * Read some byte (e.g. DMA max. payload size which can't |
1540 | * be 0xff any time) to make sure - we did not hit another PCI error |
1541 | * in the middle of recovery. If we did, then declare permanent failure. |
1542 | */ |
1543 | pci_read_config_byte(dev: pdev, where: 0x68, val: &byte); |
1544 | if (byte == 0xff) { |
1545 | dev_printk(KERN_ERR, &pdev->dev, |
1546 | "slot_reset failed ... got another PCI error !\n" ); |
1547 | goto out_disable_device; |
1548 | } |
1549 | |
1550 | pci_save_state(dev: pdev); |
1551 | pci_set_master(dev: pdev); |
1552 | |
1553 | rc = dma_set_mask_and_coherent(dev: &bfad->pcidev->dev, DMA_BIT_MASK(64)); |
1554 | if (rc) |
1555 | goto out_disable_device; |
1556 | |
1557 | if (restart_bfa(bfad) == -1) |
1558 | goto out_disable_device; |
1559 | |
1560 | dev_printk(KERN_WARNING, &pdev->dev, |
1561 | "slot_reset completed flags: 0x%x!\n" , bfad->bfad_flags); |
1562 | |
1563 | return PCI_ERS_RESULT_RECOVERED; |
1564 | |
1565 | out_disable_device: |
1566 | pci_disable_device(dev: pdev); |
1567 | return PCI_ERS_RESULT_DISCONNECT; |
1568 | } |
1569 | |
1570 | static pci_ers_result_t |
1571 | bfad_pci_mmio_enabled(struct pci_dev *pdev) |
1572 | { |
1573 | unsigned long flags; |
1574 | struct bfad_s *bfad = pci_get_drvdata(pdev); |
1575 | |
1576 | dev_printk(KERN_INFO, &pdev->dev, "mmio_enabled\n" ); |
1577 | |
1578 | /* Fetch FW diagnostic information */ |
1579 | bfa_ioc_debug_save_ftrc(ioc: &bfad->bfa.ioc); |
1580 | |
1581 | /* Cancel all pending IOs */ |
1582 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1583 | init_completion(x: &bfad->comp); |
1584 | bfa_fcs_stop(fcs: &bfad->bfa_fcs); |
1585 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1586 | wait_for_completion(&bfad->comp); |
1587 | |
1588 | bfad_remove_intr(bfad); |
1589 | del_timer_sync(timer: &bfad->hal_tmo); |
1590 | pci_disable_device(dev: pdev); |
1591 | |
1592 | return PCI_ERS_RESULT_NEED_RESET; |
1593 | } |
1594 | |
1595 | static void |
1596 | bfad_pci_resume(struct pci_dev *pdev) |
1597 | { |
1598 | unsigned long flags; |
1599 | struct bfad_s *bfad = pci_get_drvdata(pdev); |
1600 | |
1601 | dev_printk(KERN_WARNING, &pdev->dev, "resume\n" ); |
1602 | |
1603 | /* wait until the link is online */ |
1604 | bfad_rport_online_wait(bfad); |
1605 | |
1606 | spin_lock_irqsave(&bfad->bfad_lock, flags); |
1607 | bfad->bfad_flags &= ~BFAD_EEH_BUSY; |
1608 | spin_unlock_irqrestore(lock: &bfad->bfad_lock, flags); |
1609 | } |
1610 | |
1611 | struct pci_device_id bfad_id_table[] = { |
1612 | { |
1613 | .vendor = BFA_PCI_VENDOR_ID_BROCADE, |
1614 | .device = BFA_PCI_DEVICE_ID_FC_8G2P, |
1615 | .subvendor = PCI_ANY_ID, |
1616 | .subdevice = PCI_ANY_ID, |
1617 | }, |
1618 | { |
1619 | .vendor = BFA_PCI_VENDOR_ID_BROCADE, |
1620 | .device = BFA_PCI_DEVICE_ID_FC_8G1P, |
1621 | .subvendor = PCI_ANY_ID, |
1622 | .subdevice = PCI_ANY_ID, |
1623 | }, |
1624 | { |
1625 | .vendor = BFA_PCI_VENDOR_ID_BROCADE, |
1626 | .device = BFA_PCI_DEVICE_ID_CT, |
1627 | .subvendor = PCI_ANY_ID, |
1628 | .subdevice = PCI_ANY_ID, |
1629 | .class = (PCI_CLASS_SERIAL_FIBER << 8), |
1630 | .class_mask = ~0, |
1631 | }, |
1632 | { |
1633 | .vendor = BFA_PCI_VENDOR_ID_BROCADE, |
1634 | .device = BFA_PCI_DEVICE_ID_CT_FC, |
1635 | .subvendor = PCI_ANY_ID, |
1636 | .subdevice = PCI_ANY_ID, |
1637 | .class = (PCI_CLASS_SERIAL_FIBER << 8), |
1638 | .class_mask = ~0, |
1639 | }, |
1640 | { |
1641 | .vendor = BFA_PCI_VENDOR_ID_BROCADE, |
1642 | .device = BFA_PCI_DEVICE_ID_CT2, |
1643 | .subvendor = PCI_ANY_ID, |
1644 | .subdevice = PCI_ANY_ID, |
1645 | .class = (PCI_CLASS_SERIAL_FIBER << 8), |
1646 | .class_mask = ~0, |
1647 | }, |
1648 | |
1649 | { |
1650 | .vendor = BFA_PCI_VENDOR_ID_BROCADE, |
1651 | .device = BFA_PCI_DEVICE_ID_CT2_QUAD, |
1652 | .subvendor = PCI_ANY_ID, |
1653 | .subdevice = PCI_ANY_ID, |
1654 | .class = (PCI_CLASS_SERIAL_FIBER << 8), |
1655 | .class_mask = ~0, |
1656 | }, |
1657 | {0, 0}, |
1658 | }; |
1659 | |
1660 | MODULE_DEVICE_TABLE(pci, bfad_id_table); |
1661 | |
1662 | /* |
1663 | * PCI error recovery handlers. |
1664 | */ |
1665 | static struct pci_error_handlers bfad_err_handler = { |
1666 | .error_detected = bfad_pci_error_detected, |
1667 | .slot_reset = bfad_pci_slot_reset, |
1668 | .mmio_enabled = bfad_pci_mmio_enabled, |
1669 | .resume = bfad_pci_resume, |
1670 | }; |
1671 | |
1672 | static struct pci_driver bfad_pci_driver = { |
1673 | .name = BFAD_DRIVER_NAME, |
1674 | .id_table = bfad_id_table, |
1675 | .probe = bfad_pci_probe, |
1676 | .remove = bfad_pci_remove, |
1677 | .err_handler = &bfad_err_handler, |
1678 | }; |
1679 | |
1680 | /* |
1681 | * Driver module init. |
1682 | */ |
1683 | static int __init |
1684 | bfad_init(void) |
1685 | { |
1686 | int error = 0; |
1687 | |
1688 | pr_info("QLogic BR-series BFA FC/FCOE SCSI driver - version: %s\n" , |
1689 | BFAD_DRIVER_VERSION); |
1690 | |
1691 | if (num_sgpgs > 0) |
1692 | num_sgpgs_parm = num_sgpgs; |
1693 | |
1694 | error = bfad_im_module_init(); |
1695 | if (error) { |
1696 | error = -ENOMEM; |
1697 | printk(KERN_WARNING "bfad_im_module_init failure\n" ); |
1698 | goto ext; |
1699 | } |
1700 | |
1701 | if (strcmp(FCPI_NAME, " fcpim" ) == 0) |
1702 | supported_fc4s |= BFA_LPORT_ROLE_FCP_IM; |
1703 | |
1704 | bfa_auto_recover = ioc_auto_recover; |
1705 | bfa_fcs_rport_set_del_timeout(rport_tmo: rport_del_timeout); |
1706 | bfa_fcs_rport_set_max_logins(max_logins: max_rport_logins); |
1707 | |
1708 | error = pci_register_driver(&bfad_pci_driver); |
1709 | if (error) { |
1710 | printk(KERN_WARNING "pci_register_driver failure\n" ); |
1711 | goto ext; |
1712 | } |
1713 | |
1714 | return 0; |
1715 | |
1716 | ext: |
1717 | bfad_im_module_exit(); |
1718 | return error; |
1719 | } |
1720 | |
1721 | /* |
1722 | * Driver module exit. |
1723 | */ |
1724 | static void __exit |
1725 | bfad_exit(void) |
1726 | { |
1727 | pci_unregister_driver(dev: &bfad_pci_driver); |
1728 | bfad_im_module_exit(); |
1729 | bfad_free_fwimg(); |
1730 | } |
1731 | |
1732 | /* Firmware handling */ |
1733 | static void |
1734 | bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image, |
1735 | u32 *bfi_image_size, char *fw_name) |
1736 | { |
1737 | const struct firmware *fw; |
1738 | |
1739 | if (request_firmware(fw: &fw, name: fw_name, device: &pdev->dev)) { |
1740 | printk(KERN_ALERT "Can't locate firmware %s\n" , fw_name); |
1741 | *bfi_image = NULL; |
1742 | goto out; |
1743 | } |
1744 | |
1745 | *bfi_image = vmalloc(size: fw->size); |
1746 | if (NULL == *bfi_image) { |
1747 | printk(KERN_ALERT "Fail to allocate buffer for fw image " |
1748 | "size=%x!\n" , (u32) fw->size); |
1749 | goto out; |
1750 | } |
1751 | |
1752 | memcpy(*bfi_image, fw->data, fw->size); |
1753 | *bfi_image_size = fw->size/sizeof(u32); |
1754 | out: |
1755 | release_firmware(fw); |
1756 | } |
1757 | |
1758 | static u32 * |
1759 | bfad_load_fwimg(struct pci_dev *pdev) |
1760 | { |
1761 | if (bfa_asic_id_ct2(pdev->device)) { |
1762 | if (bfi_image_ct2_size == 0) |
1763 | bfad_read_firmware(pdev, bfi_image: &bfi_image_ct2, |
1764 | bfi_image_size: &bfi_image_ct2_size, BFAD_FW_FILE_CT2); |
1765 | return bfi_image_ct2; |
1766 | } else if (bfa_asic_id_ct(pdev->device)) { |
1767 | if (bfi_image_ct_size == 0) |
1768 | bfad_read_firmware(pdev, bfi_image: &bfi_image_ct, |
1769 | bfi_image_size: &bfi_image_ct_size, BFAD_FW_FILE_CT); |
1770 | return bfi_image_ct; |
1771 | } else if (bfa_asic_id_cb(pdev->device)) { |
1772 | if (bfi_image_cb_size == 0) |
1773 | bfad_read_firmware(pdev, bfi_image: &bfi_image_cb, |
1774 | bfi_image_size: &bfi_image_cb_size, BFAD_FW_FILE_CB); |
1775 | return bfi_image_cb; |
1776 | } |
1777 | |
1778 | return NULL; |
1779 | } |
1780 | |
1781 | static void |
1782 | bfad_free_fwimg(void) |
1783 | { |
1784 | if (bfi_image_ct2_size && bfi_image_ct2) |
1785 | vfree(addr: bfi_image_ct2); |
1786 | if (bfi_image_ct_size && bfi_image_ct) |
1787 | vfree(addr: bfi_image_ct); |
1788 | if (bfi_image_cb_size && bfi_image_cb) |
1789 | vfree(addr: bfi_image_cb); |
1790 | } |
1791 | |
1792 | module_init(bfad_init); |
1793 | module_exit(bfad_exit); |
1794 | MODULE_LICENSE("GPL" ); |
1795 | MODULE_DESCRIPTION("QLogic BR-series Fibre Channel HBA Driver" BFAD_PROTO_NAME); |
1796 | MODULE_AUTHOR("QLogic Corporation" ); |
1797 | MODULE_VERSION(BFAD_DRIVER_VERSION); |
1798 | |