Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2)  * Copyright 2008 Cisco Systems, Inc.  All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * Copyright 2007 Nuova Systems, Inc.  All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * This program is free software; you may redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * it under the terms of the GNU General Public License as published by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * the Free Software Foundation; version 2 of the License.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  * SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/mempool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <linux/if_ether.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <scsi/fc/fc_fip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <scsi/scsi_transport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <scsi/scsi_transport_fc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include <scsi/scsi_tcq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include <scsi/libfc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #include <scsi/fc_frame.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #include "vnic_dev.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #include "vnic_intr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #include "vnic_stats.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #include "fnic_io.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #include "fnic_fip.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #include "fnic.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #define PCI_DEVICE_ID_CISCO_FNIC	0x0045
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) /* Timer to poll notification area for events. Used for MSI interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #define FNIC_NOTIFY_TIMER_PERIOD	(2 * HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) static struct kmem_cache *fnic_sgl_cache[FNIC_SGL_NUM_CACHES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) static struct kmem_cache *fnic_io_req_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) static LIST_HEAD(fnic_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) static DEFINE_SPINLOCK(fnic_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) /* Supported devices by fnic module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) static struct pci_device_id fnic_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 	{ PCI_DEVICE(PCI_VENDOR_ID_CISCO, PCI_DEVICE_ID_CISCO_FNIC) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 	{ 0, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) MODULE_DESCRIPTION(DRV_DESCRIPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) MODULE_AUTHOR("Abhijeet Joglekar <abjoglek@cisco.com>, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	      "Joseph R. Eykholt <jeykholt@cisco.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) MODULE_VERSION(DRV_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) MODULE_DEVICE_TABLE(pci, fnic_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) unsigned int fnic_log_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) module_param(fnic_log_level, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) MODULE_PARM_DESC(fnic_log_level, "bit mask of fnic logging levels");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) unsigned int io_completions = FNIC_DFLT_IO_COMPLETIONS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) module_param(io_completions, int, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) MODULE_PARM_DESC(io_completions, "Max CQ entries to process at a time");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) unsigned int fnic_trace_max_pages = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) module_param(fnic_trace_max_pages, uint, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) MODULE_PARM_DESC(fnic_trace_max_pages, "Total allocated memory pages "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 					"for fnic trace buffer");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) unsigned int fnic_fc_trace_max_pages = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) module_param(fnic_fc_trace_max_pages, uint, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) MODULE_PARM_DESC(fnic_fc_trace_max_pages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 		 "Total allocated memory pages for fc trace buffer");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) static unsigned int fnic_max_qdepth = FNIC_DFLT_QUEUE_DEPTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) module_param(fnic_max_qdepth, uint, S_IRUGO|S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) MODULE_PARM_DESC(fnic_max_qdepth, "Queue depth to report for each LUN");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) static struct libfc_function_template fnic_transport_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	.frame_send = fnic_send,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	.lport_set_port_id = fnic_set_port_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	.fcp_abort_io = fnic_empty_scsi_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	.fcp_cleanup = fnic_empty_scsi_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	.exch_mgr_reset = fnic_exch_mgr_reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) static int fnic_slave_alloc(struct scsi_device *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	if (!rport || fc_remote_port_chkready(rport))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 		return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	scsi_change_queue_depth(sdev, fnic_max_qdepth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) static struct scsi_host_template fnic_host_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	.module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	.name = DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	.queuecommand = fnic_queuecommand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	.eh_timed_out = fc_eh_timed_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	.eh_abort_handler = fnic_abort_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	.eh_device_reset_handler = fnic_device_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	.eh_host_reset_handler = fnic_host_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	.slave_alloc = fnic_slave_alloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	.change_queue_depth = scsi_change_queue_depth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	.this_id = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	.cmd_per_lun = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	.can_queue = FNIC_DFLT_IO_REQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	.sg_tablesize = FNIC_MAX_SG_DESC_CNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	.max_sectors = 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	.shost_attrs = fnic_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	.track_queue_depth = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) fnic_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	if (timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 		rport->dev_loss_tmo = timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 		rport->dev_loss_tmo = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) static void fnic_get_host_speed(struct Scsi_Host *shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) static struct scsi_transport_template *fnic_fc_transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) static struct fc_host_statistics *fnic_get_stats(struct Scsi_Host *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) static void fnic_reset_host_stats(struct Scsi_Host *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) static struct fc_function_template fnic_fc_functions = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	.show_host_node_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	.show_host_port_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	.show_host_supported_classes = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	.show_host_supported_fc4s = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	.show_host_active_fc4s = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	.show_host_maxframe_size = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	.show_host_port_id = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	.show_host_supported_speeds = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	.get_host_speed = fnic_get_host_speed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	.show_host_speed = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	.show_host_port_type = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	.get_host_port_state = fc_get_host_port_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	.show_host_port_state = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	.show_host_symbolic_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	.show_rport_maxframe_size = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	.show_rport_supported_classes = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	.show_host_fabric_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	.show_starget_node_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	.show_starget_port_name = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	.show_starget_port_id = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	.show_rport_dev_loss_tmo = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	.set_rport_dev_loss_tmo = fnic_set_rport_dev_loss_tmo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	.issue_fc_host_lip = fnic_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	.get_fc_host_stats = fnic_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	.reset_fc_host_stats = fnic_reset_host_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	.dd_fcrport_size = sizeof(struct fc_rport_libfc_priv),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	.terminate_rport_io = fnic_terminate_rport_io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	.bsg_request = fc_lport_bsg_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) static void fnic_get_host_speed(struct Scsi_Host *shost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	struct fc_lport *lp = shost_priv(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	struct fnic *fnic = lport_priv(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	u32 port_speed = vnic_dev_port_speed(fnic->vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	/* Add in other values as they get defined in fw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	switch (port_speed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	case DCEM_PORTSPEED_10G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 		fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	case DCEM_PORTSPEED_20G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 		fc_host_speed(shost) = FC_PORTSPEED_20GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	case DCEM_PORTSPEED_25G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 		fc_host_speed(shost) = FC_PORTSPEED_25GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	case DCEM_PORTSPEED_40G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	case DCEM_PORTSPEED_4x10G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 		fc_host_speed(shost) = FC_PORTSPEED_40GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	case DCEM_PORTSPEED_100G:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 		fc_host_speed(shost) = FC_PORTSPEED_100GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 		fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) static struct fc_host_statistics *fnic_get_stats(struct Scsi_Host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	struct fc_lport *lp = shost_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	struct fnic *fnic = lport_priv(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	struct fc_host_statistics *stats = &lp->host_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	struct vnic_stats *vs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	if (time_before(jiffies, fnic->stats_time + HZ / FNIC_STATS_RATE_LIMIT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 		return stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	fnic->stats_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	spin_lock_irqsave(&fnic->fnic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	ret = vnic_dev_stats_dump(fnic->vdev, &fnic->stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 		FNIC_MAIN_DBG(KERN_DEBUG, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 			      "fnic: Get vnic stats failed"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 			      " 0x%x", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 		return stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	vs = fnic->stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	stats->tx_frames = vs->tx.tx_unicast_frames_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	stats->tx_words  = vs->tx.tx_unicast_bytes_ok / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	stats->rx_frames = vs->rx.rx_unicast_frames_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	stats->rx_words  = vs->rx.rx_unicast_bytes_ok / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	stats->error_frames = vs->tx.tx_errors + vs->rx.rx_errors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	stats->dumped_frames = vs->tx.tx_drops + vs->rx.rx_drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	stats->invalid_crc_count = vs->rx.rx_crc_errors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	stats->seconds_since_last_reset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 			(jiffies - fnic->stats_reset_time) / HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	stats->fcp_input_megabytes = div_u64(fnic->fcp_input_bytes, 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	stats->fcp_output_megabytes = div_u64(fnic->fcp_output_bytes, 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	return stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245)  * fnic_dump_fchost_stats
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246)  * note : dumps fc_statistics into system logs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) void fnic_dump_fchost_stats(struct Scsi_Host *host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 				struct fc_host_statistics *stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	FNIC_MAIN_NOTE(KERN_NOTICE, host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 			"fnic: seconds since last reset = %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 			stats->seconds_since_last_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	FNIC_MAIN_NOTE(KERN_NOTICE, host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 			"fnic: tx frames		= %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 			stats->tx_frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	FNIC_MAIN_NOTE(KERN_NOTICE, host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 			"fnic: tx words		= %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 			stats->tx_words);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	FNIC_MAIN_NOTE(KERN_NOTICE, host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 			"fnic: rx frames		= %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 			stats->rx_frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	FNIC_MAIN_NOTE(KERN_NOTICE, host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 			"fnic: rx words		= %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 			stats->rx_words);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	FNIC_MAIN_NOTE(KERN_NOTICE, host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 			"fnic: lip count		= %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 			stats->lip_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	FNIC_MAIN_NOTE(KERN_NOTICE, host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 			"fnic: nos count		= %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 			stats->nos_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	FNIC_MAIN_NOTE(KERN_NOTICE, host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 			"fnic: error frames		= %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 			stats->error_frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	FNIC_MAIN_NOTE(KERN_NOTICE, host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 			"fnic: dumped frames	= %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 			stats->dumped_frames);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	FNIC_MAIN_NOTE(KERN_NOTICE, host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 			"fnic: link failure count	= %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 			stats->link_failure_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	FNIC_MAIN_NOTE(KERN_NOTICE, host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 			"fnic: loss of sync count	= %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 			stats->loss_of_sync_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	FNIC_MAIN_NOTE(KERN_NOTICE, host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 			"fnic: loss of signal count	= %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 			stats->loss_of_signal_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	FNIC_MAIN_NOTE(KERN_NOTICE, host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 			"fnic: prim seq protocol err count = %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 			stats->prim_seq_protocol_err_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	FNIC_MAIN_NOTE(KERN_NOTICE, host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 			"fnic: invalid tx word count= %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 			stats->invalid_tx_word_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	FNIC_MAIN_NOTE(KERN_NOTICE, host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 			"fnic: invalid crc count	= %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 			stats->invalid_crc_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	FNIC_MAIN_NOTE(KERN_NOTICE, host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 			"fnic: fcp input requests	= %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 			stats->fcp_input_requests);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	FNIC_MAIN_NOTE(KERN_NOTICE, host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 			"fnic: fcp output requests	= %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 			stats->fcp_output_requests);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	FNIC_MAIN_NOTE(KERN_NOTICE, host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 			"fnic: fcp control requests	= %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 			stats->fcp_control_requests);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	FNIC_MAIN_NOTE(KERN_NOTICE, host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 			"fnic: fcp input megabytes	= %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 			stats->fcp_input_megabytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	FNIC_MAIN_NOTE(KERN_NOTICE, host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 			"fnic: fcp output megabytes	= %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 			stats->fcp_output_megabytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315)  * fnic_reset_host_stats : clears host stats
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316)  * note : called when reset_statistics set under sysfs dir
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) static void fnic_reset_host_stats(struct Scsi_Host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	struct fc_lport *lp = shost_priv(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	struct fnic *fnic = lport_priv(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	struct fc_host_statistics *stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	/* dump current stats, before clearing them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	stats = fnic_get_stats(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	fnic_dump_fchost_stats(host, stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	spin_lock_irqsave(&fnic->fnic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	ret = vnic_dev_stats_clear(fnic->vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 		FNIC_MAIN_DBG(KERN_DEBUG, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 				"fnic: Reset vnic stats failed"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 				" 0x%x", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	fnic->stats_reset_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	memset(stats, 0, sizeof(*stats));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) void fnic_log_q_error(struct fnic *fnic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	u32 error_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	for (i = 0; i < fnic->raw_wq_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 		error_status = ioread32(&fnic->wq[i].ctrl->error_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 		if (error_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 			shost_printk(KERN_ERR, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 				     "WQ[%d] error_status"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 				     " %d\n", i, error_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	for (i = 0; i < fnic->rq_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 		error_status = ioread32(&fnic->rq[i].ctrl->error_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 		if (error_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 			shost_printk(KERN_ERR, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 				     "RQ[%d] error_status"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 				     " %d\n", i, error_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	for (i = 0; i < fnic->wq_copy_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 		error_status = ioread32(&fnic->wq_copy[i].ctrl->error_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 		if (error_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 			shost_printk(KERN_ERR, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 				     "CWQ[%d] error_status"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 				     " %d\n", i, error_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) void fnic_handle_link_event(struct fnic *fnic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	spin_lock_irqsave(&fnic->fnic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	if (fnic->stop_rx_link_events) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	queue_work(fnic_event_queue, &fnic->link_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) static int fnic_notify_set(struct fnic *fnic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	switch (vnic_dev_get_intr_mode(fnic->vdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	case VNIC_DEV_INTR_MODE_INTX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 		err = vnic_dev_notify_set(fnic->vdev, FNIC_INTX_NOTIFY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	case VNIC_DEV_INTR_MODE_MSI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 		err = vnic_dev_notify_set(fnic->vdev, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	case VNIC_DEV_INTR_MODE_MSIX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 		err = vnic_dev_notify_set(fnic->vdev, FNIC_MSIX_ERR_NOTIFY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 		shost_printk(KERN_ERR, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 			     "Interrupt mode should be set up"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 			     " before devcmd notify set %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 			     vnic_dev_get_intr_mode(fnic->vdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 		err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) static void fnic_notify_timer(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	struct fnic *fnic = from_timer(fnic, t, notify_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	fnic_handle_link_event(fnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	mod_timer(&fnic->notify_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 		  round_jiffies(jiffies + FNIC_NOTIFY_TIMER_PERIOD));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) static void fnic_fip_notify_timer(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	struct fnic *fnic = from_timer(fnic, t, fip_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	fnic_handle_fip_timer(fnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) static void fnic_notify_timer_start(struct fnic *fnic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	switch (vnic_dev_get_intr_mode(fnic->vdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	case VNIC_DEV_INTR_MODE_MSI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 		 * Schedule first timeout immediately. The driver is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 		 * initiatialized and ready to look for link up notification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 		mod_timer(&fnic->notify_timer, jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 		/* Using intr for notification for INTx/MSI-X */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) static int fnic_dev_wait(struct vnic_dev *vdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 			 int (*start)(struct vnic_dev *, int),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 			 int (*finished)(struct vnic_dev *, int *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 			 int arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	unsigned long time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	int done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	err = start(vdev, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	/* Wait for func to complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	* Sometime schedule_timeout_uninterruptible take long time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	* to wake up so we do not retry as we are only waiting for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	* 2 seconds in while loop. By adding count, we make sure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	* we try atleast three times before returning -ETIMEDOUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	time = jiffies + (HZ * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 		err = finished(vdev, &done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 		count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 		if (done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 		schedule_timeout_uninterruptible(HZ / 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	} while (time_after(time, jiffies) || (count < 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) static int fnic_cleanup(struct fnic *fnic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	vnic_dev_disable(fnic->vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	for (i = 0; i < fnic->intr_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 		vnic_intr_mask(&fnic->intr[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	for (i = 0; i < fnic->rq_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 		err = vnic_rq_disable(&fnic->rq[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	for (i = 0; i < fnic->raw_wq_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 		err = vnic_wq_disable(&fnic->wq[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	for (i = 0; i < fnic->wq_copy_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 		err = vnic_wq_copy_disable(&fnic->wq_copy[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	/* Clean up completed IOs and FCS frames */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	fnic_wq_copy_cmpl_handler(fnic, io_completions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	fnic_wq_cmpl_handler(fnic, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	fnic_rq_cmpl_handler(fnic, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	/* Clean up the IOs and FCS frames that have not completed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	for (i = 0; i < fnic->raw_wq_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 		vnic_wq_clean(&fnic->wq[i], fnic_free_wq_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	for (i = 0; i < fnic->rq_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 		vnic_rq_clean(&fnic->rq[i], fnic_free_rq_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	for (i = 0; i < fnic->wq_copy_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 		vnic_wq_copy_clean(&fnic->wq_copy[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 				   fnic_wq_copy_cleanup_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	for (i = 0; i < fnic->cq_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 		vnic_cq_clean(&fnic->cq[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	for (i = 0; i < fnic->intr_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 		vnic_intr_clean(&fnic->intr[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	mempool_destroy(fnic->io_req_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	for (i = 0; i < FNIC_SGL_NUM_CACHES; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 		mempool_destroy(fnic->io_sgl_pool[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) static void fnic_iounmap(struct fnic *fnic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	if (fnic->bar0.vaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 		iounmap(fnic->bar0.vaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543)  * fnic_get_mac() - get assigned data MAC address for FIP code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544)  * @lport: 	local port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) static u8 *fnic_get_mac(struct fc_lport *lport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	struct fnic *fnic = lport_priv(lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	return fnic->data_src_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) static void fnic_set_vlan(struct fnic *fnic, u16 vlan_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	vnic_dev_set_default_vlan(fnic->vdev, vlan_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	struct Scsi_Host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	struct fc_lport *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	struct fnic *fnic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	mempool_t *pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	 * Allocate SCSI Host and set up association between host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	 * local port, and fnic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	lp = libfc_host_alloc(&fnic_host_template, sizeof(struct fnic));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	if (!lp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 		printk(KERN_ERR PFX "Unable to alloc libfc local port\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 		goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	host = lp->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	fnic = lport_priv(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	fnic->lport = lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	fnic->ctlr.lp = lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	snprintf(fnic->name, sizeof(fnic->name) - 1, "%s%d", DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 		 host->host_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	host->transportt = fnic_fc_transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	fnic_stats_debugfs_init(fnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	/* Setup PCI resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	pci_set_drvdata(pdev, fnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	fnic->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	err = pci_enable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 		shost_printk(KERN_ERR, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 			     "Cannot enable PCI device, aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 		goto err_out_free_hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	err = pci_request_regions(pdev, DRV_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 		shost_printk(KERN_ERR, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 			     "Cannot enable PCI resources, aborting\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 		goto err_out_disable_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	pci_set_master(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	/* Query PCI controller on system for DMA addressing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	 * limitation for the device.  Try 64-bit first, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	 * fail to 32-bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 		err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 			shost_printk(KERN_ERR, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 				     "No usable DMA configuration "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 				     "aborting\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 			goto err_out_release_regions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	/* Map vNIC resources from BAR0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 		shost_printk(KERN_ERR, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 			     "BAR0 not memory-map'able, aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 		err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 		goto err_out_release_regions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	fnic->bar0.vaddr = pci_iomap(pdev, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	fnic->bar0.bus_addr = pci_resource_start(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	fnic->bar0.len = pci_resource_len(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	if (!fnic->bar0.vaddr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 		shost_printk(KERN_ERR, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 			     "Cannot memory-map BAR0 res hdr, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 			     "aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 		err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 		goto err_out_release_regions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	fnic->vdev = vnic_dev_register(NULL, fnic, pdev, &fnic->bar0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	if (!fnic->vdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 		shost_printk(KERN_ERR, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 			     "vNIC registration failed, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 			     "aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 		err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 		goto err_out_iounmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 	err = vnic_dev_cmd_init(fnic->vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		shost_printk(KERN_ERR, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 				"vnic_dev_cmd_init() returns %d, aborting\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 				err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		goto err_out_vnic_unregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	err = fnic_dev_wait(fnic->vdev, vnic_dev_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 			    vnic_dev_open_done, CMD_OPENF_RQ_ENABLE_THEN_POST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 		shost_printk(KERN_ERR, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 			     "vNIC dev open failed, aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		goto err_out_dev_cmd_deinit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	err = vnic_dev_init(fnic->vdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 		shost_printk(KERN_ERR, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 			     "vNIC dev init failed, aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 		goto err_out_dev_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	err = vnic_dev_mac_addr(fnic->vdev, fnic->ctlr.ctl_src_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 		shost_printk(KERN_ERR, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 			     "vNIC get MAC addr failed \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 		goto err_out_dev_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	/* set data_src for point-to-point mode and to keep it non-zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	memcpy(fnic->data_src_addr, fnic->ctlr.ctl_src_addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	/* Get vNIC configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	err = fnic_get_vnic_config(fnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 		shost_printk(KERN_ERR, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 			     "Get vNIC configuration failed, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 			     "aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 		goto err_out_dev_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	/* Configure Maximum Outstanding IO reqs*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	if (fnic->config.io_throttle_count != FNIC_UCSM_DFLT_THROTTLE_CNT_BLD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 		host->can_queue = min_t(u32, FNIC_MAX_IO_REQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 					max_t(u32, FNIC_MIN_IO_REQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 					fnic->config.io_throttle_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	fnic->fnic_max_tag_id = host->can_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	host->max_lun = fnic->config.luns_per_tgt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	host->max_id = FNIC_MAX_FCP_TARGET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	host->max_cmd_len = FCOE_MAX_CMD_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	fnic_get_res_counts(fnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	err = fnic_set_intr_mode(fnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 		shost_printk(KERN_ERR, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 			     "Failed to set intr mode, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 			     "aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 		goto err_out_dev_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	err = fnic_alloc_vnic_resources(fnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 		shost_printk(KERN_ERR, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 			     "Failed to alloc vNIC resources, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 			     "aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		goto err_out_clear_intr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	/* initialize all fnic locks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	spin_lock_init(&fnic->fnic_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	for (i = 0; i < FNIC_WQ_MAX; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 		spin_lock_init(&fnic->wq_lock[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	for (i = 0; i < FNIC_WQ_COPY_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		spin_lock_init(&fnic->wq_copy_lock[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 		fnic->wq_copy_desc_low[i] = DESC_CLEAN_LOW_WATERMARK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 		fnic->fw_ack_recd[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 		fnic->fw_ack_index[i] = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	for (i = 0; i < FNIC_IO_LOCKS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 		spin_lock_init(&fnic->io_req_lock[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	fnic->io_req_pool = mempool_create_slab_pool(2, fnic_io_req_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	if (!fnic->io_req_pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 		goto err_out_free_resources;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	pool = mempool_create_slab_pool(2, fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	if (!pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 		goto err_out_free_ioreq_pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	fnic->io_sgl_pool[FNIC_SGL_CACHE_DFLT] = pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	pool = mempool_create_slab_pool(2, fnic_sgl_cache[FNIC_SGL_CACHE_MAX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	if (!pool)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 		goto err_out_free_dflt_pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	fnic->io_sgl_pool[FNIC_SGL_CACHE_MAX] = pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 	/* setup vlan config, hw inserts vlan header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	fnic->vlan_hw_insert = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	fnic->vlan_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	/* Initialize the FIP fcoe_ctrl struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	fnic->ctlr.send = fnic_eth_send;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	fnic->ctlr.update_mac = fnic_update_mac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	fnic->ctlr.get_src_addr = fnic_get_mac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	if (fnic->config.flags & VFCF_FIP_CAPABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 		shost_printk(KERN_INFO, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 			     "firmware supports FIP\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		/* enable directed and multicast */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 		vnic_dev_packet_filter(fnic->vdev, 1, 1, 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 		vnic_dev_add_addr(fnic->vdev, FIP_ALL_ENODE_MACS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 		vnic_dev_add_addr(fnic->vdev, fnic->ctlr.ctl_src_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 		fnic->set_vlan = fnic_set_vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 		fcoe_ctlr_init(&fnic->ctlr, FIP_MODE_AUTO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 		timer_setup(&fnic->fip_timer, fnic_fip_notify_timer, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 		spin_lock_init(&fnic->vlans_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 		INIT_WORK(&fnic->fip_frame_work, fnic_handle_fip_frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 		INIT_WORK(&fnic->event_work, fnic_handle_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 		skb_queue_head_init(&fnic->fip_frame_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 		INIT_LIST_HEAD(&fnic->evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 		INIT_LIST_HEAD(&fnic->vlans);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		shost_printk(KERN_INFO, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 			     "firmware uses non-FIP mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 		fcoe_ctlr_init(&fnic->ctlr, FIP_MODE_NON_FIP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 		fnic->ctlr.state = FIP_ST_NON_FIP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	fnic->state = FNIC_IN_FC_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	atomic_set(&fnic->in_flight, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	fnic->state_flags = FNIC_FLAGS_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	/* Enable hardware stripping of vlan header on ingress */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	fnic_set_nic_config(fnic, 0, 0, 0, 0, 0, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	/* Setup notification buffer area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	err = fnic_notify_set(fnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 		shost_printk(KERN_ERR, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 			     "Failed to alloc notify buffer, aborting.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 		goto err_out_free_max_pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	/* Setup notify timer when using MSI interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	if (vnic_dev_get_intr_mode(fnic->vdev) == VNIC_DEV_INTR_MODE_MSI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 		timer_setup(&fnic->notify_timer, fnic_notify_timer, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	/* allocate RQ buffers and post them to RQ*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	for (i = 0; i < fnic->rq_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 		vnic_rq_enable(&fnic->rq[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 		err = vnic_rq_fill(&fnic->rq[i], fnic_alloc_rq_frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 			shost_printk(KERN_ERR, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 				     "fnic_alloc_rq_frame can't alloc "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 				     "frame\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 			goto err_out_free_rq_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	 * Initialization done with PCI system, hardware, firmware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	 * Add host to SCSI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	err = scsi_add_host(lp->host, &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 		shost_printk(KERN_ERR, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 			     "fnic: scsi_add_host failed...exiting\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 		goto err_out_free_rq_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	/* Start local port initiatialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	lp->link_up = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	lp->max_retry_count = fnic->config.flogi_retries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	lp->max_rport_retry_count = fnic->config.plogi_retries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	lp->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 			      FCP_SPPF_CONF_COMPL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	if (fnic->config.flags & VFCF_FCP_SEQ_LVL_ERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 		lp->service_params |= FCP_SPPF_RETRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	lp->boot_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	lp->e_d_tov = fnic->config.ed_tov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	lp->r_a_tov = fnic->config.ra_tov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	lp->link_supported_speeds = FC_PORTSPEED_10GBIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	fc_set_wwnn(lp, fnic->config.node_wwn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	fc_set_wwpn(lp, fnic->config.port_wwn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	fcoe_libfc_config(lp, &fnic->ctlr, &fnic_transport_template, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	if (!fc_exch_mgr_alloc(lp, FC_CLASS_3, FCPIO_HOST_EXCH_RANGE_START,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 			       FCPIO_HOST_EXCH_RANGE_END, NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 		goto err_out_remove_scsi_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	fc_lport_init_stats(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	fnic->stats_reset_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	fc_lport_config(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	if (fc_set_mfs(lp, fnic->config.maxdatafieldsize +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 		       sizeof(struct fc_frame_header))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 		goto err_out_free_exch_mgr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	fc_host_maxframe_size(lp->host) = lp->mfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	fc_host_dev_loss_tmo(lp->host) = fnic->config.port_down_timeout / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	sprintf(fc_host_symbolic_name(lp->host),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 		DRV_NAME " v" DRV_VERSION " over %s", fnic->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	spin_lock_irqsave(&fnic_list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	list_add_tail(&fnic->list, &fnic_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	spin_unlock_irqrestore(&fnic_list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	INIT_WORK(&fnic->link_work, fnic_handle_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	INIT_WORK(&fnic->frame_work, fnic_handle_frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	skb_queue_head_init(&fnic->frame_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	skb_queue_head_init(&fnic->tx_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	/* Enable all queues */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	for (i = 0; i < fnic->raw_wq_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		vnic_wq_enable(&fnic->wq[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	for (i = 0; i < fnic->wq_copy_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		vnic_wq_copy_enable(&fnic->wq_copy[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	fc_fabric_login(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	err = fnic_request_intr(fnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 		shost_printk(KERN_ERR, fnic->lport->host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 			     "Unable to request irq.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 		goto err_out_free_exch_mgr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	vnic_dev_enable(fnic->vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	for (i = 0; i < fnic->intr_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 		vnic_intr_unmask(&fnic->intr[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	fnic_notify_timer_start(fnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) err_out_free_exch_mgr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	fc_exch_mgr_free(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) err_out_remove_scsi_host:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	fc_remove_host(lp->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	scsi_remove_host(lp->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) err_out_free_rq_buf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	for (i = 0; i < fnic->rq_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 		vnic_rq_clean(&fnic->rq[i], fnic_free_rq_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	vnic_dev_notify_unset(fnic->vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) err_out_free_max_pool:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	mempool_destroy(fnic->io_sgl_pool[FNIC_SGL_CACHE_MAX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) err_out_free_dflt_pool:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	mempool_destroy(fnic->io_sgl_pool[FNIC_SGL_CACHE_DFLT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) err_out_free_ioreq_pool:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	mempool_destroy(fnic->io_req_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) err_out_free_resources:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	fnic_free_vnic_resources(fnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) err_out_clear_intr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	fnic_clear_intr_mode(fnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) err_out_dev_close:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	vnic_dev_close(fnic->vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) err_out_dev_cmd_deinit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) err_out_vnic_unregister:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	vnic_dev_unregister(fnic->vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) err_out_iounmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	fnic_iounmap(fnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) err_out_release_regions:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	pci_release_regions(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) err_out_disable_device:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) err_out_free_hba:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	fnic_stats_debugfs_remove(fnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	scsi_host_put(lp->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) static void fnic_remove(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	struct fnic *fnic = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	struct fc_lport *lp = fnic->lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	 * Mark state so that the workqueue thread stops forwarding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	 * received frames and link events to the local port. ISR and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	 * other threads that can queue work items will also stop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	 * creating work items on the fnic workqueue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	spin_lock_irqsave(&fnic->fnic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	fnic->stop_rx_link_events = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	if (vnic_dev_get_intr_mode(fnic->vdev) == VNIC_DEV_INTR_MODE_MSI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 		del_timer_sync(&fnic->notify_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	 * Flush the fnic event queue. After this call, there should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	 * be no event queued for this fnic device in the workqueue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	flush_workqueue(fnic_event_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	skb_queue_purge(&fnic->frame_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	skb_queue_purge(&fnic->tx_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	if (fnic->config.flags & VFCF_FIP_CAPABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 		del_timer_sync(&fnic->fip_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 		skb_queue_purge(&fnic->fip_frame_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 		fnic_fcoe_reset_vlans(fnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 		fnic_fcoe_evlist_free(fnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	 * Log off the fabric. This stops all remote ports, dns port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	 * logs off the fabric. This flushes all rport, disc, lport work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	 * before returning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	fc_fabric_logoff(fnic->lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	spin_lock_irqsave(&fnic->fnic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	fnic->in_remove = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	fcoe_ctlr_destroy(&fnic->ctlr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	fc_lport_destroy(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	fnic_stats_debugfs_remove(fnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	 * This stops the fnic device, masks all interrupts. Completed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	 * CQ entries are drained. Posted WQ/RQ/Copy-WQ entries are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	 * cleaned up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	fnic_cleanup(fnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	BUG_ON(!skb_queue_empty(&fnic->frame_queue));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	BUG_ON(!skb_queue_empty(&fnic->tx_queue));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	spin_lock_irqsave(&fnic_list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	list_del(&fnic->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	spin_unlock_irqrestore(&fnic_list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	fc_remove_host(fnic->lport->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	scsi_remove_host(fnic->lport->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	fc_exch_mgr_free(fnic->lport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	vnic_dev_notify_unset(fnic->vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	fnic_free_intr(fnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	fnic_free_vnic_resources(fnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	fnic_clear_intr_mode(fnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	vnic_dev_close(fnic->vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	vnic_dev_unregister(fnic->vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	fnic_iounmap(fnic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	pci_release_regions(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	scsi_host_put(lp->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) static struct pci_driver fnic_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	.name = DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	.id_table = fnic_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	.probe = fnic_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	.remove = fnic_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) static int __init fnic_init_module(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	printk(KERN_INFO PFX "%s, ver %s\n", DRV_DESCRIPTION, DRV_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	/* Create debugfs entries for fnic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	err = fnic_debugfs_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 		printk(KERN_ERR PFX "Failed to create fnic directory "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 				"for tracing and stats logging\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 		fnic_debugfs_terminate();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	/* Allocate memory for trace buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	err = fnic_trace_buf_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		printk(KERN_ERR PFX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 		       "Trace buffer initialization Failed. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 		       "Fnic Tracing utility is disabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 		fnic_trace_free();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)     /* Allocate memory for fc trace buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	err = fnic_fc_trace_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 		printk(KERN_ERR PFX "FC trace buffer initialization Failed "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 		       "FC frame tracing utility is disabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 		fnic_fc_trace_free();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	/* Create a cache for allocation of default size sgls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	len = sizeof(struct fnic_dflt_sgl_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	fnic_sgl_cache[FNIC_SGL_CACHE_DFLT] = kmem_cache_create
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 		("fnic_sgl_dflt", len + FNIC_SG_DESC_ALIGN, FNIC_SG_DESC_ALIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 		 SLAB_HWCACHE_ALIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 		 NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	if (!fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 		printk(KERN_ERR PFX "failed to create fnic dflt sgl slab\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 		goto err_create_fnic_sgl_slab_dflt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	/* Create a cache for allocation of max size sgls*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	len = sizeof(struct fnic_sgl_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	fnic_sgl_cache[FNIC_SGL_CACHE_MAX] = kmem_cache_create
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 		("fnic_sgl_max", len + FNIC_SG_DESC_ALIGN, FNIC_SG_DESC_ALIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 		  SLAB_HWCACHE_ALIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 		  NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	if (!fnic_sgl_cache[FNIC_SGL_CACHE_MAX]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 		printk(KERN_ERR PFX "failed to create fnic max sgl slab\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 		goto err_create_fnic_sgl_slab_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	/* Create a cache of io_req structs for use via mempool */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	fnic_io_req_cache = kmem_cache_create("fnic_io_req",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 					      sizeof(struct fnic_io_req),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 					      0, SLAB_HWCACHE_ALIGN, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	if (!fnic_io_req_cache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 		printk(KERN_ERR PFX "failed to create fnic io_req slab\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 		goto err_create_fnic_ioreq_slab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	fnic_event_queue = create_singlethread_workqueue("fnic_event_wq");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	if (!fnic_event_queue) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 		printk(KERN_ERR PFX "fnic work queue create failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 		goto err_create_fnic_workq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	spin_lock_init(&fnic_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	INIT_LIST_HEAD(&fnic_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	fnic_fip_queue = create_singlethread_workqueue("fnic_fip_q");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	if (!fnic_fip_queue) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 		printk(KERN_ERR PFX "fnic FIP work queue create failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 		goto err_create_fip_workq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	fnic_fc_transport = fc_attach_transport(&fnic_fc_functions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	if (!fnic_fc_transport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 		printk(KERN_ERR PFX "fc_attach_transport error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 		goto err_fc_transport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	/* register the driver with PCI system */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	err = pci_register_driver(&fnic_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 		printk(KERN_ERR PFX "pci register error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 		goto err_pci_register;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) err_pci_register:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	fc_release_transport(fnic_fc_transport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) err_fc_transport:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	destroy_workqueue(fnic_fip_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) err_create_fip_workq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	destroy_workqueue(fnic_event_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) err_create_fnic_workq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	kmem_cache_destroy(fnic_io_req_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) err_create_fnic_ioreq_slab:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_MAX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) err_create_fnic_sgl_slab_max:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) err_create_fnic_sgl_slab_dflt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	fnic_trace_free();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	fnic_fc_trace_free();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 	fnic_debugfs_terminate();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) static void __exit fnic_cleanup_module(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	pci_unregister_driver(&fnic_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	destroy_workqueue(fnic_event_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	if (fnic_fip_queue) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 		flush_workqueue(fnic_fip_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 		destroy_workqueue(fnic_fip_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_MAX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	kmem_cache_destroy(fnic_io_req_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	fc_release_transport(fnic_fc_transport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	fnic_trace_free();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	fnic_fc_trace_free();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	fnic_debugfs_terminate();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) module_init(fnic_init_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) module_exit(fnic_cleanup_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)