bfad.c revision 1c8a4c37494932acd59079b4fc8d8f69fb329c2a
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/**
19 *  bfad.c Linux driver PCI interface module.
20 */
21
22#include <linux/module.h>
23#include <linux/kthread.h>
24#include "bfad_drv.h"
25#include "bfad_im.h"
26#include "bfad_tm.h"
27#include "bfad_ipfc.h"
28#include "bfad_trcmod.h"
29#include <fcb/bfa_fcb_vf.h>
30#include <fcb/bfa_fcb_rport.h>
31#include <fcb/bfa_fcb_port.h>
32#include <fcb/bfa_fcb.h>
33
34BFA_TRC_FILE(LDRV, BFAD);
35static DEFINE_MUTEX(bfad_mutex);
36LIST_HEAD(bfad_list);
37static int      bfad_inst;
38int bfad_supported_fc4s;
39
40static char     *host_name;
41static char     *os_name;
42static char     *os_patch;
43static int      num_rports;
44static int      num_ios;
45static int      num_tms;
46static int      num_fcxps;
47static int      num_ufbufs;
48static int      reqq_size;
49static int      rspq_size;
50static int      num_sgpgs;
51static int      rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT;
52static int      bfa_io_max_sge = BFAD_IO_MAX_SGE;
53static int      log_level = BFA_LOG_WARNING;
54static int      ioc_auto_recover = BFA_TRUE;
55static int      ipfc_enable = BFA_FALSE;
56static int      ipfc_mtu = -1;
57static int	fdmi_enable = BFA_TRUE;
58int 		bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH;
59int      	bfa_linkup_delay = -1;
60
61module_param(os_name, charp, S_IRUGO | S_IWUSR);
62module_param(os_patch, charp, S_IRUGO | S_IWUSR);
63module_param(host_name, charp, S_IRUGO | S_IWUSR);
64module_param(num_rports, int, S_IRUGO | S_IWUSR);
65module_param(num_ios, int, S_IRUGO | S_IWUSR);
66module_param(num_tms, int, S_IRUGO | S_IWUSR);
67module_param(num_fcxps, int, S_IRUGO | S_IWUSR);
68module_param(num_ufbufs, int, S_IRUGO | S_IWUSR);
69module_param(reqq_size, int, S_IRUGO | S_IWUSR);
70module_param(rspq_size, int, S_IRUGO | S_IWUSR);
71module_param(num_sgpgs, int, S_IRUGO | S_IWUSR);
72module_param(rport_del_timeout, int, S_IRUGO | S_IWUSR);
73module_param(bfa_lun_queue_depth, int, S_IRUGO | S_IWUSR);
74module_param(bfa_io_max_sge, int, S_IRUGO | S_IWUSR);
75module_param(log_level, int, S_IRUGO | S_IWUSR);
76module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR);
77module_param(ipfc_enable, int, S_IRUGO | S_IWUSR);
78module_param(ipfc_mtu, int, S_IRUGO | S_IWUSR);
79module_param(fdmi_enable, int, S_IRUGO | S_IWUSR);
80module_param(bfa_linkup_delay, int, S_IRUGO | S_IWUSR);
81
82/*
83 * Stores the module parm num_sgpgs value;
84 * used to reset for bfad next instance.
85 */
86static int num_sgpgs_parm;
87
88static bfa_status_t
89bfad_fc4_probe(struct bfad_s *bfad)
90{
91	int             rc;
92
93	rc = bfad_im_probe(bfad);
94	if (rc != BFA_STATUS_OK)
95		goto ext;
96
97	bfad_tm_probe(bfad);
98
99	if (ipfc_enable)
100		bfad_ipfc_probe(bfad);
101
102	bfad->bfad_flags |= BFAD_FC4_PROBE_DONE;
103ext:
104	return rc;
105}
106
107static void
108bfad_fc4_probe_undo(struct bfad_s *bfad)
109{
110	bfad_im_probe_undo(bfad);
111	bfad_tm_probe_undo(bfad);
112	if (ipfc_enable)
113		bfad_ipfc_probe_undo(bfad);
114	bfad->bfad_flags &= ~BFAD_FC4_PROBE_DONE;
115}
116
117static void
118bfad_fc4_probe_post(struct bfad_s *bfad)
119{
120	if (bfad->im)
121		bfad_im_probe_post(bfad->im);
122
123	bfad_tm_probe_post(bfad);
124	if (ipfc_enable)
125		bfad_ipfc_probe_post(bfad);
126}
127
128static bfa_status_t
129bfad_fc4_port_new(struct bfad_s *bfad, struct bfad_port_s *port, int roles)
130{
131	int             rc = BFA_STATUS_FAILED;
132
133	if (roles & BFA_PORT_ROLE_FCP_IM)
134		rc = bfad_im_port_new(bfad, port);
135	if (rc != BFA_STATUS_OK)
136		goto ext;
137
138	if (roles & BFA_PORT_ROLE_FCP_TM)
139		rc = bfad_tm_port_new(bfad, port);
140	if (rc != BFA_STATUS_OK)
141		goto ext;
142
143	if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
144		rc = bfad_ipfc_port_new(bfad, port, port->pvb_type);
145ext:
146	return rc;
147}
148
149static void
150bfad_fc4_port_delete(struct bfad_s *bfad, struct bfad_port_s *port, int roles)
151{
152	if (roles & BFA_PORT_ROLE_FCP_IM)
153		bfad_im_port_delete(bfad, port);
154
155	if (roles & BFA_PORT_ROLE_FCP_TM)
156		bfad_tm_port_delete(bfad, port);
157
158	if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
159		bfad_ipfc_port_delete(bfad, port);
160}
161
162/**
163 *  BFA callbacks
164 */
165void
166bfad_hcb_comp(void *arg, bfa_status_t status)
167{
168	struct bfad_hal_comp *fcomp = (struct bfad_hal_comp *)arg;
169
170	fcomp->status = status;
171	complete(&fcomp->comp);
172}
173
174/**
175 * bfa_init callback
176 */
177void
178bfa_cb_init(void *drv, bfa_status_t init_status)
179{
180	struct bfad_s  *bfad = drv;
181
182	if (init_status == BFA_STATUS_OK) {
183		bfad->bfad_flags |= BFAD_HAL_INIT_DONE;
184
185		/* If BFAD_HAL_INIT_FAIL flag is set:
186		 * Wake up the kernel thread to start
187		 * the bfad operations after HAL init done
188		 */
189		if ((bfad->bfad_flags & BFAD_HAL_INIT_FAIL)) {
190			bfad->bfad_flags &= ~BFAD_HAL_INIT_FAIL;
191			wake_up_process(bfad->bfad_tsk);
192		}
193	}
194
195	complete(&bfad->comp);
196}
197
198
199
200/**
201 *  BFA_FCS callbacks
202 */
203static struct bfad_port_s *
204bfad_get_drv_port(struct bfad_s *bfad, struct bfad_vf_s *vf_drv,
205		  struct bfad_vport_s *vp_drv)
206{
207	return (vp_drv) ? (&(vp_drv)->drv_port)
208		: ((vf_drv) ? (&(vf_drv)->base_port) : (&(bfad)->pport));
209}
210
211struct bfad_port_s *
212bfa_fcb_port_new(struct bfad_s *bfad, struct bfa_fcs_port_s *port,
213		 enum bfa_port_role roles, struct bfad_vf_s *vf_drv,
214		 struct bfad_vport_s *vp_drv)
215{
216	bfa_status_t    rc;
217	struct bfad_port_s *port_drv;
218
219	if (!vp_drv && !vf_drv) {
220		port_drv = &bfad->pport;
221		port_drv->pvb_type = BFAD_PORT_PHYS_BASE;
222	} else if (!vp_drv && vf_drv) {
223		port_drv = &vf_drv->base_port;
224		port_drv->pvb_type = BFAD_PORT_VF_BASE;
225	} else if (vp_drv && !vf_drv) {
226		port_drv = &vp_drv->drv_port;
227		port_drv->pvb_type = BFAD_PORT_PHYS_VPORT;
228	} else {
229		port_drv = &vp_drv->drv_port;
230		port_drv->pvb_type = BFAD_PORT_VF_VPORT;
231	}
232
233	port_drv->fcs_port = port;
234	port_drv->roles = roles;
235	rc = bfad_fc4_port_new(bfad, port_drv, roles);
236	if (rc != BFA_STATUS_OK) {
237		bfad_fc4_port_delete(bfad, port_drv, roles);
238		port_drv = NULL;
239	}
240
241	return port_drv;
242}
243
244void
245bfa_fcb_port_delete(struct bfad_s *bfad, enum bfa_port_role roles,
246		    struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
247{
248	struct bfad_port_s *port_drv;
249
250	/*
251	 * this will be only called from rmmod context
252	 */
253	if (vp_drv && !vp_drv->comp_del) {
254		port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv);
255		bfa_trc(bfad, roles);
256		bfad_fc4_port_delete(bfad, port_drv, roles);
257	}
258}
259
260void
261bfa_fcb_port_online(struct bfad_s *bfad, enum bfa_port_role roles,
262		    struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
263{
264	struct bfad_port_s *port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv);
265
266	if (roles & BFA_PORT_ROLE_FCP_IM)
267		bfad_im_port_online(bfad, port_drv);
268
269	if (roles & BFA_PORT_ROLE_FCP_TM)
270		bfad_tm_port_online(bfad, port_drv);
271
272	if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
273		bfad_ipfc_port_online(bfad, port_drv);
274
275	bfad->bfad_flags |= BFAD_PORT_ONLINE;
276}
277
278void
279bfa_fcb_port_offline(struct bfad_s *bfad, enum bfa_port_role roles,
280		     struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
281{
282	struct bfad_port_s *port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv);
283
284	if (roles & BFA_PORT_ROLE_FCP_IM)
285		bfad_im_port_offline(bfad, port_drv);
286
287	if (roles & BFA_PORT_ROLE_FCP_TM)
288		bfad_tm_port_offline(bfad, port_drv);
289
290	if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
291		bfad_ipfc_port_offline(bfad, port_drv);
292}
293
294void
295bfa_fcb_vport_delete(struct bfad_vport_s *vport_drv)
296{
297	if (vport_drv->comp_del) {
298		complete(vport_drv->comp_del);
299		return;
300	}
301
302	kfree(vport_drv);
303}
304
305/**
306 * FCS RPORT alloc callback, after successful PLOGI by FCS
307 */
308bfa_status_t
309bfa_fcb_rport_alloc(struct bfad_s *bfad, struct bfa_fcs_rport_s **rport,
310		    struct bfad_rport_s **rport_drv)
311{
312	bfa_status_t    rc = BFA_STATUS_OK;
313
314	*rport_drv = kzalloc(sizeof(struct bfad_rport_s), GFP_ATOMIC);
315	if (*rport_drv == NULL) {
316		rc = BFA_STATUS_ENOMEM;
317		goto ext;
318	}
319
320	*rport = &(*rport_drv)->fcs_rport;
321
322ext:
323	return rc;
324}
325
326
327
328void
329bfad_hal_mem_release(struct bfad_s *bfad)
330{
331	int             i;
332	struct bfa_meminfo_s *hal_meminfo = &bfad->meminfo;
333	struct bfa_mem_elem_s *meminfo_elem;
334
335	for (i = 0; i < BFA_MEM_TYPE_MAX; i++) {
336		meminfo_elem = &hal_meminfo->meminfo[i];
337		if (meminfo_elem->kva != NULL) {
338			switch (meminfo_elem->mem_type) {
339			case BFA_MEM_TYPE_KVA:
340				vfree(meminfo_elem->kva);
341				break;
342			case BFA_MEM_TYPE_DMA:
343				dma_free_coherent(&bfad->pcidev->dev,
344						meminfo_elem->mem_len,
345						meminfo_elem->kva,
346						(dma_addr_t) meminfo_elem->dma);
347				break;
348			default:
349				bfa_assert(0);
350				break;
351			}
352		}
353	}
354
355	memset(hal_meminfo, 0, sizeof(struct bfa_meminfo_s));
356}
357
358void
359bfad_update_hal_cfg(struct bfa_iocfc_cfg_s *bfa_cfg)
360{
361	if (num_rports > 0)
362		bfa_cfg->fwcfg.num_rports = num_rports;
363	if (num_ios > 0)
364		bfa_cfg->fwcfg.num_ioim_reqs = num_ios;
365	if (num_tms > 0)
366		bfa_cfg->fwcfg.num_tskim_reqs = num_tms;
367	if (num_fcxps > 0)
368		bfa_cfg->fwcfg.num_fcxp_reqs = num_fcxps;
369	if (num_ufbufs > 0)
370		bfa_cfg->fwcfg.num_uf_bufs = num_ufbufs;
371	if (reqq_size > 0)
372		bfa_cfg->drvcfg.num_reqq_elems = reqq_size;
373	if (rspq_size > 0)
374		bfa_cfg->drvcfg.num_rspq_elems = rspq_size;
375	if (num_sgpgs > 0)
376		bfa_cfg->drvcfg.num_sgpgs = num_sgpgs;
377
378	/*
379	 * populate the hal values back to the driver for sysfs use.
380	 * otherwise, the default values will be shown as 0 in sysfs
381	 */
382	num_rports = bfa_cfg->fwcfg.num_rports;
383	num_ios    = bfa_cfg->fwcfg.num_ioim_reqs;
384	num_tms	   = bfa_cfg->fwcfg.num_tskim_reqs;
385	num_fcxps  = bfa_cfg->fwcfg.num_fcxp_reqs;
386	num_ufbufs = bfa_cfg->fwcfg.num_uf_bufs;
387	reqq_size  = bfa_cfg->drvcfg.num_reqq_elems;
388	rspq_size  = bfa_cfg->drvcfg.num_rspq_elems;
389	num_sgpgs  = bfa_cfg->drvcfg.num_sgpgs;
390}
391
392bfa_status_t
393bfad_hal_mem_alloc(struct bfad_s *bfad)
394{
395	struct bfa_meminfo_s *hal_meminfo = &bfad->meminfo;
396	struct bfa_mem_elem_s *meminfo_elem;
397	bfa_status_t    rc = BFA_STATUS_OK;
398	dma_addr_t      phys_addr;
399	int             retry_count = 0;
400	int             reset_value = 1;
401	int             min_num_sgpgs = 512;
402	void           *kva;
403	int             i;
404
405	bfa_cfg_get_default(&bfad->ioc_cfg);
406
407retry:
408	bfad_update_hal_cfg(&bfad->ioc_cfg);
409	bfad->cfg_data.ioc_queue_depth = bfad->ioc_cfg.fwcfg.num_ioim_reqs;
410	bfa_cfg_get_meminfo(&bfad->ioc_cfg, hal_meminfo);
411
412	for (i = 0; i < BFA_MEM_TYPE_MAX; i++) {
413		meminfo_elem = &hal_meminfo->meminfo[i];
414		switch (meminfo_elem->mem_type) {
415		case BFA_MEM_TYPE_KVA:
416			kva = vmalloc(meminfo_elem->mem_len);
417			if (kva == NULL) {
418				bfad_hal_mem_release(bfad);
419				rc = BFA_STATUS_ENOMEM;
420				goto ext;
421			}
422			memset(kva, 0, meminfo_elem->mem_len);
423			meminfo_elem->kva = kva;
424			break;
425		case BFA_MEM_TYPE_DMA:
426			kva = dma_alloc_coherent(&bfad->pcidev->dev,
427					meminfo_elem->mem_len,
428					&phys_addr, GFP_KERNEL);
429			if (kva == NULL) {
430				bfad_hal_mem_release(bfad);
431				/*
432				 * If we cannot allocate with default
433				 * num_sgpages try with half the value.
434				 */
435				if (num_sgpgs > min_num_sgpgs) {
436					printk(KERN_INFO "bfad[%d]: memory"
437						" allocation failed with"
438						" num_sgpgs: %d\n",
439						bfad->inst_no, num_sgpgs);
440					nextLowerInt(&num_sgpgs);
441					printk(KERN_INFO "bfad[%d]: trying to"
442						" allocate memory with"
443						" num_sgpgs: %d\n",
444						bfad->inst_no, num_sgpgs);
445					retry_count++;
446					goto retry;
447				} else {
448					if (num_sgpgs_parm > 0)
449						num_sgpgs = num_sgpgs_parm;
450					else {
451						reset_value =
452							(1 << retry_count);
453						num_sgpgs *= reset_value;
454					}
455					rc = BFA_STATUS_ENOMEM;
456					goto ext;
457				}
458			}
459
460			if (num_sgpgs_parm > 0)
461				num_sgpgs = num_sgpgs_parm;
462			else {
463				reset_value = (1 << retry_count);
464				num_sgpgs *= reset_value;
465			}
466
467			memset(kva, 0, meminfo_elem->mem_len);
468			meminfo_elem->kva = kva;
469			meminfo_elem->dma = phys_addr;
470			break;
471		default:
472			break;
473
474		}
475	}
476ext:
477	return rc;
478}
479
480/**
481 * Create a vport under a vf.
482 */
483bfa_status_t
484bfad_vport_create(struct bfad_s *bfad, u16 vf_id,
485		  struct bfa_port_cfg_s *port_cfg)
486{
487	struct bfad_vport_s *vport;
488	int             rc = BFA_STATUS_OK;
489	unsigned long   flags;
490	struct completion fcomp;
491
492	vport = kzalloc(sizeof(struct bfad_vport_s), GFP_KERNEL);
493	if (!vport) {
494		rc = BFA_STATUS_ENOMEM;
495		goto ext;
496	}
497
498	vport->drv_port.bfad = bfad;
499	spin_lock_irqsave(&bfad->bfad_lock, flags);
500	rc = bfa_fcs_vport_create(&vport->fcs_vport, &bfad->bfa_fcs, vf_id,
501				  port_cfg, vport);
502	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
503
504	if (rc != BFA_STATUS_OK)
505		goto ext_free_vport;
506
507	if (port_cfg->roles & BFA_PORT_ROLE_FCP_IM) {
508		rc = bfad_im_scsi_host_alloc(bfad, vport->drv_port.im_port);
509		if (rc != BFA_STATUS_OK)
510			goto ext_free_fcs_vport;
511	}
512
513	spin_lock_irqsave(&bfad->bfad_lock, flags);
514	bfa_fcs_vport_start(&vport->fcs_vport);
515	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
516
517	return BFA_STATUS_OK;
518
519ext_free_fcs_vport:
520	spin_lock_irqsave(&bfad->bfad_lock, flags);
521	vport->comp_del = &fcomp;
522	init_completion(vport->comp_del);
523	bfa_fcs_vport_delete(&vport->fcs_vport);
524	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
525	wait_for_completion(vport->comp_del);
526ext_free_vport:
527	kfree(vport);
528ext:
529	return rc;
530}
531
532/**
533 * Create a vf and its base vport implicitely.
534 */
535bfa_status_t
536bfad_vf_create(struct bfad_s *bfad, u16 vf_id,
537	       struct bfa_port_cfg_s *port_cfg)
538{
539	struct bfad_vf_s *vf;
540	int             rc = BFA_STATUS_OK;
541
542	vf = kzalloc(sizeof(struct bfad_vf_s), GFP_KERNEL);
543	if (!vf) {
544		rc = BFA_STATUS_FAILED;
545		goto ext;
546	}
547
548	rc = bfa_fcs_vf_create(&vf->fcs_vf, &bfad->bfa_fcs, vf_id, port_cfg,
549			       vf);
550	if (rc != BFA_STATUS_OK)
551		kfree(vf);
552ext:
553	return rc;
554}
555
556void
557bfad_bfa_tmo(unsigned long data)
558{
559	struct bfad_s  *bfad = (struct bfad_s *)data;
560	unsigned long   flags;
561	struct list_head  doneq;
562
563	spin_lock_irqsave(&bfad->bfad_lock, flags);
564
565	bfa_timer_tick(&bfad->bfa);
566
567	bfa_comp_deq(&bfad->bfa, &doneq);
568	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
569
570	if (!list_empty(&doneq)) {
571		bfa_comp_process(&bfad->bfa, &doneq);
572		spin_lock_irqsave(&bfad->bfad_lock, flags);
573		bfa_comp_free(&bfad->bfa, &doneq);
574		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
575	}
576
577	mod_timer(&bfad->hal_tmo, jiffies + msecs_to_jiffies(BFA_TIMER_FREQ));
578}
579
580void
581bfad_init_timer(struct bfad_s *bfad)
582{
583	init_timer(&bfad->hal_tmo);
584	bfad->hal_tmo.function = bfad_bfa_tmo;
585	bfad->hal_tmo.data = (unsigned long)bfad;
586
587	mod_timer(&bfad->hal_tmo, jiffies + msecs_to_jiffies(BFA_TIMER_FREQ));
588}
589
590int
591bfad_pci_init(struct pci_dev *pdev, struct bfad_s *bfad)
592{
593	unsigned long   bar0_len;
594	int             rc = -ENODEV;
595
596	if (pci_enable_device(pdev)) {
597		BFA_PRINTF(BFA_ERR, "pci_enable_device fail %p\n", pdev);
598		goto out;
599	}
600
601	if (pci_request_regions(pdev, BFAD_DRIVER_NAME))
602		goto out_disable_device;
603
604	pci_set_master(pdev);
605
606
607	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0)
608		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) {
609			BFA_PRINTF(BFA_ERR, "pci_set_dma_mask fail %p\n", pdev);
610			goto out_release_region;
611		}
612
613	bfad->pci_bar0_map = pci_resource_start(pdev, 0);
614	bar0_len = pci_resource_len(pdev, 0);
615	bfad->pci_bar0_kva = ioremap(bfad->pci_bar0_map, bar0_len);
616
617	if (bfad->pci_bar0_kva == NULL) {
618		BFA_PRINTF(BFA_ERR, "Fail to map bar0\n");
619		goto out_release_region;
620	}
621
622	bfad->hal_pcidev.pci_slot = PCI_SLOT(pdev->devfn);
623	bfad->hal_pcidev.pci_func = PCI_FUNC(pdev->devfn);
624	bfad->hal_pcidev.pci_bar_kva = bfad->pci_bar0_kva;
625	bfad->hal_pcidev.device_id = pdev->device;
626	bfad->pci_name = pci_name(pdev);
627
628	bfad->pci_attr.vendor_id = pdev->vendor;
629	bfad->pci_attr.device_id = pdev->device;
630	bfad->pci_attr.ssid = pdev->subsystem_device;
631	bfad->pci_attr.ssvid = pdev->subsystem_vendor;
632	bfad->pci_attr.pcifn = PCI_FUNC(pdev->devfn);
633
634	bfad->pcidev = pdev;
635	return 0;
636
637out_release_region:
638	pci_release_regions(pdev);
639out_disable_device:
640	pci_disable_device(pdev);
641out:
642	return rc;
643}
644
645void
646bfad_pci_uninit(struct pci_dev *pdev, struct bfad_s *bfad)
647{
648#if defined(__ia64__)
649	pci_iounmap(pdev, bfad->pci_bar0_kva);
650#else
651	iounmap(bfad->pci_bar0_kva);
652#endif
653	pci_release_regions(pdev);
654	pci_disable_device(pdev);
655	pci_set_drvdata(pdev, NULL);
656}
657
658void
659bfad_fcs_port_cfg(struct bfad_s *bfad)
660{
661	struct bfa_port_cfg_s port_cfg;
662	struct bfa_pport_attr_s attr;
663	char            symname[BFA_SYMNAME_MAXLEN];
664
665	sprintf(symname, "%s-%d", BFAD_DRIVER_NAME, bfad->inst_no);
666	memcpy(port_cfg.sym_name.symname, symname, strlen(symname));
667	bfa_fcport_get_attr(&bfad->bfa, &attr);
668	port_cfg.nwwn = attr.nwwn;
669	port_cfg.pwwn = attr.pwwn;
670
671	bfa_fcs_cfg_base_port(&bfad->bfa_fcs, &port_cfg);
672}
673
674bfa_status_t
675bfad_drv_init(struct bfad_s *bfad)
676{
677	bfa_status_t    rc;
678	unsigned long   flags;
679	struct bfa_fcs_driver_info_s driver_info;
680
681	bfad->cfg_data.rport_del_timeout = rport_del_timeout;
682	bfad->cfg_data.lun_queue_depth = bfa_lun_queue_depth;
683	bfad->cfg_data.io_max_sge = bfa_io_max_sge;
684	bfad->cfg_data.binding_method = FCP_PWWN_BINDING;
685
686	rc = bfad_hal_mem_alloc(bfad);
687	if (rc != BFA_STATUS_OK) {
688		printk(KERN_WARNING "bfad%d bfad_hal_mem_alloc failure\n",
689		       bfad->inst_no);
690		printk(KERN_WARNING
691			"Not enough memory to attach all Brocade HBA ports,"
692			" System may need more memory.\n");
693		goto out_hal_mem_alloc_failure;
694	}
695
696	bfa_init_log(&bfad->bfa, bfad->logmod);
697	bfa_init_trc(&bfad->bfa, bfad->trcmod);
698	bfa_init_aen(&bfad->bfa, bfad->aen);
699	memset(bfad->file_map, 0, sizeof(bfad->file_map));
700	bfa_init_plog(&bfad->bfa, &bfad->plog_buf);
701	bfa_plog_init(&bfad->plog_buf);
702	bfa_plog_str(&bfad->plog_buf, BFA_PL_MID_DRVR, BFA_PL_EID_DRIVER_START,
703		     0, "Driver Attach");
704
705	bfa_attach(&bfad->bfa, bfad, &bfad->ioc_cfg, &bfad->meminfo,
706		   &bfad->hal_pcidev);
707
708	init_completion(&bfad->comp);
709
710	/*
711	 * Enable Interrupt and wait bfa_init completion
712	 */
713	if (bfad_setup_intr(bfad)) {
714		printk(KERN_WARNING "bfad%d: bfad_setup_intr failed\n",
715		       bfad->inst_no);
716		goto out_setup_intr_failure;
717	}
718
719	spin_lock_irqsave(&bfad->bfad_lock, flags);
720	bfa_init(&bfad->bfa);
721	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
722
723	/*
724	 * Set up interrupt handler for each vectors
725	 */
726	if ((bfad->bfad_flags & BFAD_MSIX_ON)
727	    && bfad_install_msix_handler(bfad)) {
728		printk(KERN_WARNING "%s: install_msix failed, bfad%d\n",
729		       __func__, bfad->inst_no);
730	}
731
732	bfad_init_timer(bfad);
733
734	wait_for_completion(&bfad->comp);
735
736	memset(&driver_info, 0, sizeof(driver_info));
737	strncpy(driver_info.version, BFAD_DRIVER_VERSION,
738		sizeof(driver_info.version) - 1);
739	if (host_name)
740		strncpy(driver_info.host_machine_name, host_name,
741			sizeof(driver_info.host_machine_name) - 1);
742	if (os_name)
743		strncpy(driver_info.host_os_name, os_name,
744			sizeof(driver_info.host_os_name) - 1);
745	if (os_patch)
746		strncpy(driver_info.host_os_patch, os_patch,
747			sizeof(driver_info.host_os_patch) - 1);
748
749	strncpy(driver_info.os_device_name, bfad->pci_name,
750		sizeof(driver_info.os_device_name - 1));
751
752	/*
753	 * FCS INIT
754	 */
755	spin_lock_irqsave(&bfad->bfad_lock, flags);
756	bfa_fcs_log_init(&bfad->bfa_fcs, bfad->logmod);
757	bfa_fcs_trc_init(&bfad->bfa_fcs, bfad->trcmod);
758	bfa_fcs_aen_init(&bfad->bfa_fcs, bfad->aen);
759	bfa_fcs_attach(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE);
760
761	/* Do FCS init only when HAL init is done */
762	if ((bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
763		bfa_fcs_init(&bfad->bfa_fcs);
764		bfad->bfad_flags |= BFAD_FCS_INIT_DONE;
765	}
766
767	bfa_fcs_driver_info_init(&bfad->bfa_fcs, &driver_info);
768	bfa_fcs_set_fdmi_param(&bfad->bfa_fcs, fdmi_enable);
769	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
770
771	bfad->bfad_flags |= BFAD_DRV_INIT_DONE;
772	return BFA_STATUS_OK;
773
774out_setup_intr_failure:
775	bfa_detach(&bfad->bfa);
776	bfad_hal_mem_release(bfad);
777out_hal_mem_alloc_failure:
778	return BFA_STATUS_FAILED;
779}
780
781void
782bfad_drv_uninit(struct bfad_s *bfad)
783{
784	unsigned long   flags;
785
786	spin_lock_irqsave(&bfad->bfad_lock, flags);
787	init_completion(&bfad->comp);
788	bfa_stop(&bfad->bfa);
789	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
790	wait_for_completion(&bfad->comp);
791
792	del_timer_sync(&bfad->hal_tmo);
793	bfa_isr_disable(&bfad->bfa);
794	bfa_detach(&bfad->bfa);
795	bfad_remove_intr(bfad);
796	bfad_hal_mem_release(bfad);
797
798	bfad->bfad_flags &= ~BFAD_DRV_INIT_DONE;
799}
800
801void
802bfad_drv_start(struct bfad_s *bfad)
803{
804	unsigned long   flags;
805
806	spin_lock_irqsave(&bfad->bfad_lock, flags);
807	bfa_start(&bfad->bfa);
808	bfa_fcs_start(&bfad->bfa_fcs);
809	bfad->bfad_flags |= BFAD_HAL_START_DONE;
810	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
811
812	bfad_fc4_probe_post(bfad);
813}
814
815void
816bfad_drv_stop(struct bfad_s *bfad)
817{
818	unsigned long   flags;
819
820	spin_lock_irqsave(&bfad->bfad_lock, flags);
821	init_completion(&bfad->comp);
822	bfad->pport.flags |= BFAD_PORT_DELETE;
823	bfa_fcs_exit(&bfad->bfa_fcs);
824	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
825	wait_for_completion(&bfad->comp);
826
827	spin_lock_irqsave(&bfad->bfad_lock, flags);
828	init_completion(&bfad->comp);
829	bfa_stop(&bfad->bfa);
830	bfad->bfad_flags &= ~BFAD_HAL_START_DONE;
831	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
832	wait_for_completion(&bfad->comp);
833}
834
835bfa_status_t
836bfad_cfg_pport(struct bfad_s *bfad, enum bfa_port_role role)
837{
838	int             rc = BFA_STATUS_OK;
839
840	/*
841	 * Allocate scsi_host for the physical port
842	 */
843	if ((bfad_supported_fc4s & BFA_PORT_ROLE_FCP_IM)
844	    && (role & BFA_PORT_ROLE_FCP_IM)) {
845		if (bfad->pport.im_port == NULL) {
846			rc = BFA_STATUS_FAILED;
847			goto out;
848		}
849
850		rc = bfad_im_scsi_host_alloc(bfad, bfad->pport.im_port);
851		if (rc != BFA_STATUS_OK)
852			goto out;
853
854		bfad->pport.roles |= BFA_PORT_ROLE_FCP_IM;
855	}
856
857	bfad->bfad_flags |= BFAD_CFG_PPORT_DONE;
858
859out:
860	return rc;
861}
862
863void
864bfad_uncfg_pport(struct bfad_s *bfad)
865{
866	if ((bfad->pport.roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable) {
867		bfad_ipfc_port_delete(bfad, &bfad->pport);
868		bfad->pport.roles &= ~BFA_PORT_ROLE_FCP_IPFC;
869	}
870
871	if ((bfad_supported_fc4s & BFA_PORT_ROLE_FCP_IM)
872	    && (bfad->pport.roles & BFA_PORT_ROLE_FCP_IM)) {
873		bfad_im_scsi_host_free(bfad, bfad->pport.im_port);
874		bfad_im_port_clean(bfad->pport.im_port);
875		kfree(bfad->pport.im_port);
876		bfad->pport.roles &= ~BFA_PORT_ROLE_FCP_IM;
877	}
878
879	bfad->bfad_flags &= ~BFAD_CFG_PPORT_DONE;
880}
881
882void
883bfad_drv_log_level_set(struct bfad_s *bfad)
884{
885	if (log_level > BFA_LOG_INVALID && log_level <= BFA_LOG_LEVEL_MAX)
886		bfa_log_set_level_all(&bfad->log_data, log_level);
887}
888
889bfa_status_t
890bfad_start_ops(struct bfad_s *bfad)
891{
892	int retval;
893
894	/* PPORT FCS config */
895	bfad_fcs_port_cfg(bfad);
896
897	retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM);
898	if (retval != BFA_STATUS_OK)
899		goto out_cfg_pport_failure;
900
901	/* BFAD level FC4 (IM/TM/IPFC) specific resource allocation */
902	retval = bfad_fc4_probe(bfad);
903	if (retval != BFA_STATUS_OK) {
904		printk(KERN_WARNING "bfad_fc4_probe failed\n");
905		goto out_fc4_probe_failure;
906	}
907
908	bfad_drv_start(bfad);
909
910	/*
911	 * If bfa_linkup_delay is set to -1 default; try to retrive the
912	 * value using the bfad_os_get_linkup_delay(); else use the
913	 * passed in module param value as the bfa_linkup_delay.
914	 */
915	if (bfa_linkup_delay < 0) {
916
917		bfa_linkup_delay = bfad_os_get_linkup_delay(bfad);
918		bfad_os_rport_online_wait(bfad);
919		bfa_linkup_delay = -1;
920
921	} else {
922		bfad_os_rport_online_wait(bfad);
923	}
924
925	bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name);
926
927	return BFA_STATUS_OK;
928
929out_fc4_probe_failure:
930	bfad_fc4_probe_undo(bfad);
931	bfad_uncfg_pport(bfad);
932out_cfg_pport_failure:
933	return BFA_STATUS_FAILED;
934}
935
936int
937bfad_worker (void *ptr)
938{
939	struct bfad_s *bfad;
940	unsigned long   flags;
941
942	bfad = (struct bfad_s *)ptr;
943
944	while (!kthread_should_stop()) {
945
946		/* Check if the FCS init is done from bfad_drv_init;
947		 * if not done do FCS init and set the flag.
948		 */
949		if (!(bfad->bfad_flags & BFAD_FCS_INIT_DONE)) {
950			spin_lock_irqsave(&bfad->bfad_lock, flags);
951			bfa_fcs_init(&bfad->bfa_fcs);
952			bfad->bfad_flags |= BFAD_FCS_INIT_DONE;
953			spin_unlock_irqrestore(&bfad->bfad_lock, flags);
954		}
955
956		/* Start the bfad operations after HAL init done */
957		bfad_start_ops(bfad);
958
959		spin_lock_irqsave(&bfad->bfad_lock, flags);
960		bfad->bfad_tsk = NULL;
961		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
962
963		break;
964	}
965
966	return 0;
967}
968
969 /*
970  *  PCI_entry PCI driver entries * {
971  */
972
973/**
974 * PCI probe entry.
975 */
976int
977bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
978{
979	struct bfad_s  *bfad;
980	int             error = -ENODEV, retval;
981	char            buf[16];
982
983	/*
984	 * For single port cards - only claim function 0
985	 */
986	if ((pdev->device == BFA_PCI_DEVICE_ID_FC_8G1P)
987	    && (PCI_FUNC(pdev->devfn) != 0))
988		return -ENODEV;
989
990	BFA_TRACE(BFA_INFO, "bfad_pci_probe entry");
991
992	bfad = kzalloc(sizeof(struct bfad_s), GFP_KERNEL);
993	if (!bfad) {
994		error = -ENOMEM;
995		goto out;
996	}
997
998	bfad->trcmod = kzalloc(sizeof(struct bfa_trc_mod_s), GFP_KERNEL);
999	if (!bfad->trcmod) {
1000		printk(KERN_WARNING "Error alloc trace buffer!\n");
1001		error = -ENOMEM;
1002		goto out_alloc_trace_failure;
1003	}
1004
1005	/*
1006	 * LOG/TRACE INIT
1007	 */
1008	bfa_trc_init(bfad->trcmod);
1009	bfa_trc(bfad, bfad_inst);
1010
1011	bfad->logmod = &bfad->log_data;
1012	sprintf(buf, "%d", bfad_inst);
1013	bfa_log_init(bfad->logmod, buf, bfa_os_printf);
1014
1015	bfad_drv_log_level_set(bfad);
1016
1017	bfad->aen = &bfad->aen_buf;
1018
1019	if (!(bfad_load_fwimg(pdev))) {
1020		printk(KERN_WARNING "bfad_load_fwimg failure!\n");
1021		kfree(bfad->trcmod);
1022		goto out_alloc_trace_failure;
1023	}
1024
1025	retval = bfad_pci_init(pdev, bfad);
1026	if (retval) {
1027		printk(KERN_WARNING "bfad_pci_init failure!\n");
1028		error = retval;
1029		goto out_pci_init_failure;
1030	}
1031
1032	mutex_lock(&bfad_mutex);
1033	bfad->inst_no = bfad_inst++;
1034	list_add_tail(&bfad->list_entry, &bfad_list);
1035	mutex_unlock(&bfad_mutex);
1036
1037	spin_lock_init(&bfad->bfad_lock);
1038	pci_set_drvdata(pdev, bfad);
1039
1040	bfad->ref_count = 0;
1041	bfad->pport.bfad = bfad;
1042
1043	bfad->bfad_tsk = kthread_create(bfad_worker, (void *) bfad, "%s",
1044					"bfad_worker");
1045	if (IS_ERR(bfad->bfad_tsk)) {
1046		printk(KERN_INFO "bfad[%d]: Kernel thread"
1047			" creation failed!\n",
1048			bfad->inst_no);
1049		goto out_kthread_create_failure;
1050	}
1051
1052	retval = bfad_drv_init(bfad);
1053	if (retval != BFA_STATUS_OK)
1054		goto out_drv_init_failure;
1055	if (!(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
1056		bfad->bfad_flags |= BFAD_HAL_INIT_FAIL;
1057		printk(KERN_WARNING "bfad%d: hal init failed\n", bfad->inst_no);
1058		goto ok;
1059	}
1060
1061	retval = bfad_start_ops(bfad);
1062	if (retval != BFA_STATUS_OK)
1063		goto out_start_ops_failure;
1064
1065	kthread_stop(bfad->bfad_tsk);
1066	bfad->bfad_tsk = NULL;
1067
1068ok:
1069	return 0;
1070
1071out_start_ops_failure:
1072	bfad_drv_uninit(bfad);
1073out_drv_init_failure:
1074	kthread_stop(bfad->bfad_tsk);
1075out_kthread_create_failure:
1076	mutex_lock(&bfad_mutex);
1077	bfad_inst--;
1078	list_del(&bfad->list_entry);
1079	mutex_unlock(&bfad_mutex);
1080	bfad_pci_uninit(pdev, bfad);
1081out_pci_init_failure:
1082	kfree(bfad->trcmod);
1083out_alloc_trace_failure:
1084	kfree(bfad);
1085out:
1086	return error;
1087}
1088
1089/**
1090 * PCI remove entry.
1091 */
1092void
1093bfad_pci_remove(struct pci_dev *pdev)
1094{
1095	struct bfad_s  *bfad = pci_get_drvdata(pdev);
1096	unsigned long   flags;
1097
1098	bfa_trc(bfad, bfad->inst_no);
1099
1100	spin_lock_irqsave(&bfad->bfad_lock, flags);
1101	if (bfad->bfad_tsk != NULL)
1102		kthread_stop(bfad->bfad_tsk);
1103	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1104
1105	if ((bfad->bfad_flags & BFAD_DRV_INIT_DONE)
1106	    && !(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
1107
1108		spin_lock_irqsave(&bfad->bfad_lock, flags);
1109		init_completion(&bfad->comp);
1110		bfa_stop(&bfad->bfa);
1111		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1112		wait_for_completion(&bfad->comp);
1113
1114		bfad_remove_intr(bfad);
1115		del_timer_sync(&bfad->hal_tmo);
1116		goto hal_detach;
1117	} else if (!(bfad->bfad_flags & BFAD_DRV_INIT_DONE)) {
1118		goto remove_sysfs;
1119	}
1120
1121	if (bfad->bfad_flags & BFAD_HAL_START_DONE) {
1122		bfad_drv_stop(bfad);
1123	} else if (bfad->bfad_flags & BFAD_DRV_INIT_DONE) {
1124		/* Invoking bfa_stop() before bfa_detach
1125		 * when HAL and DRV init are success
1126		 * but HAL start did not occur.
1127		 */
1128		spin_lock_irqsave(&bfad->bfad_lock, flags);
1129		init_completion(&bfad->comp);
1130		bfa_stop(&bfad->bfa);
1131		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1132		wait_for_completion(&bfad->comp);
1133	}
1134
1135	bfad_remove_intr(bfad);
1136	del_timer_sync(&bfad->hal_tmo);
1137
1138	if (bfad->bfad_flags & BFAD_FC4_PROBE_DONE)
1139		bfad_fc4_probe_undo(bfad);
1140
1141	if (bfad->bfad_flags & BFAD_CFG_PPORT_DONE)
1142		bfad_uncfg_pport(bfad);
1143
1144hal_detach:
1145	spin_lock_irqsave(&bfad->bfad_lock, flags);
1146	bfa_detach(&bfad->bfa);
1147	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1148	bfad_hal_mem_release(bfad);
1149remove_sysfs:
1150
1151	mutex_lock(&bfad_mutex);
1152	bfad_inst--;
1153	list_del(&bfad->list_entry);
1154	mutex_unlock(&bfad_mutex);
1155	bfad_pci_uninit(pdev, bfad);
1156
1157	kfree(bfad->trcmod);
1158	kfree(bfad);
1159}
1160
1161
1162static struct pci_device_id bfad_id_table[] = {
1163	{
1164	 .vendor = BFA_PCI_VENDOR_ID_BROCADE,
1165	 .device = BFA_PCI_DEVICE_ID_FC_8G2P,
1166	 .subvendor = PCI_ANY_ID,
1167	 .subdevice = PCI_ANY_ID,
1168	 },
1169	{
1170	 .vendor = BFA_PCI_VENDOR_ID_BROCADE,
1171	 .device = BFA_PCI_DEVICE_ID_FC_8G1P,
1172	 .subvendor = PCI_ANY_ID,
1173	 .subdevice = PCI_ANY_ID,
1174	 },
1175	{
1176	 .vendor = BFA_PCI_VENDOR_ID_BROCADE,
1177	 .device = BFA_PCI_DEVICE_ID_CT,
1178	 .subvendor = PCI_ANY_ID,
1179	 .subdevice = PCI_ANY_ID,
1180	 .class = (PCI_CLASS_SERIAL_FIBER << 8),
1181	 .class_mask = ~0,
1182	 },
1183
1184	{0, 0},
1185};
1186
1187MODULE_DEVICE_TABLE(pci, bfad_id_table);
1188
1189static struct pci_driver bfad_pci_driver = {
1190	.name = BFAD_DRIVER_NAME,
1191	.id_table = bfad_id_table,
1192	.probe = bfad_pci_probe,
1193	.remove = __devexit_p(bfad_pci_remove),
1194};
1195
1196/**
1197 *  Linux driver module functions
1198 */
1199bfa_status_t
1200bfad_fc4_module_init(void)
1201{
1202	int             rc;
1203
1204	rc = bfad_im_module_init();
1205	if (rc != BFA_STATUS_OK)
1206		goto ext;
1207
1208	bfad_tm_module_init();
1209	if (ipfc_enable)
1210		bfad_ipfc_module_init();
1211ext:
1212	return rc;
1213}
1214
1215void
1216bfad_fc4_module_exit(void)
1217{
1218	if (ipfc_enable)
1219		bfad_ipfc_module_exit();
1220	bfad_tm_module_exit();
1221	bfad_im_module_exit();
1222}
1223
1224/**
1225 * Driver module init.
1226 */
1227static int      __init
1228bfad_init(void)
1229{
1230	int             error = 0;
1231
1232	printk(KERN_INFO "Brocade BFA FC/FCOE SCSI driver - version: %s\n",
1233	       BFAD_DRIVER_VERSION);
1234
1235	if (num_sgpgs > 0)
1236		num_sgpgs_parm = num_sgpgs;
1237
1238	error = bfad_fc4_module_init();
1239	if (error) {
1240		error = -ENOMEM;
1241		printk(KERN_WARNING "bfad_fc4_module_init failure\n");
1242		goto ext;
1243	}
1244
1245	if (!strcmp(FCPI_NAME, " fcpim"))
1246		bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_IM;
1247	if (!strcmp(FCPT_NAME, " fcptm"))
1248		bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_TM;
1249	if (!strcmp(IPFC_NAME, " ipfc"))
1250		bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_IPFC;
1251
1252	bfa_ioc_auto_recover(ioc_auto_recover);
1253	bfa_fcs_rport_set_del_timeout(rport_del_timeout);
1254	error = pci_register_driver(&bfad_pci_driver);
1255
1256	if (error) {
1257		printk(KERN_WARNING "bfad pci_register_driver failure\n");
1258		goto ext;
1259	}
1260
1261	return 0;
1262
1263ext:
1264	bfad_fc4_module_exit();
1265	return error;
1266}
1267
1268/**
1269 * Driver module exit.
1270 */
1271static void     __exit
1272bfad_exit(void)
1273{
1274	pci_unregister_driver(&bfad_pci_driver);
1275	bfad_fc4_module_exit();
1276	bfad_free_fwimg();
1277}
1278
1279#define BFAD_PROTO_NAME FCPI_NAME FCPT_NAME IPFC_NAME
1280
1281module_init(bfad_init);
1282module_exit(bfad_exit);
1283MODULE_LICENSE("GPL");
1284MODULE_DESCRIPTION("Brocade Fibre Channel HBA Driver" BFAD_PROTO_NAME);
1285MODULE_AUTHOR("Brocade Communications Systems, Inc.");
1286MODULE_VERSION(BFAD_DRIVER_VERSION);
1287
1288
1289