bfad.c revision f7f73812e95077c19a2801bbf4f483fcdab5232f
17725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/*
2a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
37725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * All rights reserved
47725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * www.brocade.com
57725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang *
67725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Linux driver for Brocade Fibre Channel Host Bus Adapter.
77725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang *
87725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * This program is free software; you can redistribute it and/or modify it
97725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * under the terms of the GNU General Public License (GPL) Version 2 as
107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * published by the Free Software Foundation
117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang *
127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * This program is distributed in the hope that it will be useful, but
137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * WITHOUT ANY WARRANTY; without even the implied warranty of
147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * General Public License for more details.
167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
185fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang *  bfad.c Linux driver PCI interface module.
207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include <linux/module.h>
22e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati#include <linux/kthread.h>
23a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati#include <linux/errno.h>
24a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati#include <linux/sched.h>
25a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati#include <linux/init.h>
26a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati#include <linux/fs.h>
27a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati#include <linux/pci.h>
28a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati#include <linux/firmware.h>
29a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati#include <asm/uaccess.h>
30a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati#include <asm/fcntl.h>
31a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include "bfad_drv.h"
337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include "bfad_im.h"
34a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati#include "bfa_fcs.h"
35a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati#include "bfa_os_inc.h"
36a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati#include "bfa_defs.h"
37a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati#include "bfa.h"
387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangBFA_TRC_FILE(LDRV, BFAD);
4042b426ecb453cf49c3d16cf1d7a5e5d8cab9869dJing HuangDEFINE_MUTEX(bfad_mutex);
417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangLIST_HEAD(bfad_list);
42a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
43a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic int	bfad_inst;
44a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic int      num_sgpgs_parm;
45a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint		supported_fc4s;
46a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatichar		*host_name, *os_name, *os_patch;
47a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint		num_rports, num_ios, num_tms;
48a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint		num_fcxps, num_ufbufs;
49a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint		reqq_size, rspq_size, num_sgpgs;
50a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint		rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT;
51a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint		bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH;
52a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint		bfa_io_max_sge = BFAD_IO_MAX_SGE;
538816624222b12e5d7e291e9d1973fc42b994eb6bJing Huangint		bfa_log_level = 3; /* WARNING log level */
54a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint		ioc_auto_recover = BFA_TRUE;
55a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint		bfa_linkup_delay = -1;
56a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint		fdmi_enable = BFA_TRUE;
57a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint		pcie_max_read_reqsz;
58ab2a9ba189e889b3e8990e52e90d2cd9606b2aa1Jing Huangint		bfa_debugfs_enable = 1;
59a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint		msix_disable_cb = 0, msix_disable_ct = 0;
60a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
61a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiu32	bfi_image_ct_fc_size, bfi_image_ct_cna_size, bfi_image_cb_fc_size;
62a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiu32     *bfi_image_ct_fc, *bfi_image_ct_cna, *bfi_image_cb_fc;
63a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
6452f94b6fd0d1ff9d935c52f8a6360834ed871d92Maggiestatic const char *msix_name_ct[] = {
65a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	"cpe0", "cpe1", "cpe2", "cpe3",
66a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	"rme0", "rme1", "rme2", "rme3",
67a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	"ctrl" };
68a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
6952f94b6fd0d1ff9d935c52f8a6360834ed871d92Maggiestatic const char *msix_name_cb[] = {
70a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	"cpe0", "cpe1", "cpe2", "cpe3",
71a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	"rme0", "rme1", "rme2", "rme3",
72a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	"eemc", "elpu0", "elpu1", "epss", "mlpu" };
73a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
74a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_FIRMWARE(BFAD_FW_FILE_CT_FC);
75a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_FIRMWARE(BFAD_FW_FILE_CT_CNA);
76a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_FIRMWARE(BFAD_FW_FILE_CB_FC);
777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(os_name, charp, S_IRUGO | S_IWUSR);
79604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(os_name, "OS name of the hba host machine");
807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(os_patch, charp, S_IRUGO | S_IWUSR);
81604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(os_patch, "OS patch level of the hba host machine");
827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(host_name, charp, S_IRUGO | S_IWUSR);
83604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(host_name, "Hostname of the hba host machine");
847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_rports, int, S_IRUGO | S_IWUSR);
85a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_PARM_DESC(num_rports, "Max number of rports supported per port "
86a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				"(physical/logical), default=1024");
877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_ios, int, S_IRUGO | S_IWUSR);
88604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(num_ios, "Max number of ioim requests, default=2000");
897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_tms, int, S_IRUGO | S_IWUSR);
90604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(num_tms, "Max number of task im requests, default=128");
917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_fcxps, int, S_IRUGO | S_IWUSR);
92604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(num_fcxps, "Max number of fcxp requests, default=64");
937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_ufbufs, int, S_IRUGO | S_IWUSR);
94a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_PARM_DESC(num_ufbufs, "Max number of unsolicited frame "
95a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				"buffers, default=64");
967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(reqq_size, int, S_IRUGO | S_IWUSR);
97a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_PARM_DESC(reqq_size, "Max number of request queue elements, "
98a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				"default=256");
997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(rspq_size, int, S_IRUGO | S_IWUSR);
100a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_PARM_DESC(rspq_size, "Max number of response queue elements, "
101a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				"default=64");
1027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_sgpgs, int, S_IRUGO | S_IWUSR);
103604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(num_sgpgs, "Number of scatter/gather pages, default=2048");
1047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(rport_del_timeout, int, S_IRUGO | S_IWUSR);
105a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_PARM_DESC(rport_del_timeout, "Rport delete timeout, default=90 secs, "
106a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati					"Range[>0]");
1077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(bfa_lun_queue_depth, int, S_IRUGO | S_IWUSR);
108a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_PARM_DESC(bfa_lun_queue_depth, "Lun queue depth, default=32, Range[>0]");
1097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(bfa_io_max_sge, int, S_IRUGO | S_IWUSR);
110604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(bfa_io_max_sge, "Max io scatter/gather elements, default=255");
1118816624222b12e5d7e291e9d1973fc42b994eb6bJing Huangmodule_param(bfa_log_level, int, S_IRUGO | S_IWUSR);
1128816624222b12e5d7e291e9d1973fc42b994eb6bJing HuangMODULE_PARM_DESC(bfa_log_level, "Driver log level, default=3, "
113a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				"Range[Critical:1|Error:2|Warning:3|Info:4]");
1147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR);
115a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_PARM_DESC(ioc_auto_recover, "IOC auto recovery, default=1, "
116a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				"Range[off:0|on:1]");
1177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(bfa_linkup_delay, int, S_IRUGO | S_IWUSR);
118a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_PARM_DESC(bfa_linkup_delay, "Link up delay, default=30 secs for "
119a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			"boot port. Otherwise 10 secs in RHEL4 & 0 for "
120a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			"[RHEL5, SLES10, ESX40] Range[>0]");
121a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatimodule_param(msix_disable_cb, int, S_IRUGO | S_IWUSR);
122a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_PARM_DESC(msix_disable_cb, "Disable Message Signaled Interrupts "
123a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			"for Brocade-415/425/815/825 cards, default=0, "
124a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			" Range[false:0|true:1]");
125a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatimodule_param(msix_disable_ct, int, S_IRUGO | S_IWUSR);
126a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_PARM_DESC(msix_disable_ct, "Disable Message Signaled Interrupts "
127a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			"if possible for Brocade-1010/1020/804/1007/902/1741 "
128a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			"cards, default=0, Range[false:0|true:1]");
129604158ade0d5378622541232a007bf975c8bd03fJing Huangmodule_param(fdmi_enable, int, S_IRUGO | S_IWUSR);
130a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_PARM_DESC(fdmi_enable, "Enables fdmi registration, default=1, "
131a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				"Range[false:0|true:1]");
132a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatimodule_param(pcie_max_read_reqsz, int, S_IRUGO | S_IWUSR);
133a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_PARM_DESC(pcie_max_read_reqsz, "PCIe max read request size, default=0 "
134a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		"(use system setting), Range[128|256|512|1024|2048|4096]");
135ab2a9ba189e889b3e8990e52e90d2cd9606b2aa1Jing Huangmodule_param(bfa_debugfs_enable, int, S_IRUGO | S_IWUSR);
136ab2a9ba189e889b3e8990e52e90d2cd9606b2aa1Jing HuangMODULE_PARM_DESC(bfa_debugfs_enable, "Enables debugfs feature, default=1,"
137ab2a9ba189e889b3e8990e52e90d2cd9606b2aa1Jing Huang		" Range[false:0|true:1]");
1387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
139a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void
140a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_uninit(struct bfad_s *bfad, enum bfad_sm_event event);
141a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void
142a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_created(struct bfad_s *bfad, enum bfad_sm_event event);
143a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void
144a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_initializing(struct bfad_s *bfad, enum bfad_sm_event event);
145a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void
146a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_operational(struct bfad_s *bfad, enum bfad_sm_event event);
147a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void
148a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_stopping(struct bfad_s *bfad, enum bfad_sm_event event);
149a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void
150a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_failed(struct bfad_s *bfad, enum bfad_sm_event event);
151a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void
152a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_fcs_exit(struct bfad_s *bfad, enum bfad_sm_event event);
153a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1545fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
155a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati * Beginning state for the driver instance, awaiting the pci_probe event
1567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
157a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void
158a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_uninit(struct bfad_s *bfad, enum bfad_sm_event event)
159a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati{
160a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_trc(bfad, event);
161a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
162a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	switch (event) {
163a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_CREATE:
164a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_set_state(bfad, bfad_sm_created);
165a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad->bfad_tsk = kthread_create(bfad_worker, (void *) bfad,
166a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati						"%s", "bfad_worker");
167a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (IS_ERR(bfad->bfad_tsk)) {
168a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			printk(KERN_INFO "bfad[%d]: Kernel thread "
169a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				"creation failed!\n", bfad->inst_no);
170a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfa_sm_send_event(bfad, BFAD_E_KTHREAD_CREATE_FAILED);
171a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
172a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_send_event(bfad, BFAD_E_INIT);
173a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
174a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
175a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_STOP:
176a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		/* Ignore stop; already in uninit */
177a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
178a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
179a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	default:
180a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_fault(bfad, event);
181a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
182a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati}
1837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1845fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
185a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati * Driver Instance is created, awaiting event INIT to initialize the bfad
186a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati */
187a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void
188a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_created(struct bfad_s *bfad, enum bfad_sm_event event)
1897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
190a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	unsigned long flags;
1917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
192a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_trc(bfad, event);
1937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
194a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	switch (event) {
195a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_INIT:
196a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_set_state(bfad, bfad_sm_initializing);
1977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
198a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		init_completion(&bfad->comp);
199e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
200a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		/* Enable Interrupt and wait bfa_init completion */
201a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (bfad_setup_intr(bfad)) {
202a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			printk(KERN_WARNING "bfad%d: bfad_setup_intr failed\n",
203a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati					bfad->inst_no);
204a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfa_sm_send_event(bfad, BFAD_E_INTR_INIT_FAILED);
205a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			break;
206a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
207a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
208a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		spin_lock_irqsave(&bfad->bfad_lock, flags);
209f7f73812e95077c19a2801bbf4f483fcdab5232fMaggie Zhang		bfa_iocfc_init(&bfad->bfa);
210a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
211a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
212a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		/* Set up interrupt handler for each vectors */
213a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if ((bfad->bfad_flags & BFAD_MSIX_ON) &&
214a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad_install_msix_handler(bfad)) {
215a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			printk(KERN_WARNING "%s: install_msix failed, bfad%d\n",
216a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				__func__, bfad->inst_no);
217a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
218a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
219a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad_init_timer(bfad);
220a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
221a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		wait_for_completion(&bfad->comp);
222a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
223a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if ((bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
224a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfa_sm_send_event(bfad, BFAD_E_INIT_SUCCESS);
225a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		} else {
226a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad->bfad_flags |= BFAD_HAL_INIT_FAIL;
227a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfa_sm_send_event(bfad, BFAD_E_INIT_FAILED);
228a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
229a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
230a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
231a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
232a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_KTHREAD_CREATE_FAILED:
233a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_set_state(bfad, bfad_sm_uninit);
234a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
235a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
236a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	default:
237a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_fault(bfad, event);
238a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
2397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
2407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic void
242a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_initializing(struct bfad_s *bfad, enum bfad_sm_event event)
2437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
244a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int	retval;
245a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	unsigned long	flags;
246a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
247a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_trc(bfad, event);
248a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
249a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	switch (event) {
250a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_INIT_SUCCESS:
251a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		kthread_stop(bfad->bfad_tsk);
252a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		spin_lock_irqsave(&bfad->bfad_lock, flags);
253a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad->bfad_tsk = NULL;
254a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
255a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
256a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		retval = bfad_start_ops(bfad);
257a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (retval != BFA_STATUS_OK)
258a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			break;
259a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_set_state(bfad, bfad_sm_operational);
260a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
261a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
262a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_INTR_INIT_FAILED:
263a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_set_state(bfad, bfad_sm_uninit);
264a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		kthread_stop(bfad->bfad_tsk);
265a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		spin_lock_irqsave(&bfad->bfad_lock, flags);
266a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad->bfad_tsk = NULL;
267a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
268a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
269a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
270a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_INIT_FAILED:
271a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_set_state(bfad, bfad_sm_failed);
272a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
273a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	default:
274a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_fault(bfad, event);
275a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
2767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
2777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic void
279a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_failed(struct bfad_s *bfad, enum bfad_sm_event event)
2807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
281a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int	retval;
2827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
283a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_trc(bfad, event);
284a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
285a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	switch (event) {
286a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_INIT_SUCCESS:
287a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		retval = bfad_start_ops(bfad);
288a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (retval != BFA_STATUS_OK)
289a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			break;
290a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_set_state(bfad, bfad_sm_operational);
291a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
292a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
293a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_STOP:
294a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (bfad->bfad_flags & BFAD_CFG_PPORT_DONE)
295a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad_uncfg_pport(bfad);
296a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (bfad->bfad_flags & BFAD_FC4_PROBE_DONE) {
297a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad_im_probe_undo(bfad);
298a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad->bfad_flags &= ~BFAD_FC4_PROBE_DONE;
299a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
300a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad_stop(bfad);
301a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
302a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
303a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_EXIT_COMP:
304a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_set_state(bfad, bfad_sm_uninit);
305a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad_remove_intr(bfad);
306a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		del_timer_sync(&bfad->hal_tmo);
307a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
308a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
309a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	default:
310a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_fault(bfad, event);
311a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
3127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
3137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
314a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void
315a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_operational(struct bfad_s *bfad, enum bfad_sm_event event)
3167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
317a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_trc(bfad, event);
3187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
319a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	switch (event) {
320a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_STOP:
321a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_set_state(bfad, bfad_sm_fcs_exit);
322a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad_fcs_stop(bfad);
323a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
3247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
325a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	default:
326a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_fault(bfad, event);
327a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
328a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati}
3297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
330a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void
331a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_fcs_exit(struct bfad_s *bfad, enum bfad_sm_event event)
332a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati{
333a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_trc(bfad, event);
334a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
335a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	switch (event) {
336a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_FCS_EXIT_COMP:
337a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_set_state(bfad, bfad_sm_stopping);
338a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad_stop(bfad);
339a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
340a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
341a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	default:
342a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_fault(bfad, event);
343a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
3447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
3457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic void
347a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_stopping(struct bfad_s *bfad, enum bfad_sm_event event)
3487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
349a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_trc(bfad, event);
3507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
351a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	switch (event) {
352a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_EXIT_COMP:
353a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_set_state(bfad, bfad_sm_uninit);
354a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad_remove_intr(bfad);
355a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		del_timer_sync(&bfad->hal_tmo);
356a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad_im_probe_undo(bfad);
357a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad->bfad_flags &= ~BFAD_FC4_PROBE_DONE;
358a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad_uncfg_pport(bfad);
359a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
3607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
361a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	default:
362a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_fault(bfad, event);
363a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
364a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
3657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
3667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3675fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
3687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang *  BFA callbacks
3697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
3707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
3717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_hcb_comp(void *arg, bfa_status_t status)
3727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
3737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfad_hal_comp *fcomp = (struct bfad_hal_comp *)arg;
3747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	fcomp->status = status;
3767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	complete(&fcomp->comp);
3777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
3787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3795fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
3807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * bfa_init callback
3817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
3827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
3837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_cb_init(void *drv, bfa_status_t init_status)
3847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
385a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfad_s	      *bfad = drv;
3867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
387e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	if (init_status == BFA_STATUS_OK) {
3887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad->bfad_flags |= BFAD_HAL_INIT_DONE;
3897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
390a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		/*
391a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		 * If BFAD_HAL_INIT_FAIL flag is set:
392e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		 * Wake up the kernel thread to start
393e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		 * the bfad operations after HAL init done
394e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		 */
395e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		if ((bfad->bfad_flags & BFAD_HAL_INIT_FAIL)) {
396e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati			bfad->bfad_flags &= ~BFAD_HAL_INIT_FAIL;
397e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati			wake_up_process(bfad->bfad_tsk);
398e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		}
399e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	}
400e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
4017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	complete(&bfad->comp);
4027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
4037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4045fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
4057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang *  BFA_FCS callbacks
4067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
4077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstruct bfad_port_s *
408a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfa_fcb_lport_new(struct bfad_s *bfad, struct bfa_fcs_lport_s *port,
409a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		 enum bfa_lport_role roles, struct bfad_vf_s *vf_drv,
4107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		 struct bfad_vport_s *vp_drv)
4117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
412a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_status_t	rc;
413a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfad_port_s    *port_drv;
4147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!vp_drv && !vf_drv) {
4167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv = &bfad->pport;
4177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv->pvb_type = BFAD_PORT_PHYS_BASE;
4187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	} else if (!vp_drv && vf_drv) {
4197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv = &vf_drv->base_port;
4207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv->pvb_type = BFAD_PORT_VF_BASE;
4217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	} else if (vp_drv && !vf_drv) {
4227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv = &vp_drv->drv_port;
4237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv->pvb_type = BFAD_PORT_PHYS_VPORT;
4247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	} else {
4257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv = &vp_drv->drv_port;
4267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv->pvb_type = BFAD_PORT_VF_VPORT;
4277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
4287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	port_drv->fcs_port = port;
4307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	port_drv->roles = roles;
431a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
432a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (roles & BFA_LPORT_ROLE_FCP_IM) {
433a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		rc = bfad_im_port_new(bfad, port_drv);
434a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (rc != BFA_STATUS_OK) {
435a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad_im_port_delete(bfad, port_drv);
436a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			port_drv = NULL;
437a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
4387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
4397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return port_drv;
4417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
4427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
444a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfa_fcb_lport_delete(struct bfad_s *bfad, enum bfa_lport_role roles,
4457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		    struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
4467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
447a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfad_port_s    *port_drv;
4487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
449a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* this will be only called from rmmod context */
4507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (vp_drv && !vp_drv->comp_del) {
451a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		port_drv = (vp_drv) ? (&(vp_drv)->drv_port) :
452a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				((vf_drv) ? (&(vf_drv)->base_port) :
453a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				(&(bfad)->pport));
4547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_trc(bfad, roles);
455a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (roles & BFA_LPORT_ROLE_FCP_IM)
456a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad_im_port_delete(bfad, port_drv);
4577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
4587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
4597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4605fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
4617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * FCS RPORT alloc callback, after successful PLOGI by FCS
4627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
4637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t
4647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_fcb_rport_alloc(struct bfad_s *bfad, struct bfa_fcs_rport_s **rport,
4657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		    struct bfad_rport_s **rport_drv)
4667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
467a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_status_t	rc = BFA_STATUS_OK;
4687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	*rport_drv = kzalloc(sizeof(struct bfad_rport_s), GFP_ATOMIC);
4707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (*rport_drv == NULL) {
4717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		rc = BFA_STATUS_ENOMEM;
4727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
4737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
4747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	*rport = &(*rport_drv)->fcs_rport;
4767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext:
4787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
4797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
4807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4815fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
482d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang * FCS PBC VPORT Create
483d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang */
484d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huangvoid
485d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huangbfa_fcb_pbc_vport_create(struct bfad_s *bfad, struct bfi_pbc_vport_s pbc_vport)
486d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang{
487d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang
488a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfa_lport_cfg_s port_cfg = {0};
489a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfad_vport_s   *vport;
490a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int rc;
491d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang
492a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	vport = kzalloc(sizeof(struct bfad_vport_s), GFP_KERNEL);
493a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (!vport) {
494d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang		bfa_trc(bfad, 0);
495d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang		return;
496d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang	}
4977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
498a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	vport->drv_port.bfad = bfad;
499a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	port_cfg.roles = BFA_LPORT_ROLE_FCP_IM;
500a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	port_cfg.pwwn = pbc_vport.vp_pwwn;
501a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	port_cfg.nwwn = pbc_vport.vp_nwwn;
502a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	port_cfg.preboot_vp  = BFA_TRUE;
503a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
504a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	rc = bfa_fcs_pbc_vport_create(&vport->fcs_vport, &bfad->bfa_fcs, 0,
505a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				  &port_cfg, vport);
506d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang
507a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (rc != BFA_STATUS_OK) {
508a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_trc(bfad, 0);
509a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		return;
510a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
511d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang
512a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	list_add_tail(&vport->list_entry, &bfad->pbc_vport_list);
513d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang}
5147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
5167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_hal_mem_release(struct bfad_s *bfad)
5177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
518a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int		i;
5197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfa_meminfo_s *hal_meminfo = &bfad->meminfo;
5207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfa_mem_elem_s *meminfo_elem;
5217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	for (i = 0; i < BFA_MEM_TYPE_MAX; i++) {
5237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		meminfo_elem = &hal_meminfo->meminfo[i];
5247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		if (meminfo_elem->kva != NULL) {
5257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			switch (meminfo_elem->mem_type) {
5267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			case BFA_MEM_TYPE_KVA:
5277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				vfree(meminfo_elem->kva);
5287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				break;
5297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			case BFA_MEM_TYPE_DMA:
5307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				dma_free_coherent(&bfad->pcidev->dev,
531a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati					meminfo_elem->mem_len,
532a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati					meminfo_elem->kva,
533a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati					(dma_addr_t) meminfo_elem->dma);
5347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				break;
5357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			default:
5367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				bfa_assert(0);
5377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				break;
5387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			}
5397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		}
5407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
5417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	memset(hal_meminfo, 0, sizeof(struct bfa_meminfo_s));
5437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
5447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
5467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_update_hal_cfg(struct bfa_iocfc_cfg_s *bfa_cfg)
5477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
5487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_rports > 0)
5497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->fwcfg.num_rports = num_rports;
5507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_ios > 0)
5517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->fwcfg.num_ioim_reqs = num_ios;
5527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_tms > 0)
5537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->fwcfg.num_tskim_reqs = num_tms;
5547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_fcxps > 0)
5557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->fwcfg.num_fcxp_reqs = num_fcxps;
5567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_ufbufs > 0)
5577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->fwcfg.num_uf_bufs = num_ufbufs;
5587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (reqq_size > 0)
5597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->drvcfg.num_reqq_elems = reqq_size;
5607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (rspq_size > 0)
5617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->drvcfg.num_rspq_elems = rspq_size;
5627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_sgpgs > 0)
5637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->drvcfg.num_sgpgs = num_sgpgs;
5647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	/*
5667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 * populate the hal values back to the driver for sysfs use.
5677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 * otherwise, the default values will be shown as 0 in sysfs
5687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 */
5697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	num_rports = bfa_cfg->fwcfg.num_rports;
570a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	num_ios = bfa_cfg->fwcfg.num_ioim_reqs;
571a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	num_tms = bfa_cfg->fwcfg.num_tskim_reqs;
572a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	num_fcxps = bfa_cfg->fwcfg.num_fcxp_reqs;
5737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	num_ufbufs = bfa_cfg->fwcfg.num_uf_bufs;
574a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	reqq_size = bfa_cfg->drvcfg.num_reqq_elems;
575a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	rspq_size = bfa_cfg->drvcfg.num_rspq_elems;
576a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	num_sgpgs = bfa_cfg->drvcfg.num_sgpgs;
5777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
5787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t
5807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_hal_mem_alloc(struct bfad_s *bfad)
5817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
582a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int		i;
5837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfa_meminfo_s *hal_meminfo = &bfad->meminfo;
5847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfa_mem_elem_s *meminfo_elem;
585a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	dma_addr_t	phys_addr;
586a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	void	       *kva;
587a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_status_t	rc = BFA_STATUS_OK;
588a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int retry_count = 0;
589a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int reset_value = 1;
590a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int min_num_sgpgs = 512;
5917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_cfg_get_default(&bfad->ioc_cfg);
5937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangretry:
5957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_update_hal_cfg(&bfad->ioc_cfg);
5967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->cfg_data.ioc_queue_depth = bfad->ioc_cfg.fwcfg.num_ioim_reqs;
5977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_cfg_get_meminfo(&bfad->ioc_cfg, hal_meminfo);
5987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	for (i = 0; i < BFA_MEM_TYPE_MAX; i++) {
6007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		meminfo_elem = &hal_meminfo->meminfo[i];
6017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		switch (meminfo_elem->mem_type) {
6027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		case BFA_MEM_TYPE_KVA:
6037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			kva = vmalloc(meminfo_elem->mem_len);
6047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			if (kva == NULL) {
6057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				bfad_hal_mem_release(bfad);
6067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				rc = BFA_STATUS_ENOMEM;
6077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				goto ext;
6087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			}
6097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			memset(kva, 0, meminfo_elem->mem_len);
6107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			meminfo_elem->kva = kva;
6117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			break;
6127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		case BFA_MEM_TYPE_DMA:
6137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			kva = dma_alloc_coherent(&bfad->pcidev->dev,
614a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				meminfo_elem->mem_len, &phys_addr, GFP_KERNEL);
6157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			if (kva == NULL) {
6167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				bfad_hal_mem_release(bfad);
6177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				/*
6187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				 * If we cannot allocate with default
6197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				 * num_sgpages try with half the value.
6207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				 */
6217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				if (num_sgpgs > min_num_sgpgs) {
622a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati					printk(KERN_INFO
623a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati					"bfad[%d]: memory allocation failed"
624a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati					" with num_sgpgs: %d\n",
6257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						bfad->inst_no, num_sgpgs);
6267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					nextLowerInt(&num_sgpgs);
627a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati					printk(KERN_INFO
628a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati					"bfad[%d]: trying to allocate memory"
629a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati					" with num_sgpgs: %d\n",
6307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						bfad->inst_no, num_sgpgs);
6317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					retry_count++;
6327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					goto retry;
6337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				} else {
6347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					if (num_sgpgs_parm > 0)
6357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						num_sgpgs = num_sgpgs_parm;
6367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					else {
6377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						reset_value =
6387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang							(1 << retry_count);
6397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						num_sgpgs *= reset_value;
6407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					}
6417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					rc = BFA_STATUS_ENOMEM;
6427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					goto ext;
6437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				}
6447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			}
6457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			if (num_sgpgs_parm > 0)
6477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				num_sgpgs = num_sgpgs_parm;
6487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			else {
6497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				reset_value = (1 << retry_count);
6507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				num_sgpgs *= reset_value;
6517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			}
6527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			memset(kva, 0, meminfo_elem->mem_len);
6547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			meminfo_elem->kva = kva;
6557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			meminfo_elem->dma = phys_addr;
6567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			break;
6577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		default:
6587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			break;
6597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		}
6617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
6627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext:
6637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
6647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
6657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6665fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
6677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Create a vport under a vf.
6687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
6697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t
6707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_vport_create(struct bfad_s *bfad, u16 vf_id,
671a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		  struct bfa_lport_cfg_s *port_cfg, struct device *dev)
6727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
673a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfad_vport_s   *vport;
674a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int		rc = BFA_STATUS_OK;
675a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	unsigned long	flags;
6767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct completion fcomp;
6777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	vport = kzalloc(sizeof(struct bfad_vport_s), GFP_KERNEL);
6797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!vport) {
6807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		rc = BFA_STATUS_ENOMEM;
6817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
6827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
6837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	vport->drv_port.bfad = bfad;
6857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
686a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	rc = bfa_fcs_vport_create(&vport->fcs_vport, &bfad->bfa_fcs, vf_id,
687a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				  port_cfg, vport);
6887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
6897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (rc != BFA_STATUS_OK)
6917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext_free_vport;
6927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
693a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (port_cfg->roles & BFA_LPORT_ROLE_FCP_IM) {
694b504293fe9dc42917a919044f2b672fb361329d0Jing Huang		rc = bfad_im_scsi_host_alloc(bfad, vport->drv_port.im_port,
695b504293fe9dc42917a919044f2b672fb361329d0Jing Huang							dev);
6967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		if (rc != BFA_STATUS_OK)
6977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			goto ext_free_fcs_vport;
6987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
6997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
7017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_vport_start(&vport->fcs_vport);
7027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
7037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return BFA_STATUS_OK;
7057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext_free_fcs_vport:
7077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
7087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	vport->comp_del = &fcomp;
7097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	init_completion(vport->comp_del);
7107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_vport_delete(&vport->fcs_vport);
7117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
7127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	wait_for_completion(vport->comp_del);
7137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext_free_vport:
7147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	kfree(vport);
7157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext:
7167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
7177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
7187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
7207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_bfa_tmo(unsigned long data)
7217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
722a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfad_s	      *bfad = (struct bfad_s *) data;
723a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	unsigned long	flags;
724a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct list_head	       doneq;
7257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
7277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
728f7f73812e95077c19a2801bbf4f483fcdab5232fMaggie Zhang	bfa_timer_beat(&bfad->bfa.timer_mod);
7297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_comp_deq(&bfad->bfa, &doneq);
7317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
7327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!list_empty(&doneq)) {
7347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_comp_process(&bfad->bfa, &doneq);
7357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		spin_lock_irqsave(&bfad->bfad_lock, flags);
7367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_comp_free(&bfad->bfa, &doneq);
7377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
7387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
7397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
740a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	mod_timer(&bfad->hal_tmo,
741a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		  jiffies + msecs_to_jiffies(BFA_TIMER_FREQ));
7427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
7437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
7457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_init_timer(struct bfad_s *bfad)
7467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
7477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	init_timer(&bfad->hal_tmo);
7487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->hal_tmo.function = bfad_bfa_tmo;
7497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->hal_tmo.data = (unsigned long)bfad;
7507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
751a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	mod_timer(&bfad->hal_tmo,
752a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		  jiffies + msecs_to_jiffies(BFA_TIMER_FREQ));
7537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
7547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangint
7567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_pci_init(struct pci_dev *pdev, struct bfad_s *bfad)
7577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
758a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int		rc = -ENODEV;
7597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (pci_enable_device(pdev)) {
761a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		printk(KERN_ERR "pci_enable_device fail %p\n", pdev);
7627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out;
7637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
7647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (pci_request_regions(pdev, BFAD_DRIVER_NAME))
7667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_disable_device;
7677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_set_master(pdev);
7697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0)
7727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) {
773a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			printk(KERN_ERR "pci_set_dma_mask fail %p\n", pdev);
7747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			goto out_release_region;
7757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		}
7767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
777b3522f08ec7011aed0abc477bfedd00d189e9cd6Jing Huang	bfad->pci_bar0_kva = pci_iomap(pdev, 0, pci_resource_len(pdev, 0));
7787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (bfad->pci_bar0_kva == NULL) {
780a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		printk(KERN_ERR "Fail to map bar0\n");
7817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_release_region;
7827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
7837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->hal_pcidev.pci_slot = PCI_SLOT(pdev->devfn);
7857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->hal_pcidev.pci_func = PCI_FUNC(pdev->devfn);
7867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->hal_pcidev.pci_bar_kva = bfad->pci_bar0_kva;
7877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->hal_pcidev.device_id = pdev->device;
7887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_name = pci_name(pdev);
7897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_attr.vendor_id = pdev->vendor;
7917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_attr.device_id = pdev->device;
7927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_attr.ssid = pdev->subsystem_device;
7937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_attr.ssvid = pdev->subsystem_vendor;
7947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_attr.pcifn = PCI_FUNC(pdev->devfn);
7957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pcidev = pdev;
797a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
798a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* Adjust PCIe Maximum Read Request Size */
799a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (pcie_max_read_reqsz > 0) {
800a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		int pcie_cap_reg;
801a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		u16 pcie_dev_ctl;
802a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		u16 mask = 0xffff;
803a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
804a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		switch (pcie_max_read_reqsz) {
805a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		case 128:
806a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			mask = 0x0;
807a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			break;
808a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		case 256:
809a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			mask = 0x1000;
810a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			break;
811a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		case 512:
812a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			mask = 0x2000;
813a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			break;
814a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		case 1024:
815a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			mask = 0x3000;
816a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			break;
817a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		case 2048:
818a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			mask = 0x4000;
819a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			break;
820a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		case 4096:
821a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			mask = 0x5000;
822a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			break;
823a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		default:
824a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			break;
825a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
826a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
827a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		pcie_cap_reg = pci_find_capability(pdev, PCI_CAP_ID_EXP);
828a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (mask != 0xffff && pcie_cap_reg) {
829a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			pcie_cap_reg += 0x08;
830a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			pci_read_config_word(pdev, pcie_cap_reg, &pcie_dev_ctl);
831a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			if ((pcie_dev_ctl & 0x7000) != mask) {
832a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				printk(KERN_WARNING "BFA[%s]: "
833a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				"pcie_max_read_request_size is %d, "
834a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				"reset to %d\n", bfad->pci_name,
835a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				(1 << ((pcie_dev_ctl & 0x7000) >> 12)) << 7,
836a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				pcie_max_read_reqsz);
837a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
838a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				pcie_dev_ctl &= ~0x7000;
839a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				pci_write_config_word(pdev, pcie_cap_reg,
840a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati						pcie_dev_ctl | mask);
841a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			}
842a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
843a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
844a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
8457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return 0;
8467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_release_region:
8487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_release_regions(pdev);
8497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_disable_device:
8507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_disable_device(pdev);
8517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout:
8527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
8537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
8547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
8567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_pci_uninit(struct pci_dev *pdev, struct bfad_s *bfad)
8577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
8587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_iounmap(pdev, bfad->pci_bar0_kva);
8597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_release_regions(pdev);
8607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_disable_device(pdev);
8617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_set_drvdata(pdev, NULL);
8627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
8637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t
8657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_drv_init(struct bfad_s *bfad)
8667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
867a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_status_t	rc;
868a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	unsigned long	flags;
8697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->cfg_data.rport_del_timeout = rport_del_timeout;
8717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->cfg_data.lun_queue_depth = bfa_lun_queue_depth;
8727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->cfg_data.io_max_sge = bfa_io_max_sge;
8737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->cfg_data.binding_method = FCP_PWWN_BINDING;
8747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	rc = bfad_hal_mem_alloc(bfad);
8767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (rc != BFA_STATUS_OK) {
8777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING "bfad%d bfad_hal_mem_alloc failure\n",
8787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		       bfad->inst_no);
8797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING
880a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			"Not enough memory to attach all Brocade HBA ports, %s",
881a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			"System may need more memory.\n");
8827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_hal_mem_alloc_failure;
8837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
8847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
885f7f73812e95077c19a2801bbf4f483fcdab5232fMaggie Zhang	bfad->bfa.trcmod = bfad->trcmod;
886f7f73812e95077c19a2801bbf4f483fcdab5232fMaggie Zhang	bfad->bfa.plog = &bfad->plog_buf;
8877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_plog_init(&bfad->plog_buf);
8887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_plog_str(&bfad->plog_buf, BFA_PL_MID_DRVR, BFA_PL_EID_DRIVER_START,
8897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		     0, "Driver Attach");
8907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_attach(&bfad->bfa, bfad, &bfad->ioc_cfg, &bfad->meminfo,
8927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		   &bfad->hal_pcidev);
8937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
894a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* FCS INIT */
8957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
896f7f73812e95077c19a2801bbf4f483fcdab5232fMaggie Zhang	bfad->bfa_fcs.trcmod = bfad->trcmod;
89782794a2e4153657d12a0c29272e40b47eaadb748Krishna Gudipati	bfa_fcs_attach(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE);
898f7f73812e95077c19a2801bbf4f483fcdab5232fMaggie Zhang	bfad->bfa_fcs.fdmi_enabled = fdmi_enable;
8997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
9007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
9017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->bfad_flags |= BFAD_DRV_INIT_DONE;
902a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
9037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return BFA_STATUS_OK;
9047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
9057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_hal_mem_alloc_failure:
9067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return BFA_STATUS_FAILED;
9077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
9087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
9097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
9107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_drv_uninit(struct bfad_s *bfad)
9117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
912e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	unsigned long   flags;
913e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
914e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
915e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	init_completion(&bfad->comp);
916f7f73812e95077c19a2801bbf4f483fcdab5232fMaggie Zhang	bfa_iocfc_stop(&bfad->bfa);
917e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
918e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	wait_for_completion(&bfad->comp);
919e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
9207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	del_timer_sync(&bfad->hal_tmo);
9217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_isr_disable(&bfad->bfa);
9227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_detach(&bfad->bfa);
9237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_remove_intr(bfad);
9247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_hal_mem_release(bfad);
925e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
926e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad->bfad_flags &= ~BFAD_DRV_INIT_DONE;
9277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
9287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
9297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
9307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_drv_start(struct bfad_s *bfad)
9317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
932a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	unsigned long	flags;
9337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
9347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
935f7f73812e95077c19a2801bbf4f483fcdab5232fMaggie Zhang	bfa_iocfc_start(&bfad->bfa);
936f7f73812e95077c19a2801bbf4f483fcdab5232fMaggie Zhang	bfa_fcs_fabric_modstart(&bfad->bfa_fcs);
9377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->bfad_flags |= BFAD_HAL_START_DONE;
9387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
9397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
940a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (bfad->im)
941a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		flush_workqueue(bfad->im->drv_workq);
9427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
9437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
9447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
945a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_fcs_stop(struct bfad_s *bfad)
9467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
947a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	unsigned long	flags;
9487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
9497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
9507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	init_completion(&bfad->comp);
9517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pport.flags |= BFAD_PORT_DELETE;
9527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_exit(&bfad->bfa_fcs);
9537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
9547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	wait_for_completion(&bfad->comp);
9557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
956a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_sm_send_event(bfad, BFAD_E_FCS_EXIT_COMP);
957a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati}
958a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
959a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipativoid
960a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_stop(struct bfad_s *bfad)
961a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati{
962a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	unsigned long	flags;
963a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
9647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
9657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	init_completion(&bfad->comp);
966f7f73812e95077c19a2801bbf4f483fcdab5232fMaggie Zhang	bfa_iocfc_stop(&bfad->bfa);
9677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->bfad_flags &= ~BFAD_HAL_START_DONE;
9687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
9697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	wait_for_completion(&bfad->comp);
970a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
971a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_sm_send_event(bfad, BFAD_E_EXIT_COMP);
9727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
9737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
9747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t
975a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_cfg_pport(struct bfad_s *bfad, enum bfa_lport_role role)
9767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
977a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int		rc = BFA_STATUS_OK;
9787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
979a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* Allocate scsi_host for the physical port */
980a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if ((supported_fc4s & BFA_LPORT_ROLE_FCP_IM) &&
981a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	    (role & BFA_LPORT_ROLE_FCP_IM)) {
9827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		if (bfad->pport.im_port == NULL) {
9837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			rc = BFA_STATUS_FAILED;
9847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			goto out;
9857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		}
9867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
987b504293fe9dc42917a919044f2b672fb361329d0Jing Huang		rc = bfad_im_scsi_host_alloc(bfad, bfad->pport.im_port,
988b504293fe9dc42917a919044f2b672fb361329d0Jing Huang						&bfad->pcidev->dev);
9897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		if (rc != BFA_STATUS_OK)
9907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			goto out;
9917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
992a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad->pport.roles |= BFA_LPORT_ROLE_FCP_IM;
9937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
9947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
995ab2a9ba189e889b3e8990e52e90d2cd9606b2aa1Jing Huang	/* Setup the debugfs node for this scsi_host */
996ab2a9ba189e889b3e8990e52e90d2cd9606b2aa1Jing Huang	if (bfa_debugfs_enable)
997ab2a9ba189e889b3e8990e52e90d2cd9606b2aa1Jing Huang		bfad_debugfs_init(&bfad->pport);
998ab2a9ba189e889b3e8990e52e90d2cd9606b2aa1Jing Huang
9997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->bfad_flags |= BFAD_CFG_PPORT_DONE;
10007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout:
10027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
10037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
10047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
10067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_uncfg_pport(struct bfad_s *bfad)
10077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
1008a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* Remove the debugfs node for this scsi_host */
1009ab2a9ba189e889b3e8990e52e90d2cd9606b2aa1Jing Huang	kfree(bfad->regdata);
1010ab2a9ba189e889b3e8990e52e90d2cd9606b2aa1Jing Huang	bfad_debugfs_exit(&bfad->pport);
1011ab2a9ba189e889b3e8990e52e90d2cd9606b2aa1Jing Huang
1012a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if ((supported_fc4s & BFA_LPORT_ROLE_FCP_IM) &&
1013a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	    (bfad->pport.roles & BFA_LPORT_ROLE_FCP_IM)) {
10147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_im_scsi_host_free(bfad, bfad->pport.im_port);
10157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_im_port_clean(bfad->pport.im_port);
10167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		kfree(bfad->pport.im_port);
1017a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad->pport.roles &= ~BFA_LPORT_ROLE_FCP_IM;
10187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
10197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->bfad_flags &= ~BFAD_CFG_PPORT_DONE;
10217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
10227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1023e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatibfa_status_t
1024a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_start_ops(struct bfad_s *bfad) {
1025a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1026a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int	retval;
1027a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	unsigned long	flags;
1028a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfad_vport_s *vport, *vport_new;
1029a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfa_fcs_driver_info_s driver_info;
1030a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1031a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* Fill the driver_info info to fcs*/
1032a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	memset(&driver_info, 0, sizeof(driver_info));
1033a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	strncpy(driver_info.version, BFAD_DRIVER_VERSION,
1034a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		sizeof(driver_info.version) - 1);
1035a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (host_name)
1036a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		strncpy(driver_info.host_machine_name, host_name,
1037a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			sizeof(driver_info.host_machine_name) - 1);
1038a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (os_name)
1039a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		strncpy(driver_info.host_os_name, os_name,
1040a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			sizeof(driver_info.host_os_name) - 1);
1041a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (os_patch)
1042a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		strncpy(driver_info.host_os_patch, os_patch,
1043a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			sizeof(driver_info.host_os_patch) - 1);
1044a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1045a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	strncpy(driver_info.os_device_name, bfad->pci_name,
1046a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		sizeof(driver_info.os_device_name - 1));
1047a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1048a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* FCS INIT */
1049a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
1050a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_fcs_driver_info_init(&bfad->bfa_fcs, &driver_info);
1051a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_fcs_init(&bfad->bfa_fcs);
1052a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1053e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1054a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	retval = bfad_cfg_pport(bfad, BFA_LPORT_ROLE_FCP_IM);
1055e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	if (retval != BFA_STATUS_OK) {
1056a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (bfa_sm_cmp_state(bfad, bfad_sm_initializing))
1057a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfa_sm_set_state(bfad, bfad_sm_failed);
1058a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad_stop(bfad);
1059a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		return BFA_STATUS_FAILED;
1060e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	}
1061e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1062a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* BFAD level FC4 IM specific resource allocation */
1063a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	retval = bfad_im_probe(bfad);
1064a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (retval != BFA_STATUS_OK) {
1065a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		printk(KERN_WARNING "bfad_im_probe failed\n");
1066a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (bfa_sm_cmp_state(bfad, bfad_sm_initializing))
1067a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfa_sm_set_state(bfad, bfad_sm_failed);
1068a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad_im_probe_undo(bfad);
1069a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad->bfad_flags &= ~BFAD_FC4_PROBE_DONE;
1070a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad_uncfg_pport(bfad);
1071a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad_stop(bfad);
1072a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		return BFA_STATUS_FAILED;
1073a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	} else
1074a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad->bfad_flags |= BFAD_FC4_PROBE_DONE;
1075a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1076e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad_drv_start(bfad);
1077e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1078a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* Complete pbc vport create */
1079a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	list_for_each_entry_safe(vport, vport_new, &bfad->pbc_vport_list,
1080a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				list_entry) {
1081d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang		struct fc_vport_identifiers vid;
1082d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang		struct fc_vport *fc_vport;
1083a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		char pwwn_buf[BFA_STRING_32];
1084d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang
1085d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang		memset(&vid, 0, sizeof(vid));
1086d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang		vid.roles = FC_PORT_ROLE_FCP_INITIATOR;
1087d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang		vid.vport_type = FC_PORTTYPE_NPIV;
1088d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang		vid.disable = false;
1089a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		vid.node_name = wwn_to_u64((u8 *)
1090a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				(&((vport->fcs_vport).lport.port_cfg.nwwn)));
1091a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		vid.port_name = wwn_to_u64((u8 *)
1092a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				(&((vport->fcs_vport).lport.port_cfg.pwwn)));
1093d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang		fc_vport = fc_vport_create(bfad->pport.im_port->shost, 0, &vid);
1094a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (!fc_vport) {
1095a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			wwn2str(pwwn_buf, vid.port_name);
1096d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang			printk(KERN_WARNING "bfad%d: failed to create pbc vport"
1097a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				" %s\n", bfad->inst_no, pwwn_buf);
1098a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
1099a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		list_del(&vport->list_entry);
1100a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		kfree(vport);
1101d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang	}
1102d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang
1103e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	/*
1104e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	 * If bfa_linkup_delay is set to -1 default; try to retrive the
1105e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	 * value using the bfad_os_get_linkup_delay(); else use the
1106e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	 * passed in module param value as the bfa_linkup_delay.
1107e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	 */
1108e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	if (bfa_linkup_delay < 0) {
1109e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfa_linkup_delay = bfad_os_get_linkup_delay(bfad);
1110e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfad_os_rport_online_wait(bfad);
1111e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfa_linkup_delay = -1;
1112a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	} else
1113e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfad_os_rport_online_wait(bfad);
1114e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
11158816624222b12e5d7e291e9d1973fc42b994eb6bJing Huang	BFA_LOG(KERN_INFO, bfad, bfa_log_level, "bfa device claimed\n");
1116e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1117e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	return BFA_STATUS_OK;
1118e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati}
1119e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1120e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatiint
1121d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huangbfad_worker(void *ptr)
1122e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati{
1123e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	struct bfad_s *bfad;
1124e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	unsigned long   flags;
1125e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1126e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad = (struct bfad_s *)ptr;
1127e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1128e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	while (!kthread_should_stop()) {
1129e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1130a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		/* Send event BFAD_E_INIT_SUCCESS */
1131a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_send_event(bfad, BFAD_E_INIT_SUCCESS);
1132e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1133e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		spin_lock_irqsave(&bfad->bfad_lock, flags);
1134e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfad->bfad_tsk = NULL;
1135e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1136e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1137e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		break;
1138e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	}
1139e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1140e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	return 0;
1141e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati}
1142e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
11435fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
1144a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati *  BFA driver interrupt functions
1145a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati */
1146a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiirqreturn_t
1147a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_intx(int irq, void *dev_id)
1148a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati{
1149a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfad_s	*bfad = dev_id;
1150a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct list_head	doneq;
1151a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	unsigned long	flags;
1152a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_boolean_t rc;
1153a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1154a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
1155a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	rc = bfa_intx(&bfad->bfa);
1156a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (!rc) {
1157a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1158a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		return IRQ_NONE;
1159a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
1160a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1161a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_comp_deq(&bfad->bfa, &doneq);
1162a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1163a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1164a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (!list_empty(&doneq)) {
1165a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_comp_process(&bfad->bfa, &doneq);
1166a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1167a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		spin_lock_irqsave(&bfad->bfad_lock, flags);
1168a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_comp_free(&bfad->bfa, &doneq);
1169a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1170a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_trc_fp(bfad, irq);
1171a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
1172a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1173a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	return IRQ_HANDLED;
1174a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1175a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati}
1176a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1177a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic irqreturn_t
1178a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_msix(int irq, void *dev_id)
1179a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati{
1180a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfad_msix_s *vec = dev_id;
1181a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfad_s *bfad = vec->bfad;
1182a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct list_head doneq;
1183a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	unsigned long   flags;
1184a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1185a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
1186a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1187a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_msix(&bfad->bfa, vec->msix.entry);
1188a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_comp_deq(&bfad->bfa, &doneq);
1189a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1190a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1191a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (!list_empty(&doneq)) {
1192a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_comp_process(&bfad->bfa, &doneq);
1193a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1194a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		spin_lock_irqsave(&bfad->bfad_lock, flags);
1195a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_comp_free(&bfad->bfa, &doneq);
1196a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1197a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
1198a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1199a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	return IRQ_HANDLED;
1200a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati}
1201a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
12025fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
1203a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati * Initialize the MSIX entry table.
1204a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati */
1205a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void
1206a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_init_msix_entry(struct bfad_s *bfad, struct msix_entry *msix_entries,
1207a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			 int mask, int max_bit)
1208a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati{
1209a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int	i;
1210a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int	match = 0x00000001;
1211a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1212a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	for (i = 0, bfad->nvec = 0; i < MAX_MSIX_ENTRY; i++) {
1213a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (mask & match) {
1214a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad->msix_tab[bfad->nvec].msix.entry = i;
1215a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad->msix_tab[bfad->nvec].bfad = bfad;
1216a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			msix_entries[bfad->nvec].entry = i;
1217a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad->nvec++;
1218a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
1219a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1220a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		match <<= 1;
1221a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
1222a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1223a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati}
1224a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1225a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint
1226a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_install_msix_handler(struct bfad_s *bfad)
1227a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati{
1228a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int i, error = 0;
1229a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1230a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	for (i = 0; i < bfad->nvec; i++) {
1231a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		sprintf(bfad->msix_tab[i].name, "bfa-%s-%s",
1232a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				bfad->pci_name,
1233a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				((bfa_asic_id_ct(bfad->hal_pcidev.device_id)) ?
1234a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				msix_name_ct[i] : msix_name_cb[i]));
1235a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1236a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		error = request_irq(bfad->msix_tab[i].msix.vector,
1237a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				    (irq_handler_t) bfad_msix, 0,
1238a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				    bfad->msix_tab[i].name, &bfad->msix_tab[i]);
1239a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_trc(bfad, i);
1240a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_trc(bfad, bfad->msix_tab[i].msix.vector);
1241a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (error) {
1242a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			int	j;
1243a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1244a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			for (j = 0; j < i; j++)
1245a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				free_irq(bfad->msix_tab[j].msix.vector,
1246a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati						&bfad->msix_tab[j]);
1247a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1248a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			return 1;
1249a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
1250a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
1251a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1252a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	return 0;
1253a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati}
1254a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
12555fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
1256a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati * Setup MSIX based interrupt.
1257a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati */
1258a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint
1259a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_setup_intr(struct bfad_s *bfad)
1260a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati{
1261a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int error = 0;
1262a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	u32 mask = 0, i, num_bit = 0, max_bit = 0;
1263a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct msix_entry msix_entries[MAX_MSIX_ENTRY];
1264a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct pci_dev *pdev = bfad->pcidev;
1265a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1266a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* Call BFA to get the msix map for this PCI function.  */
1267a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_msix_getvecs(&bfad->bfa, &mask, &num_bit, &max_bit);
1268a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1269a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* Set up the msix entry table */
1270a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfad_init_msix_entry(bfad, msix_entries, mask, max_bit);
1271a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1272a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if ((bfa_asic_id_ct(pdev->device) && !msix_disable_ct) ||
1273a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	    (!bfa_asic_id_ct(pdev->device) && !msix_disable_cb)) {
1274a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1275a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		error = pci_enable_msix(bfad->pcidev, msix_entries, bfad->nvec);
1276a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (error) {
1277a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			/*
1278a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			 * Only error number of vector is available.
1279a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			 * We don't have a mechanism to map multiple
1280a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			 * interrupts into one vector, so even if we
1281a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			 * can try to request less vectors, we don't
1282a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			 * know how to associate interrupt events to
1283a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			 *  vectors. Linux doesn't dupicate vectors
1284a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			 * in the MSIX table for this case.
1285a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			 */
1286a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1287a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			printk(KERN_WARNING "bfad%d: "
1288a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				"pci_enable_msix failed (%d),"
1289a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				" use line based.\n", bfad->inst_no, error);
1290a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1291a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			goto line_based;
1292a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
1293a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1294a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		/* Save the vectors */
1295a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		for (i = 0; i < bfad->nvec; i++) {
1296a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfa_trc(bfad, msix_entries[i].vector);
1297a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad->msix_tab[i].msix.vector = msix_entries[i].vector;
1298a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
1299a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1300a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_msix_init(&bfad->bfa, bfad->nvec);
1301a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1302a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad->bfad_flags |= BFAD_MSIX_ON;
1303a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1304a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		return error;
1305a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
1306a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1307a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiline_based:
1308a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	error = 0;
1309a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (request_irq
1310a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	    (bfad->pcidev->irq, (irq_handler_t) bfad_intx, BFAD_IRQ_FLAGS,
1311a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	     BFAD_DRIVER_NAME, bfad) != 0) {
1312a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		/* Enable interrupt handler failed */
1313a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		return 1;
1314a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
1315a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1316a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	return error;
1317a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati}
1318a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1319a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipativoid
1320a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_remove_intr(struct bfad_s *bfad)
1321a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati{
1322a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int	i;
1323a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1324a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (bfad->bfad_flags & BFAD_MSIX_ON) {
1325a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		for (i = 0; i < bfad->nvec; i++)
1326a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			free_irq(bfad->msix_tab[i].msix.vector,
1327a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati					&bfad->msix_tab[i]);
1328a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1329a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		pci_disable_msix(bfad->pcidev);
1330a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad->bfad_flags &= ~BFAD_MSIX_ON;
1331a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	} else {
1332a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		free_irq(bfad->pcidev->irq, bfad);
1333a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
1334a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati}
13357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
13365fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
13377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * PCI probe entry.
13387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
13397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangint
13407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
13417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
1342a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfad_s	*bfad;
1343a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int		error = -ENODEV, retval;
13447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1345a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* For single port cards - only claim function 0 */
1346a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if ((pdev->device == BFA_PCI_DEVICE_ID_FC_8G1P) &&
1347a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		(PCI_FUNC(pdev->devfn) != 0))
13487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		return -ENODEV;
13497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
13507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad = kzalloc(sizeof(struct bfad_s), GFP_KERNEL);
13517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!bfad) {
13527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		error = -ENOMEM;
13537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out;
13547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
13557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
13567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->trcmod = kzalloc(sizeof(struct bfa_trc_mod_s), GFP_KERNEL);
13577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!bfad->trcmod) {
13587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING "Error alloc trace buffer!\n");
13597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		error = -ENOMEM;
13607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_alloc_trace_failure;
13617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
13627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1363a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* TRACE INIT */
13647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_trc_init(bfad->trcmod);
13657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_trc(bfad, bfad_inst);
13667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
13677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!(bfad_load_fwimg(pdev))) {
13687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		kfree(bfad->trcmod);
13697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_alloc_trace_failure;
13707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
13717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
13727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	retval = bfad_pci_init(pdev, bfad);
13737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (retval) {
13747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING "bfad_pci_init failure!\n");
13757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		error = retval;
13767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_pci_init_failure;
13777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
13787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
13797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mutex_lock(&bfad_mutex);
13807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->inst_no = bfad_inst++;
13817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	list_add_tail(&bfad->list_entry, &bfad_list);
13827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mutex_unlock(&bfad_mutex);
13837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1384a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* Initializing the state machine: State set to uninit */
1385a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_sm_set_state(bfad, bfad_sm_uninit);
1386a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
13877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_init(&bfad->bfad_lock);
13887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_set_drvdata(pdev, bfad);
13897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
13907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->ref_count = 0;
13917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pport.bfad = bfad;
1392a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	INIT_LIST_HEAD(&bfad->pbc_vport_list);
1393e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
13947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	retval = bfad_drv_init(bfad);
13957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (retval != BFA_STATUS_OK)
13967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_drv_init_failure;
13977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1398a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_sm_send_event(bfad, BFAD_E_CREATE);
13997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1400a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (bfa_sm_cmp_state(bfad, bfad_sm_uninit))
1401a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		goto out_bfad_sm_failure;
14027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
14037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return 0;
14047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1405a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiout_bfad_sm_failure:
1406a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_detach(&bfad->bfa);
1407a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfad_hal_mem_release(bfad);
14087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_drv_init_failure:
14097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mutex_lock(&bfad_mutex);
14107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_inst--;
14117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	list_del(&bfad->list_entry);
14127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mutex_unlock(&bfad_mutex);
14137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_pci_uninit(pdev, bfad);
14147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_pci_init_failure:
14157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	kfree(bfad->trcmod);
14167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_alloc_trace_failure:
14177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	kfree(bfad);
14187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout:
14197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return error;
14207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
14217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
14225fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
14237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * PCI remove entry.
14247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
14257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
14267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_pci_remove(struct pci_dev *pdev)
14277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
1428a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfad_s	      *bfad = pci_get_drvdata(pdev);
1429a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	unsigned long	flags;
14307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
14317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_trc(bfad, bfad->inst_no);
14327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1433e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
1434a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (bfad->bfad_tsk != NULL) {
14357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1436a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		kthread_stop(bfad->bfad_tsk);
1437a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	} else {
1438e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1439e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	}
14407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1441a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* Send Event BFAD_E_STOP */
1442a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_sm_send_event(bfad, BFAD_E_STOP);
1443e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1444a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* Driver detach and dealloc mem */
14457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
14467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_detach(&bfad->bfa);
14477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
14487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_hal_mem_release(bfad);
14497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1450a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* Cleaning the BFAD instance */
14517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mutex_lock(&bfad_mutex);
14527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_inst--;
14537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	list_del(&bfad->list_entry);
14547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mutex_unlock(&bfad_mutex);
14557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_pci_uninit(pdev, bfad);
14567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
14577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	kfree(bfad->trcmod);
14587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	kfree(bfad);
14597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
14607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1461a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistruct pci_device_id bfad_id_table[] = {
14627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	{
1463a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.vendor = BFA_PCI_VENDOR_ID_BROCADE,
1464a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.device = BFA_PCI_DEVICE_ID_FC_8G2P,
1465a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.subvendor = PCI_ANY_ID,
1466a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.subdevice = PCI_ANY_ID,
1467a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	},
14687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	{
1469a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.vendor = BFA_PCI_VENDOR_ID_BROCADE,
1470a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.device = BFA_PCI_DEVICE_ID_FC_8G1P,
1471a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.subvendor = PCI_ANY_ID,
1472a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.subdevice = PCI_ANY_ID,
1473a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	},
14747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	{
1475a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.vendor = BFA_PCI_VENDOR_ID_BROCADE,
1476a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.device = BFA_PCI_DEVICE_ID_CT,
1477a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.subvendor = PCI_ANY_ID,
1478a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.subdevice = PCI_ANY_ID,
1479a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.class = (PCI_CLASS_SERIAL_FIBER << 8),
1480a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.class_mask = ~0,
1481a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	},
1482293f82d59ed8b6d61d242e40ee7a6a146fae5eaaJing Huang	{
1483a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.vendor = BFA_PCI_VENDOR_ID_BROCADE,
1484a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.device = BFA_PCI_DEVICE_ID_CT_FC,
1485a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.subvendor = PCI_ANY_ID,
1486a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.subdevice = PCI_ANY_ID,
1487a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.class = (PCI_CLASS_SERIAL_FIBER << 8),
1488a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.class_mask = ~0,
1489293f82d59ed8b6d61d242e40ee7a6a146fae5eaaJing Huang	},
14907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
14917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	{0, 0},
14927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang};
14937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
14947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_DEVICE_TABLE(pci, bfad_id_table);
14957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
14967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic struct pci_driver bfad_pci_driver = {
14977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	.name = BFAD_DRIVER_NAME,
14987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	.id_table = bfad_id_table,
14997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	.probe = bfad_pci_probe,
15007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	.remove = __devexit_p(bfad_pci_remove),
15017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang};
15027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
15035fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
15047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Driver module init.
15057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
1506a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic int __init
15077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_init(void)
15087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
1509a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int		error = 0;
15107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
15117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	printk(KERN_INFO "Brocade BFA FC/FCOE SCSI driver - version: %s\n",
1512a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			BFAD_DRIVER_VERSION);
15137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
15147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_sgpgs > 0)
15157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		num_sgpgs_parm = num_sgpgs;
15167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1517a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	error = bfad_im_module_init();
15187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (error) {
15197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		error = -ENOMEM;
1520a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		printk(KERN_WARNING "bfad_im_module_init failure\n");
15217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
15227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
15237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1524a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (strcmp(FCPI_NAME, " fcpim") == 0)
1525a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		supported_fc4s |= BFA_LPORT_ROLE_FCP_IM;
15267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1527f7f73812e95077c19a2801bbf4f483fcdab5232fMaggie Zhang	bfa_auto_recover = ioc_auto_recover;
15287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_rport_set_del_timeout(rport_del_timeout);
15297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1530a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	error = pci_register_driver(&bfad_pci_driver);
15317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (error) {
1532a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		printk(KERN_WARNING "pci_register_driver failure\n");
15337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
15347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
15357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
15367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return 0;
15377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
15387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext:
1539a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfad_im_module_exit();
15407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return error;
15417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
15427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
15435fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
15447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Driver module exit.
15457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
1546a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void __exit
15477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_exit(void)
15487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
15497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_unregister_driver(&bfad_pci_driver);
1550a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfad_im_module_exit();
15517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_free_fwimg();
15527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
15537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1554a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati/* Firmware handling */
1555a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiu32 *
1556a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image,
1557a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		u32 *bfi_image_size, char *fw_name)
1558a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati{
1559a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	const struct firmware *fw;
1560a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1561a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (request_firmware(&fw, fw_name, &pdev->dev)) {
1562a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		printk(KERN_ALERT "Can't locate firmware %s\n", fw_name);
1563a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		goto error;
1564a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
1565a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1566a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	*bfi_image = vmalloc(fw->size);
1567a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (NULL == *bfi_image) {
1568a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		printk(KERN_ALERT "Fail to allocate buffer for fw image "
1569a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			"size=%x!\n", (u32) fw->size);
1570a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		goto error;
1571a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
1572a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1573a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	memcpy(*bfi_image, fw->data, fw->size);
1574a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	*bfi_image_size = fw->size/sizeof(u32);
1575a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1576a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	return *bfi_image;
1577a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1578a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatierror:
1579a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	return NULL;
1580a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati}
1581a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1582a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiu32 *
1583a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_get_firmware_buf(struct pci_dev *pdev)
1584a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati{
1585a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (pdev->device == BFA_PCI_DEVICE_ID_CT_FC) {
1586a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (bfi_image_ct_fc_size == 0)
1587a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad_read_firmware(pdev, &bfi_image_ct_fc,
1588a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				&bfi_image_ct_fc_size, BFAD_FW_FILE_CT_FC);
1589a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		return bfi_image_ct_fc;
1590a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	} else if (pdev->device == BFA_PCI_DEVICE_ID_CT) {
1591a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (bfi_image_ct_cna_size == 0)
1592a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad_read_firmware(pdev, &bfi_image_ct_cna,
1593a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				&bfi_image_ct_cna_size, BFAD_FW_FILE_CT_CNA);
1594a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		return bfi_image_ct_cna;
1595a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	} else {
1596a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (bfi_image_cb_fc_size == 0)
1597a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad_read_firmware(pdev, &bfi_image_cb_fc,
1598a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				&bfi_image_cb_fc_size, BFAD_FW_FILE_CB_FC);
1599a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		return bfi_image_cb_fc;
1600a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
1601a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati}
16027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
16037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_init(bfad_init);
16047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_exit(bfad_exit);
16057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_LICENSE("GPL");
16067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_DESCRIPTION("Brocade Fibre Channel HBA Driver" BFAD_PROTO_NAME);
16077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_AUTHOR("Brocade Communications Systems, Inc.");
16087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_VERSION(BFAD_DRIVER_VERSION);
1609