bfad.c revision 604158ade0d5378622541232a007bf975c8bd03f
17725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/* 27725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Copyright (c) 2005-2009 Brocade Communications Systems, Inc. 37725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * All rights reserved 47725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * www.brocade.com 57725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * 67725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Linux driver for Brocade Fibre Channel Host Bus Adapter. 77725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * 87725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * This program is free software; you can redistribute it and/or modify it 97725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * under the terms of the GNU General Public License (GPL) Version 2 as 107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * published by the Free Software Foundation 117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * 127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * This program is distributed in the hope that it will be useful, but 137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * WITHOUT ANY WARRANTY; without even the implied warranty of 147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * General Public License for more details. 167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */ 177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/** 197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * bfad.c Linux driver PCI interface module. 207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */ 217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 225a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include <linux/module.h> 24e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati#include <linux/kthread.h> 257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include "bfad_drv.h" 267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include "bfad_im.h" 277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include "bfad_tm.h" 287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include "bfad_ipfc.h" 297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include "bfad_trcmod.h" 307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include <fcb/bfa_fcb_vf.h> 317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include <fcb/bfa_fcb_rport.h> 327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include <fcb/bfa_fcb_port.h> 337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#include <fcb/bfa_fcb.h> 347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangBFA_TRC_FILE(LDRV, BFAD); 3642b426ecb453cf49c3d16cf1d7a5e5d8cab9869dJing HuangDEFINE_MUTEX(bfad_mutex); 377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangLIST_HEAD(bfad_list); 387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int bfad_inst; 397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangint bfad_supported_fc4s; 407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic char *host_name; 427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic char *os_name; 437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic char *os_patch; 447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int num_rports; 457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int num_ios; 467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int num_tms; 477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int num_fcxps; 487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int num_ufbufs; 497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int reqq_size; 507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int rspq_size; 517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int num_sgpgs; 527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT; 537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int bfa_io_max_sge = BFAD_IO_MAX_SGE; 547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int log_level = BFA_LOG_WARNING; 557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int ioc_auto_recover = BFA_TRUE; 567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int ipfc_enable = BFA_FALSE; 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); 62604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(os_name, "OS name of the hba host machine"); 637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(os_patch, charp, S_IRUGO | S_IWUSR); 64604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(os_patch, "OS patch level of the hba host machine"); 657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(host_name, charp, S_IRUGO | S_IWUSR); 66604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(host_name, "Hostname of the hba host machine"); 677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_rports, int, S_IRUGO | S_IWUSR); 68604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(num_rports, "Max number of rports supported per port" 69604158ade0d5378622541232a007bf975c8bd03fJing Huang " (physical/logical), default=1024"); 707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_ios, int, S_IRUGO | S_IWUSR); 71604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(num_ios, "Max number of ioim requests, default=2000"); 727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_tms, int, S_IRUGO | S_IWUSR); 73604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(num_tms, "Max number of task im requests, default=128"); 747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_fcxps, int, S_IRUGO | S_IWUSR); 75604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(num_fcxps, "Max number of fcxp requests, default=64"); 767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_ufbufs, int, S_IRUGO | S_IWUSR); 77604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(num_ufbufs, "Max number of unsolicited frame buffers," 78604158ade0d5378622541232a007bf975c8bd03fJing Huang " default=64"); 797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(reqq_size, int, S_IRUGO | S_IWUSR); 80604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(reqq_size, "Max number of request queue elements," 81604158ade0d5378622541232a007bf975c8bd03fJing Huang " default=256"); 827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(rspq_size, int, S_IRUGO | S_IWUSR); 83604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(rspq_size, "Max number of response queue elements," 84604158ade0d5378622541232a007bf975c8bd03fJing Huang " default=64"); 857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(num_sgpgs, int, S_IRUGO | S_IWUSR); 86604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(num_sgpgs, "Number of scatter/gather pages, default=2048"); 877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(rport_del_timeout, int, S_IRUGO | S_IWUSR); 88604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(rport_del_timeout, "Rport delete timeout, default=90 secs," 89604158ade0d5378622541232a007bf975c8bd03fJing Huang " Range[>0]"); 907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(bfa_lun_queue_depth, int, S_IRUGO | S_IWUSR); 91604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(bfa_lun_queue_depth, "Lun queue depth, default=32," 92604158ade0d5378622541232a007bf975c8bd03fJing Huang " Range[>0]"); 937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(bfa_io_max_sge, int, S_IRUGO | S_IWUSR); 94604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(bfa_io_max_sge, "Max io scatter/gather elements, default=255"); 957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(log_level, int, S_IRUGO | S_IWUSR); 96604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(log_level, "Driver log level, default=3," 97604158ade0d5378622541232a007bf975c8bd03fJing Huang " Range[Critical:1|Error:2|Warning:3|Info:4]"); 987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR); 99604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(ioc_auto_recover, "IOC auto recovery, default=1," 100604158ade0d5378622541232a007bf975c8bd03fJing Huang " Range[off:0|on:1]"); 1017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(ipfc_enable, int, S_IRUGO | S_IWUSR); 102604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(ipfc_enable, "Enable IPoFC, default=0, Range[off:0|on:1]"); 1037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_param(bfa_linkup_delay, int, S_IRUGO | S_IWUSR); 104604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(bfa_linkup_delay, "Link up delay, default=30 secs for boot" 105604158ade0d5378622541232a007bf975c8bd03fJing Huang " port. Otherwise Range[>0]"); 106604158ade0d5378622541232a007bf975c8bd03fJing Huangmodule_param(fdmi_enable, int, S_IRUGO | S_IWUSR); 107604158ade0d5378622541232a007bf975c8bd03fJing HuangMODULE_PARM_DESC(fdmi_enable, "Enables fdmi registration, default=1," 108604158ade0d5378622541232a007bf975c8bd03fJing Huang " Range[false:0|true:1]"); 1097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 1107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/* 1117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Stores the module parm num_sgpgs value; 1127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * used to reset for bfad next instance. 1137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */ 1147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int num_sgpgs_parm; 1157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 1167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic bfa_status_t 1177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_fc4_probe(struct bfad_s *bfad) 1187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 1197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang int rc; 1207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 1217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang rc = bfad_im_probe(bfad); 1227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (rc != BFA_STATUS_OK) 1237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto ext; 1247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 1257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_tm_probe(bfad); 1267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 1277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (ipfc_enable) 1287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_ipfc_probe(bfad); 129e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 130e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfad->bfad_flags |= BFAD_FC4_PROBE_DONE; 1317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext: 1327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang return rc; 1337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 1347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 1357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic void 1367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_fc4_probe_undo(struct bfad_s *bfad) 1377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 1387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_im_probe_undo(bfad); 1397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_tm_probe_undo(bfad); 1407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (ipfc_enable) 1417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_ipfc_probe_undo(bfad); 142e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfad->bfad_flags &= ~BFAD_FC4_PROBE_DONE; 1437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 1447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 1457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic void 1467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_fc4_probe_post(struct bfad_s *bfad) 1477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 1487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (bfad->im) 1497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_im_probe_post(bfad->im); 1507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 1517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_tm_probe_post(bfad); 1527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (ipfc_enable) 1537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_ipfc_probe_post(bfad); 1547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 1557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 1567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic bfa_status_t 1577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_fc4_port_new(struct bfad_s *bfad, struct bfad_port_s *port, int roles) 1587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 1597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang int rc = BFA_STATUS_FAILED; 1607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 1617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (roles & BFA_PORT_ROLE_FCP_IM) 1627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang rc = bfad_im_port_new(bfad, port); 1637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (rc != BFA_STATUS_OK) 1647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto ext; 1657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 1667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (roles & BFA_PORT_ROLE_FCP_TM) 1677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang rc = bfad_tm_port_new(bfad, port); 1687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (rc != BFA_STATUS_OK) 1697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto ext; 1707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 1717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable) 1727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang rc = bfad_ipfc_port_new(bfad, port, port->pvb_type); 1737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext: 1747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang return rc; 1757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 1767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 1777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic void 1787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_fc4_port_delete(struct bfad_s *bfad, struct bfad_port_s *port, int roles) 1797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 1807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (roles & BFA_PORT_ROLE_FCP_IM) 1817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_im_port_delete(bfad, port); 1827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 1837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (roles & BFA_PORT_ROLE_FCP_TM) 1847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_tm_port_delete(bfad, port); 1857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 1867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable) 1877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_ipfc_port_delete(bfad, port); 1887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 1897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 1907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/** 1917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * BFA callbacks 1927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */ 1937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid 1947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_hcb_comp(void *arg, bfa_status_t status) 1957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 1967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfad_hal_comp *fcomp = (struct bfad_hal_comp *)arg; 1977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 1987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang fcomp->status = status; 1997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang complete(&fcomp->comp); 2007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 2017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 2027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/** 2037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * bfa_init callback 2047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */ 2057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid 2067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_cb_init(void *drv, bfa_status_t init_status) 2077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 2087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfad_s *bfad = drv; 2097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 210e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati if (init_status == BFA_STATUS_OK) { 2117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->bfad_flags |= BFAD_HAL_INIT_DONE; 2127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 213e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati /* If BFAD_HAL_INIT_FAIL flag is set: 214e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati * Wake up the kernel thread to start 215e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati * the bfad operations after HAL init done 216e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati */ 217e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati if ((bfad->bfad_flags & BFAD_HAL_INIT_FAIL)) { 218e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfad->bfad_flags &= ~BFAD_HAL_INIT_FAIL; 219e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati wake_up_process(bfad->bfad_tsk); 220e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati } 221e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati } 222e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 2237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang complete(&bfad->comp); 2247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 2257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 2267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 2277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 2287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/** 2297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * BFA_FCS callbacks 2307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */ 2317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic struct bfad_port_s * 2327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_get_drv_port(struct bfad_s *bfad, struct bfad_vf_s *vf_drv, 2337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfad_vport_s *vp_drv) 2347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 235f8ceafde6f5bf6b4b7087c7f5e9da1b2a5284a2eJing Huang return (vp_drv) ? (&(vp_drv)->drv_port) 236f8ceafde6f5bf6b4b7087c7f5e9da1b2a5284a2eJing Huang : ((vf_drv) ? (&(vf_drv)->base_port) : (&(bfad)->pport)); 2377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 2387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 2397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstruct bfad_port_s * 2407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_fcb_port_new(struct bfad_s *bfad, struct bfa_fcs_port_s *port, 2417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang enum bfa_port_role roles, struct bfad_vf_s *vf_drv, 2427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfad_vport_s *vp_drv) 2437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 2447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_status_t rc; 2457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfad_port_s *port_drv; 2467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 2477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (!vp_drv && !vf_drv) { 2487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang port_drv = &bfad->pport; 2497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang port_drv->pvb_type = BFAD_PORT_PHYS_BASE; 2507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } else if (!vp_drv && vf_drv) { 2517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang port_drv = &vf_drv->base_port; 2527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang port_drv->pvb_type = BFAD_PORT_VF_BASE; 2537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } else if (vp_drv && !vf_drv) { 2547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang port_drv = &vp_drv->drv_port; 2557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang port_drv->pvb_type = BFAD_PORT_PHYS_VPORT; 2567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } else { 2577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang port_drv = &vp_drv->drv_port; 2587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang port_drv->pvb_type = BFAD_PORT_VF_VPORT; 2597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 2607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 2617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang port_drv->fcs_port = port; 2627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang port_drv->roles = roles; 2637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang rc = bfad_fc4_port_new(bfad, port_drv, roles); 2647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (rc != BFA_STATUS_OK) { 2657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_fc4_port_delete(bfad, port_drv, roles); 2667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang port_drv = NULL; 2677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 2687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 2697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang return port_drv; 2707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 2717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 2727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid 2737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_fcb_port_delete(struct bfad_s *bfad, enum bfa_port_role roles, 2747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv) 2757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 2767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfad_port_s *port_drv; 2777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 2787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang /* 2797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * this will be only called from rmmod context 2807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */ 2817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (vp_drv && !vp_drv->comp_del) { 2827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv); 2837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_trc(bfad, roles); 2847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_fc4_port_delete(bfad, port_drv, roles); 2857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 2867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 2877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 2887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid 2897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_fcb_port_online(struct bfad_s *bfad, enum bfa_port_role roles, 2907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv) 2917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 2927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfad_port_s *port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv); 2937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 2947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (roles & BFA_PORT_ROLE_FCP_IM) 2957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_im_port_online(bfad, port_drv); 2967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 2977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (roles & BFA_PORT_ROLE_FCP_TM) 2987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_tm_port_online(bfad, port_drv); 2997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 3007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable) 3017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_ipfc_port_online(bfad, port_drv); 3027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 3037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->bfad_flags |= BFAD_PORT_ONLINE; 3047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 3057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 3067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid 3077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_fcb_port_offline(struct bfad_s *bfad, enum bfa_port_role roles, 3087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv) 3097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 3107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfad_port_s *port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv); 3117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 3127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (roles & BFA_PORT_ROLE_FCP_IM) 3137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_im_port_offline(bfad, port_drv); 3147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 3157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (roles & BFA_PORT_ROLE_FCP_TM) 3167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_tm_port_offline(bfad, port_drv); 3177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 3187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable) 3197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_ipfc_port_offline(bfad, port_drv); 3207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 3217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 3227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid 3237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_fcb_vport_delete(struct bfad_vport_s *vport_drv) 3247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 3257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (vport_drv->comp_del) { 3267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang complete(vport_drv->comp_del); 3277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang return; 3287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 3297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 3307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 3317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/** 3327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * FCS RPORT alloc callback, after successful PLOGI by FCS 3337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */ 3347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t 3357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_fcb_rport_alloc(struct bfad_s *bfad, struct bfa_fcs_rport_s **rport, 3367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfad_rport_s **rport_drv) 3377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 3387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_status_t rc = BFA_STATUS_OK; 3397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 3407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang *rport_drv = kzalloc(sizeof(struct bfad_rport_s), GFP_ATOMIC); 3417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (*rport_drv == NULL) { 3427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang rc = BFA_STATUS_ENOMEM; 3437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto ext; 3447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 3457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 3467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang *rport = &(*rport_drv)->fcs_rport; 3477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 3487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext: 3497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang return rc; 3507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 3517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 352d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang/** 353d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang * @brief 354d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang * FCS PBC VPORT Create 355d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang */ 356d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huangvoid 357d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huangbfa_fcb_pbc_vport_create(struct bfad_s *bfad, struct bfi_pbc_vport_s pbc_vport) 358d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang{ 359d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang 360d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang struct bfad_pcfg_s *pcfg; 361d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang 362d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang pcfg = kzalloc(sizeof(struct bfad_pcfg_s), GFP_ATOMIC); 363d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang if (!pcfg) { 364d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang bfa_trc(bfad, 0); 365d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang return; 366d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang } 3677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 368d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang pcfg->port_cfg.roles = BFA_PORT_ROLE_FCP_IM; 369d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang pcfg->port_cfg.pwwn = pbc_vport.vp_pwwn; 370d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang pcfg->port_cfg.nwwn = pbc_vport.vp_nwwn; 371d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang pcfg->port_cfg.preboot_vp = BFA_TRUE; 372d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang 373d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang list_add_tail(&pcfg->list_entry, &bfad->pbc_pcfg_list); 374d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang 375d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang return; 376d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang} 3777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 3787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid 3797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_hal_mem_release(struct bfad_s *bfad) 3807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 3817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang int i; 3827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfa_meminfo_s *hal_meminfo = &bfad->meminfo; 3837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfa_mem_elem_s *meminfo_elem; 3847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 3857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang for (i = 0; i < BFA_MEM_TYPE_MAX; i++) { 3867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang meminfo_elem = &hal_meminfo->meminfo[i]; 3877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (meminfo_elem->kva != NULL) { 3887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang switch (meminfo_elem->mem_type) { 3897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang case BFA_MEM_TYPE_KVA: 3907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang vfree(meminfo_elem->kva); 3917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang break; 3927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang case BFA_MEM_TYPE_DMA: 3937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang dma_free_coherent(&bfad->pcidev->dev, 3947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang meminfo_elem->mem_len, 3957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang meminfo_elem->kva, 3967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang (dma_addr_t) meminfo_elem->dma); 3977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang break; 3987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang default: 3997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_assert(0); 4007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang break; 4017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 4027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 4037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 4047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 4057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang memset(hal_meminfo, 0, sizeof(struct bfa_meminfo_s)); 4067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 4077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 4087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid 4097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_update_hal_cfg(struct bfa_iocfc_cfg_s *bfa_cfg) 4107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 4117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (num_rports > 0) 4127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_cfg->fwcfg.num_rports = num_rports; 4137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (num_ios > 0) 4147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_cfg->fwcfg.num_ioim_reqs = num_ios; 4157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (num_tms > 0) 4167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_cfg->fwcfg.num_tskim_reqs = num_tms; 4177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (num_fcxps > 0) 4187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_cfg->fwcfg.num_fcxp_reqs = num_fcxps; 4197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (num_ufbufs > 0) 4207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_cfg->fwcfg.num_uf_bufs = num_ufbufs; 4217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (reqq_size > 0) 4227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_cfg->drvcfg.num_reqq_elems = reqq_size; 4237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (rspq_size > 0) 4247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_cfg->drvcfg.num_rspq_elems = rspq_size; 4257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (num_sgpgs > 0) 4267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_cfg->drvcfg.num_sgpgs = num_sgpgs; 4277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 4287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang /* 4297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * populate the hal values back to the driver for sysfs use. 4307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * otherwise, the default values will be shown as 0 in sysfs 4317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */ 4327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang num_rports = bfa_cfg->fwcfg.num_rports; 4337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang num_ios = bfa_cfg->fwcfg.num_ioim_reqs; 4347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang num_tms = bfa_cfg->fwcfg.num_tskim_reqs; 4357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang num_fcxps = bfa_cfg->fwcfg.num_fcxp_reqs; 4367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang num_ufbufs = bfa_cfg->fwcfg.num_uf_bufs; 4377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang reqq_size = bfa_cfg->drvcfg.num_reqq_elems; 4387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang rspq_size = bfa_cfg->drvcfg.num_rspq_elems; 4397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang num_sgpgs = bfa_cfg->drvcfg.num_sgpgs; 4407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 4417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 4427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t 4437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_hal_mem_alloc(struct bfad_s *bfad) 4447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 4457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfa_meminfo_s *hal_meminfo = &bfad->meminfo; 4467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfa_mem_elem_s *meminfo_elem; 4477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_status_t rc = BFA_STATUS_OK; 4487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang dma_addr_t phys_addr; 4497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang int retry_count = 0; 4507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang int reset_value = 1; 4517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang int min_num_sgpgs = 512; 4527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang void *kva; 4537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang int i; 4547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 4557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_cfg_get_default(&bfad->ioc_cfg); 4567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 4577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangretry: 4587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_update_hal_cfg(&bfad->ioc_cfg); 4597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->cfg_data.ioc_queue_depth = bfad->ioc_cfg.fwcfg.num_ioim_reqs; 4607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_cfg_get_meminfo(&bfad->ioc_cfg, hal_meminfo); 4617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 4627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang for (i = 0; i < BFA_MEM_TYPE_MAX; i++) { 4637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang meminfo_elem = &hal_meminfo->meminfo[i]; 4647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang switch (meminfo_elem->mem_type) { 4657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang case BFA_MEM_TYPE_KVA: 4667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang kva = vmalloc(meminfo_elem->mem_len); 4677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (kva == NULL) { 4687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_hal_mem_release(bfad); 4697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang rc = BFA_STATUS_ENOMEM; 4707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto ext; 4717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 4727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang memset(kva, 0, meminfo_elem->mem_len); 4737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang meminfo_elem->kva = kva; 4747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang break; 4757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang case BFA_MEM_TYPE_DMA: 4767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang kva = dma_alloc_coherent(&bfad->pcidev->dev, 4777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang meminfo_elem->mem_len, 4787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang &phys_addr, GFP_KERNEL); 4797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (kva == NULL) { 4807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_hal_mem_release(bfad); 4817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang /* 4827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * If we cannot allocate with default 4837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * num_sgpages try with half the value. 4847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */ 4857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (num_sgpgs > min_num_sgpgs) { 4867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang printk(KERN_INFO "bfad[%d]: memory" 4877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang " allocation failed with" 4887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang " num_sgpgs: %d\n", 4897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->inst_no, num_sgpgs); 4907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang nextLowerInt(&num_sgpgs); 4917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang printk(KERN_INFO "bfad[%d]: trying to" 4927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang " allocate memory with" 4937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang " num_sgpgs: %d\n", 4947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->inst_no, num_sgpgs); 4957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang retry_count++; 4967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto retry; 4977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } else { 4987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (num_sgpgs_parm > 0) 4997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang num_sgpgs = num_sgpgs_parm; 5007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang else { 5017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang reset_value = 5027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang (1 << retry_count); 5037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang num_sgpgs *= reset_value; 5047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 5057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang rc = BFA_STATUS_ENOMEM; 5067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto ext; 5077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 5087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 5097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 5107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (num_sgpgs_parm > 0) 5117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang num_sgpgs = num_sgpgs_parm; 5127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang else { 5137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang reset_value = (1 << retry_count); 5147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang num_sgpgs *= reset_value; 5157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 5167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 5177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang memset(kva, 0, meminfo_elem->mem_len); 5187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang meminfo_elem->kva = kva; 5197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang meminfo_elem->dma = phys_addr; 5207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang break; 5217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang default: 5227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang break; 5237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 5247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 5257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 5267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext: 5277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang return rc; 5287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 5297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 5307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/** 5317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Create a vport under a vf. 5327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */ 5337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t 5347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_vport_create(struct bfad_s *bfad, u16 vf_id, 535d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang struct bfa_port_cfg_s *port_cfg, struct device *dev) 5367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 5377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfad_vport_s *vport; 538d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang int rc = BFA_STATUS_OK; 5397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang unsigned long flags; 5407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct completion fcomp; 5417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 5427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang vport = kzalloc(sizeof(struct bfad_vport_s), GFP_KERNEL); 5437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (!vport) { 5447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang rc = BFA_STATUS_ENOMEM; 5457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto ext; 5467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 5477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 5487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang vport->drv_port.bfad = bfad; 5497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_lock_irqsave(&bfad->bfad_lock, flags); 550d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang if (port_cfg->preboot_vp == BFA_TRUE) 551d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang rc = bfa_fcs_pbc_vport_create(&vport->fcs_vport, 552d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang &bfad->bfa_fcs, vf_id, port_cfg, vport); 553d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang else 554d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang rc = bfa_fcs_vport_create(&vport->fcs_vport, 555d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang &bfad->bfa_fcs, vf_id, port_cfg, vport); 5567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_unlock_irqrestore(&bfad->bfad_lock, flags); 5577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 5587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (rc != BFA_STATUS_OK) 5597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto ext_free_vport; 5607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 5617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (port_cfg->roles & BFA_PORT_ROLE_FCP_IM) { 562b504293fe9dc42917a919044f2b672fb361329d0Jing Huang rc = bfad_im_scsi_host_alloc(bfad, vport->drv_port.im_port, 563b504293fe9dc42917a919044f2b672fb361329d0Jing Huang dev); 5647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (rc != BFA_STATUS_OK) 5657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto ext_free_fcs_vport; 5667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 5677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 5687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_lock_irqsave(&bfad->bfad_lock, flags); 5697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_fcs_vport_start(&vport->fcs_vport); 5707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_unlock_irqrestore(&bfad->bfad_lock, flags); 5717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 5727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang return BFA_STATUS_OK; 5737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 5747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext_free_fcs_vport: 5757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_lock_irqsave(&bfad->bfad_lock, flags); 5767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang vport->comp_del = &fcomp; 5777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang init_completion(vport->comp_del); 5787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_fcs_vport_delete(&vport->fcs_vport); 5797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_unlock_irqrestore(&bfad->bfad_lock, flags); 5807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang wait_for_completion(vport->comp_del); 5817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext_free_vport: 5827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang kfree(vport); 5837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext: 5847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang return rc; 5857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 5867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 5877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/** 5887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Create a vf and its base vport implicitely. 5897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */ 5907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t 5917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_vf_create(struct bfad_s *bfad, u16 vf_id, 5927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfa_port_cfg_s *port_cfg) 5937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 5947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfad_vf_s *vf; 5957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang int rc = BFA_STATUS_OK; 5967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 5977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang vf = kzalloc(sizeof(struct bfad_vf_s), GFP_KERNEL); 5987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (!vf) { 5997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang rc = BFA_STATUS_FAILED; 6007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto ext; 6017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 6027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 6037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang rc = bfa_fcs_vf_create(&vf->fcs_vf, &bfad->bfa_fcs, vf_id, port_cfg, 6047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang vf); 6057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (rc != BFA_STATUS_OK) 6067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang kfree(vf); 6077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext: 6087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang return rc; 6097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 6107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 6117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid 6127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_bfa_tmo(unsigned long data) 6137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 6147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfad_s *bfad = (struct bfad_s *)data; 6157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang unsigned long flags; 6167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct list_head doneq; 6177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 6187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_lock_irqsave(&bfad->bfad_lock, flags); 6197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 6207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_timer_tick(&bfad->bfa); 6217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 6227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_comp_deq(&bfad->bfa, &doneq); 6237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_unlock_irqrestore(&bfad->bfad_lock, flags); 6247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 6257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (!list_empty(&doneq)) { 6267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_comp_process(&bfad->bfa, &doneq); 6277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_lock_irqsave(&bfad->bfad_lock, flags); 6287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_comp_free(&bfad->bfa, &doneq); 6297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_unlock_irqrestore(&bfad->bfad_lock, flags); 6307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 6317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 6327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang mod_timer(&bfad->hal_tmo, jiffies + msecs_to_jiffies(BFA_TIMER_FREQ)); 6337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 6347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 6357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid 6367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_init_timer(struct bfad_s *bfad) 6377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 6387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang init_timer(&bfad->hal_tmo); 6397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->hal_tmo.function = bfad_bfa_tmo; 6407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->hal_tmo.data = (unsigned long)bfad; 6417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 6427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang mod_timer(&bfad->hal_tmo, jiffies + msecs_to_jiffies(BFA_TIMER_FREQ)); 6437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 6447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 6457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangint 6467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_pci_init(struct pci_dev *pdev, struct bfad_s *bfad) 6477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 6487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang int rc = -ENODEV; 6497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 6507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (pci_enable_device(pdev)) { 6517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang BFA_PRINTF(BFA_ERR, "pci_enable_device fail %p\n", pdev); 6527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto out; 6537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 6547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 6557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (pci_request_regions(pdev, BFAD_DRIVER_NAME)) 6567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto out_disable_device; 6577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 6587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang pci_set_master(pdev); 6597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 6607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 6617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) 6627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) { 6637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang BFA_PRINTF(BFA_ERR, "pci_set_dma_mask fail %p\n", pdev); 6647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto out_release_region; 6657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 6667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 667b3522f08ec7011aed0abc477bfedd00d189e9cd6Jing Huang bfad->pci_bar0_kva = pci_iomap(pdev, 0, pci_resource_len(pdev, 0)); 6687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 6697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (bfad->pci_bar0_kva == NULL) { 6707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang BFA_PRINTF(BFA_ERR, "Fail to map bar0\n"); 6717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto out_release_region; 6727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 6737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 6747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->hal_pcidev.pci_slot = PCI_SLOT(pdev->devfn); 6757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->hal_pcidev.pci_func = PCI_FUNC(pdev->devfn); 6767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->hal_pcidev.pci_bar_kva = bfad->pci_bar0_kva; 6777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->hal_pcidev.device_id = pdev->device; 6787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->pci_name = pci_name(pdev); 6797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 6807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->pci_attr.vendor_id = pdev->vendor; 6817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->pci_attr.device_id = pdev->device; 6827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->pci_attr.ssid = pdev->subsystem_device; 6837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->pci_attr.ssvid = pdev->subsystem_vendor; 6847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->pci_attr.pcifn = PCI_FUNC(pdev->devfn); 6857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 6867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->pcidev = pdev; 6877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang return 0; 6887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 6897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_release_region: 6907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang pci_release_regions(pdev); 6917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_disable_device: 6927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang pci_disable_device(pdev); 6937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout: 6947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang return rc; 6957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 6967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 6977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid 6987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_pci_uninit(struct pci_dev *pdev, struct bfad_s *bfad) 6997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 7007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang pci_iounmap(pdev, bfad->pci_bar0_kva); 7017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang pci_release_regions(pdev); 7027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang pci_disable_device(pdev); 7037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang pci_set_drvdata(pdev, NULL); 7047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 7057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 7067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid 7077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_fcs_port_cfg(struct bfad_s *bfad) 7087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 7097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfa_port_cfg_s port_cfg; 7107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfa_pport_attr_s attr; 7117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang char symname[BFA_SYMNAME_MAXLEN]; 7127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 7137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang sprintf(symname, "%s-%d", BFAD_DRIVER_NAME, bfad->inst_no); 7147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang memcpy(port_cfg.sym_name.symname, symname, strlen(symname)); 7151c8a4c37494932acd59079b4fc8d8f69fb329c2aKrishna Gudipati bfa_fcport_get_attr(&bfad->bfa, &attr); 7167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang port_cfg.nwwn = attr.nwwn; 7177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang port_cfg.pwwn = attr.pwwn; 7187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 7197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_fcs_cfg_base_port(&bfad->bfa_fcs, &port_cfg); 7207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 7217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 7227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t 7237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_drv_init(struct bfad_s *bfad) 7247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 7257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_status_t rc; 7267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang unsigned long flags; 7277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfa_fcs_driver_info_s driver_info; 7287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 7297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->cfg_data.rport_del_timeout = rport_del_timeout; 7307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->cfg_data.lun_queue_depth = bfa_lun_queue_depth; 7317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->cfg_data.io_max_sge = bfa_io_max_sge; 7327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->cfg_data.binding_method = FCP_PWWN_BINDING; 7337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 7347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang rc = bfad_hal_mem_alloc(bfad); 7357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (rc != BFA_STATUS_OK) { 7367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang printk(KERN_WARNING "bfad%d bfad_hal_mem_alloc failure\n", 7377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->inst_no); 7387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang printk(KERN_WARNING 7397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang "Not enough memory to attach all Brocade HBA ports," 7407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang " System may need more memory.\n"); 7417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto out_hal_mem_alloc_failure; 7427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 7437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 7447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_init_log(&bfad->bfa, bfad->logmod); 7457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_init_trc(&bfad->bfa, bfad->trcmod); 7467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_init_aen(&bfad->bfa, bfad->aen); 7472993cc71d1bff61999ade7f2b6b3ea2dd1e2c8d9Krishna Gudipati memset(bfad->file_map, 0, sizeof(bfad->file_map)); 7487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_init_plog(&bfad->bfa, &bfad->plog_buf); 7497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_plog_init(&bfad->plog_buf); 7507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_plog_str(&bfad->plog_buf, BFA_PL_MID_DRVR, BFA_PL_EID_DRIVER_START, 7517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 0, "Driver Attach"); 7527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 7537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_attach(&bfad->bfa, bfad, &bfad->ioc_cfg, &bfad->meminfo, 7547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang &bfad->hal_pcidev); 7557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 7567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang init_completion(&bfad->comp); 7577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 7587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang /* 7597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Enable Interrupt and wait bfa_init completion 7607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */ 7617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (bfad_setup_intr(bfad)) { 7627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang printk(KERN_WARNING "bfad%d: bfad_setup_intr failed\n", 7637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->inst_no); 7647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto out_setup_intr_failure; 7657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 7667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 7677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_lock_irqsave(&bfad->bfad_lock, flags); 7687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_init(&bfad->bfa); 7697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_unlock_irqrestore(&bfad->bfad_lock, flags); 7707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 7717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang /* 7727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Set up interrupt handler for each vectors 7737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */ 7747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if ((bfad->bfad_flags & BFAD_MSIX_ON) 7757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang && bfad_install_msix_handler(bfad)) { 7767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang printk(KERN_WARNING "%s: install_msix failed, bfad%d\n", 777f8ceafde6f5bf6b4b7087c7f5e9da1b2a5284a2eJing Huang __func__, bfad->inst_no); 7787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 7797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 7807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_init_timer(bfad); 7817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 7827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang wait_for_completion(&bfad->comp); 7837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 7847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang memset(&driver_info, 0, sizeof(driver_info)); 7857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang strncpy(driver_info.version, BFAD_DRIVER_VERSION, 7867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang sizeof(driver_info.version) - 1); 7877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (host_name) 7887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang strncpy(driver_info.host_machine_name, host_name, 7897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang sizeof(driver_info.host_machine_name) - 1); 7907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (os_name) 7917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang strncpy(driver_info.host_os_name, os_name, 7927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang sizeof(driver_info.host_os_name) - 1); 7937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (os_patch) 7947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang strncpy(driver_info.host_os_patch, os_patch, 7957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang sizeof(driver_info.host_os_patch) - 1); 7967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 7977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang strncpy(driver_info.os_device_name, bfad->pci_name, 7987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang sizeof(driver_info.os_device_name - 1)); 7997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 8007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang /* 8017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * FCS INIT 8027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */ 8037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_lock_irqsave(&bfad->bfad_lock, flags); 8047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_fcs_log_init(&bfad->bfa_fcs, bfad->logmod); 8057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_fcs_trc_init(&bfad->bfa_fcs, bfad->trcmod); 8067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_fcs_aen_init(&bfad->bfa_fcs, bfad->aen); 80782794a2e4153657d12a0c29272e40b47eaadb748Krishna Gudipati bfa_fcs_attach(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE); 808e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 809e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati /* Do FCS init only when HAL init is done */ 810e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati if ((bfad->bfad_flags & BFAD_HAL_INIT_DONE)) { 811e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfa_fcs_init(&bfad->bfa_fcs); 812e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfad->bfad_flags |= BFAD_FCS_INIT_DONE; 813e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati } 814e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 8157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_fcs_driver_info_init(&bfad->bfa_fcs, &driver_info); 8165b098082e22c168b7df4c5c3cd924047cee7d995Krishna Gudipati bfa_fcs_set_fdmi_param(&bfad->bfa_fcs, fdmi_enable); 8177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_unlock_irqrestore(&bfad->bfad_lock, flags); 8187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 8197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->bfad_flags |= BFAD_DRV_INIT_DONE; 8207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang return BFA_STATUS_OK; 8217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 8227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_setup_intr_failure: 8237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_detach(&bfad->bfa); 8247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_hal_mem_release(bfad); 8257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_hal_mem_alloc_failure: 8267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang return BFA_STATUS_FAILED; 8277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 8287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 8297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid 8307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_drv_uninit(struct bfad_s *bfad) 8317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 832e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati unsigned long flags; 833e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 834e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati spin_lock_irqsave(&bfad->bfad_lock, flags); 835e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati init_completion(&bfad->comp); 836e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfa_stop(&bfad->bfa); 837e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati spin_unlock_irqrestore(&bfad->bfad_lock, flags); 838e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati wait_for_completion(&bfad->comp); 839e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 8407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang del_timer_sync(&bfad->hal_tmo); 8417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_isr_disable(&bfad->bfa); 8427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_detach(&bfad->bfa); 8437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_remove_intr(bfad); 8447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_hal_mem_release(bfad); 845e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 846e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfad->bfad_flags &= ~BFAD_DRV_INIT_DONE; 8477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 8487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 8497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid 8507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_drv_start(struct bfad_s *bfad) 8517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 8527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang unsigned long flags; 8537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 8547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_lock_irqsave(&bfad->bfad_lock, flags); 8557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_start(&bfad->bfa); 8567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_fcs_start(&bfad->bfa_fcs); 8577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->bfad_flags |= BFAD_HAL_START_DONE; 8587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_unlock_irqrestore(&bfad->bfad_lock, flags); 8597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 8607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_fc4_probe_post(bfad); 8617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 8627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 8637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid 8647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_drv_stop(struct bfad_s *bfad) 8657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 8667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang unsigned long flags; 8677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 8687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_lock_irqsave(&bfad->bfad_lock, flags); 8697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang init_completion(&bfad->comp); 8707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->pport.flags |= BFAD_PORT_DELETE; 8717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_fcs_exit(&bfad->bfa_fcs); 8727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_unlock_irqrestore(&bfad->bfad_lock, flags); 8737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang wait_for_completion(&bfad->comp); 8747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 8757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_lock_irqsave(&bfad->bfad_lock, flags); 8767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang init_completion(&bfad->comp); 8777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_stop(&bfad->bfa); 8787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->bfad_flags &= ~BFAD_HAL_START_DONE; 8797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_unlock_irqrestore(&bfad->bfad_lock, flags); 8807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang wait_for_completion(&bfad->comp); 8817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 8827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 8837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t 8847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_cfg_pport(struct bfad_s *bfad, enum bfa_port_role role) 8857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 8867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang int rc = BFA_STATUS_OK; 8877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 8887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang /* 8897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Allocate scsi_host for the physical port 8907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */ 8917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if ((bfad_supported_fc4s & BFA_PORT_ROLE_FCP_IM) 8927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang && (role & BFA_PORT_ROLE_FCP_IM)) { 8937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (bfad->pport.im_port == NULL) { 8947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang rc = BFA_STATUS_FAILED; 8957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto out; 8967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 8977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 898b504293fe9dc42917a919044f2b672fb361329d0Jing Huang rc = bfad_im_scsi_host_alloc(bfad, bfad->pport.im_port, 899b504293fe9dc42917a919044f2b672fb361329d0Jing Huang &bfad->pcidev->dev); 9007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (rc != BFA_STATUS_OK) 9017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto out; 9027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 9037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->pport.roles |= BFA_PORT_ROLE_FCP_IM; 9047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 9057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 9067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->bfad_flags |= BFAD_CFG_PPORT_DONE; 9077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 9087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout: 9097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang return rc; 9107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 9117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 9127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid 9137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_uncfg_pport(struct bfad_s *bfad) 9147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 9157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if ((bfad->pport.roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable) { 9167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_ipfc_port_delete(bfad, &bfad->pport); 9177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->pport.roles &= ~BFA_PORT_ROLE_FCP_IPFC; 9187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 9197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 9207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if ((bfad_supported_fc4s & BFA_PORT_ROLE_FCP_IM) 9217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang && (bfad->pport.roles & BFA_PORT_ROLE_FCP_IM)) { 9227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_im_scsi_host_free(bfad, bfad->pport.im_port); 9237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_im_port_clean(bfad->pport.im_port); 9247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang kfree(bfad->pport.im_port); 9257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->pport.roles &= ~BFA_PORT_ROLE_FCP_IM; 9267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 9277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 9287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->bfad_flags &= ~BFAD_CFG_PPORT_DONE; 9297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 9307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 9317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid 9327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_drv_log_level_set(struct bfad_s *bfad) 9337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 9347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (log_level > BFA_LOG_INVALID && log_level <= BFA_LOG_LEVEL_MAX) 9357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_log_set_level_all(&bfad->log_data, log_level); 9367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 9377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 938e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatibfa_status_t 939e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatibfad_start_ops(struct bfad_s *bfad) 940e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati{ 941e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati int retval; 942d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang struct bfad_pcfg_s *pcfg, *pcfg_new; 943e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 944e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati /* PPORT FCS config */ 945e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfad_fcs_port_cfg(bfad); 946e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 947e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM); 948e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati if (retval != BFA_STATUS_OK) 949e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati goto out_cfg_pport_failure; 950e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 951e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati /* BFAD level FC4 (IM/TM/IPFC) specific resource allocation */ 952e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati retval = bfad_fc4_probe(bfad); 953e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati if (retval != BFA_STATUS_OK) { 954e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati printk(KERN_WARNING "bfad_fc4_probe failed\n"); 955e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati goto out_fc4_probe_failure; 956e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati } 957e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 958e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfad_drv_start(bfad); 959e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 960d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang /* pbc vport creation */ 961d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang list_for_each_entry_safe(pcfg, pcfg_new, &bfad->pbc_pcfg_list, 962d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang list_entry) { 963d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang struct fc_vport_identifiers vid; 964d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang struct fc_vport *fc_vport; 965d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang 966d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang memset(&vid, 0, sizeof(vid)); 967d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang vid.roles = FC_PORT_ROLE_FCP_INITIATOR; 968d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang vid.vport_type = FC_PORTTYPE_NPIV; 969d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang vid.disable = false; 970d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang vid.node_name = wwn_to_u64((u8 *)&pcfg->port_cfg.nwwn); 971d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang vid.port_name = wwn_to_u64((u8 *)&pcfg->port_cfg.pwwn); 972d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang fc_vport = fc_vport_create(bfad->pport.im_port->shost, 0, &vid); 973d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang if (!fc_vport) 974d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang printk(KERN_WARNING "bfad%d: failed to create pbc vport" 975d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang " %llx\n", bfad->inst_no, vid.port_name); 976d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang list_del(&pcfg->list_entry); 977d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang kfree(pcfg); 978d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang 979d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang } 980d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang 981e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati /* 982e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati * If bfa_linkup_delay is set to -1 default; try to retrive the 983e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati * value using the bfad_os_get_linkup_delay(); else use the 984e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati * passed in module param value as the bfa_linkup_delay. 985e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati */ 986e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati if (bfa_linkup_delay < 0) { 987e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 988e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfa_linkup_delay = bfad_os_get_linkup_delay(bfad); 989e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfad_os_rport_online_wait(bfad); 990e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfa_linkup_delay = -1; 991e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 992e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati } else { 993e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfad_os_rport_online_wait(bfad); 994e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati } 995e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 996e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name); 997e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 998e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati return BFA_STATUS_OK; 999e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 1000e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatiout_fc4_probe_failure: 1001e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfad_fc4_probe_undo(bfad); 1002e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfad_uncfg_pport(bfad); 1003e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatiout_cfg_pport_failure: 1004e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati return BFA_STATUS_FAILED; 1005e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati} 1006e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 1007e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatiint 1008d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huangbfad_worker(void *ptr) 1009e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati{ 1010e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati struct bfad_s *bfad; 1011e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati unsigned long flags; 1012e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 1013e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfad = (struct bfad_s *)ptr; 1014e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 1015e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati while (!kthread_should_stop()) { 1016e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 1017e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati /* Check if the FCS init is done from bfad_drv_init; 1018e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati * if not done do FCS init and set the flag. 1019e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati */ 1020e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati if (!(bfad->bfad_flags & BFAD_FCS_INIT_DONE)) { 1021e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati spin_lock_irqsave(&bfad->bfad_lock, flags); 1022e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfa_fcs_init(&bfad->bfa_fcs); 1023e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfad->bfad_flags |= BFAD_FCS_INIT_DONE; 1024e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1025e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati } 1026e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 1027e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati /* Start the bfad operations after HAL init done */ 1028e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfad_start_ops(bfad); 1029e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 1030e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati spin_lock_irqsave(&bfad->bfad_lock, flags); 1031e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfad->bfad_tsk = NULL; 1032e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1033e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 1034e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati break; 1035e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati } 1036e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 1037e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati return 0; 1038e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati} 1039e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 10407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang /* 10417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * PCI_entry PCI driver entries * { 10427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */ 10437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 10447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/** 10457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * PCI probe entry. 10467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */ 10477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangint 10487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid) 10497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 10507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfad_s *bfad; 10517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang int error = -ENODEV, retval; 10527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 10537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang /* 10547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * For single port cards - only claim function 0 10557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */ 10567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if ((pdev->device == BFA_PCI_DEVICE_ID_FC_8G1P) 10577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang && (PCI_FUNC(pdev->devfn) != 0)) 10587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang return -ENODEV; 10597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 10607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang BFA_TRACE(BFA_INFO, "bfad_pci_probe entry"); 10617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 10627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad = kzalloc(sizeof(struct bfad_s), GFP_KERNEL); 10637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (!bfad) { 10647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang error = -ENOMEM; 10657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto out; 10667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 10677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 10687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->trcmod = kzalloc(sizeof(struct bfa_trc_mod_s), GFP_KERNEL); 10697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (!bfad->trcmod) { 10707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang printk(KERN_WARNING "Error alloc trace buffer!\n"); 10717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang error = -ENOMEM; 10727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto out_alloc_trace_failure; 10737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 10747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 10757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang /* 10767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * LOG/TRACE INIT 10777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */ 10787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_trc_init(bfad->trcmod); 10797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_trc(bfad, bfad_inst); 10807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 10817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->logmod = &bfad->log_data; 10820a4b1fc0b24fc7adbaf8413f2992ce1395991a78Krishna Gudipati bfa_log_init(bfad->logmod, (char *)pci_name(pdev), bfa_os_printf); 10837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 10847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_drv_log_level_set(bfad); 10857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 10867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->aen = &bfad->aen_buf; 10877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 10887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (!(bfad_load_fwimg(pdev))) { 10897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang printk(KERN_WARNING "bfad_load_fwimg failure!\n"); 10907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang kfree(bfad->trcmod); 10917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto out_alloc_trace_failure; 10927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 10937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 10947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang retval = bfad_pci_init(pdev, bfad); 10957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (retval) { 10967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang printk(KERN_WARNING "bfad_pci_init failure!\n"); 10977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang error = retval; 10987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto out_pci_init_failure; 10997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 11007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 11017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang mutex_lock(&bfad_mutex); 11027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->inst_no = bfad_inst++; 11037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang list_add_tail(&bfad->list_entry, &bfad_list); 11047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang mutex_unlock(&bfad_mutex); 11057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 11067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_lock_init(&bfad->bfad_lock); 11077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang pci_set_drvdata(pdev, bfad); 11087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 11097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->ref_count = 0; 11107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad->pport.bfad = bfad; 1111d9883548a0b0afec4786e6c5cd8d03d43a30b779Jing Huang INIT_LIST_HEAD(&bfad->pbc_pcfg_list); 11127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 1113e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfad->bfad_tsk = kthread_create(bfad_worker, (void *) bfad, "%s", 1114e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati "bfad_worker"); 1115e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati if (IS_ERR(bfad->bfad_tsk)) { 1116e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati printk(KERN_INFO "bfad[%d]: Kernel thread" 1117e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati " creation failed!\n", 1118e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfad->inst_no); 1119e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati goto out_kthread_create_failure; 1120e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati } 1121e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 11227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang retval = bfad_drv_init(bfad); 11237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (retval != BFA_STATUS_OK) 11247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto out_drv_init_failure; 11257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (!(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) { 1126e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfad->bfad_flags |= BFAD_HAL_INIT_FAIL; 11277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang printk(KERN_WARNING "bfad%d: hal init failed\n", bfad->inst_no); 11287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto ok; 11297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 11307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 1131e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati retval = bfad_start_ops(bfad); 11327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (retval != BFA_STATUS_OK) 1133e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati goto out_start_ops_failure; 11347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 1135e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati kthread_stop(bfad->bfad_tsk); 1136e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfad->bfad_tsk = NULL; 11377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 11387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangok: 11397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang return 0; 11407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 1141e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatiout_start_ops_failure: 11427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_drv_uninit(bfad); 11437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_drv_init_failure: 1144e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati kthread_stop(bfad->bfad_tsk); 1145e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipatiout_kthread_create_failure: 11467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang mutex_lock(&bfad_mutex); 11477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_inst--; 11487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang list_del(&bfad->list_entry); 11497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang mutex_unlock(&bfad_mutex); 11507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_pci_uninit(pdev, bfad); 11517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_pci_init_failure: 11527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang kfree(bfad->trcmod); 11537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout_alloc_trace_failure: 11547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang kfree(bfad); 11557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangout: 11567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang return error; 11577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 11587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 11597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/** 11607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * PCI remove entry. 11617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */ 11627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid 11637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_pci_remove(struct pci_dev *pdev) 11647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 11657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang struct bfad_s *bfad = pci_get_drvdata(pdev); 11667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang unsigned long flags; 11677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 11687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_trc(bfad, bfad->inst_no); 11697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 1170e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati spin_lock_irqsave(&bfad->bfad_lock, flags); 1171e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati if (bfad->bfad_tsk != NULL) 1172e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati kthread_stop(bfad->bfad_tsk); 1173e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1174e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 11757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if ((bfad->bfad_flags & BFAD_DRV_INIT_DONE) 11767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang && !(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) { 11777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 11787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_lock_irqsave(&bfad->bfad_lock, flags); 11797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang init_completion(&bfad->comp); 11807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_stop(&bfad->bfa); 11817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_unlock_irqrestore(&bfad->bfad_lock, flags); 11827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang wait_for_completion(&bfad->comp); 11837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 11847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_remove_intr(bfad); 11857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang del_timer_sync(&bfad->hal_tmo); 11867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto hal_detach; 11877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } else if (!(bfad->bfad_flags & BFAD_DRV_INIT_DONE)) { 11887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto remove_sysfs; 11897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 11907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 1191e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati if (bfad->bfad_flags & BFAD_HAL_START_DONE) { 11927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_drv_stop(bfad); 1193e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati } else if (bfad->bfad_flags & BFAD_DRV_INIT_DONE) { 1194e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati /* Invoking bfa_stop() before bfa_detach 1195e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati * when HAL and DRV init are success 1196e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati * but HAL start did not occur. 1197e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati */ 1198e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati spin_lock_irqsave(&bfad->bfad_lock, flags); 1199e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati init_completion(&bfad->comp); 1200e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfa_stop(&bfad->bfa); 1201e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati spin_unlock_irqrestore(&bfad->bfad_lock, flags); 1202e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati wait_for_completion(&bfad->comp); 1203e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati } 12047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 12057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_remove_intr(bfad); 12067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang del_timer_sync(&bfad->hal_tmo); 1207e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati 1208e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati if (bfad->bfad_flags & BFAD_FC4_PROBE_DONE) 1209e67143243a1a6b47e1bdcda189ffac46d2a8744dKrishna Gudipati bfad_fc4_probe_undo(bfad); 12107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 12117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (bfad->bfad_flags & BFAD_CFG_PPORT_DONE) 12127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_uncfg_pport(bfad); 12137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 12147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huanghal_detach: 12157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_lock_irqsave(&bfad->bfad_lock, flags); 12167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_detach(&bfad->bfa); 12177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang spin_unlock_irqrestore(&bfad->bfad_lock, flags); 12187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_hal_mem_release(bfad); 12197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangremove_sysfs: 12207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 12217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang mutex_lock(&bfad_mutex); 12227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_inst--; 12237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang list_del(&bfad->list_entry); 12247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang mutex_unlock(&bfad_mutex); 12257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_pci_uninit(pdev, bfad); 12267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 12277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang kfree(bfad->trcmod); 12287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang kfree(bfad); 12297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 12307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 12317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 12327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic struct pci_device_id bfad_id_table[] = { 12337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang { 12347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang .vendor = BFA_PCI_VENDOR_ID_BROCADE, 12357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang .device = BFA_PCI_DEVICE_ID_FC_8G2P, 12367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang .subvendor = PCI_ANY_ID, 12377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang .subdevice = PCI_ANY_ID, 12387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang }, 12397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang { 12407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang .vendor = BFA_PCI_VENDOR_ID_BROCADE, 12417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang .device = BFA_PCI_DEVICE_ID_FC_8G1P, 12427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang .subvendor = PCI_ANY_ID, 12437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang .subdevice = PCI_ANY_ID, 12447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang }, 12457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang { 12467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang .vendor = BFA_PCI_VENDOR_ID_BROCADE, 12477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang .device = BFA_PCI_DEVICE_ID_CT, 12487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang .subvendor = PCI_ANY_ID, 12497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang .subdevice = PCI_ANY_ID, 12507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang .class = (PCI_CLASS_SERIAL_FIBER << 8), 12517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang .class_mask = ~0, 12527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang }, 1253293f82d59ed8b6d61d242e40ee7a6a146fae5eaaJing Huang { 1254293f82d59ed8b6d61d242e40ee7a6a146fae5eaaJing Huang .vendor = BFA_PCI_VENDOR_ID_BROCADE, 1255293f82d59ed8b6d61d242e40ee7a6a146fae5eaaJing Huang .device = BFA_PCI_DEVICE_ID_CT_FC, 1256293f82d59ed8b6d61d242e40ee7a6a146fae5eaaJing Huang .subvendor = PCI_ANY_ID, 1257293f82d59ed8b6d61d242e40ee7a6a146fae5eaaJing Huang .subdevice = PCI_ANY_ID, 1258293f82d59ed8b6d61d242e40ee7a6a146fae5eaaJing Huang .class = (PCI_CLASS_SERIAL_FIBER << 8), 1259293f82d59ed8b6d61d242e40ee7a6a146fae5eaaJing Huang .class_mask = ~0, 1260293f82d59ed8b6d61d242e40ee7a6a146fae5eaaJing Huang }, 12617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 12627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang {0, 0}, 12637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}; 12647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 12657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_DEVICE_TABLE(pci, bfad_id_table); 12667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 12677725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic struct pci_driver bfad_pci_driver = { 12687725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang .name = BFAD_DRIVER_NAME, 12697725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang .id_table = bfad_id_table, 12707725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang .probe = bfad_pci_probe, 12717725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang .remove = __devexit_p(bfad_pci_remove), 12727725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang}; 12737725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 12747725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/** 12757725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Linux driver module functions 12767725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */ 12777725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfa_status_t 12787725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_fc4_module_init(void) 12797725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 12807725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang int rc; 12817725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 12827725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang rc = bfad_im_module_init(); 12837725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (rc != BFA_STATUS_OK) 12847725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto ext; 12857725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 12867725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_tm_module_init(); 12877725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (ipfc_enable) 12887725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_ipfc_module_init(); 12897725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext: 12907725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang return rc; 12917725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 12927725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 12937725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangvoid 12947725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_fc4_module_exit(void) 12957725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 12967725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (ipfc_enable) 12977725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_ipfc_module_exit(); 12987725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_tm_module_exit(); 12997725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_im_module_exit(); 13007725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 13017725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 13027725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/** 13037725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Driver module init. 13047725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */ 13057725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic int __init 13067725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_init(void) 13077725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 13087725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang int error = 0; 13097725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 13107725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang printk(KERN_INFO "Brocade BFA FC/FCOE SCSI driver - version: %s\n", 13117725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang BFAD_DRIVER_VERSION); 13127725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 13137725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (num_sgpgs > 0) 13147725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang num_sgpgs_parm = num_sgpgs; 13157725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 13167725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang error = bfad_fc4_module_init(); 13177725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (error) { 13187725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang error = -ENOMEM; 13197725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang printk(KERN_WARNING "bfad_fc4_module_init failure\n"); 13207725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto ext; 13217725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 13227725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 13237725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (!strcmp(FCPI_NAME, " fcpim")) 13247725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_IM; 13257725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (!strcmp(FCPT_NAME, " fcptm")) 13267725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_TM; 13277725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (!strcmp(IPFC_NAME, " ipfc")) 13287725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_IPFC; 13297725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 13307725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_ioc_auto_recover(ioc_auto_recover); 13317725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfa_fcs_rport_set_del_timeout(rport_del_timeout); 13327725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang error = pci_register_driver(&bfad_pci_driver); 13337725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 13347725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang if (error) { 13357725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang printk(KERN_WARNING "bfad pci_register_driver failure\n"); 13367725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang goto ext; 13377725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang } 13387725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 13397725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang return 0; 13407725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 13417725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangext: 13427725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_fc4_module_exit(); 13437725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang return error; 13447725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 13457725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 13467725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang/** 13477725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang * Driver module exit. 13487725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang */ 13497725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangstatic void __exit 13507725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangbfad_exit(void) 13517725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang{ 13527725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang pci_unregister_driver(&bfad_pci_driver); 13537725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_fc4_module_exit(); 13547725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang bfad_free_fwimg(); 13557725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang} 13567725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 13577725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang#define BFAD_PROTO_NAME FCPI_NAME FCPT_NAME IPFC_NAME 13587725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 13597725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_init(bfad_init); 13607725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huangmodule_exit(bfad_exit); 13617725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_LICENSE("GPL"); 13627725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_DESCRIPTION("Brocade Fibre Channel HBA Driver" BFAD_PROTO_NAME); 13637725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_AUTHOR("Brocade Communications Systems, Inc."); 13647725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing HuangMODULE_VERSION(BFAD_DRIVER_VERSION); 13657725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 13667725ccfda59715ecf8f99e3b520a0b84cc2ea79eJing Huang 1367