bfad.c revision 293f82d59ed8b6d61d242e40ee7a6a146fae5eaa
17725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/*
27725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Copyright (c) 2005-2009 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
187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/**
197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang *  bfad.c Linux driver PCI interface module.
207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
225a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include <linux/module.h>
24e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati#include <linux/kthread.h>
257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include "bfad_drv.h"
267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include "bfad_im.h"
277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include "bfad_tm.h"
287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include "bfad_ipfc.h"
297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include "bfad_trcmod.h"
307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include <fcb/bfa_fcb_vf.h>
317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include <fcb/bfa_fcb_rport.h>
327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include <fcb/bfa_fcb_port.h>
337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include <fcb/bfa_fcb.h>
347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangBFA_TRC_FILE(LDRV, BFAD);
3642b426ecb453cf49c3d16cf1d7a5e5d8cab9869dJing HuangDEFINE_MUTEX(bfad_mutex);
377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangLIST_HEAD(bfad_list);
387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      bfad_inst;
397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangint bfad_supported_fc4s;
407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic char     *host_name;
427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic char     *os_name;
437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic char     *os_patch;
447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      num_rports;
457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      num_ios;
467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      num_tms;
477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      num_fcxps;
487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      num_ufbufs;
497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      reqq_size;
507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      rspq_size;
517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      num_sgpgs;
527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT;
537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      bfa_io_max_sge = BFAD_IO_MAX_SGE;
547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      log_level = BFA_LOG_WARNING;
557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      ioc_auto_recover = BFA_TRUE;
567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      ipfc_enable = BFA_FALSE;
577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      ipfc_mtu = -1;
585b098082e22c168b7df4c5c3cd924047cee7d995Krishna Gudipatistatic int	fdmi_enable = BFA_TRUE;
597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangint 		bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH;
607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangint      	bfa_linkup_delay = -1;
617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(os_name, charp, S_IRUGO | S_IWUSR);
637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(os_patch, charp, S_IRUGO | S_IWUSR);
647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(host_name, charp, S_IRUGO | S_IWUSR);
657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_rports, int, S_IRUGO | S_IWUSR);
667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_ios, int, S_IRUGO | S_IWUSR);
677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_tms, int, S_IRUGO | S_IWUSR);
687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_fcxps, int, S_IRUGO | S_IWUSR);
697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_ufbufs, int, S_IRUGO | S_IWUSR);
707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(reqq_size, int, S_IRUGO | S_IWUSR);
717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(rspq_size, int, S_IRUGO | S_IWUSR);
727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_sgpgs, int, S_IRUGO | S_IWUSR);
737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(rport_del_timeout, int, S_IRUGO | S_IWUSR);
747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(bfa_lun_queue_depth, int, S_IRUGO | S_IWUSR);
757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(bfa_io_max_sge, int, S_IRUGO | S_IWUSR);
767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(log_level, int, S_IRUGO | S_IWUSR);
777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR);
787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(ipfc_enable, int, S_IRUGO | S_IWUSR);
797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(ipfc_mtu, int, S_IRUGO | S_IWUSR);
805b098082e22c168b7df4c5c3cd924047cee7d995Krishna Gudipatimodule_param(fdmi_enable, int, S_IRUGO | S_IWUSR);
817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(bfa_linkup_delay, int, S_IRUGO | S_IWUSR);
827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/*
847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Stores the module parm num_sgpgs value;
857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * used to reset for bfad next instance.
867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int num_sgpgs_parm;
887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic bfa_status_t
907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_fc4_probe(struct bfad_s *bfad)
917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             rc;
937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	rc = bfad_im_probe(bfad);
957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (rc != BFA_STATUS_OK)
967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_tm_probe(bfad);
997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (ipfc_enable)
1017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_ipfc_probe(bfad);
102e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
103e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad->bfad_flags |= BFAD_FC4_PROBE_DONE;
1047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext:
1057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
1067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
1077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic void
1097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_fc4_probe_undo(struct bfad_s *bfad)
1107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
1117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_im_probe_undo(bfad);
1127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_tm_probe_undo(bfad);
1137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (ipfc_enable)
1147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_ipfc_probe_undo(bfad);
115e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad->bfad_flags &= ~BFAD_FC4_PROBE_DONE;
1167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
1177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic void
1197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_fc4_probe_post(struct bfad_s *bfad)
1207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
1217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (bfad->im)
1227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_im_probe_post(bfad->im);
1237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_tm_probe_post(bfad);
1257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (ipfc_enable)
1267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_ipfc_probe_post(bfad);
1277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
1287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic bfa_status_t
1307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_fc4_port_new(struct bfad_s *bfad, struct bfad_port_s *port, int roles)
1317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
1327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             rc = BFA_STATUS_FAILED;
1337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (roles & BFA_PORT_ROLE_FCP_IM)
1357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		rc = bfad_im_port_new(bfad, port);
1367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (rc != BFA_STATUS_OK)
1377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
1387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (roles & BFA_PORT_ROLE_FCP_TM)
1407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		rc = bfad_tm_port_new(bfad, port);
1417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (rc != BFA_STATUS_OK)
1427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
1437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
1457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		rc = bfad_ipfc_port_new(bfad, port, port->pvb_type);
1467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext:
1477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
1487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
1497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic void
1517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_fc4_port_delete(struct bfad_s *bfad, struct bfad_port_s *port, int roles)
1527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
1537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (roles & BFA_PORT_ROLE_FCP_IM)
1547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_im_port_delete(bfad, port);
1557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (roles & BFA_PORT_ROLE_FCP_TM)
1577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_tm_port_delete(bfad, port);
1587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
1607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_ipfc_port_delete(bfad, port);
1617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
1627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/**
1647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang *  BFA callbacks
1657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
1667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
1677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_hcb_comp(void *arg, bfa_status_t status)
1687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
1697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfad_hal_comp *fcomp = (struct bfad_hal_comp *)arg;
1707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	fcomp->status = status;
1727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	complete(&fcomp->comp);
1737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
1747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/**
1767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * bfa_init callback
1777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
1787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
1797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_cb_init(void *drv, bfa_status_t init_status)
1807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
1817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfad_s  *bfad = drv;
1827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
183e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	if (init_status == BFA_STATUS_OK) {
1847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad->bfad_flags |= BFAD_HAL_INIT_DONE;
1857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
186e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		/* If BFAD_HAL_INIT_FAIL flag is set:
187e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		 * Wake up the kernel thread to start
188e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		 * the bfad operations after HAL init done
189e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		 */
190e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		if ((bfad->bfad_flags & BFAD_HAL_INIT_FAIL)) {
191e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati			bfad->bfad_flags &= ~BFAD_HAL_INIT_FAIL;
192e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati			wake_up_process(bfad->bfad_tsk);
193e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		}
194e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	}
195e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	complete(&bfad->comp);
1977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
1987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/**
2027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang *  BFA_FCS callbacks
2037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
2047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic struct bfad_port_s *
2057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_get_drv_port(struct bfad_s *bfad, struct bfad_vf_s *vf_drv,
2067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		  struct bfad_vport_s *vp_drv)
2077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
208f8ceafde6f5bf6b4b7087c7f5e9da1b2a5284a2eJing Huang	return (vp_drv) ? (&(vp_drv)->drv_port)
209f8ceafde6f5bf6b4b7087c7f5e9da1b2a5284a2eJing Huang		: ((vf_drv) ? (&(vf_drv)->base_port) : (&(bfad)->pport));
2107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
2117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstruct bfad_port_s *
2137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_fcb_port_new(struct bfad_s *bfad, struct bfa_fcs_port_s *port,
2147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		 enum bfa_port_role roles, struct bfad_vf_s *vf_drv,
2157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		 struct bfad_vport_s *vp_drv)
2167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
2177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_status_t    rc;
2187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfad_port_s *port_drv;
2197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!vp_drv && !vf_drv) {
2217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv = &bfad->pport;
2227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv->pvb_type = BFAD_PORT_PHYS_BASE;
2237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	} else if (!vp_drv && vf_drv) {
2247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv = &vf_drv->base_port;
2257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv->pvb_type = BFAD_PORT_VF_BASE;
2267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	} else if (vp_drv && !vf_drv) {
2277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv = &vp_drv->drv_port;
2287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv->pvb_type = BFAD_PORT_PHYS_VPORT;
2297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	} else {
2307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv = &vp_drv->drv_port;
2317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv->pvb_type = BFAD_PORT_VF_VPORT;
2327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
2337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	port_drv->fcs_port = port;
2357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	port_drv->roles = roles;
2367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	rc = bfad_fc4_port_new(bfad, port_drv, roles);
2377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (rc != BFA_STATUS_OK) {
2387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_fc4_port_delete(bfad, port_drv, roles);
2397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv = NULL;
2407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
2417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return port_drv;
2437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
2447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
2467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_fcb_port_delete(struct bfad_s *bfad, enum bfa_port_role roles,
2477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		    struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
2487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
2497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfad_port_s *port_drv;
2507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	/*
2527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 * this will be only called from rmmod context
2537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 */
2547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (vp_drv && !vp_drv->comp_del) {
2557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv);
2567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_trc(bfad, roles);
2577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_fc4_port_delete(bfad, port_drv, roles);
2587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
2597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
2607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
2627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_fcb_port_online(struct bfad_s *bfad, enum bfa_port_role roles,
2637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		    struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
2647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
2657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfad_port_s *port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv);
2667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (roles & BFA_PORT_ROLE_FCP_IM)
2687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_im_port_online(bfad, port_drv);
2697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (roles & BFA_PORT_ROLE_FCP_TM)
2717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_tm_port_online(bfad, port_drv);
2727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
2747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_ipfc_port_online(bfad, port_drv);
2757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->bfad_flags |= BFAD_PORT_ONLINE;
2777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
2787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
2807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_fcb_port_offline(struct bfad_s *bfad, enum bfa_port_role roles,
2817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		     struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
2827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
2837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfad_port_s *port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv);
2847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (roles & BFA_PORT_ROLE_FCP_IM)
2867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_im_port_offline(bfad, port_drv);
2877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (roles & BFA_PORT_ROLE_FCP_TM)
2897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_tm_port_offline(bfad, port_drv);
2907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
2927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_ipfc_port_offline(bfad, port_drv);
2937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
2947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
2967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_fcb_vport_delete(struct bfad_vport_s *vport_drv)
2977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
2987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (vport_drv->comp_del) {
2997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		complete(vport_drv->comp_del);
3007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		return;
3017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
3027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
3037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/**
3057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * FCS RPORT alloc callback, after successful PLOGI by FCS
3067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
3077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t
3087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_fcb_rport_alloc(struct bfad_s *bfad, struct bfa_fcs_rport_s **rport,
3097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		    struct bfad_rport_s **rport_drv)
3107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
3117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_status_t    rc = BFA_STATUS_OK;
3127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	*rport_drv = kzalloc(sizeof(struct bfad_rport_s), GFP_ATOMIC);
3147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (*rport_drv == NULL) {
3157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		rc = BFA_STATUS_ENOMEM;
3167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
3177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
3187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	*rport = &(*rport_drv)->fcs_rport;
3207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext:
3227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
3237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
3247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
3287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_hal_mem_release(struct bfad_s *bfad)
3297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
3307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             i;
3317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfa_meminfo_s *hal_meminfo = &bfad->meminfo;
3327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfa_mem_elem_s *meminfo_elem;
3337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	for (i = 0; i < BFA_MEM_TYPE_MAX; i++) {
3357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		meminfo_elem = &hal_meminfo->meminfo[i];
3367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		if (meminfo_elem->kva != NULL) {
3377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			switch (meminfo_elem->mem_type) {
3387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			case BFA_MEM_TYPE_KVA:
3397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				vfree(meminfo_elem->kva);
3407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				break;
3417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			case BFA_MEM_TYPE_DMA:
3427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				dma_free_coherent(&bfad->pcidev->dev,
3437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						meminfo_elem->mem_len,
3447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						meminfo_elem->kva,
3457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						(dma_addr_t) meminfo_elem->dma);
3467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				break;
3477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			default:
3487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				bfa_assert(0);
3497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				break;
3507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			}
3517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		}
3527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
3537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	memset(hal_meminfo, 0, sizeof(struct bfa_meminfo_s));
3557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
3567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
3587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_update_hal_cfg(struct bfa_iocfc_cfg_s *bfa_cfg)
3597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
3607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_rports > 0)
3617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->fwcfg.num_rports = num_rports;
3627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_ios > 0)
3637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->fwcfg.num_ioim_reqs = num_ios;
3647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_tms > 0)
3657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->fwcfg.num_tskim_reqs = num_tms;
3667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_fcxps > 0)
3677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->fwcfg.num_fcxp_reqs = num_fcxps;
3687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_ufbufs > 0)
3697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->fwcfg.num_uf_bufs = num_ufbufs;
3707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (reqq_size > 0)
3717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->drvcfg.num_reqq_elems = reqq_size;
3727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (rspq_size > 0)
3737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->drvcfg.num_rspq_elems = rspq_size;
3747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_sgpgs > 0)
3757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->drvcfg.num_sgpgs = num_sgpgs;
3767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	/*
3787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 * populate the hal values back to the driver for sysfs use.
3797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 * otherwise, the default values will be shown as 0 in sysfs
3807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 */
3817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	num_rports = bfa_cfg->fwcfg.num_rports;
3827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	num_ios    = bfa_cfg->fwcfg.num_ioim_reqs;
3837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	num_tms	   = bfa_cfg->fwcfg.num_tskim_reqs;
3847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	num_fcxps  = bfa_cfg->fwcfg.num_fcxp_reqs;
3857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	num_ufbufs = bfa_cfg->fwcfg.num_uf_bufs;
3867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	reqq_size  = bfa_cfg->drvcfg.num_reqq_elems;
3877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	rspq_size  = bfa_cfg->drvcfg.num_rspq_elems;
3887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	num_sgpgs  = bfa_cfg->drvcfg.num_sgpgs;
3897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
3907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t
3927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_hal_mem_alloc(struct bfad_s *bfad)
3937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
3947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfa_meminfo_s *hal_meminfo = &bfad->meminfo;
3957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfa_mem_elem_s *meminfo_elem;
3967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_status_t    rc = BFA_STATUS_OK;
3977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	dma_addr_t      phys_addr;
3987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             retry_count = 0;
3997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             reset_value = 1;
4007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             min_num_sgpgs = 512;
4017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	void           *kva;
4027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             i;
4037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_cfg_get_default(&bfad->ioc_cfg);
4057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangretry:
4077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_update_hal_cfg(&bfad->ioc_cfg);
4087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->cfg_data.ioc_queue_depth = bfad->ioc_cfg.fwcfg.num_ioim_reqs;
4097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_cfg_get_meminfo(&bfad->ioc_cfg, hal_meminfo);
4107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	for (i = 0; i < BFA_MEM_TYPE_MAX; i++) {
4127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		meminfo_elem = &hal_meminfo->meminfo[i];
4137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		switch (meminfo_elem->mem_type) {
4147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		case BFA_MEM_TYPE_KVA:
4157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			kva = vmalloc(meminfo_elem->mem_len);
4167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			if (kva == NULL) {
4177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				bfad_hal_mem_release(bfad);
4187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				rc = BFA_STATUS_ENOMEM;
4197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				goto ext;
4207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			}
4217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			memset(kva, 0, meminfo_elem->mem_len);
4227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			meminfo_elem->kva = kva;
4237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			break;
4247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		case BFA_MEM_TYPE_DMA:
4257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			kva = dma_alloc_coherent(&bfad->pcidev->dev,
4267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					meminfo_elem->mem_len,
4277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					&phys_addr, GFP_KERNEL);
4287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			if (kva == NULL) {
4297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				bfad_hal_mem_release(bfad);
4307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				/*
4317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				 * If we cannot allocate with default
4327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				 * num_sgpages try with half the value.
4337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				 */
4347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				if (num_sgpgs > min_num_sgpgs) {
4357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					printk(KERN_INFO "bfad[%d]: memory"
4367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						" allocation failed with"
4377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						" num_sgpgs: %d\n",
4387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						bfad->inst_no, num_sgpgs);
4397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					nextLowerInt(&num_sgpgs);
4407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					printk(KERN_INFO "bfad[%d]: trying to"
4417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						" allocate memory with"
4427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						" num_sgpgs: %d\n",
4437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						bfad->inst_no, num_sgpgs);
4447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					retry_count++;
4457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					goto retry;
4467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				} else {
4477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					if (num_sgpgs_parm > 0)
4487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						num_sgpgs = num_sgpgs_parm;
4497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					else {
4507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						reset_value =
4517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang							(1 << retry_count);
4527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						num_sgpgs *= reset_value;
4537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					}
4547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					rc = BFA_STATUS_ENOMEM;
4557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					goto ext;
4567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				}
4577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			}
4587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			if (num_sgpgs_parm > 0)
4607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				num_sgpgs = num_sgpgs_parm;
4617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			else {
4627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				reset_value = (1 << retry_count);
4637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				num_sgpgs *= reset_value;
4647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			}
4657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			memset(kva, 0, meminfo_elem->mem_len);
4677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			meminfo_elem->kva = kva;
4687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			meminfo_elem->dma = phys_addr;
4697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			break;
4707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		default:
4717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			break;
4727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		}
4747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
4757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext:
4767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
4777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
4787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/**
4807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Create a vport under a vf.
4817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
4827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t
4837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_vport_create(struct bfad_s *bfad, u16 vf_id,
484b504293fe9dc42917a919044f2b672fb361329d0Jing Huang		  struct bfa_port_cfg_s *port_cfg, struct device *dev)
4857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
4867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfad_vport_s *vport;
4877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             rc = BFA_STATUS_OK;
4887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	unsigned long   flags;
4897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct completion fcomp;
4907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	vport = kzalloc(sizeof(struct bfad_vport_s), GFP_KERNEL);
4927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!vport) {
4937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		rc = BFA_STATUS_ENOMEM;
4947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
4957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
4967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	vport->drv_port.bfad = bfad;
4987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
4997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	rc = bfa_fcs_vport_create(&vport->fcs_vport, &bfad->bfa_fcs, vf_id,
5007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				  port_cfg, vport);
5017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
5027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (rc != BFA_STATUS_OK)
5047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext_free_vport;
5057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (port_cfg->roles & BFA_PORT_ROLE_FCP_IM) {
507b504293fe9dc42917a919044f2b672fb361329d0Jing Huang		rc = bfad_im_scsi_host_alloc(bfad, vport->drv_port.im_port,
508b504293fe9dc42917a919044f2b672fb361329d0Jing Huang							dev);
5097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		if (rc != BFA_STATUS_OK)
5107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			goto ext_free_fcs_vport;
5117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
5127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
5147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_vport_start(&vport->fcs_vport);
5157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
5167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return BFA_STATUS_OK;
5187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext_free_fcs_vport:
5207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
5217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	vport->comp_del = &fcomp;
5227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	init_completion(vport->comp_del);
5237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_vport_delete(&vport->fcs_vport);
5247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
5257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	wait_for_completion(vport->comp_del);
5267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext_free_vport:
5277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	kfree(vport);
5287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext:
5297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
5307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
5317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/**
5337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Create a vf and its base vport implicitely.
5347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
5357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t
5367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_vf_create(struct bfad_s *bfad, u16 vf_id,
5377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	       struct bfa_port_cfg_s *port_cfg)
5387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
5397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfad_vf_s *vf;
5407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             rc = BFA_STATUS_OK;
5417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	vf = kzalloc(sizeof(struct bfad_vf_s), GFP_KERNEL);
5437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!vf) {
5447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		rc = BFA_STATUS_FAILED;
5457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
5467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
5477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	rc = bfa_fcs_vf_create(&vf->fcs_vf, &bfad->bfa_fcs, vf_id, port_cfg,
5497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			       vf);
5507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (rc != BFA_STATUS_OK)
5517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		kfree(vf);
5527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext:
5537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
5547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
5557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
5577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_bfa_tmo(unsigned long data)
5587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
5597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfad_s  *bfad = (struct bfad_s *)data;
5607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	unsigned long   flags;
5617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct list_head  doneq;
5627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
5647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_timer_tick(&bfad->bfa);
5667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_comp_deq(&bfad->bfa, &doneq);
5687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
5697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!list_empty(&doneq)) {
5717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_comp_process(&bfad->bfa, &doneq);
5727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		spin_lock_irqsave(&bfad->bfad_lock, flags);
5737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_comp_free(&bfad->bfa, &doneq);
5747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
5757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
5767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mod_timer(&bfad->hal_tmo, jiffies + msecs_to_jiffies(BFA_TIMER_FREQ));
5787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
5797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
5817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_init_timer(struct bfad_s *bfad)
5827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
5837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	init_timer(&bfad->hal_tmo);
5847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->hal_tmo.function = bfad_bfa_tmo;
5857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->hal_tmo.data = (unsigned long)bfad;
5867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mod_timer(&bfad->hal_tmo, jiffies + msecs_to_jiffies(BFA_TIMER_FREQ));
5887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
5897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangint
5917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_pci_init(struct pci_dev *pdev, struct bfad_s *bfad)
5927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
5937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             rc = -ENODEV;
5947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (pci_enable_device(pdev)) {
5967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		BFA_PRINTF(BFA_ERR, "pci_enable_device fail %p\n", pdev);
5977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out;
5987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
5997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (pci_request_regions(pdev, BFAD_DRIVER_NAME))
6017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_disable_device;
6027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_set_master(pdev);
6047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0)
6077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) {
6087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			BFA_PRINTF(BFA_ERR, "pci_set_dma_mask fail %p\n", pdev);
6097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			goto out_release_region;
6107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		}
6117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
612b3522f08ec7011aed0abc477bfedd00d189e9cd6Jing Huang	bfad->pci_bar0_kva = pci_iomap(pdev, 0, pci_resource_len(pdev, 0));
6137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (bfad->pci_bar0_kva == NULL) {
6157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		BFA_PRINTF(BFA_ERR, "Fail to map bar0\n");
6167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_release_region;
6177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
6187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->hal_pcidev.pci_slot = PCI_SLOT(pdev->devfn);
6207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->hal_pcidev.pci_func = PCI_FUNC(pdev->devfn);
6217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->hal_pcidev.pci_bar_kva = bfad->pci_bar0_kva;
6227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->hal_pcidev.device_id = pdev->device;
6237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_name = pci_name(pdev);
6247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_attr.vendor_id = pdev->vendor;
6267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_attr.device_id = pdev->device;
6277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_attr.ssid = pdev->subsystem_device;
6287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_attr.ssvid = pdev->subsystem_vendor;
6297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_attr.pcifn = PCI_FUNC(pdev->devfn);
6307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pcidev = pdev;
6327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return 0;
6337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_release_region:
6357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_release_regions(pdev);
6367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_disable_device:
6377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_disable_device(pdev);
6387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout:
6397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
6407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
6417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
6437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_pci_uninit(struct pci_dev *pdev, struct bfad_s *bfad)
6447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
6457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_iounmap(pdev, bfad->pci_bar0_kva);
6467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_release_regions(pdev);
6477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_disable_device(pdev);
6487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_set_drvdata(pdev, NULL);
6497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
6507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
6527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_fcs_port_cfg(struct bfad_s *bfad)
6537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
6547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfa_port_cfg_s port_cfg;
6557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfa_pport_attr_s attr;
6567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	char            symname[BFA_SYMNAME_MAXLEN];
6577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	sprintf(symname, "%s-%d", BFAD_DRIVER_NAME, bfad->inst_no);
6597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	memcpy(port_cfg.sym_name.symname, symname, strlen(symname));
6601c8a4c37494932acd59079b4fc8d8f69fb329c2aKrishna Gudipati	bfa_fcport_get_attr(&bfad->bfa, &attr);
6617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	port_cfg.nwwn = attr.nwwn;
6627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	port_cfg.pwwn = attr.pwwn;
6637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_cfg_base_port(&bfad->bfa_fcs, &port_cfg);
6657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
6667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t
6687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_drv_init(struct bfad_s *bfad)
6697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
6707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_status_t    rc;
6717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	unsigned long   flags;
6727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfa_fcs_driver_info_s driver_info;
6737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->cfg_data.rport_del_timeout = rport_del_timeout;
6757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->cfg_data.lun_queue_depth = bfa_lun_queue_depth;
6767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->cfg_data.io_max_sge = bfa_io_max_sge;
6777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->cfg_data.binding_method = FCP_PWWN_BINDING;
6787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	rc = bfad_hal_mem_alloc(bfad);
6807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (rc != BFA_STATUS_OK) {
6817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING "bfad%d bfad_hal_mem_alloc failure\n",
6827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		       bfad->inst_no);
6837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING
6847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			"Not enough memory to attach all Brocade HBA ports,"
6857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			" System may need more memory.\n");
6867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_hal_mem_alloc_failure;
6877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
6887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_init_log(&bfad->bfa, bfad->logmod);
6907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_init_trc(&bfad->bfa, bfad->trcmod);
6917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_init_aen(&bfad->bfa, bfad->aen);
6922993cc71d1bff61999ade7f2b6b3ea2dd1e2c8d9Krishna Gudipati	memset(bfad->file_map, 0, sizeof(bfad->file_map));
6937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_init_plog(&bfad->bfa, &bfad->plog_buf);
6947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_plog_init(&bfad->plog_buf);
6957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_plog_str(&bfad->plog_buf, BFA_PL_MID_DRVR, BFA_PL_EID_DRIVER_START,
6967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		     0, "Driver Attach");
6977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_attach(&bfad->bfa, bfad, &bfad->ioc_cfg, &bfad->meminfo,
6997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		   &bfad->hal_pcidev);
7007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	init_completion(&bfad->comp);
7027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	/*
7047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 * Enable Interrupt and wait bfa_init completion
7057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 */
7067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (bfad_setup_intr(bfad)) {
7077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING "bfad%d: bfad_setup_intr failed\n",
7087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		       bfad->inst_no);
7097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_setup_intr_failure;
7107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
7117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
7137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_init(&bfad->bfa);
7147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
7157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	/*
7177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 * Set up interrupt handler for each vectors
7187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 */
7197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if ((bfad->bfad_flags & BFAD_MSIX_ON)
7207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	    && bfad_install_msix_handler(bfad)) {
7217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING "%s: install_msix failed, bfad%d\n",
722f8ceafde6f5bf6b4b7087c7f5e9da1b2a5284a2eJing Huang		       __func__, bfad->inst_no);
7237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
7247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_init_timer(bfad);
7267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	wait_for_completion(&bfad->comp);
7287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	memset(&driver_info, 0, sizeof(driver_info));
7307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	strncpy(driver_info.version, BFAD_DRIVER_VERSION,
7317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		sizeof(driver_info.version) - 1);
7327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (host_name)
7337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		strncpy(driver_info.host_machine_name, host_name,
7347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			sizeof(driver_info.host_machine_name) - 1);
7357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (os_name)
7367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		strncpy(driver_info.host_os_name, os_name,
7377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			sizeof(driver_info.host_os_name) - 1);
7387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (os_patch)
7397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		strncpy(driver_info.host_os_patch, os_patch,
7407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			sizeof(driver_info.host_os_patch) - 1);
7417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	strncpy(driver_info.os_device_name, bfad->pci_name,
7437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		sizeof(driver_info.os_device_name - 1));
7447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	/*
7467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 * FCS INIT
7477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 */
7487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
7497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_log_init(&bfad->bfa_fcs, bfad->logmod);
7507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_trc_init(&bfad->bfa_fcs, bfad->trcmod);
7517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_aen_init(&bfad->bfa_fcs, bfad->aen);
75282794a2e4153657d12a0c29272e40b47eaadb748Krishna Gudipati	bfa_fcs_attach(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE);
753e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
754e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	/* Do FCS init only when HAL init is done */
755e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	if ((bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
756e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfa_fcs_init(&bfad->bfa_fcs);
757e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfad->bfad_flags |= BFAD_FCS_INIT_DONE;
758e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	}
759e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
7607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_driver_info_init(&bfad->bfa_fcs, &driver_info);
7615b098082e22c168b7df4c5c3cd924047cee7d995Krishna Gudipati	bfa_fcs_set_fdmi_param(&bfad->bfa_fcs, fdmi_enable);
7627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
7637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->bfad_flags |= BFAD_DRV_INIT_DONE;
7657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return BFA_STATUS_OK;
7667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_setup_intr_failure:
7687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_detach(&bfad->bfa);
7697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_hal_mem_release(bfad);
7707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_hal_mem_alloc_failure:
7717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return BFA_STATUS_FAILED;
7727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
7737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
7757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_drv_uninit(struct bfad_s *bfad)
7767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
777e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	unsigned long   flags;
778e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
779e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
780e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	init_completion(&bfad->comp);
781e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfa_stop(&bfad->bfa);
782e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
783e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	wait_for_completion(&bfad->comp);
784e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
7857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	del_timer_sync(&bfad->hal_tmo);
7867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_isr_disable(&bfad->bfa);
7877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_detach(&bfad->bfa);
7887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_remove_intr(bfad);
7897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_hal_mem_release(bfad);
790e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
791e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad->bfad_flags &= ~BFAD_DRV_INIT_DONE;
7927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
7937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
7957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_drv_start(struct bfad_s *bfad)
7967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
7977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	unsigned long   flags;
7987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
8007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_start(&bfad->bfa);
8017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_start(&bfad->bfa_fcs);
8027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->bfad_flags |= BFAD_HAL_START_DONE;
8037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
8047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_fc4_probe_post(bfad);
8067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
8077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
8097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_drv_stop(struct bfad_s *bfad)
8107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
8117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	unsigned long   flags;
8127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
8147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	init_completion(&bfad->comp);
8157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pport.flags |= BFAD_PORT_DELETE;
8167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_exit(&bfad->bfa_fcs);
8177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
8187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	wait_for_completion(&bfad->comp);
8197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
8217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	init_completion(&bfad->comp);
8227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_stop(&bfad->bfa);
8237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->bfad_flags &= ~BFAD_HAL_START_DONE;
8247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
8257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	wait_for_completion(&bfad->comp);
8267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
8277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t
8297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_cfg_pport(struct bfad_s *bfad, enum bfa_port_role role)
8307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
8317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             rc = BFA_STATUS_OK;
8327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	/*
8347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 * Allocate scsi_host for the physical port
8357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 */
8367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if ((bfad_supported_fc4s & BFA_PORT_ROLE_FCP_IM)
8377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	    && (role & BFA_PORT_ROLE_FCP_IM)) {
8387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		if (bfad->pport.im_port == NULL) {
8397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			rc = BFA_STATUS_FAILED;
8407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			goto out;
8417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		}
8427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
843b504293fe9dc42917a919044f2b672fb361329d0Jing Huang		rc = bfad_im_scsi_host_alloc(bfad, bfad->pport.im_port,
844b504293fe9dc42917a919044f2b672fb361329d0Jing Huang						&bfad->pcidev->dev);
8457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		if (rc != BFA_STATUS_OK)
8467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			goto out;
8477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad->pport.roles |= BFA_PORT_ROLE_FCP_IM;
8497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
8507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->bfad_flags |= BFAD_CFG_PPORT_DONE;
8527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout:
8547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
8557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
8567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
8587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_uncfg_pport(struct bfad_s *bfad)
8597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
8607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if ((bfad->pport.roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable) {
8617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_ipfc_port_delete(bfad, &bfad->pport);
8627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad->pport.roles &= ~BFA_PORT_ROLE_FCP_IPFC;
8637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
8647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if ((bfad_supported_fc4s & BFA_PORT_ROLE_FCP_IM)
8667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	    && (bfad->pport.roles & BFA_PORT_ROLE_FCP_IM)) {
8677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_im_scsi_host_free(bfad, bfad->pport.im_port);
8687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_im_port_clean(bfad->pport.im_port);
8697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		kfree(bfad->pport.im_port);
8707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad->pport.roles &= ~BFA_PORT_ROLE_FCP_IM;
8717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
8727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->bfad_flags &= ~BFAD_CFG_PPORT_DONE;
8747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
8757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
8777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_drv_log_level_set(struct bfad_s *bfad)
8787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
8797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (log_level > BFA_LOG_INVALID && log_level <= BFA_LOG_LEVEL_MAX)
8807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_log_set_level_all(&bfad->log_data, log_level);
8817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
8827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
883e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatibfa_status_t
884e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatibfad_start_ops(struct bfad_s *bfad)
885e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati{
886e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	int retval;
887e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
888e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	/* PPORT FCS config */
889e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad_fcs_port_cfg(bfad);
890e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
891e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM);
892e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	if (retval != BFA_STATUS_OK)
893e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		goto out_cfg_pport_failure;
894e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
895e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	/* BFAD level FC4 (IM/TM/IPFC) specific resource allocation */
896e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	retval = bfad_fc4_probe(bfad);
897e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	if (retval != BFA_STATUS_OK) {
898e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		printk(KERN_WARNING "bfad_fc4_probe failed\n");
899e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		goto out_fc4_probe_failure;
900e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	}
901e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
902e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad_drv_start(bfad);
903e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
904e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	/*
905e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	 * If bfa_linkup_delay is set to -1 default; try to retrive the
906e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	 * value using the bfad_os_get_linkup_delay(); else use the
907e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	 * passed in module param value as the bfa_linkup_delay.
908e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	 */
909e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	if (bfa_linkup_delay < 0) {
910e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
911e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfa_linkup_delay = bfad_os_get_linkup_delay(bfad);
912e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfad_os_rport_online_wait(bfad);
913e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfa_linkup_delay = -1;
914e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
915e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	} else {
916e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfad_os_rport_online_wait(bfad);
917e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	}
918e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
919e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name);
920e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
921e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	return BFA_STATUS_OK;
922e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
923e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatiout_fc4_probe_failure:
924e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad_fc4_probe_undo(bfad);
925e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad_uncfg_pport(bfad);
926e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatiout_cfg_pport_failure:
927e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	return BFA_STATUS_FAILED;
928e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati}
929e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
930e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatiint
931e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatibfad_worker (void *ptr)
932e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati{
933e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	struct bfad_s *bfad;
934e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	unsigned long   flags;
935e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
936e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad = (struct bfad_s *)ptr;
937e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
938e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	while (!kthread_should_stop()) {
939e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
940e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		/* Check if the FCS init is done from bfad_drv_init;
941e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		 * if not done do FCS init and set the flag.
942e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		 */
943e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		if (!(bfad->bfad_flags & BFAD_FCS_INIT_DONE)) {
944e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati			spin_lock_irqsave(&bfad->bfad_lock, flags);
945e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati			bfa_fcs_init(&bfad->bfa_fcs);
946e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati			bfad->bfad_flags |= BFAD_FCS_INIT_DONE;
947e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati			spin_unlock_irqrestore(&bfad->bfad_lock, flags);
948e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		}
949e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
950e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		/* Start the bfad operations after HAL init done */
951e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfad_start_ops(bfad);
952e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
953e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		spin_lock_irqsave(&bfad->bfad_lock, flags);
954e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfad->bfad_tsk = NULL;
955e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
956e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
957e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		break;
958e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	}
959e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
960e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	return 0;
961e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati}
962e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
9637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang /*
9647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang  *  PCI_entry PCI driver entries * {
9657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang  */
9667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
9677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/**
9687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * PCI probe entry.
9697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
9707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangint
9717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
9727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
9737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfad_s  *bfad;
9747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             error = -ENODEV, retval;
9757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
9767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	/*
9777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 * For single port cards - only claim function 0
9787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 */
9797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if ((pdev->device == BFA_PCI_DEVICE_ID_FC_8G1P)
9807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	    && (PCI_FUNC(pdev->devfn) != 0))
9817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		return -ENODEV;
9827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
9837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	BFA_TRACE(BFA_INFO, "bfad_pci_probe entry");
9847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
9857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad = kzalloc(sizeof(struct bfad_s), GFP_KERNEL);
9867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!bfad) {
9877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		error = -ENOMEM;
9887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out;
9897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
9907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
9917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->trcmod = kzalloc(sizeof(struct bfa_trc_mod_s), GFP_KERNEL);
9927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!bfad->trcmod) {
9937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING "Error alloc trace buffer!\n");
9947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		error = -ENOMEM;
9957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_alloc_trace_failure;
9967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
9977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
9987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	/*
9997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 * LOG/TRACE INIT
10007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 */
10017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_trc_init(bfad->trcmod);
10027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_trc(bfad, bfad_inst);
10037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->logmod = &bfad->log_data;
10050a4b1fc0b24fc7adbaf8413f2992ce1395991a78Krishna Gudipati	bfa_log_init(bfad->logmod, (char *)pci_name(pdev), bfa_os_printf);
10067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_drv_log_level_set(bfad);
10087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->aen = &bfad->aen_buf;
10107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!(bfad_load_fwimg(pdev))) {
10127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING "bfad_load_fwimg failure!\n");
10137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		kfree(bfad->trcmod);
10147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_alloc_trace_failure;
10157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
10167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	retval = bfad_pci_init(pdev, bfad);
10187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (retval) {
10197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING "bfad_pci_init failure!\n");
10207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		error = retval;
10217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_pci_init_failure;
10227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
10237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mutex_lock(&bfad_mutex);
10257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->inst_no = bfad_inst++;
10267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	list_add_tail(&bfad->list_entry, &bfad_list);
10277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mutex_unlock(&bfad_mutex);
10287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_init(&bfad->bfad_lock);
10307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_set_drvdata(pdev, bfad);
10317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->ref_count = 0;
10337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pport.bfad = bfad;
10347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1035e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad->bfad_tsk = kthread_create(bfad_worker, (void *) bfad, "%s",
1036e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati					"bfad_worker");
1037e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	if (IS_ERR(bfad->bfad_tsk)) {
1038e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		printk(KERN_INFO "bfad[%d]: Kernel thread"
1039e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati			" creation failed!\n",
1040e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati			bfad->inst_no);
1041e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		goto out_kthread_create_failure;
1042e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	}
1043e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
10447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	retval = bfad_drv_init(bfad);
10457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (retval != BFA_STATUS_OK)
10467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_drv_init_failure;
10477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
1048e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfad->bfad_flags |= BFAD_HAL_INIT_FAIL;
10497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING "bfad%d: hal init failed\n", bfad->inst_no);
10507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ok;
10517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
10527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1053e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	retval = bfad_start_ops(bfad);
10547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (retval != BFA_STATUS_OK)
1055e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		goto out_start_ops_failure;
10567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1057e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	kthread_stop(bfad->bfad_tsk);
1058e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad->bfad_tsk = NULL;
10597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangok:
10617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return 0;
10627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1063e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatiout_start_ops_failure:
10647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_drv_uninit(bfad);
10657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_drv_init_failure:
1066e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	kthread_stop(bfad->bfad_tsk);
1067e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatiout_kthread_create_failure:
10687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mutex_lock(&bfad_mutex);
10697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_inst--;
10707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	list_del(&bfad->list_entry);
10717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mutex_unlock(&bfad_mutex);
10727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_pci_uninit(pdev, bfad);
10737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_pci_init_failure:
10747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	kfree(bfad->trcmod);
10757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_alloc_trace_failure:
10767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	kfree(bfad);
10777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout:
10787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return error;
10797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
10807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/**
10827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * PCI remove entry.
10837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
10847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
10857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_pci_remove(struct pci_dev *pdev)
10867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
10877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfad_s  *bfad = pci_get_drvdata(pdev);
10887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	unsigned long   flags;
10897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_trc(bfad, bfad->inst_no);
10917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1092e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
1093e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	if (bfad->bfad_tsk != NULL)
1094e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		kthread_stop(bfad->bfad_tsk);
1095e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1096e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
10977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if ((bfad->bfad_flags & BFAD_DRV_INIT_DONE)
10987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	    && !(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
10997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		spin_lock_irqsave(&bfad->bfad_lock, flags);
11017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		init_completion(&bfad->comp);
11027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_stop(&bfad->bfa);
11037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
11047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		wait_for_completion(&bfad->comp);
11057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_remove_intr(bfad);
11077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		del_timer_sync(&bfad->hal_tmo);
11087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto hal_detach;
11097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	} else if (!(bfad->bfad_flags & BFAD_DRV_INIT_DONE)) {
11107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto remove_sysfs;
11117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
11127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1113e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	if (bfad->bfad_flags & BFAD_HAL_START_DONE) {
11147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_drv_stop(bfad);
1115e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	} else if (bfad->bfad_flags & BFAD_DRV_INIT_DONE) {
1116e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		/* Invoking bfa_stop() before bfa_detach
1117e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		 * when HAL and DRV init are success
1118e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		 * but HAL start did not occur.
1119e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		 */
1120e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		spin_lock_irqsave(&bfad->bfad_lock, flags);
1121e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		init_completion(&bfad->comp);
1122e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfa_stop(&bfad->bfa);
1123e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1124e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		wait_for_completion(&bfad->comp);
1125e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	}
11267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_remove_intr(bfad);
11287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	del_timer_sync(&bfad->hal_tmo);
1129e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1130e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	if (bfad->bfad_flags & BFAD_FC4_PROBE_DONE)
1131e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfad_fc4_probe_undo(bfad);
11327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (bfad->bfad_flags & BFAD_CFG_PPORT_DONE)
11347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_uncfg_pport(bfad);
11357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huanghal_detach:
11377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
11387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_detach(&bfad->bfa);
11397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
11407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_hal_mem_release(bfad);
11417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangremove_sysfs:
11427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mutex_lock(&bfad_mutex);
11447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_inst--;
11457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	list_del(&bfad->list_entry);
11467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mutex_unlock(&bfad_mutex);
11477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_pci_uninit(pdev, bfad);
11487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	kfree(bfad->trcmod);
11507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	kfree(bfad);
11517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
11527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic struct pci_device_id bfad_id_table[] = {
11557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	{
11567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .vendor = BFA_PCI_VENDOR_ID_BROCADE,
11577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .device = BFA_PCI_DEVICE_ID_FC_8G2P,
11587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .subvendor = PCI_ANY_ID,
11597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .subdevice = PCI_ANY_ID,
11607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 },
11617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	{
11627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .vendor = BFA_PCI_VENDOR_ID_BROCADE,
11637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .device = BFA_PCI_DEVICE_ID_FC_8G1P,
11647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .subvendor = PCI_ANY_ID,
11657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .subdevice = PCI_ANY_ID,
11667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 },
11677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	{
11687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .vendor = BFA_PCI_VENDOR_ID_BROCADE,
11697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .device = BFA_PCI_DEVICE_ID_CT,
11707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .subvendor = PCI_ANY_ID,
11717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .subdevice = PCI_ANY_ID,
11727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .class = (PCI_CLASS_SERIAL_FIBER << 8),
11737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .class_mask = ~0,
11747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 },
1175293f82d59ed8b6d61d242e40ee7a6a146fae5eaaJing Huang	{
1176293f82d59ed8b6d61d242e40ee7a6a146fae5eaaJing Huang	 .vendor = BFA_PCI_VENDOR_ID_BROCADE,
1177293f82d59ed8b6d61d242e40ee7a6a146fae5eaaJing Huang	 .device = BFA_PCI_DEVICE_ID_CT_FC,
1178293f82d59ed8b6d61d242e40ee7a6a146fae5eaaJing Huang	 .subvendor = PCI_ANY_ID,
1179293f82d59ed8b6d61d242e40ee7a6a146fae5eaaJing Huang	 .subdevice = PCI_ANY_ID,
1180293f82d59ed8b6d61d242e40ee7a6a146fae5eaaJing Huang	 .class = (PCI_CLASS_SERIAL_FIBER << 8),
1181293f82d59ed8b6d61d242e40ee7a6a146fae5eaaJing Huang	 .class_mask = ~0,
1182293f82d59ed8b6d61d242e40ee7a6a146fae5eaaJing Huang	},
11837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	{0, 0},
11857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang};
11867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_DEVICE_TABLE(pci, bfad_id_table);
11887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic struct pci_driver bfad_pci_driver = {
11907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	.name = BFAD_DRIVER_NAME,
11917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	.id_table = bfad_id_table,
11927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	.probe = bfad_pci_probe,
11937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	.remove = __devexit_p(bfad_pci_remove),
11947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang};
11957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/**
11977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang *  Linux driver module functions
11987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
11997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t
12007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_fc4_module_init(void)
12017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
12027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             rc;
12037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	rc = bfad_im_module_init();
12057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (rc != BFA_STATUS_OK)
12067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
12077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_tm_module_init();
12097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (ipfc_enable)
12107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_ipfc_module_init();
12117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext:
12127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
12137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
12147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
12167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_fc4_module_exit(void)
12177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
12187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (ipfc_enable)
12197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_ipfc_module_exit();
12207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_tm_module_exit();
12217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_im_module_exit();
12227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
12237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/**
12257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Driver module init.
12267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
12277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      __init
12287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_init(void)
12297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
12307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             error = 0;
12317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	printk(KERN_INFO "Brocade BFA FC/FCOE SCSI driver - version: %s\n",
12337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	       BFAD_DRIVER_VERSION);
12347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_sgpgs > 0)
12367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		num_sgpgs_parm = num_sgpgs;
12377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	error = bfad_fc4_module_init();
12397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (error) {
12407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		error = -ENOMEM;
12417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING "bfad_fc4_module_init failure\n");
12427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
12437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
12447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!strcmp(FCPI_NAME, " fcpim"))
12467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_IM;
12477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!strcmp(FCPT_NAME, " fcptm"))
12487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_TM;
12497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!strcmp(IPFC_NAME, " ipfc"))
12507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_IPFC;
12517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_ioc_auto_recover(ioc_auto_recover);
12537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_rport_set_del_timeout(rport_del_timeout);
12547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	error = pci_register_driver(&bfad_pci_driver);
12557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (error) {
12577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING "bfad pci_register_driver failure\n");
12587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
12597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
12607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return 0;
12627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext:
12647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_fc4_module_exit();
12657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return error;
12667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
12677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/**
12697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Driver module exit.
12707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
12717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic void     __exit
12727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_exit(void)
12737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
12747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_unregister_driver(&bfad_pci_driver);
12757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_fc4_module_exit();
12767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_free_fwimg();
12777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
12787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#define BFAD_PROTO_NAME FCPI_NAME FCPT_NAME IPFC_NAME
12807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_init(bfad_init);
12827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_exit(bfad_exit);
12837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_LICENSE("GPL");
12847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_DESCRIPTION("Brocade Fibre Channel HBA Driver" BFAD_PROTO_NAME);
12857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_AUTHOR("Brocade Communications Systems, Inc.");
12867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_VERSION(BFAD_DRIVER_VERSION);
12877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1289