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_defs.h"
36a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati#include "bfa.h"
377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangBFA_TRC_FILE(LDRV, BFAD);
3942b426ecb453cf49c3d16cf1d7a5e5d8cab9869dJing HuangDEFINE_MUTEX(bfad_mutex);
407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangLIST_HEAD(bfad_list);
41a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
42a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic int	bfad_inst;
43a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic int      num_sgpgs_parm;
44a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint		supported_fc4s;
45a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatichar		*host_name, *os_name, *os_patch;
46a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint		num_rports, num_ios, num_tms;
47a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint		num_fcxps, num_ufbufs;
48a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint		reqq_size, rspq_size, num_sgpgs;
49a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint		rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT;
50a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint		bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH;
51a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint		bfa_io_max_sge = BFAD_IO_MAX_SGE;
528816624222b12e5d7e291e9d1973fc42b994eb6bJing Huangint		bfa_log_level = 3; /* WARNING log level */
53a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint		ioc_auto_recover = BFA_TRUE;
54a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint		bfa_linkup_delay = -1;
55a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint		fdmi_enable = BFA_TRUE;
56a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint		pcie_max_read_reqsz;
57ab2a9ba189e889b3e8990e52e90d2cd9606b2aa1Jing Huangint		bfa_debugfs_enable = 1;
58a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint		msix_disable_cb = 0, msix_disable_ct = 0;
5961e62e21afe469854e04546ea10b7a6f4cfd1142Krishna Gudipatiint		max_xfer_size = BFAD_MAX_SECTORS >> 1;
60a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
6161338a0b3493fddfca2980ece4423839748fcbabJing Huang/* Firmware releated */
62111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipatiu32	bfi_image_cb_size, bfi_image_ct_size, bfi_image_ct2_size;
63111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipatiu32	*bfi_image_cb, *bfi_image_ct, *bfi_image_ct2;
64a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
65111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati#define BFAD_FW_FILE_CB		"cbfw.bin"
66111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati#define BFAD_FW_FILE_CT		"ctfw.bin"
67111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati#define BFAD_FW_FILE_CT2	"ct2fw.bin"
6861338a0b3493fddfca2980ece4423839748fcbabJing Huang
6961338a0b3493fddfca2980ece4423839748fcbabJing Huangstatic u32 *bfad_load_fwimg(struct pci_dev *pdev);
7061338a0b3493fddfca2980ece4423839748fcbabJing Huangstatic void bfad_free_fwimg(void);
7161338a0b3493fddfca2980ece4423839748fcbabJing Huangstatic void bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image,
7261338a0b3493fddfca2980ece4423839748fcbabJing Huang		u32 *bfi_image_size, char *fw_name);
7361338a0b3493fddfca2980ece4423839748fcbabJing Huang
7452f94b6fd0d1ff9d935c52f8a6360834ed871d92Maggiestatic const char *msix_name_ct[] = {
75111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati	"ctrl",
76a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	"cpe0", "cpe1", "cpe2", "cpe3",
77111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati	"rme0", "rme1", "rme2", "rme3" };
78a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
7952f94b6fd0d1ff9d935c52f8a6360834ed871d92Maggiestatic const char *msix_name_cb[] = {
80a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	"cpe0", "cpe1", "cpe2", "cpe3",
81a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	"rme0", "rme1", "rme2", "rme3",
82a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	"eemc", "elpu0", "elpu1", "epss", "mlpu" };
83a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
84111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna GudipatiMODULE_FIRMWARE(BFAD_FW_FILE_CB);
85111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna GudipatiMODULE_FIRMWARE(BFAD_FW_FILE_CT);
86111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna GudipatiMODULE_FIRMWARE(BFAD_FW_FILE_CT2);
877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(os_name, charp, S_IRUGO | S_IWUSR);
89604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(os_name, "OS name of the hba host machine");
907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(os_patch, charp, S_IRUGO | S_IWUSR);
91604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(os_patch, "OS patch level of the hba host machine");
927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(host_name, charp, S_IRUGO | S_IWUSR);
93604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(host_name, "Hostname of the hba host machine");
947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_rports, int, S_IRUGO | S_IWUSR);
95a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_PARM_DESC(num_rports, "Max number of rports supported per port "
96a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				"(physical/logical), default=1024");
977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_ios, int, S_IRUGO | S_IWUSR);
98604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(num_ios, "Max number of ioim requests, default=2000");
997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_tms, int, S_IRUGO | S_IWUSR);
100604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(num_tms, "Max number of task im requests, default=128");
1017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_fcxps, int, S_IRUGO | S_IWUSR);
102604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(num_fcxps, "Max number of fcxp requests, default=64");
1037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_ufbufs, int, S_IRUGO | S_IWUSR);
104a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_PARM_DESC(num_ufbufs, "Max number of unsolicited frame "
105a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				"buffers, default=64");
1067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(reqq_size, int, S_IRUGO | S_IWUSR);
107a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_PARM_DESC(reqq_size, "Max number of request queue elements, "
108a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				"default=256");
1097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(rspq_size, int, S_IRUGO | S_IWUSR);
110a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_PARM_DESC(rspq_size, "Max number of response queue elements, "
111a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				"default=64");
1127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_sgpgs, int, S_IRUGO | S_IWUSR);
113604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(num_sgpgs, "Number of scatter/gather pages, default=2048");
1147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(rport_del_timeout, int, S_IRUGO | S_IWUSR);
115a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_PARM_DESC(rport_del_timeout, "Rport delete timeout, default=90 secs, "
116a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati					"Range[>0]");
1177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(bfa_lun_queue_depth, int, S_IRUGO | S_IWUSR);
118a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_PARM_DESC(bfa_lun_queue_depth, "Lun queue depth, default=32, Range[>0]");
1197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(bfa_io_max_sge, int, S_IRUGO | S_IWUSR);
120604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(bfa_io_max_sge, "Max io scatter/gather elements, default=255");
1218816624222b12e5d7e291e9d1973fc42b994eb6bJing Huangmodule_param(bfa_log_level, int, S_IRUGO | S_IWUSR);
1228816624222b12e5d7e291e9d1973fc42b994eb6bJing HuangMODULE_PARM_DESC(bfa_log_level, "Driver log level, default=3, "
123a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				"Range[Critical:1|Error:2|Warning:3|Info:4]");
1247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR);
125a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_PARM_DESC(ioc_auto_recover, "IOC auto recovery, default=1, "
126a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				"Range[off:0|on:1]");
1277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(bfa_linkup_delay, int, S_IRUGO | S_IWUSR);
128a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_PARM_DESC(bfa_linkup_delay, "Link up delay, default=30 secs for "
129a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			"boot port. Otherwise 10 secs in RHEL4 & 0 for "
130a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			"[RHEL5, SLES10, ESX40] Range[>0]");
131a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatimodule_param(msix_disable_cb, int, S_IRUGO | S_IWUSR);
132a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_PARM_DESC(msix_disable_cb, "Disable Message Signaled Interrupts "
133a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			"for Brocade-415/425/815/825 cards, default=0, "
134a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			" Range[false:0|true:1]");
135a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatimodule_param(msix_disable_ct, int, S_IRUGO | S_IWUSR);
136a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_PARM_DESC(msix_disable_ct, "Disable Message Signaled Interrupts "
137a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			"if possible for Brocade-1010/1020/804/1007/902/1741 "
138a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			"cards, default=0, Range[false:0|true:1]");
139604158ade0d5378622541232a007bf975c8bd03fJing Huangmodule_param(fdmi_enable, int, S_IRUGO | S_IWUSR);
140a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_PARM_DESC(fdmi_enable, "Enables fdmi registration, default=1, "
141a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				"Range[false:0|true:1]");
142a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatimodule_param(pcie_max_read_reqsz, int, S_IRUGO | S_IWUSR);
143a36c61f9025b8924f99f54d518763bee7aa84085Krishna GudipatiMODULE_PARM_DESC(pcie_max_read_reqsz, "PCIe max read request size, default=0 "
144a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		"(use system setting), Range[128|256|512|1024|2048|4096]");
145ab2a9ba189e889b3e8990e52e90d2cd9606b2aa1Jing Huangmodule_param(bfa_debugfs_enable, int, S_IRUGO | S_IWUSR);
146ab2a9ba189e889b3e8990e52e90d2cd9606b2aa1Jing HuangMODULE_PARM_DESC(bfa_debugfs_enable, "Enables debugfs feature, default=1,"
147ab2a9ba189e889b3e8990e52e90d2cd9606b2aa1Jing Huang		" Range[false:0|true:1]");
14861e62e21afe469854e04546ea10b7a6f4cfd1142Krishna Gudipatimodule_param(max_xfer_size, int, S_IRUGO | S_IWUSR);
14961e62e21afe469854e04546ea10b7a6f4cfd1142Krishna GudipatiMODULE_PARM_DESC(max_xfer_size, "default=32MB,"
15061e62e21afe469854e04546ea10b7a6f4cfd1142Krishna Gudipati		" Range[64k|128k|256k|512k|1024k|2048k]");
1517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
152a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void
153a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_uninit(struct bfad_s *bfad, enum bfad_sm_event event);
154a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void
155a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_created(struct bfad_s *bfad, enum bfad_sm_event event);
156a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void
157a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_initializing(struct bfad_s *bfad, enum bfad_sm_event event);
158a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void
159a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_operational(struct bfad_s *bfad, enum bfad_sm_event event);
160a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void
161a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_stopping(struct bfad_s *bfad, enum bfad_sm_event event);
162a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void
163a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_failed(struct bfad_s *bfad, enum bfad_sm_event event);
164a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void
165a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_fcs_exit(struct bfad_s *bfad, enum bfad_sm_event event);
166a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1675fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
168a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati * Beginning state for the driver instance, awaiting the pci_probe event
1697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
170a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void
171a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_uninit(struct bfad_s *bfad, enum bfad_sm_event event)
172a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati{
173a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_trc(bfad, event);
174a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
175a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	switch (event) {
176a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_CREATE:
177a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_set_state(bfad, bfad_sm_created);
178a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad->bfad_tsk = kthread_create(bfad_worker, (void *) bfad,
179a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati						"%s", "bfad_worker");
180a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (IS_ERR(bfad->bfad_tsk)) {
181a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			printk(KERN_INFO "bfad[%d]: Kernel thread "
182a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				"creation failed!\n", bfad->inst_no);
183a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfa_sm_send_event(bfad, BFAD_E_KTHREAD_CREATE_FAILED);
184a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
185a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_send_event(bfad, BFAD_E_INIT);
186a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
187a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
188a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_STOP:
189a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		/* Ignore stop; already in uninit */
190a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
191a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
192a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	default:
193a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_fault(bfad, event);
194a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
195a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati}
1967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1975fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
198a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati * Driver Instance is created, awaiting event INIT to initialize the bfad
199a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati */
200a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void
201a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_created(struct bfad_s *bfad, enum bfad_sm_event event)
2027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
203a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	unsigned long flags;
2047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
205a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_trc(bfad, event);
2067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
207a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	switch (event) {
208a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_INIT:
209a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_set_state(bfad, bfad_sm_initializing);
2107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
211a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		init_completion(&bfad->comp);
212e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
213a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		/* Enable Interrupt and wait bfa_init completion */
214a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (bfad_setup_intr(bfad)) {
215a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			printk(KERN_WARNING "bfad%d: bfad_setup_intr failed\n",
216a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati					bfad->inst_no);
217a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfa_sm_send_event(bfad, BFAD_E_INTR_INIT_FAILED);
218a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			break;
219a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
220a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
221a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		spin_lock_irqsave(&bfad->bfad_lock, flags);
222f7f73812e95077c19a2801bbf4f483fcdab5232fMaggie Zhang		bfa_iocfc_init(&bfad->bfa);
223a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
224a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
225a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		/* Set up interrupt handler for each vectors */
226a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if ((bfad->bfad_flags & BFAD_MSIX_ON) &&
227a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad_install_msix_handler(bfad)) {
228a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			printk(KERN_WARNING "%s: install_msix failed, bfad%d\n",
229a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				__func__, bfad->inst_no);
230a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
231a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
232a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad_init_timer(bfad);
233a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
234a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		wait_for_completion(&bfad->comp);
235a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
236a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if ((bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
237a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfa_sm_send_event(bfad, BFAD_E_INIT_SUCCESS);
238a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		} else {
2397c38c05b3ef1a8a9f7e0416072a8ea2730841c91Krishna Gudipati			printk(KERN_WARNING
2407c38c05b3ef1a8a9f7e0416072a8ea2730841c91Krishna Gudipati				"bfa %s: bfa init failed\n",
2417c38c05b3ef1a8a9f7e0416072a8ea2730841c91Krishna Gudipati				bfad->pci_name);
242a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad->bfad_flags |= BFAD_HAL_INIT_FAIL;
243a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfa_sm_send_event(bfad, BFAD_E_INIT_FAILED);
244a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
245a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
246a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
247a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
248a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_KTHREAD_CREATE_FAILED:
249a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_set_state(bfad, bfad_sm_uninit);
250a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
251a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
252a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	default:
253a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_fault(bfad, event);
254a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
2557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
2567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic void
258a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_initializing(struct bfad_s *bfad, enum bfad_sm_event event)
2597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
260a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int	retval;
261a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	unsigned long	flags;
262a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
263a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_trc(bfad, event);
264a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
265a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	switch (event) {
266a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_INIT_SUCCESS:
267a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		kthread_stop(bfad->bfad_tsk);
268a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		spin_lock_irqsave(&bfad->bfad_lock, flags);
269a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad->bfad_tsk = NULL;
270a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
271a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
272a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		retval = bfad_start_ops(bfad);
273a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (retval != BFA_STATUS_OK)
274a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			break;
275a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_set_state(bfad, bfad_sm_operational);
276a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
277a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
278a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_INTR_INIT_FAILED:
279a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_set_state(bfad, bfad_sm_uninit);
280a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		kthread_stop(bfad->bfad_tsk);
281a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		spin_lock_irqsave(&bfad->bfad_lock, flags);
282a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad->bfad_tsk = NULL;
283a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
284a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
285a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
286a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_INIT_FAILED:
287a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_set_state(bfad, bfad_sm_failed);
288a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
289a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	default:
290a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_fault(bfad, event);
291a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
2927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
2937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic void
295a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_failed(struct bfad_s *bfad, enum bfad_sm_event event)
2967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
297a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int	retval;
2987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
299a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_trc(bfad, event);
300a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
301a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	switch (event) {
302a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_INIT_SUCCESS:
303a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		retval = bfad_start_ops(bfad);
304a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (retval != BFA_STATUS_OK)
305a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			break;
306a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_set_state(bfad, bfad_sm_operational);
307a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
308a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
309a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_STOP:
310a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (bfad->bfad_flags & BFAD_CFG_PPORT_DONE)
311a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad_uncfg_pport(bfad);
312a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (bfad->bfad_flags & BFAD_FC4_PROBE_DONE) {
313a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad_im_probe_undo(bfad);
314a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad->bfad_flags &= ~BFAD_FC4_PROBE_DONE;
315a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
316a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad_stop(bfad);
317a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
318a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
319a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_EXIT_COMP:
320a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_set_state(bfad, bfad_sm_uninit);
321a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad_remove_intr(bfad);
322a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		del_timer_sync(&bfad->hal_tmo);
323a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
324a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
325a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	default:
326a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_fault(bfad, event);
327a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
3287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
3297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
330a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void
331a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_operational(struct bfad_s *bfad, enum bfad_sm_event event)
3327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
333a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_trc(bfad, event);
3347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
335a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	switch (event) {
336a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_STOP:
337a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_set_state(bfad, bfad_sm_fcs_exit);
338a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad_fcs_stop(bfad);
339a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
3407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
341a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	default:
342a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_fault(bfad, event);
343a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
344a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati}
3457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
346a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void
347a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_fcs_exit(struct bfad_s *bfad, enum bfad_sm_event event)
348a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati{
349a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_trc(bfad, event);
350a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
351a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	switch (event) {
352a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_FCS_EXIT_COMP:
353a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_set_state(bfad, bfad_sm_stopping);
354a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad_stop(bfad);
355a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
356a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
357a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	default:
358a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_fault(bfad, event);
359a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
3607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
3617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic void
363a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_sm_stopping(struct bfad_s *bfad, enum bfad_sm_event event)
3647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
365a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_trc(bfad, event);
3667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
367a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	switch (event) {
368a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	case BFAD_E_EXIT_COMP:
369a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_set_state(bfad, bfad_sm_uninit);
370a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad_remove_intr(bfad);
371a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		del_timer_sync(&bfad->hal_tmo);
372a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad_im_probe_undo(bfad);
373a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad->bfad_flags &= ~BFAD_FC4_PROBE_DONE;
374a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad_uncfg_pport(bfad);
375a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
3767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
377a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	default:
378a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_fault(bfad, event);
379a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		break;
380a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
3817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
3827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3835fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
3847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang *  BFA callbacks
3857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
3867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
3877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_hcb_comp(void *arg, bfa_status_t status)
3887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
3897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfad_hal_comp *fcomp = (struct bfad_hal_comp *)arg;
3907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	fcomp->status = status;
3927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	complete(&fcomp->comp);
3937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
3947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3955fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
3967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * bfa_init callback
3977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
3987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
3997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_cb_init(void *drv, bfa_status_t init_status)
4007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
401a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfad_s	      *bfad = drv;
4027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
403e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	if (init_status == BFA_STATUS_OK) {
4047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad->bfad_flags |= BFAD_HAL_INIT_DONE;
4057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
406a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		/*
407a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		 * If BFAD_HAL_INIT_FAIL flag is set:
408e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		 * Wake up the kernel thread to start
409e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		 * the bfad operations after HAL init done
410e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		 */
411e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		if ((bfad->bfad_flags & BFAD_HAL_INIT_FAIL)) {
412e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati			bfad->bfad_flags &= ~BFAD_HAL_INIT_FAIL;
413e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati			wake_up_process(bfad->bfad_tsk);
414e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		}
415e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	}
416e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
4177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	complete(&bfad->comp);
4187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
4197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4205fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
4217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang *  BFA_FCS callbacks
4227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
4237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstruct bfad_port_s *
424a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfa_fcb_lport_new(struct bfad_s *bfad, struct bfa_fcs_lport_s *port,
425a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		 enum bfa_lport_role roles, struct bfad_vf_s *vf_drv,
4267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		 struct bfad_vport_s *vp_drv)
4277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
428a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_status_t	rc;
429a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfad_port_s    *port_drv;
4307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!vp_drv && !vf_drv) {
4327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv = &bfad->pport;
4337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv->pvb_type = BFAD_PORT_PHYS_BASE;
4347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	} else if (!vp_drv && vf_drv) {
4357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv = &vf_drv->base_port;
4367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv->pvb_type = BFAD_PORT_VF_BASE;
4377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	} else if (vp_drv && !vf_drv) {
4387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv = &vp_drv->drv_port;
4397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv->pvb_type = BFAD_PORT_PHYS_VPORT;
4407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	} else {
4417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv = &vp_drv->drv_port;
4427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv->pvb_type = BFAD_PORT_VF_VPORT;
4437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
4447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	port_drv->fcs_port = port;
4467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	port_drv->roles = roles;
447a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
448a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (roles & BFA_LPORT_ROLE_FCP_IM) {
449a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		rc = bfad_im_port_new(bfad, port_drv);
450a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (rc != BFA_STATUS_OK) {
451a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad_im_port_delete(bfad, port_drv);
452a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			port_drv = NULL;
453a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
4547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
4557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return port_drv;
4577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
4587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
460a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfa_fcb_lport_delete(struct bfad_s *bfad, enum bfa_lport_role roles,
4617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		    struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
4627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
463a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfad_port_s    *port_drv;
4647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
465a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* this will be only called from rmmod context */
4667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (vp_drv && !vp_drv->comp_del) {
467a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		port_drv = (vp_drv) ? (&(vp_drv)->drv_port) :
468a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				((vf_drv) ? (&(vf_drv)->base_port) :
469a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				(&(bfad)->pport));
4707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_trc(bfad, roles);
471a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (roles & BFA_LPORT_ROLE_FCP_IM)
472a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad_im_port_delete(bfad, port_drv);
4737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
4747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
4757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4765fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
4777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * FCS RPORT alloc callback, after successful PLOGI by FCS
4787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
4797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t
4807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_fcb_rport_alloc(struct bfad_s *bfad, struct bfa_fcs_rport_s **rport,
4817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		    struct bfad_rport_s **rport_drv)
4827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
483a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_status_t	rc = BFA_STATUS_OK;
4847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	*rport_drv = kzalloc(sizeof(struct bfad_rport_s), GFP_ATOMIC);
4867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (*rport_drv == NULL) {
4877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		rc = BFA_STATUS_ENOMEM;
4887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
4897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
4907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	*rport = &(*rport_drv)->fcs_rport;
4927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext:
4947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
4957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
4967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4975fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
498d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang * FCS PBC VPORT Create
499d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang */
500d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huangvoid
501d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huangbfa_fcb_pbc_vport_create(struct bfad_s *bfad, struct bfi_pbc_vport_s pbc_vport)
502d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang{
503d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang
504a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfa_lport_cfg_s port_cfg = {0};
505a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfad_vport_s   *vport;
506a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int rc;
507d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang
508a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	vport = kzalloc(sizeof(struct bfad_vport_s), GFP_KERNEL);
509a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (!vport) {
510d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang		bfa_trc(bfad, 0);
511d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang		return;
512d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang	}
5137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
514a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	vport->drv_port.bfad = bfad;
515a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	port_cfg.roles = BFA_LPORT_ROLE_FCP_IM;
516a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	port_cfg.pwwn = pbc_vport.vp_pwwn;
517a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	port_cfg.nwwn = pbc_vport.vp_nwwn;
518a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	port_cfg.preboot_vp  = BFA_TRUE;
519a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
520a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	rc = bfa_fcs_pbc_vport_create(&vport->fcs_vport, &bfad->bfa_fcs, 0,
521a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				  &port_cfg, vport);
522d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang
523a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (rc != BFA_STATUS_OK) {
524a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_trc(bfad, 0);
525a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		return;
526a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
527d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang
528a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	list_add_tail(&vport->list_entry, &bfad->pbc_vport_list);
529d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang}
5307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
5327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_hal_mem_release(struct bfad_s *bfad)
5337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
5347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfa_meminfo_s *hal_meminfo = &bfad->meminfo;
5354507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	struct bfa_mem_dma_s *dma_info, *dma_elem;
5364507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	struct bfa_mem_kva_s *kva_info, *kva_elem;
5374507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	struct list_head *dm_qe, *km_qe;
5384507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati
5394507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	dma_info = &hal_meminfo->dma_info;
5404507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	kva_info = &hal_meminfo->kva_info;
5414507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati
5424507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	/* Iterate through the KVA meminfo queue */
5434507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	list_for_each(km_qe, &kva_info->qe) {
5444507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati		kva_elem = (struct bfa_mem_kva_s *) km_qe;
5454507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati		vfree(kva_elem->kva);
5464507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	}
5474507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati
5484507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	/* Iterate through the DMA meminfo queue */
5494507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	list_for_each(dm_qe, &dma_info->qe) {
5504507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati		dma_elem = (struct bfa_mem_dma_s *) dm_qe;
5514507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati		dma_free_coherent(&bfad->pcidev->dev,
5524507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati				dma_elem->mem_len, dma_elem->kva,
5534507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati				(dma_addr_t) dma_elem->dma);
5547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
5557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	memset(hal_meminfo, 0, sizeof(struct bfa_meminfo_s));
5577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
5587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
5607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_update_hal_cfg(struct bfa_iocfc_cfg_s *bfa_cfg)
5617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
5627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_rports > 0)
5637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->fwcfg.num_rports = num_rports;
5647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_ios > 0)
5657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->fwcfg.num_ioim_reqs = num_ios;
5667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_tms > 0)
5677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->fwcfg.num_tskim_reqs = num_tms;
5684507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	if (num_fcxps > 0 && num_fcxps <= BFA_FCXP_MAX)
5697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->fwcfg.num_fcxp_reqs = num_fcxps;
5704507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	if (num_ufbufs > 0 && num_ufbufs <= BFA_UF_MAX)
5717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->fwcfg.num_uf_bufs = num_ufbufs;
5727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (reqq_size > 0)
5737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->drvcfg.num_reqq_elems = reqq_size;
5747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (rspq_size > 0)
5757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->drvcfg.num_rspq_elems = rspq_size;
5764507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	if (num_sgpgs > 0 && num_sgpgs <= BFA_SGPG_MAX)
5777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->drvcfg.num_sgpgs = num_sgpgs;
5787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	/*
5807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 * populate the hal values back to the driver for sysfs use.
5817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 * otherwise, the default values will be shown as 0 in sysfs
5827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 */
5837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	num_rports = bfa_cfg->fwcfg.num_rports;
584a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	num_ios = bfa_cfg->fwcfg.num_ioim_reqs;
585a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	num_tms = bfa_cfg->fwcfg.num_tskim_reqs;
586a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	num_fcxps = bfa_cfg->fwcfg.num_fcxp_reqs;
5877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	num_ufbufs = bfa_cfg->fwcfg.num_uf_bufs;
588a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	reqq_size = bfa_cfg->drvcfg.num_reqq_elems;
589a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	rspq_size = bfa_cfg->drvcfg.num_rspq_elems;
590a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	num_sgpgs = bfa_cfg->drvcfg.num_sgpgs;
5917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
5927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t
5947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_hal_mem_alloc(struct bfad_s *bfad)
5957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
5967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfa_meminfo_s *hal_meminfo = &bfad->meminfo;
5974507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	struct bfa_mem_dma_s *dma_info, *dma_elem;
5984507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	struct bfa_mem_kva_s *kva_info, *kva_elem;
5994507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	struct list_head *dm_qe, *km_qe;
600a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_status_t	rc = BFA_STATUS_OK;
6014507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	dma_addr_t	phys_addr;
6027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_cfg_get_default(&bfad->ioc_cfg);
6047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_update_hal_cfg(&bfad->ioc_cfg);
6057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->cfg_data.ioc_queue_depth = bfad->ioc_cfg.fwcfg.num_ioim_reqs;
6064507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	bfa_cfg_get_meminfo(&bfad->ioc_cfg, hal_meminfo, &bfad->bfa);
6074507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati
6084507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	dma_info = &hal_meminfo->dma_info;
6094507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	kva_info = &hal_meminfo->kva_info;
6104507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati
6114507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	/* Iterate through the KVA meminfo queue */
6124507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	list_for_each(km_qe, &kva_info->qe) {
6134507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati		kva_elem = (struct bfa_mem_kva_s *) km_qe;
6144507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati		kva_elem->kva = vmalloc(kva_elem->mem_len);
6154507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati		if (kva_elem->kva == NULL) {
6164507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati			bfad_hal_mem_release(bfad);
6174507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati			rc = BFA_STATUS_ENOMEM;
6184507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati			goto ext;
6194507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati		}
6204507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati		memset(kva_elem->kva, 0, kva_elem->mem_len);
6214507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	}
6227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6234507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	/* Iterate through the DMA meminfo queue */
6244507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati	list_for_each(dm_qe, &dma_info->qe) {
6254507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati		dma_elem = (struct bfa_mem_dma_s *) dm_qe;
6264507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati		dma_elem->kva = dma_alloc_coherent(&bfad->pcidev->dev,
6274507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati						dma_elem->mem_len,
6284507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati						&phys_addr, GFP_KERNEL);
6294507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati		if (dma_elem->kva == NULL) {
6304507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati			bfad_hal_mem_release(bfad);
6314507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati			rc = BFA_STATUS_ENOMEM;
6324507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati			goto ext;
6337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		}
6344507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati		dma_elem->dma = phys_addr;
6354507025d01149aea8705e43508d0ef11e7010cfdKrishna Gudipati		memset(dma_elem->kva, 0, dma_elem->mem_len);
6367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
6377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext:
6387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
6397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
6407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6415fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
6427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Create a vport under a vf.
6437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
6447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t
6457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_vport_create(struct bfad_s *bfad, u16 vf_id,
646a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		  struct bfa_lport_cfg_s *port_cfg, struct device *dev)
6477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
648a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfad_vport_s   *vport;
649a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int		rc = BFA_STATUS_OK;
650a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	unsigned long	flags;
6517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct completion fcomp;
6527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	vport = kzalloc(sizeof(struct bfad_vport_s), GFP_KERNEL);
6547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!vport) {
6557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		rc = BFA_STATUS_ENOMEM;
6567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
6577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
6587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	vport->drv_port.bfad = bfad;
6607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
661a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	rc = bfa_fcs_vport_create(&vport->fcs_vport, &bfad->bfa_fcs, vf_id,
662a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				  port_cfg, vport);
6637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
6647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (rc != BFA_STATUS_OK)
6667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext_free_vport;
6677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
668a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (port_cfg->roles & BFA_LPORT_ROLE_FCP_IM) {
669b504293fe9dc42917a919044f2b672fb361329d0Jing Huang		rc = bfad_im_scsi_host_alloc(bfad, vport->drv_port.im_port,
670b504293fe9dc42917a919044f2b672fb361329d0Jing Huang							dev);
6717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		if (rc != BFA_STATUS_OK)
6727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			goto ext_free_fcs_vport;
6737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
6747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
6767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_vport_start(&vport->fcs_vport);
6775b7db7af522d9f281ff8bf540d2b5cbea2206b27Krishna Gudipati	list_add_tail(&vport->list_entry, &bfad->vport_list);
6787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
6797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return BFA_STATUS_OK;
6817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext_free_fcs_vport:
6837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
6847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	vport->comp_del = &fcomp;
6857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	init_completion(vport->comp_del);
6867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_vport_delete(&vport->fcs_vport);
6877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
6887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	wait_for_completion(vport->comp_del);
6897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext_free_vport:
6907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	kfree(vport);
6917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext:
6927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
6937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
6947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
6967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_bfa_tmo(unsigned long data)
6977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
698a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfad_s	      *bfad = (struct bfad_s *) data;
699a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	unsigned long	flags;
700a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct list_head	       doneq;
7017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
7037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
704f7f73812e95077c19a2801bbf4f483fcdab5232fMaggie Zhang	bfa_timer_beat(&bfad->bfa.timer_mod);
7057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_comp_deq(&bfad->bfa, &doneq);
7077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
7087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!list_empty(&doneq)) {
7107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_comp_process(&bfad->bfa, &doneq);
7117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		spin_lock_irqsave(&bfad->bfad_lock, flags);
7127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_comp_free(&bfad->bfa, &doneq);
7137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
7147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
7157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
716a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	mod_timer(&bfad->hal_tmo,
717a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		  jiffies + msecs_to_jiffies(BFA_TIMER_FREQ));
7187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
7197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
7217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_init_timer(struct bfad_s *bfad)
7227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
7237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	init_timer(&bfad->hal_tmo);
7247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->hal_tmo.function = bfad_bfa_tmo;
7257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->hal_tmo.data = (unsigned long)bfad;
7267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
727a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	mod_timer(&bfad->hal_tmo,
728a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		  jiffies + msecs_to_jiffies(BFA_TIMER_FREQ));
7297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
7307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangint
7327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_pci_init(struct pci_dev *pdev, struct bfad_s *bfad)
7337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
734a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int		rc = -ENODEV;
7357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (pci_enable_device(pdev)) {
737a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		printk(KERN_ERR "pci_enable_device fail %p\n", pdev);
7387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out;
7397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
7407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (pci_request_regions(pdev, BFAD_DRIVER_NAME))
7427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_disable_device;
7437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_set_master(pdev);
7457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
74710a07379247078448c076690657a076076bf89aaKrishna Gudipati	if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) ||
74810a07379247078448c076690657a076076bf89aaKrishna Gudipati	    (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) != 0)) {
74910a07379247078448c076690657a076076bf89aaKrishna Gudipati		if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) ||
75010a07379247078448c076690657a076076bf89aaKrishna Gudipati		   (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)) {
751a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			printk(KERN_ERR "pci_set_dma_mask fail %p\n", pdev);
7527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			goto out_release_region;
7537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		}
75410a07379247078448c076690657a076076bf89aaKrishna Gudipati	}
7557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
756b3522f08ec7011aed0abc477bfedd00d189e9cd6Jing Huang	bfad->pci_bar0_kva = pci_iomap(pdev, 0, pci_resource_len(pdev, 0));
757111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati	bfad->pci_bar2_kva = pci_iomap(pdev, 2, pci_resource_len(pdev, 2));
7587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (bfad->pci_bar0_kva == NULL) {
760a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		printk(KERN_ERR "Fail to map bar0\n");
7617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_release_region;
7627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
7637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->hal_pcidev.pci_slot = PCI_SLOT(pdev->devfn);
7657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->hal_pcidev.pci_func = PCI_FUNC(pdev->devfn);
7667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->hal_pcidev.pci_bar_kva = bfad->pci_bar0_kva;
7677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->hal_pcidev.device_id = pdev->device;
7681a4d8e1bd81c018f7b8c7622066d5cfead59b38aKrishna Gudipati	bfad->hal_pcidev.ssid = pdev->subsystem_device;
7697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_name = pci_name(pdev);
7707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_attr.vendor_id = pdev->vendor;
7727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_attr.device_id = pdev->device;
7737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_attr.ssid = pdev->subsystem_device;
7747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_attr.ssvid = pdev->subsystem_vendor;
7757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_attr.pcifn = PCI_FUNC(pdev->devfn);
7767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pcidev = pdev;
778a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
779a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* Adjust PCIe Maximum Read Request Size */
780a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (pcie_max_read_reqsz > 0) {
781a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		int pcie_cap_reg;
782a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		u16 pcie_dev_ctl;
783a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		u16 mask = 0xffff;
784a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
785a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		switch (pcie_max_read_reqsz) {
786a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		case 128:
787a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			mask = 0x0;
788a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			break;
789a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		case 256:
790a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			mask = 0x1000;
791a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			break;
792a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		case 512:
793a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			mask = 0x2000;
794a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			break;
795a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		case 1024:
796a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			mask = 0x3000;
797a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			break;
798a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		case 2048:
799a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			mask = 0x4000;
800a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			break;
801a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		case 4096:
802a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			mask = 0x5000;
803a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			break;
804a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		default:
805a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			break;
806a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
807a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
808a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		pcie_cap_reg = pci_find_capability(pdev, PCI_CAP_ID_EXP);
809a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (mask != 0xffff && pcie_cap_reg) {
810a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			pcie_cap_reg += 0x08;
811a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			pci_read_config_word(pdev, pcie_cap_reg, &pcie_dev_ctl);
812a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			if ((pcie_dev_ctl & 0x7000) != mask) {
813a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				printk(KERN_WARNING "BFA[%s]: "
814a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				"pcie_max_read_request_size is %d, "
815a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				"reset to %d\n", bfad->pci_name,
816a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				(1 << ((pcie_dev_ctl & 0x7000) >> 12)) << 7,
817a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				pcie_max_read_reqsz);
818a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
819a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				pcie_dev_ctl &= ~0x7000;
820a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				pci_write_config_word(pdev, pcie_cap_reg,
821a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati						pcie_dev_ctl | mask);
822a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			}
823a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
824a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
825a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
8267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return 0;
8277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_release_region:
8297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_release_regions(pdev);
8307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_disable_device:
8317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_disable_device(pdev);
8327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout:
8337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
8347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
8357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
8377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_pci_uninit(struct pci_dev *pdev, struct bfad_s *bfad)
8387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
8397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_iounmap(pdev, bfad->pci_bar0_kva);
840111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati	pci_iounmap(pdev, bfad->pci_bar2_kva);
8417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_release_regions(pdev);
8427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_disable_device(pdev);
8437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_set_drvdata(pdev, NULL);
8447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
8457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t
8477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_drv_init(struct bfad_s *bfad)
8487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
849a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_status_t	rc;
850a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	unsigned long	flags;
8517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->cfg_data.rport_del_timeout = rport_del_timeout;
8537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->cfg_data.lun_queue_depth = bfa_lun_queue_depth;
8547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->cfg_data.io_max_sge = bfa_io_max_sge;
8557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->cfg_data.binding_method = FCP_PWWN_BINDING;
8567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	rc = bfad_hal_mem_alloc(bfad);
8587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (rc != BFA_STATUS_OK) {
8597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING "bfad%d bfad_hal_mem_alloc failure\n",
8607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		       bfad->inst_no);
8617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING
862a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			"Not enough memory to attach all Brocade HBA ports, %s",
863a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			"System may need more memory.\n");
8647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_hal_mem_alloc_failure;
8657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
8667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
867f7f73812e95077c19a2801bbf4f483fcdab5232fMaggie Zhang	bfad->bfa.trcmod = bfad->trcmod;
868f7f73812e95077c19a2801bbf4f483fcdab5232fMaggie Zhang	bfad->bfa.plog = &bfad->plog_buf;
8697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_plog_init(&bfad->plog_buf);
8707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_plog_str(&bfad->plog_buf, BFA_PL_MID_DRVR, BFA_PL_EID_DRIVER_START,
8717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		     0, "Driver Attach");
8727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_attach(&bfad->bfa, bfad, &bfad->ioc_cfg, &bfad->meminfo,
8747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		   &bfad->hal_pcidev);
8757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
876a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* FCS INIT */
8777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
878f7f73812e95077c19a2801bbf4f483fcdab5232fMaggie Zhang	bfad->bfa_fcs.trcmod = bfad->trcmod;
87982794a2e4153657d12a0c29272e40b47eaadb748Krishna Gudipati	bfa_fcs_attach(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE);
880f7f73812e95077c19a2801bbf4f483fcdab5232fMaggie Zhang	bfad->bfa_fcs.fdmi_enabled = fdmi_enable;
88175332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati	bfa_fcs_init(&bfad->bfa_fcs);
8827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
8837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->bfad_flags |= BFAD_DRV_INIT_DONE;
885a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
88675332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati	/* configure base port */
88775332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati	rc = bfad_cfg_pport(bfad, BFA_LPORT_ROLE_FCP_IM);
88875332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati	if (rc != BFA_STATUS_OK)
88975332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati		goto out_cfg_pport_fail;
89075332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati
8917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return BFA_STATUS_OK;
8927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
89375332a70a84908810ab5f525b03f230be9e31753Krishna Gudipatiout_cfg_pport_fail:
89475332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati	/* fcs exit - on cfg pport failure */
89575332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
89675332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati	init_completion(&bfad->comp);
89775332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati	bfad->pport.flags |= BFAD_PORT_DELETE;
89875332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati	bfa_fcs_exit(&bfad->bfa_fcs);
89975332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
90075332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati	wait_for_completion(&bfad->comp);
90175332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati	/* bfa detach - free hal memory */
90275332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati	bfa_detach(&bfad->bfa);
90375332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati	bfad_hal_mem_release(bfad);
9047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_hal_mem_alloc_failure:
9057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return BFA_STATUS_FAILED;
9067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
9077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
9087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
9097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_drv_uninit(struct bfad_s *bfad)
9107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
911e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	unsigned long   flags;
912e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
913e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
914e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	init_completion(&bfad->comp);
915f7f73812e95077c19a2801bbf4f483fcdab5232fMaggie Zhang	bfa_iocfc_stop(&bfad->bfa);
916e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
917e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	wait_for_completion(&bfad->comp);
918e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
9197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	del_timer_sync(&bfad->hal_tmo);
9207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_isr_disable(&bfad->bfa);
9217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_detach(&bfad->bfa);
9227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_remove_intr(bfad);
9237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_hal_mem_release(bfad);
924e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
925e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad->bfad_flags &= ~BFAD_DRV_INIT_DONE;
9267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
9277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
9287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
9297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_drv_start(struct bfad_s *bfad)
9307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
931a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	unsigned long	flags;
9327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
9337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
934f7f73812e95077c19a2801bbf4f483fcdab5232fMaggie Zhang	bfa_iocfc_start(&bfad->bfa);
93575332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati	bfa_fcs_pbc_vport_init(&bfad->bfa_fcs);
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
9957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->bfad_flags |= BFAD_CFG_PPORT_DONE;
9967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
9977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout:
9987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
9997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
10007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
10027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_uncfg_pport(struct bfad_s *bfad)
10037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
1004a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if ((supported_fc4s & BFA_LPORT_ROLE_FCP_IM) &&
1005a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	    (bfad->pport.roles & BFA_LPORT_ROLE_FCP_IM)) {
10067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_im_scsi_host_free(bfad, bfad->pport.im_port);
10077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_im_port_clean(bfad->pport.im_port);
10087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		kfree(bfad->pport.im_port);
1009a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad->pport.roles &= ~BFA_LPORT_ROLE_FCP_IM;
10107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
10117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->bfad_flags &= ~BFAD_CFG_PPORT_DONE;
10137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
10147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1015e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatibfa_status_t
1016a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_start_ops(struct bfad_s *bfad) {
1017a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1018a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int	retval;
1019a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	unsigned long	flags;
1020a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfad_vport_s *vport, *vport_new;
1021a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfa_fcs_driver_info_s driver_info;
1022a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
102361e62e21afe469854e04546ea10b7a6f4cfd1142Krishna Gudipati	/* Limit min/max. xfer size to [64k-32MB] */
102461e62e21afe469854e04546ea10b7a6f4cfd1142Krishna Gudipati	if (max_xfer_size < BFAD_MIN_SECTORS >> 1)
102561e62e21afe469854e04546ea10b7a6f4cfd1142Krishna Gudipati		max_xfer_size = BFAD_MIN_SECTORS >> 1;
102661e62e21afe469854e04546ea10b7a6f4cfd1142Krishna Gudipati	if (max_xfer_size > BFAD_MAX_SECTORS >> 1)
102761e62e21afe469854e04546ea10b7a6f4cfd1142Krishna Gudipati		max_xfer_size = BFAD_MAX_SECTORS >> 1;
102861e62e21afe469854e04546ea10b7a6f4cfd1142Krishna Gudipati
1029a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* Fill the driver_info info to fcs*/
1030a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	memset(&driver_info, 0, sizeof(driver_info));
1031a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	strncpy(driver_info.version, BFAD_DRIVER_VERSION,
1032a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		sizeof(driver_info.version) - 1);
1033a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (host_name)
1034a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		strncpy(driver_info.host_machine_name, host_name,
1035a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			sizeof(driver_info.host_machine_name) - 1);
1036a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (os_name)
1037a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		strncpy(driver_info.host_os_name, os_name,
1038a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			sizeof(driver_info.host_os_name) - 1);
1039a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (os_patch)
1040a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		strncpy(driver_info.host_os_patch, os_patch,
1041a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			sizeof(driver_info.host_os_patch) - 1);
1042a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1043a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	strncpy(driver_info.os_device_name, bfad->pci_name,
1044a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		sizeof(driver_info.os_device_name - 1));
1045a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
104675332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati	/* FCS driver info init */
1047a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
1048a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_fcs_driver_info_init(&bfad->bfa_fcs, &driver_info);
1049a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1050e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
105175332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati	/*
105275332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati	 * FCS update cfg - reset the pwwn/nwwn of fabric base logical port
105375332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati	 * with values learned during bfa_init firmware GETATTR REQ.
105475332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati	 */
105575332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati	bfa_fcs_update_cfg(&bfad->bfa_fcs);
105675332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati
105775332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati	/* Setup fc host fixed attribute if the lk supports */
105875332a70a84908810ab5f525b03f230be9e31753Krishna Gudipati	bfad_fc_host_init(bfad->pport.im_port);
1059e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1060a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* BFAD level FC4 IM specific resource allocation */
1061a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	retval = bfad_im_probe(bfad);
1062a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (retval != BFA_STATUS_OK) {
1063a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		printk(KERN_WARNING "bfad_im_probe failed\n");
1064a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (bfa_sm_cmp_state(bfad, bfad_sm_initializing))
1065a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfa_sm_set_state(bfad, bfad_sm_failed);
1066a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad_im_probe_undo(bfad);
1067a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad->bfad_flags &= ~BFAD_FC4_PROBE_DONE;
1068a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad_uncfg_pport(bfad);
1069a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad_stop(bfad);
1070a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		return BFA_STATUS_FAILED;
1071a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	} else
1072a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad->bfad_flags |= BFAD_FC4_PROBE_DONE;
1073a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1074e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad_drv_start(bfad);
1075e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1076a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* Complete pbc vport create */
1077a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	list_for_each_entry_safe(vport, vport_new, &bfad->pbc_vport_list,
1078a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				list_entry) {
1079d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang		struct fc_vport_identifiers vid;
1080d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang		struct fc_vport *fc_vport;
1081a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		char pwwn_buf[BFA_STRING_32];
1082d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang
1083d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang		memset(&vid, 0, sizeof(vid));
1084d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang		vid.roles = FC_PORT_ROLE_FCP_INITIATOR;
1085d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang		vid.vport_type = FC_PORTTYPE_NPIV;
1086d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang		vid.disable = false;
1087a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		vid.node_name = wwn_to_u64((u8 *)
1088a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				(&((vport->fcs_vport).lport.port_cfg.nwwn)));
1089a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		vid.port_name = wwn_to_u64((u8 *)
1090a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				(&((vport->fcs_vport).lport.port_cfg.pwwn)));
1091d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang		fc_vport = fc_vport_create(bfad->pport.im_port->shost, 0, &vid);
1092a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (!fc_vport) {
1093a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			wwn2str(pwwn_buf, vid.port_name);
1094d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang			printk(KERN_WARNING "bfad%d: failed to create pbc vport"
1095a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				" %s\n", bfad->inst_no, pwwn_buf);
1096a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
1097a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		list_del(&vport->list_entry);
1098a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		kfree(vport);
1099d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang	}
1100d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang
1101e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	/*
1102e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	 * If bfa_linkup_delay is set to -1 default; try to retrive the
1103f16a17507b09e10e0cccc4d675ccbfe030d51ef1Maggie Zhang	 * value using the bfad_get_linkup_delay(); else use the
1104e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	 * passed in module param value as the bfa_linkup_delay.
1105e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	 */
1106e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	if (bfa_linkup_delay < 0) {
1107f16a17507b09e10e0cccc4d675ccbfe030d51ef1Maggie Zhang		bfa_linkup_delay = bfad_get_linkup_delay(bfad);
1108f16a17507b09e10e0cccc4d675ccbfe030d51ef1Maggie Zhang		bfad_rport_online_wait(bfad);
1109e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfa_linkup_delay = -1;
1110a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	} else
1111f16a17507b09e10e0cccc4d675ccbfe030d51ef1Maggie Zhang		bfad_rport_online_wait(bfad);
1112e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
11138816624222b12e5d7e291e9d1973fc42b994eb6bJing Huang	BFA_LOG(KERN_INFO, bfad, bfa_log_level, "bfa device claimed\n");
1114e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1115e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	return BFA_STATUS_OK;
1116e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati}
1117e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1118e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatiint
1119d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huangbfad_worker(void *ptr)
1120e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati{
1121e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	struct bfad_s *bfad;
1122e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	unsigned long   flags;
1123e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1124e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad = (struct bfad_s *)ptr;
1125e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1126e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	while (!kthread_should_stop()) {
1127e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1128a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		/* Send event BFAD_E_INIT_SUCCESS */
1129a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_sm_send_event(bfad, BFAD_E_INIT_SUCCESS);
1130e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1131e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		spin_lock_irqsave(&bfad->bfad_lock, flags);
1132e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfad->bfad_tsk = NULL;
1133e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1134e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1135e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		break;
1136e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	}
1137e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1138e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	return 0;
1139e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati}
1140e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
11415fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
1142a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati *  BFA driver interrupt functions
1143a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati */
1144a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiirqreturn_t
1145a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_intx(int irq, void *dev_id)
1146a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati{
1147a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfad_s	*bfad = dev_id;
1148a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct list_head	doneq;
1149a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	unsigned long	flags;
1150a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_boolean_t rc;
1151a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1152a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
1153a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	rc = bfa_intx(&bfad->bfa);
1154a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (!rc) {
1155a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1156a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		return IRQ_NONE;
1157a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
1158a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1159a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_comp_deq(&bfad->bfa, &doneq);
1160a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1161a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1162a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (!list_empty(&doneq)) {
1163a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_comp_process(&bfad->bfa, &doneq);
1164a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1165a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		spin_lock_irqsave(&bfad->bfad_lock, flags);
1166a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_comp_free(&bfad->bfa, &doneq);
1167a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1168a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
1169a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1170a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	return IRQ_HANDLED;
1171a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1172a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati}
1173a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1174a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic irqreturn_t
1175a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_msix(int irq, void *dev_id)
1176a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati{
1177a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfad_msix_s *vec = dev_id;
1178a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfad_s *bfad = vec->bfad;
1179a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct list_head doneq;
1180a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	unsigned long   flags;
1181a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1182a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
1183a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1184a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_msix(&bfad->bfa, vec->msix.entry);
1185a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_comp_deq(&bfad->bfa, &doneq);
1186a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1187a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1188a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (!list_empty(&doneq)) {
1189a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_comp_process(&bfad->bfa, &doneq);
1190a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1191a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		spin_lock_irqsave(&bfad->bfad_lock, flags);
1192a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_comp_free(&bfad->bfa, &doneq);
1193a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1194a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
1195a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1196a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	return IRQ_HANDLED;
1197a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati}
1198a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
11995fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
1200a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati * Initialize the MSIX entry table.
1201a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati */
1202a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void
1203a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_init_msix_entry(struct bfad_s *bfad, struct msix_entry *msix_entries,
1204a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			 int mask, int max_bit)
1205a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati{
1206a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int	i;
1207a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int	match = 0x00000001;
1208a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1209a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	for (i = 0, bfad->nvec = 0; i < MAX_MSIX_ENTRY; i++) {
1210a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (mask & match) {
1211a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad->msix_tab[bfad->nvec].msix.entry = i;
1212a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad->msix_tab[bfad->nvec].bfad = bfad;
1213a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			msix_entries[bfad->nvec].entry = i;
1214a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad->nvec++;
1215a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
1216a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1217a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		match <<= 1;
1218a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
1219a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1220a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati}
1221a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1222a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiint
1223a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_install_msix_handler(struct bfad_s *bfad)
1224a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati{
1225a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int i, error = 0;
1226a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1227a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	for (i = 0; i < bfad->nvec; i++) {
1228a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		sprintf(bfad->msix_tab[i].name, "bfa-%s-%s",
1229a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				bfad->pci_name,
1230111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati				((bfa_asic_id_cb(bfad->hal_pcidev.device_id)) ?
1231111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati				msix_name_cb[i] : msix_name_ct[i]));
1232a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1233a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		error = request_irq(bfad->msix_tab[i].msix.vector,
1234a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				    (irq_handler_t) bfad_msix, 0,
1235a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				    bfad->msix_tab[i].name, &bfad->msix_tab[i]);
1236a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_trc(bfad, i);
1237a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_trc(bfad, bfad->msix_tab[i].msix.vector);
1238a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (error) {
1239a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			int	j;
1240a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1241a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			for (j = 0; j < i; j++)
1242a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				free_irq(bfad->msix_tab[j].msix.vector,
1243a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati						&bfad->msix_tab[j]);
1244a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
124561e62e21afe469854e04546ea10b7a6f4cfd1142Krishna Gudipati			bfad->bfad_flags &= ~BFAD_MSIX_ON;
124661e62e21afe469854e04546ea10b7a6f4cfd1142Krishna Gudipati			pci_disable_msix(bfad->pcidev);
124761e62e21afe469854e04546ea10b7a6f4cfd1142Krishna 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;
126510a07379247078448c076690657a076076bf89aaKrishna Gudipati	u16	reg;
1266a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1267a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* Call BFA to get the msix map for this PCI function.  */
1268a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_msix_getvecs(&bfad->bfa, &mask, &num_bit, &max_bit);
1269a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1270a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* Set up the msix entry table */
1271a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfad_init_msix_entry(bfad, msix_entries, mask, max_bit);
1272a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1273111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati	if ((bfa_asic_id_ctc(pdev->device) && !msix_disable_ct) ||
1274111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati	   (bfa_asic_id_cb(pdev->device) && !msix_disable_cb)) {
1275a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1276a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		error = pci_enable_msix(bfad->pcidev, msix_entries, bfad->nvec);
1277a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		if (error) {
1278a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			/*
1279a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			 * Only error number of vector is available.
1280a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			 * We don't have a mechanism to map multiple
1281a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			 * interrupts into one vector, so even if we
1282a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			 * can try to request less vectors, we don't
1283a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			 * know how to associate interrupt events to
128425985edcedea6396277003854657b5f3cb31a628Lucas De Marchi			 *  vectors. Linux doesn't duplicate vectors
1285a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			 * in the MSIX table for this case.
1286a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			 */
1287a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1288a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			printk(KERN_WARNING "bfad%d: "
1289a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				"pci_enable_msix failed (%d),"
1290a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati				" use line based.\n", bfad->inst_no, error);
1291a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1292a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			goto line_based;
1293a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
1294a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
129510a07379247078448c076690657a076076bf89aaKrishna Gudipati		/* Disable INTX in MSI-X mode */
129610a07379247078448c076690657a076076bf89aaKrishna Gudipati		pci_read_config_word(pdev, PCI_COMMAND, &reg);
129710a07379247078448c076690657a076076bf89aaKrishna Gudipati
129810a07379247078448c076690657a076076bf89aaKrishna Gudipati		if (!(reg & PCI_COMMAND_INTX_DISABLE))
129910a07379247078448c076690657a076076bf89aaKrishna Gudipati			pci_write_config_word(pdev, PCI_COMMAND,
130010a07379247078448c076690657a076076bf89aaKrishna Gudipati				reg | PCI_COMMAND_INTX_DISABLE);
130110a07379247078448c076690657a076076bf89aaKrishna Gudipati
1302a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		/* Save the vectors */
1303a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		for (i = 0; i < bfad->nvec; i++) {
1304a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfa_trc(bfad, msix_entries[i].vector);
1305a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			bfad->msix_tab[i].msix.vector = msix_entries[i].vector;
1306a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		}
1307a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1308a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfa_msix_init(&bfad->bfa, bfad->nvec);
1309a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1310a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad->bfad_flags |= BFAD_MSIX_ON;
1311a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1312a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		return error;
1313a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
1314a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1315a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiline_based:
1316a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	error = 0;
1317a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (request_irq
1318a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	    (bfad->pcidev->irq, (irq_handler_t) bfad_intx, BFAD_IRQ_FLAGS,
1319a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	     BFAD_DRIVER_NAME, bfad) != 0) {
1320a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		/* Enable interrupt handler failed */
1321a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		return 1;
1322a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
132361e62e21afe469854e04546ea10b7a6f4cfd1142Krishna Gudipati	bfad->bfad_flags |= BFAD_INTX_ON;
1324a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1325a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	return error;
1326a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati}
1327a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1328a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipativoid
1329a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_remove_intr(struct bfad_s *bfad)
1330a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati{
1331a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int	i;
1332a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1333a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (bfad->bfad_flags & BFAD_MSIX_ON) {
1334a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		for (i = 0; i < bfad->nvec; i++)
1335a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			free_irq(bfad->msix_tab[i].msix.vector,
1336a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati					&bfad->msix_tab[i]);
1337a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1338a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		pci_disable_msix(bfad->pcidev);
1339a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		bfad->bfad_flags &= ~BFAD_MSIX_ON;
134061e62e21afe469854e04546ea10b7a6f4cfd1142Krishna Gudipati	} else if (bfad->bfad_flags & BFAD_INTX_ON) {
1341a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		free_irq(bfad->pcidev->irq, bfad);
1342a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
1343a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati}
13447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
13455fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
13467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * PCI probe entry.
13477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
13487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangint
13497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
13507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
1351a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfad_s	*bfad;
13527826f304b1efa5ab839cf029742290f51c4fa009Krishna Gudipati	int		error = -ENODEV, retval, i;
13537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1354a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* For single port cards - only claim function 0 */
13558b070b4a022f86dd5098308e36426ce29b6b8960Krishna Gudipati	if ((pdev->device == BFA_PCI_DEVICE_ID_FC_8G1P) &&
1356a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		(PCI_FUNC(pdev->devfn) != 0))
13577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		return -ENODEV;
13587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
13597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad = kzalloc(sizeof(struct bfad_s), GFP_KERNEL);
13607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!bfad) {
13617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		error = -ENOMEM;
13627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out;
13637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
13647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
13657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->trcmod = kzalloc(sizeof(struct bfa_trc_mod_s), GFP_KERNEL);
13667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!bfad->trcmod) {
13677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING "Error alloc trace buffer!\n");
13687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		error = -ENOMEM;
13697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_alloc_trace_failure;
13707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
13717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1372a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* TRACE INIT */
13737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_trc_init(bfad->trcmod);
13747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_trc(bfad, bfad_inst);
13757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
13767826f304b1efa5ab839cf029742290f51c4fa009Krishna Gudipati	/* AEN INIT */
13777826f304b1efa5ab839cf029742290f51c4fa009Krishna Gudipati	INIT_LIST_HEAD(&bfad->free_aen_q);
13787826f304b1efa5ab839cf029742290f51c4fa009Krishna Gudipati	INIT_LIST_HEAD(&bfad->active_aen_q);
13797826f304b1efa5ab839cf029742290f51c4fa009Krishna Gudipati	for (i = 0; i < BFA_AEN_MAX_ENTRY; i++)
13807826f304b1efa5ab839cf029742290f51c4fa009Krishna Gudipati		list_add_tail(&bfad->aen_list[i].qe, &bfad->free_aen_q);
13817826f304b1efa5ab839cf029742290f51c4fa009Krishna Gudipati
13827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!(bfad_load_fwimg(pdev))) {
13837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		kfree(bfad->trcmod);
13847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_alloc_trace_failure;
13857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
13867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
13877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	retval = bfad_pci_init(pdev, bfad);
13887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (retval) {
13897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING "bfad_pci_init failure!\n");
13907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		error = retval;
13917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_pci_init_failure;
13927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
13937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
13947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mutex_lock(&bfad_mutex);
13957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->inst_no = bfad_inst++;
13967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	list_add_tail(&bfad->list_entry, &bfad_list);
13977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mutex_unlock(&bfad_mutex);
13987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1399a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* Initializing the state machine: State set to uninit */
1400a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_sm_set_state(bfad, bfad_sm_uninit);
1401a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
14027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_init(&bfad->bfad_lock);
14037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_set_drvdata(pdev, bfad);
14047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
14057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->ref_count = 0;
14067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pport.bfad = bfad;
1407a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	INIT_LIST_HEAD(&bfad->pbc_vport_list);
14085b7db7af522d9f281ff8bf540d2b5cbea2206b27Krishna Gudipati	INIT_LIST_HEAD(&bfad->vport_list);
1409e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
14107c38c05b3ef1a8a9f7e0416072a8ea2730841c91Krishna Gudipati	/* Setup the debugfs node for this bfad */
14117c38c05b3ef1a8a9f7e0416072a8ea2730841c91Krishna Gudipati	if (bfa_debugfs_enable)
14127c38c05b3ef1a8a9f7e0416072a8ea2730841c91Krishna Gudipati		bfad_debugfs_init(&bfad->pport);
14137c38c05b3ef1a8a9f7e0416072a8ea2730841c91Krishna Gudipati
14147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	retval = bfad_drv_init(bfad);
14157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (retval != BFA_STATUS_OK)
14167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_drv_init_failure;
14177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1418a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_sm_send_event(bfad, BFAD_E_CREATE);
14197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1420a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (bfa_sm_cmp_state(bfad, bfad_sm_uninit))
1421a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		goto out_bfad_sm_failure;
14227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
14237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return 0;
14247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1425a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatiout_bfad_sm_failure:
1426a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_detach(&bfad->bfa);
1427a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfad_hal_mem_release(bfad);
14287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_drv_init_failure:
14297c38c05b3ef1a8a9f7e0416072a8ea2730841c91Krishna Gudipati	/* Remove the debugfs node for this bfad */
14307c38c05b3ef1a8a9f7e0416072a8ea2730841c91Krishna Gudipati	kfree(bfad->regdata);
14317c38c05b3ef1a8a9f7e0416072a8ea2730841c91Krishna Gudipati	bfad_debugfs_exit(&bfad->pport);
14327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mutex_lock(&bfad_mutex);
14337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_inst--;
14347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	list_del(&bfad->list_entry);
14357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mutex_unlock(&bfad_mutex);
14367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_pci_uninit(pdev, bfad);
14377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_pci_init_failure:
14387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	kfree(bfad->trcmod);
14397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_alloc_trace_failure:
14407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	kfree(bfad);
14417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout:
14427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return error;
14437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
14447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
14455fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
14467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * PCI remove entry.
14477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
14487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
14497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_pci_remove(struct pci_dev *pdev)
14507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
1451a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	struct bfad_s	      *bfad = pci_get_drvdata(pdev);
1452a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	unsigned long	flags;
14537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
14547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_trc(bfad, bfad->inst_no);
14557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1456e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
1457a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (bfad->bfad_tsk != NULL) {
14587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1459a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		kthread_stop(bfad->bfad_tsk);
1460a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	} else {
1461e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1462e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	}
14637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1464a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* Send Event BFAD_E_STOP */
1465a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfa_sm_send_event(bfad, BFAD_E_STOP);
1466e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1467a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* Driver detach and dealloc mem */
14687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
14697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_detach(&bfad->bfa);
14707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
14717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_hal_mem_release(bfad);
14727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
14737c38c05b3ef1a8a9f7e0416072a8ea2730841c91Krishna Gudipati	/* Remove the debugfs node for this bfad */
14747c38c05b3ef1a8a9f7e0416072a8ea2730841c91Krishna Gudipati	kfree(bfad->regdata);
14757c38c05b3ef1a8a9f7e0416072a8ea2730841c91Krishna Gudipati	bfad_debugfs_exit(&bfad->pport);
14767c38c05b3ef1a8a9f7e0416072a8ea2730841c91Krishna Gudipati
1477a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	/* Cleaning the BFAD instance */
14787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mutex_lock(&bfad_mutex);
14797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_inst--;
14807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	list_del(&bfad->list_entry);
14817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mutex_unlock(&bfad_mutex);
14827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_pci_uninit(pdev, bfad);
14837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
14847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	kfree(bfad->trcmod);
14857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	kfree(bfad);
14867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
14877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1488a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistruct pci_device_id bfad_id_table[] = {
14897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	{
1490a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.vendor = BFA_PCI_VENDOR_ID_BROCADE,
1491a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.device = BFA_PCI_DEVICE_ID_FC_8G2P,
1492a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.subvendor = PCI_ANY_ID,
1493a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.subdevice = PCI_ANY_ID,
1494a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	},
14957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	{
1496a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.vendor = BFA_PCI_VENDOR_ID_BROCADE,
1497a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.device = BFA_PCI_DEVICE_ID_FC_8G1P,
1498a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.subvendor = PCI_ANY_ID,
1499a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.subdevice = PCI_ANY_ID,
1500a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	},
15017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	{
1502a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.vendor = BFA_PCI_VENDOR_ID_BROCADE,
1503a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.device = BFA_PCI_DEVICE_ID_CT,
1504a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.subvendor = PCI_ANY_ID,
1505a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.subdevice = PCI_ANY_ID,
1506a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.class = (PCI_CLASS_SERIAL_FIBER << 8),
1507a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.class_mask = ~0,
1508a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	},
1509293f82d59ed8b6d61d242e40ee7a6a146fae5eaaJing Huang	{
1510a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.vendor = BFA_PCI_VENDOR_ID_BROCADE,
1511a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.device = BFA_PCI_DEVICE_ID_CT_FC,
1512a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.subvendor = PCI_ANY_ID,
1513a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.subdevice = PCI_ANY_ID,
1514a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.class = (PCI_CLASS_SERIAL_FIBER << 8),
1515a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		.class_mask = ~0,
1516293f82d59ed8b6d61d242e40ee7a6a146fae5eaaJing Huang	},
1517111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati	{
1518111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati		.vendor = BFA_PCI_VENDOR_ID_BROCADE,
1519111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati		.device = BFA_PCI_DEVICE_ID_CT2,
1520111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati		.subvendor = PCI_ANY_ID,
1521111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati		.subdevice = PCI_ANY_ID,
1522111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati		.class = (PCI_CLASS_SERIAL_FIBER << 8),
1523111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati		.class_mask = ~0,
1524111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati	},
15257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
15267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	{0, 0},
15277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang};
15287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
15297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_DEVICE_TABLE(pci, bfad_id_table);
15307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
15317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic struct pci_driver bfad_pci_driver = {
15327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	.name = BFAD_DRIVER_NAME,
15337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	.id_table = bfad_id_table,
15347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	.probe = bfad_pci_probe,
15357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	.remove = __devexit_p(bfad_pci_remove),
15367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang};
15377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
15385fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
15397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Driver module init.
15407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
1541a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic int __init
15427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_init(void)
15437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
1544a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	int		error = 0;
15457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
15467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	printk(KERN_INFO "Brocade BFA FC/FCOE SCSI driver - version: %s\n",
1547a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			BFAD_DRIVER_VERSION);
15487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
15497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_sgpgs > 0)
15507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		num_sgpgs_parm = num_sgpgs;
15517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1552a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	error = bfad_im_module_init();
15537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (error) {
15547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		error = -ENOMEM;
1555a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		printk(KERN_WARNING "bfad_im_module_init failure\n");
15567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
15577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
15587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1559a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (strcmp(FCPI_NAME, " fcpim") == 0)
1560a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		supported_fc4s |= BFA_LPORT_ROLE_FCP_IM;
15617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1562f7f73812e95077c19a2801bbf4f483fcdab5232fMaggie Zhang	bfa_auto_recover = ioc_auto_recover;
15637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_rport_set_del_timeout(rport_del_timeout);
15647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1565a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	error = pci_register_driver(&bfad_pci_driver);
15667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (error) {
1567a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		printk(KERN_WARNING "pci_register_driver failure\n");
15687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
15697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
15707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
15717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return 0;
15727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
15737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext:
1574a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfad_im_module_exit();
15757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return error;
15767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
15777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
15785fbe25c7a664601666895e8f95eaa59bd9741392Jing Huang/*
15797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Driver module exit.
15807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
1581a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatistatic void __exit
15827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_exit(void)
15837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
15847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_unregister_driver(&bfad_pci_driver);
1585a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	bfad_im_module_exit();
15867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_free_fwimg();
15877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
15887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1589a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati/* Firmware handling */
159061338a0b3493fddfca2980ece4423839748fcbabJing Huangstatic void
1591a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipatibfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image,
1592a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		u32 *bfi_image_size, char *fw_name)
1593a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati{
1594a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	const struct firmware *fw;
1595a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1596a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (request_firmware(&fw, fw_name, &pdev->dev)) {
1597a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		printk(KERN_ALERT "Can't locate firmware %s\n", fw_name);
159861338a0b3493fddfca2980ece4423839748fcbabJing Huang		*bfi_image = NULL;
159961338a0b3493fddfca2980ece4423839748fcbabJing Huang		goto out;
1600a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
1601a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1602a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	*bfi_image = vmalloc(fw->size);
1603a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	if (NULL == *bfi_image) {
1604a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati		printk(KERN_ALERT "Fail to allocate buffer for fw image "
1605a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati			"size=%x!\n", (u32) fw->size);
160661338a0b3493fddfca2980ece4423839748fcbabJing Huang		goto out;
1607a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
1608a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
1609a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	memcpy(*bfi_image, fw->data, fw->size);
1610a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	*bfi_image_size = fw->size/sizeof(u32);
161161338a0b3493fddfca2980ece4423839748fcbabJing Huangout:
161261338a0b3493fddfca2980ece4423839748fcbabJing Huang	release_firmware(fw);
1613a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati}
1614a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati
161561338a0b3493fddfca2980ece4423839748fcbabJing Huangstatic u32 *
161661338a0b3493fddfca2980ece4423839748fcbabJing Huangbfad_load_fwimg(struct pci_dev *pdev)
1617a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati{
1618111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati	if (pdev->device == BFA_PCI_DEVICE_ID_CT2) {
1619111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati		if (bfi_image_ct2_size == 0)
1620111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati			bfad_read_firmware(pdev, &bfi_image_ct2,
1621111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati				&bfi_image_ct2_size, BFAD_FW_FILE_CT2);
1622111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati		return bfi_image_ct2;
1623111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati	} else if (bfa_asic_id_ct(pdev->device)) {
1624111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati		if (bfi_image_ct_size == 0)
1625111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati			bfad_read_firmware(pdev, &bfi_image_ct,
1626111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati				&bfi_image_ct_size, BFAD_FW_FILE_CT);
1627111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati		return bfi_image_ct;
1628a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	} else {
1629111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati		if (bfi_image_cb_size == 0)
1630111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati			bfad_read_firmware(pdev, &bfi_image_cb,
1631111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati				&bfi_image_cb_size, BFAD_FW_FILE_CB);
1632111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati		return bfi_image_cb;
1633a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati	}
1634a36c61f9025b8924f99f54d518763bee7aa84085Krishna Gudipati}
16357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
163661338a0b3493fddfca2980ece4423839748fcbabJing Huangstatic void
163761338a0b3493fddfca2980ece4423839748fcbabJing Huangbfad_free_fwimg(void)
163861338a0b3493fddfca2980ece4423839748fcbabJing Huang{
1639111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati	if (bfi_image_ct2_size && bfi_image_ct2)
1640111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati		vfree(bfi_image_ct2);
1641111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati	if (bfi_image_ct_size && bfi_image_ct)
1642111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati		vfree(bfi_image_ct);
1643111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati	if (bfi_image_cb_size && bfi_image_cb)
1644111892082ed7a3214bc7a7ec6b8b20e8f847501aKrishna Gudipati		vfree(bfi_image_cb);
164561338a0b3493fddfca2980ece4423839748fcbabJing Huang}
164661338a0b3493fddfca2980ece4423839748fcbabJing Huang
16477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_init(bfad_init);
16487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_exit(bfad_exit);
16497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_LICENSE("GPL");
16507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_DESCRIPTION("Brocade Fibre Channel HBA Driver" BFAD_PROTO_NAME);
16517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_AUTHOR("Brocade Communications Systems, Inc.");
16527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_VERSION(BFAD_DRIVER_VERSION);
1653