diff options
author | James Smart <James.Smart@Emulex.Com> | 2009-05-22 14:52:59 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-06-08 12:25:24 -0400 |
commit | 6fb120a7ed882aae9636545142a51cf3182a3ace (patch) | |
tree | 7e830b09907286288f20f60c0f104d5fbec9998d /drivers | |
parent | 04c684968487eb4f98728363a97b8da48f3bb958 (diff) |
[SCSI] lpfc 8.3.2 : Addition of SLI4 Interface - FCOE Discovery support
SLI4 supports both FC and FCOE, with some extended topology objects.
This patch adss support for the objects, and updates the disovery
engines for their use.
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 32 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_crtn.h | 3 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 179 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 1055 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_nportdisc.c | 34 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 517 |
6 files changed, 1756 insertions, 64 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 463104d96867..270a4c6cd3ac 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -2924,6 +2924,14 @@ LPFC_ATTR_R(enable_hba_heartbeat, 1, 0, 1, "Enable HBA Heartbeat."); | |||
2924 | */ | 2924 | */ |
2925 | LPFC_ATTR_R(enable_bg, 0, 0, 1, "Enable BlockGuard Support"); | 2925 | LPFC_ATTR_R(enable_bg, 0, 0, 1, "Enable BlockGuard Support"); |
2926 | 2926 | ||
2927 | /* | ||
2928 | # lpfc_enable_fip: When set, FIP is required to start discovery. If not | ||
2929 | # set, the driver will add an FCF record manually if the port has no | ||
2930 | # FCF records available and start discovery. | ||
2931 | # Value range is [0,1]. Default value is 1 (enabled) | ||
2932 | */ | ||
2933 | LPFC_ATTR_RW(enable_fip, 0, 0, 1, "Enable FIP Discovery"); | ||
2934 | |||
2927 | 2935 | ||
2928 | /* | 2936 | /* |
2929 | # lpfc_prot_mask: i | 2937 | # lpfc_prot_mask: i |
@@ -2990,6 +2998,7 @@ struct device_attribute *lpfc_hba_attrs[] = { | |||
2990 | &dev_attr_lpfc_peer_port_login, | 2998 | &dev_attr_lpfc_peer_port_login, |
2991 | &dev_attr_lpfc_nodev_tmo, | 2999 | &dev_attr_lpfc_nodev_tmo, |
2992 | &dev_attr_lpfc_devloss_tmo, | 3000 | &dev_attr_lpfc_devloss_tmo, |
3001 | &dev_attr_lpfc_enable_fip, | ||
2993 | &dev_attr_lpfc_fcp_class, | 3002 | &dev_attr_lpfc_fcp_class, |
2994 | &dev_attr_lpfc_use_adisc, | 3003 | &dev_attr_lpfc_use_adisc, |
2995 | &dev_attr_lpfc_ack0, | 3004 | &dev_attr_lpfc_ack0, |
@@ -3042,6 +3051,7 @@ struct device_attribute *lpfc_vport_attrs[] = { | |||
3042 | &dev_attr_lpfc_lun_queue_depth, | 3051 | &dev_attr_lpfc_lun_queue_depth, |
3043 | &dev_attr_lpfc_nodev_tmo, | 3052 | &dev_attr_lpfc_nodev_tmo, |
3044 | &dev_attr_lpfc_devloss_tmo, | 3053 | &dev_attr_lpfc_devloss_tmo, |
3054 | &dev_attr_lpfc_enable_fip, | ||
3045 | &dev_attr_lpfc_hba_queue_depth, | 3055 | &dev_attr_lpfc_hba_queue_depth, |
3046 | &dev_attr_lpfc_peer_port_login, | 3056 | &dev_attr_lpfc_peer_port_login, |
3047 | &dev_attr_lpfc_restrict_login, | 3057 | &dev_attr_lpfc_restrict_login, |
@@ -4167,26 +4177,10 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) | |||
4167 | phba->cfg_soft_wwpn = 0L; | 4177 | phba->cfg_soft_wwpn = 0L; |
4168 | lpfc_sg_seg_cnt_init(phba, lpfc_sg_seg_cnt); | 4178 | lpfc_sg_seg_cnt_init(phba, lpfc_sg_seg_cnt); |
4169 | lpfc_prot_sg_seg_cnt_init(phba, lpfc_prot_sg_seg_cnt); | 4179 | lpfc_prot_sg_seg_cnt_init(phba, lpfc_prot_sg_seg_cnt); |
4170 | /* | ||
4171 | * Since the sg_tablesize is module parameter, the sg_dma_buf_size | ||
4172 | * used to create the sg_dma_buf_pool must be dynamically calculated. | ||
4173 | * 2 segments are added since the IOCB needs a command and response bde. | ||
4174 | */ | ||
4175 | phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) + | ||
4176 | sizeof(struct fcp_rsp) + | ||
4177 | ((phba->cfg_sg_seg_cnt + 2) * sizeof(struct ulp_bde64)); | ||
4178 | |||
4179 | if (phba->cfg_enable_bg) { | ||
4180 | phba->cfg_sg_seg_cnt = LPFC_MAX_SG_SEG_CNT; | ||
4181 | phba->cfg_sg_dma_buf_size += | ||
4182 | phba->cfg_prot_sg_seg_cnt * sizeof(struct ulp_bde64); | ||
4183 | } | ||
4184 | |||
4185 | /* Also reinitialize the host templates with new values. */ | ||
4186 | lpfc_vport_template.sg_tablesize = phba->cfg_sg_seg_cnt; | ||
4187 | lpfc_template.sg_tablesize = phba->cfg_sg_seg_cnt; | ||
4188 | |||
4189 | lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth); | 4180 | lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth); |
4181 | lpfc_enable_fip_init(phba, lpfc_enable_fip); | ||
4182 | lpfc_hba_log_verbose_init(phba, lpfc_log_verbose); | ||
4183 | |||
4190 | return; | 4184 | return; |
4191 | } | 4185 | } |
4192 | 4186 | ||
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index e0f1cd4b3d3d..d2a922997c0f 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
@@ -23,6 +23,8 @@ typedef int (*node_filter)(struct lpfc_nodelist *, void *); | |||
23 | struct fc_rport; | 23 | struct fc_rport; |
24 | void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t); | 24 | void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t); |
25 | void lpfc_dump_wakeup_param(struct lpfc_hba *, LPFC_MBOXQ_t *); | 25 | void lpfc_dump_wakeup_param(struct lpfc_hba *, LPFC_MBOXQ_t *); |
26 | void lpfc_dump_static_vport(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t); | ||
27 | int lpfc_dump_fcoe_param(struct lpfc_hba *, struct lpfcMboxq *); | ||
26 | void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *); | 28 | void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *); |
27 | void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); | 29 | void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); |
28 | 30 | ||
@@ -108,6 +110,7 @@ int lpfc_issue_els_adisc(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t); | |||
108 | int lpfc_issue_els_logo(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t); | 110 | int lpfc_issue_els_logo(struct lpfc_vport *, struct lpfc_nodelist *, uint8_t); |
109 | int lpfc_issue_els_npiv_logo(struct lpfc_vport *, struct lpfc_nodelist *); | 111 | int lpfc_issue_els_npiv_logo(struct lpfc_vport *, struct lpfc_nodelist *); |
110 | int lpfc_issue_els_scr(struct lpfc_vport *, uint32_t, uint8_t); | 112 | int lpfc_issue_els_scr(struct lpfc_vport *, uint32_t, uint8_t); |
113 | int lpfc_issue_fabric_reglogin(struct lpfc_vport *); | ||
111 | int lpfc_els_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *); | 114 | int lpfc_els_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *); |
112 | int lpfc_ct_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *); | 115 | int lpfc_ct_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *); |
113 | int lpfc_els_rsp_acc(struct lpfc_vport *, uint32_t, struct lpfc_iocbq *, | 116 | int lpfc_els_rsp_acc(struct lpfc_vport *, uint32_t, struct lpfc_iocbq *, |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 2c034a554c88..a3b56d7f72f4 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -388,6 +388,75 @@ fail: | |||
388 | } | 388 | } |
389 | 389 | ||
390 | /** | 390 | /** |
391 | * lpfc_issue_reg_vfi - Register VFI for this vport's fabric login | ||
392 | * @vport: pointer to a host virtual N_Port data structure. | ||
393 | * | ||
394 | * This routine issues a REG_VFI mailbox for the vfi, vpi, fcfi triplet for | ||
395 | * the @vport. This mailbox command is necessary for FCoE only. | ||
396 | * | ||
397 | * Return code | ||
398 | * 0 - successfully issued REG_VFI for @vport | ||
399 | * A failure code otherwise. | ||
400 | **/ | ||
401 | static int | ||
402 | lpfc_issue_reg_vfi(struct lpfc_vport *vport) | ||
403 | { | ||
404 | struct lpfc_hba *phba = vport->phba; | ||
405 | LPFC_MBOXQ_t *mboxq; | ||
406 | struct lpfc_nodelist *ndlp; | ||
407 | struct serv_parm *sp; | ||
408 | struct lpfc_dmabuf *dmabuf; | ||
409 | int rc = 0; | ||
410 | |||
411 | sp = &phba->fc_fabparam; | ||
412 | ndlp = lpfc_findnode_did(vport, Fabric_DID); | ||
413 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { | ||
414 | rc = -ENODEV; | ||
415 | goto fail; | ||
416 | } | ||
417 | |||
418 | dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); | ||
419 | if (!dmabuf) { | ||
420 | rc = -ENOMEM; | ||
421 | goto fail; | ||
422 | } | ||
423 | dmabuf->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &dmabuf->phys); | ||
424 | if (!dmabuf->virt) { | ||
425 | rc = -ENOMEM; | ||
426 | goto fail_free_dmabuf; | ||
427 | } | ||
428 | mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
429 | if (!mboxq) { | ||
430 | rc = -ENOMEM; | ||
431 | goto fail_free_coherent; | ||
432 | } | ||
433 | vport->port_state = LPFC_FABRIC_CFG_LINK; | ||
434 | memcpy(dmabuf->virt, &phba->fc_fabparam, sizeof(vport->fc_sparam)); | ||
435 | lpfc_reg_vfi(mboxq, vport, dmabuf->phys); | ||
436 | mboxq->mbox_cmpl = lpfc_mbx_cmpl_reg_vfi; | ||
437 | mboxq->vport = vport; | ||
438 | mboxq->context1 = dmabuf; | ||
439 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); | ||
440 | if (rc == MBX_NOT_FINISHED) { | ||
441 | rc = -ENXIO; | ||
442 | goto fail_free_mbox; | ||
443 | } | ||
444 | return 0; | ||
445 | |||
446 | fail_free_mbox: | ||
447 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
448 | fail_free_coherent: | ||
449 | lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys); | ||
450 | fail_free_dmabuf: | ||
451 | kfree(dmabuf); | ||
452 | fail: | ||
453 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | ||
454 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | ||
455 | "0289 Issue Register VFI failed: Err %d\n", rc); | ||
456 | return rc; | ||
457 | } | ||
458 | |||
459 | /** | ||
391 | * lpfc_cmpl_els_flogi_fabric - Completion function for flogi to a fabric port | 460 | * lpfc_cmpl_els_flogi_fabric - Completion function for flogi to a fabric port |
392 | * @vport: pointer to a host virtual N_Port data structure. | 461 | * @vport: pointer to a host virtual N_Port data structure. |
393 | * @ndlp: pointer to a node-list data structure. | 462 | * @ndlp: pointer to a node-list data structure. |
@@ -499,17 +568,24 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
499 | } | 568 | } |
500 | } | 569 | } |
501 | 570 | ||
502 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_REG_LOGIN_ISSUE); | 571 | if (phba->sli_rev < LPFC_SLI_REV4) { |
503 | 572 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_REG_LOGIN_ISSUE); | |
504 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED && | 573 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED && |
505 | vport->fc_flag & FC_VPORT_NEEDS_REG_VPI) { | 574 | vport->fc_flag & FC_VPORT_NEEDS_REG_VPI) |
506 | lpfc_register_new_vport(phba, vport, ndlp); | 575 | lpfc_register_new_vport(phba, vport, ndlp); |
507 | return 0; | 576 | else |
577 | lpfc_issue_fabric_reglogin(vport); | ||
578 | } else { | ||
579 | ndlp->nlp_type |= NLP_FABRIC; | ||
580 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); | ||
581 | if (vport->vfi_state & LPFC_VFI_REGISTERED) { | ||
582 | lpfc_start_fdiscs(phba); | ||
583 | lpfc_do_scr_ns_plogi(phba, vport); | ||
584 | } else | ||
585 | lpfc_issue_reg_vfi(vport); | ||
508 | } | 586 | } |
509 | lpfc_issue_fabric_reglogin(vport); | ||
510 | return 0; | 587 | return 0; |
511 | } | 588 | } |
512 | |||
513 | /** | 589 | /** |
514 | * lpfc_cmpl_els_flogi_nport - Completion function for flogi to an N_Port | 590 | * lpfc_cmpl_els_flogi_nport - Completion function for flogi to an N_Port |
515 | * @vport: pointer to a host virtual N_Port data structure. | 591 | * @vport: pointer to a host virtual N_Port data structure. |
@@ -817,9 +893,14 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
817 | if (sp->cmn.fcphHigh < FC_PH3) | 893 | if (sp->cmn.fcphHigh < FC_PH3) |
818 | sp->cmn.fcphHigh = FC_PH3; | 894 | sp->cmn.fcphHigh = FC_PH3; |
819 | 895 | ||
820 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) { | 896 | if (phba->sli_rev == LPFC_SLI_REV4) { |
897 | elsiocb->iocb.ulpCt_h = ((SLI4_CT_FCFI >> 1) & 1); | ||
898 | elsiocb->iocb.ulpCt_l = (SLI4_CT_FCFI & 1); | ||
899 | /* FLOGI needs to be 3 for WQE FCFI */ | ||
900 | /* Set the fcfi to the fcfi we registered with */ | ||
901 | elsiocb->iocb.ulpContext = phba->fcf.fcfi; | ||
902 | } else if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) { | ||
821 | sp->cmn.request_multiple_Nport = 1; | 903 | sp->cmn.request_multiple_Nport = 1; |
822 | |||
823 | /* For FLOGI, Let FLOGI rsp set the NPortID for VPI 0 */ | 904 | /* For FLOGI, Let FLOGI rsp set the NPortID for VPI 0 */ |
824 | icmd->ulpCt_h = 1; | 905 | icmd->ulpCt_h = 1; |
825 | icmd->ulpCt_l = 0; | 906 | icmd->ulpCt_l = 0; |
@@ -932,6 +1013,8 @@ lpfc_initial_flogi(struct lpfc_vport *vport) | |||
932 | if (!ndlp) | 1013 | if (!ndlp) |
933 | return 0; | 1014 | return 0; |
934 | lpfc_nlp_init(vport, ndlp, Fabric_DID); | 1015 | lpfc_nlp_init(vport, ndlp, Fabric_DID); |
1016 | /* Set the node type */ | ||
1017 | ndlp->nlp_type |= NLP_FABRIC; | ||
935 | /* Put ndlp onto node list */ | 1018 | /* Put ndlp onto node list */ |
936 | lpfc_enqueue_node(vport, ndlp); | 1019 | lpfc_enqueue_node(vport, ndlp); |
937 | } else if (!NLP_CHK_NODE_ACT(ndlp)) { | 1020 | } else if (!NLP_CHK_NODE_ACT(ndlp)) { |
@@ -1604,7 +1687,8 @@ lpfc_adisc_done(struct lpfc_vport *vport) | |||
1604 | * and continue discovery. | 1687 | * and continue discovery. |
1605 | */ | 1688 | */ |
1606 | if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && | 1689 | if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && |
1607 | !(vport->fc_flag & FC_RSCN_MODE)) { | 1690 | !(vport->fc_flag & FC_RSCN_MODE) && |
1691 | (phba->sli_rev < LPFC_SLI_REV4)) { | ||
1608 | lpfc_issue_reg_vpi(phba, vport); | 1692 | lpfc_issue_reg_vpi(phba, vport); |
1609 | return; | 1693 | return; |
1610 | } | 1694 | } |
@@ -2937,6 +3021,14 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2937 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); | 3021 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); |
2938 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; | 3022 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; |
2939 | 3023 | ||
3024 | /* | ||
3025 | * This routine is used to register and unregister in previous SLI | ||
3026 | * modes. | ||
3027 | */ | ||
3028 | if ((pmb->u.mb.mbxCommand == MBX_UNREG_LOGIN) && | ||
3029 | (phba->sli_rev == LPFC_SLI_REV4)) | ||
3030 | lpfc_sli4_free_rpi(phba, pmb->u.mb.un.varUnregLogin.rpi); | ||
3031 | |||
2940 | pmb->context1 = NULL; | 3032 | pmb->context1 = NULL; |
2941 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 3033 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
2942 | kfree(mp); | 3034 | kfree(mp); |
@@ -3816,7 +3908,9 @@ lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did) | |||
3816 | payload_len -= sizeof(uint32_t); | 3908 | payload_len -= sizeof(uint32_t); |
3817 | switch (rscn_did.un.b.resv & RSCN_ADDRESS_FORMAT_MASK) { | 3909 | switch (rscn_did.un.b.resv & RSCN_ADDRESS_FORMAT_MASK) { |
3818 | case RSCN_ADDRESS_FORMAT_PORT: | 3910 | case RSCN_ADDRESS_FORMAT_PORT: |
3819 | if (ns_did.un.word == rscn_did.un.word) | 3911 | if ((ns_did.un.b.domain == rscn_did.un.b.domain) |
3912 | && (ns_did.un.b.area == rscn_did.un.b.area) | ||
3913 | && (ns_did.un.b.id == rscn_did.un.b.id)) | ||
3820 | goto return_did_out; | 3914 | goto return_did_out; |
3821 | break; | 3915 | break; |
3822 | case RSCN_ADDRESS_FORMAT_AREA: | 3916 | case RSCN_ADDRESS_FORMAT_AREA: |
@@ -4857,7 +4951,10 @@ lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
4857 | } else { | 4951 | } else { |
4858 | /* FAN verified - skip FLOGI */ | 4952 | /* FAN verified - skip FLOGI */ |
4859 | vport->fc_myDID = vport->fc_prevDID; | 4953 | vport->fc_myDID = vport->fc_prevDID; |
4860 | lpfc_issue_fabric_reglogin(vport); | 4954 | if (phba->sli_rev < LPFC_SLI_REV4) |
4955 | lpfc_issue_fabric_reglogin(vport); | ||
4956 | else | ||
4957 | lpfc_issue_reg_vfi(vport); | ||
4861 | } | 4958 | } |
4862 | } | 4959 | } |
4863 | return 0; | 4960 | return 0; |
@@ -5540,11 +5637,10 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
5540 | 5637 | ||
5541 | dropit: | 5638 | dropit: |
5542 | if (vport && !(vport->load_flag & FC_UNLOADING)) | 5639 | if (vport && !(vport->load_flag & FC_UNLOADING)) |
5543 | lpfc_printf_log(phba, KERN_ERR, LOG_ELS, | 5640 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
5544 | "(%d):0111 Dropping received ELS cmd " | 5641 | "0111 Dropping received ELS cmd " |
5545 | "Data: x%x x%x x%x\n", | 5642 | "Data: x%x x%x x%x\n", |
5546 | vport->vpi, icmd->ulpStatus, | 5643 | icmd->ulpStatus, icmd->un.ulpWord[4], icmd->ulpTimeout); |
5547 | icmd->un.ulpWord[4], icmd->ulpTimeout); | ||
5548 | phba->fc_stat.elsRcvDrop++; | 5644 | phba->fc_stat.elsRcvDrop++; |
5549 | } | 5645 | } |
5550 | 5646 | ||
@@ -5620,10 +5716,9 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
5620 | icmd->ulpCommand == CMD_IOCB_RCV_SEQ64_CX)) { | 5716 | icmd->ulpCommand == CMD_IOCB_RCV_SEQ64_CX)) { |
5621 | if (icmd->unsli3.rcvsli3.vpi == 0xffff) | 5717 | if (icmd->unsli3.rcvsli3.vpi == 0xffff) |
5622 | vport = phba->pport; | 5718 | vport = phba->pport; |
5623 | else { | 5719 | else |
5624 | uint16_t vpi = icmd->unsli3.rcvsli3.vpi; | 5720 | vport = lpfc_find_vport_by_vpid(phba, |
5625 | vport = lpfc_find_vport_by_vpid(phba, vpi); | 5721 | icmd->unsli3.rcvsli3.vpi - phba->vpi_base); |
5626 | } | ||
5627 | } | 5722 | } |
5628 | /* If there are no BDEs associated | 5723 | /* If there are no BDEs associated |
5629 | * with this IOCB, there is nothing to do. | 5724 | * with this IOCB, there is nothing to do. |
@@ -5792,7 +5887,10 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
5792 | 5887 | ||
5793 | } else { | 5888 | } else { |
5794 | if (vport == phba->pport) | 5889 | if (vport == phba->pport) |
5795 | lpfc_issue_fabric_reglogin(vport); | 5890 | if (phba->sli_rev < LPFC_SLI_REV4) |
5891 | lpfc_issue_fabric_reglogin(vport); | ||
5892 | else | ||
5893 | lpfc_issue_reg_vfi(vport); | ||
5796 | else | 5894 | else |
5797 | lpfc_do_scr_ns_plogi(phba, vport); | 5895 | lpfc_do_scr_ns_plogi(phba, vport); |
5798 | } | 5896 | } |
@@ -5824,7 +5922,7 @@ lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport, | |||
5824 | 5922 | ||
5825 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 5923 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
5826 | if (mbox) { | 5924 | if (mbox) { |
5827 | lpfc_reg_vpi(phba, vport->vpi, vport->fc_myDID, mbox); | 5925 | lpfc_reg_vpi(vport, mbox); |
5828 | mbox->vport = vport; | 5926 | mbox->vport = vport; |
5829 | mbox->context2 = lpfc_nlp_get(ndlp); | 5927 | mbox->context2 = lpfc_nlp_get(ndlp); |
5830 | mbox->mbox_cmpl = lpfc_cmpl_reg_new_vport; | 5928 | mbox->mbox_cmpl = lpfc_cmpl_reg_new_vport; |
@@ -6496,3 +6594,38 @@ void lpfc_fabric_abort_hba(struct lpfc_hba *phba) | |||
6496 | lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT, | 6594 | lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT, |
6497 | IOERR_SLI_ABORTED); | 6595 | IOERR_SLI_ABORTED); |
6498 | } | 6596 | } |
6597 | |||
6598 | /** | ||
6599 | * lpfc_sli4_els_xri_aborted - Slow-path process of els xri abort | ||
6600 | * @phba: pointer to lpfc hba data structure. | ||
6601 | * @axri: pointer to the els xri abort wcqe structure. | ||
6602 | * | ||
6603 | * This routine is invoked by the worker thread to process a SLI4 slow-path | ||
6604 | * ELS aborted xri. | ||
6605 | **/ | ||
6606 | void | ||
6607 | lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba, | ||
6608 | struct sli4_wcqe_xri_aborted *axri) | ||
6609 | { | ||
6610 | uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri); | ||
6611 | struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL; | ||
6612 | unsigned long iflag = 0; | ||
6613 | |||
6614 | spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock, iflag); | ||
6615 | list_for_each_entry_safe(sglq_entry, sglq_next, | ||
6616 | &phba->sli4_hba.lpfc_abts_els_sgl_list, list) { | ||
6617 | if (sglq_entry->sli4_xritag == xri) { | ||
6618 | list_del(&sglq_entry->list); | ||
6619 | spin_unlock_irqrestore( | ||
6620 | &phba->sli4_hba.abts_sgl_list_lock, | ||
6621 | iflag); | ||
6622 | spin_lock_irqsave(&phba->hbalock, iflag); | ||
6623 | |||
6624 | list_add_tail(&sglq_entry->list, | ||
6625 | &phba->sli4_hba.lpfc_sgl_list); | ||
6626 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
6627 | return; | ||
6628 | } | ||
6629 | } | ||
6630 | spin_unlock_irqrestore(&phba->sli4_hba.abts_sgl_list_lock, iflag); | ||
6631 | } | ||
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 2270d9a7c8e3..9bd7a8927a34 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -275,6 +275,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) | |||
275 | !(ndlp->nlp_flag & NLP_NPR_2B_DISC) && | 275 | !(ndlp->nlp_flag & NLP_NPR_2B_DISC) && |
276 | (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)) | 276 | (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)) |
277 | lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM); | 277 | lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM); |
278 | |||
279 | lpfc_unregister_unused_fcf(phba); | ||
278 | } | 280 | } |
279 | 281 | ||
280 | /** | 282 | /** |
@@ -297,10 +299,11 @@ lpfc_alloc_fast_evt(struct lpfc_hba *phba) { | |||
297 | 299 | ||
298 | ret = kzalloc(sizeof(struct lpfc_fast_path_event), | 300 | ret = kzalloc(sizeof(struct lpfc_fast_path_event), |
299 | GFP_ATOMIC); | 301 | GFP_ATOMIC); |
300 | if (ret) | 302 | if (ret) { |
301 | atomic_inc(&phba->fast_event_count); | 303 | atomic_inc(&phba->fast_event_count); |
302 | INIT_LIST_HEAD(&ret->work_evt.evt_listp); | 304 | INIT_LIST_HEAD(&ret->work_evt.evt_listp); |
303 | ret->work_evt.evt = LPFC_EVT_FASTPATH_MGMT_EVT; | 305 | ret->work_evt.evt = LPFC_EVT_FASTPATH_MGMT_EVT; |
306 | } | ||
304 | return ret; | 307 | return ret; |
305 | } | 308 | } |
306 | 309 | ||
@@ -741,6 +744,7 @@ lpfc_linkdown(struct lpfc_hba *phba) | |||
741 | if (phba->link_state == LPFC_LINK_DOWN) | 744 | if (phba->link_state == LPFC_LINK_DOWN) |
742 | return 0; | 745 | return 0; |
743 | spin_lock_irq(&phba->hbalock); | 746 | spin_lock_irq(&phba->hbalock); |
747 | phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_DISCOVERED); | ||
744 | if (phba->link_state > LPFC_LINK_DOWN) { | 748 | if (phba->link_state > LPFC_LINK_DOWN) { |
745 | phba->link_state = LPFC_LINK_DOWN; | 749 | phba->link_state = LPFC_LINK_DOWN; |
746 | phba->pport->fc_flag &= ~FC_LBIT; | 750 | phba->pport->fc_flag &= ~FC_LBIT; |
@@ -748,7 +752,7 @@ lpfc_linkdown(struct lpfc_hba *phba) | |||
748 | spin_unlock_irq(&phba->hbalock); | 752 | spin_unlock_irq(&phba->hbalock); |
749 | vports = lpfc_create_vport_work_array(phba); | 753 | vports = lpfc_create_vport_work_array(phba); |
750 | if (vports != NULL) | 754 | if (vports != NULL) |
751 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { | 755 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { |
752 | /* Issue a LINK DOWN event to all nodes */ | 756 | /* Issue a LINK DOWN event to all nodes */ |
753 | lpfc_linkdown_port(vports[i]); | 757 | lpfc_linkdown_port(vports[i]); |
754 | } | 758 | } |
@@ -858,10 +862,11 @@ lpfc_linkup(struct lpfc_hba *phba) | |||
858 | 862 | ||
859 | vports = lpfc_create_vport_work_array(phba); | 863 | vports = lpfc_create_vport_work_array(phba); |
860 | if (vports != NULL) | 864 | if (vports != NULL) |
861 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) | 865 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) |
862 | lpfc_linkup_port(vports[i]); | 866 | lpfc_linkup_port(vports[i]); |
863 | lpfc_destroy_vport_work_array(phba, vports); | 867 | lpfc_destroy_vport_work_array(phba, vports); |
864 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) | 868 | if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && |
869 | (phba->sli_rev < LPFC_SLI_REV4)) | ||
865 | lpfc_issue_clear_la(phba, phba->pport); | 870 | lpfc_issue_clear_la(phba, phba->pport); |
866 | 871 | ||
867 | return 0; | 872 | return 0; |
@@ -984,9 +989,592 @@ out: | |||
984 | } | 989 | } |
985 | 990 | ||
986 | static void | 991 | static void |
992 | lpfc_mbx_cmpl_reg_fcfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
993 | { | ||
994 | struct lpfc_vport *vport = mboxq->vport; | ||
995 | unsigned long flags; | ||
996 | |||
997 | if (mboxq->u.mb.mbxStatus) { | ||
998 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, | ||
999 | "2017 REG_FCFI mbxStatus error x%x " | ||
1000 | "HBA state x%x\n", | ||
1001 | mboxq->u.mb.mbxStatus, vport->port_state); | ||
1002 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
1003 | return; | ||
1004 | } | ||
1005 | |||
1006 | /* Start FCoE discovery by sending a FLOGI. */ | ||
1007 | phba->fcf.fcfi = bf_get(lpfc_reg_fcfi_fcfi, &mboxq->u.mqe.un.reg_fcfi); | ||
1008 | /* Set the FCFI registered flag */ | ||
1009 | spin_lock_irqsave(&phba->hbalock, flags); | ||
1010 | phba->fcf.fcf_flag |= FCF_REGISTERED; | ||
1011 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1012 | if (vport->port_state != LPFC_FLOGI) { | ||
1013 | spin_lock_irqsave(&phba->hbalock, flags); | ||
1014 | phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE); | ||
1015 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1016 | lpfc_initial_flogi(vport); | ||
1017 | } | ||
1018 | |||
1019 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
1020 | return; | ||
1021 | } | ||
1022 | |||
1023 | /** | ||
1024 | * lpfc_fab_name_match - Check if the fcf fabric name match. | ||
1025 | * @fab_name: pointer to fabric name. | ||
1026 | * @new_fcf_record: pointer to fcf record. | ||
1027 | * | ||
1028 | * This routine compare the fcf record's fabric name with provided | ||
1029 | * fabric name. If the fabric name are identical this function | ||
1030 | * returns 1 else return 0. | ||
1031 | **/ | ||
1032 | static uint32_t | ||
1033 | lpfc_fab_name_match(uint8_t *fab_name, struct fcf_record *new_fcf_record) | ||
1034 | { | ||
1035 | if ((fab_name[0] == | ||
1036 | bf_get(lpfc_fcf_record_fab_name_0, new_fcf_record)) && | ||
1037 | (fab_name[1] == | ||
1038 | bf_get(lpfc_fcf_record_fab_name_1, new_fcf_record)) && | ||
1039 | (fab_name[2] == | ||
1040 | bf_get(lpfc_fcf_record_fab_name_2, new_fcf_record)) && | ||
1041 | (fab_name[3] == | ||
1042 | bf_get(lpfc_fcf_record_fab_name_3, new_fcf_record)) && | ||
1043 | (fab_name[4] == | ||
1044 | bf_get(lpfc_fcf_record_fab_name_4, new_fcf_record)) && | ||
1045 | (fab_name[5] == | ||
1046 | bf_get(lpfc_fcf_record_fab_name_5, new_fcf_record)) && | ||
1047 | (fab_name[6] == | ||
1048 | bf_get(lpfc_fcf_record_fab_name_6, new_fcf_record)) && | ||
1049 | (fab_name[7] == | ||
1050 | bf_get(lpfc_fcf_record_fab_name_7, new_fcf_record))) | ||
1051 | return 1; | ||
1052 | else | ||
1053 | return 0; | ||
1054 | } | ||
1055 | |||
1056 | /** | ||
1057 | * lpfc_mac_addr_match - Check if the fcf mac address match. | ||
1058 | * @phba: pointer to lpfc hba data structure. | ||
1059 | * @new_fcf_record: pointer to fcf record. | ||
1060 | * | ||
1061 | * This routine compare the fcf record's mac address with HBA's | ||
1062 | * FCF mac address. If the mac addresses are identical this function | ||
1063 | * returns 1 else return 0. | ||
1064 | **/ | ||
1065 | static uint32_t | ||
1066 | lpfc_mac_addr_match(struct lpfc_hba *phba, struct fcf_record *new_fcf_record) | ||
1067 | { | ||
1068 | if ((phba->fcf.mac_addr[0] == | ||
1069 | bf_get(lpfc_fcf_record_mac_0, new_fcf_record)) && | ||
1070 | (phba->fcf.mac_addr[1] == | ||
1071 | bf_get(lpfc_fcf_record_mac_1, new_fcf_record)) && | ||
1072 | (phba->fcf.mac_addr[2] == | ||
1073 | bf_get(lpfc_fcf_record_mac_2, new_fcf_record)) && | ||
1074 | (phba->fcf.mac_addr[3] == | ||
1075 | bf_get(lpfc_fcf_record_mac_3, new_fcf_record)) && | ||
1076 | (phba->fcf.mac_addr[4] == | ||
1077 | bf_get(lpfc_fcf_record_mac_4, new_fcf_record)) && | ||
1078 | (phba->fcf.mac_addr[5] == | ||
1079 | bf_get(lpfc_fcf_record_mac_5, new_fcf_record))) | ||
1080 | return 1; | ||
1081 | else | ||
1082 | return 0; | ||
1083 | } | ||
1084 | |||
1085 | /** | ||
1086 | * lpfc_copy_fcf_record - Copy fcf information to lpfc_hba. | ||
1087 | * @phba: pointer to lpfc hba data structure. | ||
1088 | * @new_fcf_record: pointer to fcf record. | ||
1089 | * | ||
1090 | * This routine copies the FCF information from the FCF | ||
1091 | * record to lpfc_hba data structure. | ||
1092 | **/ | ||
1093 | static void | ||
1094 | lpfc_copy_fcf_record(struct lpfc_hba *phba, struct fcf_record *new_fcf_record) | ||
1095 | { | ||
1096 | phba->fcf.fabric_name[0] = | ||
1097 | bf_get(lpfc_fcf_record_fab_name_0, new_fcf_record); | ||
1098 | phba->fcf.fabric_name[1] = | ||
1099 | bf_get(lpfc_fcf_record_fab_name_1, new_fcf_record); | ||
1100 | phba->fcf.fabric_name[2] = | ||
1101 | bf_get(lpfc_fcf_record_fab_name_2, new_fcf_record); | ||
1102 | phba->fcf.fabric_name[3] = | ||
1103 | bf_get(lpfc_fcf_record_fab_name_3, new_fcf_record); | ||
1104 | phba->fcf.fabric_name[4] = | ||
1105 | bf_get(lpfc_fcf_record_fab_name_4, new_fcf_record); | ||
1106 | phba->fcf.fabric_name[5] = | ||
1107 | bf_get(lpfc_fcf_record_fab_name_5, new_fcf_record); | ||
1108 | phba->fcf.fabric_name[6] = | ||
1109 | bf_get(lpfc_fcf_record_fab_name_6, new_fcf_record); | ||
1110 | phba->fcf.fabric_name[7] = | ||
1111 | bf_get(lpfc_fcf_record_fab_name_7, new_fcf_record); | ||
1112 | phba->fcf.mac_addr[0] = | ||
1113 | bf_get(lpfc_fcf_record_mac_0, new_fcf_record); | ||
1114 | phba->fcf.mac_addr[1] = | ||
1115 | bf_get(lpfc_fcf_record_mac_1, new_fcf_record); | ||
1116 | phba->fcf.mac_addr[2] = | ||
1117 | bf_get(lpfc_fcf_record_mac_2, new_fcf_record); | ||
1118 | phba->fcf.mac_addr[3] = | ||
1119 | bf_get(lpfc_fcf_record_mac_3, new_fcf_record); | ||
1120 | phba->fcf.mac_addr[4] = | ||
1121 | bf_get(lpfc_fcf_record_mac_4, new_fcf_record); | ||
1122 | phba->fcf.mac_addr[5] = | ||
1123 | bf_get(lpfc_fcf_record_mac_5, new_fcf_record); | ||
1124 | phba->fcf.fcf_indx = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record); | ||
1125 | phba->fcf.priority = new_fcf_record->fip_priority; | ||
1126 | } | ||
1127 | |||
1128 | /** | ||
1129 | * lpfc_register_fcf - Register the FCF with hba. | ||
1130 | * @phba: pointer to lpfc hba data structure. | ||
1131 | * | ||
1132 | * This routine issues a register fcfi mailbox command to register | ||
1133 | * the fcf with HBA. | ||
1134 | **/ | ||
1135 | static void | ||
1136 | lpfc_register_fcf(struct lpfc_hba *phba) | ||
1137 | { | ||
1138 | LPFC_MBOXQ_t *fcf_mbxq; | ||
1139 | int rc; | ||
1140 | unsigned long flags; | ||
1141 | |||
1142 | spin_lock_irqsave(&phba->hbalock, flags); | ||
1143 | |||
1144 | /* If the FCF is not availabe do nothing. */ | ||
1145 | if (!(phba->fcf.fcf_flag & FCF_AVAILABLE)) { | ||
1146 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1147 | return; | ||
1148 | } | ||
1149 | |||
1150 | /* The FCF is already registered, start discovery */ | ||
1151 | if (phba->fcf.fcf_flag & FCF_REGISTERED) { | ||
1152 | phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE); | ||
1153 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1154 | if (phba->pport->port_state != LPFC_FLOGI) | ||
1155 | lpfc_initial_flogi(phba->pport); | ||
1156 | return; | ||
1157 | } | ||
1158 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1159 | |||
1160 | fcf_mbxq = mempool_alloc(phba->mbox_mem_pool, | ||
1161 | GFP_KERNEL); | ||
1162 | if (!fcf_mbxq) | ||
1163 | return; | ||
1164 | |||
1165 | lpfc_reg_fcfi(phba, fcf_mbxq); | ||
1166 | fcf_mbxq->vport = phba->pport; | ||
1167 | fcf_mbxq->mbox_cmpl = lpfc_mbx_cmpl_reg_fcfi; | ||
1168 | rc = lpfc_sli_issue_mbox(phba, fcf_mbxq, MBX_NOWAIT); | ||
1169 | if (rc == MBX_NOT_FINISHED) | ||
1170 | mempool_free(fcf_mbxq, phba->mbox_mem_pool); | ||
1171 | |||
1172 | return; | ||
1173 | } | ||
1174 | |||
1175 | /** | ||
1176 | * lpfc_match_fcf_conn_list - Check if the FCF record can be used for discovery. | ||
1177 | * @phba: pointer to lpfc hba data structure. | ||
1178 | * @new_fcf_record: pointer to fcf record. | ||
1179 | * @boot_flag: Indicates if this record used by boot bios. | ||
1180 | * @addr_mode: The address mode to be used by this FCF | ||
1181 | * | ||
1182 | * This routine compare the fcf record with connect list obtained from the | ||
1183 | * config region to decide if this FCF can be used for SAN discovery. It returns | ||
1184 | * 1 if this record can be used for SAN discovery else return zero. If this FCF | ||
1185 | * record can be used for SAN discovery, the boot_flag will indicate if this FCF | ||
1186 | * is used by boot bios and addr_mode will indicate the addressing mode to be | ||
1187 | * used for this FCF when the function returns. | ||
1188 | * If the FCF record need to be used with a particular vlan id, the vlan is | ||
1189 | * set in the vlan_id on return of the function. If not VLAN tagging need to | ||
1190 | * be used with the FCF vlan_id will be set to 0xFFFF; | ||
1191 | **/ | ||
1192 | static int | ||
1193 | lpfc_match_fcf_conn_list(struct lpfc_hba *phba, | ||
1194 | struct fcf_record *new_fcf_record, | ||
1195 | uint32_t *boot_flag, uint32_t *addr_mode, | ||
1196 | uint16_t *vlan_id) | ||
1197 | { | ||
1198 | struct lpfc_fcf_conn_entry *conn_entry; | ||
1199 | |||
1200 | if (!phba->cfg_enable_fip) { | ||
1201 | *boot_flag = 0; | ||
1202 | *addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov, | ||
1203 | new_fcf_record); | ||
1204 | if (phba->valid_vlan) | ||
1205 | *vlan_id = phba->vlan_id; | ||
1206 | else | ||
1207 | *vlan_id = 0xFFFF; | ||
1208 | return 1; | ||
1209 | } | ||
1210 | |||
1211 | /* | ||
1212 | * If there are no FCF connection table entry, driver connect to all | ||
1213 | * FCFs. | ||
1214 | */ | ||
1215 | if (list_empty(&phba->fcf_conn_rec_list)) { | ||
1216 | *boot_flag = 0; | ||
1217 | *addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov, | ||
1218 | new_fcf_record); | ||
1219 | *vlan_id = 0xFFFF; | ||
1220 | return 1; | ||
1221 | } | ||
1222 | |||
1223 | list_for_each_entry(conn_entry, &phba->fcf_conn_rec_list, list) { | ||
1224 | if (!(conn_entry->conn_rec.flags & FCFCNCT_VALID)) | ||
1225 | continue; | ||
1226 | |||
1227 | if ((conn_entry->conn_rec.flags & FCFCNCT_FBNM_VALID) && | ||
1228 | !lpfc_fab_name_match(conn_entry->conn_rec.fabric_name, | ||
1229 | new_fcf_record)) | ||
1230 | continue; | ||
1231 | |||
1232 | if (conn_entry->conn_rec.flags & FCFCNCT_VLAN_VALID) { | ||
1233 | /* | ||
1234 | * If the vlan bit map does not have the bit set for the | ||
1235 | * vlan id to be used, then it is not a match. | ||
1236 | */ | ||
1237 | if (!(new_fcf_record->vlan_bitmap | ||
1238 | [conn_entry->conn_rec.vlan_tag / 8] & | ||
1239 | (1 << (conn_entry->conn_rec.vlan_tag % 8)))) | ||
1240 | continue; | ||
1241 | } | ||
1242 | |||
1243 | /* | ||
1244 | * Check if the connection record specifies a required | ||
1245 | * addressing mode. | ||
1246 | */ | ||
1247 | if ((conn_entry->conn_rec.flags & FCFCNCT_AM_VALID) && | ||
1248 | !(conn_entry->conn_rec.flags & FCFCNCT_AM_PREFERRED)) { | ||
1249 | |||
1250 | /* | ||
1251 | * If SPMA required but FCF not support this continue. | ||
1252 | */ | ||
1253 | if ((conn_entry->conn_rec.flags & FCFCNCT_AM_SPMA) && | ||
1254 | !(bf_get(lpfc_fcf_record_mac_addr_prov, | ||
1255 | new_fcf_record) & LPFC_FCF_SPMA)) | ||
1256 | continue; | ||
1257 | |||
1258 | /* | ||
1259 | * If FPMA required but FCF not support this continue. | ||
1260 | */ | ||
1261 | if (!(conn_entry->conn_rec.flags & FCFCNCT_AM_SPMA) && | ||
1262 | !(bf_get(lpfc_fcf_record_mac_addr_prov, | ||
1263 | new_fcf_record) & LPFC_FCF_FPMA)) | ||
1264 | continue; | ||
1265 | } | ||
1266 | |||
1267 | /* | ||
1268 | * This fcf record matches filtering criteria. | ||
1269 | */ | ||
1270 | if (conn_entry->conn_rec.flags & FCFCNCT_BOOT) | ||
1271 | *boot_flag = 1; | ||
1272 | else | ||
1273 | *boot_flag = 0; | ||
1274 | |||
1275 | *addr_mode = bf_get(lpfc_fcf_record_mac_addr_prov, | ||
1276 | new_fcf_record); | ||
1277 | /* | ||
1278 | * If the user specified a required address mode, assign that | ||
1279 | * address mode | ||
1280 | */ | ||
1281 | if ((conn_entry->conn_rec.flags & FCFCNCT_AM_VALID) && | ||
1282 | (!(conn_entry->conn_rec.flags & FCFCNCT_AM_PREFERRED))) | ||
1283 | *addr_mode = (conn_entry->conn_rec.flags & | ||
1284 | FCFCNCT_AM_SPMA) ? | ||
1285 | LPFC_FCF_SPMA : LPFC_FCF_FPMA; | ||
1286 | /* | ||
1287 | * If the user specified a prefered address mode, use the | ||
1288 | * addr mode only if FCF support the addr_mode. | ||
1289 | */ | ||
1290 | else if ((conn_entry->conn_rec.flags & FCFCNCT_AM_VALID) && | ||
1291 | (conn_entry->conn_rec.flags & FCFCNCT_AM_PREFERRED) && | ||
1292 | (conn_entry->conn_rec.flags & FCFCNCT_AM_SPMA) && | ||
1293 | (*addr_mode & LPFC_FCF_SPMA)) | ||
1294 | *addr_mode = LPFC_FCF_SPMA; | ||
1295 | else if ((conn_entry->conn_rec.flags & FCFCNCT_AM_VALID) && | ||
1296 | (conn_entry->conn_rec.flags & FCFCNCT_AM_PREFERRED) && | ||
1297 | !(conn_entry->conn_rec.flags & FCFCNCT_AM_SPMA) && | ||
1298 | (*addr_mode & LPFC_FCF_FPMA)) | ||
1299 | *addr_mode = LPFC_FCF_FPMA; | ||
1300 | /* | ||
1301 | * If user did not specify any addressing mode, use FPMA if | ||
1302 | * possible else use SPMA. | ||
1303 | */ | ||
1304 | else if (*addr_mode & LPFC_FCF_FPMA) | ||
1305 | *addr_mode = LPFC_FCF_FPMA; | ||
1306 | |||
1307 | if (conn_entry->conn_rec.flags & FCFCNCT_VLAN_VALID) | ||
1308 | *vlan_id = conn_entry->conn_rec.vlan_tag; | ||
1309 | else | ||
1310 | *vlan_id = 0xFFFF; | ||
1311 | |||
1312 | return 1; | ||
1313 | } | ||
1314 | |||
1315 | return 0; | ||
1316 | } | ||
1317 | |||
1318 | /** | ||
1319 | * lpfc_mbx_cmpl_read_fcf_record - Completion handler for read_fcf mbox. | ||
1320 | * @phba: pointer to lpfc hba data structure. | ||
1321 | * @mboxq: pointer to mailbox object. | ||
1322 | * | ||
1323 | * This function iterate through all the fcf records available in | ||
1324 | * HBA and choose the optimal FCF record for discovery. After finding | ||
1325 | * the FCF for discovery it register the FCF record and kick start | ||
1326 | * discovery. | ||
1327 | * If FCF_IN_USE flag is set in currently used FCF, the routine try to | ||
1328 | * use a FCF record which match fabric name and mac address of the | ||
1329 | * currently used FCF record. | ||
1330 | * If the driver support only one FCF, it will try to use the FCF record | ||
1331 | * used by BOOT_BIOS. | ||
1332 | */ | ||
1333 | void | ||
1334 | lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
1335 | { | ||
1336 | void *virt_addr; | ||
1337 | dma_addr_t phys_addr; | ||
1338 | uint8_t *bytep; | ||
1339 | struct lpfc_mbx_sge sge; | ||
1340 | struct lpfc_mbx_read_fcf_tbl *read_fcf; | ||
1341 | uint32_t shdr_status, shdr_add_status; | ||
1342 | union lpfc_sli4_cfg_shdr *shdr; | ||
1343 | struct fcf_record *new_fcf_record; | ||
1344 | int rc; | ||
1345 | uint32_t boot_flag, addr_mode; | ||
1346 | uint32_t next_fcf_index; | ||
1347 | unsigned long flags; | ||
1348 | uint16_t vlan_id; | ||
1349 | |||
1350 | /* Get the first SGE entry from the non-embedded DMA memory. This | ||
1351 | * routine only uses a single SGE. | ||
1352 | */ | ||
1353 | lpfc_sli4_mbx_sge_get(mboxq, 0, &sge); | ||
1354 | phys_addr = getPaddr(sge.pa_hi, sge.pa_lo); | ||
1355 | if (unlikely(!mboxq->sge_array)) { | ||
1356 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, | ||
1357 | "2524 Failed to get the non-embedded SGE " | ||
1358 | "virtual address\n"); | ||
1359 | goto out; | ||
1360 | } | ||
1361 | virt_addr = mboxq->sge_array->addr[0]; | ||
1362 | |||
1363 | shdr = (union lpfc_sli4_cfg_shdr *)virt_addr; | ||
1364 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | ||
1365 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, | ||
1366 | &shdr->response); | ||
1367 | /* | ||
1368 | * The FCF Record was read and there is no reason for the driver | ||
1369 | * to maintain the FCF record data or memory. Instead, just need | ||
1370 | * to book keeping the FCFIs can be used. | ||
1371 | */ | ||
1372 | if (shdr_status || shdr_add_status) { | ||
1373 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
1374 | "2521 READ_FCF_RECORD mailbox failed " | ||
1375 | "with status x%x add_status x%x, mbx\n", | ||
1376 | shdr_status, shdr_add_status); | ||
1377 | goto out; | ||
1378 | } | ||
1379 | /* Interpreting the returned information of FCF records */ | ||
1380 | read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr; | ||
1381 | lpfc_sli_pcimem_bcopy(read_fcf, read_fcf, | ||
1382 | sizeof(struct lpfc_mbx_read_fcf_tbl)); | ||
1383 | next_fcf_index = bf_get(lpfc_mbx_read_fcf_tbl_nxt_vindx, read_fcf); | ||
1384 | |||
1385 | new_fcf_record = (struct fcf_record *)(virt_addr + | ||
1386 | sizeof(struct lpfc_mbx_read_fcf_tbl)); | ||
1387 | lpfc_sli_pcimem_bcopy(new_fcf_record, new_fcf_record, | ||
1388 | sizeof(struct fcf_record)); | ||
1389 | bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr); | ||
1390 | |||
1391 | rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, | ||
1392 | &boot_flag, &addr_mode, | ||
1393 | &vlan_id); | ||
1394 | /* | ||
1395 | * If the fcf record does not match with connect list entries | ||
1396 | * read the next entry. | ||
1397 | */ | ||
1398 | if (!rc) | ||
1399 | goto read_next_fcf; | ||
1400 | /* | ||
1401 | * If this is not the first FCF discovery of the HBA, use last | ||
1402 | * FCF record for the discovery. | ||
1403 | */ | ||
1404 | spin_lock_irqsave(&phba->hbalock, flags); | ||
1405 | if (phba->fcf.fcf_flag & FCF_IN_USE) { | ||
1406 | if (lpfc_fab_name_match(phba->fcf.fabric_name, | ||
1407 | new_fcf_record) && | ||
1408 | lpfc_mac_addr_match(phba, new_fcf_record)) { | ||
1409 | phba->fcf.fcf_flag |= FCF_AVAILABLE; | ||
1410 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1411 | goto out; | ||
1412 | } | ||
1413 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1414 | goto read_next_fcf; | ||
1415 | } | ||
1416 | if (phba->fcf.fcf_flag & FCF_AVAILABLE) { | ||
1417 | /* | ||
1418 | * If the current FCF record does not have boot flag | ||
1419 | * set and new fcf record has boot flag set, use the | ||
1420 | * new fcf record. | ||
1421 | */ | ||
1422 | if (boot_flag && !(phba->fcf.fcf_flag & FCF_BOOT_ENABLE)) { | ||
1423 | /* Use this FCF record */ | ||
1424 | lpfc_copy_fcf_record(phba, new_fcf_record); | ||
1425 | phba->fcf.addr_mode = addr_mode; | ||
1426 | phba->fcf.fcf_flag |= FCF_BOOT_ENABLE; | ||
1427 | if (vlan_id != 0xFFFF) { | ||
1428 | phba->fcf.fcf_flag |= FCF_VALID_VLAN; | ||
1429 | phba->fcf.vlan_id = vlan_id; | ||
1430 | } | ||
1431 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1432 | goto read_next_fcf; | ||
1433 | } | ||
1434 | /* | ||
1435 | * If the current FCF record has boot flag set and the | ||
1436 | * new FCF record does not have boot flag, read the next | ||
1437 | * FCF record. | ||
1438 | */ | ||
1439 | if (!boot_flag && (phba->fcf.fcf_flag & FCF_BOOT_ENABLE)) { | ||
1440 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1441 | goto read_next_fcf; | ||
1442 | } | ||
1443 | /* | ||
1444 | * If there is a record with lower priority value for | ||
1445 | * the current FCF, use that record. | ||
1446 | */ | ||
1447 | if (lpfc_fab_name_match(phba->fcf.fabric_name, new_fcf_record) | ||
1448 | && (new_fcf_record->fip_priority < | ||
1449 | phba->fcf.priority)) { | ||
1450 | /* Use this FCF record */ | ||
1451 | lpfc_copy_fcf_record(phba, new_fcf_record); | ||
1452 | phba->fcf.addr_mode = addr_mode; | ||
1453 | if (vlan_id != 0xFFFF) { | ||
1454 | phba->fcf.fcf_flag |= FCF_VALID_VLAN; | ||
1455 | phba->fcf.vlan_id = vlan_id; | ||
1456 | } | ||
1457 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1458 | goto read_next_fcf; | ||
1459 | } | ||
1460 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1461 | goto read_next_fcf; | ||
1462 | } | ||
1463 | /* | ||
1464 | * This is the first available FCF record, use this | ||
1465 | * record. | ||
1466 | */ | ||
1467 | lpfc_copy_fcf_record(phba, new_fcf_record); | ||
1468 | phba->fcf.addr_mode = addr_mode; | ||
1469 | if (boot_flag) | ||
1470 | phba->fcf.fcf_flag |= FCF_BOOT_ENABLE; | ||
1471 | phba->fcf.fcf_flag |= FCF_AVAILABLE; | ||
1472 | if (vlan_id != 0xFFFF) { | ||
1473 | phba->fcf.fcf_flag |= FCF_VALID_VLAN; | ||
1474 | phba->fcf.vlan_id = vlan_id; | ||
1475 | } | ||
1476 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1477 | goto read_next_fcf; | ||
1478 | |||
1479 | read_next_fcf: | ||
1480 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
1481 | if (next_fcf_index == LPFC_FCOE_FCF_NEXT_NONE || next_fcf_index == 0) | ||
1482 | lpfc_register_fcf(phba); | ||
1483 | else | ||
1484 | lpfc_sli4_read_fcf_record(phba, next_fcf_index); | ||
1485 | return; | ||
1486 | |||
1487 | out: | ||
1488 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
1489 | lpfc_register_fcf(phba); | ||
1490 | |||
1491 | return; | ||
1492 | } | ||
1493 | |||
1494 | /** | ||
1495 | * lpfc_start_fdiscs - send fdiscs for each vports on this port. | ||
1496 | * @phba: pointer to lpfc hba data structure. | ||
1497 | * | ||
1498 | * This function loops through the list of vports on the @phba and issues an | ||
1499 | * FDISC if possible. | ||
1500 | */ | ||
1501 | void | ||
1502 | lpfc_start_fdiscs(struct lpfc_hba *phba) | ||
1503 | { | ||
1504 | struct lpfc_vport **vports; | ||
1505 | int i; | ||
1506 | |||
1507 | vports = lpfc_create_vport_work_array(phba); | ||
1508 | if (vports != NULL) { | ||
1509 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { | ||
1510 | if (vports[i]->port_type == LPFC_PHYSICAL_PORT) | ||
1511 | continue; | ||
1512 | /* There are no vpi for this vport */ | ||
1513 | if (vports[i]->vpi > phba->max_vpi) { | ||
1514 | lpfc_vport_set_state(vports[i], | ||
1515 | FC_VPORT_FAILED); | ||
1516 | continue; | ||
1517 | } | ||
1518 | if (phba->fc_topology == TOPOLOGY_LOOP) { | ||
1519 | lpfc_vport_set_state(vports[i], | ||
1520 | FC_VPORT_LINKDOWN); | ||
1521 | continue; | ||
1522 | } | ||
1523 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) | ||
1524 | lpfc_initial_fdisc(vports[i]); | ||
1525 | else { | ||
1526 | lpfc_vport_set_state(vports[i], | ||
1527 | FC_VPORT_NO_FABRIC_SUPP); | ||
1528 | lpfc_printf_vlog(vports[i], KERN_ERR, | ||
1529 | LOG_ELS, | ||
1530 | "0259 No NPIV " | ||
1531 | "Fabric support\n"); | ||
1532 | } | ||
1533 | } | ||
1534 | } | ||
1535 | lpfc_destroy_vport_work_array(phba, vports); | ||
1536 | } | ||
1537 | |||
1538 | void | ||
1539 | lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
1540 | { | ||
1541 | struct lpfc_dmabuf *dmabuf = mboxq->context1; | ||
1542 | struct lpfc_vport *vport = mboxq->vport; | ||
1543 | |||
1544 | if (mboxq->u.mb.mbxStatus) { | ||
1545 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, | ||
1546 | "2018 REG_VFI mbxStatus error x%x " | ||
1547 | "HBA state x%x\n", | ||
1548 | mboxq->u.mb.mbxStatus, vport->port_state); | ||
1549 | if (phba->fc_topology == TOPOLOGY_LOOP) { | ||
1550 | /* FLOGI failed, use loop map to make discovery list */ | ||
1551 | lpfc_disc_list_loopmap(vport); | ||
1552 | /* Start discovery */ | ||
1553 | lpfc_disc_start(vport); | ||
1554 | goto fail_free_mem; | ||
1555 | } | ||
1556 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | ||
1557 | goto fail_free_mem; | ||
1558 | } | ||
1559 | /* Mark the vport has registered with its VFI */ | ||
1560 | vport->vfi_state |= LPFC_VFI_REGISTERED; | ||
1561 | |||
1562 | if (vport->port_state == LPFC_FABRIC_CFG_LINK) { | ||
1563 | lpfc_start_fdiscs(phba); | ||
1564 | lpfc_do_scr_ns_plogi(phba, vport); | ||
1565 | } | ||
1566 | |||
1567 | fail_free_mem: | ||
1568 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
1569 | lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys); | ||
1570 | kfree(dmabuf); | ||
1571 | return; | ||
1572 | } | ||
1573 | |||
1574 | static void | ||
987 | lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | 1575 | lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
988 | { | 1576 | { |
989 | MAILBOX_t *mb = &pmb->mb; | 1577 | MAILBOX_t *mb = &pmb->u.mb; |
990 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) pmb->context1; | 1578 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) pmb->context1; |
991 | struct lpfc_vport *vport = pmb->vport; | 1579 | struct lpfc_vport *vport = pmb->vport; |
992 | 1580 | ||
@@ -1037,13 +1625,13 @@ static void | |||
1037 | lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | 1625 | lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) |
1038 | { | 1626 | { |
1039 | struct lpfc_vport *vport = phba->pport; | 1627 | struct lpfc_vport *vport = phba->pport; |
1040 | LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox; | 1628 | LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox = NULL; |
1041 | int i; | 1629 | int i; |
1042 | struct lpfc_dmabuf *mp; | 1630 | struct lpfc_dmabuf *mp; |
1043 | int rc; | 1631 | int rc; |
1632 | struct fcf_record *fcf_record; | ||
1044 | 1633 | ||
1045 | sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 1634 | sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
1046 | cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
1047 | 1635 | ||
1048 | spin_lock_irq(&phba->hbalock); | 1636 | spin_lock_irq(&phba->hbalock); |
1049 | switch (la->UlnkSpeed) { | 1637 | switch (la->UlnkSpeed) { |
@@ -1140,22 +1728,66 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
1140 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 1728 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
1141 | kfree(mp); | 1729 | kfree(mp); |
1142 | mempool_free(sparam_mbox, phba->mbox_mem_pool); | 1730 | mempool_free(sparam_mbox, phba->mbox_mem_pool); |
1143 | if (cfglink_mbox) | ||
1144 | mempool_free(cfglink_mbox, phba->mbox_mem_pool); | ||
1145 | goto out; | 1731 | goto out; |
1146 | } | 1732 | } |
1147 | } | 1733 | } |
1148 | 1734 | ||
1149 | if (cfglink_mbox) { | 1735 | if (!(phba->hba_flag & HBA_FCOE_SUPPORT)) { |
1736 | cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
1737 | if (!cfglink_mbox) | ||
1738 | goto out; | ||
1150 | vport->port_state = LPFC_LOCAL_CFG_LINK; | 1739 | vport->port_state = LPFC_LOCAL_CFG_LINK; |
1151 | lpfc_config_link(phba, cfglink_mbox); | 1740 | lpfc_config_link(phba, cfglink_mbox); |
1152 | cfglink_mbox->vport = vport; | 1741 | cfglink_mbox->vport = vport; |
1153 | cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link; | 1742 | cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link; |
1154 | rc = lpfc_sli_issue_mbox(phba, cfglink_mbox, MBX_NOWAIT); | 1743 | rc = lpfc_sli_issue_mbox(phba, cfglink_mbox, MBX_NOWAIT); |
1155 | if (rc != MBX_NOT_FINISHED) | 1744 | if (rc == MBX_NOT_FINISHED) { |
1156 | return; | 1745 | mempool_free(cfglink_mbox, phba->mbox_mem_pool); |
1157 | mempool_free(cfglink_mbox, phba->mbox_mem_pool); | 1746 | goto out; |
1747 | } | ||
1748 | } else { | ||
1749 | /* | ||
1750 | * Add the driver's default FCF record at FCF index 0 now. This | ||
1751 | * is phase 1 implementation that support FCF index 0 and driver | ||
1752 | * defaults. | ||
1753 | */ | ||
1754 | if (phba->cfg_enable_fip == 0) { | ||
1755 | fcf_record = kzalloc(sizeof(struct fcf_record), | ||
1756 | GFP_KERNEL); | ||
1757 | if (unlikely(!fcf_record)) { | ||
1758 | lpfc_printf_log(phba, KERN_ERR, | ||
1759 | LOG_MBOX | LOG_SLI, | ||
1760 | "2554 Could not allocate memmory for " | ||
1761 | "fcf record\n"); | ||
1762 | rc = -ENODEV; | ||
1763 | goto out; | ||
1764 | } | ||
1765 | |||
1766 | lpfc_sli4_build_dflt_fcf_record(phba, fcf_record, | ||
1767 | LPFC_FCOE_FCF_DEF_INDEX); | ||
1768 | rc = lpfc_sli4_add_fcf_record(phba, fcf_record); | ||
1769 | if (unlikely(rc)) { | ||
1770 | lpfc_printf_log(phba, KERN_ERR, | ||
1771 | LOG_MBOX | LOG_SLI, | ||
1772 | "2013 Could not manually add FCF " | ||
1773 | "record 0, status %d\n", rc); | ||
1774 | rc = -ENODEV; | ||
1775 | kfree(fcf_record); | ||
1776 | goto out; | ||
1777 | } | ||
1778 | kfree(fcf_record); | ||
1779 | } | ||
1780 | /* | ||
1781 | * The driver is expected to do FIP/FCF. Call the port | ||
1782 | * and get the FCF Table. | ||
1783 | */ | ||
1784 | rc = lpfc_sli4_read_fcf_record(phba, | ||
1785 | LPFC_FCOE_FCF_GET_FIRST); | ||
1786 | if (rc) | ||
1787 | goto out; | ||
1158 | } | 1788 | } |
1789 | |||
1790 | return; | ||
1159 | out: | 1791 | out: |
1160 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 1792 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
1161 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, | 1793 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, |
@@ -1186,6 +1818,7 @@ lpfc_mbx_issue_link_down(struct lpfc_hba *phba) | |||
1186 | { | 1818 | { |
1187 | lpfc_linkdown(phba); | 1819 | lpfc_linkdown(phba); |
1188 | lpfc_enable_la(phba); | 1820 | lpfc_enable_la(phba); |
1821 | lpfc_unregister_unused_fcf(phba); | ||
1189 | /* turn on Link Attention interrupts - no CLEAR_LA needed */ | 1822 | /* turn on Link Attention interrupts - no CLEAR_LA needed */ |
1190 | } | 1823 | } |
1191 | 1824 | ||
@@ -3330,3 +3963,395 @@ lpfc_nlp_not_used(struct lpfc_nodelist *ndlp) | |||
3330 | return 1; | 3963 | return 1; |
3331 | return 0; | 3964 | return 0; |
3332 | } | 3965 | } |
3966 | |||
3967 | /** | ||
3968 | * lpfc_fcf_inuse - Check if FCF can be unregistered. | ||
3969 | * @phba: Pointer to hba context object. | ||
3970 | * | ||
3971 | * This function iterate through all FC nodes associated | ||
3972 | * will all vports to check if there is any node with | ||
3973 | * fc_rports associated with it. If there is an fc_rport | ||
3974 | * associated with the node, then the node is either in | ||
3975 | * discovered state or its devloss_timer is pending. | ||
3976 | */ | ||
3977 | static int | ||
3978 | lpfc_fcf_inuse(struct lpfc_hba *phba) | ||
3979 | { | ||
3980 | struct lpfc_vport **vports; | ||
3981 | int i, ret = 0; | ||
3982 | struct lpfc_nodelist *ndlp; | ||
3983 | struct Scsi_Host *shost; | ||
3984 | |||
3985 | vports = lpfc_create_vport_work_array(phba); | ||
3986 | |||
3987 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { | ||
3988 | shost = lpfc_shost_from_vport(vports[i]); | ||
3989 | spin_lock_irq(shost->host_lock); | ||
3990 | list_for_each_entry(ndlp, &vports[i]->fc_nodes, nlp_listp) { | ||
3991 | if (NLP_CHK_NODE_ACT(ndlp) && ndlp->rport && | ||
3992 | (ndlp->rport->roles & FC_RPORT_ROLE_FCP_TARGET)) { | ||
3993 | ret = 1; | ||
3994 | spin_unlock_irq(shost->host_lock); | ||
3995 | goto out; | ||
3996 | } | ||
3997 | } | ||
3998 | spin_unlock_irq(shost->host_lock); | ||
3999 | } | ||
4000 | out: | ||
4001 | lpfc_destroy_vport_work_array(phba, vports); | ||
4002 | return ret; | ||
4003 | } | ||
4004 | |||
4005 | /** | ||
4006 | * lpfc_unregister_vfi_cmpl - Completion handler for unreg vfi. | ||
4007 | * @phba: Pointer to hba context object. | ||
4008 | * @mboxq: Pointer to mailbox object. | ||
4009 | * | ||
4010 | * This function frees memory associated with the mailbox command. | ||
4011 | */ | ||
4012 | static void | ||
4013 | lpfc_unregister_vfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
4014 | { | ||
4015 | struct lpfc_vport *vport = mboxq->vport; | ||
4016 | |||
4017 | if (mboxq->u.mb.mbxStatus) { | ||
4018 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
4019 | "2555 UNREG_VFI mbxStatus error x%x " | ||
4020 | "HBA state x%x\n", | ||
4021 | mboxq->u.mb.mbxStatus, vport->port_state); | ||
4022 | } | ||
4023 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
4024 | return; | ||
4025 | } | ||
4026 | |||
4027 | /** | ||
4028 | * lpfc_unregister_fcfi_cmpl - Completion handler for unreg fcfi. | ||
4029 | * @phba: Pointer to hba context object. | ||
4030 | * @mboxq: Pointer to mailbox object. | ||
4031 | * | ||
4032 | * This function frees memory associated with the mailbox command. | ||
4033 | */ | ||
4034 | static void | ||
4035 | lpfc_unregister_fcfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
4036 | { | ||
4037 | struct lpfc_vport *vport = mboxq->vport; | ||
4038 | |||
4039 | if (mboxq->u.mb.mbxStatus) { | ||
4040 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
4041 | "2550 UNREG_FCFI mbxStatus error x%x " | ||
4042 | "HBA state x%x\n", | ||
4043 | mboxq->u.mb.mbxStatus, vport->port_state); | ||
4044 | } | ||
4045 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
4046 | return; | ||
4047 | } | ||
4048 | |||
4049 | /** | ||
4050 | * lpfc_unregister_unused_fcf - Unregister FCF if all devices are disconnected. | ||
4051 | * @phba: Pointer to hba context object. | ||
4052 | * | ||
4053 | * This function check if there are any connected remote port for the FCF and | ||
4054 | * if all the devices are disconnected, this function unregister FCFI. | ||
4055 | * This function also tries to use another FCF for discovery. | ||
4056 | */ | ||
4057 | void | ||
4058 | lpfc_unregister_unused_fcf(struct lpfc_hba *phba) | ||
4059 | { | ||
4060 | LPFC_MBOXQ_t *mbox; | ||
4061 | int rc; | ||
4062 | struct lpfc_vport **vports; | ||
4063 | int i; | ||
4064 | |||
4065 | spin_lock_irq(&phba->hbalock); | ||
4066 | /* | ||
4067 | * If HBA is not running in FIP mode or | ||
4068 | * If HBA does not support FCoE or | ||
4069 | * If FCF is not registered. | ||
4070 | * do nothing. | ||
4071 | */ | ||
4072 | if (!(phba->hba_flag & HBA_FCOE_SUPPORT) || | ||
4073 | !(phba->fcf.fcf_flag & FCF_REGISTERED) || | ||
4074 | (phba->cfg_enable_fip == 0)) { | ||
4075 | spin_unlock_irq(&phba->hbalock); | ||
4076 | return; | ||
4077 | } | ||
4078 | spin_unlock_irq(&phba->hbalock); | ||
4079 | |||
4080 | if (lpfc_fcf_inuse(phba)) | ||
4081 | return; | ||
4082 | |||
4083 | |||
4084 | /* Unregister VPIs */ | ||
4085 | vports = lpfc_create_vport_work_array(phba); | ||
4086 | if (vports && | ||
4087 | (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) | ||
4088 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { | ||
4089 | lpfc_mbx_unreg_vpi(vports[i]); | ||
4090 | vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | ||
4091 | vports[i]->vfi_state &= ~LPFC_VFI_REGISTERED; | ||
4092 | } | ||
4093 | lpfc_destroy_vport_work_array(phba, vports); | ||
4094 | |||
4095 | /* Unregister VFI */ | ||
4096 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
4097 | if (!mbox) { | ||
4098 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
4099 | "2556 UNREG_VFI mbox allocation failed" | ||
4100 | "HBA state x%x\n", | ||
4101 | phba->pport->port_state); | ||
4102 | return; | ||
4103 | } | ||
4104 | |||
4105 | lpfc_unreg_vfi(mbox, phba->pport->vfi); | ||
4106 | mbox->vport = phba->pport; | ||
4107 | mbox->mbox_cmpl = lpfc_unregister_vfi_cmpl; | ||
4108 | |||
4109 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | ||
4110 | if (rc == MBX_NOT_FINISHED) { | ||
4111 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
4112 | "2557 UNREG_VFI issue mbox failed rc x%x " | ||
4113 | "HBA state x%x\n", | ||
4114 | rc, phba->pport->port_state); | ||
4115 | mempool_free(mbox, phba->mbox_mem_pool); | ||
4116 | return; | ||
4117 | } | ||
4118 | |||
4119 | /* Unregister FCF */ | ||
4120 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
4121 | if (!mbox) { | ||
4122 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
4123 | "2551 UNREG_FCFI mbox allocation failed" | ||
4124 | "HBA state x%x\n", | ||
4125 | phba->pport->port_state); | ||
4126 | return; | ||
4127 | } | ||
4128 | |||
4129 | lpfc_unreg_fcfi(mbox, phba->fcf.fcfi); | ||
4130 | mbox->vport = phba->pport; | ||
4131 | mbox->mbox_cmpl = lpfc_unregister_fcfi_cmpl; | ||
4132 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | ||
4133 | |||
4134 | if (rc == MBX_NOT_FINISHED) { | ||
4135 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
4136 | "2552 UNREG_FCFI issue mbox failed rc x%x " | ||
4137 | "HBA state x%x\n", | ||
4138 | rc, phba->pport->port_state); | ||
4139 | mempool_free(mbox, phba->mbox_mem_pool); | ||
4140 | return; | ||
4141 | } | ||
4142 | |||
4143 | spin_lock_irq(&phba->hbalock); | ||
4144 | phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_REGISTERED | | ||
4145 | FCF_DISCOVERED | FCF_BOOT_ENABLE | FCF_IN_USE | | ||
4146 | FCF_VALID_VLAN); | ||
4147 | spin_unlock_irq(&phba->hbalock); | ||
4148 | |||
4149 | /* | ||
4150 | * If driver is not unloading, check if there is any other | ||
4151 | * FCF record that can be used for discovery. | ||
4152 | */ | ||
4153 | if ((phba->pport->load_flag & FC_UNLOADING) || | ||
4154 | (phba->link_state < LPFC_LINK_UP)) | ||
4155 | return; | ||
4156 | |||
4157 | rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); | ||
4158 | |||
4159 | if (rc) | ||
4160 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | ||
4161 | "2553 lpfc_unregister_unused_fcf failed to read FCF" | ||
4162 | " record HBA state x%x\n", | ||
4163 | phba->pport->port_state); | ||
4164 | } | ||
4165 | |||
4166 | /** | ||
4167 | * lpfc_read_fcf_conn_tbl - Create driver FCF connection table. | ||
4168 | * @phba: Pointer to hba context object. | ||
4169 | * @buff: Buffer containing the FCF connection table as in the config | ||
4170 | * region. | ||
4171 | * This function create driver data structure for the FCF connection | ||
4172 | * record table read from config region 23. | ||
4173 | */ | ||
4174 | static void | ||
4175 | lpfc_read_fcf_conn_tbl(struct lpfc_hba *phba, | ||
4176 | uint8_t *buff) | ||
4177 | { | ||
4178 | struct lpfc_fcf_conn_entry *conn_entry, *next_conn_entry; | ||
4179 | struct lpfc_fcf_conn_hdr *conn_hdr; | ||
4180 | struct lpfc_fcf_conn_rec *conn_rec; | ||
4181 | uint32_t record_count; | ||
4182 | int i; | ||
4183 | |||
4184 | /* Free the current connect table */ | ||
4185 | list_for_each_entry_safe(conn_entry, next_conn_entry, | ||
4186 | &phba->fcf_conn_rec_list, list) | ||
4187 | kfree(conn_entry); | ||
4188 | |||
4189 | conn_hdr = (struct lpfc_fcf_conn_hdr *) buff; | ||
4190 | record_count = conn_hdr->length * sizeof(uint32_t)/ | ||
4191 | sizeof(struct lpfc_fcf_conn_rec); | ||
4192 | |||
4193 | conn_rec = (struct lpfc_fcf_conn_rec *) | ||
4194 | (buff + sizeof(struct lpfc_fcf_conn_hdr)); | ||
4195 | |||
4196 | for (i = 0; i < record_count; i++) { | ||
4197 | if (!(conn_rec[i].flags & FCFCNCT_VALID)) | ||
4198 | continue; | ||
4199 | conn_entry = kzalloc(sizeof(struct lpfc_fcf_conn_entry), | ||
4200 | GFP_KERNEL); | ||
4201 | if (!conn_entry) { | ||
4202 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
4203 | "2566 Failed to allocate connection" | ||
4204 | " table entry\n"); | ||
4205 | return; | ||
4206 | } | ||
4207 | |||
4208 | memcpy(&conn_entry->conn_rec, &conn_rec[i], | ||
4209 | sizeof(struct lpfc_fcf_conn_rec)); | ||
4210 | conn_entry->conn_rec.vlan_tag = | ||
4211 | le16_to_cpu(conn_entry->conn_rec.vlan_tag) & 0xFFF; | ||
4212 | conn_entry->conn_rec.flags = | ||
4213 | le16_to_cpu(conn_entry->conn_rec.flags); | ||
4214 | list_add_tail(&conn_entry->list, | ||
4215 | &phba->fcf_conn_rec_list); | ||
4216 | } | ||
4217 | } | ||
4218 | |||
4219 | /** | ||
4220 | * lpfc_read_fcoe_param - Read FCoe parameters from conf region.. | ||
4221 | * @phba: Pointer to hba context object. | ||
4222 | * @buff: Buffer containing the FCoE parameter data structure. | ||
4223 | * | ||
4224 | * This function update driver data structure with config | ||
4225 | * parameters read from config region 23. | ||
4226 | */ | ||
4227 | static void | ||
4228 | lpfc_read_fcoe_param(struct lpfc_hba *phba, | ||
4229 | uint8_t *buff) | ||
4230 | { | ||
4231 | struct lpfc_fip_param_hdr *fcoe_param_hdr; | ||
4232 | struct lpfc_fcoe_params *fcoe_param; | ||
4233 | |||
4234 | fcoe_param_hdr = (struct lpfc_fip_param_hdr *) | ||
4235 | buff; | ||
4236 | fcoe_param = (struct lpfc_fcoe_params *) | ||
4237 | buff + sizeof(struct lpfc_fip_param_hdr); | ||
4238 | |||
4239 | if ((fcoe_param_hdr->parm_version != FIPP_VERSION) || | ||
4240 | (fcoe_param_hdr->length != FCOE_PARAM_LENGTH)) | ||
4241 | return; | ||
4242 | |||
4243 | if (bf_get(lpfc_fip_param_hdr_fipp_mode, fcoe_param_hdr) == | ||
4244 | FIPP_MODE_ON) | ||
4245 | phba->cfg_enable_fip = 1; | ||
4246 | |||
4247 | if (bf_get(lpfc_fip_param_hdr_fipp_mode, fcoe_param_hdr) == | ||
4248 | FIPP_MODE_OFF) | ||
4249 | phba->cfg_enable_fip = 0; | ||
4250 | |||
4251 | if (fcoe_param_hdr->parm_flags & FIPP_VLAN_VALID) { | ||
4252 | phba->valid_vlan = 1; | ||
4253 | phba->vlan_id = le16_to_cpu(fcoe_param->vlan_tag) & | ||
4254 | 0xFFF; | ||
4255 | } | ||
4256 | |||
4257 | phba->fc_map[0] = fcoe_param->fc_map[0]; | ||
4258 | phba->fc_map[1] = fcoe_param->fc_map[1]; | ||
4259 | phba->fc_map[2] = fcoe_param->fc_map[2]; | ||
4260 | return; | ||
4261 | } | ||
4262 | |||
4263 | /** | ||
4264 | * lpfc_get_rec_conf23 - Get a record type in config region data. | ||
4265 | * @buff: Buffer containing config region 23 data. | ||
4266 | * @size: Size of the data buffer. | ||
4267 | * @rec_type: Record type to be searched. | ||
4268 | * | ||
4269 | * This function searches config region data to find the begining | ||
4270 | * of the record specified by record_type. If record found, this | ||
4271 | * function return pointer to the record else return NULL. | ||
4272 | */ | ||
4273 | static uint8_t * | ||
4274 | lpfc_get_rec_conf23(uint8_t *buff, uint32_t size, uint8_t rec_type) | ||
4275 | { | ||
4276 | uint32_t offset = 0, rec_length; | ||
4277 | |||
4278 | if ((buff[0] == LPFC_REGION23_LAST_REC) || | ||
4279 | (size < sizeof(uint32_t))) | ||
4280 | return NULL; | ||
4281 | |||
4282 | rec_length = buff[offset + 1]; | ||
4283 | |||
4284 | /* | ||
4285 | * One TLV record has one word header and number of data words | ||
4286 | * specified in the rec_length field of the record header. | ||
4287 | */ | ||
4288 | while ((offset + rec_length * sizeof(uint32_t) + sizeof(uint32_t)) | ||
4289 | <= size) { | ||
4290 | if (buff[offset] == rec_type) | ||
4291 | return &buff[offset]; | ||
4292 | |||
4293 | if (buff[offset] == LPFC_REGION23_LAST_REC) | ||
4294 | return NULL; | ||
4295 | |||
4296 | offset += rec_length * sizeof(uint32_t) + sizeof(uint32_t); | ||
4297 | rec_length = buff[offset + 1]; | ||
4298 | } | ||
4299 | return NULL; | ||
4300 | } | ||
4301 | |||
4302 | /** | ||
4303 | * lpfc_parse_fcoe_conf - Parse FCoE config data read from config region 23. | ||
4304 | * @phba: Pointer to lpfc_hba data structure. | ||
4305 | * @buff: Buffer containing config region 23 data. | ||
4306 | * @size: Size of the data buffer. | ||
4307 | * | ||
4308 | * This fuction parse the FCoE config parameters in config region 23 and | ||
4309 | * populate driver data structure with the parameters. | ||
4310 | */ | ||
4311 | void | ||
4312 | lpfc_parse_fcoe_conf(struct lpfc_hba *phba, | ||
4313 | uint8_t *buff, | ||
4314 | uint32_t size) | ||
4315 | { | ||
4316 | uint32_t offset = 0, rec_length; | ||
4317 | uint8_t *rec_ptr; | ||
4318 | |||
4319 | /* | ||
4320 | * If data size is less than 2 words signature and version cannot be | ||
4321 | * verified. | ||
4322 | */ | ||
4323 | if (size < 2*sizeof(uint32_t)) | ||
4324 | return; | ||
4325 | |||
4326 | /* Check the region signature first */ | ||
4327 | if (memcmp(buff, LPFC_REGION23_SIGNATURE, 4)) { | ||
4328 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
4329 | "2567 Config region 23 has bad signature\n"); | ||
4330 | return; | ||
4331 | } | ||
4332 | |||
4333 | offset += 4; | ||
4334 | |||
4335 | /* Check the data structure version */ | ||
4336 | if (buff[offset] != LPFC_REGION23_VERSION) { | ||
4337 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
4338 | "2568 Config region 23 has bad version\n"); | ||
4339 | return; | ||
4340 | } | ||
4341 | offset += 4; | ||
4342 | |||
4343 | rec_length = buff[offset + 1]; | ||
4344 | |||
4345 | /* Read FCoE param record */ | ||
4346 | rec_ptr = lpfc_get_rec_conf23(&buff[offset], | ||
4347 | size - offset, FCOE_PARAM_TYPE); | ||
4348 | if (rec_ptr) | ||
4349 | lpfc_read_fcoe_param(phba, rec_ptr); | ||
4350 | |||
4351 | /* Read FCF connection table */ | ||
4352 | rec_ptr = lpfc_get_rec_conf23(&buff[offset], | ||
4353 | size - offset, FCOE_CONN_TBL_TYPE); | ||
4354 | if (rec_ptr) | ||
4355 | lpfc_read_fcf_conn_tbl(phba, rec_ptr); | ||
4356 | |||
4357 | } | ||
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 6efe459e8ddf..2c7eba686262 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c | |||
@@ -363,7 +363,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
363 | if (!mbox) | 363 | if (!mbox) |
364 | goto out; | 364 | goto out; |
365 | 365 | ||
366 | rc = lpfc_reg_login(phba, vport->vpi, icmd->un.rcvels.remoteID, | 366 | rc = lpfc_reg_rpi(phba, vport->vpi, icmd->un.rcvels.remoteID, |
367 | (uint8_t *) sp, mbox, 0); | 367 | (uint8_t *) sp, mbox, 0); |
368 | if (rc) { | 368 | if (rc) { |
369 | mempool_free(mbox, phba->mbox_mem_pool); | 369 | mempool_free(mbox, phba->mbox_mem_pool); |
@@ -497,11 +497,19 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
497 | lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL); | 497 | lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL); |
498 | else | 498 | else |
499 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); | 499 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); |
500 | if ((ndlp->nlp_type & NLP_FABRIC) && | ||
501 | vport->port_type == LPFC_NPIV_PORT) { | ||
502 | lpfc_linkdown_port(vport); | ||
503 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); | ||
504 | spin_lock_irq(shost->host_lock); | ||
505 | ndlp->nlp_flag |= NLP_DELAY_TMO; | ||
506 | spin_unlock_irq(shost->host_lock); | ||
500 | 507 | ||
501 | if ((!(ndlp->nlp_type & NLP_FABRIC) && | 508 | ndlp->nlp_last_elscmd = ELS_CMD_FDISC; |
502 | ((ndlp->nlp_type & NLP_FCP_TARGET) || | 509 | } else if ((!(ndlp->nlp_type & NLP_FABRIC) && |
503 | !(ndlp->nlp_type & NLP_FCP_INITIATOR))) || | 510 | ((ndlp->nlp_type & NLP_FCP_TARGET) || |
504 | (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) { | 511 | !(ndlp->nlp_type & NLP_FCP_INITIATOR))) || |
512 | (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) { | ||
505 | /* Only try to re-login if this is NOT a Fabric Node */ | 513 | /* Only try to re-login if this is NOT a Fabric Node */ |
506 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); | 514 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); |
507 | spin_lock_irq(shost->host_lock); | 515 | spin_lock_irq(shost->host_lock); |
@@ -569,7 +577,7 @@ lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
569 | { | 577 | { |
570 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 578 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
571 | 579 | ||
572 | if (!ndlp->nlp_rpi) { | 580 | if (!(ndlp->nlp_flag & NLP_RPI_VALID)) { |
573 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 581 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
574 | return 0; | 582 | return 0; |
575 | } | 583 | } |
@@ -859,7 +867,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, | |||
859 | 867 | ||
860 | lpfc_unreg_rpi(vport, ndlp); | 868 | lpfc_unreg_rpi(vport, ndlp); |
861 | 869 | ||
862 | if (lpfc_reg_login(phba, vport->vpi, irsp->un.elsreq64.remoteID, | 870 | if (lpfc_reg_rpi(phba, vport->vpi, irsp->un.elsreq64.remoteID, |
863 | (uint8_t *) sp, mbox, 0) == 0) { | 871 | (uint8_t *) sp, mbox, 0) == 0) { |
864 | switch (ndlp->nlp_DID) { | 872 | switch (ndlp->nlp_DID) { |
865 | case NameServer_DID: | 873 | case NameServer_DID: |
@@ -1070,6 +1078,7 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_vport *vport, | |||
1070 | struct lpfc_iocbq *cmdiocb, *rspiocb; | 1078 | struct lpfc_iocbq *cmdiocb, *rspiocb; |
1071 | IOCB_t *irsp; | 1079 | IOCB_t *irsp; |
1072 | ADISC *ap; | 1080 | ADISC *ap; |
1081 | int rc; | ||
1073 | 1082 | ||
1074 | cmdiocb = (struct lpfc_iocbq *) arg; | 1083 | cmdiocb = (struct lpfc_iocbq *) arg; |
1075 | rspiocb = cmdiocb->context_un.rsp_iocb; | 1084 | rspiocb = cmdiocb->context_un.rsp_iocb; |
@@ -1095,6 +1104,15 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_vport *vport, | |||
1095 | return ndlp->nlp_state; | 1104 | return ndlp->nlp_state; |
1096 | } | 1105 | } |
1097 | 1106 | ||
1107 | if (phba->sli_rev == LPFC_SLI_REV4) { | ||
1108 | rc = lpfc_sli4_resume_rpi(ndlp); | ||
1109 | if (rc) { | ||
1110 | /* Stay in state and retry. */ | ||
1111 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | ||
1112 | return ndlp->nlp_state; | ||
1113 | } | ||
1114 | } | ||
1115 | |||
1098 | if (ndlp->nlp_type & NLP_FCP_TARGET) { | 1116 | if (ndlp->nlp_type & NLP_FCP_TARGET) { |
1099 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | 1117 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; |
1100 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE); | 1118 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE); |
@@ -1102,6 +1120,7 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_vport *vport, | |||
1102 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | 1120 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; |
1103 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); | 1121 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
1104 | } | 1122 | } |
1123 | |||
1105 | return ndlp->nlp_state; | 1124 | return ndlp->nlp_state; |
1106 | } | 1125 | } |
1107 | 1126 | ||
@@ -1285,6 +1304,7 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport, | |||
1285 | } | 1304 | } |
1286 | 1305 | ||
1287 | ndlp->nlp_rpi = mb->un.varWords[0]; | 1306 | ndlp->nlp_rpi = mb->un.varWords[0]; |
1307 | ndlp->nlp_flag |= NLP_RPI_VALID; | ||
1288 | 1308 | ||
1289 | /* Only if we are not a fabric nport do we issue PRLI */ | 1309 | /* Only if we are not a fabric nport do we issue PRLI */ |
1290 | if (!(ndlp->nlp_type & NLP_FABRIC)) { | 1310 | if (!(ndlp->nlp_type & NLP_FABRIC)) { |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index b53af9936282..9645d32e6f87 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -10929,3 +10929,520 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba) | |||
10929 | }; | 10929 | }; |
10930 | return 0; | 10930 | return 0; |
10931 | } | 10931 | } |
10932 | |||
10933 | /** | ||
10934 | * lpfc_sli4_post_all_rpi_hdrs - Post the rpi header memory region to the port | ||
10935 | * @phba: pointer to lpfc hba data structure. | ||
10936 | * | ||
10937 | * This routine is invoked to post rpi header templates to the | ||
10938 | * HBA consistent with the SLI-4 interface spec. This routine | ||
10939 | * posts a PAGE_SIZE memory region to the port to hold up to | ||
10940 | * PAGE_SIZE modulo 64 rpi context headers. | ||
10941 | * | ||
10942 | * This routine does not require any locks. It's usage is expected | ||
10943 | * to be driver load or reset recovery when the driver is | ||
10944 | * sequential. | ||
10945 | * | ||
10946 | * Return codes | ||
10947 | * 0 - sucessful | ||
10948 | * EIO - The mailbox failed to complete successfully. | ||
10949 | * When this error occurs, the driver is not guaranteed | ||
10950 | * to have any rpi regions posted to the device and | ||
10951 | * must either attempt to repost the regions or take a | ||
10952 | * fatal error. | ||
10953 | **/ | ||
10954 | int | ||
10955 | lpfc_sli4_post_all_rpi_hdrs(struct lpfc_hba *phba) | ||
10956 | { | ||
10957 | struct lpfc_rpi_hdr *rpi_page; | ||
10958 | uint32_t rc = 0; | ||
10959 | |||
10960 | /* Post all rpi memory regions to the port. */ | ||
10961 | list_for_each_entry(rpi_page, &phba->sli4_hba.lpfc_rpi_hdr_list, list) { | ||
10962 | rc = lpfc_sli4_post_rpi_hdr(phba, rpi_page); | ||
10963 | if (rc != MBX_SUCCESS) { | ||
10964 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
10965 | "2008 Error %d posting all rpi " | ||
10966 | "headers\n", rc); | ||
10967 | rc = -EIO; | ||
10968 | break; | ||
10969 | } | ||
10970 | } | ||
10971 | |||
10972 | return rc; | ||
10973 | } | ||
10974 | |||
10975 | /** | ||
10976 | * lpfc_sli4_post_rpi_hdr - Post an rpi header memory region to the port | ||
10977 | * @phba: pointer to lpfc hba data structure. | ||
10978 | * @rpi_page: pointer to the rpi memory region. | ||
10979 | * | ||
10980 | * This routine is invoked to post a single rpi header to the | ||
10981 | * HBA consistent with the SLI-4 interface spec. This memory region | ||
10982 | * maps up to 64 rpi context regions. | ||
10983 | * | ||
10984 | * Return codes | ||
10985 | * 0 - sucessful | ||
10986 | * ENOMEM - No available memory | ||
10987 | * EIO - The mailbox failed to complete successfully. | ||
10988 | **/ | ||
10989 | int | ||
10990 | lpfc_sli4_post_rpi_hdr(struct lpfc_hba *phba, struct lpfc_rpi_hdr *rpi_page) | ||
10991 | { | ||
10992 | LPFC_MBOXQ_t *mboxq; | ||
10993 | struct lpfc_mbx_post_hdr_tmpl *hdr_tmpl; | ||
10994 | uint32_t rc = 0; | ||
10995 | uint32_t mbox_tmo; | ||
10996 | uint32_t shdr_status, shdr_add_status; | ||
10997 | union lpfc_sli4_cfg_shdr *shdr; | ||
10998 | |||
10999 | /* The port is notified of the header region via a mailbox command. */ | ||
11000 | mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
11001 | if (!mboxq) { | ||
11002 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
11003 | "2001 Unable to allocate memory for issuing " | ||
11004 | "SLI_CONFIG_SPECIAL mailbox command\n"); | ||
11005 | return -ENOMEM; | ||
11006 | } | ||
11007 | |||
11008 | /* Post all rpi memory regions to the port. */ | ||
11009 | hdr_tmpl = &mboxq->u.mqe.un.hdr_tmpl; | ||
11010 | mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_SLI4_CONFIG); | ||
11011 | lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_FCOE, | ||
11012 | LPFC_MBOX_OPCODE_FCOE_POST_HDR_TEMPLATE, | ||
11013 | sizeof(struct lpfc_mbx_post_hdr_tmpl) - | ||
11014 | sizeof(struct mbox_header), LPFC_SLI4_MBX_EMBED); | ||
11015 | bf_set(lpfc_mbx_post_hdr_tmpl_page_cnt, | ||
11016 | hdr_tmpl, rpi_page->page_count); | ||
11017 | bf_set(lpfc_mbx_post_hdr_tmpl_rpi_offset, hdr_tmpl, | ||
11018 | rpi_page->start_rpi); | ||
11019 | hdr_tmpl->rpi_paddr_lo = putPaddrLow(rpi_page->dmabuf->phys); | ||
11020 | hdr_tmpl->rpi_paddr_hi = putPaddrHigh(rpi_page->dmabuf->phys); | ||
11021 | if (!phba->sli4_hba.intr_enable) | ||
11022 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); | ||
11023 | else | ||
11024 | rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo); | ||
11025 | shdr = (union lpfc_sli4_cfg_shdr *) &hdr_tmpl->header.cfg_shdr; | ||
11026 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | ||
11027 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); | ||
11028 | if (rc != MBX_TIMEOUT) | ||
11029 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
11030 | if (shdr_status || shdr_add_status || rc) { | ||
11031 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
11032 | "2514 POST_RPI_HDR mailbox failed with " | ||
11033 | "status x%x add_status x%x, mbx status x%x\n", | ||
11034 | shdr_status, shdr_add_status, rc); | ||
11035 | rc = -ENXIO; | ||
11036 | } | ||
11037 | return rc; | ||
11038 | } | ||
11039 | |||
11040 | /** | ||
11041 | * lpfc_sli4_alloc_rpi - Get an available rpi in the device's range | ||
11042 | * @phba: pointer to lpfc hba data structure. | ||
11043 | * | ||
11044 | * This routine is invoked to post rpi header templates to the | ||
11045 | * HBA consistent with the SLI-4 interface spec. This routine | ||
11046 | * posts a PAGE_SIZE memory region to the port to hold up to | ||
11047 | * PAGE_SIZE modulo 64 rpi context headers. | ||
11048 | * | ||
11049 | * Returns | ||
11050 | * A nonzero rpi defined as rpi_base <= rpi < max_rpi if sucessful | ||
11051 | * LPFC_RPI_ALLOC_ERROR if no rpis are available. | ||
11052 | **/ | ||
11053 | int | ||
11054 | lpfc_sli4_alloc_rpi(struct lpfc_hba *phba) | ||
11055 | { | ||
11056 | int rpi; | ||
11057 | uint16_t max_rpi, rpi_base, rpi_limit; | ||
11058 | uint16_t rpi_remaining; | ||
11059 | struct lpfc_rpi_hdr *rpi_hdr; | ||
11060 | |||
11061 | max_rpi = phba->sli4_hba.max_cfg_param.max_rpi; | ||
11062 | rpi_base = phba->sli4_hba.max_cfg_param.rpi_base; | ||
11063 | rpi_limit = phba->sli4_hba.next_rpi; | ||
11064 | |||
11065 | /* | ||
11066 | * The valid rpi range is not guaranteed to be zero-based. Start | ||
11067 | * the search at the rpi_base as reported by the port. | ||
11068 | */ | ||
11069 | spin_lock_irq(&phba->hbalock); | ||
11070 | rpi = find_next_zero_bit(phba->sli4_hba.rpi_bmask, rpi_limit, rpi_base); | ||
11071 | if (rpi >= rpi_limit || rpi < rpi_base) | ||
11072 | rpi = LPFC_RPI_ALLOC_ERROR; | ||
11073 | else { | ||
11074 | set_bit(rpi, phba->sli4_hba.rpi_bmask); | ||
11075 | phba->sli4_hba.max_cfg_param.rpi_used++; | ||
11076 | phba->sli4_hba.rpi_count++; | ||
11077 | } | ||
11078 | |||
11079 | /* | ||
11080 | * Don't try to allocate more rpi header regions if the device limit | ||
11081 | * on available rpis max has been exhausted. | ||
11082 | */ | ||
11083 | if ((rpi == LPFC_RPI_ALLOC_ERROR) && | ||
11084 | (phba->sli4_hba.rpi_count >= max_rpi)) { | ||
11085 | spin_unlock_irq(&phba->hbalock); | ||
11086 | return rpi; | ||
11087 | } | ||
11088 | |||
11089 | /* | ||
11090 | * If the driver is running low on rpi resources, allocate another | ||
11091 | * page now. Note that the next_rpi value is used because | ||
11092 | * it represents how many are actually in use whereas max_rpi notes | ||
11093 | * how many are supported max by the device. | ||
11094 | */ | ||
11095 | rpi_remaining = phba->sli4_hba.next_rpi - rpi_base - | ||
11096 | phba->sli4_hba.rpi_count; | ||
11097 | spin_unlock_irq(&phba->hbalock); | ||
11098 | if (rpi_remaining < LPFC_RPI_LOW_WATER_MARK) { | ||
11099 | rpi_hdr = lpfc_sli4_create_rpi_hdr(phba); | ||
11100 | if (!rpi_hdr) { | ||
11101 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
11102 | "2002 Error Could not grow rpi " | ||
11103 | "count\n"); | ||
11104 | } else { | ||
11105 | lpfc_sli4_post_rpi_hdr(phba, rpi_hdr); | ||
11106 | } | ||
11107 | } | ||
11108 | |||
11109 | return rpi; | ||
11110 | } | ||
11111 | |||
11112 | /** | ||
11113 | * lpfc_sli4_free_rpi - Release an rpi for reuse. | ||
11114 | * @phba: pointer to lpfc hba data structure. | ||
11115 | * | ||
11116 | * This routine is invoked to release an rpi to the pool of | ||
11117 | * available rpis maintained by the driver. | ||
11118 | **/ | ||
11119 | void | ||
11120 | lpfc_sli4_free_rpi(struct lpfc_hba *phba, int rpi) | ||
11121 | { | ||
11122 | spin_lock_irq(&phba->hbalock); | ||
11123 | clear_bit(rpi, phba->sli4_hba.rpi_bmask); | ||
11124 | phba->sli4_hba.rpi_count--; | ||
11125 | phba->sli4_hba.max_cfg_param.rpi_used--; | ||
11126 | spin_unlock_irq(&phba->hbalock); | ||
11127 | } | ||
11128 | |||
11129 | /** | ||
11130 | * lpfc_sli4_remove_rpis - Remove the rpi bitmask region | ||
11131 | * @phba: pointer to lpfc hba data structure. | ||
11132 | * | ||
11133 | * This routine is invoked to remove the memory region that | ||
11134 | * provided rpi via a bitmask. | ||
11135 | **/ | ||
11136 | void | ||
11137 | lpfc_sli4_remove_rpis(struct lpfc_hba *phba) | ||
11138 | { | ||
11139 | kfree(phba->sli4_hba.rpi_bmask); | ||
11140 | } | ||
11141 | |||
11142 | /** | ||
11143 | * lpfc_sli4_resume_rpi - Remove the rpi bitmask region | ||
11144 | * @phba: pointer to lpfc hba data structure. | ||
11145 | * | ||
11146 | * This routine is invoked to remove the memory region that | ||
11147 | * provided rpi via a bitmask. | ||
11148 | **/ | ||
11149 | int | ||
11150 | lpfc_sli4_resume_rpi(struct lpfc_nodelist *ndlp) | ||
11151 | { | ||
11152 | LPFC_MBOXQ_t *mboxq; | ||
11153 | struct lpfc_hba *phba = ndlp->phba; | ||
11154 | int rc; | ||
11155 | |||
11156 | /* The port is notified of the header region via a mailbox command. */ | ||
11157 | mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
11158 | if (!mboxq) | ||
11159 | return -ENOMEM; | ||
11160 | |||
11161 | /* Post all rpi memory regions to the port. */ | ||
11162 | lpfc_resume_rpi(mboxq, ndlp); | ||
11163 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); | ||
11164 | if (rc == MBX_NOT_FINISHED) { | ||
11165 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
11166 | "2010 Resume RPI Mailbox failed " | ||
11167 | "status %d, mbxStatus x%x\n", rc, | ||
11168 | bf_get(lpfc_mqe_status, &mboxq->u.mqe)); | ||
11169 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
11170 | return -EIO; | ||
11171 | } | ||
11172 | return 0; | ||
11173 | } | ||
11174 | |||
11175 | /** | ||
11176 | * lpfc_sli4_init_vpi - Initialize a vpi with the port | ||
11177 | * @phba: pointer to lpfc hba data structure. | ||
11178 | * @vpi: vpi value to activate with the port. | ||
11179 | * | ||
11180 | * This routine is invoked to activate a vpi with the | ||
11181 | * port when the host intends to use vports with a | ||
11182 | * nonzero vpi. | ||
11183 | * | ||
11184 | * Returns: | ||
11185 | * 0 success | ||
11186 | * -Evalue otherwise | ||
11187 | **/ | ||
11188 | int | ||
11189 | lpfc_sli4_init_vpi(struct lpfc_hba *phba, uint16_t vpi) | ||
11190 | { | ||
11191 | LPFC_MBOXQ_t *mboxq; | ||
11192 | int rc = 0; | ||
11193 | uint32_t mbox_tmo; | ||
11194 | |||
11195 | if (vpi == 0) | ||
11196 | return -EINVAL; | ||
11197 | mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
11198 | if (!mboxq) | ||
11199 | return -ENOMEM; | ||
11200 | lpfc_init_vpi(mboxq, vpi); | ||
11201 | mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_INIT_VPI); | ||
11202 | rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo); | ||
11203 | if (rc != MBX_TIMEOUT) | ||
11204 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
11205 | if (rc != MBX_SUCCESS) { | ||
11206 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, | ||
11207 | "2022 INIT VPI Mailbox failed " | ||
11208 | "status %d, mbxStatus x%x\n", rc, | ||
11209 | bf_get(lpfc_mqe_status, &mboxq->u.mqe)); | ||
11210 | rc = -EIO; | ||
11211 | } | ||
11212 | return rc; | ||
11213 | } | ||
11214 | |||
11215 | /** | ||
11216 | * lpfc_mbx_cmpl_add_fcf_record - add fcf mbox completion handler. | ||
11217 | * @phba: pointer to lpfc hba data structure. | ||
11218 | * @mboxq: Pointer to mailbox object. | ||
11219 | * | ||
11220 | * This routine is invoked to manually add a single FCF record. The caller | ||
11221 | * must pass a completely initialized FCF_Record. This routine takes | ||
11222 | * care of the nonembedded mailbox operations. | ||
11223 | **/ | ||
11224 | static void | ||
11225 | lpfc_mbx_cmpl_add_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | ||
11226 | { | ||
11227 | void *virt_addr; | ||
11228 | union lpfc_sli4_cfg_shdr *shdr; | ||
11229 | uint32_t shdr_status, shdr_add_status; | ||
11230 | |||
11231 | virt_addr = mboxq->sge_array->addr[0]; | ||
11232 | /* The IOCTL status is embedded in the mailbox subheader. */ | ||
11233 | shdr = (union lpfc_sli4_cfg_shdr *) virt_addr; | ||
11234 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | ||
11235 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); | ||
11236 | |||
11237 | if ((shdr_status || shdr_add_status) && | ||
11238 | (shdr_status != STATUS_FCF_IN_USE)) | ||
11239 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
11240 | "2558 ADD_FCF_RECORD mailbox failed with " | ||
11241 | "status x%x add_status x%x\n", | ||
11242 | shdr_status, shdr_add_status); | ||
11243 | |||
11244 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
11245 | } | ||
11246 | |||
11247 | /** | ||
11248 | * lpfc_sli4_add_fcf_record - Manually add an FCF Record. | ||
11249 | * @phba: pointer to lpfc hba data structure. | ||
11250 | * @fcf_record: pointer to the initialized fcf record to add. | ||
11251 | * | ||
11252 | * This routine is invoked to manually add a single FCF record. The caller | ||
11253 | * must pass a completely initialized FCF_Record. This routine takes | ||
11254 | * care of the nonembedded mailbox operations. | ||
11255 | **/ | ||
11256 | int | ||
11257 | lpfc_sli4_add_fcf_record(struct lpfc_hba *phba, struct fcf_record *fcf_record) | ||
11258 | { | ||
11259 | int rc = 0; | ||
11260 | LPFC_MBOXQ_t *mboxq; | ||
11261 | uint8_t *bytep; | ||
11262 | void *virt_addr; | ||
11263 | dma_addr_t phys_addr; | ||
11264 | struct lpfc_mbx_sge sge; | ||
11265 | uint32_t alloc_len, req_len; | ||
11266 | uint32_t fcfindex; | ||
11267 | |||
11268 | mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
11269 | if (!mboxq) { | ||
11270 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
11271 | "2009 Failed to allocate mbox for ADD_FCF cmd\n"); | ||
11272 | return -ENOMEM; | ||
11273 | } | ||
11274 | |||
11275 | req_len = sizeof(struct fcf_record) + sizeof(union lpfc_sli4_cfg_shdr) + | ||
11276 | sizeof(uint32_t); | ||
11277 | |||
11278 | /* Allocate DMA memory and set up the non-embedded mailbox command */ | ||
11279 | alloc_len = lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_FCOE, | ||
11280 | LPFC_MBOX_OPCODE_FCOE_ADD_FCF, | ||
11281 | req_len, LPFC_SLI4_MBX_NEMBED); | ||
11282 | if (alloc_len < req_len) { | ||
11283 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
11284 | "2523 Allocated DMA memory size (x%x) is " | ||
11285 | "less than the requested DMA memory " | ||
11286 | "size (x%x)\n", alloc_len, req_len); | ||
11287 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
11288 | return -ENOMEM; | ||
11289 | } | ||
11290 | |||
11291 | /* | ||
11292 | * Get the first SGE entry from the non-embedded DMA memory. This | ||
11293 | * routine only uses a single SGE. | ||
11294 | */ | ||
11295 | lpfc_sli4_mbx_sge_get(mboxq, 0, &sge); | ||
11296 | phys_addr = getPaddr(sge.pa_hi, sge.pa_lo); | ||
11297 | if (unlikely(!mboxq->sge_array)) { | ||
11298 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, | ||
11299 | "2526 Failed to get the non-embedded SGE " | ||
11300 | "virtual address\n"); | ||
11301 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
11302 | return -ENOMEM; | ||
11303 | } | ||
11304 | virt_addr = mboxq->sge_array->addr[0]; | ||
11305 | /* | ||
11306 | * Configure the FCF record for FCFI 0. This is the driver's | ||
11307 | * hardcoded default and gets used in nonFIP mode. | ||
11308 | */ | ||
11309 | fcfindex = bf_get(lpfc_fcf_record_fcf_index, fcf_record); | ||
11310 | bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr); | ||
11311 | lpfc_sli_pcimem_bcopy(&fcfindex, bytep, sizeof(uint32_t)); | ||
11312 | |||
11313 | /* | ||
11314 | * Copy the fcf_index and the FCF Record Data. The data starts after | ||
11315 | * the FCoE header plus word10. The data copy needs to be endian | ||
11316 | * correct. | ||
11317 | */ | ||
11318 | bytep += sizeof(uint32_t); | ||
11319 | lpfc_sli_pcimem_bcopy(fcf_record, bytep, sizeof(struct fcf_record)); | ||
11320 | mboxq->vport = phba->pport; | ||
11321 | mboxq->mbox_cmpl = lpfc_mbx_cmpl_add_fcf_record; | ||
11322 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); | ||
11323 | if (rc == MBX_NOT_FINISHED) { | ||
11324 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
11325 | "2515 ADD_FCF_RECORD mailbox failed with " | ||
11326 | "status 0x%x\n", rc); | ||
11327 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
11328 | rc = -EIO; | ||
11329 | } else | ||
11330 | rc = 0; | ||
11331 | |||
11332 | return rc; | ||
11333 | } | ||
11334 | |||
11335 | /** | ||
11336 | * lpfc_sli4_build_dflt_fcf_record - Build the driver's default FCF Record. | ||
11337 | * @phba: pointer to lpfc hba data structure. | ||
11338 | * @fcf_record: pointer to the fcf record to write the default data. | ||
11339 | * @fcf_index: FCF table entry index. | ||
11340 | * | ||
11341 | * This routine is invoked to build the driver's default FCF record. The | ||
11342 | * values used are hardcoded. This routine handles memory initialization. | ||
11343 | * | ||
11344 | **/ | ||
11345 | void | ||
11346 | lpfc_sli4_build_dflt_fcf_record(struct lpfc_hba *phba, | ||
11347 | struct fcf_record *fcf_record, | ||
11348 | uint16_t fcf_index) | ||
11349 | { | ||
11350 | memset(fcf_record, 0, sizeof(struct fcf_record)); | ||
11351 | fcf_record->max_rcv_size = LPFC_FCOE_MAX_RCV_SIZE; | ||
11352 | fcf_record->fka_adv_period = LPFC_FCOE_FKA_ADV_PER; | ||
11353 | fcf_record->fip_priority = LPFC_FCOE_FIP_PRIORITY; | ||
11354 | bf_set(lpfc_fcf_record_mac_0, fcf_record, phba->fc_map[0]); | ||
11355 | bf_set(lpfc_fcf_record_mac_1, fcf_record, phba->fc_map[1]); | ||
11356 | bf_set(lpfc_fcf_record_mac_2, fcf_record, phba->fc_map[2]); | ||
11357 | bf_set(lpfc_fcf_record_mac_3, fcf_record, LPFC_FCOE_FCF_MAC3); | ||
11358 | bf_set(lpfc_fcf_record_mac_4, fcf_record, LPFC_FCOE_FCF_MAC4); | ||
11359 | bf_set(lpfc_fcf_record_mac_5, fcf_record, LPFC_FCOE_FCF_MAC5); | ||
11360 | bf_set(lpfc_fcf_record_fc_map_0, fcf_record, phba->fc_map[0]); | ||
11361 | bf_set(lpfc_fcf_record_fc_map_1, fcf_record, phba->fc_map[1]); | ||
11362 | bf_set(lpfc_fcf_record_fc_map_2, fcf_record, phba->fc_map[2]); | ||
11363 | bf_set(lpfc_fcf_record_fcf_valid, fcf_record, 1); | ||
11364 | bf_set(lpfc_fcf_record_fcf_index, fcf_record, fcf_index); | ||
11365 | bf_set(lpfc_fcf_record_mac_addr_prov, fcf_record, | ||
11366 | LPFC_FCF_FPMA | LPFC_FCF_SPMA); | ||
11367 | /* Set the VLAN bit map */ | ||
11368 | if (phba->valid_vlan) { | ||
11369 | fcf_record->vlan_bitmap[phba->vlan_id / 8] | ||
11370 | = 1 << (phba->vlan_id % 8); | ||
11371 | } | ||
11372 | } | ||
11373 | |||
11374 | /** | ||
11375 | * lpfc_sli4_read_fcf_record - Read the driver's default FCF Record. | ||
11376 | * @phba: pointer to lpfc hba data structure. | ||
11377 | * @fcf_index: FCF table entry offset. | ||
11378 | * | ||
11379 | * This routine is invoked to read up to @fcf_num of FCF record from the | ||
11380 | * device starting with the given @fcf_index. | ||
11381 | **/ | ||
11382 | int | ||
11383 | lpfc_sli4_read_fcf_record(struct lpfc_hba *phba, uint16_t fcf_index) | ||
11384 | { | ||
11385 | int rc = 0, error; | ||
11386 | LPFC_MBOXQ_t *mboxq; | ||
11387 | void *virt_addr; | ||
11388 | dma_addr_t phys_addr; | ||
11389 | uint8_t *bytep; | ||
11390 | struct lpfc_mbx_sge sge; | ||
11391 | uint32_t alloc_len, req_len; | ||
11392 | struct lpfc_mbx_read_fcf_tbl *read_fcf; | ||
11393 | |||
11394 | mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
11395 | if (!mboxq) { | ||
11396 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
11397 | "2000 Failed to allocate mbox for " | ||
11398 | "READ_FCF cmd\n"); | ||
11399 | return -ENOMEM; | ||
11400 | } | ||
11401 | |||
11402 | req_len = sizeof(struct fcf_record) + | ||
11403 | sizeof(union lpfc_sli4_cfg_shdr) + 2 * sizeof(uint32_t); | ||
11404 | |||
11405 | /* Set up READ_FCF SLI4_CONFIG mailbox-ioctl command */ | ||
11406 | alloc_len = lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_FCOE, | ||
11407 | LPFC_MBOX_OPCODE_FCOE_READ_FCF_TABLE, req_len, | ||
11408 | LPFC_SLI4_MBX_NEMBED); | ||
11409 | |||
11410 | if (alloc_len < req_len) { | ||
11411 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
11412 | "0291 Allocated DMA memory size (x%x) is " | ||
11413 | "less than the requested DMA memory " | ||
11414 | "size (x%x)\n", alloc_len, req_len); | ||
11415 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
11416 | return -ENOMEM; | ||
11417 | } | ||
11418 | |||
11419 | /* Get the first SGE entry from the non-embedded DMA memory. This | ||
11420 | * routine only uses a single SGE. | ||
11421 | */ | ||
11422 | lpfc_sli4_mbx_sge_get(mboxq, 0, &sge); | ||
11423 | phys_addr = getPaddr(sge.pa_hi, sge.pa_lo); | ||
11424 | if (unlikely(!mboxq->sge_array)) { | ||
11425 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, | ||
11426 | "2527 Failed to get the non-embedded SGE " | ||
11427 | "virtual address\n"); | ||
11428 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
11429 | return -ENOMEM; | ||
11430 | } | ||
11431 | virt_addr = mboxq->sge_array->addr[0]; | ||
11432 | read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr; | ||
11433 | |||
11434 | /* Set up command fields */ | ||
11435 | bf_set(lpfc_mbx_read_fcf_tbl_indx, &read_fcf->u.request, fcf_index); | ||
11436 | /* Perform necessary endian conversion */ | ||
11437 | bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr); | ||
11438 | lpfc_sli_pcimem_bcopy(bytep, bytep, sizeof(uint32_t)); | ||
11439 | mboxq->vport = phba->pport; | ||
11440 | mboxq->mbox_cmpl = lpfc_mbx_cmpl_read_fcf_record; | ||
11441 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); | ||
11442 | if (rc == MBX_NOT_FINISHED) { | ||
11443 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | ||
11444 | error = -EIO; | ||
11445 | } else | ||
11446 | error = 0; | ||
11447 | return error; | ||
11448 | } | ||