2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
19 * bfa_attr.c Linux driver configuration interface module.
24 #include "bfad_trcmod.h"
25 #include "bfad_attr.h"
28 * FC_transport_template FC transport template
32 * FC transport template entry, get SCSI target port ID.
35 bfad_im_get_starget_port_id(struct scsi_target
*starget
)
37 struct Scsi_Host
*shost
;
38 struct bfad_im_port_s
*im_port
;
40 struct bfad_itnim_s
*itnim
= NULL
;
44 shost
= bfad_os_starget_to_shost(starget
);
45 im_port
= (struct bfad_im_port_s
*) shost
->hostdata
[0];
47 spin_lock_irqsave(&bfad
->bfad_lock
, flags
);
49 itnim
= bfad_os_get_itnim(im_port
, starget
->id
);
51 fc_id
= bfa_fcs_itnim_get_fcid(&itnim
->fcs_itnim
);
53 fc_starget_port_id(starget
) = fc_id
;
54 spin_unlock_irqrestore(&bfad
->bfad_lock
, flags
);
58 * FC transport template entry, get SCSI target nwwn.
61 bfad_im_get_starget_node_name(struct scsi_target
*starget
)
63 struct Scsi_Host
*shost
;
64 struct bfad_im_port_s
*im_port
;
66 struct bfad_itnim_s
*itnim
= NULL
;
70 shost
= bfad_os_starget_to_shost(starget
);
71 im_port
= (struct bfad_im_port_s
*) shost
->hostdata
[0];
73 spin_lock_irqsave(&bfad
->bfad_lock
, flags
);
75 itnim
= bfad_os_get_itnim(im_port
, starget
->id
);
77 node_name
= bfa_fcs_itnim_get_nwwn(&itnim
->fcs_itnim
);
79 fc_starget_node_name(starget
) = bfa_os_htonll(node_name
);
80 spin_unlock_irqrestore(&bfad
->bfad_lock
, flags
);
84 * FC transport template entry, get SCSI target pwwn.
87 bfad_im_get_starget_port_name(struct scsi_target
*starget
)
89 struct Scsi_Host
*shost
;
90 struct bfad_im_port_s
*im_port
;
92 struct bfad_itnim_s
*itnim
= NULL
;
96 shost
= bfad_os_starget_to_shost(starget
);
97 im_port
= (struct bfad_im_port_s
*) shost
->hostdata
[0];
99 spin_lock_irqsave(&bfad
->bfad_lock
, flags
);
101 itnim
= bfad_os_get_itnim(im_port
, starget
->id
);
103 port_name
= bfa_fcs_itnim_get_pwwn(&itnim
->fcs_itnim
);
105 fc_starget_port_name(starget
) = bfa_os_htonll(port_name
);
106 spin_unlock_irqrestore(&bfad
->bfad_lock
, flags
);
110 * FC transport template entry, get SCSI host port ID.
113 bfad_im_get_host_port_id(struct Scsi_Host
*shost
)
115 struct bfad_im_port_s
*im_port
=
116 (struct bfad_im_port_s
*) shost
->hostdata
[0];
117 struct bfad_port_s
*port
= im_port
->port
;
119 fc_host_port_id(shost
) =
120 bfa_os_hton3b(bfa_fcs_port_get_fcid(port
->fcs_port
));
128 bfad_os_starget_to_shost(struct scsi_target
*starget
)
130 return dev_to_shost(starget
->dev
.parent
);
134 * FC transport template entry, get SCSI host port type.
137 bfad_im_get_host_port_type(struct Scsi_Host
*shost
)
139 struct bfad_im_port_s
*im_port
=
140 (struct bfad_im_port_s
*) shost
->hostdata
[0];
141 struct bfad_s
*bfad
= im_port
->bfad
;
142 struct bfa_pport_attr_s attr
;
144 bfa_pport_get_attr(&bfad
->bfa
, &attr
);
146 switch (attr
.port_type
) {
147 case BFA_PPORT_TYPE_NPORT
:
148 fc_host_port_type(shost
) = FC_PORTTYPE_NPORT
;
150 case BFA_PPORT_TYPE_NLPORT
:
151 fc_host_port_type(shost
) = FC_PORTTYPE_NLPORT
;
153 case BFA_PPORT_TYPE_P2P
:
154 fc_host_port_type(shost
) = FC_PORTTYPE_PTP
;
156 case BFA_PPORT_TYPE_LPORT
:
157 fc_host_port_type(shost
) = FC_PORTTYPE_LPORT
;
160 fc_host_port_type(shost
) = FC_PORTTYPE_UNKNOWN
;
166 * FC transport template entry, get SCSI host port state.
169 bfad_im_get_host_port_state(struct Scsi_Host
*shost
)
171 struct bfad_im_port_s
*im_port
=
172 (struct bfad_im_port_s
*) shost
->hostdata
[0];
173 struct bfad_s
*bfad
= im_port
->bfad
;
174 struct bfa_pport_attr_s attr
;
176 bfa_pport_get_attr(&bfad
->bfa
, &attr
);
178 switch (attr
.port_state
) {
179 case BFA_PPORT_ST_LINKDOWN
:
180 fc_host_port_state(shost
) = FC_PORTSTATE_LINKDOWN
;
182 case BFA_PPORT_ST_LINKUP
:
183 fc_host_port_state(shost
) = FC_PORTSTATE_ONLINE
;
185 case BFA_PPORT_ST_UNINIT
:
186 case BFA_PPORT_ST_ENABLING_QWAIT
:
187 case BFA_PPORT_ST_ENABLING
:
188 case BFA_PPORT_ST_DISABLING_QWAIT
:
189 case BFA_PPORT_ST_DISABLING
:
190 case BFA_PPORT_ST_DISABLED
:
191 case BFA_PPORT_ST_STOPPED
:
192 case BFA_PPORT_ST_IOCDOWN
:
194 fc_host_port_state(shost
) = FC_PORTSTATE_UNKNOWN
;
200 * FC transport template entry, get SCSI host active fc4s.
203 bfad_im_get_host_active_fc4s(struct Scsi_Host
*shost
)
205 struct bfad_im_port_s
*im_port
=
206 (struct bfad_im_port_s
*) shost
->hostdata
[0];
207 struct bfad_port_s
*port
= im_port
->port
;
209 memset(fc_host_active_fc4s(shost
), 0,
210 sizeof(fc_host_active_fc4s(shost
)));
212 if (port
->supported_fc4s
&
213 (BFA_PORT_ROLE_FCP_IM
| BFA_PORT_ROLE_FCP_TM
))
214 fc_host_active_fc4s(shost
)[2] = 1;
216 if (port
->supported_fc4s
& BFA_PORT_ROLE_FCP_IPFC
)
217 fc_host_active_fc4s(shost
)[3] = 0x20;
219 fc_host_active_fc4s(shost
)[7] = 1;
223 * FC transport template entry, get SCSI host link speed.
226 bfad_im_get_host_speed(struct Scsi_Host
*shost
)
228 struct bfad_im_port_s
*im_port
=
229 (struct bfad_im_port_s
*) shost
->hostdata
[0];
230 struct bfad_s
*bfad
= im_port
->bfad
;
231 struct bfa_pport_attr_s attr
;
233 bfa_pport_get_attr(&bfad
->bfa
, &attr
);
234 switch (attr
.speed
) {
235 case BFA_PPORT_SPEED_8GBPS
:
236 fc_host_speed(shost
) = FC_PORTSPEED_8GBIT
;
238 case BFA_PPORT_SPEED_4GBPS
:
239 fc_host_speed(shost
) = FC_PORTSPEED_4GBIT
;
241 case BFA_PPORT_SPEED_2GBPS
:
242 fc_host_speed(shost
) = FC_PORTSPEED_2GBIT
;
244 case BFA_PPORT_SPEED_1GBPS
:
245 fc_host_speed(shost
) = FC_PORTSPEED_1GBIT
;
248 fc_host_speed(shost
) = FC_PORTSPEED_UNKNOWN
;
254 * FC transport template entry, get SCSI host port type.
257 bfad_im_get_host_fabric_name(struct Scsi_Host
*shost
)
259 struct bfad_im_port_s
*im_port
=
260 (struct bfad_im_port_s
*) shost
->hostdata
[0];
261 struct bfad_port_s
*port
= im_port
->port
;
262 wwn_t fabric_nwwn
= 0;
264 fabric_nwwn
= bfa_fcs_port_get_fabric_name(port
->fcs_port
);
266 fc_host_fabric_name(shost
) = bfa_os_htonll(fabric_nwwn
);
271 * FC transport template entry, get BFAD statistics.
273 static struct fc_host_statistics
*
274 bfad_im_get_stats(struct Scsi_Host
*shost
)
276 struct bfad_im_port_s
*im_port
=
277 (struct bfad_im_port_s
*) shost
->hostdata
[0];
278 struct bfad_s
*bfad
= im_port
->bfad
;
279 struct bfad_hal_comp fcomp
;
280 struct fc_host_statistics
*hstats
;
284 hstats
= &bfad
->link_stats
;
285 init_completion(&fcomp
.comp
);
286 spin_lock_irqsave(&bfad
->bfad_lock
, flags
);
287 memset(hstats
, 0, sizeof(struct fc_host_statistics
));
288 rc
= bfa_pport_get_stats(&bfad
->bfa
,
289 (union bfa_pport_stats_u
*) hstats
,
290 bfad_hcb_comp
, &fcomp
);
291 spin_unlock_irqrestore(&bfad
->bfad_lock
, flags
);
292 if (rc
!= BFA_STATUS_OK
)
295 wait_for_completion(&fcomp
.comp
);
301 * FC transport template entry, reset BFAD statistics.
304 bfad_im_reset_stats(struct Scsi_Host
*shost
)
306 struct bfad_im_port_s
*im_port
=
307 (struct bfad_im_port_s
*) shost
->hostdata
[0];
308 struct bfad_s
*bfad
= im_port
->bfad
;
309 struct bfad_hal_comp fcomp
;
313 init_completion(&fcomp
.comp
);
314 spin_lock_irqsave(&bfad
->bfad_lock
, flags
);
315 rc
= bfa_pport_clear_stats(&bfad
->bfa
, bfad_hcb_comp
, &fcomp
);
316 spin_unlock_irqrestore(&bfad
->bfad_lock
, flags
);
318 if (rc
!= BFA_STATUS_OK
)
321 wait_for_completion(&fcomp
.comp
);
327 * FC transport template entry, get rport loss timeout.
330 bfad_im_get_rport_loss_tmo(struct fc_rport
*rport
)
332 struct bfad_itnim_data_s
*itnim_data
= rport
->dd_data
;
333 struct bfad_itnim_s
*itnim
= itnim_data
->itnim
;
334 struct bfad_s
*bfad
= itnim
->im
->bfad
;
337 spin_lock_irqsave(&bfad
->bfad_lock
, flags
);
338 rport
->dev_loss_tmo
= bfa_fcpim_path_tov_get(&bfad
->bfa
);
339 spin_unlock_irqrestore(&bfad
->bfad_lock
, flags
);
343 * FC transport template entry, set rport loss timeout.
346 bfad_im_set_rport_loss_tmo(struct fc_rport
*rport
, u32 timeout
)
348 struct bfad_itnim_data_s
*itnim_data
= rport
->dd_data
;
349 struct bfad_itnim_s
*itnim
= itnim_data
->itnim
;
350 struct bfad_s
*bfad
= itnim
->im
->bfad
;
354 spin_lock_irqsave(&bfad
->bfad_lock
, flags
);
355 bfa_fcpim_path_tov_set(&bfad
->bfa
, timeout
);
356 rport
->dev_loss_tmo
= bfa_fcpim_path_tov_get(&bfad
->bfa
);
357 spin_unlock_irqrestore(&bfad
->bfad_lock
, flags
);
362 struct fc_function_template bfad_im_fc_function_template
= {
364 /* Target dynamic attributes */
365 .get_starget_port_id
= bfad_im_get_starget_port_id
,
366 .show_starget_port_id
= 1,
367 .get_starget_node_name
= bfad_im_get_starget_node_name
,
368 .show_starget_node_name
= 1,
369 .get_starget_port_name
= bfad_im_get_starget_port_name
,
370 .show_starget_port_name
= 1,
372 /* Host dynamic attribute */
373 .get_host_port_id
= bfad_im_get_host_port_id
,
374 .show_host_port_id
= 1,
376 /* Host fixed attributes */
377 .show_host_node_name
= 1,
378 .show_host_port_name
= 1,
379 .show_host_supported_classes
= 1,
380 .show_host_supported_fc4s
= 1,
381 .show_host_supported_speeds
= 1,
382 .show_host_maxframe_size
= 1,
384 /* More host dynamic attributes */
385 .show_host_port_type
= 1,
386 .get_host_port_type
= bfad_im_get_host_port_type
,
387 .show_host_port_state
= 1,
388 .get_host_port_state
= bfad_im_get_host_port_state
,
389 .show_host_active_fc4s
= 1,
390 .get_host_active_fc4s
= bfad_im_get_host_active_fc4s
,
391 .show_host_speed
= 1,
392 .get_host_speed
= bfad_im_get_host_speed
,
393 .show_host_fabric_name
= 1,
394 .get_host_fabric_name
= bfad_im_get_host_fabric_name
,
396 .show_host_symbolic_name
= 1,
399 .get_fc_host_stats
= bfad_im_get_stats
,
400 .reset_fc_host_stats
= bfad_im_reset_stats
,
402 /* Allocation length for host specific data */
403 .dd_fcrport_size
= sizeof(struct bfad_itnim_data_s
*),
405 /* Remote port fixed attributes */
406 .show_rport_maxframe_size
= 1,
407 .show_rport_supported_classes
= 1,
408 .show_rport_dev_loss_tmo
= 1,
409 .get_rport_dev_loss_tmo
= bfad_im_get_rport_loss_tmo
,
410 .set_rport_dev_loss_tmo
= bfad_im_set_rport_loss_tmo
,
414 * Scsi_Host_attrs SCSI host attributes
417 bfad_im_serial_num_show(struct device
*dev
, struct device_attribute
*attr
,
420 struct Scsi_Host
*shost
= class_to_shost(dev
);
421 struct bfad_im_port_s
*im_port
=
422 (struct bfad_im_port_s
*) shost
->hostdata
[0];
423 struct bfad_s
*bfad
= im_port
->bfad
;
424 struct bfa_ioc_attr_s ioc_attr
;
426 memset(&ioc_attr
, 0, sizeof(ioc_attr
));
427 bfa_get_attr(&bfad
->bfa
, &ioc_attr
);
428 return snprintf(buf
, PAGE_SIZE
, "%s\n",
429 ioc_attr
.adapter_attr
.serial_num
);
433 bfad_im_model_show(struct device
*dev
, struct device_attribute
*attr
,
436 struct Scsi_Host
*shost
= class_to_shost(dev
);
437 struct bfad_im_port_s
*im_port
=
438 (struct bfad_im_port_s
*) shost
->hostdata
[0];
439 struct bfad_s
*bfad
= im_port
->bfad
;
440 struct bfa_ioc_attr_s ioc_attr
;
442 memset(&ioc_attr
, 0, sizeof(ioc_attr
));
443 bfa_get_attr(&bfad
->bfa
, &ioc_attr
);
444 return snprintf(buf
, PAGE_SIZE
, "%s\n", ioc_attr
.adapter_attr
.model
);
448 bfad_im_model_desc_show(struct device
*dev
, struct device_attribute
*attr
,
451 struct Scsi_Host
*shost
= class_to_shost(dev
);
452 struct bfad_im_port_s
*im_port
=
453 (struct bfad_im_port_s
*) shost
->hostdata
[0];
454 struct bfad_s
*bfad
= im_port
->bfad
;
455 struct bfa_ioc_attr_s ioc_attr
;
457 memset(&ioc_attr
, 0, sizeof(ioc_attr
));
458 bfa_get_attr(&bfad
->bfa
, &ioc_attr
);
459 return snprintf(buf
, PAGE_SIZE
, "%s\n",
460 ioc_attr
.adapter_attr
.model_descr
);
464 bfad_im_node_name_show(struct device
*dev
, struct device_attribute
*attr
,
467 struct Scsi_Host
*shost
= class_to_shost(dev
);
468 struct bfad_im_port_s
*im_port
=
469 (struct bfad_im_port_s
*) shost
->hostdata
[0];
470 struct bfad_port_s
*port
= im_port
->port
;
473 nwwn
= bfa_fcs_port_get_nwwn(port
->fcs_port
);
474 return snprintf(buf
, PAGE_SIZE
, "0x%llx\n", bfa_os_htonll(nwwn
));
478 bfad_im_symbolic_name_show(struct device
*dev
, struct device_attribute
*attr
,
481 struct Scsi_Host
*shost
= class_to_shost(dev
);
482 struct bfad_im_port_s
*im_port
=
483 (struct bfad_im_port_s
*) shost
->hostdata
[0];
484 struct bfad_s
*bfad
= im_port
->bfad
;
485 struct bfa_ioc_attr_s ioc_attr
;
487 memset(&ioc_attr
, 0, sizeof(ioc_attr
));
488 bfa_get_attr(&bfad
->bfa
, &ioc_attr
);
490 return snprintf(buf
, PAGE_SIZE
, "Brocade %s FV%s DV%s\n",
491 ioc_attr
.adapter_attr
.model
,
492 ioc_attr
.adapter_attr
.fw_ver
, BFAD_DRIVER_VERSION
);
496 bfad_im_hw_version_show(struct device
*dev
, struct device_attribute
*attr
,
499 struct Scsi_Host
*shost
= class_to_shost(dev
);
500 struct bfad_im_port_s
*im_port
=
501 (struct bfad_im_port_s
*) shost
->hostdata
[0];
502 struct bfad_s
*bfad
= im_port
->bfad
;
503 struct bfa_ioc_attr_s ioc_attr
;
505 memset(&ioc_attr
, 0, sizeof(ioc_attr
));
506 bfa_get_attr(&bfad
->bfa
, &ioc_attr
);
507 return snprintf(buf
, PAGE_SIZE
, "%s\n", ioc_attr
.adapter_attr
.hw_ver
);
511 bfad_im_drv_version_show(struct device
*dev
, struct device_attribute
*attr
,
514 return snprintf(buf
, PAGE_SIZE
, "%s\n", BFAD_DRIVER_VERSION
);
518 bfad_im_optionrom_version_show(struct device
*dev
,
519 struct device_attribute
*attr
, char *buf
)
521 struct Scsi_Host
*shost
= class_to_shost(dev
);
522 struct bfad_im_port_s
*im_port
=
523 (struct bfad_im_port_s
*) shost
->hostdata
[0];
524 struct bfad_s
*bfad
= im_port
->bfad
;
525 struct bfa_ioc_attr_s ioc_attr
;
527 memset(&ioc_attr
, 0, sizeof(ioc_attr
));
528 bfa_get_attr(&bfad
->bfa
, &ioc_attr
);
529 return snprintf(buf
, PAGE_SIZE
, "%s\n",
530 ioc_attr
.adapter_attr
.optrom_ver
);
534 bfad_im_fw_version_show(struct device
*dev
, struct device_attribute
*attr
,
537 struct Scsi_Host
*shost
= class_to_shost(dev
);
538 struct bfad_im_port_s
*im_port
=
539 (struct bfad_im_port_s
*) shost
->hostdata
[0];
540 struct bfad_s
*bfad
= im_port
->bfad
;
541 struct bfa_ioc_attr_s ioc_attr
;
543 memset(&ioc_attr
, 0, sizeof(ioc_attr
));
544 bfa_get_attr(&bfad
->bfa
, &ioc_attr
);
545 return snprintf(buf
, PAGE_SIZE
, "%s\n", ioc_attr
.adapter_attr
.fw_ver
);
549 bfad_im_num_of_ports_show(struct device
*dev
, struct device_attribute
*attr
,
552 struct Scsi_Host
*shost
= class_to_shost(dev
);
553 struct bfad_im_port_s
*im_port
=
554 (struct bfad_im_port_s
*) shost
->hostdata
[0];
555 struct bfad_s
*bfad
= im_port
->bfad
;
556 struct bfa_ioc_attr_s ioc_attr
;
558 memset(&ioc_attr
, 0, sizeof(ioc_attr
));
559 bfa_get_attr(&bfad
->bfa
, &ioc_attr
);
560 return snprintf(buf
, PAGE_SIZE
, "%d\n", ioc_attr
.adapter_attr
.nports
);
564 bfad_im_drv_name_show(struct device
*dev
, struct device_attribute
*attr
,
567 return snprintf(buf
, PAGE_SIZE
, "%s\n", BFAD_DRIVER_NAME
);
571 bfad_im_num_of_discovered_ports_show(struct device
*dev
,
572 struct device_attribute
*attr
, char *buf
)
574 struct Scsi_Host
*shost
= class_to_shost(dev
);
575 struct bfad_im_port_s
*im_port
=
576 (struct bfad_im_port_s
*) shost
->hostdata
[0];
577 struct bfad_port_s
*port
= im_port
->port
;
578 struct bfad_s
*bfad
= im_port
->bfad
;
580 wwn_t
*rports
= NULL
;
583 rports
= kzalloc(sizeof(wwn_t
) * nrports
, GFP_ATOMIC
);
587 spin_lock_irqsave(&bfad
->bfad_lock
, flags
);
588 bfa_fcs_port_get_rports(port
->fcs_port
, rports
, &nrports
);
589 spin_unlock_irqrestore(&bfad
->bfad_lock
, flags
);
592 return snprintf(buf
, PAGE_SIZE
, "%d\n", nrports
);
595 static DEVICE_ATTR(serial_number
, S_IRUGO
,
596 bfad_im_serial_num_show
, NULL
);
597 static DEVICE_ATTR(model
, S_IRUGO
, bfad_im_model_show
, NULL
);
598 static DEVICE_ATTR(model_description
, S_IRUGO
,
599 bfad_im_model_desc_show
, NULL
);
600 static DEVICE_ATTR(node_name
, S_IRUGO
, bfad_im_node_name_show
, NULL
);
601 static DEVICE_ATTR(symbolic_name
, S_IRUGO
,
602 bfad_im_symbolic_name_show
, NULL
);
603 static DEVICE_ATTR(hardware_version
, S_IRUGO
,
604 bfad_im_hw_version_show
, NULL
);
605 static DEVICE_ATTR(driver_version
, S_IRUGO
,
606 bfad_im_drv_version_show
, NULL
);
607 static DEVICE_ATTR(option_rom_version
, S_IRUGO
,
608 bfad_im_optionrom_version_show
, NULL
);
609 static DEVICE_ATTR(firmware_version
, S_IRUGO
,
610 bfad_im_fw_version_show
, NULL
);
611 static DEVICE_ATTR(number_of_ports
, S_IRUGO
,
612 bfad_im_num_of_ports_show
, NULL
);
613 static DEVICE_ATTR(driver_name
, S_IRUGO
, bfad_im_drv_name_show
, NULL
);
614 static DEVICE_ATTR(number_of_discovered_ports
, S_IRUGO
,
615 bfad_im_num_of_discovered_ports_show
, NULL
);
617 struct device_attribute
*bfad_im_host_attrs
[] = {
618 &dev_attr_serial_number
,
620 &dev_attr_model_description
,
622 &dev_attr_symbolic_name
,
623 &dev_attr_hardware_version
,
624 &dev_attr_driver_version
,
625 &dev_attr_option_rom_version
,
626 &dev_attr_firmware_version
,
627 &dev_attr_number_of_ports
,
628 &dev_attr_driver_name
,
629 &dev_attr_number_of_discovered_ports
,
633 struct device_attribute
*bfad_im_vport_attrs
[] = {
634 &dev_attr_serial_number
,
636 &dev_attr_model_description
,
638 &dev_attr_symbolic_name
,
639 &dev_attr_hardware_version
,
640 &dev_attr_driver_version
,
641 &dev_attr_option_rom_version
,
642 &dev_attr_firmware_version
,
643 &dev_attr_number_of_ports
,
644 &dev_attr_driver_name
,
645 &dev_attr_number_of_discovered_ports
,