cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

bfad_attr.c (29935B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
      4 * Copyright (c) 2014- QLogic Corporation.
      5 * All rights reserved
      6 * www.qlogic.com
      7 *
      8 * Linux driver for QLogic BR-series Fibre Channel Host Bus Adapter.
      9 */
     10
     11/*
     12 *  bfa_attr.c Linux driver configuration interface module.
     13 */
     14
     15#include "bfad_drv.h"
     16#include "bfad_im.h"
     17
     18/*
     19 * FC transport template entry, get SCSI target port ID.
     20 */
     21static void
     22bfad_im_get_starget_port_id(struct scsi_target *starget)
     23{
     24	struct Scsi_Host *shost;
     25	struct bfad_im_port_s *im_port;
     26	struct bfad_s         *bfad;
     27	struct bfad_itnim_s   *itnim = NULL;
     28	u32        fc_id = -1;
     29	unsigned long   flags;
     30
     31	shost = dev_to_shost(starget->dev.parent);
     32	im_port = (struct bfad_im_port_s *) shost->hostdata[0];
     33	bfad = im_port->bfad;
     34	spin_lock_irqsave(&bfad->bfad_lock, flags);
     35
     36	itnim = bfad_get_itnim(im_port, starget->id);
     37	if (itnim)
     38		fc_id = bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim);
     39
     40	fc_starget_port_id(starget) = fc_id;
     41	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
     42}
     43
     44/*
     45 * FC transport template entry, get SCSI target nwwn.
     46 */
     47static void
     48bfad_im_get_starget_node_name(struct scsi_target *starget)
     49{
     50	struct Scsi_Host *shost;
     51	struct bfad_im_port_s *im_port;
     52	struct bfad_s         *bfad;
     53	struct bfad_itnim_s   *itnim = NULL;
     54	u64             node_name = 0;
     55	unsigned long   flags;
     56
     57	shost = dev_to_shost(starget->dev.parent);
     58	im_port = (struct bfad_im_port_s *) shost->hostdata[0];
     59	bfad = im_port->bfad;
     60	spin_lock_irqsave(&bfad->bfad_lock, flags);
     61
     62	itnim = bfad_get_itnim(im_port, starget->id);
     63	if (itnim)
     64		node_name = bfa_fcs_itnim_get_nwwn(&itnim->fcs_itnim);
     65
     66	fc_starget_node_name(starget) = cpu_to_be64(node_name);
     67	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
     68}
     69
     70/*
     71 * FC transport template entry, get SCSI target pwwn.
     72 */
     73static void
     74bfad_im_get_starget_port_name(struct scsi_target *starget)
     75{
     76	struct Scsi_Host *shost;
     77	struct bfad_im_port_s *im_port;
     78	struct bfad_s         *bfad;
     79	struct bfad_itnim_s   *itnim = NULL;
     80	u64             port_name = 0;
     81	unsigned long   flags;
     82
     83	shost = dev_to_shost(starget->dev.parent);
     84	im_port = (struct bfad_im_port_s *) shost->hostdata[0];
     85	bfad = im_port->bfad;
     86	spin_lock_irqsave(&bfad->bfad_lock, flags);
     87
     88	itnim = bfad_get_itnim(im_port, starget->id);
     89	if (itnim)
     90		port_name = bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim);
     91
     92	fc_starget_port_name(starget) = cpu_to_be64(port_name);
     93	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
     94}
     95
     96/*
     97 * FC transport template entry, get SCSI host port ID.
     98 */
     99static void
    100bfad_im_get_host_port_id(struct Scsi_Host *shost)
    101{
    102	struct bfad_im_port_s *im_port =
    103			(struct bfad_im_port_s *) shost->hostdata[0];
    104	struct bfad_port_s    *port = im_port->port;
    105
    106	fc_host_port_id(shost) =
    107			bfa_hton3b(bfa_fcs_lport_get_fcid(port->fcs_port));
    108}
    109
    110/*
    111 * FC transport template entry, get SCSI host port type.
    112 */
    113static void
    114bfad_im_get_host_port_type(struct Scsi_Host *shost)
    115{
    116	struct bfad_im_port_s *im_port =
    117			(struct bfad_im_port_s *) shost->hostdata[0];
    118	struct bfad_s         *bfad = im_port->bfad;
    119	struct bfa_lport_attr_s port_attr;
    120
    121	bfa_fcs_lport_get_attr(&bfad->bfa_fcs.fabric.bport, &port_attr);
    122
    123	switch (port_attr.port_type) {
    124	case BFA_PORT_TYPE_NPORT:
    125		fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
    126		break;
    127	case BFA_PORT_TYPE_NLPORT:
    128		fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
    129		break;
    130	case BFA_PORT_TYPE_P2P:
    131		fc_host_port_type(shost) = FC_PORTTYPE_PTP;
    132		break;
    133	case BFA_PORT_TYPE_LPORT:
    134		fc_host_port_type(shost) = FC_PORTTYPE_LPORT;
    135		break;
    136	default:
    137		fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
    138		break;
    139	}
    140}
    141
    142/*
    143 * FC transport template entry, get SCSI host port state.
    144 */
    145static void
    146bfad_im_get_host_port_state(struct Scsi_Host *shost)
    147{
    148	struct bfad_im_port_s *im_port =
    149			(struct bfad_im_port_s *) shost->hostdata[0];
    150	struct bfad_s         *bfad = im_port->bfad;
    151	struct bfa_port_attr_s attr;
    152
    153	bfa_fcport_get_attr(&bfad->bfa, &attr);
    154
    155	switch (attr.port_state) {
    156	case BFA_PORT_ST_LINKDOWN:
    157		fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN;
    158		break;
    159	case BFA_PORT_ST_LINKUP:
    160		fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
    161		break;
    162	case BFA_PORT_ST_DISABLED:
    163	case BFA_PORT_ST_STOPPED:
    164	case BFA_PORT_ST_IOCDOWN:
    165	case BFA_PORT_ST_IOCDIS:
    166		fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
    167		break;
    168	case BFA_PORT_ST_UNINIT:
    169	case BFA_PORT_ST_ENABLING_QWAIT:
    170	case BFA_PORT_ST_ENABLING:
    171	case BFA_PORT_ST_DISABLING_QWAIT:
    172	case BFA_PORT_ST_DISABLING:
    173	default:
    174		fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN;
    175		break;
    176	}
    177}
    178
    179/*
    180 * FC transport template entry, get SCSI host active fc4s.
    181 */
    182static void
    183bfad_im_get_host_active_fc4s(struct Scsi_Host *shost)
    184{
    185	struct bfad_im_port_s *im_port =
    186			(struct bfad_im_port_s *) shost->hostdata[0];
    187	struct bfad_port_s    *port = im_port->port;
    188
    189	memset(fc_host_active_fc4s(shost), 0,
    190	       sizeof(fc_host_active_fc4s(shost)));
    191
    192	if (port->supported_fc4s & BFA_LPORT_ROLE_FCP_IM)
    193		fc_host_active_fc4s(shost)[2] = 1;
    194
    195	fc_host_active_fc4s(shost)[7] = 1;
    196}
    197
    198/*
    199 * FC transport template entry, get SCSI host link speed.
    200 */
    201static void
    202bfad_im_get_host_speed(struct Scsi_Host *shost)
    203{
    204	struct bfad_im_port_s *im_port =
    205			(struct bfad_im_port_s *) shost->hostdata[0];
    206	struct bfad_s         *bfad = im_port->bfad;
    207	struct bfa_port_attr_s attr;
    208
    209	bfa_fcport_get_attr(&bfad->bfa, &attr);
    210	switch (attr.speed) {
    211	case BFA_PORT_SPEED_10GBPS:
    212		fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
    213		break;
    214	case BFA_PORT_SPEED_16GBPS:
    215		fc_host_speed(shost) = FC_PORTSPEED_16GBIT;
    216		break;
    217	case BFA_PORT_SPEED_8GBPS:
    218		fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
    219		break;
    220	case BFA_PORT_SPEED_4GBPS:
    221		fc_host_speed(shost) = FC_PORTSPEED_4GBIT;
    222		break;
    223	case BFA_PORT_SPEED_2GBPS:
    224		fc_host_speed(shost) = FC_PORTSPEED_2GBIT;
    225		break;
    226	case BFA_PORT_SPEED_1GBPS:
    227		fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
    228		break;
    229	default:
    230		fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
    231		break;
    232	}
    233}
    234
    235/*
    236 * FC transport template entry, get SCSI host port type.
    237 */
    238static void
    239bfad_im_get_host_fabric_name(struct Scsi_Host *shost)
    240{
    241	struct bfad_im_port_s *im_port =
    242			(struct bfad_im_port_s *) shost->hostdata[0];
    243	struct bfad_port_s    *port = im_port->port;
    244	wwn_t           fabric_nwwn = 0;
    245
    246	fabric_nwwn = bfa_fcs_lport_get_fabric_name(port->fcs_port);
    247
    248	fc_host_fabric_name(shost) = cpu_to_be64(fabric_nwwn);
    249
    250}
    251
    252/*
    253 * FC transport template entry, get BFAD statistics.
    254 */
    255static struct fc_host_statistics *
    256bfad_im_get_stats(struct Scsi_Host *shost)
    257{
    258	struct bfad_im_port_s *im_port =
    259			(struct bfad_im_port_s *) shost->hostdata[0];
    260	struct bfad_s         *bfad = im_port->bfad;
    261	struct bfad_hal_comp fcomp;
    262	union bfa_port_stats_u *fcstats;
    263	struct fc_host_statistics *hstats;
    264	bfa_status_t    rc;
    265	unsigned long   flags;
    266
    267	fcstats = kzalloc(sizeof(union bfa_port_stats_u), GFP_KERNEL);
    268	if (fcstats == NULL)
    269		return NULL;
    270
    271	hstats = &bfad->link_stats;
    272	init_completion(&fcomp.comp);
    273	spin_lock_irqsave(&bfad->bfad_lock, flags);
    274	memset(hstats, 0, sizeof(struct fc_host_statistics));
    275	rc = bfa_port_get_stats(BFA_FCPORT(&bfad->bfa),
    276				fcstats, bfad_hcb_comp, &fcomp);
    277	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
    278	if (rc != BFA_STATUS_OK) {
    279		kfree(fcstats);
    280		return NULL;
    281	}
    282
    283	wait_for_completion(&fcomp.comp);
    284
    285	/* Fill the fc_host_statistics structure */
    286	hstats->seconds_since_last_reset = fcstats->fc.secs_reset;
    287	hstats->tx_frames = fcstats->fc.tx_frames;
    288	hstats->tx_words  = fcstats->fc.tx_words;
    289	hstats->rx_frames = fcstats->fc.rx_frames;
    290	hstats->rx_words  = fcstats->fc.rx_words;
    291	hstats->lip_count = fcstats->fc.lip_count;
    292	hstats->nos_count = fcstats->fc.nos_count;
    293	hstats->error_frames = fcstats->fc.error_frames;
    294	hstats->dumped_frames = fcstats->fc.dropped_frames;
    295	hstats->link_failure_count = fcstats->fc.link_failures;
    296	hstats->loss_of_sync_count = fcstats->fc.loss_of_syncs;
    297	hstats->loss_of_signal_count = fcstats->fc.loss_of_signals;
    298	hstats->prim_seq_protocol_err_count = fcstats->fc.primseq_errs;
    299	hstats->invalid_crc_count = fcstats->fc.invalid_crcs;
    300
    301	kfree(fcstats);
    302	return hstats;
    303}
    304
    305/*
    306 * FC transport template entry, reset BFAD statistics.
    307 */
    308static void
    309bfad_im_reset_stats(struct Scsi_Host *shost)
    310{
    311	struct bfad_im_port_s *im_port =
    312			(struct bfad_im_port_s *) shost->hostdata[0];
    313	struct bfad_s         *bfad = im_port->bfad;
    314	struct bfad_hal_comp fcomp;
    315	unsigned long   flags;
    316	bfa_status_t    rc;
    317
    318	init_completion(&fcomp.comp);
    319	spin_lock_irqsave(&bfad->bfad_lock, flags);
    320	rc = bfa_port_clear_stats(BFA_FCPORT(&bfad->bfa), bfad_hcb_comp,
    321					&fcomp);
    322	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
    323
    324	if (rc != BFA_STATUS_OK)
    325		return;
    326
    327	wait_for_completion(&fcomp.comp);
    328
    329	return;
    330}
    331
    332/*
    333 * FC transport template entry, set rport loss timeout.
    334 * Update dev_loss_tmo based on the value pushed down by the stack
    335 * In case it is lesser than path_tov of driver, set it to path_tov + 1
    336 * to ensure that the driver times out before the application
    337 */
    338static void
    339bfad_im_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout)
    340{
    341	struct bfad_itnim_data_s *itnim_data = rport->dd_data;
    342	struct bfad_itnim_s   *itnim = itnim_data->itnim;
    343	struct bfad_s         *bfad = itnim->im->bfad;
    344	uint16_t path_tov = bfa_fcpim_path_tov_get(&bfad->bfa);
    345
    346	rport->dev_loss_tmo = timeout;
    347	if (timeout < path_tov)
    348		rport->dev_loss_tmo = path_tov + 1;
    349}
    350
    351static int
    352bfad_im_vport_create(struct fc_vport *fc_vport, bool disable)
    353{
    354	char *vname = fc_vport->symbolic_name;
    355	struct Scsi_Host *shost = fc_vport->shost;
    356	struct bfad_im_port_s *im_port =
    357		(struct bfad_im_port_s *) shost->hostdata[0];
    358	struct bfad_s *bfad = im_port->bfad;
    359	struct bfa_lport_cfg_s port_cfg;
    360	struct bfad_vport_s *vp;
    361	int status = 0, rc;
    362	unsigned long flags;
    363
    364	memset(&port_cfg, 0, sizeof(port_cfg));
    365	u64_to_wwn(fc_vport->node_name, (u8 *)&port_cfg.nwwn);
    366	u64_to_wwn(fc_vport->port_name, (u8 *)&port_cfg.pwwn);
    367	if (strlen(vname) > 0)
    368		strcpy((char *)&port_cfg.sym_name, vname);
    369	port_cfg.roles = BFA_LPORT_ROLE_FCP_IM;
    370
    371	spin_lock_irqsave(&bfad->bfad_lock, flags);
    372	list_for_each_entry(vp, &bfad->pbc_vport_list, list_entry) {
    373		if (port_cfg.pwwn ==
    374				vp->fcs_vport.lport.port_cfg.pwwn) {
    375			port_cfg.preboot_vp =
    376				vp->fcs_vport.lport.port_cfg.preboot_vp;
    377			break;
    378		}
    379	}
    380	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
    381
    382	rc = bfad_vport_create(bfad, 0, &port_cfg, &fc_vport->dev);
    383	if (rc == BFA_STATUS_OK) {
    384		struct bfad_vport_s *vport;
    385		struct bfa_fcs_vport_s *fcs_vport;
    386		struct Scsi_Host *vshost;
    387
    388		spin_lock_irqsave(&bfad->bfad_lock, flags);
    389		fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0,
    390					port_cfg.pwwn);
    391		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
    392		if (fcs_vport == NULL)
    393			return VPCERR_BAD_WWN;
    394
    395		fc_vport_set_state(fc_vport, FC_VPORT_ACTIVE);
    396		if (disable) {
    397			spin_lock_irqsave(&bfad->bfad_lock, flags);
    398			bfa_fcs_vport_stop(fcs_vport);
    399			spin_unlock_irqrestore(&bfad->bfad_lock, flags);
    400			fc_vport_set_state(fc_vport, FC_VPORT_DISABLED);
    401		}
    402
    403		vport = fcs_vport->vport_drv;
    404		vshost = vport->drv_port.im_port->shost;
    405		fc_host_node_name(vshost) = wwn_to_u64((u8 *)&port_cfg.nwwn);
    406		fc_host_port_name(vshost) = wwn_to_u64((u8 *)&port_cfg.pwwn);
    407		fc_host_supported_classes(vshost) = FC_COS_CLASS3;
    408
    409		memset(fc_host_supported_fc4s(vshost), 0,
    410			sizeof(fc_host_supported_fc4s(vshost)));
    411
    412		/* For FCP type 0x08 */
    413		if (supported_fc4s & BFA_LPORT_ROLE_FCP_IM)
    414			fc_host_supported_fc4s(vshost)[2] = 1;
    415
    416		/* For fibre channel services type 0x20 */
    417		fc_host_supported_fc4s(vshost)[7] = 1;
    418
    419		fc_host_supported_speeds(vshost) =
    420				bfad_im_supported_speeds(&bfad->bfa);
    421		fc_host_maxframe_size(vshost) =
    422				bfa_fcport_get_maxfrsize(&bfad->bfa);
    423
    424		fc_vport->dd_data = vport;
    425		vport->drv_port.im_port->fc_vport = fc_vport;
    426	} else if (rc == BFA_STATUS_INVALID_WWN)
    427		return VPCERR_BAD_WWN;
    428	else if (rc == BFA_STATUS_VPORT_EXISTS)
    429		return VPCERR_BAD_WWN;
    430	else if (rc == BFA_STATUS_VPORT_MAX)
    431		return VPCERR_NO_FABRIC_SUPP;
    432	else if (rc == BFA_STATUS_VPORT_WWN_BP)
    433		return VPCERR_BAD_WWN;
    434	else
    435		return FC_VPORT_FAILED;
    436
    437	return status;
    438}
    439
    440static int
    441bfad_im_issue_fc_host_lip(struct Scsi_Host *shost)
    442{
    443	struct bfad_im_port_s *im_port =
    444			(struct bfad_im_port_s *) shost->hostdata[0];
    445	struct bfad_s *bfad = im_port->bfad;
    446	struct bfad_hal_comp fcomp;
    447	unsigned long flags;
    448	uint32_t status;
    449
    450	init_completion(&fcomp.comp);
    451	spin_lock_irqsave(&bfad->bfad_lock, flags);
    452	status = bfa_port_disable(&bfad->bfa.modules.port,
    453					bfad_hcb_comp, &fcomp);
    454	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
    455
    456	if (status != BFA_STATUS_OK)
    457		return -EIO;
    458
    459	wait_for_completion(&fcomp.comp);
    460	if (fcomp.status != BFA_STATUS_OK)
    461		return -EIO;
    462
    463	spin_lock_irqsave(&bfad->bfad_lock, flags);
    464	status = bfa_port_enable(&bfad->bfa.modules.port,
    465					bfad_hcb_comp, &fcomp);
    466	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
    467	if (status != BFA_STATUS_OK)
    468		return -EIO;
    469
    470	wait_for_completion(&fcomp.comp);
    471	if (fcomp.status != BFA_STATUS_OK)
    472		return -EIO;
    473
    474	return 0;
    475}
    476
    477static int
    478bfad_im_vport_delete(struct fc_vport *fc_vport)
    479{
    480	struct bfad_vport_s *vport = (struct bfad_vport_s *)fc_vport->dd_data;
    481	struct bfad_im_port_s *im_port =
    482			(struct bfad_im_port_s *) vport->drv_port.im_port;
    483	struct bfad_s *bfad = im_port->bfad;
    484	struct bfa_fcs_vport_s *fcs_vport;
    485	struct Scsi_Host *vshost;
    486	wwn_t   pwwn;
    487	int rc;
    488	unsigned long flags;
    489	struct completion fcomp;
    490
    491	if (im_port->flags & BFAD_PORT_DELETE) {
    492		bfad_scsi_host_free(bfad, im_port);
    493		list_del(&vport->list_entry);
    494		kfree(vport);
    495		return 0;
    496	}
    497
    498	vshost = vport->drv_port.im_port->shost;
    499	u64_to_wwn(fc_host_port_name(vshost), (u8 *)&pwwn);
    500
    501	spin_lock_irqsave(&bfad->bfad_lock, flags);
    502	fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn);
    503	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
    504
    505	if (fcs_vport == NULL)
    506		return VPCERR_BAD_WWN;
    507
    508	vport->drv_port.flags |= BFAD_PORT_DELETE;
    509
    510	vport->comp_del = &fcomp;
    511	init_completion(vport->comp_del);
    512
    513	spin_lock_irqsave(&bfad->bfad_lock, flags);
    514	rc = bfa_fcs_vport_delete(&vport->fcs_vport);
    515	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
    516
    517	if (rc == BFA_STATUS_PBC) {
    518		vport->drv_port.flags &= ~BFAD_PORT_DELETE;
    519		vport->comp_del = NULL;
    520		return -1;
    521	}
    522
    523	wait_for_completion(vport->comp_del);
    524
    525	bfad_scsi_host_free(bfad, im_port);
    526	list_del(&vport->list_entry);
    527	kfree(vport);
    528
    529	return 0;
    530}
    531
    532static int
    533bfad_im_vport_disable(struct fc_vport *fc_vport, bool disable)
    534{
    535	struct bfad_vport_s *vport;
    536	struct bfad_s *bfad;
    537	struct bfa_fcs_vport_s *fcs_vport;
    538	struct Scsi_Host *vshost;
    539	wwn_t   pwwn;
    540	unsigned long flags;
    541
    542	vport = (struct bfad_vport_s *)fc_vport->dd_data;
    543	bfad = vport->drv_port.bfad;
    544	vshost = vport->drv_port.im_port->shost;
    545	u64_to_wwn(fc_host_port_name(vshost), (u8 *)&pwwn);
    546
    547	spin_lock_irqsave(&bfad->bfad_lock, flags);
    548	fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn);
    549	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
    550
    551	if (fcs_vport == NULL)
    552		return VPCERR_BAD_WWN;
    553
    554	if (disable) {
    555		bfa_fcs_vport_stop(fcs_vport);
    556		fc_vport_set_state(fc_vport, FC_VPORT_DISABLED);
    557	} else {
    558		bfa_fcs_vport_start(fcs_vport);
    559		fc_vport_set_state(fc_vport, FC_VPORT_ACTIVE);
    560	}
    561
    562	return 0;
    563}
    564
    565static void
    566bfad_im_vport_set_symbolic_name(struct fc_vport *fc_vport)
    567{
    568	struct bfad_vport_s *vport = (struct bfad_vport_s *)fc_vport->dd_data;
    569	struct bfad_im_port_s *im_port =
    570			(struct bfad_im_port_s *)vport->drv_port.im_port;
    571	struct bfad_s *bfad = im_port->bfad;
    572	struct Scsi_Host *vshost = vport->drv_port.im_port->shost;
    573	char *sym_name = fc_vport->symbolic_name;
    574	struct bfa_fcs_vport_s *fcs_vport;
    575	wwn_t	pwwn;
    576	unsigned long flags;
    577
    578	u64_to_wwn(fc_host_port_name(vshost), (u8 *)&pwwn);
    579
    580	spin_lock_irqsave(&bfad->bfad_lock, flags);
    581	fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn);
    582	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
    583
    584	if (fcs_vport == NULL)
    585		return;
    586
    587	spin_lock_irqsave(&bfad->bfad_lock, flags);
    588	if (strlen(sym_name) > 0)
    589		bfa_fcs_lport_set_symname(&fcs_vport->lport, sym_name);
    590	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
    591}
    592
    593struct fc_function_template bfad_im_fc_function_template = {
    594
    595	/* Target dynamic attributes */
    596	.get_starget_port_id = bfad_im_get_starget_port_id,
    597	.show_starget_port_id = 1,
    598	.get_starget_node_name = bfad_im_get_starget_node_name,
    599	.show_starget_node_name = 1,
    600	.get_starget_port_name = bfad_im_get_starget_port_name,
    601	.show_starget_port_name = 1,
    602
    603	/* Host dynamic attribute */
    604	.get_host_port_id = bfad_im_get_host_port_id,
    605	.show_host_port_id = 1,
    606
    607	/* Host fixed attributes */
    608	.show_host_node_name = 1,
    609	.show_host_port_name = 1,
    610	.show_host_supported_classes = 1,
    611	.show_host_supported_fc4s = 1,
    612	.show_host_supported_speeds = 1,
    613	.show_host_maxframe_size = 1,
    614
    615	/* More host dynamic attributes */
    616	.show_host_port_type = 1,
    617	.get_host_port_type = bfad_im_get_host_port_type,
    618	.show_host_port_state = 1,
    619	.get_host_port_state = bfad_im_get_host_port_state,
    620	.show_host_active_fc4s = 1,
    621	.get_host_active_fc4s = bfad_im_get_host_active_fc4s,
    622	.show_host_speed = 1,
    623	.get_host_speed = bfad_im_get_host_speed,
    624	.show_host_fabric_name = 1,
    625	.get_host_fabric_name = bfad_im_get_host_fabric_name,
    626
    627	.show_host_symbolic_name = 1,
    628
    629	/* Statistics */
    630	.get_fc_host_stats = bfad_im_get_stats,
    631	.reset_fc_host_stats = bfad_im_reset_stats,
    632
    633	/* Allocation length for host specific data */
    634	.dd_fcrport_size = sizeof(struct bfad_itnim_data_s *),
    635
    636	/* Remote port fixed attributes */
    637	.show_rport_maxframe_size = 1,
    638	.show_rport_supported_classes = 1,
    639	.show_rport_dev_loss_tmo = 1,
    640	.set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo,
    641	.issue_fc_host_lip = bfad_im_issue_fc_host_lip,
    642	.vport_create = bfad_im_vport_create,
    643	.vport_delete = bfad_im_vport_delete,
    644	.vport_disable = bfad_im_vport_disable,
    645	.set_vport_symbolic_name = bfad_im_vport_set_symbolic_name,
    646	.bsg_request = bfad_im_bsg_request,
    647	.bsg_timeout = bfad_im_bsg_timeout,
    648};
    649
    650struct fc_function_template bfad_im_vport_fc_function_template = {
    651
    652	/* Target dynamic attributes */
    653	.get_starget_port_id = bfad_im_get_starget_port_id,
    654	.show_starget_port_id = 1,
    655	.get_starget_node_name = bfad_im_get_starget_node_name,
    656	.show_starget_node_name = 1,
    657	.get_starget_port_name = bfad_im_get_starget_port_name,
    658	.show_starget_port_name = 1,
    659
    660	/* Host dynamic attribute */
    661	.get_host_port_id = bfad_im_get_host_port_id,
    662	.show_host_port_id = 1,
    663
    664	/* Host fixed attributes */
    665	.show_host_node_name = 1,
    666	.show_host_port_name = 1,
    667	.show_host_supported_classes = 1,
    668	.show_host_supported_fc4s = 1,
    669	.show_host_supported_speeds = 1,
    670	.show_host_maxframe_size = 1,
    671
    672	/* More host dynamic attributes */
    673	.show_host_port_type = 1,
    674	.get_host_port_type = bfad_im_get_host_port_type,
    675	.show_host_port_state = 1,
    676	.get_host_port_state = bfad_im_get_host_port_state,
    677	.show_host_active_fc4s = 1,
    678	.get_host_active_fc4s = bfad_im_get_host_active_fc4s,
    679	.show_host_speed = 1,
    680	.get_host_speed = bfad_im_get_host_speed,
    681	.show_host_fabric_name = 1,
    682	.get_host_fabric_name = bfad_im_get_host_fabric_name,
    683
    684	.show_host_symbolic_name = 1,
    685
    686	/* Statistics */
    687	.get_fc_host_stats = bfad_im_get_stats,
    688	.reset_fc_host_stats = bfad_im_reset_stats,
    689
    690	/* Allocation length for host specific data */
    691	.dd_fcrport_size = sizeof(struct bfad_itnim_data_s *),
    692
    693	/* Remote port fixed attributes */
    694	.show_rport_maxframe_size = 1,
    695	.show_rport_supported_classes = 1,
    696	.show_rport_dev_loss_tmo = 1,
    697	.set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo,
    698};
    699
    700/*
    701 *  Scsi_Host_attrs SCSI host attributes
    702 */
    703static ssize_t
    704bfad_im_serial_num_show(struct device *dev, struct device_attribute *attr,
    705			 char *buf)
    706{
    707	struct Scsi_Host *shost = class_to_shost(dev);
    708	struct bfad_im_port_s *im_port =
    709			(struct bfad_im_port_s *) shost->hostdata[0];
    710	struct bfad_s *bfad = im_port->bfad;
    711	char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
    712
    713	bfa_get_adapter_serial_num(&bfad->bfa, serial_num);
    714	return sysfs_emit(buf, "%s\n", serial_num);
    715}
    716
    717static ssize_t
    718bfad_im_model_show(struct device *dev, struct device_attribute *attr,
    719			char *buf)
    720{
    721	struct Scsi_Host *shost = class_to_shost(dev);
    722	struct bfad_im_port_s *im_port =
    723			(struct bfad_im_port_s *) shost->hostdata[0];
    724	struct bfad_s *bfad = im_port->bfad;
    725	char model[BFA_ADAPTER_MODEL_NAME_LEN];
    726
    727	bfa_get_adapter_model(&bfad->bfa, model);
    728	return sysfs_emit(buf, "%s\n", model);
    729}
    730
    731static ssize_t
    732bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr,
    733				 char *buf)
    734{
    735	struct Scsi_Host *shost = class_to_shost(dev);
    736	struct bfad_im_port_s *im_port =
    737			(struct bfad_im_port_s *) shost->hostdata[0];
    738	struct bfad_s *bfad = im_port->bfad;
    739	char model[BFA_ADAPTER_MODEL_NAME_LEN];
    740	char model_descr[BFA_ADAPTER_MODEL_DESCR_LEN];
    741	int nports = 0;
    742
    743	bfa_get_adapter_model(&bfad->bfa, model);
    744	nports = bfa_get_nports(&bfad->bfa);
    745	if (!strcmp(model, "QLogic-425"))
    746		snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
    747			"QLogic BR-series 4Gbps PCIe dual port FC HBA");
    748	else if (!strcmp(model, "QLogic-825"))
    749		snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
    750			"QLogic BR-series 8Gbps PCIe dual port FC HBA");
    751	else if (!strcmp(model, "QLogic-42B"))
    752		snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
    753			"QLogic BR-series 4Gbps PCIe dual port FC HBA for HP");
    754	else if (!strcmp(model, "QLogic-82B"))
    755		snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
    756			"QLogic BR-series 8Gbps PCIe dual port FC HBA for HP");
    757	else if (!strcmp(model, "QLogic-1010"))
    758		snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
    759			"QLogic BR-series 10Gbps single port CNA");
    760	else if (!strcmp(model, "QLogic-1020"))
    761		snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
    762			"QLogic BR-series 10Gbps dual port CNA");
    763	else if (!strcmp(model, "QLogic-1007"))
    764		snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
    765			"QLogic BR-series 10Gbps CNA for IBM Blade Center");
    766	else if (!strcmp(model, "QLogic-415"))
    767		snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
    768			"QLogic BR-series 4Gbps PCIe single port FC HBA");
    769	else if (!strcmp(model, "QLogic-815"))
    770		snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
    771			"QLogic BR-series 8Gbps PCIe single port FC HBA");
    772	else if (!strcmp(model, "QLogic-41B"))
    773		snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
    774			"QLogic BR-series 4Gbps PCIe single port FC HBA for HP");
    775	else if (!strcmp(model, "QLogic-81B"))
    776		snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
    777			"QLogic BR-series 8Gbps PCIe single port FC HBA for HP");
    778	else if (!strcmp(model, "QLogic-804"))
    779		snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
    780			"QLogic BR-series 8Gbps FC HBA for HP Bladesystem C-class");
    781	else if (!strcmp(model, "QLogic-1741"))
    782		snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
    783			"QLogic BR-series 10Gbps CNA for Dell M-Series Blade Servers");
    784	else if (strstr(model, "QLogic-1860")) {
    785		if (nports == 1 && bfa_ioc_is_cna(&bfad->bfa.ioc))
    786			snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
    787				"QLogic BR-series 10Gbps single port CNA");
    788		else if (nports == 1 && !bfa_ioc_is_cna(&bfad->bfa.ioc))
    789			snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
    790				"QLogic BR-series 16Gbps PCIe single port FC HBA");
    791		else if (nports == 2 && bfa_ioc_is_cna(&bfad->bfa.ioc))
    792			snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
    793				"QLogic BR-series 10Gbps dual port CNA");
    794		else if (nports == 2 && !bfa_ioc_is_cna(&bfad->bfa.ioc))
    795			snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
    796				"QLogic BR-series 16Gbps PCIe dual port FC HBA");
    797	} else if (!strcmp(model, "QLogic-1867")) {
    798		if (nports == 1 && !bfa_ioc_is_cna(&bfad->bfa.ioc))
    799			snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
    800				"QLogic BR-series 16Gbps PCIe single port FC HBA for IBM");
    801		else if (nports == 2 && !bfa_ioc_is_cna(&bfad->bfa.ioc))
    802			snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
    803				"QLogic BR-series 16Gbps PCIe dual port FC HBA for IBM");
    804	} else
    805		snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
    806			"Invalid Model");
    807
    808	return sysfs_emit(buf, "%s\n", model_descr);
    809}
    810
    811static ssize_t
    812bfad_im_node_name_show(struct device *dev, struct device_attribute *attr,
    813				 char *buf)
    814{
    815	struct Scsi_Host *shost = class_to_shost(dev);
    816	struct bfad_im_port_s *im_port =
    817			(struct bfad_im_port_s *) shost->hostdata[0];
    818	struct bfad_port_s    *port = im_port->port;
    819	u64        nwwn;
    820
    821	nwwn = bfa_fcs_lport_get_nwwn(port->fcs_port);
    822	return sysfs_emit(buf, "0x%llx\n", cpu_to_be64(nwwn));
    823}
    824
    825static ssize_t
    826bfad_im_symbolic_name_show(struct device *dev, struct device_attribute *attr,
    827				 char *buf)
    828{
    829	struct Scsi_Host *shost = class_to_shost(dev);
    830	struct bfad_im_port_s *im_port =
    831			(struct bfad_im_port_s *) shost->hostdata[0];
    832	struct bfad_s *bfad = im_port->bfad;
    833	struct bfa_lport_attr_s port_attr;
    834	char symname[BFA_SYMNAME_MAXLEN];
    835
    836	bfa_fcs_lport_get_attr(&bfad->bfa_fcs.fabric.bport, &port_attr);
    837	strlcpy(symname, port_attr.port_cfg.sym_name.symname,
    838			BFA_SYMNAME_MAXLEN);
    839	return sysfs_emit(buf, "%s\n", symname);
    840}
    841
    842static ssize_t
    843bfad_im_hw_version_show(struct device *dev, struct device_attribute *attr,
    844				char *buf)
    845{
    846	struct Scsi_Host *shost = class_to_shost(dev);
    847	struct bfad_im_port_s *im_port =
    848			(struct bfad_im_port_s *) shost->hostdata[0];
    849	struct bfad_s *bfad = im_port->bfad;
    850	char hw_ver[BFA_VERSION_LEN];
    851
    852	bfa_get_pci_chip_rev(&bfad->bfa, hw_ver);
    853	return sysfs_emit(buf, "%s\n", hw_ver);
    854}
    855
    856static ssize_t
    857bfad_im_drv_version_show(struct device *dev, struct device_attribute *attr,
    858				char *buf)
    859{
    860	return sysfs_emit(buf, "%s\n", BFAD_DRIVER_VERSION);
    861}
    862
    863static ssize_t
    864bfad_im_optionrom_version_show(struct device *dev,
    865			 struct device_attribute *attr, char *buf)
    866{
    867	struct Scsi_Host *shost = class_to_shost(dev);
    868	struct bfad_im_port_s *im_port =
    869			(struct bfad_im_port_s *) shost->hostdata[0];
    870	struct bfad_s *bfad = im_port->bfad;
    871	char optrom_ver[BFA_VERSION_LEN];
    872
    873	bfa_get_adapter_optrom_ver(&bfad->bfa, optrom_ver);
    874	return sysfs_emit(buf, "%s\n", optrom_ver);
    875}
    876
    877static ssize_t
    878bfad_im_fw_version_show(struct device *dev, struct device_attribute *attr,
    879				 char *buf)
    880{
    881	struct Scsi_Host *shost = class_to_shost(dev);
    882	struct bfad_im_port_s *im_port =
    883			(struct bfad_im_port_s *) shost->hostdata[0];
    884	struct bfad_s *bfad = im_port->bfad;
    885	char fw_ver[BFA_VERSION_LEN];
    886
    887	bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver);
    888	return sysfs_emit(buf, "%s\n", fw_ver);
    889}
    890
    891static ssize_t
    892bfad_im_num_of_ports_show(struct device *dev, struct device_attribute *attr,
    893				char *buf)
    894{
    895	struct Scsi_Host *shost = class_to_shost(dev);
    896	struct bfad_im_port_s *im_port =
    897			(struct bfad_im_port_s *) shost->hostdata[0];
    898	struct bfad_s *bfad = im_port->bfad;
    899
    900	return sysfs_emit(buf, "%d\n",
    901			bfa_get_nports(&bfad->bfa));
    902}
    903
    904static ssize_t
    905bfad_im_drv_name_show(struct device *dev, struct device_attribute *attr,
    906				char *buf)
    907{
    908	return sysfs_emit(buf, "%s\n", BFAD_DRIVER_NAME);
    909}
    910
    911static ssize_t
    912bfad_im_num_of_discovered_ports_show(struct device *dev,
    913			struct device_attribute *attr, char *buf)
    914{
    915	struct Scsi_Host *shost = class_to_shost(dev);
    916	struct bfad_im_port_s *im_port =
    917			(struct bfad_im_port_s *) shost->hostdata[0];
    918	struct bfad_port_s    *port = im_port->port;
    919	struct bfad_s         *bfad = im_port->bfad;
    920	int        nrports = 2048;
    921	struct bfa_rport_qualifier_s *rports = NULL;
    922	unsigned long   flags;
    923
    924	rports = kcalloc(nrports, sizeof(struct bfa_rport_qualifier_s),
    925			 GFP_ATOMIC);
    926	if (rports == NULL)
    927		return sysfs_emit(buf, "Failed\n");
    928
    929	spin_lock_irqsave(&bfad->bfad_lock, flags);
    930	bfa_fcs_lport_get_rport_quals(port->fcs_port, rports, &nrports);
    931	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
    932	kfree(rports);
    933
    934	return sysfs_emit(buf, "%d\n", nrports);
    935}
    936
    937static          DEVICE_ATTR(serial_number, S_IRUGO,
    938				bfad_im_serial_num_show, NULL);
    939static          DEVICE_ATTR(model, S_IRUGO, bfad_im_model_show, NULL);
    940static          DEVICE_ATTR(model_description, S_IRUGO,
    941				bfad_im_model_desc_show, NULL);
    942static          DEVICE_ATTR(node_name, S_IRUGO, bfad_im_node_name_show, NULL);
    943static          DEVICE_ATTR(symbolic_name, S_IRUGO,
    944				bfad_im_symbolic_name_show, NULL);
    945static          DEVICE_ATTR(hardware_version, S_IRUGO,
    946				bfad_im_hw_version_show, NULL);
    947static          DEVICE_ATTR(driver_version, S_IRUGO,
    948				bfad_im_drv_version_show, NULL);
    949static          DEVICE_ATTR(option_rom_version, S_IRUGO,
    950				bfad_im_optionrom_version_show, NULL);
    951static          DEVICE_ATTR(firmware_version, S_IRUGO,
    952				bfad_im_fw_version_show, NULL);
    953static          DEVICE_ATTR(number_of_ports, S_IRUGO,
    954				bfad_im_num_of_ports_show, NULL);
    955static          DEVICE_ATTR(driver_name, S_IRUGO, bfad_im_drv_name_show, NULL);
    956static          DEVICE_ATTR(number_of_discovered_ports, S_IRUGO,
    957				bfad_im_num_of_discovered_ports_show, NULL);
    958
    959static struct attribute *bfad_im_host_attrs[] = {
    960	&dev_attr_serial_number.attr,
    961	&dev_attr_model.attr,
    962	&dev_attr_model_description.attr,
    963	&dev_attr_node_name.attr,
    964	&dev_attr_symbolic_name.attr,
    965	&dev_attr_hardware_version.attr,
    966	&dev_attr_driver_version.attr,
    967	&dev_attr_option_rom_version.attr,
    968	&dev_attr_firmware_version.attr,
    969	&dev_attr_number_of_ports.attr,
    970	&dev_attr_driver_name.attr,
    971	&dev_attr_number_of_discovered_ports.attr,
    972	NULL,
    973};
    974
    975static const struct attribute_group bfad_im_host_attr_group = {
    976	.attrs = bfad_im_host_attrs
    977};
    978
    979const struct attribute_group *bfad_im_host_groups[] = {
    980	&bfad_im_host_attr_group,
    981	NULL
    982};
    983
    984static struct attribute *bfad_im_vport_attrs[] = {
    985	&dev_attr_serial_number.attr,
    986	&dev_attr_model.attr,
    987	&dev_attr_model_description.attr,
    988	&dev_attr_node_name.attr,
    989	&dev_attr_symbolic_name.attr,
    990	&dev_attr_hardware_version.attr,
    991	&dev_attr_driver_version.attr,
    992	&dev_attr_option_rom_version.attr,
    993	&dev_attr_firmware_version.attr,
    994	&dev_attr_number_of_ports.attr,
    995	&dev_attr_driver_name.attr,
    996	&dev_attr_number_of_discovered_ports.attr,
    997	NULL,
    998};
    999
   1000static const struct attribute_group bfad_im_vport_attr_group = {
   1001	.attrs = bfad_im_vport_attrs
   1002};
   1003
   1004const struct attribute_group *bfad_im_vport_groups[] = {
   1005	&bfad_im_vport_attr_group,
   1006	NULL
   1007};