Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

lpfc: Modularize and cleanup FDMI code in driver

Modularize, cleanup, add comments - for FDMI code in driver

Note: I don't like the comments with leading # - but as we have a lot if
present, I'm deferring to handle it in one big fix later.

Signed-off-by: Dick Kennedy <dick.kennedy@avagotech.com>
Signed-off-by: James Smart <james.smart@avagotech.com>
Reviewed-by: Hannes Reinicke <hare@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

James Smart and committed by
Martin K. Petersen
4258e98e c90261dc

+1458 -753
+10 -6
drivers/scsi/lpfc/lpfc.h
··· 386 386 uint32_t work_port_events; /* Timeout to be handled */ 387 387 #define WORKER_DISC_TMO 0x1 /* vport: Discovery timeout */ 388 388 #define WORKER_ELS_TMO 0x2 /* vport: ELS timeout */ 389 - #define WORKER_FDMI_TMO 0x4 /* vport: FDMI timeout */ 390 389 #define WORKER_DELAYED_DISC_TMO 0x8 /* vport: delayed discovery */ 391 390 392 391 #define WORKER_MBOX_TMO 0x100 /* hba: MBOX timeout */ ··· 395 396 #define WORKER_RAMP_UP_QUEUE 0x1000 /* hba: Increase Q depth */ 396 397 #define WORKER_SERVICE_TXQ 0x2000 /* hba: IOCBs on the txq */ 397 398 398 - struct timer_list fc_fdmitmo; 399 399 struct timer_list els_tmofunc; 400 400 struct timer_list delayed_disc_tmo; 401 401 ··· 403 405 uint8_t load_flag; 404 406 #define FC_LOADING 0x1 /* HBA in process of loading drvr */ 405 407 #define FC_UNLOADING 0x2 /* HBA in process of unloading drvr */ 408 + #define FC_ALLOW_FDMI 0x4 /* port is ready for FDMI requests */ 406 409 /* Vport Config Parameters */ 407 410 uint32_t cfg_scan_down; 408 411 uint32_t cfg_lun_queue_depth; ··· 413 414 uint32_t cfg_peer_port_login; 414 415 uint32_t cfg_fcp_class; 415 416 uint32_t cfg_use_adisc; 416 - uint32_t cfg_fdmi_on; 417 - #define LPFC_FDMI_SUPPORT 1 /* bit 0 - FDMI supported? */ 418 - #define LPFC_FDMI_REG_DELAY 2 /* bit 1 - 60 sec registration delay */ 419 - #define LPFC_FDMI_ALL_ATTRIB 4 /* bit 2 - register ALL attributes? */ 420 417 uint32_t cfg_discovery_threads; 421 418 uint32_t cfg_log_verbose; 422 419 uint32_t cfg_max_luns; ··· 438 443 unsigned long rcv_buffer_time_stamp; 439 444 uint32_t vport_flag; 440 445 #define STATIC_VPORT 1 446 + 447 + uint16_t fdmi_num_disc; 448 + uint32_t fdmi_hba_mask; 449 + uint32_t fdmi_port_mask; 441 450 }; 442 451 443 452 struct hbq_s { ··· 754 755 #define LPFC_DELAY_INIT_LINK 1 /* layered driver hold off */ 755 756 #define LPFC_DELAY_INIT_LINK_INDEFINITELY 2 /* wait, manual intervention */ 756 757 uint32_t cfg_enable_dss; 758 + uint32_t cfg_fdmi_on; 759 + #define LPFC_FDMI_NO_SUPPORT 0 /* FDMI not supported */ 760 + #define LPFC_FDMI_SUPPORT 1 /* FDMI supported? */ 761 + #define LPFC_FDMI_SMART_SAN 2 /* SmartSAN supported */ 762 + uint32_t cfg_enable_SmartSAN; 757 763 lpfc_vpd_t vpd; /* vital product data */ 758 764 759 765 struct pci_dev *pcidev;
+32 -14
drivers/scsi/lpfc/lpfc_attr.c
··· 4572 4572 255, "Identifies TYPE for additional ring configuration"); 4573 4573 4574 4574 /* 4575 - # lpfc_fdmi_on: controls FDMI support. 4576 - # Set NOT Set 4577 - # bit 0 = FDMI support no FDMI support 4578 - # LPFC_FDMI_SUPPORT just turns basic support on/off 4579 - # bit 1 = Register delay no register delay (60 seconds) 4580 - # LPFC_FDMI_REG_DELAY 60 sec registration delay after FDMI login 4581 - # bit 2 = All attributes Use a attribute subset 4582 - # LPFC_FDMI_ALL_ATTRIB applies to both port and HBA attributes 4583 - # Port attrutes subset: 1 thru 6 OR all: 1 thru 0xd 0x101 0x102 0x103 4584 - # HBA attributes subset: 1 thru 0xb OR all: 1 thru 0xc 4585 - # Value range [0,7]. Default value is 0. 4575 + # lpfc_enable_SmartSAN: Sets up FDMI support for SmartSAN 4576 + # 0 = SmartSAN functionality disabled (default) 4577 + # 1 = SmartSAN functionality enabled 4578 + # This parameter will override the value of lpfc_fdmi_on module parameter. 4579 + # Value range is [0,1]. Default value is 0. 4586 4580 */ 4587 - LPFC_VPORT_ATTR_RW(fdmi_on, 0, 0, 7, "Enable FDMI support"); 4581 + LPFC_ATTR_R(enable_SmartSAN, 0, 0, 1, "Enable SmartSAN functionality"); 4582 + 4583 + /* 4584 + # lpfc_fdmi_on: Controls FDMI support. 4585 + # 0 No FDMI support (default) 4586 + # 1 Traditional FDMI support 4587 + # 2 Smart SAN support 4588 + # If lpfc_enable_SmartSAN is set 1, the driver sets lpfc_fdmi_on to value 2 4589 + # overwriting the current value. If lpfc_enable_SmartSAN is set 0, the 4590 + # driver uses the current value of lpfc_fdmi_on provided it has value 0 or 1. 4591 + # A value of 2 with lpfc_enable_SmartSAN set to 0 causes the driver to 4592 + # set lpfc_fdmi_on back to 1. 4593 + # Value range [0,2]. Default value is 0. 4594 + */ 4595 + LPFC_ATTR_R(fdmi_on, 0, 0, 2, "Enable FDMI support"); 4588 4596 4589 4597 /* 4590 4598 # Specifies the maximum number of ELS cmds we can have outstanding (for ··· 4823 4815 &dev_attr_lpfc_multi_ring_rctl, 4824 4816 &dev_attr_lpfc_multi_ring_type, 4825 4817 &dev_attr_lpfc_fdmi_on, 4818 + &dev_attr_lpfc_enable_SmartSAN, 4826 4819 &dev_attr_lpfc_max_luns, 4827 4820 &dev_attr_lpfc_enable_npiv, 4828 4821 &dev_attr_lpfc_fcf_failover_policy, ··· 4896 4887 &dev_attr_lpfc_fcp_class, 4897 4888 &dev_attr_lpfc_use_adisc, 4898 4889 &dev_attr_lpfc_first_burst_size, 4899 - &dev_attr_lpfc_fdmi_on, 4900 4890 &dev_attr_lpfc_max_luns, 4901 4891 &dev_attr_nport_evt_cnt, 4902 4892 &dev_attr_npiv_info, ··· 5834 5826 lpfc_enable_npiv_init(phba, lpfc_enable_npiv); 5835 5827 lpfc_fcf_failover_policy_init(phba, lpfc_fcf_failover_policy); 5836 5828 lpfc_enable_rrq_init(phba, lpfc_enable_rrq); 5829 + lpfc_fdmi_on_init(phba, lpfc_fdmi_on); 5830 + lpfc_enable_SmartSAN_init(phba, lpfc_enable_SmartSAN); 5837 5831 lpfc_use_msi_init(phba, lpfc_use_msi); 5838 5832 lpfc_fcp_imax_init(phba, lpfc_fcp_imax); 5839 5833 lpfc_fcp_cpu_map_init(phba, lpfc_fcp_cpu_map); ··· 5856 5846 phba->cfg_poll = 0; 5857 5847 else 5858 5848 phba->cfg_poll = lpfc_poll; 5849 + 5850 + /* Ensure fdmi_on and enable_SmartSAN don't conflict */ 5851 + if (phba->cfg_enable_SmartSAN) { 5852 + phba->cfg_fdmi_on = LPFC_FDMI_SMART_SAN; 5853 + } else { 5854 + if (phba->cfg_fdmi_on == LPFC_FDMI_SMART_SAN) 5855 + phba->cfg_fdmi_on = LPFC_FDMI_SUPPORT; 5856 + } 5857 + 5859 5858 phba->cfg_soft_wwnn = 0L; 5860 5859 phba->cfg_soft_wwpn = 0L; 5861 5860 lpfc_sg_seg_cnt_init(phba, lpfc_sg_seg_cnt); ··· 5898 5879 lpfc_use_adisc_init(vport, lpfc_use_adisc); 5899 5880 lpfc_first_burst_size_init(vport, lpfc_first_burst_size); 5900 5881 lpfc_max_scsicmpl_time_init(vport, lpfc_max_scsicmpl_time); 5901 - lpfc_fdmi_on_init(vport, lpfc_fdmi_on); 5902 5882 lpfc_discovery_threads_init(vport, lpfc_discovery_threads); 5903 5883 lpfc_max_luns_init(vport, lpfc_max_luns); 5904 5884 lpfc_scan_down_init(vport, lpfc_scan_down);
+2 -3
drivers/scsi/lpfc/lpfc_crtn.h
··· 168 168 struct lpfc_iocbq *); 169 169 int lpfc_ct_handle_unsol_abort(struct lpfc_hba *, struct hbq_dmabuf *); 170 170 int lpfc_ns_cmd(struct lpfc_vport *, int, uint8_t, uint32_t); 171 - int lpfc_fdmi_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int); 172 - void lpfc_fdmi_tmo(unsigned long); 173 - void lpfc_fdmi_timeout_handler(struct lpfc_vport *); 171 + int lpfc_fdmi_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int, uint32_t); 172 + void lpfc_fdmi_num_disc_check(struct lpfc_vport *); 174 173 void lpfc_delayed_disc_tmo(unsigned long); 175 174 void lpfc_delayed_disc_timeout_handler(struct lpfc_vport *); 176 175
+1158 -652
drivers/scsi/lpfc/lpfc_ct.c
··· 287 287 return 0; 288 288 } 289 289 290 + /** 291 + * lpfc_gen_req - Build and issue a GEN_REQUEST command to the SLI Layer 292 + * @vport: pointer to a host virtual N_Port data structure. 293 + * @bmp: Pointer to BPL for SLI command 294 + * @inp: Pointer to data buffer for response data. 295 + * @outp: Pointer to data buffer that hold the CT command. 296 + * @cmpl: completion routine to call when command completes 297 + * @ndlp: Destination NPort nodelist entry 298 + * 299 + * This function as the final part for issuing a CT command. 300 + */ 290 301 static int 291 302 lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp, 292 303 struct lpfc_dmabuf *inp, struct lpfc_dmabuf *outp, ··· 322 311 icmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys); 323 312 icmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys); 324 313 icmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64; 325 - icmd->un.genreq64.bdl.bdeSize = (num_entry * sizeof (struct ulp_bde64)); 314 + icmd->un.genreq64.bdl.bdeSize = (num_entry * sizeof(struct ulp_bde64)); 326 315 327 316 if (usr_flg) 328 317 geniocb->context3 = NULL; ··· 381 370 return 0; 382 371 } 383 372 373 + /** 374 + * lpfc_ct_cmd - Build and issue a CT command 375 + * @vport: pointer to a host virtual N_Port data structure. 376 + * @inmp: Pointer to data buffer for response data. 377 + * @bmp: Pointer to BPL for SLI command 378 + * @ndlp: Destination NPort nodelist entry 379 + * @cmpl: completion routine to call when command completes 380 + * 381 + * This function is called for issuing a CT command. 382 + */ 384 383 static int 385 384 lpfc_ct_cmd(struct lpfc_vport *vport, struct lpfc_dmabuf *inmp, 386 385 struct lpfc_dmabuf *bmp, struct lpfc_nodelist *ndlp, ··· 474 453 Cnt -= 16; /* subtract length of CT header */ 475 454 476 455 /* Loop through entire NameServer list of DIDs */ 477 - while (Cnt >= sizeof (uint32_t)) { 456 + while (Cnt >= sizeof(uint32_t)) { 478 457 /* Get next DID from NameServer List */ 479 458 CTentry = *ctptr++; 480 459 Did = ((be32_to_cpu(CTentry)) & Mask_DID); ··· 579 558 } 580 559 if (CTentry & (cpu_to_be32(SLI_CT_LAST_ENTRY))) 581 560 goto nsout1; 582 - Cnt -= sizeof (uint32_t); 561 + Cnt -= sizeof(uint32_t); 583 562 } 584 563 ctptr = NULL; 585 564 ··· 1167 1146 1168 1147 /* fill in BDEs for command */ 1169 1148 /* Allocate buffer for command payload */ 1170 - mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL); 1149 + mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); 1171 1150 if (!mp) { 1172 1151 rc=2; 1173 1152 goto ns_cmd_exit; ··· 1181 1160 } 1182 1161 1183 1162 /* Allocate buffer for Buffer ptr list */ 1184 - bmp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL); 1163 + bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); 1185 1164 if (!bmp) { 1186 1165 rc=4; 1187 1166 goto ns_cmd_free_mpvirt; ··· 1225 1204 bpl->tus.w = le32_to_cpu(bpl->tus.w); 1226 1205 1227 1206 CtReq = (struct lpfc_sli_ct_request *) mp->virt; 1228 - memset(CtReq, 0, sizeof (struct lpfc_sli_ct_request)); 1207 + memset(CtReq, 0, sizeof(struct lpfc_sli_ct_request)); 1229 1208 CtReq->RevisionId.bits.Revision = SLI_CT_REVISION; 1230 1209 CtReq->RevisionId.bits.InId = 0; 1231 1210 CtReq->FsType = SLI_CT_DIRECTORY_SERVICE; ··· 1265 1244 cpu_to_be16(SLI_CTNS_RNN_ID); 1266 1245 CtReq->un.rnn.PortId = cpu_to_be32(vport->fc_myDID); 1267 1246 memcpy(CtReq->un.rnn.wwnn, &vport->fc_nodename, 1268 - sizeof (struct lpfc_name)); 1247 + sizeof(struct lpfc_name)); 1269 1248 cmpl = lpfc_cmpl_ct_cmd_rnn_id; 1270 1249 break; 1271 1250 ··· 1285 1264 CtReq->CommandResponse.bits.CmdRsp = 1286 1265 cpu_to_be16(SLI_CTNS_RSNN_NN); 1287 1266 memcpy(CtReq->un.rsnn.wwnn, &vport->fc_nodename, 1288 - sizeof (struct lpfc_name)); 1267 + sizeof(struct lpfc_name)); 1289 1268 size = sizeof(CtReq->un.rsnn.symbname); 1290 1269 CtReq->un.rsnn.len = 1291 1270 lpfc_vport_symbolic_node_name(vport, ··· 1340 1319 return 1; 1341 1320 } 1342 1321 1322 + /** 1323 + * lpfc_cmpl_ct_disc_fdmi - Handle a discovery FDMI completion 1324 + * @phba: Pointer to HBA context object. 1325 + * @cmdiocb: Pointer to the command IOCBQ. 1326 + * @rspiocb: Pointer to the response IOCBQ. 1327 + * 1328 + * This function to handle the completion of a driver initiated FDMI 1329 + * CT command issued during discovery. 1330 + */ 1343 1331 static void 1344 - lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, 1345 - struct lpfc_iocbq * rspiocb) 1332 + lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, 1333 + struct lpfc_iocbq *rspiocb) 1346 1334 { 1335 + struct lpfc_vport *vport = cmdiocb->vport; 1347 1336 struct lpfc_dmabuf *inp = cmdiocb->context1; 1348 1337 struct lpfc_dmabuf *outp = cmdiocb->context2; 1349 - struct lpfc_sli_ct_request *CTrsp = outp->virt; 1350 1338 struct lpfc_sli_ct_request *CTcmd = inp->virt; 1351 - struct lpfc_nodelist *ndlp; 1339 + struct lpfc_sli_ct_request *CTrsp = outp->virt; 1352 1340 uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp; 1353 1341 uint16_t fdmi_rsp = CTrsp->CommandResponse.bits.CmdRsp; 1354 - struct lpfc_vport *vport = cmdiocb->vport; 1355 1342 IOCB_t *irsp = &rspiocb->iocb; 1356 - uint32_t latt; 1343 + struct lpfc_nodelist *ndlp; 1344 + uint32_t latt, cmd, err; 1357 1345 1358 1346 latt = lpfc_els_chk_latt(vport); 1359 1347 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT, ··· 1370 1340 irsp->ulpStatus, irsp->un.ulpWord[4], latt); 1371 1341 1372 1342 if (latt || irsp->ulpStatus) { 1343 + 1344 + /* Look for a retryable error */ 1345 + if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) { 1346 + switch ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK)) { 1347 + case IOERR_SLI_ABORTED: 1348 + case IOERR_ABORT_IN_PROGRESS: 1349 + case IOERR_SEQUENCE_TIMEOUT: 1350 + case IOERR_ILLEGAL_FRAME: 1351 + case IOERR_NO_RESOURCES: 1352 + case IOERR_ILLEGAL_COMMAND: 1353 + cmdiocb->retry++; 1354 + if (cmdiocb->retry >= LPFC_FDMI_MAX_RETRY) 1355 + break; 1356 + 1357 + /* Retry the same FDMI command */ 1358 + err = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, 1359 + cmdiocb, 0); 1360 + if (err == IOCB_ERROR) 1361 + break; 1362 + return; 1363 + default: 1364 + break; 1365 + } 1366 + } 1367 + 1373 1368 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, 1374 1369 "0229 FDMI cmd %04x failed, latt = %d " 1375 1370 "ulpStatus: x%x, rid x%x\n", 1376 1371 be16_to_cpu(fdmi_cmd), latt, irsp->ulpStatus, 1377 1372 irsp->un.ulpWord[4]); 1378 - goto fail_out; 1379 1373 } 1380 - 1381 - ndlp = lpfc_findnode_did(vport, FDMI_DID); 1382 - if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) 1383 - goto fail_out; 1384 - 1385 - if (fdmi_rsp == cpu_to_be16(SLI_CT_RESPONSE_FS_RJT)) { 1386 - /* FDMI rsp failed */ 1387 - lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, 1388 - "0220 FDMI rsp failed Data: x%x\n", 1389 - be16_to_cpu(fdmi_cmd)); 1390 - } 1391 - 1392 - fail_out: 1393 1374 lpfc_ct_free_iocb(phba, cmdiocb); 1394 - } 1395 - 1396 - static void 1397 - lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, 1398 - struct lpfc_iocbq *rspiocb) 1399 - { 1400 - struct lpfc_vport *vport = cmdiocb->vport; 1401 - struct lpfc_dmabuf *inp = cmdiocb->context1; 1402 - struct lpfc_sli_ct_request *CTcmd = inp->virt; 1403 - uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp; 1404 - struct lpfc_nodelist *ndlp; 1405 - 1406 - lpfc_cmpl_ct_cmd_fdmi(phba, cmdiocb, rspiocb); 1407 1375 1408 1376 ndlp = lpfc_findnode_did(vport, FDMI_DID); 1409 1377 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) 1410 1378 return; 1411 1379 1380 + /* Check for a CT LS_RJT response */ 1381 + cmd = be16_to_cpu(fdmi_cmd); 1382 + if (fdmi_rsp == cpu_to_be16(SLI_CT_RESPONSE_FS_RJT)) { 1383 + /* FDMI rsp failed */ 1384 + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, 1385 + "0220 FDMI cmd failed FS_RJT Data: x%x", cmd); 1386 + 1387 + /* Should we fallback to FDMI-2 / FDMI-1 ? */ 1388 + switch (cmd) { 1389 + case SLI_MGMT_RHBA: 1390 + if (vport->fdmi_hba_mask == LPFC_FDMI2_HBA_ATTR) { 1391 + /* Fallback to FDMI-1 */ 1392 + vport->fdmi_hba_mask = LPFC_FDMI1_HBA_ATTR; 1393 + vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR; 1394 + /* Start over */ 1395 + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0); 1396 + } 1397 + return; 1398 + 1399 + case SLI_MGMT_RPRT: 1400 + if (vport->fdmi_port_mask == LPFC_FDMI2_PORT_ATTR) { 1401 + /* Fallback to FDMI-1 */ 1402 + vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR; 1403 + /* Start over */ 1404 + lpfc_fdmi_cmd(vport, ndlp, cmd, 0); 1405 + } 1406 + if (vport->fdmi_port_mask == LPFC_FDMI2_SMART_ATTR) { 1407 + vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR; 1408 + /* Retry the same command */ 1409 + lpfc_fdmi_cmd(vport, ndlp, cmd, 0); 1410 + } 1411 + return; 1412 + 1413 + case SLI_MGMT_RPA: 1414 + if (vport->fdmi_port_mask == LPFC_FDMI2_PORT_ATTR) { 1415 + /* Fallback to FDMI-1 */ 1416 + vport->fdmi_hba_mask = LPFC_FDMI1_HBA_ATTR; 1417 + vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR; 1418 + /* Start over */ 1419 + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0); 1420 + } 1421 + if (vport->fdmi_port_mask == LPFC_FDMI2_SMART_ATTR) { 1422 + vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR; 1423 + /* Retry the same command */ 1424 + lpfc_fdmi_cmd(vport, ndlp, cmd, 0); 1425 + } 1426 + return; 1427 + } 1428 + } 1429 + 1412 1430 /* 1413 - * Need to cycle thru FDMI registration for discovery 1414 - * DHBA -> DPRT -> RHBA -> RPA 1431 + * On success, need to cycle thru FDMI registration for discovery 1432 + * DHBA -> DPRT -> RHBA -> RPA (physical port) 1433 + * DPRT -> RPRT (vports) 1415 1434 */ 1416 - switch (be16_to_cpu(fdmi_cmd)) { 1435 + switch (cmd) { 1417 1436 case SLI_MGMT_RHBA: 1418 - lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA); 1437 + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA, 0); 1419 1438 break; 1420 1439 1421 1440 case SLI_MGMT_DHBA: 1422 - lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT); 1441 + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT, 0); 1423 1442 break; 1424 1443 1425 1444 case SLI_MGMT_DPRT: 1426 - lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RHBA); 1445 + if (vport->port_type == LPFC_PHYSICAL_PORT) 1446 + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RHBA, 0); 1447 + else 1448 + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPRT, 0); 1427 1449 break; 1428 1450 } 1451 + return; 1429 1452 } 1430 1453 1431 1454 1455 + /** 1456 + * lpfc_fdmi_num_disc_check - Check how many mapped NPorts we are connected to 1457 + * @vport: pointer to a host virtual N_Port data structure. 1458 + * 1459 + * Called from hbeat timeout routine to check if the number of discovered 1460 + * ports has changed. If so, re-register thar port Attribute. 1461 + */ 1462 + void 1463 + lpfc_fdmi_num_disc_check(struct lpfc_vport *vport) 1464 + { 1465 + struct lpfc_hba *phba = vport->phba; 1466 + struct lpfc_nodelist *ndlp; 1467 + uint16_t cnt; 1468 + 1469 + if (!lpfc_is_link_up(phba)) 1470 + return; 1471 + 1472 + if (!(vport->fdmi_port_mask & LPFC_FDMI_PORT_ATTR_num_disc)) 1473 + return; 1474 + 1475 + cnt = lpfc_find_map_node(vport); 1476 + if (cnt == vport->fdmi_num_disc) 1477 + return; 1478 + 1479 + ndlp = lpfc_findnode_did(vport, FDMI_DID); 1480 + if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) 1481 + return; 1482 + 1483 + if (vport->port_type == LPFC_PHYSICAL_PORT) { 1484 + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA, 1485 + LPFC_FDMI_PORT_ATTR_num_disc); 1486 + } else { 1487 + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPRT, 1488 + LPFC_FDMI_PORT_ATTR_num_disc); 1489 + } 1490 + } 1491 + 1492 + /* Routines for all individual HBA attributes */ 1432 1493 int 1433 - lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode) 1494 + lpfc_fdmi_hba_attr_wwnn(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) 1495 + { 1496 + struct lpfc_fdmi_attr_entry *ae; 1497 + uint32_t size; 1498 + 1499 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 1500 + memset(ae, 0, sizeof(struct lpfc_name)); 1501 + 1502 + memcpy(&ae->un.AttrWWN, &vport->fc_sparam.nodeName, 1503 + sizeof(struct lpfc_name)); 1504 + size = FOURBYTES + sizeof(struct lpfc_name); 1505 + ad->AttrLen = cpu_to_be16(size); 1506 + ad->AttrType = cpu_to_be16(RHBA_NODENAME); 1507 + return size; 1508 + } 1509 + int 1510 + lpfc_fdmi_hba_attr_manufacturer(struct lpfc_vport *vport, 1511 + struct lpfc_fdmi_attr_def *ad) 1512 + { 1513 + struct lpfc_fdmi_attr_entry *ae; 1514 + uint32_t len, size; 1515 + 1516 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 1517 + memset(ae, 0, 256); 1518 + 1519 + strncpy(ae->un.AttrString, 1520 + "Emulex Corporation", 1521 + sizeof(ae->un.AttrString)); 1522 + len = strnlen(ae->un.AttrString, 1523 + sizeof(ae->un.AttrString)); 1524 + len += (len & 3) ? (4 - (len & 3)) : 4; 1525 + size = FOURBYTES + len; 1526 + ad->AttrLen = cpu_to_be16(size); 1527 + ad->AttrType = cpu_to_be16(RHBA_MANUFACTURER); 1528 + return size; 1529 + } 1530 + 1531 + int 1532 + lpfc_fdmi_hba_attr_sn(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) 1533 + { 1534 + struct lpfc_hba *phba = vport->phba; 1535 + struct lpfc_fdmi_attr_entry *ae; 1536 + uint32_t len, size; 1537 + 1538 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 1539 + memset(ae, 0, 256); 1540 + 1541 + strncpy(ae->un.AttrString, phba->SerialNumber, 1542 + sizeof(ae->un.AttrString)); 1543 + len = strnlen(ae->un.AttrString, 1544 + sizeof(ae->un.AttrString)); 1545 + len += (len & 3) ? (4 - (len & 3)) : 4; 1546 + size = FOURBYTES + len; 1547 + ad->AttrLen = cpu_to_be16(size); 1548 + ad->AttrType = cpu_to_be16(RHBA_SERIAL_NUMBER); 1549 + return size; 1550 + } 1551 + 1552 + int 1553 + lpfc_fdmi_hba_attr_model(struct lpfc_vport *vport, 1554 + struct lpfc_fdmi_attr_def *ad) 1555 + { 1556 + struct lpfc_hba *phba = vport->phba; 1557 + struct lpfc_fdmi_attr_entry *ae; 1558 + uint32_t len, size; 1559 + 1560 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 1561 + memset(ae, 0, 256); 1562 + 1563 + strncpy(ae->un.AttrString, phba->ModelName, 1564 + sizeof(ae->un.AttrString)); 1565 + len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString)); 1566 + len += (len & 3) ? (4 - (len & 3)) : 4; 1567 + size = FOURBYTES + len; 1568 + ad->AttrLen = cpu_to_be16(size); 1569 + ad->AttrType = cpu_to_be16(RHBA_MODEL); 1570 + return size; 1571 + } 1572 + 1573 + int 1574 + lpfc_fdmi_hba_attr_description(struct lpfc_vport *vport, 1575 + struct lpfc_fdmi_attr_def *ad) 1576 + { 1577 + struct lpfc_hba *phba = vport->phba; 1578 + struct lpfc_fdmi_attr_entry *ae; 1579 + uint32_t len, size; 1580 + 1581 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 1582 + memset(ae, 0, 256); 1583 + 1584 + strncpy(ae->un.AttrString, phba->ModelDesc, 1585 + sizeof(ae->un.AttrString)); 1586 + len = strnlen(ae->un.AttrString, 1587 + sizeof(ae->un.AttrString)); 1588 + len += (len & 3) ? (4 - (len & 3)) : 4; 1589 + size = FOURBYTES + len; 1590 + ad->AttrLen = cpu_to_be16(size); 1591 + ad->AttrType = cpu_to_be16(RHBA_MODEL_DESCRIPTION); 1592 + return size; 1593 + } 1594 + 1595 + int 1596 + lpfc_fdmi_hba_attr_hdw_ver(struct lpfc_vport *vport, 1597 + struct lpfc_fdmi_attr_def *ad) 1598 + { 1599 + struct lpfc_hba *phba = vport->phba; 1600 + lpfc_vpd_t *vp = &phba->vpd; 1601 + struct lpfc_fdmi_attr_entry *ae; 1602 + uint32_t i, j, incr, size; 1603 + 1604 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 1605 + memset(ae, 0, 256); 1606 + 1607 + /* Convert JEDEC ID to ascii for hardware version */ 1608 + incr = vp->rev.biuRev; 1609 + for (i = 0; i < 8; i++) { 1610 + j = (incr & 0xf); 1611 + if (j <= 9) 1612 + ae->un.AttrString[7 - i] = 1613 + (char)((uint8_t) 0x30 + 1614 + (uint8_t) j); 1615 + else 1616 + ae->un.AttrString[7 - i] = 1617 + (char)((uint8_t) 0x61 + 1618 + (uint8_t) (j - 10)); 1619 + incr = (incr >> 4); 1620 + } 1621 + size = FOURBYTES + 8; 1622 + ad->AttrLen = cpu_to_be16(size); 1623 + ad->AttrType = cpu_to_be16(RHBA_HARDWARE_VERSION); 1624 + return size; 1625 + } 1626 + 1627 + int 1628 + lpfc_fdmi_hba_attr_drvr_ver(struct lpfc_vport *vport, 1629 + struct lpfc_fdmi_attr_def *ad) 1630 + { 1631 + struct lpfc_fdmi_attr_entry *ae; 1632 + uint32_t len, size; 1633 + 1634 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 1635 + memset(ae, 0, 256); 1636 + 1637 + strncpy(ae->un.AttrString, lpfc_release_version, 1638 + sizeof(ae->un.AttrString)); 1639 + len = strnlen(ae->un.AttrString, 1640 + sizeof(ae->un.AttrString)); 1641 + len += (len & 3) ? (4 - (len & 3)) : 4; 1642 + size = FOURBYTES + len; 1643 + ad->AttrLen = cpu_to_be16(size); 1644 + ad->AttrType = cpu_to_be16(RHBA_DRIVER_VERSION); 1645 + return size; 1646 + } 1647 + 1648 + int 1649 + lpfc_fdmi_hba_attr_rom_ver(struct lpfc_vport *vport, 1650 + struct lpfc_fdmi_attr_def *ad) 1651 + { 1652 + struct lpfc_hba *phba = vport->phba; 1653 + struct lpfc_fdmi_attr_entry *ae; 1654 + uint32_t len, size; 1655 + 1656 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 1657 + memset(ae, 0, 256); 1658 + 1659 + if (phba->sli_rev == LPFC_SLI_REV4) 1660 + lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1); 1661 + else 1662 + strncpy(ae->un.AttrString, phba->OptionROMVersion, 1663 + sizeof(ae->un.AttrString)); 1664 + len = strnlen(ae->un.AttrString, 1665 + sizeof(ae->un.AttrString)); 1666 + len += (len & 3) ? (4 - (len & 3)) : 4; 1667 + size = FOURBYTES + len; 1668 + ad->AttrLen = cpu_to_be16(size); 1669 + ad->AttrType = cpu_to_be16(RHBA_OPTION_ROM_VERSION); 1670 + return size; 1671 + } 1672 + 1673 + int 1674 + lpfc_fdmi_hba_attr_fmw_ver(struct lpfc_vport *vport, 1675 + struct lpfc_fdmi_attr_def *ad) 1676 + { 1677 + struct lpfc_hba *phba = vport->phba; 1678 + struct lpfc_fdmi_attr_entry *ae; 1679 + uint32_t len, size; 1680 + 1681 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 1682 + memset(ae, 0, 256); 1683 + 1684 + lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1); 1685 + len = strnlen(ae->un.AttrString, 1686 + sizeof(ae->un.AttrString)); 1687 + len += (len & 3) ? (4 - (len & 3)) : 4; 1688 + size = FOURBYTES + len; 1689 + ad->AttrLen = cpu_to_be16(size); 1690 + ad->AttrType = cpu_to_be16(RHBA_FIRMWARE_VERSION); 1691 + return size; 1692 + } 1693 + 1694 + int 1695 + lpfc_fdmi_hba_attr_os_ver(struct lpfc_vport *vport, 1696 + struct lpfc_fdmi_attr_def *ad) 1697 + { 1698 + struct lpfc_fdmi_attr_entry *ae; 1699 + uint32_t len, size; 1700 + 1701 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 1702 + memset(ae, 0, 256); 1703 + 1704 + snprintf(ae->un.AttrString, sizeof(ae->un.AttrString), "%s %s %s", 1705 + init_utsname()->sysname, 1706 + init_utsname()->release, 1707 + init_utsname()->version); 1708 + 1709 + len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString)); 1710 + len += (len & 3) ? (4 - (len & 3)) : 4; 1711 + size = FOURBYTES + len; 1712 + ad->AttrLen = cpu_to_be16(size); 1713 + ad->AttrType = cpu_to_be16(RHBA_OS_NAME_VERSION); 1714 + return size; 1715 + } 1716 + 1717 + int 1718 + lpfc_fdmi_hba_attr_ct_len(struct lpfc_vport *vport, 1719 + struct lpfc_fdmi_attr_def *ad) 1720 + { 1721 + struct lpfc_fdmi_attr_entry *ae; 1722 + uint32_t size; 1723 + 1724 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 1725 + 1726 + ae->un.AttrInt = cpu_to_be32(LPFC_MAX_CT_SIZE); 1727 + size = FOURBYTES + sizeof(uint32_t); 1728 + ad->AttrLen = cpu_to_be16(size); 1729 + ad->AttrType = cpu_to_be16(RHBA_MAX_CT_PAYLOAD_LEN); 1730 + return size; 1731 + } 1732 + 1733 + int 1734 + lpfc_fdmi_hba_attr_symbolic_name(struct lpfc_vport *vport, 1735 + struct lpfc_fdmi_attr_def *ad) 1736 + { 1737 + struct lpfc_fdmi_attr_entry *ae; 1738 + uint32_t len, size; 1739 + 1740 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 1741 + memset(ae, 0, 256); 1742 + 1743 + len = lpfc_vport_symbolic_node_name(vport, 1744 + ae->un.AttrString, 256); 1745 + len += (len & 3) ? (4 - (len & 3)) : 4; 1746 + size = FOURBYTES + len; 1747 + ad->AttrLen = cpu_to_be16(size); 1748 + ad->AttrType = cpu_to_be16(RHBA_SYM_NODENAME); 1749 + return size; 1750 + } 1751 + 1752 + int 1753 + lpfc_fdmi_hba_attr_vendor_info(struct lpfc_vport *vport, 1754 + struct lpfc_fdmi_attr_def *ad) 1755 + { 1756 + struct lpfc_fdmi_attr_entry *ae; 1757 + uint32_t size; 1758 + 1759 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 1760 + 1761 + /* Nothing is defined for this currently */ 1762 + ae->un.AttrInt = cpu_to_be32(0); 1763 + size = FOURBYTES + sizeof(uint32_t); 1764 + ad->AttrLen = cpu_to_be16(size); 1765 + ad->AttrType = cpu_to_be16(RHBA_VENDOR_INFO); 1766 + return size; 1767 + } 1768 + 1769 + int 1770 + lpfc_fdmi_hba_attr_num_ports(struct lpfc_vport *vport, 1771 + struct lpfc_fdmi_attr_def *ad) 1772 + { 1773 + struct lpfc_fdmi_attr_entry *ae; 1774 + uint32_t size; 1775 + 1776 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 1777 + 1778 + /* Each driver instance corresponds to a single port */ 1779 + ae->un.AttrInt = cpu_to_be32(1); 1780 + size = FOURBYTES + sizeof(uint32_t); 1781 + ad->AttrLen = cpu_to_be16(size); 1782 + ad->AttrType = cpu_to_be16(RHBA_NUM_PORTS); 1783 + return size; 1784 + } 1785 + 1786 + int 1787 + lpfc_fdmi_hba_attr_fabric_wwnn(struct lpfc_vport *vport, 1788 + struct lpfc_fdmi_attr_def *ad) 1789 + { 1790 + struct lpfc_fdmi_attr_entry *ae; 1791 + uint32_t size; 1792 + 1793 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 1794 + memset(ae, 0, sizeof(struct lpfc_name)); 1795 + 1796 + memcpy(&ae->un.AttrWWN, &vport->fabric_nodename, 1797 + sizeof(struct lpfc_name)); 1798 + size = FOURBYTES + sizeof(struct lpfc_name); 1799 + ad->AttrLen = cpu_to_be16(size); 1800 + ad->AttrType = cpu_to_be16(RHBA_FABRIC_WWNN); 1801 + return size; 1802 + } 1803 + 1804 + int 1805 + lpfc_fdmi_hba_attr_bios_ver(struct lpfc_vport *vport, 1806 + struct lpfc_fdmi_attr_def *ad) 1807 + { 1808 + struct lpfc_hba *phba = vport->phba; 1809 + struct lpfc_fdmi_attr_entry *ae; 1810 + uint32_t len, size; 1811 + 1812 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 1813 + memset(ae, 0, 256); 1814 + 1815 + lpfc_decode_firmware_rev(phba, ae->un.AttrString, 1); 1816 + len = strnlen(ae->un.AttrString, 1817 + sizeof(ae->un.AttrString)); 1818 + len += (len & 3) ? (4 - (len & 3)) : 4; 1819 + size = FOURBYTES + len; 1820 + ad->AttrLen = cpu_to_be16(size); 1821 + ad->AttrType = cpu_to_be16(RHBA_BIOS_VERSION); 1822 + return size; 1823 + } 1824 + 1825 + int 1826 + lpfc_fdmi_hba_attr_bios_state(struct lpfc_vport *vport, 1827 + struct lpfc_fdmi_attr_def *ad) 1828 + { 1829 + struct lpfc_fdmi_attr_entry *ae; 1830 + uint32_t size; 1831 + 1832 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 1833 + 1834 + /* Driver doesn't have access to this information */ 1835 + ae->un.AttrInt = cpu_to_be32(0); 1836 + size = FOURBYTES + sizeof(uint32_t); 1837 + ad->AttrLen = cpu_to_be16(size); 1838 + ad->AttrType = cpu_to_be16(RHBA_BIOS_STATE); 1839 + return size; 1840 + } 1841 + 1842 + int 1843 + lpfc_fdmi_hba_attr_vendor_id(struct lpfc_vport *vport, 1844 + struct lpfc_fdmi_attr_def *ad) 1845 + { 1846 + struct lpfc_fdmi_attr_entry *ae; 1847 + uint32_t len, size; 1848 + 1849 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 1850 + memset(ae, 0, 256); 1851 + 1852 + strncpy(ae->un.AttrString, "EMULEX", 1853 + sizeof(ae->un.AttrString)); 1854 + len = strnlen(ae->un.AttrString, 1855 + sizeof(ae->un.AttrString)); 1856 + len += (len & 3) ? (4 - (len & 3)) : 4; 1857 + size = FOURBYTES + len; 1858 + ad->AttrLen = cpu_to_be16(size); 1859 + ad->AttrType = cpu_to_be16(RHBA_VENDOR_ID); 1860 + return size; 1861 + } 1862 + 1863 + /* Routines for all individual PORT attributes */ 1864 + int 1865 + lpfc_fdmi_port_attr_fc4type(struct lpfc_vport *vport, 1866 + struct lpfc_fdmi_attr_def *ad) 1867 + { 1868 + struct lpfc_fdmi_attr_entry *ae; 1869 + uint32_t size; 1870 + 1871 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 1872 + memset(ae, 0, 32); 1873 + 1874 + ae->un.AttrTypes[3] = 0x02; /* Type 1 - ELS */ 1875 + ae->un.AttrTypes[2] = 0x01; /* Type 8 - FCP */ 1876 + ae->un.AttrTypes[7] = 0x01; /* Type 32 - CT */ 1877 + size = FOURBYTES + 32; 1878 + ad->AttrLen = cpu_to_be16(size); 1879 + ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_FC4_TYPES); 1880 + return size; 1881 + } 1882 + 1883 + int 1884 + lpfc_fdmi_port_attr_support_speed(struct lpfc_vport *vport, 1885 + struct lpfc_fdmi_attr_def *ad) 1886 + { 1887 + struct lpfc_hba *phba = vport->phba; 1888 + struct lpfc_fdmi_attr_entry *ae; 1889 + uint32_t size; 1890 + 1891 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 1892 + 1893 + ae->un.AttrInt = 0; 1894 + if (phba->lmt & LMT_32Gb) 1895 + ae->un.AttrInt |= HBA_PORTSPEED_32GBIT; 1896 + if (phba->lmt & LMT_16Gb) 1897 + ae->un.AttrInt |= HBA_PORTSPEED_16GBIT; 1898 + if (phba->lmt & LMT_10Gb) 1899 + ae->un.AttrInt |= HBA_PORTSPEED_10GBIT; 1900 + if (phba->lmt & LMT_8Gb) 1901 + ae->un.AttrInt |= HBA_PORTSPEED_8GBIT; 1902 + if (phba->lmt & LMT_4Gb) 1903 + ae->un.AttrInt |= HBA_PORTSPEED_4GBIT; 1904 + if (phba->lmt & LMT_2Gb) 1905 + ae->un.AttrInt |= HBA_PORTSPEED_2GBIT; 1906 + if (phba->lmt & LMT_1Gb) 1907 + ae->un.AttrInt |= HBA_PORTSPEED_1GBIT; 1908 + ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt); 1909 + size = FOURBYTES + sizeof(uint32_t); 1910 + ad->AttrLen = cpu_to_be16(size); 1911 + ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_SPEED); 1912 + return size; 1913 + } 1914 + 1915 + int 1916 + lpfc_fdmi_port_attr_speed(struct lpfc_vport *vport, 1917 + struct lpfc_fdmi_attr_def *ad) 1918 + { 1919 + struct lpfc_hba *phba = vport->phba; 1920 + struct lpfc_fdmi_attr_entry *ae; 1921 + uint32_t size; 1922 + 1923 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 1924 + 1925 + switch (phba->fc_linkspeed) { 1926 + case LPFC_LINK_SPEED_1GHZ: 1927 + ae->un.AttrInt = HBA_PORTSPEED_1GBIT; 1928 + break; 1929 + case LPFC_LINK_SPEED_2GHZ: 1930 + ae->un.AttrInt = HBA_PORTSPEED_2GBIT; 1931 + break; 1932 + case LPFC_LINK_SPEED_4GHZ: 1933 + ae->un.AttrInt = HBA_PORTSPEED_4GBIT; 1934 + break; 1935 + case LPFC_LINK_SPEED_8GHZ: 1936 + ae->un.AttrInt = HBA_PORTSPEED_8GBIT; 1937 + break; 1938 + case LPFC_LINK_SPEED_10GHZ: 1939 + ae->un.AttrInt = HBA_PORTSPEED_10GBIT; 1940 + break; 1941 + case LPFC_LINK_SPEED_16GHZ: 1942 + ae->un.AttrInt = HBA_PORTSPEED_16GBIT; 1943 + break; 1944 + case LPFC_LINK_SPEED_32GHZ: 1945 + ae->un.AttrInt = HBA_PORTSPEED_32GBIT; 1946 + break; 1947 + default: 1948 + ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN; 1949 + break; 1950 + } 1951 + ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt); 1952 + size = FOURBYTES + sizeof(uint32_t); 1953 + ad->AttrLen = cpu_to_be16(size); 1954 + ad->AttrType = cpu_to_be16(RPRT_PORT_SPEED); 1955 + return size; 1956 + } 1957 + 1958 + int 1959 + lpfc_fdmi_port_attr_max_frame(struct lpfc_vport *vport, 1960 + struct lpfc_fdmi_attr_def *ad) 1961 + { 1962 + struct serv_parm *hsp; 1963 + struct lpfc_fdmi_attr_entry *ae; 1964 + uint32_t size; 1965 + 1966 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 1967 + 1968 + hsp = (struct serv_parm *)&vport->fc_sparam; 1969 + ae->un.AttrInt = (((uint32_t) hsp->cmn.bbRcvSizeMsb) << 8) | 1970 + (uint32_t) hsp->cmn.bbRcvSizeLsb; 1971 + ae->un.AttrInt = cpu_to_be32(ae->un.AttrInt); 1972 + size = FOURBYTES + sizeof(uint32_t); 1973 + ad->AttrLen = cpu_to_be16(size); 1974 + ad->AttrType = cpu_to_be16(RPRT_MAX_FRAME_SIZE); 1975 + return size; 1976 + } 1977 + 1978 + int 1979 + lpfc_fdmi_port_attr_os_devname(struct lpfc_vport *vport, 1980 + struct lpfc_fdmi_attr_def *ad) 1981 + { 1982 + struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 1983 + struct lpfc_fdmi_attr_entry *ae; 1984 + uint32_t len, size; 1985 + 1986 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 1987 + memset(ae, 0, 256); 1988 + 1989 + snprintf(ae->un.AttrString, sizeof(ae->un.AttrString), 1990 + "/sys/class/scsi_host/host%d", shost->host_no); 1991 + len = strnlen((char *)ae->un.AttrString, 1992 + sizeof(ae->un.AttrString)); 1993 + len += (len & 3) ? (4 - (len & 3)) : 4; 1994 + size = FOURBYTES + len; 1995 + ad->AttrLen = cpu_to_be16(size); 1996 + ad->AttrType = cpu_to_be16(RPRT_OS_DEVICE_NAME); 1997 + return size; 1998 + } 1999 + 2000 + int 2001 + lpfc_fdmi_port_attr_host_name(struct lpfc_vport *vport, 2002 + struct lpfc_fdmi_attr_def *ad) 2003 + { 2004 + struct lpfc_fdmi_attr_entry *ae; 2005 + uint32_t len, size; 2006 + 2007 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2008 + memset(ae, 0, 256); 2009 + 2010 + snprintf(ae->un.AttrString, sizeof(ae->un.AttrString), "%s", 2011 + init_utsname()->nodename); 2012 + 2013 + len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString)); 2014 + len += (len & 3) ? (4 - (len & 3)) : 4; 2015 + size = FOURBYTES + len; 2016 + ad->AttrLen = cpu_to_be16(size); 2017 + ad->AttrType = cpu_to_be16(RPRT_HOST_NAME); 2018 + return size; 2019 + } 2020 + 2021 + int 2022 + lpfc_fdmi_port_attr_wwnn(struct lpfc_vport *vport, 2023 + struct lpfc_fdmi_attr_def *ad) 2024 + { 2025 + struct lpfc_fdmi_attr_entry *ae; 2026 + uint32_t size; 2027 + 2028 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2029 + memset(ae, 0, sizeof(struct lpfc_name)); 2030 + 2031 + memcpy(&ae->un.AttrWWN, &vport->fc_sparam.nodeName, 2032 + sizeof(struct lpfc_name)); 2033 + size = FOURBYTES + sizeof(struct lpfc_name); 2034 + ad->AttrLen = cpu_to_be16(size); 2035 + ad->AttrType = cpu_to_be16(RPRT_NODENAME); 2036 + return size; 2037 + } 2038 + 2039 + int 2040 + lpfc_fdmi_port_attr_wwpn(struct lpfc_vport *vport, 2041 + struct lpfc_fdmi_attr_def *ad) 2042 + { 2043 + struct lpfc_fdmi_attr_entry *ae; 2044 + uint32_t size; 2045 + 2046 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2047 + memset(ae, 0, sizeof(struct lpfc_name)); 2048 + 2049 + memcpy(&ae->un.AttrWWN, &vport->fc_sparam.portName, 2050 + sizeof(struct lpfc_name)); 2051 + size = FOURBYTES + sizeof(struct lpfc_name); 2052 + ad->AttrLen = cpu_to_be16(size); 2053 + ad->AttrType = cpu_to_be16(RPRT_PORTNAME); 2054 + return size; 2055 + } 2056 + 2057 + int 2058 + lpfc_fdmi_port_attr_symbolic_name(struct lpfc_vport *vport, 2059 + struct lpfc_fdmi_attr_def *ad) 2060 + { 2061 + struct lpfc_fdmi_attr_entry *ae; 2062 + uint32_t len, size; 2063 + 2064 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2065 + memset(ae, 0, 256); 2066 + 2067 + len = lpfc_vport_symbolic_port_name(vport, ae->un.AttrString, 256); 2068 + len += (len & 3) ? (4 - (len & 3)) : 4; 2069 + size = FOURBYTES + len; 2070 + ad->AttrLen = cpu_to_be16(size); 2071 + ad->AttrType = cpu_to_be16(RPRT_SYM_PORTNAME); 2072 + return size; 2073 + } 2074 + 2075 + int 2076 + lpfc_fdmi_port_attr_port_type(struct lpfc_vport *vport, 2077 + struct lpfc_fdmi_attr_def *ad) 2078 + { 2079 + struct lpfc_hba *phba = vport->phba; 2080 + struct lpfc_fdmi_attr_entry *ae; 2081 + uint32_t size; 2082 + 2083 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2084 + if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) 2085 + ae->un.AttrInt = cpu_to_be32(LPFC_FDMI_PORTTYPE_NLPORT); 2086 + else 2087 + ae->un.AttrInt = cpu_to_be32(LPFC_FDMI_PORTTYPE_NPORT); 2088 + size = FOURBYTES + sizeof(uint32_t); 2089 + ad->AttrLen = cpu_to_be16(size); 2090 + ad->AttrType = cpu_to_be16(RPRT_PORT_TYPE); 2091 + return size; 2092 + } 2093 + 2094 + int 2095 + lpfc_fdmi_port_attr_class(struct lpfc_vport *vport, 2096 + struct lpfc_fdmi_attr_def *ad) 2097 + { 2098 + struct lpfc_fdmi_attr_entry *ae; 2099 + uint32_t size; 2100 + 2101 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2102 + ae->un.AttrInt = cpu_to_be32(FC_COS_CLASS2 | FC_COS_CLASS3); 2103 + size = FOURBYTES + sizeof(uint32_t); 2104 + ad->AttrLen = cpu_to_be16(size); 2105 + ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_CLASS); 2106 + return size; 2107 + } 2108 + 2109 + int 2110 + lpfc_fdmi_port_attr_fabric_wwpn(struct lpfc_vport *vport, 2111 + struct lpfc_fdmi_attr_def *ad) 2112 + { 2113 + struct lpfc_fdmi_attr_entry *ae; 2114 + uint32_t size; 2115 + 2116 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2117 + memset(ae, 0, sizeof(struct lpfc_name)); 2118 + 2119 + memcpy(&ae->un.AttrWWN, &vport->fabric_portname, 2120 + sizeof(struct lpfc_name)); 2121 + size = FOURBYTES + sizeof(struct lpfc_name); 2122 + ad->AttrLen = cpu_to_be16(size); 2123 + ad->AttrType = cpu_to_be16(RPRT_FABRICNAME); 2124 + return size; 2125 + } 2126 + 2127 + int 2128 + lpfc_fdmi_port_attr_active_fc4type(struct lpfc_vport *vport, 2129 + struct lpfc_fdmi_attr_def *ad) 2130 + { 2131 + struct lpfc_fdmi_attr_entry *ae; 2132 + uint32_t size; 2133 + 2134 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2135 + memset(ae, 0, 32); 2136 + 2137 + ae->un.AttrTypes[3] = 0x02; /* Type 1 - ELS */ 2138 + ae->un.AttrTypes[2] = 0x01; /* Type 8 - FCP */ 2139 + ae->un.AttrTypes[7] = 0x01; /* Type 32 - CT */ 2140 + size = FOURBYTES + 32; 2141 + ad->AttrLen = cpu_to_be16(size); 2142 + ad->AttrType = cpu_to_be16(RPRT_ACTIVE_FC4_TYPES); 2143 + return size; 2144 + } 2145 + 2146 + int 2147 + lpfc_fdmi_port_attr_port_state(struct lpfc_vport *vport, 2148 + struct lpfc_fdmi_attr_def *ad) 2149 + { 2150 + struct lpfc_fdmi_attr_entry *ae; 2151 + uint32_t size; 2152 + 2153 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2154 + /* Link Up - operational */ 2155 + ae->un.AttrInt = cpu_to_be32(LPFC_FDMI_PORTSTATE_ONLINE); 2156 + size = FOURBYTES + sizeof(uint32_t); 2157 + ad->AttrLen = cpu_to_be16(size); 2158 + ad->AttrType = cpu_to_be16(RPRT_PORT_STATE); 2159 + return size; 2160 + } 2161 + 2162 + int 2163 + lpfc_fdmi_port_attr_num_disc(struct lpfc_vport *vport, 2164 + struct lpfc_fdmi_attr_def *ad) 2165 + { 2166 + struct lpfc_fdmi_attr_entry *ae; 2167 + uint32_t size; 2168 + 2169 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2170 + vport->fdmi_num_disc = lpfc_find_map_node(vport); 2171 + ae->un.AttrInt = cpu_to_be32(vport->fdmi_num_disc); 2172 + size = FOURBYTES + sizeof(uint32_t); 2173 + ad->AttrLen = cpu_to_be16(size); 2174 + ad->AttrType = cpu_to_be16(RPRT_DISC_PORT); 2175 + return size; 2176 + } 2177 + 2178 + int 2179 + lpfc_fdmi_port_attr_nportid(struct lpfc_vport *vport, 2180 + struct lpfc_fdmi_attr_def *ad) 2181 + { 2182 + struct lpfc_fdmi_attr_entry *ae; 2183 + uint32_t size; 2184 + 2185 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2186 + ae->un.AttrInt = cpu_to_be32(vport->fc_myDID); 2187 + size = FOURBYTES + sizeof(uint32_t); 2188 + ad->AttrLen = cpu_to_be16(size); 2189 + ad->AttrType = cpu_to_be16(RPRT_PORT_ID); 2190 + return size; 2191 + } 2192 + 2193 + int 2194 + lpfc_fdmi_smart_attr_service(struct lpfc_vport *vport, 2195 + struct lpfc_fdmi_attr_def *ad) 2196 + { 2197 + struct lpfc_fdmi_attr_entry *ae; 2198 + uint32_t len, size; 2199 + 2200 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2201 + memset(ae, 0, 256); 2202 + 2203 + strncpy(ae->un.AttrString, "Smart SAN Initiator", 2204 + sizeof(ae->un.AttrString)); 2205 + len = strnlen(ae->un.AttrString, 2206 + sizeof(ae->un.AttrString)); 2207 + len += (len & 3) ? (4 - (len & 3)) : 4; 2208 + size = FOURBYTES + len; 2209 + ad->AttrLen = cpu_to_be16(size); 2210 + ad->AttrType = cpu_to_be16(RPRT_SMART_SERVICE); 2211 + return size; 2212 + } 2213 + 2214 + int 2215 + lpfc_fdmi_smart_attr_guid(struct lpfc_vport *vport, 2216 + struct lpfc_fdmi_attr_def *ad) 2217 + { 2218 + struct lpfc_fdmi_attr_entry *ae; 2219 + uint32_t size; 2220 + 2221 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2222 + memset(ae, 0, 256); 2223 + 2224 + memcpy(&ae->un.AttrString, &vport->fc_sparam.nodeName, 2225 + sizeof(struct lpfc_name)); 2226 + memcpy((((uint8_t *)&ae->un.AttrString) + 2227 + sizeof(struct lpfc_name)), 2228 + &vport->fc_sparam.portName, sizeof(struct lpfc_name)); 2229 + size = FOURBYTES + (2 * sizeof(struct lpfc_name)); 2230 + ad->AttrLen = cpu_to_be16(size); 2231 + ad->AttrType = cpu_to_be16(RPRT_SMART_GUID); 2232 + return size; 2233 + } 2234 + 2235 + int 2236 + lpfc_fdmi_smart_attr_version(struct lpfc_vport *vport, 2237 + struct lpfc_fdmi_attr_def *ad) 2238 + { 2239 + struct lpfc_fdmi_attr_entry *ae; 2240 + uint32_t len, size; 2241 + 2242 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2243 + memset(ae, 0, 256); 2244 + 2245 + strncpy(ae->un.AttrString, "Smart SAN Version 1.0", 2246 + sizeof(ae->un.AttrString)); 2247 + len = strnlen(ae->un.AttrString, 2248 + sizeof(ae->un.AttrString)); 2249 + len += (len & 3) ? (4 - (len & 3)) : 4; 2250 + size = FOURBYTES + len; 2251 + ad->AttrLen = cpu_to_be16(size); 2252 + ad->AttrType = cpu_to_be16(RPRT_SMART_VERSION); 2253 + return size; 2254 + } 2255 + 2256 + int 2257 + lpfc_fdmi_smart_attr_model(struct lpfc_vport *vport, 2258 + struct lpfc_fdmi_attr_def *ad) 2259 + { 2260 + struct lpfc_hba *phba = vport->phba; 2261 + struct lpfc_fdmi_attr_entry *ae; 2262 + uint32_t len, size; 2263 + 2264 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2265 + memset(ae, 0, 256); 2266 + 2267 + strncpy(ae->un.AttrString, phba->ModelName, 2268 + sizeof(ae->un.AttrString)); 2269 + len = strnlen(ae->un.AttrString, sizeof(ae->un.AttrString)); 2270 + len += (len & 3) ? (4 - (len & 3)) : 4; 2271 + size = FOURBYTES + len; 2272 + ad->AttrLen = cpu_to_be16(size); 2273 + ad->AttrType = cpu_to_be16(RPRT_SMART_MODEL); 2274 + return size; 2275 + } 2276 + 2277 + int 2278 + lpfc_fdmi_smart_attr_port_info(struct lpfc_vport *vport, 2279 + struct lpfc_fdmi_attr_def *ad) 2280 + { 2281 + struct lpfc_fdmi_attr_entry *ae; 2282 + uint32_t size; 2283 + 2284 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2285 + 2286 + /* SRIOV (type 3) is not supported */ 2287 + if (vport->vpi) 2288 + ae->un.AttrInt = cpu_to_be32(2); /* NPIV */ 2289 + else 2290 + ae->un.AttrInt = cpu_to_be32(1); /* Physical */ 2291 + size = FOURBYTES + sizeof(uint32_t); 2292 + ad->AttrLen = cpu_to_be16(size); 2293 + ad->AttrType = cpu_to_be16(RPRT_SMART_PORT_INFO); 2294 + return size; 2295 + } 2296 + 2297 + int 2298 + lpfc_fdmi_smart_attr_qos(struct lpfc_vport *vport, 2299 + struct lpfc_fdmi_attr_def *ad) 2300 + { 2301 + struct lpfc_fdmi_attr_entry *ae; 2302 + uint32_t size; 2303 + 2304 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2305 + ae->un.AttrInt = cpu_to_be32(0); 2306 + size = FOURBYTES + sizeof(uint32_t); 2307 + ad->AttrLen = cpu_to_be16(size); 2308 + ad->AttrType = cpu_to_be16(RPRT_SMART_QOS); 2309 + return size; 2310 + } 2311 + 2312 + int 2313 + lpfc_fdmi_smart_attr_security(struct lpfc_vport *vport, 2314 + struct lpfc_fdmi_attr_def *ad) 2315 + { 2316 + struct lpfc_fdmi_attr_entry *ae; 2317 + uint32_t size; 2318 + 2319 + ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2320 + ae->un.AttrInt = cpu_to_be32(0); 2321 + size = FOURBYTES + sizeof(uint32_t); 2322 + ad->AttrLen = cpu_to_be16(size); 2323 + ad->AttrType = cpu_to_be16(RPRT_SMART_SECURITY); 2324 + return size; 2325 + } 2326 + 2327 + /* RHBA attribute jump table */ 2328 + int (*lpfc_fdmi_hba_action[]) 2329 + (struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) = { 2330 + /* Action routine Mask bit Attribute type */ 2331 + lpfc_fdmi_hba_attr_wwnn, /* bit0 RHBA_NODENAME */ 2332 + lpfc_fdmi_hba_attr_manufacturer, /* bit1 RHBA_MANUFACTURER */ 2333 + lpfc_fdmi_hba_attr_sn, /* bit2 RHBA_SERIAL_NUMBER */ 2334 + lpfc_fdmi_hba_attr_model, /* bit3 RHBA_MODEL */ 2335 + lpfc_fdmi_hba_attr_description, /* bit4 RHBA_MODEL_DESCRIPTION */ 2336 + lpfc_fdmi_hba_attr_hdw_ver, /* bit5 RHBA_HARDWARE_VERSION */ 2337 + lpfc_fdmi_hba_attr_drvr_ver, /* bit6 RHBA_DRIVER_VERSION */ 2338 + lpfc_fdmi_hba_attr_rom_ver, /* bit7 RHBA_OPTION_ROM_VERSION */ 2339 + lpfc_fdmi_hba_attr_fmw_ver, /* bit8 RHBA_FIRMWARE_VERSION */ 2340 + lpfc_fdmi_hba_attr_os_ver, /* bit9 RHBA_OS_NAME_VERSION */ 2341 + lpfc_fdmi_hba_attr_ct_len, /* bit10 RHBA_MAX_CT_PAYLOAD_LEN */ 2342 + lpfc_fdmi_hba_attr_symbolic_name, /* bit11 RHBA_SYM_NODENAME */ 2343 + lpfc_fdmi_hba_attr_vendor_info, /* bit12 RHBA_VENDOR_INFO */ 2344 + lpfc_fdmi_hba_attr_num_ports, /* bit13 RHBA_NUM_PORTS */ 2345 + lpfc_fdmi_hba_attr_fabric_wwnn, /* bit14 RHBA_FABRIC_WWNN */ 2346 + lpfc_fdmi_hba_attr_bios_ver, /* bit15 RHBA_BIOS_VERSION */ 2347 + lpfc_fdmi_hba_attr_bios_state, /* bit16 RHBA_BIOS_STATE */ 2348 + lpfc_fdmi_hba_attr_vendor_id, /* bit17 RHBA_VENDOR_ID */ 2349 + }; 2350 + 2351 + /* RPA / RPRT attribute jump table */ 2352 + int (*lpfc_fdmi_port_action[]) 2353 + (struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad) = { 2354 + /* Action routine Mask bit Attribute type */ 2355 + lpfc_fdmi_port_attr_fc4type, /* bit0 RPRT_SUPPORT_FC4_TYPES */ 2356 + lpfc_fdmi_port_attr_support_speed, /* bit1 RPRT_SUPPORTED_SPEED */ 2357 + lpfc_fdmi_port_attr_speed, /* bit2 RPRT_PORT_SPEED */ 2358 + lpfc_fdmi_port_attr_max_frame, /* bit3 RPRT_MAX_FRAME_SIZE */ 2359 + lpfc_fdmi_port_attr_os_devname, /* bit4 RPRT_OS_DEVICE_NAME */ 2360 + lpfc_fdmi_port_attr_host_name, /* bit5 RPRT_HOST_NAME */ 2361 + lpfc_fdmi_port_attr_wwnn, /* bit6 RPRT_NODENAME */ 2362 + lpfc_fdmi_port_attr_wwpn, /* bit7 RPRT_PORTNAME */ 2363 + lpfc_fdmi_port_attr_symbolic_name, /* bit8 RPRT_SYM_PORTNAME */ 2364 + lpfc_fdmi_port_attr_port_type, /* bit9 RPRT_PORT_TYPE */ 2365 + lpfc_fdmi_port_attr_class, /* bit10 RPRT_SUPPORTED_CLASS */ 2366 + lpfc_fdmi_port_attr_fabric_wwpn, /* bit11 RPRT_FABRICNAME */ 2367 + lpfc_fdmi_port_attr_active_fc4type, /* bit12 RPRT_ACTIVE_FC4_TYPES */ 2368 + lpfc_fdmi_port_attr_port_state, /* bit13 RPRT_PORT_STATE */ 2369 + lpfc_fdmi_port_attr_num_disc, /* bit14 RPRT_DISC_PORT */ 2370 + lpfc_fdmi_port_attr_nportid, /* bit15 RPRT_PORT_ID */ 2371 + lpfc_fdmi_smart_attr_service, /* bit16 RPRT_SMART_SERVICE */ 2372 + lpfc_fdmi_smart_attr_guid, /* bit17 RPRT_SMART_GUID */ 2373 + lpfc_fdmi_smart_attr_version, /* bit18 RPRT_SMART_VERSION */ 2374 + lpfc_fdmi_smart_attr_model, /* bit19 RPRT_SMART_MODEL */ 2375 + lpfc_fdmi_smart_attr_port_info, /* bit20 RPRT_SMART_PORT_INFO */ 2376 + lpfc_fdmi_smart_attr_qos, /* bit21 RPRT_SMART_QOS */ 2377 + lpfc_fdmi_smart_attr_security, /* bit22 RPRT_SMART_SECURITY */ 2378 + }; 2379 + 2380 + /** 2381 + * lpfc_fdmi_cmd - Build and send a FDMI cmd to the specified NPort 2382 + * @vport: pointer to a host virtual N_Port data structure. 2383 + * @ndlp: ndlp to send FDMI cmd to (if NULL use FDMI_DID) 2384 + * cmdcode: FDMI command to send 2385 + * mask: Mask of HBA or PORT Attributes to send 2386 + * 2387 + * Builds and sends a FDMI command using the CT subsystem. 2388 + */ 2389 + int 2390 + lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, 2391 + int cmdcode, uint32_t new_mask) 1434 2392 { 1435 2393 struct lpfc_hba *phba = vport->phba; 1436 2394 struct lpfc_dmabuf *mp, *bmp; 1437 2395 struct lpfc_sli_ct_request *CtReq; 1438 2396 struct ulp_bde64 *bpl; 2397 + uint32_t bit_pos; 1439 2398 uint32_t size; 1440 2399 uint32_t rsp_size; 2400 + uint32_t mask; 1441 2401 struct lpfc_fdmi_reg_hba *rh; 1442 2402 struct lpfc_fdmi_port_entry *pe; 1443 2403 struct lpfc_fdmi_reg_portattr *pab = NULL; 1444 2404 struct lpfc_fdmi_attr_block *ab = NULL; 1445 - struct lpfc_fdmi_attr_entry *ae; 1446 - struct lpfc_fdmi_attr_def *ad; 1447 - void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *, 1448 - struct lpfc_iocbq *); 2405 + int (*func)(struct lpfc_vport *vport, struct lpfc_fdmi_attr_def *ad); 2406 + void (*cmpl)(struct lpfc_hba *, struct lpfc_iocbq *, 2407 + struct lpfc_iocbq *); 1449 2408 1450 - if (ndlp == NULL) { 1451 - ndlp = lpfc_findnode_did(vport, FDMI_DID); 1452 - if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) 1453 - return 0; 1454 - cmpl = lpfc_cmpl_ct_cmd_fdmi; /* cmd interface */ 1455 - } else { 1456 - cmpl = lpfc_cmpl_ct_disc_fdmi; /* called from discovery */ 1457 - } 2409 + if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) 2410 + return 0; 2411 + 2412 + cmpl = lpfc_cmpl_ct_disc_fdmi; /* called from discovery */ 1458 2413 1459 2414 /* fill in BDEs for command */ 1460 2415 /* Allocate buffer for command payload */ ··· 2485 1470 switch (cmdcode) { 2486 1471 case SLI_MGMT_RHAT: 2487 1472 case SLI_MGMT_RHBA: 2488 - { 2489 - lpfc_vpd_t *vp = &phba->vpd; 2490 - uint32_t i, j, incr; 2491 - int len = 0; 1473 + rh = (struct lpfc_fdmi_reg_hba *)&CtReq->un.PortID; 1474 + /* HBA Identifier */ 1475 + memcpy(&rh->hi.PortName, &phba->pport->fc_sparam.portName, 1476 + sizeof(struct lpfc_name)); 2492 1477 2493 - rh = (struct lpfc_fdmi_reg_hba *)&CtReq->un.PortID; 2494 - /* HBA Identifier */ 2495 - memcpy(&rh->hi.PortName, &vport->fc_sparam.portName, 1478 + if (cmdcode == SLI_MGMT_RHBA) { 1479 + /* Registered Port List */ 1480 + /* One entry (port) per adapter */ 1481 + rh->rpl.EntryCnt = cpu_to_be32(1); 1482 + memcpy(&rh->rpl.pe, &phba->pport->fc_sparam.portName, 2496 1483 sizeof(struct lpfc_name)); 2497 1484 2498 - if (cmdcode == SLI_MGMT_RHBA) { 2499 - /* Registered Port List */ 2500 - /* One entry (port) per adapter */ 2501 - rh->rpl.EntryCnt = cpu_to_be32(1); 2502 - memcpy(&rh->rpl.pe, &vport->fc_sparam.portName, 2503 - sizeof(struct lpfc_name)); 2504 - 2505 - /* point to the HBA attribute block */ 2506 - size = 2 * sizeof(struct lpfc_name) + 2507 - FOURBYTES; 2508 - } else { 2509 - size = sizeof(struct lpfc_name); 2510 - } 2511 - ab = (struct lpfc_fdmi_attr_block *) 2512 - ((uint8_t *)rh + size); 2513 - ab->EntryCnt = 0; 2514 - size += FOURBYTES; 2515 - 2516 - /* 2517 - * Point to beginning of first HBA attribute entry 2518 - */ 2519 - /* #1 HBA attribute entry */ 2520 - ad = (struct lpfc_fdmi_attr_def *) 2521 - ((uint8_t *)rh + size); 2522 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2523 - memset(ae, 0, sizeof(struct lpfc_name)); 2524 - ad->AttrType = cpu_to_be16(RHBA_NODENAME); 2525 - ad->AttrLen = cpu_to_be16(FOURBYTES 2526 - + sizeof(struct lpfc_name)); 2527 - memcpy(&ae->un.NodeName, &vport->fc_sparam.nodeName, 2528 - sizeof(struct lpfc_name)); 2529 - ab->EntryCnt++; 2530 - size += FOURBYTES + sizeof(struct lpfc_name); 2531 - if ((size + LPFC_FDMI_MAX_AE_SIZE) > 2532 - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 2533 - goto hba_out; 2534 - 2535 - /* #2 HBA attribute entry */ 2536 - ad = (struct lpfc_fdmi_attr_def *) 2537 - ((uint8_t *)rh + size); 2538 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2539 - memset(ae, 0, sizeof(ae->un.Manufacturer)); 2540 - ad->AttrType = cpu_to_be16(RHBA_MANUFACTURER); 2541 - strncpy(ae->un.Manufacturer, "Emulex Corporation", 2542 - sizeof(ae->un.Manufacturer)); 2543 - len = strnlen(ae->un.Manufacturer, 2544 - sizeof(ae->un.Manufacturer)); 2545 - len += (len & 3) ? (4 - (len & 3)) : 4; 2546 - ad->AttrLen = cpu_to_be16(FOURBYTES + len); 2547 - ab->EntryCnt++; 2548 - size += FOURBYTES + len; 2549 - if ((size + LPFC_FDMI_MAX_AE_SIZE) > 2550 - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 2551 - goto hba_out; 2552 - 2553 - /* #3 HBA attribute entry */ 2554 - ad = (struct lpfc_fdmi_attr_def *) 2555 - ((uint8_t *)rh + size); 2556 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2557 - memset(ae, 0, sizeof(ae->un.SerialNumber)); 2558 - ad->AttrType = cpu_to_be16(RHBA_SERIAL_NUMBER); 2559 - strncpy(ae->un.SerialNumber, phba->SerialNumber, 2560 - sizeof(ae->un.SerialNumber)); 2561 - len = strnlen(ae->un.SerialNumber, 2562 - sizeof(ae->un.SerialNumber)); 2563 - len += (len & 3) ? (4 - (len & 3)) : 4; 2564 - ad->AttrLen = cpu_to_be16(FOURBYTES + len); 2565 - ab->EntryCnt++; 2566 - size += FOURBYTES + len; 2567 - if ((size + LPFC_FDMI_MAX_AE_SIZE) > 2568 - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 2569 - goto hba_out; 2570 - 2571 - /* #4 HBA attribute entry */ 2572 - ad = (struct lpfc_fdmi_attr_def *) 2573 - ((uint8_t *)rh + size); 2574 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2575 - memset(ae, 0, sizeof(ae->un.Model)); 2576 - ad->AttrType = cpu_to_be16(RHBA_MODEL); 2577 - strncpy(ae->un.Model, phba->ModelName, 2578 - sizeof(ae->un.Model)); 2579 - len = strnlen(ae->un.Model, sizeof(ae->un.Model)); 2580 - len += (len & 3) ? (4 - (len & 3)) : 4; 2581 - ad->AttrLen = cpu_to_be16(FOURBYTES + len); 2582 - ab->EntryCnt++; 2583 - size += FOURBYTES + len; 2584 - if ((size + LPFC_FDMI_MAX_AE_SIZE) > 2585 - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 2586 - goto hba_out; 2587 - 2588 - /* #5 HBA attribute entry */ 2589 - ad = (struct lpfc_fdmi_attr_def *) 2590 - ((uint8_t *)rh + size); 2591 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2592 - memset(ae, 0, sizeof(ae->un.ModelDescription)); 2593 - ad->AttrType = cpu_to_be16(RHBA_MODEL_DESCRIPTION); 2594 - strncpy(ae->un.ModelDescription, phba->ModelDesc, 2595 - sizeof(ae->un.ModelDescription)); 2596 - len = strnlen(ae->un.ModelDescription, 2597 - sizeof(ae->un.ModelDescription)); 2598 - len += (len & 3) ? (4 - (len & 3)) : 4; 2599 - ad->AttrLen = cpu_to_be16(FOURBYTES + len); 2600 - ab->EntryCnt++; 2601 - size += FOURBYTES + len; 2602 - if ((size + 8) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 2603 - goto hba_out; 2604 - 2605 - /* #6 HBA attribute entry */ 2606 - ad = (struct lpfc_fdmi_attr_def *) 2607 - ((uint8_t *)rh + size); 2608 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2609 - memset(ae, 0, 8); 2610 - ad->AttrType = cpu_to_be16(RHBA_HARDWARE_VERSION); 2611 - ad->AttrLen = cpu_to_be16(FOURBYTES + 8); 2612 - /* Convert JEDEC ID to ascii for hardware version */ 2613 - incr = vp->rev.biuRev; 2614 - for (i = 0; i < 8; i++) { 2615 - j = (incr & 0xf); 2616 - if (j <= 9) 2617 - ae->un.HardwareVersion[7 - i] = 2618 - (char)((uint8_t)0x30 + 2619 - (uint8_t)j); 2620 - else 2621 - ae->un.HardwareVersion[7 - i] = 2622 - (char)((uint8_t)0x61 + 2623 - (uint8_t)(j - 10)); 2624 - incr = (incr >> 4); 2625 - } 2626 - ab->EntryCnt++; 2627 - size += FOURBYTES + 8; 2628 - if ((size + LPFC_FDMI_MAX_AE_SIZE) > 2629 - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 2630 - goto hba_out; 2631 - 2632 - /* #7 HBA attribute entry */ 2633 - ad = (struct lpfc_fdmi_attr_def *) 2634 - ((uint8_t *)rh + size); 2635 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2636 - memset(ae, 0, sizeof(ae->un.DriverVersion)); 2637 - ad->AttrType = cpu_to_be16(RHBA_DRIVER_VERSION); 2638 - strncpy(ae->un.DriverVersion, lpfc_release_version, 2639 - sizeof(ae->un.DriverVersion)); 2640 - len = strnlen(ae->un.DriverVersion, 2641 - sizeof(ae->un.DriverVersion)); 2642 - len += (len & 3) ? (4 - (len & 3)) : 4; 2643 - ad->AttrLen = cpu_to_be16(FOURBYTES + len); 2644 - ab->EntryCnt++; 2645 - size += FOURBYTES + len; 2646 - if ((size + LPFC_FDMI_MAX_AE_SIZE) > 2647 - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 2648 - goto hba_out; 2649 - 2650 - /* #8 HBA attribute entry */ 2651 - ad = (struct lpfc_fdmi_attr_def *) 2652 - ((uint8_t *)rh + size); 2653 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2654 - memset(ae, 0, sizeof(ae->un.OptionROMVersion)); 2655 - ad->AttrType = cpu_to_be16(RHBA_OPTION_ROM_VERSION); 2656 - strncpy(ae->un.OptionROMVersion, phba->OptionROMVersion, 2657 - sizeof(ae->un.OptionROMVersion)); 2658 - len = strnlen(ae->un.OptionROMVersion, 2659 - sizeof(ae->un.OptionROMVersion)); 2660 - len += (len & 3) ? (4 - (len & 3)) : 4; 2661 - ad->AttrLen = cpu_to_be16(FOURBYTES + len); 2662 - ab->EntryCnt++; 2663 - size += FOURBYTES + len; 2664 - if ((size + LPFC_FDMI_MAX_AE_SIZE) > 2665 - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 2666 - goto hba_out; 2667 - 2668 - /* #9 HBA attribute entry */ 2669 - ad = (struct lpfc_fdmi_attr_def *) 2670 - ((uint8_t *)rh + size); 2671 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2672 - memset(ae, 0, sizeof(ae->un.FirmwareVersion)); 2673 - ad->AttrType = cpu_to_be16(RHBA_FIRMWARE_VERSION); 2674 - lpfc_decode_firmware_rev(phba, ae->un.FirmwareVersion, 2675 - 1); 2676 - len = strnlen(ae->un.FirmwareVersion, 2677 - sizeof(ae->un.FirmwareVersion)); 2678 - len += (len & 3) ? (4 - (len & 3)) : 4; 2679 - ad->AttrLen = cpu_to_be16(FOURBYTES + len); 2680 - ab->EntryCnt++; 2681 - size += FOURBYTES + len; 2682 - if ((size + LPFC_FDMI_MAX_AE_SIZE) > 2683 - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 2684 - goto hba_out; 2685 - 2686 - /* #10 HBA attribute entry */ 2687 - ad = (struct lpfc_fdmi_attr_def *) 2688 - ((uint8_t *)rh + size); 2689 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2690 - memset(ae, 0, sizeof(ae->un.OsNameVersion)); 2691 - ad->AttrType = cpu_to_be16(RHBA_OS_NAME_VERSION); 2692 - snprintf(ae->un.OsNameVersion, 2693 - sizeof(ae->un.OsNameVersion), 2694 - "%s %s %s", 2695 - init_utsname()->sysname, 2696 - init_utsname()->release, 2697 - init_utsname()->version); 2698 - len = strnlen(ae->un.OsNameVersion, 2699 - sizeof(ae->un.OsNameVersion)); 2700 - len += (len & 3) ? (4 - (len & 3)) : 4; 2701 - ad->AttrLen = cpu_to_be16(FOURBYTES + len); 2702 - ab->EntryCnt++; 2703 - size += FOURBYTES + len; 2704 - if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 2705 - goto hba_out; 2706 - 2707 - /* #11 HBA attribute entry */ 2708 - ad = (struct lpfc_fdmi_attr_def *) 2709 - ((uint8_t *)rh + size); 2710 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2711 - ad->AttrType = 2712 - cpu_to_be16(RHBA_MAX_CT_PAYLOAD_LEN); 2713 - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); 2714 - ae->un.MaxCTPayloadLen = cpu_to_be32(LPFC_MAX_CT_SIZE); 2715 - ab->EntryCnt++; 2716 - size += FOURBYTES + 4; 2717 - if ((size + LPFC_FDMI_MAX_AE_SIZE) > 2718 - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 2719 - goto hba_out; 2720 - 2721 - /* 2722 - * Currently switches don't seem to support the 2723 - * following extended HBA attributes. 2724 - */ 2725 - if (!(vport->cfg_fdmi_on & LPFC_FDMI_ALL_ATTRIB)) 2726 - goto hba_out; 2727 - 2728 - /* #12 HBA attribute entry */ 2729 - ad = (struct lpfc_fdmi_attr_def *) 2730 - ((uint8_t *)rh + size); 2731 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2732 - memset(ae, 0, sizeof(ae->un.NodeSymName)); 2733 - ad->AttrType = cpu_to_be16(RHBA_SYM_NODENAME); 2734 - len = lpfc_vport_symbolic_node_name(vport, 2735 - ae->un.NodeSymName, sizeof(ae->un.NodeSymName)); 2736 - len += (len & 3) ? (4 - (len & 3)) : 4; 2737 - ad->AttrLen = cpu_to_be16(FOURBYTES + len); 2738 - ab->EntryCnt++; 2739 - size += FOURBYTES + len; 2740 - hba_out: 2741 - ab->EntryCnt = cpu_to_be32(ab->EntryCnt); 2742 - /* Total size */ 2743 - size = GID_REQUEST_SZ - 4 + size; 1485 + /* point to the HBA attribute block */ 1486 + size = 2 * sizeof(struct lpfc_name) + 1487 + FOURBYTES; 1488 + } else { 1489 + size = sizeof(struct lpfc_name); 2744 1490 } 1491 + ab = (struct lpfc_fdmi_attr_block *)((uint8_t *)rh + size); 1492 + ab->EntryCnt = 0; 1493 + size += FOURBYTES; 1494 + bit_pos = 0; 1495 + if (new_mask) 1496 + mask = new_mask; 1497 + else 1498 + mask = vport->fdmi_hba_mask; 1499 + 1500 + /* Mask will dictate what attributes to build in the request */ 1501 + while (mask) { 1502 + if (mask & 0x1) { 1503 + func = lpfc_fdmi_hba_action[bit_pos]; 1504 + size += func(vport, 1505 + (struct lpfc_fdmi_attr_def *) 1506 + ((uint8_t *)rh + size)); 1507 + ab->EntryCnt++; 1508 + if ((size + 256) > 1509 + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 1510 + goto hba_out; 1511 + } 1512 + mask = mask >> 1; 1513 + bit_pos++; 1514 + } 1515 + hba_out: 1516 + ab->EntryCnt = cpu_to_be32(ab->EntryCnt); 1517 + /* Total size */ 1518 + size = GID_REQUEST_SZ - 4 + size; 2745 1519 break; 2746 1520 2747 1521 case SLI_MGMT_RPRT: 2748 1522 case SLI_MGMT_RPA: 2749 - { 2750 - struct serv_parm *hsp; 2751 - int len = 0; 2752 - 2753 - if (cmdcode == SLI_MGMT_RPRT) { 2754 - rh = (struct lpfc_fdmi_reg_hba *) 2755 - &CtReq->un.PortID; 2756 - /* HBA Identifier */ 2757 - memcpy(&rh->hi.PortName, 2758 - &vport->fc_sparam.portName, 2759 - sizeof(struct lpfc_name)); 2760 - pab = (struct lpfc_fdmi_reg_portattr *) 2761 - &rh->rpl.EntryCnt; 2762 - } else 2763 - pab = (struct lpfc_fdmi_reg_portattr *) 2764 - &CtReq->un.PortID; 2765 - size = sizeof(struct lpfc_name) + FOURBYTES; 2766 - memcpy((uint8_t *)&pab->PortName, 2767 - (uint8_t *)&vport->fc_sparam.portName, 1523 + pab = (struct lpfc_fdmi_reg_portattr *)&CtReq->un.PortID; 1524 + if (cmdcode == SLI_MGMT_RPRT) { 1525 + rh = (struct lpfc_fdmi_reg_hba *)pab; 1526 + /* HBA Identifier */ 1527 + memcpy(&rh->hi.PortName, 1528 + &phba->pport->fc_sparam.portName, 2768 1529 sizeof(struct lpfc_name)); 2769 - pab->ab.EntryCnt = 0; 2770 - 2771 - /* #1 Port attribute entry */ 2772 - ad = (struct lpfc_fdmi_attr_def *) 2773 - ((uint8_t *)pab + size); 2774 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2775 - memset(ae, 0, sizeof(ae->un.FC4Types)); 2776 - ad->AttrType = 2777 - cpu_to_be16(RPRT_SUPPORTED_FC4_TYPES); 2778 - ad->AttrLen = cpu_to_be16(FOURBYTES + 32); 2779 - ae->un.FC4Types[0] = 0x40; /* Type 1 - ELS */ 2780 - ae->un.FC4Types[1] = 0x80; /* Type 8 - FCP */ 2781 - ae->un.FC4Types[4] = 0x80; /* Type 32 - CT */ 2782 - pab->ab.EntryCnt++; 2783 - size += FOURBYTES + 32; 2784 - 2785 - /* #2 Port attribute entry */ 2786 - ad = (struct lpfc_fdmi_attr_def *) 2787 - ((uint8_t *)pab + size); 2788 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2789 - ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_SPEED); 2790 - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); 2791 - ae->un.SupportSpeed = 0; 2792 - if (phba->lmt & LMT_32Gb) 2793 - ae->un.SupportSpeed |= HBA_PORTSPEED_32GBIT; 2794 - if (phba->lmt & LMT_16Gb) 2795 - ae->un.SupportSpeed |= HBA_PORTSPEED_16GBIT; 2796 - if (phba->lmt & LMT_10Gb) 2797 - ae->un.SupportSpeed |= HBA_PORTSPEED_10GBIT; 2798 - if (phba->lmt & LMT_8Gb) 2799 - ae->un.SupportSpeed |= HBA_PORTSPEED_8GBIT; 2800 - if (phba->lmt & LMT_4Gb) 2801 - ae->un.SupportSpeed |= HBA_PORTSPEED_4GBIT; 2802 - if (phba->lmt & LMT_2Gb) 2803 - ae->un.SupportSpeed |= HBA_PORTSPEED_2GBIT; 2804 - if (phba->lmt & LMT_1Gb) 2805 - ae->un.SupportSpeed |= HBA_PORTSPEED_1GBIT; 2806 - ae->un.SupportSpeed = 2807 - cpu_to_be32(ae->un.SupportSpeed); 2808 - 2809 - pab->ab.EntryCnt++; 2810 - size += FOURBYTES + 4; 2811 - 2812 - /* #3 Port attribute entry */ 2813 - ad = (struct lpfc_fdmi_attr_def *) 2814 - ((uint8_t *)pab + size); 2815 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2816 - ad->AttrType = cpu_to_be16(RPRT_PORT_SPEED); 2817 - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); 2818 - switch (phba->fc_linkspeed) { 2819 - case LPFC_LINK_SPEED_1GHZ: 2820 - ae->un.PortSpeed = HBA_PORTSPEED_1GBIT; 2821 - break; 2822 - case LPFC_LINK_SPEED_2GHZ: 2823 - ae->un.PortSpeed = HBA_PORTSPEED_2GBIT; 2824 - break; 2825 - case LPFC_LINK_SPEED_4GHZ: 2826 - ae->un.PortSpeed = HBA_PORTSPEED_4GBIT; 2827 - break; 2828 - case LPFC_LINK_SPEED_8GHZ: 2829 - ae->un.PortSpeed = HBA_PORTSPEED_8GBIT; 2830 - break; 2831 - case LPFC_LINK_SPEED_10GHZ: 2832 - ae->un.PortSpeed = HBA_PORTSPEED_10GBIT; 2833 - break; 2834 - case LPFC_LINK_SPEED_16GHZ: 2835 - ae->un.PortSpeed = HBA_PORTSPEED_16GBIT; 2836 - break; 2837 - case LPFC_LINK_SPEED_32GHZ: 2838 - ae->un.PortSpeed = HBA_PORTSPEED_32GBIT; 2839 - break; 2840 - default: 2841 - ae->un.PortSpeed = HBA_PORTSPEED_UNKNOWN; 2842 - break; 2843 - } 2844 - ae->un.PortSpeed = cpu_to_be32(ae->un.PortSpeed); 2845 - pab->ab.EntryCnt++; 2846 - size += FOURBYTES + 4; 2847 - 2848 - /* #4 Port attribute entry */ 2849 - ad = (struct lpfc_fdmi_attr_def *) 2850 - ((uint8_t *)pab + size); 2851 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2852 - ad->AttrType = cpu_to_be16(RPRT_MAX_FRAME_SIZE); 2853 - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); 2854 - hsp = (struct serv_parm *)&vport->fc_sparam; 2855 - ae->un.MaxFrameSize = 2856 - (((uint32_t)hsp->cmn. 2857 - bbRcvSizeMsb) << 8) | (uint32_t)hsp->cmn. 2858 - bbRcvSizeLsb; 2859 - ae->un.MaxFrameSize = 2860 - cpu_to_be32(ae->un.MaxFrameSize); 2861 - pab->ab.EntryCnt++; 2862 - size += FOURBYTES + 4; 2863 - if ((size + LPFC_FDMI_MAX_AE_SIZE) > 2864 - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 2865 - goto port_out; 2866 - 2867 - /* #5 Port attribute entry */ 2868 - ad = (struct lpfc_fdmi_attr_def *) 2869 - ((uint8_t *)pab + size); 2870 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2871 - memset(ae, 0, sizeof(ae->un.OsDeviceName)); 2872 - ad->AttrType = cpu_to_be16(RPRT_OS_DEVICE_NAME); 2873 - strncpy((char *)ae->un.OsDeviceName, LPFC_DRIVER_NAME, 2874 - sizeof(ae->un.OsDeviceName)); 2875 - len = strnlen((char *)ae->un.OsDeviceName, 2876 - sizeof(ae->un.OsDeviceName)); 2877 - len += (len & 3) ? (4 - (len & 3)) : 4; 2878 - ad->AttrLen = cpu_to_be16(FOURBYTES + len); 2879 - pab->ab.EntryCnt++; 2880 - size += FOURBYTES + len; 2881 - if ((size + LPFC_FDMI_MAX_AE_SIZE) > 2882 - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 2883 - goto port_out; 2884 - 2885 - /* #6 Port attribute entry */ 2886 - ad = (struct lpfc_fdmi_attr_def *) 2887 - ((uint8_t *)pab + size); 2888 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2889 - memset(ae, 0, sizeof(ae->un.HostName)); 2890 - snprintf(ae->un.HostName, sizeof(ae->un.HostName), "%s", 2891 - init_utsname()->nodename); 2892 - ad->AttrType = cpu_to_be16(RPRT_HOST_NAME); 2893 - len = strnlen(ae->un.HostName, 2894 - sizeof(ae->un.HostName)); 2895 - len += (len & 3) ? (4 - (len & 3)) : 4; 2896 - ad->AttrLen = 2897 - cpu_to_be16(FOURBYTES + len); 2898 - pab->ab.EntryCnt++; 2899 - size += FOURBYTES + len; 2900 - if ((size + sizeof(struct lpfc_name)) > 2901 - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 2902 - goto port_out; 2903 - 2904 - /* 2905 - * Currently switches don't seem to support the 2906 - * following extended Port attributes. 2907 - */ 2908 - if (!(vport->cfg_fdmi_on & LPFC_FDMI_ALL_ATTRIB)) 2909 - goto port_out; 2910 - 2911 - /* #7 Port attribute entry */ 2912 - ad = (struct lpfc_fdmi_attr_def *) 2913 - ((uint8_t *)pab + size); 2914 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2915 - memset(ae, 0, sizeof(struct lpfc_name)); 2916 - ad->AttrType = cpu_to_be16(RPRT_NODENAME); 2917 - ad->AttrLen = cpu_to_be16(FOURBYTES 2918 - + sizeof(struct lpfc_name)); 2919 - memcpy(&ae->un.NodeName, &vport->fc_sparam.nodeName, 2920 - sizeof(struct lpfc_name)); 2921 - pab->ab.EntryCnt++; 2922 - size += FOURBYTES + sizeof(struct lpfc_name); 2923 - if ((size + sizeof(struct lpfc_name)) > 2924 - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 2925 - goto port_out; 2926 - 2927 - /* #8 Port attribute entry */ 2928 - ad = (struct lpfc_fdmi_attr_def *) 2929 - ((uint8_t *)pab + size); 2930 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2931 - memset(ae, 0, sizeof(struct lpfc_name)); 2932 - ad->AttrType = cpu_to_be16(RPRT_PORTNAME); 2933 - ad->AttrLen = cpu_to_be16(FOURBYTES 2934 - + sizeof(struct lpfc_name)); 2935 - memcpy(&ae->un.PortName, &vport->fc_sparam.portName, 2936 - sizeof(struct lpfc_name)); 2937 - pab->ab.EntryCnt++; 2938 - size += FOURBYTES + sizeof(struct lpfc_name); 2939 - if ((size + LPFC_FDMI_MAX_AE_SIZE) > 2940 - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 2941 - goto port_out; 2942 - 2943 - /* #9 Port attribute entry */ 2944 - ad = (struct lpfc_fdmi_attr_def *) 2945 - ((uint8_t *)pab + size); 2946 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2947 - memset(ae, 0, sizeof(ae->un.NodeSymName)); 2948 - ad->AttrType = cpu_to_be16(RPRT_SYM_PORTNAME); 2949 - len = lpfc_vport_symbolic_port_name(vport, 2950 - ae->un.NodeSymName, sizeof(ae->un.NodeSymName)); 2951 - len += (len & 3) ? (4 - (len & 3)) : 4; 2952 - ad->AttrLen = cpu_to_be16(FOURBYTES + len); 2953 - pab->ab.EntryCnt++; 2954 - size += FOURBYTES + len; 2955 - if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 2956 - goto port_out; 2957 - 2958 - /* #10 Port attribute entry */ 2959 - ad = (struct lpfc_fdmi_attr_def *) 2960 - ((uint8_t *)pab + size); 2961 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2962 - ad->AttrType = cpu_to_be16(RPRT_PORT_TYPE); 2963 - ae->un.PortState = 0; 2964 - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); 2965 - pab->ab.EntryCnt++; 2966 - size += FOURBYTES + 4; 2967 - if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 2968 - goto port_out; 2969 - 2970 - /* #11 Port attribute entry */ 2971 - ad = (struct lpfc_fdmi_attr_def *) 2972 - ((uint8_t *)pab + size); 2973 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2974 - ad->AttrType = cpu_to_be16(RPRT_SUPPORTED_CLASS); 2975 - ae->un.SupportClass = 2976 - cpu_to_be32(FC_COS_CLASS2 | FC_COS_CLASS3); 2977 - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); 2978 - pab->ab.EntryCnt++; 2979 - size += FOURBYTES + 4; 2980 - if ((size + sizeof(struct lpfc_name)) > 2981 - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 2982 - goto port_out; 2983 - 2984 - /* #12 Port attribute entry */ 2985 - ad = (struct lpfc_fdmi_attr_def *) 2986 - ((uint8_t *)pab + size); 2987 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 2988 - memset(ae, 0, sizeof(struct lpfc_name)); 2989 - ad->AttrType = cpu_to_be16(RPRT_FABRICNAME); 2990 - ad->AttrLen = cpu_to_be16(FOURBYTES 2991 - + sizeof(struct lpfc_name)); 2992 - memcpy(&ae->un.FabricName, &vport->fabric_nodename, 2993 - sizeof(struct lpfc_name)); 2994 - pab->ab.EntryCnt++; 2995 - size += FOURBYTES + sizeof(struct lpfc_name); 2996 - if ((size + LPFC_FDMI_MAX_AE_SIZE) > 2997 - (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 2998 - goto port_out; 2999 - 3000 - /* #13 Port attribute entry */ 3001 - ad = (struct lpfc_fdmi_attr_def *) 3002 - ((uint8_t *)pab + size); 3003 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 3004 - memset(ae, 0, sizeof(ae->un.FC4Types)); 3005 - ad->AttrType = 3006 - cpu_to_be16(RPRT_ACTIVE_FC4_TYPES); 3007 - ad->AttrLen = cpu_to_be16(FOURBYTES + 32); 3008 - ae->un.FC4Types[0] = 0x40; /* Type 1 - ELS */ 3009 - ae->un.FC4Types[1] = 0x80; /* Type 8 - FCP */ 3010 - ae->un.FC4Types[4] = 0x80; /* Type 32 - CT */ 3011 - pab->ab.EntryCnt++; 3012 - size += FOURBYTES + 32; 3013 - if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 3014 - goto port_out; 3015 - 3016 - /* #257 Port attribute entry */ 3017 - ad = (struct lpfc_fdmi_attr_def *) 3018 - ((uint8_t *)pab + size); 3019 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 3020 - ad->AttrType = cpu_to_be16(RPRT_PORT_STATE); 3021 - ae->un.PortState = 0; 3022 - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); 3023 - pab->ab.EntryCnt++; 3024 - size += FOURBYTES + 4; 3025 - if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 3026 - goto port_out; 3027 - 3028 - /* #258 Port attribute entry */ 3029 - ad = (struct lpfc_fdmi_attr_def *) 3030 - ((uint8_t *)pab + size); 3031 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 3032 - ad->AttrType = cpu_to_be16(RPRT_DISC_PORT); 3033 - ae->un.PortState = lpfc_find_map_node(vport); 3034 - ae->un.PortState = cpu_to_be32(ae->un.PortState); 3035 - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); 3036 - pab->ab.EntryCnt++; 3037 - size += FOURBYTES + 4; 3038 - if ((size + 4) > (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 3039 - goto port_out; 3040 - 3041 - /* #259 Port attribute entry */ 3042 - ad = (struct lpfc_fdmi_attr_def *) 3043 - ((uint8_t *)pab + size); 3044 - ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue; 3045 - ad->AttrType = cpu_to_be16(RPRT_PORT_ID); 3046 - ae->un.PortId = cpu_to_be32(vport->fc_myDID); 3047 - ad->AttrLen = cpu_to_be16(FOURBYTES + 4); 3048 - pab->ab.EntryCnt++; 3049 - size += FOURBYTES + 4; 3050 - port_out: 3051 - pab->ab.EntryCnt = cpu_to_be32(pab->ab.EntryCnt); 3052 - /* Total size */ 3053 - size = GID_REQUEST_SZ - 4 + size; 1530 + pab = (struct lpfc_fdmi_reg_portattr *) 1531 + ((uint8_t *)pab + sizeof(struct lpfc_name)); 3054 1532 } 1533 + 1534 + memcpy((uint8_t *)&pab->PortName, 1535 + (uint8_t *)&vport->fc_sparam.portName, 1536 + sizeof(struct lpfc_name)); 1537 + size += sizeof(struct lpfc_name) + FOURBYTES; 1538 + pab->ab.EntryCnt = 0; 1539 + bit_pos = 0; 1540 + if (new_mask) 1541 + mask = new_mask; 1542 + else 1543 + mask = vport->fdmi_port_mask; 1544 + 1545 + /* Mask will dictate what attributes to build in the request */ 1546 + while (mask) { 1547 + if (mask & 0x1) { 1548 + func = lpfc_fdmi_port_action[bit_pos]; 1549 + size += func(vport, 1550 + (struct lpfc_fdmi_attr_def *) 1551 + ((uint8_t *)pab + size)); 1552 + pab->ab.EntryCnt++; 1553 + if ((size + 256) > 1554 + (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE)) 1555 + goto port_out; 1556 + } 1557 + mask = mask >> 1; 1558 + bit_pos++; 1559 + } 1560 + port_out: 1561 + pab->ab.EntryCnt = cpu_to_be32(pab->ab.EntryCnt); 1562 + /* Total size */ 1563 + if (cmdcode == SLI_MGMT_RPRT) 1564 + size += sizeof(struct lpfc_name); 1565 + size = GID_REQUEST_SZ - 4 + size; 3055 1566 break; 3056 1567 3057 1568 case SLI_MGMT_GHAT: ··· 2696 2155 spin_unlock_irq(shost->host_lock); 2697 2156 2698 2157 lpfc_do_scr_ns_plogi(vport->phba, vport); 2699 - } 2700 - 2701 - void 2702 - lpfc_fdmi_tmo(unsigned long ptr) 2703 - { 2704 - struct lpfc_vport *vport = (struct lpfc_vport *)ptr; 2705 - struct lpfc_hba *phba = vport->phba; 2706 - uint32_t tmo_posted; 2707 - unsigned long iflag; 2708 - 2709 - spin_lock_irqsave(&vport->work_port_lock, iflag); 2710 - tmo_posted = vport->work_port_events & WORKER_FDMI_TMO; 2711 - if (!tmo_posted) 2712 - vport->work_port_events |= WORKER_FDMI_TMO; 2713 - spin_unlock_irqrestore(&vport->work_port_lock, iflag); 2714 - 2715 - if (!tmo_posted) 2716 - lpfc_worker_wake_up(phba); 2717 - return; 2718 - } 2719 - 2720 - void 2721 - lpfc_fdmi_timeout_handler(struct lpfc_vport *vport) 2722 - { 2723 - struct lpfc_nodelist *ndlp; 2724 - 2725 - ndlp = lpfc_findnode_did(vport, FDMI_DID); 2726 - if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { 2727 - if (init_utsname()->nodename[0] != '\0') 2728 - lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA); 2729 - else 2730 - mod_timer(&vport->fc_fdmitmo, jiffies + 2731 - msecs_to_jiffies(1000 * 60)); 2732 - } 2733 - return; 2734 2158 } 2735 2159 2736 2160 void
+69 -30
drivers/scsi/lpfc/lpfc_els.c
··· 688 688 sp->cmn.bbRcvSizeLsb; 689 689 690 690 fabric_param_changed = lpfc_check_clean_addr_bit(vport, sp); 691 + if (fabric_param_changed) { 692 + /* Reset FDMI attribute masks based on config parameter */ 693 + if (phba->cfg_fdmi_on == LPFC_FDMI_NO_SUPPORT) { 694 + vport->fdmi_hba_mask = 0; 695 + vport->fdmi_port_mask = 0; 696 + } else { 697 + /* Setup appropriate attribute masks */ 698 + vport->fdmi_hba_mask = LPFC_FDMI2_HBA_ATTR; 699 + if (phba->cfg_fdmi_on == LPFC_FDMI_SMART_SAN) 700 + vport->fdmi_port_mask = LPFC_FDMI2_SMART_ATTR; 701 + else 702 + vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR; 703 + } 704 + 705 + } 691 706 memcpy(&vport->fabric_portname, &sp->portName, 692 707 sizeof(struct lpfc_name)); 693 708 memcpy(&vport->fabric_nodename, &sp->nodeName, ··· 4705 4690 desc->length = cpu_to_be32(sizeof(desc->info)); 4706 4691 } 4707 4692 4693 + int 4694 + lpfc_rdp_res_fec_desc(struct fc_fec_rdp_desc *desc, READ_LNK_VAR *stat) 4695 + { 4696 + if (bf_get(lpfc_read_link_stat_gec2, stat) == 0) 4697 + return 0; 4698 + desc->tag = cpu_to_be32(RDP_FEC_DESC_TAG); 4699 + 4700 + desc->info.CorrectedBlocks = 4701 + cpu_to_be32(stat->fecCorrBlkCount); 4702 + desc->info.UncorrectableBlocks = 4703 + cpu_to_be32(stat->fecUncorrBlkCount); 4704 + 4705 + desc->length = cpu_to_be32(sizeof(desc->info)); 4706 + 4707 + return sizeof(struct fc_fec_rdp_desc); 4708 + } 4709 + 4708 4710 void 4709 4711 lpfc_rdp_res_speed(struct fc_rdp_port_speed_desc *desc, struct lpfc_hba *phba) 4710 4712 { ··· 4832 4800 struct ls_rjt *stat; 4833 4801 struct fc_rdp_res_frame *rdp_res; 4834 4802 uint32_t cmdsize; 4835 - int rc; 4803 + int rc, fec_size; 4836 4804 4837 4805 if (status != SUCCESS) 4838 4806 goto error; ··· 4872 4840 lpfc_rdp_res_diag_port_names(&rdp_res->diag_port_names_desc, phba); 4873 4841 lpfc_rdp_res_attach_port_names(&rdp_res->attached_port_names_desc, 4874 4842 vport, ndlp); 4875 - rdp_res->length = cpu_to_be32(RDP_DESC_PAYLOAD_SIZE); 4876 - 4843 + fec_size = lpfc_rdp_res_fec_desc(&rdp_res->fec_desc, 4844 + &rdp_context->link_stat); 4845 + rdp_res->length = cpu_to_be32(fec_size + RDP_DESC_PAYLOAD_SIZE); 4877 4846 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; 4878 4847 4879 4848 phba->fc_stat.elsXmitACC++; ··· 7737 7704 } 7738 7705 } 7739 7706 7707 + void 7708 + lpfc_start_fdmi(struct lpfc_vport *vport) 7709 + { 7710 + struct lpfc_hba *phba = vport->phba; 7711 + struct lpfc_nodelist *ndlp; 7712 + 7713 + /* If this is the first time, allocate an ndlp and initialize 7714 + * it. Otherwise, make sure the node is enabled and then do the 7715 + * login. 7716 + */ 7717 + ndlp = lpfc_findnode_did(vport, FDMI_DID); 7718 + if (!ndlp) { 7719 + ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); 7720 + if (ndlp) { 7721 + lpfc_nlp_init(vport, ndlp, FDMI_DID); 7722 + ndlp->nlp_type |= NLP_FABRIC; 7723 + } else { 7724 + return; 7725 + } 7726 + } 7727 + if (!NLP_CHK_NODE_ACT(ndlp)) 7728 + ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_NPR_NODE); 7729 + 7730 + if (ndlp) { 7731 + lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); 7732 + lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0); 7733 + } 7734 + } 7735 + 7740 7736 /** 7741 7737 * lpfc_do_scr_ns_plogi - Issue a plogi to the name server for scr 7742 7738 * @phba: pointer to lpfc hba data structure. ··· 7782 7720 void 7783 7721 lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) 7784 7722 { 7785 - struct lpfc_nodelist *ndlp, *ndlp_fdmi; 7723 + struct lpfc_nodelist *ndlp; 7786 7724 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 7787 7725 7788 7726 /* ··· 7840 7778 return; 7841 7779 } 7842 7780 7843 - if (vport->cfg_fdmi_on & LPFC_FDMI_SUPPORT) { 7844 - /* If this is the first time, allocate an ndlp and initialize 7845 - * it. Otherwise, make sure the node is enabled and then do the 7846 - * login. 7847 - */ 7848 - ndlp_fdmi = lpfc_findnode_did(vport, FDMI_DID); 7849 - if (!ndlp_fdmi) { 7850 - ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool, 7851 - GFP_KERNEL); 7852 - if (ndlp_fdmi) { 7853 - lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID); 7854 - ndlp_fdmi->nlp_type |= NLP_FABRIC; 7855 - } else 7856 - return; 7857 - } 7858 - if (!NLP_CHK_NODE_ACT(ndlp_fdmi)) 7859 - ndlp_fdmi = lpfc_enable_node(vport, 7860 - ndlp_fdmi, 7861 - NLP_STE_NPR_NODE); 7862 - 7863 - if (ndlp_fdmi) { 7864 - lpfc_nlp_set_state(vport, ndlp_fdmi, 7865 - NLP_STE_PLOGI_ISSUE); 7866 - lpfc_issue_els_plogi(vport, ndlp_fdmi->nlp_DID, 0); 7867 - } 7868 - } 7781 + if ((phba->cfg_fdmi_on > LPFC_FDMI_NO_SUPPORT) && 7782 + (vport->load_flag & FC_ALLOW_FDMI)) 7783 + lpfc_start_fdmi(vport); 7869 7784 } 7870 7785 7871 7786 /**
+7 -9
drivers/scsi/lpfc/lpfc_hbadisc.c
··· 674 674 lpfc_mbox_timeout_handler(phba); 675 675 if (work_port_events & WORKER_FABRIC_BLOCK_TMO) 676 676 lpfc_unblock_fabric_iocbs(phba); 677 - if (work_port_events & WORKER_FDMI_TMO) 678 - lpfc_fdmi_timeout_handler(vport); 679 677 if (work_port_events & WORKER_RAMP_DOWN_QUEUE) 680 678 lpfc_ramp_down_queue_handler(phba); 681 679 if (work_port_events & WORKER_DELAYED_DISC_TMO) ··· 5552 5554 ndlp->nlp_usg_map, ndlp); 5553 5555 /* 5554 5556 * Start issuing Fabric-Device Management Interface (FDMI) command to 5555 - * 0xfffffa (FDMI well known port) or Delay issuing FDMI command if 5556 - * fdmi-on=2 (supporting RPA/hostnmae) 5557 + * 0xfffffa (FDMI well known port). 5558 + * DHBA -> DPRT -> RHBA -> RPA (physical port) 5559 + * DPRT -> RPRT (vports) 5557 5560 */ 5558 - 5559 - if (vport->cfg_fdmi_on & LPFC_FDMI_REG_DELAY) 5560 - mod_timer(&vport->fc_fdmitmo, 5561 - jiffies + msecs_to_jiffies(1000 * 60)); 5561 + if (vport->port_type == LPFC_PHYSICAL_PORT) 5562 + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0); 5562 5563 else 5563 - lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA); 5564 + lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT, 0); 5565 + 5564 5566 5565 5567 /* decrement the node reference count held for this callback 5566 5568 * function.
+151 -33
drivers/scsi/lpfc/lpfc_hw.h
··· 1097 1097 }; 1098 1098 1099 1099 1100 + struct fc_rdp_fec_info { 1101 + uint32_t CorrectedBlocks; 1102 + uint32_t UncorrectableBlocks; 1103 + }; 1104 + 1105 + #define RDP_FEC_DESC_TAG 0x00010005 1106 + struct fc_fec_rdp_desc { 1107 + uint32_t tag; 1108 + uint32_t length; 1109 + struct fc_rdp_fec_info info; 1110 + }; 1111 + 1100 1112 struct fc_rdp_link_error_status_payload_info { 1101 1113 struct fc_link_status link_status; /* 24 bytes */ 1102 1114 uint32_t port_type; /* bits 31-30 only */ ··· 1208 1196 struct fc_rdp_link_error_status_desc link_error_desc; /* Word 13-21 */ 1209 1197 struct fc_rdp_port_name_desc diag_port_names_desc; /* Word 22-27 */ 1210 1198 struct fc_rdp_port_name_desc attached_port_names_desc;/* Word 28-33 */ 1199 + struct fc_fec_rdp_desc fec_desc; /* FC Word 34 - 37 */ 1211 1200 }; 1212 1201 1213 1202 1214 1203 #define RDP_DESC_PAYLOAD_SIZE (sizeof(struct fc_rdp_link_service_desc) \ 1215 - + sizeof(struct fc_rdp_sfp_desc) \ 1216 - + sizeof(struct fc_rdp_port_speed_desc) \ 1217 - + sizeof(struct fc_rdp_link_error_status_desc) \ 1218 - + (sizeof(struct fc_rdp_port_name_desc) * 2)) 1204 + + sizeof(struct fc_rdp_sfp_desc) \ 1205 + + sizeof(struct fc_rdp_port_speed_desc) \ 1206 + + sizeof(struct fc_rdp_link_error_status_desc) \ 1207 + + (sizeof(struct fc_rdp_port_name_desc) * 2)) 1219 1208 1220 1209 1221 1210 /******** FDMI ********/ ··· 1246 1233 /* Attribute Entry */ 1247 1234 struct lpfc_fdmi_attr_entry { 1248 1235 union { 1249 - uint32_t VendorSpecific; 1250 - uint32_t SupportClass; 1251 - uint32_t SupportSpeed; 1252 - uint32_t PortSpeed; 1253 - uint32_t MaxFrameSize; 1254 - uint32_t MaxCTPayloadLen; 1255 - uint32_t PortState; 1256 - uint32_t PortId; 1257 - struct lpfc_name NodeName; 1258 - struct lpfc_name PortName; 1259 - struct lpfc_name FabricName; 1260 - uint8_t FC4Types[32]; 1261 - uint8_t Manufacturer[64]; 1262 - uint8_t SerialNumber[64]; 1263 - uint8_t Model[256]; 1264 - uint8_t ModelDescription[256]; 1265 - uint8_t HardwareVersion[256]; 1266 - uint8_t DriverVersion[256]; 1267 - uint8_t OptionROMVersion[256]; 1268 - uint8_t FirmwareVersion[256]; 1269 - uint8_t OsHostName[256]; 1270 - uint8_t NodeSymName[256]; 1271 - uint8_t OsDeviceName[256]; 1272 - uint8_t OsNameVersion[256]; 1273 - uint8_t HostName[256]; 1236 + uint32_t AttrInt; 1237 + uint8_t AttrTypes[32]; 1238 + uint8_t AttrString[256]; 1239 + struct lpfc_name AttrWWN; 1274 1240 } un; 1275 1241 }; 1276 1242 ··· 1319 1327 #define SLI_MGMT_DPRT 0x310 /* De-register Port */ 1320 1328 #define SLI_MGMT_DPA 0x311 /* De-register Port attributes */ 1321 1329 1330 + #define LPFC_FDMI_MAX_RETRY 3 /* Max retries for a FDMI command */ 1331 + 1322 1332 /* 1323 1333 * HBA Attribute Types 1324 1334 */ ··· 1336 1342 #define RHBA_OS_NAME_VERSION 0xa /* 4 to 256 byte ASCII string */ 1337 1343 #define RHBA_MAX_CT_PAYLOAD_LEN 0xb /* 32-bit unsigned int */ 1338 1344 #define RHBA_SYM_NODENAME 0xc /* 4 to 256 byte ASCII string */ 1345 + #define RHBA_VENDOR_INFO 0xd /* 32-bit unsigned int */ 1346 + #define RHBA_NUM_PORTS 0xe /* 32-bit unsigned int */ 1347 + #define RHBA_FABRIC_WWNN 0xf /* 8 byte WWNN */ 1348 + #define RHBA_BIOS_VERSION 0x10 /* 4 to 256 byte ASCII string */ 1349 + #define RHBA_BIOS_STATE 0x11 /* 32-bit unsigned int */ 1350 + #define RHBA_VENDOR_ID 0xe0 /* 8 byte ASCII string */ 1351 + 1352 + /* Bit mask for all individual HBA attributes */ 1353 + #define LPFC_FDMI_HBA_ATTR_wwnn 0x00000001 1354 + #define LPFC_FDMI_HBA_ATTR_manufacturer 0x00000002 1355 + #define LPFC_FDMI_HBA_ATTR_sn 0x00000004 1356 + #define LPFC_FDMI_HBA_ATTR_model 0x00000008 1357 + #define LPFC_FDMI_HBA_ATTR_description 0x00000010 1358 + #define LPFC_FDMI_HBA_ATTR_hdw_ver 0x00000020 1359 + #define LPFC_FDMI_HBA_ATTR_drvr_ver 0x00000040 1360 + #define LPFC_FDMI_HBA_ATTR_rom_ver 0x00000080 1361 + #define LPFC_FDMI_HBA_ATTR_fmw_ver 0x00000100 1362 + #define LPFC_FDMI_HBA_ATTR_os_ver 0x00000200 1363 + #define LPFC_FDMI_HBA_ATTR_ct_len 0x00000400 1364 + #define LPFC_FDMI_HBA_ATTR_symbolic_name 0x00000800 1365 + #define LPFC_FDMI_HBA_ATTR_vendor_info 0x00001000 /* Not used */ 1366 + #define LPFC_FDMI_HBA_ATTR_num_ports 0x00002000 1367 + #define LPFC_FDMI_HBA_ATTR_fabric_wwnn 0x00004000 1368 + #define LPFC_FDMI_HBA_ATTR_bios_ver 0x00008000 1369 + #define LPFC_FDMI_HBA_ATTR_bios_state 0x00010000 /* Not used */ 1370 + #define LPFC_FDMI_HBA_ATTR_vendor_id 0x00020000 1371 + 1372 + /* Bit mask for FDMI-1 defined HBA attributes */ 1373 + #define LPFC_FDMI1_HBA_ATTR 0x000007ff 1374 + 1375 + /* Bit mask for FDMI-2 defined HBA attributes */ 1376 + /* Skip vendor_info and bios_state */ 1377 + #define LPFC_FDMI2_HBA_ATTR 0x0002efff 1339 1378 1340 1379 /* 1341 1380 * Port Attrubute Types ··· 1380 1353 #define RPRT_OS_DEVICE_NAME 0x5 /* 4 to 256 byte ASCII string */ 1381 1354 #define RPRT_HOST_NAME 0x6 /* 4 to 256 byte ASCII string */ 1382 1355 #define RPRT_NODENAME 0x7 /* 8 byte WWNN */ 1383 - #define RPRT_PORTNAME 0x8 /* 8 byte WWNN */ 1356 + #define RPRT_PORTNAME 0x8 /* 8 byte WWPN */ 1384 1357 #define RPRT_SYM_PORTNAME 0x9 /* 4 to 256 byte ASCII string */ 1385 1358 #define RPRT_PORT_TYPE 0xa /* 32-bit unsigned int */ 1386 1359 #define RPRT_SUPPORTED_CLASS 0xb /* 32-bit unsigned int */ 1387 - #define RPRT_FABRICNAME 0xc /* 8 byte Fabric WWNN */ 1360 + #define RPRT_FABRICNAME 0xc /* 8 byte Fabric WWPN */ 1388 1361 #define RPRT_ACTIVE_FC4_TYPES 0xd /* 32 byte binary array */ 1389 1362 #define RPRT_PORT_STATE 0x101 /* 32-bit unsigned int */ 1390 1363 #define RPRT_DISC_PORT 0x102 /* 32-bit unsigned int */ 1391 1364 #define RPRT_PORT_ID 0x103 /* 32-bit unsigned int */ 1365 + #define RPRT_SMART_SERVICE 0xf100 /* 4 to 256 byte ASCII string */ 1366 + #define RPRT_SMART_GUID 0xf101 /* 8 byte WWNN + 8 byte WWPN */ 1367 + #define RPRT_SMART_VERSION 0xf102 /* 4 to 256 byte ASCII string */ 1368 + #define RPRT_SMART_MODEL 0xf103 /* 4 to 256 byte ASCII string */ 1369 + #define RPRT_SMART_PORT_INFO 0xf104 /* 32-bit unsigned int */ 1370 + #define RPRT_SMART_QOS 0xf105 /* 32-bit unsigned int */ 1371 + #define RPRT_SMART_SECURITY 0xf106 /* 32-bit unsigned int */ 1372 + 1373 + /* Bit mask for all individual PORT attributes */ 1374 + #define LPFC_FDMI_PORT_ATTR_fc4type 0x00000001 1375 + #define LPFC_FDMI_PORT_ATTR_support_speed 0x00000002 1376 + #define LPFC_FDMI_PORT_ATTR_speed 0x00000004 1377 + #define LPFC_FDMI_PORT_ATTR_max_frame 0x00000008 1378 + #define LPFC_FDMI_PORT_ATTR_os_devname 0x00000010 1379 + #define LPFC_FDMI_PORT_ATTR_host_name 0x00000020 1380 + #define LPFC_FDMI_PORT_ATTR_wwnn 0x00000040 1381 + #define LPFC_FDMI_PORT_ATTR_wwpn 0x00000080 1382 + #define LPFC_FDMI_PORT_ATTR_symbolic_name 0x00000100 1383 + #define LPFC_FDMI_PORT_ATTR_port_type 0x00000200 1384 + #define LPFC_FDMI_PORT_ATTR_class 0x00000400 1385 + #define LPFC_FDMI_PORT_ATTR_fabric_wwpn 0x00000800 1386 + #define LPFC_FDMI_PORT_ATTR_port_state 0x00001000 1387 + #define LPFC_FDMI_PORT_ATTR_active_fc4type 0x00002000 1388 + #define LPFC_FDMI_PORT_ATTR_num_disc 0x00004000 1389 + #define LPFC_FDMI_PORT_ATTR_nportid 0x00008000 1390 + #define LPFC_FDMI_SMART_ATTR_service 0x00010000 /* Vendor specific */ 1391 + #define LPFC_FDMI_SMART_ATTR_guid 0x00020000 /* Vendor specific */ 1392 + #define LPFC_FDMI_SMART_ATTR_version 0x00040000 /* Vendor specific */ 1393 + #define LPFC_FDMI_SMART_ATTR_model 0x00080000 /* Vendor specific */ 1394 + #define LPFC_FDMI_SMART_ATTR_port_info 0x00100000 /* Vendor specific */ 1395 + #define LPFC_FDMI_SMART_ATTR_qos 0x00200000 /* Vendor specific */ 1396 + #define LPFC_FDMI_SMART_ATTR_security 0x00400000 /* Vendor specific */ 1397 + 1398 + /* Bit mask for FDMI-1 defined PORT attributes */ 1399 + #define LPFC_FDMI1_PORT_ATTR 0x0000003f 1400 + 1401 + /* Bit mask for FDMI-2 defined PORT attributes */ 1402 + #define LPFC_FDMI2_PORT_ATTR 0x0000ffff 1403 + 1404 + /* Bit mask for Smart SAN defined PORT attributes */ 1405 + #define LPFC_FDMI2_SMART_ATTR 0x007fffff 1406 + 1407 + /* Defines for PORT port state attribute */ 1408 + #define LPFC_FDMI_PORTSTATE_UNKNOWN 1 1409 + #define LPFC_FDMI_PORTSTATE_ONLINE 2 1410 + 1411 + /* Defines for PORT port type attribute */ 1412 + #define LPFC_FDMI_PORTTYPE_UNKNOWN 0 1413 + #define LPFC_FDMI_PORTTYPE_NPORT 1 1414 + #define LPFC_FDMI_PORTTYPE_NLPORT 2 1392 1415 1393 1416 /* 1394 1417 * Begin HBA configuration parameters. ··· 2575 2498 /* Structure for MB Command READ_LINK_STAT (18) */ 2576 2499 2577 2500 typedef struct { 2578 - uint32_t rsvd1; 2501 + uint32_t word0; 2502 + 2503 + #define lpfc_read_link_stat_rec_SHIFT 0 2504 + #define lpfc_read_link_stat_rec_MASK 0x1 2505 + #define lpfc_read_link_stat_rec_WORD word0 2506 + 2507 + #define lpfc_read_link_stat_gec_SHIFT 1 2508 + #define lpfc_read_link_stat_gec_MASK 0x1 2509 + #define lpfc_read_link_stat_gec_WORD word0 2510 + 2511 + #define lpfc_read_link_stat_w02oftow23of_SHIFT 2 2512 + #define lpfc_read_link_stat_w02oftow23of_MASK 0x3FFFFF 2513 + #define lpfc_read_link_stat_w02oftow23of_WORD word0 2514 + 2515 + #define lpfc_read_link_stat_rsvd_SHIFT 24 2516 + #define lpfc_read_link_stat_rsvd_MASK 0x1F 2517 + #define lpfc_read_link_stat_rsvd_WORD word0 2518 + 2519 + #define lpfc_read_link_stat_gec2_SHIFT 29 2520 + #define lpfc_read_link_stat_gec2_MASK 0x1 2521 + #define lpfc_read_link_stat_gec2_WORD word0 2522 + 2523 + #define lpfc_read_link_stat_clrc_SHIFT 30 2524 + #define lpfc_read_link_stat_clrc_MASK 0x1 2525 + #define lpfc_read_link_stat_clrc_WORD word0 2526 + 2527 + #define lpfc_read_link_stat_clof_SHIFT 31 2528 + #define lpfc_read_link_stat_clof_MASK 0x1 2529 + #define lpfc_read_link_stat_clof_WORD word0 2530 + 2579 2531 uint32_t linkFailureCnt; 2580 2532 uint32_t lossSyncCnt; 2581 - 2582 2533 uint32_t lossSignalCnt; 2583 2534 uint32_t primSeqErrCnt; 2584 2535 uint32_t invalidXmitWord; ··· 2614 2509 uint32_t primSeqTimeout; 2615 2510 uint32_t elasticOverrun; 2616 2511 uint32_t arbTimeout; 2512 + uint32_t advRecBufCredit; 2513 + uint32_t curRecBufCredit; 2514 + uint32_t advTransBufCredit; 2515 + uint32_t curTransBufCredit; 2516 + uint32_t recEofCount; 2517 + uint32_t recEofdtiCount; 2518 + uint32_t recEofniCount; 2519 + uint32_t recSofcount; 2520 + uint32_t rsvd1; 2521 + uint32_t rsvd2; 2522 + uint32_t recDrpXriCount; 2523 + uint32_t fecCorrBlkCount; 2524 + uint32_t fecUncorrBlkCount; 2617 2525 } READ_LNK_VAR; 2618 2526 2619 2527 /* Structure for MB Command REG_LOGIN (19) */
+21 -6
drivers/scsi/lpfc/lpfc_init.c
··· 1184 1184 1185 1185 vports = lpfc_create_vport_work_array(phba); 1186 1186 if (vports != NULL) 1187 - for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) 1187 + for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { 1188 1188 lpfc_rcv_seq_check_edtov(vports[i]); 1189 + lpfc_fdmi_num_disc_check(vports[i]); 1190 + } 1189 1191 lpfc_destroy_vport_work_array(phba, vports); 1190 1192 1191 1193 if ((phba->link_state == LPFC_HBA_ERROR) || ··· 1292 1290 jiffies + 1293 1291 msecs_to_jiffies(1000 * LPFC_HB_MBOX_TIMEOUT)); 1294 1292 } 1293 + } else { 1294 + mod_timer(&phba->hb_tmofunc, 1295 + jiffies + 1296 + msecs_to_jiffies(1000 * LPFC_HB_MBOX_INTERVAL)); 1295 1297 } 1296 1298 } 1297 1299 ··· 2627 2621 lpfc_stop_vport_timers(struct lpfc_vport *vport) 2628 2622 { 2629 2623 del_timer_sync(&vport->els_tmofunc); 2630 - del_timer_sync(&vport->fc_fdmitmo); 2631 2624 del_timer_sync(&vport->delayed_disc_tmo); 2632 2625 lpfc_can_disctmo(vport); 2633 2626 return; ··· 3344 3339 init_timer(&vport->fc_disctmo); 3345 3340 vport->fc_disctmo.function = lpfc_disc_timeout; 3346 3341 vport->fc_disctmo.data = (unsigned long)vport; 3347 - 3348 - init_timer(&vport->fc_fdmitmo); 3349 - vport->fc_fdmitmo.function = lpfc_fdmi_tmo; 3350 - vport->fc_fdmitmo.data = (unsigned long)vport; 3351 3342 3352 3343 init_timer(&vport->els_tmofunc); 3353 3344 vport->els_tmofunc.function = lpfc_els_timeout; ··· 6160 6159 /* Put reference to SCSI host to driver's device private data */ 6161 6160 pci_set_drvdata(phba->pcidev, shost); 6162 6161 6162 + /* 6163 + * At this point we are fully registered with PSA. In addition, 6164 + * any initial discovery should be completed. 6165 + */ 6166 + vport->load_flag |= FC_ALLOW_FDMI; 6167 + if (phba->cfg_fdmi_on > LPFC_FDMI_NO_SUPPORT) { 6168 + 6169 + /* Setup appropriate attribute masks */ 6170 + vport->fdmi_hba_mask = LPFC_FDMI2_HBA_ATTR; 6171 + if (phba->cfg_fdmi_on == LPFC_FDMI_SMART_SAN) 6172 + vport->fdmi_port_mask = LPFC_FDMI2_SMART_ATTR; 6173 + else 6174 + vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR; 6175 + } 6163 6176 return 0; 6164 6177 } 6165 6178
+8
drivers/scsi/lpfc/lpfc_vport.c
··· 393 393 *(struct lpfc_vport **)fc_vport->dd_data = vport; 394 394 vport->fc_vport = fc_vport; 395 395 396 + /* At this point we are fully registered with SCSI Layer. */ 397 + vport->load_flag |= FC_ALLOW_FDMI; 398 + if (phba->cfg_fdmi_on > LPFC_FDMI_NO_SUPPORT) { 399 + /* Setup appropriate attribute masks */ 400 + vport->fdmi_hba_mask = phba->pport->fdmi_hba_mask; 401 + vport->fdmi_port_mask = phba->pport->fdmi_port_mask; 402 + } 403 + 396 404 /* 397 405 * In SLI4, the vpi must be activated before it can be used 398 406 * by the port.