xref: /openbmc/linux/drivers/scsi/bfa/bfad_attr.c (revision 9e255e2b)
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  */
21 static void
22 bfad_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  */
47 static void
48 bfad_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  */
73 static void
74 bfad_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  */
99 static void
100 bfad_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  */
113 static void
114 bfad_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  */
145 static void
146 bfad_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  */
182 static void
183 bfad_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  */
201 static void
202 bfad_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  */
238 static void
239 bfad_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  */
255 static struct fc_host_statistics *
256 bfad_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  */
308 static void
309 bfad_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  */
338 static void
339 bfad_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 
351 static int
352 bfad_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 
440 static int
441 bfad_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 
477 static int
478 bfad_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 
532 static int
533 bfad_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 
565 static void
566 bfad_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 
593 struct 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 
650 struct 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  */
703 static ssize_t
704 bfad_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 snprintf(buf, PAGE_SIZE, "%s\n", serial_num);
715 }
716 
717 static ssize_t
718 bfad_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 snprintf(buf, PAGE_SIZE, "%s\n", model);
729 }
730 
731 static ssize_t
732 bfad_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 snprintf(buf, PAGE_SIZE, "%s\n", model_descr);
809 }
810 
811 static ssize_t
812 bfad_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 snprintf(buf, PAGE_SIZE, "0x%llx\n", cpu_to_be64(nwwn));
823 }
824 
825 static ssize_t
826 bfad_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 snprintf(buf, PAGE_SIZE, "%s\n", symname);
840 }
841 
842 static ssize_t
843 bfad_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 snprintf(buf, PAGE_SIZE, "%s\n", hw_ver);
854 }
855 
856 static ssize_t
857 bfad_im_drv_version_show(struct device *dev, struct device_attribute *attr,
858 				char *buf)
859 {
860 	return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_VERSION);
861 }
862 
863 static ssize_t
864 bfad_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 snprintf(buf, PAGE_SIZE, "%s\n", optrom_ver);
875 }
876 
877 static ssize_t
878 bfad_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 snprintf(buf, PAGE_SIZE, "%s\n", fw_ver);
889 }
890 
891 static ssize_t
892 bfad_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 snprintf(buf, PAGE_SIZE, "%d\n",
901 			bfa_get_nports(&bfad->bfa));
902 }
903 
904 static ssize_t
905 bfad_im_drv_name_show(struct device *dev, struct device_attribute *attr,
906 				char *buf)
907 {
908 	return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_NAME);
909 }
910 
911 static ssize_t
912 bfad_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 snprintf(buf, PAGE_SIZE, "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 snprintf(buf, PAGE_SIZE, "%d\n", nrports);
935 }
936 
937 static          DEVICE_ATTR(serial_number, S_IRUGO,
938 				bfad_im_serial_num_show, NULL);
939 static          DEVICE_ATTR(model, S_IRUGO, bfad_im_model_show, NULL);
940 static          DEVICE_ATTR(model_description, S_IRUGO,
941 				bfad_im_model_desc_show, NULL);
942 static          DEVICE_ATTR(node_name, S_IRUGO, bfad_im_node_name_show, NULL);
943 static          DEVICE_ATTR(symbolic_name, S_IRUGO,
944 				bfad_im_symbolic_name_show, NULL);
945 static          DEVICE_ATTR(hardware_version, S_IRUGO,
946 				bfad_im_hw_version_show, NULL);
947 static          DEVICE_ATTR(driver_version, S_IRUGO,
948 				bfad_im_drv_version_show, NULL);
949 static          DEVICE_ATTR(option_rom_version, S_IRUGO,
950 				bfad_im_optionrom_version_show, NULL);
951 static          DEVICE_ATTR(firmware_version, S_IRUGO,
952 				bfad_im_fw_version_show, NULL);
953 static          DEVICE_ATTR(number_of_ports, S_IRUGO,
954 				bfad_im_num_of_ports_show, NULL);
955 static          DEVICE_ATTR(driver_name, S_IRUGO, bfad_im_drv_name_show, NULL);
956 static          DEVICE_ATTR(number_of_discovered_ports, S_IRUGO,
957 				bfad_im_num_of_discovered_ports_show, NULL);
958 
959 struct device_attribute *bfad_im_host_attrs[] = {
960 	&dev_attr_serial_number,
961 	&dev_attr_model,
962 	&dev_attr_model_description,
963 	&dev_attr_node_name,
964 	&dev_attr_symbolic_name,
965 	&dev_attr_hardware_version,
966 	&dev_attr_driver_version,
967 	&dev_attr_option_rom_version,
968 	&dev_attr_firmware_version,
969 	&dev_attr_number_of_ports,
970 	&dev_attr_driver_name,
971 	&dev_attr_number_of_discovered_ports,
972 	NULL,
973 };
974 
975 struct device_attribute *bfad_im_vport_attrs[] = {
976 	&dev_attr_serial_number,
977 	&dev_attr_model,
978 	&dev_attr_model_description,
979 	&dev_attr_node_name,
980 	&dev_attr_symbolic_name,
981 	&dev_attr_hardware_version,
982 	&dev_attr_driver_version,
983 	&dev_attr_option_rom_version,
984 	&dev_attr_firmware_version,
985 	&dev_attr_number_of_ports,
986 	&dev_attr_driver_name,
987 	&dev_attr_number_of_discovered_ports,
988 	NULL,
989 };
990 
991 
992