brintos

brintos / linux-shallow public Read only

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