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