bfad.c revision e67143243a1a6b47e1bdcda189ffac46d2a8744d
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
227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include <linux/module.h>
23e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati#include <linux/kthread.h>
247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include "bfad_drv.h"
257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include "bfad_im.h"
267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include "bfad_tm.h"
277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include "bfad_ipfc.h"
287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include "bfad_trcmod.h"
297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include <fcb/bfa_fcb_vf.h>
307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include <fcb/bfa_fcb_rport.h>
317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include <fcb/bfa_fcb_port.h>
327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include <fcb/bfa_fcb.h>
337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangBFA_TRC_FILE(LDRV, BFAD);
357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic DEFINE_MUTEX(bfad_mutex);
367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangLIST_HEAD(bfad_list);
377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      bfad_inst;
387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangint bfad_supported_fc4s;
397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic char     *host_name;
417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic char     *os_name;
427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic char     *os_patch;
437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      num_rports;
447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      num_ios;
457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      num_tms;
467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      num_fcxps;
477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      num_ufbufs;
487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      reqq_size;
497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      rspq_size;
507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      num_sgpgs;
517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT;
527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      bfa_io_max_sge = BFAD_IO_MAX_SGE;
537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      log_level = BFA_LOG_WARNING;
547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      ioc_auto_recover = BFA_TRUE;
557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      ipfc_enable = BFA_FALSE;
567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      ipfc_mtu = -1;
575b098082e22c168b7df4c5c3cd924047cee7d995Krishna Gudipatistatic int	fdmi_enable = BFA_TRUE;
587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangint 		bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH;
597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangint      	bfa_linkup_delay = -1;
607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(os_name, charp, S_IRUGO | S_IWUSR);
627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(os_patch, charp, S_IRUGO | S_IWUSR);
637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(host_name, charp, S_IRUGO | S_IWUSR);
647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_rports, int, S_IRUGO | S_IWUSR);
657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_ios, int, S_IRUGO | S_IWUSR);
667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_tms, int, S_IRUGO | S_IWUSR);
677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_fcxps, int, S_IRUGO | S_IWUSR);
687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_ufbufs, int, S_IRUGO | S_IWUSR);
697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(reqq_size, int, S_IRUGO | S_IWUSR);
707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(rspq_size, int, S_IRUGO | S_IWUSR);
717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_sgpgs, int, S_IRUGO | S_IWUSR);
727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(rport_del_timeout, int, S_IRUGO | S_IWUSR);
737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(bfa_lun_queue_depth, int, S_IRUGO | S_IWUSR);
747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(bfa_io_max_sge, int, S_IRUGO | S_IWUSR);
757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(log_level, int, S_IRUGO | S_IWUSR);
767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR);
777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(ipfc_enable, int, S_IRUGO | S_IWUSR);
787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(ipfc_mtu, int, S_IRUGO | S_IWUSR);
795b098082e22c168b7df4c5c3cd924047cee7d995Krishna Gudipatimodule_param(fdmi_enable, int, S_IRUGO | S_IWUSR);
807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(bfa_linkup_delay, int, S_IRUGO | S_IWUSR);
817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/*
837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Stores the module parm num_sgpgs value;
847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * used to reset for bfad next instance.
857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int num_sgpgs_parm;
877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic bfa_status_t
897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_fc4_probe(struct bfad_s *bfad)
907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             rc;
927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	rc = bfad_im_probe(bfad);
947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (rc != BFA_STATUS_OK)
957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_tm_probe(bfad);
987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (ipfc_enable)
1007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_ipfc_probe(bfad);
101e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
102e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad->bfad_flags |= BFAD_FC4_PROBE_DONE;
1037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext:
1047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
1057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
1067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic void
1087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_fc4_probe_undo(struct bfad_s *bfad)
1097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
1107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_im_probe_undo(bfad);
1117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_tm_probe_undo(bfad);
1127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (ipfc_enable)
1137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_ipfc_probe_undo(bfad);
114e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad->bfad_flags &= ~BFAD_FC4_PROBE_DONE;
1157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
1167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic void
1187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_fc4_probe_post(struct bfad_s *bfad)
1197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
1207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (bfad->im)
1217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_im_probe_post(bfad->im);
1227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_tm_probe_post(bfad);
1247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (ipfc_enable)
1257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_ipfc_probe_post(bfad);
1267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
1277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic bfa_status_t
1297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_fc4_port_new(struct bfad_s *bfad, struct bfad_port_s *port, int roles)
1307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
1317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             rc = BFA_STATUS_FAILED;
1327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (roles & BFA_PORT_ROLE_FCP_IM)
1347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		rc = bfad_im_port_new(bfad, port);
1357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (rc != BFA_STATUS_OK)
1367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
1377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (roles & BFA_PORT_ROLE_FCP_TM)
1397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		rc = bfad_tm_port_new(bfad, port);
1407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (rc != BFA_STATUS_OK)
1417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
1427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
1447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		rc = bfad_ipfc_port_new(bfad, port, port->pvb_type);
1457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext:
1467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
1477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
1487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic void
1507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_fc4_port_delete(struct bfad_s *bfad, struct bfad_port_s *port, int roles)
1517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
1527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (roles & BFA_PORT_ROLE_FCP_IM)
1537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_im_port_delete(bfad, port);
1547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (roles & BFA_PORT_ROLE_FCP_TM)
1567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_tm_port_delete(bfad, port);
1577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
1597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_ipfc_port_delete(bfad, port);
1607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
1617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/**
1637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang *  BFA callbacks
1647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
1657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
1667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_hcb_comp(void *arg, bfa_status_t status)
1677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
1687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfad_hal_comp *fcomp = (struct bfad_hal_comp *)arg;
1697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	fcomp->status = status;
1717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	complete(&fcomp->comp);
1727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
1737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/**
1757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * bfa_init callback
1767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
1777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
1787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_cb_init(void *drv, bfa_status_t init_status)
1797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
1807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfad_s  *bfad = drv;
1817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
182e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	if (init_status == BFA_STATUS_OK) {
1837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad->bfad_flags |= BFAD_HAL_INIT_DONE;
1847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
185e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		/* If BFAD_HAL_INIT_FAIL flag is set:
186e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		 * Wake up the kernel thread to start
187e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		 * the bfad operations after HAL init done
188e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		 */
189e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		if ((bfad->bfad_flags & BFAD_HAL_INIT_FAIL)) {
190e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati			bfad->bfad_flags &= ~BFAD_HAL_INIT_FAIL;
191e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati			wake_up_process(bfad->bfad_tsk);
192e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		}
193e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	}
194e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	complete(&bfad->comp);
1967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
1977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/**
2017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang *  BFA_FCS callbacks
2027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
2037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic struct bfad_port_s *
2047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_get_drv_port(struct bfad_s *bfad, struct bfad_vf_s *vf_drv,
2057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		  struct bfad_vport_s *vp_drv)
2067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
207f8ceafde6f5bf6b4b7087c7f5e9da1b2a5284a2eJing Huang	return (vp_drv) ? (&(vp_drv)->drv_port)
208f8ceafde6f5bf6b4b7087c7f5e9da1b2a5284a2eJing Huang		: ((vf_drv) ? (&(vf_drv)->base_port) : (&(bfad)->pport));
2097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
2107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstruct bfad_port_s *
2127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_fcb_port_new(struct bfad_s *bfad, struct bfa_fcs_port_s *port,
2137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		 enum bfa_port_role roles, struct bfad_vf_s *vf_drv,
2147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		 struct bfad_vport_s *vp_drv)
2157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
2167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_status_t    rc;
2177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfad_port_s *port_drv;
2187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!vp_drv && !vf_drv) {
2207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv = &bfad->pport;
2217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv->pvb_type = BFAD_PORT_PHYS_BASE;
2227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	} else if (!vp_drv && vf_drv) {
2237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv = &vf_drv->base_port;
2247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv->pvb_type = BFAD_PORT_VF_BASE;
2257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	} else if (vp_drv && !vf_drv) {
2267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv = &vp_drv->drv_port;
2277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv->pvb_type = BFAD_PORT_PHYS_VPORT;
2287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	} else {
2297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv = &vp_drv->drv_port;
2307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv->pvb_type = BFAD_PORT_VF_VPORT;
2317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
2327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	port_drv->fcs_port = port;
2347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	port_drv->roles = roles;
2357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	rc = bfad_fc4_port_new(bfad, port_drv, roles);
2367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (rc != BFA_STATUS_OK) {
2377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_fc4_port_delete(bfad, port_drv, roles);
2387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv = NULL;
2397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
2407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return port_drv;
2427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
2437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
2457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_fcb_port_delete(struct bfad_s *bfad, enum bfa_port_role roles,
2467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		    struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
2477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
2487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfad_port_s *port_drv;
2497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	/*
2517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 * this will be only called from rmmod context
2527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 */
2537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (vp_drv && !vp_drv->comp_del) {
2547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv);
2557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_trc(bfad, roles);
2567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_fc4_port_delete(bfad, port_drv, roles);
2577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
2587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
2597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
2617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_fcb_port_online(struct bfad_s *bfad, enum bfa_port_role roles,
2627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		    struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
2637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
2647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfad_port_s *port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv);
2657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (roles & BFA_PORT_ROLE_FCP_IM)
2677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_im_port_online(bfad, port_drv);
2687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (roles & BFA_PORT_ROLE_FCP_TM)
2707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_tm_port_online(bfad, port_drv);
2717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
2737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_ipfc_port_online(bfad, port_drv);
2747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->bfad_flags |= BFAD_PORT_ONLINE;
2767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
2777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
2797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_fcb_port_offline(struct bfad_s *bfad, enum bfa_port_role roles,
2807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		     struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
2817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
2827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfad_port_s *port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv);
2837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (roles & BFA_PORT_ROLE_FCP_IM)
2857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_im_port_offline(bfad, port_drv);
2867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (roles & BFA_PORT_ROLE_FCP_TM)
2887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_tm_port_offline(bfad, port_drv);
2897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
2917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_ipfc_port_offline(bfad, port_drv);
2927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
2937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
2947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
2957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_fcb_vport_delete(struct bfad_vport_s *vport_drv)
2967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
2977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (vport_drv->comp_del) {
2987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		complete(vport_drv->comp_del);
2997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		return;
3007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
3017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	kfree(vport_drv);
3037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
3047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/**
3067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * FCS RPORT alloc callback, after successful PLOGI by FCS
3077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
3087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t
3097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_fcb_rport_alloc(struct bfad_s *bfad, struct bfa_fcs_rport_s **rport,
3107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		    struct bfad_rport_s **rport_drv)
3117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
3127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_status_t    rc = BFA_STATUS_OK;
3137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	*rport_drv = kzalloc(sizeof(struct bfad_rport_s), GFP_ATOMIC);
3157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (*rport_drv == NULL) {
3167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		rc = BFA_STATUS_ENOMEM;
3177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
3187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
3197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	*rport = &(*rport_drv)->fcs_rport;
3217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext:
3237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
3247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
3257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
3297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_hal_mem_release(struct bfad_s *bfad)
3307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
3317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             i;
3327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfa_meminfo_s *hal_meminfo = &bfad->meminfo;
3337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfa_mem_elem_s *meminfo_elem;
3347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	for (i = 0; i < BFA_MEM_TYPE_MAX; i++) {
3367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		meminfo_elem = &hal_meminfo->meminfo[i];
3377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		if (meminfo_elem->kva != NULL) {
3387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			switch (meminfo_elem->mem_type) {
3397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			case BFA_MEM_TYPE_KVA:
3407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				vfree(meminfo_elem->kva);
3417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				break;
3427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			case BFA_MEM_TYPE_DMA:
3437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				dma_free_coherent(&bfad->pcidev->dev,
3447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						meminfo_elem->mem_len,
3457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						meminfo_elem->kva,
3467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						(dma_addr_t) meminfo_elem->dma);
3477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				break;
3487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			default:
3497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				bfa_assert(0);
3507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				break;
3517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			}
3527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		}
3537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
3547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	memset(hal_meminfo, 0, sizeof(struct bfa_meminfo_s));
3567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
3577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
3597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_update_hal_cfg(struct bfa_iocfc_cfg_s *bfa_cfg)
3607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
3617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_rports > 0)
3627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->fwcfg.num_rports = num_rports;
3637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_ios > 0)
3647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->fwcfg.num_ioim_reqs = num_ios;
3657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_tms > 0)
3667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->fwcfg.num_tskim_reqs = num_tms;
3677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_fcxps > 0)
3687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->fwcfg.num_fcxp_reqs = num_fcxps;
3697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_ufbufs > 0)
3707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->fwcfg.num_uf_bufs = num_ufbufs;
3717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (reqq_size > 0)
3727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->drvcfg.num_reqq_elems = reqq_size;
3737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (rspq_size > 0)
3747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->drvcfg.num_rspq_elems = rspq_size;
3757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_sgpgs > 0)
3767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_cfg->drvcfg.num_sgpgs = num_sgpgs;
3777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	/*
3797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 * populate the hal values back to the driver for sysfs use.
3807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 * otherwise, the default values will be shown as 0 in sysfs
3817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 */
3827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	num_rports = bfa_cfg->fwcfg.num_rports;
3837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	num_ios    = bfa_cfg->fwcfg.num_ioim_reqs;
3847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	num_tms	   = bfa_cfg->fwcfg.num_tskim_reqs;
3857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	num_fcxps  = bfa_cfg->fwcfg.num_fcxp_reqs;
3867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	num_ufbufs = bfa_cfg->fwcfg.num_uf_bufs;
3877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	reqq_size  = bfa_cfg->drvcfg.num_reqq_elems;
3887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	rspq_size  = bfa_cfg->drvcfg.num_rspq_elems;
3897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	num_sgpgs  = bfa_cfg->drvcfg.num_sgpgs;
3907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
3917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
3927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t
3937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_hal_mem_alloc(struct bfad_s *bfad)
3947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
3957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfa_meminfo_s *hal_meminfo = &bfad->meminfo;
3967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfa_mem_elem_s *meminfo_elem;
3977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_status_t    rc = BFA_STATUS_OK;
3987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	dma_addr_t      phys_addr;
3997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             retry_count = 0;
4007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             reset_value = 1;
4017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             min_num_sgpgs = 512;
4027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	void           *kva;
4037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             i;
4047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_cfg_get_default(&bfad->ioc_cfg);
4067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangretry:
4087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_update_hal_cfg(&bfad->ioc_cfg);
4097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->cfg_data.ioc_queue_depth = bfad->ioc_cfg.fwcfg.num_ioim_reqs;
4107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_cfg_get_meminfo(&bfad->ioc_cfg, hal_meminfo);
4117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	for (i = 0; i < BFA_MEM_TYPE_MAX; i++) {
4137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		meminfo_elem = &hal_meminfo->meminfo[i];
4147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		switch (meminfo_elem->mem_type) {
4157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		case BFA_MEM_TYPE_KVA:
4167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			kva = vmalloc(meminfo_elem->mem_len);
4177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			if (kva == NULL) {
4187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				bfad_hal_mem_release(bfad);
4197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				rc = BFA_STATUS_ENOMEM;
4207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				goto ext;
4217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			}
4227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			memset(kva, 0, meminfo_elem->mem_len);
4237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			meminfo_elem->kva = kva;
4247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			break;
4257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		case BFA_MEM_TYPE_DMA:
4267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			kva = dma_alloc_coherent(&bfad->pcidev->dev,
4277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					meminfo_elem->mem_len,
4287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					&phys_addr, GFP_KERNEL);
4297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			if (kva == NULL) {
4307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				bfad_hal_mem_release(bfad);
4317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				/*
4327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				 * If we cannot allocate with default
4337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				 * num_sgpages try with half the value.
4347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				 */
4357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				if (num_sgpgs > min_num_sgpgs) {
4367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					printk(KERN_INFO "bfad[%d]: memory"
4377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						" allocation failed with"
4387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						" num_sgpgs: %d\n",
4397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						bfad->inst_no, num_sgpgs);
4407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					nextLowerInt(&num_sgpgs);
4417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					printk(KERN_INFO "bfad[%d]: trying to"
4427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						" allocate memory with"
4437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						" num_sgpgs: %d\n",
4447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						bfad->inst_no, num_sgpgs);
4457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					retry_count++;
4467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					goto retry;
4477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				} else {
4487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					if (num_sgpgs_parm > 0)
4497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						num_sgpgs = num_sgpgs_parm;
4507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					else {
4517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						reset_value =
4527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang							(1 << retry_count);
4537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang						num_sgpgs *= reset_value;
4547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					}
4557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					rc = BFA_STATUS_ENOMEM;
4567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang					goto ext;
4577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				}
4587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			}
4597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			if (num_sgpgs_parm > 0)
4617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				num_sgpgs = num_sgpgs_parm;
4627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			else {
4637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				reset_value = (1 << retry_count);
4647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				num_sgpgs *= reset_value;
4657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			}
4667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			memset(kva, 0, meminfo_elem->mem_len);
4687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			meminfo_elem->kva = kva;
4697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			meminfo_elem->dma = phys_addr;
4707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			break;
4717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		default:
4727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			break;
4737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		}
4757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
4767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext:
4777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
4787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
4797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/**
4817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Create a vport under a vf.
4827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
4837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t
4847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_vport_create(struct bfad_s *bfad, u16 vf_id,
4857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		  struct bfa_port_cfg_s *port_cfg)
4867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
4877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfad_vport_s *vport;
4887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             rc = BFA_STATUS_OK;
4897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	unsigned long   flags;
4907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct completion fcomp;
4917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	vport = kzalloc(sizeof(struct bfad_vport_s), GFP_KERNEL);
4937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!vport) {
4947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		rc = BFA_STATUS_ENOMEM;
4957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
4967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
4977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
4987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	vport->drv_port.bfad = bfad;
4997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
5007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	rc = bfa_fcs_vport_create(&vport->fcs_vport, &bfad->bfa_fcs, vf_id,
5017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang				  port_cfg, vport);
5027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
5037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (rc != BFA_STATUS_OK)
5057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext_free_vport;
5067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (port_cfg->roles & BFA_PORT_ROLE_FCP_IM) {
5087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		rc = bfad_im_scsi_host_alloc(bfad, vport->drv_port.im_port);
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	unsigned long   bar0_len;
5947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             rc = -ENODEV;
5957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
5967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (pci_enable_device(pdev)) {
5977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		BFA_PRINTF(BFA_ERR, "pci_enable_device fail %p\n", pdev);
5987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out;
5997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
6007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (pci_request_regions(pdev, BFAD_DRIVER_NAME))
6027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_disable_device;
6037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_set_master(pdev);
6057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0)
6087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) {
6097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			BFA_PRINTF(BFA_ERR, "pci_set_dma_mask fail %p\n", pdev);
6107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			goto out_release_region;
6117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		}
6127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_bar0_map = pci_resource_start(pdev, 0);
6147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bar0_len = pci_resource_len(pdev, 0);
6157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_bar0_kva = ioremap(bfad->pci_bar0_map, bar0_len);
6167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (bfad->pci_bar0_kva == NULL) {
6187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		BFA_PRINTF(BFA_ERR, "Fail to map bar0\n");
6197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_release_region;
6207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
6217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->hal_pcidev.pci_slot = PCI_SLOT(pdev->devfn);
6237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->hal_pcidev.pci_func = PCI_FUNC(pdev->devfn);
6247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->hal_pcidev.pci_bar_kva = bfad->pci_bar0_kva;
6257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->hal_pcidev.device_id = pdev->device;
6267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_name = pci_name(pdev);
6277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_attr.vendor_id = pdev->vendor;
6297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_attr.device_id = pdev->device;
6307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_attr.ssid = pdev->subsystem_device;
6317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_attr.ssvid = pdev->subsystem_vendor;
6327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pci_attr.pcifn = PCI_FUNC(pdev->devfn);
6337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pcidev = pdev;
6357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return 0;
6367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_release_region:
6387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_release_regions(pdev);
6397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_disable_device:
6407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_disable_device(pdev);
6417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout:
6427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
6437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
6447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
6467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_pci_uninit(struct pci_dev *pdev, struct bfad_s *bfad)
6477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
6487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#if defined(__ia64__)
6497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_iounmap(pdev, bfad->pci_bar0_kva);
6507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#else
6517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	iounmap(bfad->pci_bar0_kva);
6527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#endif
6537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_release_regions(pdev);
6547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_disable_device(pdev);
6557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_set_drvdata(pdev, NULL);
6567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
6577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
6597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_fcs_port_cfg(struct bfad_s *bfad)
6607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
6617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfa_port_cfg_s port_cfg;
6627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfa_pport_attr_s attr;
6637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	char            symname[BFA_SYMNAME_MAXLEN];
6647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	sprintf(symname, "%s-%d", BFAD_DRIVER_NAME, bfad->inst_no);
6667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	memcpy(port_cfg.sym_name.symname, symname, strlen(symname));
6677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_pport_get_attr(&bfad->bfa, &attr);
6687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	port_cfg.nwwn = attr.nwwn;
6697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	port_cfg.pwwn = attr.pwwn;
6707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_cfg_base_port(&bfad->bfa_fcs, &port_cfg);
6727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
6737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t
6757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_drv_init(struct bfad_s *bfad)
6767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
6777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_status_t    rc;
6787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	unsigned long   flags;
6797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfa_fcs_driver_info_s driver_info;
6807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             i;
6817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->cfg_data.rport_del_timeout = rport_del_timeout;
6837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->cfg_data.lun_queue_depth = bfa_lun_queue_depth;
6847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->cfg_data.io_max_sge = bfa_io_max_sge;
6857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->cfg_data.binding_method = FCP_PWWN_BINDING;
6867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	rc = bfad_hal_mem_alloc(bfad);
6887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (rc != BFA_STATUS_OK) {
6897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING "bfad%d bfad_hal_mem_alloc failure\n",
6907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		       bfad->inst_no);
6917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING
6927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			"Not enough memory to attach all Brocade HBA ports,"
6937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			" System may need more memory.\n");
6947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_hal_mem_alloc_failure;
6957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
6967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
6977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_init_log(&bfad->bfa, bfad->logmod);
6987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_init_trc(&bfad->bfa, bfad->trcmod);
6997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_init_aen(&bfad->bfa, bfad->aen);
7007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	INIT_LIST_HEAD(&bfad->file_q);
7017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	INIT_LIST_HEAD(&bfad->file_free_q);
7027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	for (i = 0; i < BFAD_AEN_MAX_APPS; i++) {
7037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_q_qe_init(&bfad->file_buf[i].qe);
7047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		list_add_tail(&bfad->file_buf[i].qe, &bfad->file_free_q);
7057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
7067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_init_plog(&bfad->bfa, &bfad->plog_buf);
7077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_plog_init(&bfad->plog_buf);
7087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_plog_str(&bfad->plog_buf, BFA_PL_MID_DRVR, BFA_PL_EID_DRIVER_START,
7097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		     0, "Driver Attach");
7107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_attach(&bfad->bfa, bfad, &bfad->ioc_cfg, &bfad->meminfo,
7127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		   &bfad->hal_pcidev);
7137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	init_completion(&bfad->comp);
7157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	/*
7177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 * Enable Interrupt and wait bfa_init completion
7187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 */
7197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (bfad_setup_intr(bfad)) {
7207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING "bfad%d: bfad_setup_intr failed\n",
7217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		       bfad->inst_no);
7227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_setup_intr_failure;
7237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
7247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
7267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_init(&bfad->bfa);
7277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
7287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	/*
7307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 * Set up interrupt handler for each vectors
7317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 */
7327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if ((bfad->bfad_flags & BFAD_MSIX_ON)
7337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	    && bfad_install_msix_handler(bfad)) {
7347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING "%s: install_msix failed, bfad%d\n",
735f8ceafde6f5bf6b4b7087c7f5e9da1b2a5284a2eJing Huang		       __func__, bfad->inst_no);
7367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
7377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_init_timer(bfad);
7397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	wait_for_completion(&bfad->comp);
7417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	memset(&driver_info, 0, sizeof(driver_info));
7437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	strncpy(driver_info.version, BFAD_DRIVER_VERSION,
7447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		sizeof(driver_info.version) - 1);
7457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (host_name)
7467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		strncpy(driver_info.host_machine_name, host_name,
7477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			sizeof(driver_info.host_machine_name) - 1);
7487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (os_name)
7497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		strncpy(driver_info.host_os_name, os_name,
7507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			sizeof(driver_info.host_os_name) - 1);
7517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (os_patch)
7527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		strncpy(driver_info.host_os_patch, os_patch,
7537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			sizeof(driver_info.host_os_patch) - 1);
7547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	strncpy(driver_info.os_device_name, bfad->pci_name,
7567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		sizeof(driver_info.os_device_name - 1));
7577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	/*
7597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 * FCS INIT
7607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 */
7617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
7627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_log_init(&bfad->bfa_fcs, bfad->logmod);
7637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_trc_init(&bfad->bfa_fcs, bfad->trcmod);
7647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_aen_init(&bfad->bfa_fcs, bfad->aen);
76582794a2e4153657d12a0c29272e40b47eaadb748Krishna Gudipati	bfa_fcs_attach(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE);
766e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
767e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	/* Do FCS init only when HAL init is done */
768e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	if ((bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
769e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfa_fcs_init(&bfad->bfa_fcs);
770e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfad->bfad_flags |= BFAD_FCS_INIT_DONE;
771e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	}
772e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
7737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_driver_info_init(&bfad->bfa_fcs, &driver_info);
7745b098082e22c168b7df4c5c3cd924047cee7d995Krishna Gudipati	bfa_fcs_set_fdmi_param(&bfad->bfa_fcs, fdmi_enable);
7757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
7767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->bfad_flags |= BFAD_DRV_INIT_DONE;
7787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return BFA_STATUS_OK;
7797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_setup_intr_failure:
7817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_detach(&bfad->bfa);
7827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_hal_mem_release(bfad);
7837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_hal_mem_alloc_failure:
7847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return BFA_STATUS_FAILED;
7857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
7867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
7877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
7887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_drv_uninit(struct bfad_s *bfad)
7897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
790e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	unsigned long   flags;
791e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
792e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
793e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	init_completion(&bfad->comp);
794e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfa_stop(&bfad->bfa);
795e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
796e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	wait_for_completion(&bfad->comp);
797e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
7987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	del_timer_sync(&bfad->hal_tmo);
7997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_isr_disable(&bfad->bfa);
8007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_detach(&bfad->bfa);
8017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_remove_intr(bfad);
8027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_assert(list_empty(&bfad->file_q));
8037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_hal_mem_release(bfad);
804e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
805e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad->bfad_flags &= ~BFAD_DRV_INIT_DONE;
8067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
8077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
8097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_drv_start(struct bfad_s *bfad)
8107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
8117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	unsigned long   flags;
8127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
8147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_start(&bfad->bfa);
8157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_start(&bfad->bfa_fcs);
8167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->bfad_flags |= BFAD_HAL_START_DONE;
8177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
8187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_fc4_probe_post(bfad);
8207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
8217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
8237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_drv_stop(struct bfad_s *bfad)
8247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
8257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	unsigned long   flags;
8267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
8287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	init_completion(&bfad->comp);
8297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pport.flags |= BFAD_PORT_DELETE;
8307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_exit(&bfad->bfa_fcs);
8317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
8327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	wait_for_completion(&bfad->comp);
8337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
8357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	init_completion(&bfad->comp);
8367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_stop(&bfad->bfa);
8377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->bfad_flags &= ~BFAD_HAL_START_DONE;
8387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
8397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	wait_for_completion(&bfad->comp);
8407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
8417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t
8437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_cfg_pport(struct bfad_s *bfad, enum bfa_port_role role)
8447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
8457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             rc = BFA_STATUS_OK;
8467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	/*
8487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 * Allocate scsi_host for the physical port
8497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 */
8507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if ((bfad_supported_fc4s & BFA_PORT_ROLE_FCP_IM)
8517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	    && (role & BFA_PORT_ROLE_FCP_IM)) {
8527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		if (bfad->pport.im_port == NULL) {
8537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			rc = BFA_STATUS_FAILED;
8547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			goto out;
8557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		}
8567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		rc = bfad_im_scsi_host_alloc(bfad, bfad->pport.im_port);
8587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		if (rc != BFA_STATUS_OK)
8597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang			goto out;
8607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad->pport.roles |= BFA_PORT_ROLE_FCP_IM;
8627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
8637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->bfad_flags |= BFAD_CFG_PPORT_DONE;
8657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout:
8677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
8687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
8697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
8717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_uncfg_pport(struct bfad_s *bfad)
8727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
8737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if ((bfad->pport.roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable) {
8747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_ipfc_port_delete(bfad, &bfad->pport);
8757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad->pport.roles &= ~BFA_PORT_ROLE_FCP_IPFC;
8767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
8777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if ((bfad_supported_fc4s & BFA_PORT_ROLE_FCP_IM)
8797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	    && (bfad->pport.roles & BFA_PORT_ROLE_FCP_IM)) {
8807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_im_scsi_host_free(bfad, bfad->pport.im_port);
8817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_im_port_clean(bfad->pport.im_port);
8827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		kfree(bfad->pport.im_port);
8837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad->pport.roles &= ~BFA_PORT_ROLE_FCP_IM;
8847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
8857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->bfad_flags &= ~BFAD_CFG_PPORT_DONE;
8877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
8887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
8897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
8907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_drv_log_level_set(struct bfad_s *bfad)
8917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
8927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (log_level > BFA_LOG_INVALID && log_level <= BFA_LOG_LEVEL_MAX)
8937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_log_set_level_all(&bfad->log_data, log_level);
8947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
8957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
896e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatibfa_status_t
897e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatibfad_start_ops(struct bfad_s *bfad)
898e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati{
899e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	int retval;
900e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
901e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	/* PPORT FCS config */
902e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad_fcs_port_cfg(bfad);
903e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
904e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM);
905e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	if (retval != BFA_STATUS_OK)
906e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		goto out_cfg_pport_failure;
907e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
908e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	/* BFAD level FC4 (IM/TM/IPFC) specific resource allocation */
909e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	retval = bfad_fc4_probe(bfad);
910e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	if (retval != BFA_STATUS_OK) {
911e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		printk(KERN_WARNING "bfad_fc4_probe failed\n");
912e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		goto out_fc4_probe_failure;
913e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	}
914e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
915e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad_drv_start(bfad);
916e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
917e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	/*
918e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	 * If bfa_linkup_delay is set to -1 default; try to retrive the
919e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	 * value using the bfad_os_get_linkup_delay(); else use the
920e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	 * passed in module param value as the bfa_linkup_delay.
921e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	 */
922e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	if (bfa_linkup_delay < 0) {
923e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
924e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfa_linkup_delay = bfad_os_get_linkup_delay(bfad);
925e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfad_os_rport_online_wait(bfad);
926e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfa_linkup_delay = -1;
927e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
928e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	} else {
929e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfad_os_rport_online_wait(bfad);
930e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	}
931e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
932e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name);
933e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
934e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	return BFA_STATUS_OK;
935e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
936e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatiout_fc4_probe_failure:
937e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad_fc4_probe_undo(bfad);
938e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad_uncfg_pport(bfad);
939e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatiout_cfg_pport_failure:
940e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	return BFA_STATUS_FAILED;
941e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati}
942e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
943e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatiint
944e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatibfad_worker (void *ptr)
945e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati{
946e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	struct bfad_s *bfad;
947e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	unsigned long   flags;
948e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
949e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad = (struct bfad_s *)ptr;
950e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
951e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	while (!kthread_should_stop()) {
952e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
953e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		/* Check if the FCS init is done from bfad_drv_init;
954e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		 * if not done do FCS init and set the flag.
955e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		 */
956e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		if (!(bfad->bfad_flags & BFAD_FCS_INIT_DONE)) {
957e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati			spin_lock_irqsave(&bfad->bfad_lock, flags);
958e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati			bfa_fcs_init(&bfad->bfa_fcs);
959e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati			bfad->bfad_flags |= BFAD_FCS_INIT_DONE;
960e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati			spin_unlock_irqrestore(&bfad->bfad_lock, flags);
961e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		}
962e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
963e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		/* Start the bfad operations after HAL init done */
964e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfad_start_ops(bfad);
965e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
966e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		spin_lock_irqsave(&bfad->bfad_lock, flags);
967e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfad->bfad_tsk = NULL;
968e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
969e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
970e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		break;
971e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	}
972e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
973e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	return 0;
974e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati}
975e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
9767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang /*
9777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang  *  PCI_entry PCI driver entries * {
9787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang  */
9797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
9807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/**
9817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * PCI probe entry.
9827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
9837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangint
9847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
9857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
9867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfad_s  *bfad;
9877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             error = -ENODEV, retval;
9887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	char            buf[16];
9897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
9907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	/*
9917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 * For single port cards - only claim function 0
9927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 */
9937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if ((pdev->device == BFA_PCI_DEVICE_ID_FC_8G1P)
9947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	    && (PCI_FUNC(pdev->devfn) != 0))
9957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		return -ENODEV;
9967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
9977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	BFA_TRACE(BFA_INFO, "bfad_pci_probe entry");
9987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
9997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad = kzalloc(sizeof(struct bfad_s), GFP_KERNEL);
10007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!bfad) {
10017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		error = -ENOMEM;
10027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out;
10037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
10047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->trcmod = kzalloc(sizeof(struct bfa_trc_mod_s), GFP_KERNEL);
10067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!bfad->trcmod) {
10077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING "Error alloc trace buffer!\n");
10087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		error = -ENOMEM;
10097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_alloc_trace_failure;
10107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
10117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	/*
10137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 * LOG/TRACE INIT
10147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 */
10157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_trc_init(bfad->trcmod);
10167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_trc(bfad, bfad_inst);
10177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->logmod = &bfad->log_data;
10197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	sprintf(buf, "%d", bfad_inst);
10207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_log_init(bfad->logmod, buf, bfa_os_printf);
10217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_drv_log_level_set(bfad);
10237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->aen = &bfad->aen_buf;
10257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!(bfad_load_fwimg(pdev))) {
10277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING "bfad_load_fwimg failure!\n");
10287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		kfree(bfad->trcmod);
10297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_alloc_trace_failure;
10307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
10317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	retval = bfad_pci_init(pdev, bfad);
10337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (retval) {
10347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING "bfad_pci_init failure!\n");
10357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		error = retval;
10367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_pci_init_failure;
10377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
10387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mutex_lock(&bfad_mutex);
10407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->inst_no = bfad_inst++;
10417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	list_add_tail(&bfad->list_entry, &bfad_list);
10427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mutex_unlock(&bfad_mutex);
10437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_init(&bfad->bfad_lock);
10457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_set_drvdata(pdev, bfad);
10467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->ref_count = 0;
10487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad->pport.bfad = bfad;
10497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1050e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad->bfad_tsk = kthread_create(bfad_worker, (void *) bfad, "%s",
1051e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati					"bfad_worker");
1052e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	if (IS_ERR(bfad->bfad_tsk)) {
1053e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		printk(KERN_INFO "bfad[%d]: Kernel thread"
1054e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati			" creation failed!\n",
1055e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati			bfad->inst_no);
1056e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		goto out_kthread_create_failure;
1057e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	}
1058e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
10597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	retval = bfad_drv_init(bfad);
10607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (retval != BFA_STATUS_OK)
10617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto out_drv_init_failure;
10627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
1063e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfad->bfad_flags |= BFAD_HAL_INIT_FAIL;
10647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING "bfad%d: hal init failed\n", bfad->inst_no);
10657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ok;
10667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
10677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1068e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	retval = bfad_start_ops(bfad);
10697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (retval != BFA_STATUS_OK)
1070e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		goto out_start_ops_failure;
10717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1072e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	kthread_stop(bfad->bfad_tsk);
1073e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	bfad->bfad_tsk = NULL;
10747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangok:
10767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return 0;
10777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1078e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatiout_start_ops_failure:
10797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_drv_uninit(bfad);
10807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_drv_init_failure:
1081e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	kthread_stop(bfad->bfad_tsk);
1082e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatiout_kthread_create_failure:
10837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mutex_lock(&bfad_mutex);
10847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_inst--;
10857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	list_del(&bfad->list_entry);
10867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mutex_unlock(&bfad_mutex);
10877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_pci_uninit(pdev, bfad);
10887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_pci_init_failure:
10897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	kfree(bfad->trcmod);
10907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_alloc_trace_failure:
10917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	kfree(bfad);
10927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout:
10937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return error;
10947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
10957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
10967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/**
10977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * PCI remove entry.
10987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
10997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
11007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_pci_remove(struct pci_dev *pdev)
11017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
11027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	struct bfad_s  *bfad = pci_get_drvdata(pdev);
11037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	unsigned long   flags;
11047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_trc(bfad, bfad->inst_no);
11067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1107e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	spin_lock_irqsave(&bfad->bfad_lock, flags);
1108e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	if (bfad->bfad_tsk != NULL)
1109e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		kthread_stop(bfad->bfad_tsk);
1110e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1111e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
11127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if ((bfad->bfad_flags & BFAD_DRV_INIT_DONE)
11137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	    && !(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
11147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		spin_lock_irqsave(&bfad->bfad_lock, flags);
11167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		init_completion(&bfad->comp);
11177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfa_stop(&bfad->bfa);
11187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
11197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		wait_for_completion(&bfad->comp);
11207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_remove_intr(bfad);
11227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		del_timer_sync(&bfad->hal_tmo);
11237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto hal_detach;
11247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	} else if (!(bfad->bfad_flags & BFAD_DRV_INIT_DONE)) {
11257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto remove_sysfs;
11267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
11277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1128e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	if (bfad->bfad_flags & BFAD_HAL_START_DONE) {
11297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_drv_stop(bfad);
1130e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	} else if (bfad->bfad_flags & BFAD_DRV_INIT_DONE) {
1131e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		/* Invoking bfa_stop() before bfa_detach
1132e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		 * when HAL and DRV init are success
1133e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		 * but HAL start did not occur.
1134e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		 */
1135e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		spin_lock_irqsave(&bfad->bfad_lock, flags);
1136e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		init_completion(&bfad->comp);
1137e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfa_stop(&bfad->bfa);
1138e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1139e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		wait_for_completion(&bfad->comp);
1140e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	}
11417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_remove_intr(bfad);
11437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	del_timer_sync(&bfad->hal_tmo);
1144e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati
1145e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati	if (bfad->bfad_flags & BFAD_FC4_PROBE_DONE)
1146e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati		bfad_fc4_probe_undo(bfad);
11477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (bfad->bfad_flags & BFAD_CFG_PPORT_DONE)
11497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_uncfg_pport(bfad);
11507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huanghal_detach:
11527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_lock_irqsave(&bfad->bfad_lock, flags);
11537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_detach(&bfad->bfa);
11547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
11557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_hal_mem_release(bfad);
11567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangremove_sysfs:
11577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mutex_lock(&bfad_mutex);
11597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_inst--;
11607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	list_del(&bfad->list_entry);
11617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	mutex_unlock(&bfad_mutex);
11627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_pci_uninit(pdev, bfad);
11637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	kfree(bfad->trcmod);
11657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	kfree(bfad);
11667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
11677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic struct pci_device_id bfad_id_table[] = {
11707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	{
11717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .vendor = BFA_PCI_VENDOR_ID_BROCADE,
11727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .device = BFA_PCI_DEVICE_ID_FC_8G2P,
11737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .subvendor = PCI_ANY_ID,
11747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .subdevice = PCI_ANY_ID,
11757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 },
11767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	{
11777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .vendor = BFA_PCI_VENDOR_ID_BROCADE,
11787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .device = BFA_PCI_DEVICE_ID_FC_8G1P,
11797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .subvendor = PCI_ANY_ID,
11807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .subdevice = PCI_ANY_ID,
11817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 },
11827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	{
11837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .vendor = BFA_PCI_VENDOR_ID_BROCADE,
11847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .device = BFA_PCI_DEVICE_ID_CT,
11857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .subvendor = PCI_ANY_ID,
11867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .subdevice = PCI_ANY_ID,
11877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .class = (PCI_CLASS_SERIAL_FIBER << 8),
11887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 .class_mask = ~0,
11897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	 },
11907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	{0, 0},
11927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang};
11937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_DEVICE_TABLE(pci, bfad_id_table);
11957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
11967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic struct pci_driver bfad_pci_driver = {
11977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	.name = BFAD_DRIVER_NAME,
11987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	.id_table = bfad_id_table,
11997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	.probe = bfad_pci_probe,
12007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	.remove = __devexit_p(bfad_pci_remove),
12017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang};
12027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/**
12047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang *  Linux driver module functions
12057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
12067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t
12077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_fc4_module_init(void)
12087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
12097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             rc;
12107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	rc = bfad_im_module_init();
12127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (rc != BFA_STATUS_OK)
12137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
12147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_tm_module_init();
12167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (ipfc_enable)
12177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_ipfc_module_init();
12187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext:
12197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return rc;
12207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
12217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid
12237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_fc4_module_exit(void)
12247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
12257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (ipfc_enable)
12267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_ipfc_module_exit();
12277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_tm_module_exit();
12287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_im_module_exit();
12297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
12307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/**
12327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Driver module init.
12337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
12347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int      __init
12357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_init(void)
12367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
12377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	int             error = 0;
12387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	printk(KERN_INFO "Brocade BFA FC/FCOE SCSI driver - version: %s\n",
12407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	       BFAD_DRIVER_VERSION);
12417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (num_sgpgs > 0)
12437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		num_sgpgs_parm = num_sgpgs;
12447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	error = bfad_fc4_module_init();
12467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (error) {
12477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		error = -ENOMEM;
12487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING "bfad_fc4_module_init failure\n");
12497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
12507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
12517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!strcmp(FCPI_NAME, " fcpim"))
12537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_IM;
12547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!strcmp(FCPT_NAME, " fcptm"))
12557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_TM;
12567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (!strcmp(IPFC_NAME, " ipfc"))
12577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_IPFC;
12587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_ioc_auto_recover(ioc_auto_recover);
12607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfa_fcs_rport_set_del_timeout(rport_del_timeout);
12617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	error = pci_register_driver(&bfad_pci_driver);
12627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	if (error) {
12647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		printk(KERN_WARNING "bfad pci_register_driver failure\n");
12657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang		goto ext;
12667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	}
12677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return 0;
12697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext:
12717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_fc4_module_exit();
12727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	return error;
12737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
12747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/**
12767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Driver module exit.
12777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */
12787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic void     __exit
12797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_exit(void)
12807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{
12817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	pci_unregister_driver(&bfad_pci_driver);
12827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_fc4_module_exit();
12837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang	bfad_free_fwimg();
12847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}
12857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#define BFAD_PROTO_NAME FCPI_NAME FCPT_NAME IPFC_NAME
12877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_init(bfad_init);
12897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_exit(bfad_exit);
12907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_LICENSE("GPL");
12917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_DESCRIPTION("Brocade Fibre Channel HBA Driver" BFAD_PROTO_NAME);
12927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_AUTHOR("Brocade Communications Systems, Inc.");
12937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_VERSION(BFAD_DRIVER_VERSION);
12947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
12957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang
1296