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
bfad_im_get_starget_port_id(struct scsi_target * starget)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
bfad_im_get_starget_node_name(struct scsi_target * starget)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
bfad_im_get_starget_port_name(struct scsi_target * starget)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
bfad_im_get_host_port_id(struct Scsi_Host * shost)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
bfad_im_get_host_port_type(struct Scsi_Host * shost)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
bfad_im_get_host_port_state(struct Scsi_Host * shost)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
bfad_im_get_host_active_fc4s(struct Scsi_Host * shost)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
bfad_im_get_host_speed(struct Scsi_Host * shost)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
bfad_im_get_host_fabric_name(struct Scsi_Host * shost)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 *
bfad_im_get_stats(struct Scsi_Host * shost)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
bfad_im_reset_stats(struct Scsi_Host * shost)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
bfad_im_set_rport_loss_tmo(struct fc_rport * rport,u32 timeout)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
bfad_im_vport_create(struct fc_vport * fc_vport,bool disable)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
bfad_im_issue_fc_host_lip(struct Scsi_Host * shost)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
bfad_im_vport_delete(struct fc_vport * fc_vport)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
bfad_im_vport_disable(struct fc_vport * fc_vport,bool disable)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
bfad_im_vport_set_symbolic_name(struct fc_vport * fc_vport)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
bfad_im_serial_num_show(struct device * dev,struct device_attribute * attr,char * buf)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 sysfs_emit(buf, "%s\n", serial_num);
715  }
716  
717  static ssize_t
bfad_im_model_show(struct device * dev,struct device_attribute * attr,char * buf)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 sysfs_emit(buf, "%s\n", model);
729  }
730  
731  static ssize_t
bfad_im_model_desc_show(struct device * dev,struct device_attribute * attr,char * buf)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 sysfs_emit(buf, "%s\n", model_descr);
809  }
810  
811  static ssize_t
bfad_im_node_name_show(struct device * dev,struct device_attribute * attr,char * buf)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 sysfs_emit(buf, "0x%llx\n", cpu_to_be64(nwwn));
823  }
824  
825  static ssize_t
bfad_im_symbolic_name_show(struct device * dev,struct device_attribute * attr,char * buf)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  	strscpy(symname, port_attr.port_cfg.sym_name.symname,
838  			BFA_SYMNAME_MAXLEN);
839  	return sysfs_emit(buf, "%s\n", symname);
840  }
841  
842  static ssize_t
bfad_im_hw_version_show(struct device * dev,struct device_attribute * attr,char * buf)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 sysfs_emit(buf, "%s\n", hw_ver);
854  }
855  
856  static ssize_t
bfad_im_optionrom_version_show(struct device * dev,struct device_attribute * attr,char * buf)857  bfad_im_optionrom_version_show(struct device *dev,
858  			 struct device_attribute *attr, char *buf)
859  {
860  	struct Scsi_Host *shost = class_to_shost(dev);
861  	struct bfad_im_port_s *im_port =
862  			(struct bfad_im_port_s *) shost->hostdata[0];
863  	struct bfad_s *bfad = im_port->bfad;
864  	char optrom_ver[BFA_VERSION_LEN];
865  
866  	bfa_get_adapter_optrom_ver(&bfad->bfa, optrom_ver);
867  	return sysfs_emit(buf, "%s\n", optrom_ver);
868  }
869  
870  static ssize_t
bfad_im_fw_version_show(struct device * dev,struct device_attribute * attr,char * buf)871  bfad_im_fw_version_show(struct device *dev, struct device_attribute *attr,
872  				 char *buf)
873  {
874  	struct Scsi_Host *shost = class_to_shost(dev);
875  	struct bfad_im_port_s *im_port =
876  			(struct bfad_im_port_s *) shost->hostdata[0];
877  	struct bfad_s *bfad = im_port->bfad;
878  	char fw_ver[BFA_VERSION_LEN];
879  
880  	bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver);
881  	return sysfs_emit(buf, "%s\n", fw_ver);
882  }
883  
884  static ssize_t
bfad_im_num_of_ports_show(struct device * dev,struct device_attribute * attr,char * buf)885  bfad_im_num_of_ports_show(struct device *dev, struct device_attribute *attr,
886  				char *buf)
887  {
888  	struct Scsi_Host *shost = class_to_shost(dev);
889  	struct bfad_im_port_s *im_port =
890  			(struct bfad_im_port_s *) shost->hostdata[0];
891  	struct bfad_s *bfad = im_port->bfad;
892  
893  	return sysfs_emit(buf, "%d\n",
894  			bfa_get_nports(&bfad->bfa));
895  }
896  
897  static ssize_t
bfad_im_num_of_discovered_ports_show(struct device * dev,struct device_attribute * attr,char * buf)898  bfad_im_num_of_discovered_ports_show(struct device *dev,
899  			struct device_attribute *attr, char *buf)
900  {
901  	struct Scsi_Host *shost = class_to_shost(dev);
902  	struct bfad_im_port_s *im_port =
903  			(struct bfad_im_port_s *) shost->hostdata[0];
904  	struct bfad_port_s    *port = im_port->port;
905  	struct bfad_s         *bfad = im_port->bfad;
906  	int        nrports = 2048;
907  	struct bfa_rport_qualifier_s *rports = NULL;
908  	unsigned long   flags;
909  
910  	rports = kcalloc(nrports, sizeof(struct bfa_rport_qualifier_s),
911  			 GFP_ATOMIC);
912  	if (rports == NULL)
913  		return sysfs_emit(buf, "Failed\n");
914  
915  	spin_lock_irqsave(&bfad->bfad_lock, flags);
916  	bfa_fcs_lport_get_rport_quals(port->fcs_port, rports, &nrports);
917  	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
918  	kfree(rports);
919  
920  	return sysfs_emit(buf, "%d\n", nrports);
921  }
922  
923  static          DEVICE_ATTR(serial_number, S_IRUGO,
924  				bfad_im_serial_num_show, NULL);
925  static          DEVICE_ATTR(model, S_IRUGO, bfad_im_model_show, NULL);
926  static          DEVICE_ATTR(model_description, S_IRUGO,
927  				bfad_im_model_desc_show, NULL);
928  static          DEVICE_ATTR(node_name, S_IRUGO, bfad_im_node_name_show, NULL);
929  static          DEVICE_ATTR(symbolic_name, S_IRUGO,
930  				bfad_im_symbolic_name_show, NULL);
931  static          DEVICE_ATTR(hardware_version, S_IRUGO,
932  				bfad_im_hw_version_show, NULL);
933  static		DEVICE_STRING_ATTR_RO(driver_version, S_IRUGO,
934  				BFAD_DRIVER_VERSION);
935  static          DEVICE_ATTR(option_rom_version, S_IRUGO,
936  				bfad_im_optionrom_version_show, NULL);
937  static          DEVICE_ATTR(firmware_version, S_IRUGO,
938  				bfad_im_fw_version_show, NULL);
939  static          DEVICE_ATTR(number_of_ports, S_IRUGO,
940  				bfad_im_num_of_ports_show, NULL);
941  static		DEVICE_STRING_ATTR_RO(driver_name, S_IRUGO, BFAD_DRIVER_NAME);
942  static          DEVICE_ATTR(number_of_discovered_ports, S_IRUGO,
943  				bfad_im_num_of_discovered_ports_show, NULL);
944  
945  static struct attribute *bfad_im_host_attrs[] = {
946  	&dev_attr_serial_number.attr,
947  	&dev_attr_model.attr,
948  	&dev_attr_model_description.attr,
949  	&dev_attr_node_name.attr,
950  	&dev_attr_symbolic_name.attr,
951  	&dev_attr_hardware_version.attr,
952  	&dev_attr_driver_version.attr.attr,
953  	&dev_attr_option_rom_version.attr,
954  	&dev_attr_firmware_version.attr,
955  	&dev_attr_number_of_ports.attr,
956  	&dev_attr_driver_name.attr.attr,
957  	&dev_attr_number_of_discovered_ports.attr,
958  	NULL,
959  };
960  
961  static const struct attribute_group bfad_im_host_attr_group = {
962  	.attrs = bfad_im_host_attrs
963  };
964  
965  const struct attribute_group *bfad_im_host_groups[] = {
966  	&bfad_im_host_attr_group,
967  	NULL
968  };
969  
970  static struct attribute *bfad_im_vport_attrs[] = {
971  	&dev_attr_serial_number.attr,
972  	&dev_attr_model.attr,
973  	&dev_attr_model_description.attr,
974  	&dev_attr_node_name.attr,
975  	&dev_attr_symbolic_name.attr,
976  	&dev_attr_hardware_version.attr,
977  	&dev_attr_driver_version.attr.attr,
978  	&dev_attr_option_rom_version.attr,
979  	&dev_attr_firmware_version.attr,
980  	&dev_attr_number_of_ports.attr,
981  	&dev_attr_driver_name.attr.attr,
982  	&dev_attr_number_of_discovered_ports.attr,
983  	NULL,
984  };
985  
986  static const struct attribute_group bfad_im_vport_attr_group = {
987  	.attrs = bfad_im_vport_attrs
988  };
989  
990  const struct attribute_group *bfad_im_vport_groups[] = {
991  	&bfad_im_vport_attr_group,
992  	NULL
993  };
994