0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include "bfad_drv.h"
0016 #include "bfad_im.h"
0017
0018
0019
0020
0021 static void
0022 bfad_im_get_starget_port_id(struct scsi_target *starget)
0023 {
0024 struct Scsi_Host *shost;
0025 struct bfad_im_port_s *im_port;
0026 struct bfad_s *bfad;
0027 struct bfad_itnim_s *itnim = NULL;
0028 u32 fc_id = -1;
0029 unsigned long flags;
0030
0031 shost = dev_to_shost(starget->dev.parent);
0032 im_port = (struct bfad_im_port_s *) shost->hostdata[0];
0033 bfad = im_port->bfad;
0034 spin_lock_irqsave(&bfad->bfad_lock, flags);
0035
0036 itnim = bfad_get_itnim(im_port, starget->id);
0037 if (itnim)
0038 fc_id = bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim);
0039
0040 fc_starget_port_id(starget) = fc_id;
0041 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
0042 }
0043
0044
0045
0046
0047 static void
0048 bfad_im_get_starget_node_name(struct scsi_target *starget)
0049 {
0050 struct Scsi_Host *shost;
0051 struct bfad_im_port_s *im_port;
0052 struct bfad_s *bfad;
0053 struct bfad_itnim_s *itnim = NULL;
0054 u64 node_name = 0;
0055 unsigned long flags;
0056
0057 shost = dev_to_shost(starget->dev.parent);
0058 im_port = (struct bfad_im_port_s *) shost->hostdata[0];
0059 bfad = im_port->bfad;
0060 spin_lock_irqsave(&bfad->bfad_lock, flags);
0061
0062 itnim = bfad_get_itnim(im_port, starget->id);
0063 if (itnim)
0064 node_name = bfa_fcs_itnim_get_nwwn(&itnim->fcs_itnim);
0065
0066 fc_starget_node_name(starget) = cpu_to_be64(node_name);
0067 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
0068 }
0069
0070
0071
0072
0073 static void
0074 bfad_im_get_starget_port_name(struct scsi_target *starget)
0075 {
0076 struct Scsi_Host *shost;
0077 struct bfad_im_port_s *im_port;
0078 struct bfad_s *bfad;
0079 struct bfad_itnim_s *itnim = NULL;
0080 u64 port_name = 0;
0081 unsigned long flags;
0082
0083 shost = dev_to_shost(starget->dev.parent);
0084 im_port = (struct bfad_im_port_s *) shost->hostdata[0];
0085 bfad = im_port->bfad;
0086 spin_lock_irqsave(&bfad->bfad_lock, flags);
0087
0088 itnim = bfad_get_itnim(im_port, starget->id);
0089 if (itnim)
0090 port_name = bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim);
0091
0092 fc_starget_port_name(starget) = cpu_to_be64(port_name);
0093 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
0094 }
0095
0096
0097
0098
0099 static void
0100 bfad_im_get_host_port_id(struct Scsi_Host *shost)
0101 {
0102 struct bfad_im_port_s *im_port =
0103 (struct bfad_im_port_s *) shost->hostdata[0];
0104 struct bfad_port_s *port = im_port->port;
0105
0106 fc_host_port_id(shost) =
0107 bfa_hton3b(bfa_fcs_lport_get_fcid(port->fcs_port));
0108 }
0109
0110
0111
0112
0113 static void
0114 bfad_im_get_host_port_type(struct Scsi_Host *shost)
0115 {
0116 struct bfad_im_port_s *im_port =
0117 (struct bfad_im_port_s *) shost->hostdata[0];
0118 struct bfad_s *bfad = im_port->bfad;
0119 struct bfa_lport_attr_s port_attr;
0120
0121 bfa_fcs_lport_get_attr(&bfad->bfa_fcs.fabric.bport, &port_attr);
0122
0123 switch (port_attr.port_type) {
0124 case BFA_PORT_TYPE_NPORT:
0125 fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
0126 break;
0127 case BFA_PORT_TYPE_NLPORT:
0128 fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
0129 break;
0130 case BFA_PORT_TYPE_P2P:
0131 fc_host_port_type(shost) = FC_PORTTYPE_PTP;
0132 break;
0133 case BFA_PORT_TYPE_LPORT:
0134 fc_host_port_type(shost) = FC_PORTTYPE_LPORT;
0135 break;
0136 default:
0137 fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
0138 break;
0139 }
0140 }
0141
0142
0143
0144
0145 static void
0146 bfad_im_get_host_port_state(struct Scsi_Host *shost)
0147 {
0148 struct bfad_im_port_s *im_port =
0149 (struct bfad_im_port_s *) shost->hostdata[0];
0150 struct bfad_s *bfad = im_port->bfad;
0151 struct bfa_port_attr_s attr;
0152
0153 bfa_fcport_get_attr(&bfad->bfa, &attr);
0154
0155 switch (attr.port_state) {
0156 case BFA_PORT_ST_LINKDOWN:
0157 fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN;
0158 break;
0159 case BFA_PORT_ST_LINKUP:
0160 fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
0161 break;
0162 case BFA_PORT_ST_DISABLED:
0163 case BFA_PORT_ST_STOPPED:
0164 case BFA_PORT_ST_IOCDOWN:
0165 case BFA_PORT_ST_IOCDIS:
0166 fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE;
0167 break;
0168 case BFA_PORT_ST_UNINIT:
0169 case BFA_PORT_ST_ENABLING_QWAIT:
0170 case BFA_PORT_ST_ENABLING:
0171 case BFA_PORT_ST_DISABLING_QWAIT:
0172 case BFA_PORT_ST_DISABLING:
0173 default:
0174 fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN;
0175 break;
0176 }
0177 }
0178
0179
0180
0181
0182 static void
0183 bfad_im_get_host_active_fc4s(struct Scsi_Host *shost)
0184 {
0185 struct bfad_im_port_s *im_port =
0186 (struct bfad_im_port_s *) shost->hostdata[0];
0187 struct bfad_port_s *port = im_port->port;
0188
0189 memset(fc_host_active_fc4s(shost), 0,
0190 sizeof(fc_host_active_fc4s(shost)));
0191
0192 if (port->supported_fc4s & BFA_LPORT_ROLE_FCP_IM)
0193 fc_host_active_fc4s(shost)[2] = 1;
0194
0195 fc_host_active_fc4s(shost)[7] = 1;
0196 }
0197
0198
0199
0200
0201 static void
0202 bfad_im_get_host_speed(struct Scsi_Host *shost)
0203 {
0204 struct bfad_im_port_s *im_port =
0205 (struct bfad_im_port_s *) shost->hostdata[0];
0206 struct bfad_s *bfad = im_port->bfad;
0207 struct bfa_port_attr_s attr;
0208
0209 bfa_fcport_get_attr(&bfad->bfa, &attr);
0210 switch (attr.speed) {
0211 case BFA_PORT_SPEED_10GBPS:
0212 fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
0213 break;
0214 case BFA_PORT_SPEED_16GBPS:
0215 fc_host_speed(shost) = FC_PORTSPEED_16GBIT;
0216 break;
0217 case BFA_PORT_SPEED_8GBPS:
0218 fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
0219 break;
0220 case BFA_PORT_SPEED_4GBPS:
0221 fc_host_speed(shost) = FC_PORTSPEED_4GBIT;
0222 break;
0223 case BFA_PORT_SPEED_2GBPS:
0224 fc_host_speed(shost) = FC_PORTSPEED_2GBIT;
0225 break;
0226 case BFA_PORT_SPEED_1GBPS:
0227 fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
0228 break;
0229 default:
0230 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
0231 break;
0232 }
0233 }
0234
0235
0236
0237
0238 static void
0239 bfad_im_get_host_fabric_name(struct Scsi_Host *shost)
0240 {
0241 struct bfad_im_port_s *im_port =
0242 (struct bfad_im_port_s *) shost->hostdata[0];
0243 struct bfad_port_s *port = im_port->port;
0244 wwn_t fabric_nwwn = 0;
0245
0246 fabric_nwwn = bfa_fcs_lport_get_fabric_name(port->fcs_port);
0247
0248 fc_host_fabric_name(shost) = cpu_to_be64(fabric_nwwn);
0249
0250 }
0251
0252
0253
0254
0255 static struct fc_host_statistics *
0256 bfad_im_get_stats(struct Scsi_Host *shost)
0257 {
0258 struct bfad_im_port_s *im_port =
0259 (struct bfad_im_port_s *) shost->hostdata[0];
0260 struct bfad_s *bfad = im_port->bfad;
0261 struct bfad_hal_comp fcomp;
0262 union bfa_port_stats_u *fcstats;
0263 struct fc_host_statistics *hstats;
0264 bfa_status_t rc;
0265 unsigned long flags;
0266
0267 fcstats = kzalloc(sizeof(union bfa_port_stats_u), GFP_KERNEL);
0268 if (fcstats == NULL)
0269 return NULL;
0270
0271 hstats = &bfad->link_stats;
0272 init_completion(&fcomp.comp);
0273 spin_lock_irqsave(&bfad->bfad_lock, flags);
0274 memset(hstats, 0, sizeof(struct fc_host_statistics));
0275 rc = bfa_port_get_stats(BFA_FCPORT(&bfad->bfa),
0276 fcstats, bfad_hcb_comp, &fcomp);
0277 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
0278 if (rc != BFA_STATUS_OK) {
0279 kfree(fcstats);
0280 return NULL;
0281 }
0282
0283 wait_for_completion(&fcomp.comp);
0284
0285
0286 hstats->seconds_since_last_reset = fcstats->fc.secs_reset;
0287 hstats->tx_frames = fcstats->fc.tx_frames;
0288 hstats->tx_words = fcstats->fc.tx_words;
0289 hstats->rx_frames = fcstats->fc.rx_frames;
0290 hstats->rx_words = fcstats->fc.rx_words;
0291 hstats->lip_count = fcstats->fc.lip_count;
0292 hstats->nos_count = fcstats->fc.nos_count;
0293 hstats->error_frames = fcstats->fc.error_frames;
0294 hstats->dumped_frames = fcstats->fc.dropped_frames;
0295 hstats->link_failure_count = fcstats->fc.link_failures;
0296 hstats->loss_of_sync_count = fcstats->fc.loss_of_syncs;
0297 hstats->loss_of_signal_count = fcstats->fc.loss_of_signals;
0298 hstats->prim_seq_protocol_err_count = fcstats->fc.primseq_errs;
0299 hstats->invalid_crc_count = fcstats->fc.invalid_crcs;
0300
0301 kfree(fcstats);
0302 return hstats;
0303 }
0304
0305
0306
0307
0308 static void
0309 bfad_im_reset_stats(struct Scsi_Host *shost)
0310 {
0311 struct bfad_im_port_s *im_port =
0312 (struct bfad_im_port_s *) shost->hostdata[0];
0313 struct bfad_s *bfad = im_port->bfad;
0314 struct bfad_hal_comp fcomp;
0315 unsigned long flags;
0316 bfa_status_t rc;
0317
0318 init_completion(&fcomp.comp);
0319 spin_lock_irqsave(&bfad->bfad_lock, flags);
0320 rc = bfa_port_clear_stats(BFA_FCPORT(&bfad->bfa), bfad_hcb_comp,
0321 &fcomp);
0322 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
0323
0324 if (rc != BFA_STATUS_OK)
0325 return;
0326
0327 wait_for_completion(&fcomp.comp);
0328
0329 return;
0330 }
0331
0332
0333
0334
0335
0336
0337
0338 static void
0339 bfad_im_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout)
0340 {
0341 struct bfad_itnim_data_s *itnim_data = rport->dd_data;
0342 struct bfad_itnim_s *itnim = itnim_data->itnim;
0343 struct bfad_s *bfad = itnim->im->bfad;
0344 uint16_t path_tov = bfa_fcpim_path_tov_get(&bfad->bfa);
0345
0346 rport->dev_loss_tmo = timeout;
0347 if (timeout < path_tov)
0348 rport->dev_loss_tmo = path_tov + 1;
0349 }
0350
0351 static int
0352 bfad_im_vport_create(struct fc_vport *fc_vport, bool disable)
0353 {
0354 char *vname = fc_vport->symbolic_name;
0355 struct Scsi_Host *shost = fc_vport->shost;
0356 struct bfad_im_port_s *im_port =
0357 (struct bfad_im_port_s *) shost->hostdata[0];
0358 struct bfad_s *bfad = im_port->bfad;
0359 struct bfa_lport_cfg_s port_cfg;
0360 struct bfad_vport_s *vp;
0361 int status = 0, rc;
0362 unsigned long flags;
0363
0364 memset(&port_cfg, 0, sizeof(port_cfg));
0365 u64_to_wwn(fc_vport->node_name, (u8 *)&port_cfg.nwwn);
0366 u64_to_wwn(fc_vport->port_name, (u8 *)&port_cfg.pwwn);
0367 if (strlen(vname) > 0)
0368 strcpy((char *)&port_cfg.sym_name, vname);
0369 port_cfg.roles = BFA_LPORT_ROLE_FCP_IM;
0370
0371 spin_lock_irqsave(&bfad->bfad_lock, flags);
0372 list_for_each_entry(vp, &bfad->pbc_vport_list, list_entry) {
0373 if (port_cfg.pwwn ==
0374 vp->fcs_vport.lport.port_cfg.pwwn) {
0375 port_cfg.preboot_vp =
0376 vp->fcs_vport.lport.port_cfg.preboot_vp;
0377 break;
0378 }
0379 }
0380 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
0381
0382 rc = bfad_vport_create(bfad, 0, &port_cfg, &fc_vport->dev);
0383 if (rc == BFA_STATUS_OK) {
0384 struct bfad_vport_s *vport;
0385 struct bfa_fcs_vport_s *fcs_vport;
0386 struct Scsi_Host *vshost;
0387
0388 spin_lock_irqsave(&bfad->bfad_lock, flags);
0389 fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0,
0390 port_cfg.pwwn);
0391 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
0392 if (fcs_vport == NULL)
0393 return VPCERR_BAD_WWN;
0394
0395 fc_vport_set_state(fc_vport, FC_VPORT_ACTIVE);
0396 if (disable) {
0397 spin_lock_irqsave(&bfad->bfad_lock, flags);
0398 bfa_fcs_vport_stop(fcs_vport);
0399 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
0400 fc_vport_set_state(fc_vport, FC_VPORT_DISABLED);
0401 }
0402
0403 vport = fcs_vport->vport_drv;
0404 vshost = vport->drv_port.im_port->shost;
0405 fc_host_node_name(vshost) = wwn_to_u64((u8 *)&port_cfg.nwwn);
0406 fc_host_port_name(vshost) = wwn_to_u64((u8 *)&port_cfg.pwwn);
0407 fc_host_supported_classes(vshost) = FC_COS_CLASS3;
0408
0409 memset(fc_host_supported_fc4s(vshost), 0,
0410 sizeof(fc_host_supported_fc4s(vshost)));
0411
0412
0413 if (supported_fc4s & BFA_LPORT_ROLE_FCP_IM)
0414 fc_host_supported_fc4s(vshost)[2] = 1;
0415
0416
0417 fc_host_supported_fc4s(vshost)[7] = 1;
0418
0419 fc_host_supported_speeds(vshost) =
0420 bfad_im_supported_speeds(&bfad->bfa);
0421 fc_host_maxframe_size(vshost) =
0422 bfa_fcport_get_maxfrsize(&bfad->bfa);
0423
0424 fc_vport->dd_data = vport;
0425 vport->drv_port.im_port->fc_vport = fc_vport;
0426 } else if (rc == BFA_STATUS_INVALID_WWN)
0427 return VPCERR_BAD_WWN;
0428 else if (rc == BFA_STATUS_VPORT_EXISTS)
0429 return VPCERR_BAD_WWN;
0430 else if (rc == BFA_STATUS_VPORT_MAX)
0431 return VPCERR_NO_FABRIC_SUPP;
0432 else if (rc == BFA_STATUS_VPORT_WWN_BP)
0433 return VPCERR_BAD_WWN;
0434 else
0435 return FC_VPORT_FAILED;
0436
0437 return status;
0438 }
0439
0440 static int
0441 bfad_im_issue_fc_host_lip(struct Scsi_Host *shost)
0442 {
0443 struct bfad_im_port_s *im_port =
0444 (struct bfad_im_port_s *) shost->hostdata[0];
0445 struct bfad_s *bfad = im_port->bfad;
0446 struct bfad_hal_comp fcomp;
0447 unsigned long flags;
0448 uint32_t status;
0449
0450 init_completion(&fcomp.comp);
0451 spin_lock_irqsave(&bfad->bfad_lock, flags);
0452 status = bfa_port_disable(&bfad->bfa.modules.port,
0453 bfad_hcb_comp, &fcomp);
0454 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
0455
0456 if (status != BFA_STATUS_OK)
0457 return -EIO;
0458
0459 wait_for_completion(&fcomp.comp);
0460 if (fcomp.status != BFA_STATUS_OK)
0461 return -EIO;
0462
0463 spin_lock_irqsave(&bfad->bfad_lock, flags);
0464 status = bfa_port_enable(&bfad->bfa.modules.port,
0465 bfad_hcb_comp, &fcomp);
0466 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
0467 if (status != BFA_STATUS_OK)
0468 return -EIO;
0469
0470 wait_for_completion(&fcomp.comp);
0471 if (fcomp.status != BFA_STATUS_OK)
0472 return -EIO;
0473
0474 return 0;
0475 }
0476
0477 static int
0478 bfad_im_vport_delete(struct fc_vport *fc_vport)
0479 {
0480 struct bfad_vport_s *vport = (struct bfad_vport_s *)fc_vport->dd_data;
0481 struct bfad_im_port_s *im_port =
0482 (struct bfad_im_port_s *) vport->drv_port.im_port;
0483 struct bfad_s *bfad = im_port->bfad;
0484 struct bfa_fcs_vport_s *fcs_vport;
0485 struct Scsi_Host *vshost;
0486 wwn_t pwwn;
0487 int rc;
0488 unsigned long flags;
0489 struct completion fcomp;
0490
0491 if (im_port->flags & BFAD_PORT_DELETE) {
0492 bfad_scsi_host_free(bfad, im_port);
0493 list_del(&vport->list_entry);
0494 kfree(vport);
0495 return 0;
0496 }
0497
0498 vshost = vport->drv_port.im_port->shost;
0499 u64_to_wwn(fc_host_port_name(vshost), (u8 *)&pwwn);
0500
0501 spin_lock_irqsave(&bfad->bfad_lock, flags);
0502 fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn);
0503 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
0504
0505 if (fcs_vport == NULL)
0506 return VPCERR_BAD_WWN;
0507
0508 vport->drv_port.flags |= BFAD_PORT_DELETE;
0509
0510 vport->comp_del = &fcomp;
0511 init_completion(vport->comp_del);
0512
0513 spin_lock_irqsave(&bfad->bfad_lock, flags);
0514 rc = bfa_fcs_vport_delete(&vport->fcs_vport);
0515 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
0516
0517 if (rc == BFA_STATUS_PBC) {
0518 vport->drv_port.flags &= ~BFAD_PORT_DELETE;
0519 vport->comp_del = NULL;
0520 return -1;
0521 }
0522
0523 wait_for_completion(vport->comp_del);
0524
0525 bfad_scsi_host_free(bfad, im_port);
0526 list_del(&vport->list_entry);
0527 kfree(vport);
0528
0529 return 0;
0530 }
0531
0532 static int
0533 bfad_im_vport_disable(struct fc_vport *fc_vport, bool disable)
0534 {
0535 struct bfad_vport_s *vport;
0536 struct bfad_s *bfad;
0537 struct bfa_fcs_vport_s *fcs_vport;
0538 struct Scsi_Host *vshost;
0539 wwn_t pwwn;
0540 unsigned long flags;
0541
0542 vport = (struct bfad_vport_s *)fc_vport->dd_data;
0543 bfad = vport->drv_port.bfad;
0544 vshost = vport->drv_port.im_port->shost;
0545 u64_to_wwn(fc_host_port_name(vshost), (u8 *)&pwwn);
0546
0547 spin_lock_irqsave(&bfad->bfad_lock, flags);
0548 fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn);
0549 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
0550
0551 if (fcs_vport == NULL)
0552 return VPCERR_BAD_WWN;
0553
0554 if (disable) {
0555 bfa_fcs_vport_stop(fcs_vport);
0556 fc_vport_set_state(fc_vport, FC_VPORT_DISABLED);
0557 } else {
0558 bfa_fcs_vport_start(fcs_vport);
0559 fc_vport_set_state(fc_vport, FC_VPORT_ACTIVE);
0560 }
0561
0562 return 0;
0563 }
0564
0565 static void
0566 bfad_im_vport_set_symbolic_name(struct fc_vport *fc_vport)
0567 {
0568 struct bfad_vport_s *vport = (struct bfad_vport_s *)fc_vport->dd_data;
0569 struct bfad_im_port_s *im_port =
0570 (struct bfad_im_port_s *)vport->drv_port.im_port;
0571 struct bfad_s *bfad = im_port->bfad;
0572 struct Scsi_Host *vshost = vport->drv_port.im_port->shost;
0573 char *sym_name = fc_vport->symbolic_name;
0574 struct bfa_fcs_vport_s *fcs_vport;
0575 wwn_t pwwn;
0576 unsigned long flags;
0577
0578 u64_to_wwn(fc_host_port_name(vshost), (u8 *)&pwwn);
0579
0580 spin_lock_irqsave(&bfad->bfad_lock, flags);
0581 fcs_vport = bfa_fcs_vport_lookup(&bfad->bfa_fcs, 0, pwwn);
0582 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
0583
0584 if (fcs_vport == NULL)
0585 return;
0586
0587 spin_lock_irqsave(&bfad->bfad_lock, flags);
0588 if (strlen(sym_name) > 0)
0589 bfa_fcs_lport_set_symname(&fcs_vport->lport, sym_name);
0590 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
0591 }
0592
0593 struct fc_function_template bfad_im_fc_function_template = {
0594
0595
0596 .get_starget_port_id = bfad_im_get_starget_port_id,
0597 .show_starget_port_id = 1,
0598 .get_starget_node_name = bfad_im_get_starget_node_name,
0599 .show_starget_node_name = 1,
0600 .get_starget_port_name = bfad_im_get_starget_port_name,
0601 .show_starget_port_name = 1,
0602
0603
0604 .get_host_port_id = bfad_im_get_host_port_id,
0605 .show_host_port_id = 1,
0606
0607
0608 .show_host_node_name = 1,
0609 .show_host_port_name = 1,
0610 .show_host_supported_classes = 1,
0611 .show_host_supported_fc4s = 1,
0612 .show_host_supported_speeds = 1,
0613 .show_host_maxframe_size = 1,
0614
0615
0616 .show_host_port_type = 1,
0617 .get_host_port_type = bfad_im_get_host_port_type,
0618 .show_host_port_state = 1,
0619 .get_host_port_state = bfad_im_get_host_port_state,
0620 .show_host_active_fc4s = 1,
0621 .get_host_active_fc4s = bfad_im_get_host_active_fc4s,
0622 .show_host_speed = 1,
0623 .get_host_speed = bfad_im_get_host_speed,
0624 .show_host_fabric_name = 1,
0625 .get_host_fabric_name = bfad_im_get_host_fabric_name,
0626
0627 .show_host_symbolic_name = 1,
0628
0629
0630 .get_fc_host_stats = bfad_im_get_stats,
0631 .reset_fc_host_stats = bfad_im_reset_stats,
0632
0633
0634 .dd_fcrport_size = sizeof(struct bfad_itnim_data_s *),
0635
0636
0637 .show_rport_maxframe_size = 1,
0638 .show_rport_supported_classes = 1,
0639 .show_rport_dev_loss_tmo = 1,
0640 .set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo,
0641 .issue_fc_host_lip = bfad_im_issue_fc_host_lip,
0642 .vport_create = bfad_im_vport_create,
0643 .vport_delete = bfad_im_vport_delete,
0644 .vport_disable = bfad_im_vport_disable,
0645 .set_vport_symbolic_name = bfad_im_vport_set_symbolic_name,
0646 .bsg_request = bfad_im_bsg_request,
0647 .bsg_timeout = bfad_im_bsg_timeout,
0648 };
0649
0650 struct fc_function_template bfad_im_vport_fc_function_template = {
0651
0652
0653 .get_starget_port_id = bfad_im_get_starget_port_id,
0654 .show_starget_port_id = 1,
0655 .get_starget_node_name = bfad_im_get_starget_node_name,
0656 .show_starget_node_name = 1,
0657 .get_starget_port_name = bfad_im_get_starget_port_name,
0658 .show_starget_port_name = 1,
0659
0660
0661 .get_host_port_id = bfad_im_get_host_port_id,
0662 .show_host_port_id = 1,
0663
0664
0665 .show_host_node_name = 1,
0666 .show_host_port_name = 1,
0667 .show_host_supported_classes = 1,
0668 .show_host_supported_fc4s = 1,
0669 .show_host_supported_speeds = 1,
0670 .show_host_maxframe_size = 1,
0671
0672
0673 .show_host_port_type = 1,
0674 .get_host_port_type = bfad_im_get_host_port_type,
0675 .show_host_port_state = 1,
0676 .get_host_port_state = bfad_im_get_host_port_state,
0677 .show_host_active_fc4s = 1,
0678 .get_host_active_fc4s = bfad_im_get_host_active_fc4s,
0679 .show_host_speed = 1,
0680 .get_host_speed = bfad_im_get_host_speed,
0681 .show_host_fabric_name = 1,
0682 .get_host_fabric_name = bfad_im_get_host_fabric_name,
0683
0684 .show_host_symbolic_name = 1,
0685
0686
0687 .get_fc_host_stats = bfad_im_get_stats,
0688 .reset_fc_host_stats = bfad_im_reset_stats,
0689
0690
0691 .dd_fcrport_size = sizeof(struct bfad_itnim_data_s *),
0692
0693
0694 .show_rport_maxframe_size = 1,
0695 .show_rport_supported_classes = 1,
0696 .show_rport_dev_loss_tmo = 1,
0697 .set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo,
0698 };
0699
0700
0701
0702
0703 static ssize_t
0704 bfad_im_serial_num_show(struct device *dev, struct device_attribute *attr,
0705 char *buf)
0706 {
0707 struct Scsi_Host *shost = class_to_shost(dev);
0708 struct bfad_im_port_s *im_port =
0709 (struct bfad_im_port_s *) shost->hostdata[0];
0710 struct bfad_s *bfad = im_port->bfad;
0711 char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
0712
0713 bfa_get_adapter_serial_num(&bfad->bfa, serial_num);
0714 return sysfs_emit(buf, "%s\n", serial_num);
0715 }
0716
0717 static ssize_t
0718 bfad_im_model_show(struct device *dev, struct device_attribute *attr,
0719 char *buf)
0720 {
0721 struct Scsi_Host *shost = class_to_shost(dev);
0722 struct bfad_im_port_s *im_port =
0723 (struct bfad_im_port_s *) shost->hostdata[0];
0724 struct bfad_s *bfad = im_port->bfad;
0725 char model[BFA_ADAPTER_MODEL_NAME_LEN];
0726
0727 bfa_get_adapter_model(&bfad->bfa, model);
0728 return sysfs_emit(buf, "%s\n", model);
0729 }
0730
0731 static ssize_t
0732 bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr,
0733 char *buf)
0734 {
0735 struct Scsi_Host *shost = class_to_shost(dev);
0736 struct bfad_im_port_s *im_port =
0737 (struct bfad_im_port_s *) shost->hostdata[0];
0738 struct bfad_s *bfad = im_port->bfad;
0739 char model[BFA_ADAPTER_MODEL_NAME_LEN];
0740 char model_descr[BFA_ADAPTER_MODEL_DESCR_LEN];
0741 int nports = 0;
0742
0743 bfa_get_adapter_model(&bfad->bfa, model);
0744 nports = bfa_get_nports(&bfad->bfa);
0745 if (!strcmp(model, "QLogic-425"))
0746 snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
0747 "QLogic BR-series 4Gbps PCIe dual port FC HBA");
0748 else if (!strcmp(model, "QLogic-825"))
0749 snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
0750 "QLogic BR-series 8Gbps PCIe dual port FC HBA");
0751 else if (!strcmp(model, "QLogic-42B"))
0752 snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
0753 "QLogic BR-series 4Gbps PCIe dual port FC HBA for HP");
0754 else if (!strcmp(model, "QLogic-82B"))
0755 snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
0756 "QLogic BR-series 8Gbps PCIe dual port FC HBA for HP");
0757 else if (!strcmp(model, "QLogic-1010"))
0758 snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
0759 "QLogic BR-series 10Gbps single port CNA");
0760 else if (!strcmp(model, "QLogic-1020"))
0761 snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
0762 "QLogic BR-series 10Gbps dual port CNA");
0763 else if (!strcmp(model, "QLogic-1007"))
0764 snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
0765 "QLogic BR-series 10Gbps CNA for IBM Blade Center");
0766 else if (!strcmp(model, "QLogic-415"))
0767 snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
0768 "QLogic BR-series 4Gbps PCIe single port FC HBA");
0769 else if (!strcmp(model, "QLogic-815"))
0770 snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
0771 "QLogic BR-series 8Gbps PCIe single port FC HBA");
0772 else if (!strcmp(model, "QLogic-41B"))
0773 snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
0774 "QLogic BR-series 4Gbps PCIe single port FC HBA for HP");
0775 else if (!strcmp(model, "QLogic-81B"))
0776 snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
0777 "QLogic BR-series 8Gbps PCIe single port FC HBA for HP");
0778 else if (!strcmp(model, "QLogic-804"))
0779 snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
0780 "QLogic BR-series 8Gbps FC HBA for HP Bladesystem C-class");
0781 else if (!strcmp(model, "QLogic-1741"))
0782 snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
0783 "QLogic BR-series 10Gbps CNA for Dell M-Series Blade Servers");
0784 else if (strstr(model, "QLogic-1860")) {
0785 if (nports == 1 && bfa_ioc_is_cna(&bfad->bfa.ioc))
0786 snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
0787 "QLogic BR-series 10Gbps single port CNA");
0788 else if (nports == 1 && !bfa_ioc_is_cna(&bfad->bfa.ioc))
0789 snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
0790 "QLogic BR-series 16Gbps PCIe single port FC HBA");
0791 else if (nports == 2 && bfa_ioc_is_cna(&bfad->bfa.ioc))
0792 snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
0793 "QLogic BR-series 10Gbps dual port CNA");
0794 else if (nports == 2 && !bfa_ioc_is_cna(&bfad->bfa.ioc))
0795 snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
0796 "QLogic BR-series 16Gbps PCIe dual port FC HBA");
0797 } else if (!strcmp(model, "QLogic-1867")) {
0798 if (nports == 1 && !bfa_ioc_is_cna(&bfad->bfa.ioc))
0799 snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
0800 "QLogic BR-series 16Gbps PCIe single port FC HBA for IBM");
0801 else if (nports == 2 && !bfa_ioc_is_cna(&bfad->bfa.ioc))
0802 snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
0803 "QLogic BR-series 16Gbps PCIe dual port FC HBA for IBM");
0804 } else
0805 snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
0806 "Invalid Model");
0807
0808 return sysfs_emit(buf, "%s\n", model_descr);
0809 }
0810
0811 static ssize_t
0812 bfad_im_node_name_show(struct device *dev, struct device_attribute *attr,
0813 char *buf)
0814 {
0815 struct Scsi_Host *shost = class_to_shost(dev);
0816 struct bfad_im_port_s *im_port =
0817 (struct bfad_im_port_s *) shost->hostdata[0];
0818 struct bfad_port_s *port = im_port->port;
0819 u64 nwwn;
0820
0821 nwwn = bfa_fcs_lport_get_nwwn(port->fcs_port);
0822 return sysfs_emit(buf, "0x%llx\n", cpu_to_be64(nwwn));
0823 }
0824
0825 static ssize_t
0826 bfad_im_symbolic_name_show(struct device *dev, struct device_attribute *attr,
0827 char *buf)
0828 {
0829 struct Scsi_Host *shost = class_to_shost(dev);
0830 struct bfad_im_port_s *im_port =
0831 (struct bfad_im_port_s *) shost->hostdata[0];
0832 struct bfad_s *bfad = im_port->bfad;
0833 struct bfa_lport_attr_s port_attr;
0834 char symname[BFA_SYMNAME_MAXLEN];
0835
0836 bfa_fcs_lport_get_attr(&bfad->bfa_fcs.fabric.bport, &port_attr);
0837 strlcpy(symname, port_attr.port_cfg.sym_name.symname,
0838 BFA_SYMNAME_MAXLEN);
0839 return sysfs_emit(buf, "%s\n", symname);
0840 }
0841
0842 static ssize_t
0843 bfad_im_hw_version_show(struct device *dev, struct device_attribute *attr,
0844 char *buf)
0845 {
0846 struct Scsi_Host *shost = class_to_shost(dev);
0847 struct bfad_im_port_s *im_port =
0848 (struct bfad_im_port_s *) shost->hostdata[0];
0849 struct bfad_s *bfad = im_port->bfad;
0850 char hw_ver[BFA_VERSION_LEN];
0851
0852 bfa_get_pci_chip_rev(&bfad->bfa, hw_ver);
0853 return sysfs_emit(buf, "%s\n", hw_ver);
0854 }
0855
0856 static ssize_t
0857 bfad_im_drv_version_show(struct device *dev, struct device_attribute *attr,
0858 char *buf)
0859 {
0860 return sysfs_emit(buf, "%s\n", BFAD_DRIVER_VERSION);
0861 }
0862
0863 static ssize_t
0864 bfad_im_optionrom_version_show(struct device *dev,
0865 struct device_attribute *attr, char *buf)
0866 {
0867 struct Scsi_Host *shost = class_to_shost(dev);
0868 struct bfad_im_port_s *im_port =
0869 (struct bfad_im_port_s *) shost->hostdata[0];
0870 struct bfad_s *bfad = im_port->bfad;
0871 char optrom_ver[BFA_VERSION_LEN];
0872
0873 bfa_get_adapter_optrom_ver(&bfad->bfa, optrom_ver);
0874 return sysfs_emit(buf, "%s\n", optrom_ver);
0875 }
0876
0877 static ssize_t
0878 bfad_im_fw_version_show(struct device *dev, struct device_attribute *attr,
0879 char *buf)
0880 {
0881 struct Scsi_Host *shost = class_to_shost(dev);
0882 struct bfad_im_port_s *im_port =
0883 (struct bfad_im_port_s *) shost->hostdata[0];
0884 struct bfad_s *bfad = im_port->bfad;
0885 char fw_ver[BFA_VERSION_LEN];
0886
0887 bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver);
0888 return sysfs_emit(buf, "%s\n", fw_ver);
0889 }
0890
0891 static ssize_t
0892 bfad_im_num_of_ports_show(struct device *dev, struct device_attribute *attr,
0893 char *buf)
0894 {
0895 struct Scsi_Host *shost = class_to_shost(dev);
0896 struct bfad_im_port_s *im_port =
0897 (struct bfad_im_port_s *) shost->hostdata[0];
0898 struct bfad_s *bfad = im_port->bfad;
0899
0900 return sysfs_emit(buf, "%d\n",
0901 bfa_get_nports(&bfad->bfa));
0902 }
0903
0904 static ssize_t
0905 bfad_im_drv_name_show(struct device *dev, struct device_attribute *attr,
0906 char *buf)
0907 {
0908 return sysfs_emit(buf, "%s\n", BFAD_DRIVER_NAME);
0909 }
0910
0911 static ssize_t
0912 bfad_im_num_of_discovered_ports_show(struct device *dev,
0913 struct device_attribute *attr, char *buf)
0914 {
0915 struct Scsi_Host *shost = class_to_shost(dev);
0916 struct bfad_im_port_s *im_port =
0917 (struct bfad_im_port_s *) shost->hostdata[0];
0918 struct bfad_port_s *port = im_port->port;
0919 struct bfad_s *bfad = im_port->bfad;
0920 int nrports = 2048;
0921 struct bfa_rport_qualifier_s *rports = NULL;
0922 unsigned long flags;
0923
0924 rports = kcalloc(nrports, sizeof(struct bfa_rport_qualifier_s),
0925 GFP_ATOMIC);
0926 if (rports == NULL)
0927 return sysfs_emit(buf, "Failed\n");
0928
0929 spin_lock_irqsave(&bfad->bfad_lock, flags);
0930 bfa_fcs_lport_get_rport_quals(port->fcs_port, rports, &nrports);
0931 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
0932 kfree(rports);
0933
0934 return sysfs_emit(buf, "%d\n", nrports);
0935 }
0936
0937 static DEVICE_ATTR(serial_number, S_IRUGO,
0938 bfad_im_serial_num_show, NULL);
0939 static DEVICE_ATTR(model, S_IRUGO, bfad_im_model_show, NULL);
0940 static DEVICE_ATTR(model_description, S_IRUGO,
0941 bfad_im_model_desc_show, NULL);
0942 static DEVICE_ATTR(node_name, S_IRUGO, bfad_im_node_name_show, NULL);
0943 static DEVICE_ATTR(symbolic_name, S_IRUGO,
0944 bfad_im_symbolic_name_show, NULL);
0945 static DEVICE_ATTR(hardware_version, S_IRUGO,
0946 bfad_im_hw_version_show, NULL);
0947 static DEVICE_ATTR(driver_version, S_IRUGO,
0948 bfad_im_drv_version_show, NULL);
0949 static DEVICE_ATTR(option_rom_version, S_IRUGO,
0950 bfad_im_optionrom_version_show, NULL);
0951 static DEVICE_ATTR(firmware_version, S_IRUGO,
0952 bfad_im_fw_version_show, NULL);
0953 static DEVICE_ATTR(number_of_ports, S_IRUGO,
0954 bfad_im_num_of_ports_show, NULL);
0955 static DEVICE_ATTR(driver_name, S_IRUGO, bfad_im_drv_name_show, NULL);
0956 static DEVICE_ATTR(number_of_discovered_ports, S_IRUGO,
0957 bfad_im_num_of_discovered_ports_show, NULL);
0958
0959 static struct attribute *bfad_im_host_attrs[] = {
0960 &dev_attr_serial_number.attr,
0961 &dev_attr_model.attr,
0962 &dev_attr_model_description.attr,
0963 &dev_attr_node_name.attr,
0964 &dev_attr_symbolic_name.attr,
0965 &dev_attr_hardware_version.attr,
0966 &dev_attr_driver_version.attr,
0967 &dev_attr_option_rom_version.attr,
0968 &dev_attr_firmware_version.attr,
0969 &dev_attr_number_of_ports.attr,
0970 &dev_attr_driver_name.attr,
0971 &dev_attr_number_of_discovered_ports.attr,
0972 NULL,
0973 };
0974
0975 static const struct attribute_group bfad_im_host_attr_group = {
0976 .attrs = bfad_im_host_attrs
0977 };
0978
0979 const struct attribute_group *bfad_im_host_groups[] = {
0980 &bfad_im_host_attr_group,
0981 NULL
0982 };
0983
0984 static struct attribute *bfad_im_vport_attrs[] = {
0985 &dev_attr_serial_number.attr,
0986 &dev_attr_model.attr,
0987 &dev_attr_model_description.attr,
0988 &dev_attr_node_name.attr,
0989 &dev_attr_symbolic_name.attr,
0990 &dev_attr_hardware_version.attr,
0991 &dev_attr_driver_version.attr,
0992 &dev_attr_option_rom_version.attr,
0993 &dev_attr_firmware_version.attr,
0994 &dev_attr_number_of_ports.attr,
0995 &dev_attr_driver_name.attr,
0996 &dev_attr_number_of_discovered_ports.attr,
0997 NULL,
0998 };
0999
1000 static const struct attribute_group bfad_im_vport_attr_group = {
1001 .attrs = bfad_im_vport_attrs
1002 };
1003
1004 const struct attribute_group *bfad_im_vport_groups[] = {
1005 &bfad_im_vport_attr_group,
1006 NULL
1007 };