diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 302 |
1 files changed, 214 insertions, 88 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index b8b34cf5c3d2..f72fdf23bf1b 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************* | 1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2004-2008 Emulex. All rights reserved. * | 4 | * Copyright (C) 2004-2009 Emulex. All rights reserved. * |
5 | * EMULEX and SLI are trademarks of Emulex. * | 5 | * EMULEX and SLI are trademarks of Emulex. * |
6 | * www.emulex.com * | 6 | * www.emulex.com * |
7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * | 7 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
@@ -28,8 +28,10 @@ | |||
28 | #include <scsi/scsi_host.h> | 28 | #include <scsi/scsi_host.h> |
29 | #include <scsi/scsi_transport_fc.h> | 29 | #include <scsi/scsi_transport_fc.h> |
30 | 30 | ||
31 | #include "lpfc_hw4.h" | ||
31 | #include "lpfc_hw.h" | 32 | #include "lpfc_hw.h" |
32 | #include "lpfc_sli.h" | 33 | #include "lpfc_sli.h" |
34 | #include "lpfc_sli4.h" | ||
33 | #include "lpfc_nl.h" | 35 | #include "lpfc_nl.h" |
34 | #include "lpfc_disc.h" | 36 | #include "lpfc_disc.h" |
35 | #include "lpfc_scsi.h" | 37 | #include "lpfc_scsi.h" |
@@ -84,7 +86,8 @@ lpfc_els_chk_latt(struct lpfc_vport *vport) | |||
84 | uint32_t ha_copy; | 86 | uint32_t ha_copy; |
85 | 87 | ||
86 | if (vport->port_state >= LPFC_VPORT_READY || | 88 | if (vport->port_state >= LPFC_VPORT_READY || |
87 | phba->link_state == LPFC_LINK_DOWN) | 89 | phba->link_state == LPFC_LINK_DOWN || |
90 | phba->sli_rev > LPFC_SLI_REV3) | ||
88 | return 0; | 91 | return 0; |
89 | 92 | ||
90 | /* Read the HBA Host Attention Register */ | 93 | /* Read the HBA Host Attention Register */ |
@@ -165,6 +168,19 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, | |||
165 | if (elsiocb == NULL) | 168 | if (elsiocb == NULL) |
166 | return NULL; | 169 | return NULL; |
167 | 170 | ||
171 | /* | ||
172 | * If this command is for fabric controller and HBA running | ||
173 | * in FIP mode send FLOGI, FDISC and LOGO as FIP frames. | ||
174 | */ | ||
175 | if ((did == Fabric_DID) && | ||
176 | bf_get(lpfc_fip_flag, &phba->sli4_hba.sli4_flags) && | ||
177 | ((elscmd == ELS_CMD_FLOGI) || | ||
178 | (elscmd == ELS_CMD_FDISC) || | ||
179 | (elscmd == ELS_CMD_LOGO))) | ||
180 | elsiocb->iocb_flag |= LPFC_FIP_ELS; | ||
181 | else | ||
182 | elsiocb->iocb_flag &= ~LPFC_FIP_ELS; | ||
183 | |||
168 | icmd = &elsiocb->iocb; | 184 | icmd = &elsiocb->iocb; |
169 | 185 | ||
170 | /* fill in BDEs for command */ | 186 | /* fill in BDEs for command */ |
@@ -219,7 +235,7 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, | |||
219 | icmd->un.elsreq64.myID = vport->fc_myDID; | 235 | icmd->un.elsreq64.myID = vport->fc_myDID; |
220 | 236 | ||
221 | /* For ELS_REQUEST64_CR, use the VPI by default */ | 237 | /* For ELS_REQUEST64_CR, use the VPI by default */ |
222 | icmd->ulpContext = vport->vpi; | 238 | icmd->ulpContext = vport->vpi + phba->vpi_base; |
223 | icmd->ulpCt_h = 0; | 239 | icmd->ulpCt_h = 0; |
224 | /* The CT field must be 0=INVALID_RPI for the ECHO cmd */ | 240 | /* The CT field must be 0=INVALID_RPI for the ECHO cmd */ |
225 | if (elscmd == ELS_CMD_ECHO) | 241 | if (elscmd == ELS_CMD_ECHO) |
@@ -305,7 +321,7 @@ els_iocb_free_pcmb_exit: | |||
305 | * 0 - successfully issued fabric registration login for @vport | 321 | * 0 - successfully issued fabric registration login for @vport |
306 | * -ENXIO -- failed to issue fabric registration login for @vport | 322 | * -ENXIO -- failed to issue fabric registration login for @vport |
307 | **/ | 323 | **/ |
308 | static int | 324 | int |
309 | lpfc_issue_fabric_reglogin(struct lpfc_vport *vport) | 325 | lpfc_issue_fabric_reglogin(struct lpfc_vport *vport) |
310 | { | 326 | { |
311 | struct lpfc_hba *phba = vport->phba; | 327 | struct lpfc_hba *phba = vport->phba; |
@@ -345,8 +361,7 @@ lpfc_issue_fabric_reglogin(struct lpfc_vport *vport) | |||
345 | err = 4; | 361 | err = 4; |
346 | goto fail; | 362 | goto fail; |
347 | } | 363 | } |
348 | rc = lpfc_reg_login(phba, vport->vpi, Fabric_DID, (uint8_t *)sp, mbox, | 364 | rc = lpfc_reg_rpi(phba, vport->vpi, Fabric_DID, (uint8_t *)sp, mbox, 0); |
349 | 0); | ||
350 | if (rc) { | 365 | if (rc) { |
351 | err = 5; | 366 | err = 5; |
352 | goto fail_free_mbox; | 367 | goto fail_free_mbox; |
@@ -386,6 +401,75 @@ fail: | |||
386 | } | 401 | } |
387 | 402 | ||
388 | /** | 403 | /** |
404 | * lpfc_issue_reg_vfi - Register VFI for this vport's fabric login | ||
405 | * @vport: pointer to a host virtual N_Port data structure. | ||
406 | * | ||
407 | * This routine issues a REG_VFI mailbox for the vfi, vpi, fcfi triplet for | ||
408 | * the @vport. This mailbox command is necessary for FCoE only. | ||
409 | * | ||
410 | * Return code | ||
411 | * 0 - successfully issued REG_VFI for @vport | ||
412 | * A failure code otherwise. | ||
413 | **/ | ||
414 | static int | ||
415 | lpfc_issue_reg_vfi(struct lpfc_vport *vport) | ||
416 | { | ||
417 | struct lpfc_hba *phba = vport->phba; | ||
418 | LPFC_MBOXQ_t *mboxq; | ||
419 | struct lpfc_nodelist *ndlp; | ||
420 | struct serv_parm *sp; | ||
421 | struct lpfc_dmabuf *dmabuf; | ||
422 | int rc = 0; | ||
423 | |||
424 | sp = &phba->fc_fabparam; | ||
425 | ndlp = lpfc_findnode_did(vport, Fabric_DID); | ||
426 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { | ||
427 | rc = -ENODEV; | ||
428 | goto fail; | ||
429 | } | ||
430 | |||
431 | dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); | ||
432 | if (!dmabuf) { | ||
433 | rc = -ENOMEM; | ||
434 | goto fail; | ||
435 | } | ||
436 | dmabuf->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &dmabuf->phys); | ||
437 | if (!dmabuf->virt) { | ||
438 | rc = -ENOMEM; | ||
439 | goto fail_free_dmabuf; | ||
440 | } | ||
441 | mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | ||
442 | if (!mboxq) { | ||
443 | rc = -ENOMEM; | ||
444 | goto fail_free_coherent; | ||
445 | } | ||
446 | vport->port_state = LPFC_FABRIC_CFG_LINK; | ||
447 | memcpy(dmabuf->virt, &phba->fc_fabparam, sizeof(vport->fc_sparam)); | ||
448 | lpfc_reg_vfi(mboxq, vport, dmabuf->phys); | ||
449 | mboxq->mbox_cmpl = lpfc_mbx_cmpl_reg_vfi; | ||
450 | mboxq->vport = vport; | ||
451 | mboxq->context1 = dmabuf; | ||
452 | rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT); | ||
453 | if (rc == MBX_NOT_FINISHED) { | ||
454 | rc = -ENXIO; | ||
455 | goto fail_free_mbox; | ||
456 | } | ||
457 | return 0; | ||
458 | |||
459 | fail_free_mbox: | ||
460 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
461 | fail_free_coherent: | ||
462 | lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys); | ||
463 | fail_free_dmabuf: | ||
464 | kfree(dmabuf); | ||
465 | fail: | ||
466 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | ||
467 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | ||
468 | "0289 Issue Register VFI failed: Err %d\n", rc); | ||
469 | return rc; | ||
470 | } | ||
471 | |||
472 | /** | ||
389 | * lpfc_cmpl_els_flogi_fabric - Completion function for flogi to a fabric port | 473 | * lpfc_cmpl_els_flogi_fabric - Completion function for flogi to a fabric port |
390 | * @vport: pointer to a host virtual N_Port data structure. | 474 | * @vport: pointer to a host virtual N_Port data structure. |
391 | * @ndlp: pointer to a node-list data structure. | 475 | * @ndlp: pointer to a node-list data structure. |
@@ -497,17 +581,24 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
497 | } | 581 | } |
498 | } | 582 | } |
499 | 583 | ||
500 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_REG_LOGIN_ISSUE); | 584 | if (phba->sli_rev < LPFC_SLI_REV4) { |
501 | 585 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_REG_LOGIN_ISSUE); | |
502 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED && | 586 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED && |
503 | vport->fc_flag & FC_VPORT_NEEDS_REG_VPI) { | 587 | vport->fc_flag & FC_VPORT_NEEDS_REG_VPI) |
504 | lpfc_register_new_vport(phba, vport, ndlp); | 588 | lpfc_register_new_vport(phba, vport, ndlp); |
505 | return 0; | 589 | else |
590 | lpfc_issue_fabric_reglogin(vport); | ||
591 | } else { | ||
592 | ndlp->nlp_type |= NLP_FABRIC; | ||
593 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); | ||
594 | if (vport->vfi_state & LPFC_VFI_REGISTERED) { | ||
595 | lpfc_start_fdiscs(phba); | ||
596 | lpfc_do_scr_ns_plogi(phba, vport); | ||
597 | } else | ||
598 | lpfc_issue_reg_vfi(vport); | ||
506 | } | 599 | } |
507 | lpfc_issue_fabric_reglogin(vport); | ||
508 | return 0; | 600 | return 0; |
509 | } | 601 | } |
510 | |||
511 | /** | 602 | /** |
512 | * lpfc_cmpl_els_flogi_nport - Completion function for flogi to an N_Port | 603 | * lpfc_cmpl_els_flogi_nport - Completion function for flogi to an N_Port |
513 | * @vport: pointer to a host virtual N_Port data structure. | 604 | * @vport: pointer to a host virtual N_Port data structure. |
@@ -815,9 +906,14 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
815 | if (sp->cmn.fcphHigh < FC_PH3) | 906 | if (sp->cmn.fcphHigh < FC_PH3) |
816 | sp->cmn.fcphHigh = FC_PH3; | 907 | sp->cmn.fcphHigh = FC_PH3; |
817 | 908 | ||
818 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) { | 909 | if (phba->sli_rev == LPFC_SLI_REV4) { |
910 | elsiocb->iocb.ulpCt_h = ((SLI4_CT_FCFI >> 1) & 1); | ||
911 | elsiocb->iocb.ulpCt_l = (SLI4_CT_FCFI & 1); | ||
912 | /* FLOGI needs to be 3 for WQE FCFI */ | ||
913 | /* Set the fcfi to the fcfi we registered with */ | ||
914 | elsiocb->iocb.ulpContext = phba->fcf.fcfi; | ||
915 | } else if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) { | ||
819 | sp->cmn.request_multiple_Nport = 1; | 916 | sp->cmn.request_multiple_Nport = 1; |
820 | |||
821 | /* For FLOGI, Let FLOGI rsp set the NPortID for VPI 0 */ | 917 | /* For FLOGI, Let FLOGI rsp set the NPortID for VPI 0 */ |
822 | icmd->ulpCt_h = 1; | 918 | icmd->ulpCt_h = 1; |
823 | icmd->ulpCt_l = 0; | 919 | icmd->ulpCt_l = 0; |
@@ -930,6 +1026,8 @@ lpfc_initial_flogi(struct lpfc_vport *vport) | |||
930 | if (!ndlp) | 1026 | if (!ndlp) |
931 | return 0; | 1027 | return 0; |
932 | lpfc_nlp_init(vport, ndlp, Fabric_DID); | 1028 | lpfc_nlp_init(vport, ndlp, Fabric_DID); |
1029 | /* Set the node type */ | ||
1030 | ndlp->nlp_type |= NLP_FABRIC; | ||
933 | /* Put ndlp onto node list */ | 1031 | /* Put ndlp onto node list */ |
934 | lpfc_enqueue_node(vport, ndlp); | 1032 | lpfc_enqueue_node(vport, ndlp); |
935 | } else if (!NLP_CHK_NODE_ACT(ndlp)) { | 1033 | } else if (!NLP_CHK_NODE_ACT(ndlp)) { |
@@ -1350,14 +1448,12 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry) | |||
1350 | IOCB_t *icmd; | 1448 | IOCB_t *icmd; |
1351 | struct lpfc_nodelist *ndlp; | 1449 | struct lpfc_nodelist *ndlp; |
1352 | struct lpfc_iocbq *elsiocb; | 1450 | struct lpfc_iocbq *elsiocb; |
1353 | struct lpfc_sli_ring *pring; | ||
1354 | struct lpfc_sli *psli; | 1451 | struct lpfc_sli *psli; |
1355 | uint8_t *pcmd; | 1452 | uint8_t *pcmd; |
1356 | uint16_t cmdsize; | 1453 | uint16_t cmdsize; |
1357 | int ret; | 1454 | int ret; |
1358 | 1455 | ||
1359 | psli = &phba->sli; | 1456 | psli = &phba->sli; |
1360 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | ||
1361 | 1457 | ||
1362 | ndlp = lpfc_findnode_did(vport, did); | 1458 | ndlp = lpfc_findnode_did(vport, did); |
1363 | if (ndlp && !NLP_CHK_NODE_ACT(ndlp)) | 1459 | if (ndlp && !NLP_CHK_NODE_ACT(ndlp)) |
@@ -1391,7 +1487,7 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry) | |||
1391 | 1487 | ||
1392 | phba->fc_stat.elsXmitPLOGI++; | 1488 | phba->fc_stat.elsXmitPLOGI++; |
1393 | elsiocb->iocb_cmpl = lpfc_cmpl_els_plogi; | 1489 | elsiocb->iocb_cmpl = lpfc_cmpl_els_plogi; |
1394 | ret = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); | 1490 | ret = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); |
1395 | 1491 | ||
1396 | if (ret == IOCB_ERROR) { | 1492 | if (ret == IOCB_ERROR) { |
1397 | lpfc_els_free_iocb(phba, elsiocb); | 1493 | lpfc_els_free_iocb(phba, elsiocb); |
@@ -1501,14 +1597,9 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
1501 | PRLI *npr; | 1597 | PRLI *npr; |
1502 | IOCB_t *icmd; | 1598 | IOCB_t *icmd; |
1503 | struct lpfc_iocbq *elsiocb; | 1599 | struct lpfc_iocbq *elsiocb; |
1504 | struct lpfc_sli_ring *pring; | ||
1505 | struct lpfc_sli *psli; | ||
1506 | uint8_t *pcmd; | 1600 | uint8_t *pcmd; |
1507 | uint16_t cmdsize; | 1601 | uint16_t cmdsize; |
1508 | 1602 | ||
1509 | psli = &phba->sli; | ||
1510 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | ||
1511 | |||
1512 | cmdsize = (sizeof(uint32_t) + sizeof(PRLI)); | 1603 | cmdsize = (sizeof(uint32_t) + sizeof(PRLI)); |
1513 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, | 1604 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, |
1514 | ndlp->nlp_DID, ELS_CMD_PRLI); | 1605 | ndlp->nlp_DID, ELS_CMD_PRLI); |
@@ -1550,7 +1641,8 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
1550 | spin_lock_irq(shost->host_lock); | 1641 | spin_lock_irq(shost->host_lock); |
1551 | ndlp->nlp_flag |= NLP_PRLI_SND; | 1642 | ndlp->nlp_flag |= NLP_PRLI_SND; |
1552 | spin_unlock_irq(shost->host_lock); | 1643 | spin_unlock_irq(shost->host_lock); |
1553 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { | 1644 | if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) == |
1645 | IOCB_ERROR) { | ||
1554 | spin_lock_irq(shost->host_lock); | 1646 | spin_lock_irq(shost->host_lock); |
1555 | ndlp->nlp_flag &= ~NLP_PRLI_SND; | 1647 | ndlp->nlp_flag &= ~NLP_PRLI_SND; |
1556 | spin_unlock_irq(shost->host_lock); | 1648 | spin_unlock_irq(shost->host_lock); |
@@ -1608,7 +1700,8 @@ lpfc_adisc_done(struct lpfc_vport *vport) | |||
1608 | * and continue discovery. | 1700 | * and continue discovery. |
1609 | */ | 1701 | */ |
1610 | if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && | 1702 | if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && |
1611 | !(vport->fc_flag & FC_RSCN_MODE)) { | 1703 | !(vport->fc_flag & FC_RSCN_MODE) && |
1704 | (phba->sli_rev < LPFC_SLI_REV4)) { | ||
1612 | lpfc_issue_reg_vpi(phba, vport); | 1705 | lpfc_issue_reg_vpi(phba, vport); |
1613 | return; | 1706 | return; |
1614 | } | 1707 | } |
@@ -1788,8 +1881,6 @@ lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
1788 | ADISC *ap; | 1881 | ADISC *ap; |
1789 | IOCB_t *icmd; | 1882 | IOCB_t *icmd; |
1790 | struct lpfc_iocbq *elsiocb; | 1883 | struct lpfc_iocbq *elsiocb; |
1791 | struct lpfc_sli *psli = &phba->sli; | ||
1792 | struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING]; | ||
1793 | uint8_t *pcmd; | 1884 | uint8_t *pcmd; |
1794 | uint16_t cmdsize; | 1885 | uint16_t cmdsize; |
1795 | 1886 | ||
@@ -1822,7 +1913,8 @@ lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
1822 | spin_lock_irq(shost->host_lock); | 1913 | spin_lock_irq(shost->host_lock); |
1823 | ndlp->nlp_flag |= NLP_ADISC_SND; | 1914 | ndlp->nlp_flag |= NLP_ADISC_SND; |
1824 | spin_unlock_irq(shost->host_lock); | 1915 | spin_unlock_irq(shost->host_lock); |
1825 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { | 1916 | if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) == |
1917 | IOCB_ERROR) { | ||
1826 | spin_lock_irq(shost->host_lock); | 1918 | spin_lock_irq(shost->host_lock); |
1827 | ndlp->nlp_flag &= ~NLP_ADISC_SND; | 1919 | ndlp->nlp_flag &= ~NLP_ADISC_SND; |
1828 | spin_unlock_irq(shost->host_lock); | 1920 | spin_unlock_irq(shost->host_lock); |
@@ -1937,15 +2029,10 @@ lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
1937 | struct lpfc_hba *phba = vport->phba; | 2029 | struct lpfc_hba *phba = vport->phba; |
1938 | IOCB_t *icmd; | 2030 | IOCB_t *icmd; |
1939 | struct lpfc_iocbq *elsiocb; | 2031 | struct lpfc_iocbq *elsiocb; |
1940 | struct lpfc_sli_ring *pring; | ||
1941 | struct lpfc_sli *psli; | ||
1942 | uint8_t *pcmd; | 2032 | uint8_t *pcmd; |
1943 | uint16_t cmdsize; | 2033 | uint16_t cmdsize; |
1944 | int rc; | 2034 | int rc; |
1945 | 2035 | ||
1946 | psli = &phba->sli; | ||
1947 | pring = &psli->ring[LPFC_ELS_RING]; | ||
1948 | |||
1949 | spin_lock_irq(shost->host_lock); | 2036 | spin_lock_irq(shost->host_lock); |
1950 | if (ndlp->nlp_flag & NLP_LOGO_SND) { | 2037 | if (ndlp->nlp_flag & NLP_LOGO_SND) { |
1951 | spin_unlock_irq(shost->host_lock); | 2038 | spin_unlock_irq(shost->host_lock); |
@@ -1978,7 +2065,7 @@ lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
1978 | spin_lock_irq(shost->host_lock); | 2065 | spin_lock_irq(shost->host_lock); |
1979 | ndlp->nlp_flag |= NLP_LOGO_SND; | 2066 | ndlp->nlp_flag |= NLP_LOGO_SND; |
1980 | spin_unlock_irq(shost->host_lock); | 2067 | spin_unlock_irq(shost->host_lock); |
1981 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); | 2068 | rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); |
1982 | 2069 | ||
1983 | if (rc == IOCB_ERROR) { | 2070 | if (rc == IOCB_ERROR) { |
1984 | spin_lock_irq(shost->host_lock); | 2071 | spin_lock_irq(shost->host_lock); |
@@ -2058,14 +2145,12 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) | |||
2058 | struct lpfc_hba *phba = vport->phba; | 2145 | struct lpfc_hba *phba = vport->phba; |
2059 | IOCB_t *icmd; | 2146 | IOCB_t *icmd; |
2060 | struct lpfc_iocbq *elsiocb; | 2147 | struct lpfc_iocbq *elsiocb; |
2061 | struct lpfc_sli_ring *pring; | ||
2062 | struct lpfc_sli *psli; | 2148 | struct lpfc_sli *psli; |
2063 | uint8_t *pcmd; | 2149 | uint8_t *pcmd; |
2064 | uint16_t cmdsize; | 2150 | uint16_t cmdsize; |
2065 | struct lpfc_nodelist *ndlp; | 2151 | struct lpfc_nodelist *ndlp; |
2066 | 2152 | ||
2067 | psli = &phba->sli; | 2153 | psli = &phba->sli; |
2068 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | ||
2069 | cmdsize = (sizeof(uint32_t) + sizeof(SCR)); | 2154 | cmdsize = (sizeof(uint32_t) + sizeof(SCR)); |
2070 | 2155 | ||
2071 | ndlp = lpfc_findnode_did(vport, nportid); | 2156 | ndlp = lpfc_findnode_did(vport, nportid); |
@@ -2108,7 +2193,8 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) | |||
2108 | 2193 | ||
2109 | phba->fc_stat.elsXmitSCR++; | 2194 | phba->fc_stat.elsXmitSCR++; |
2110 | elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; | 2195 | elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; |
2111 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { | 2196 | if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) == |
2197 | IOCB_ERROR) { | ||
2112 | /* The additional lpfc_nlp_put will cause the following | 2198 | /* The additional lpfc_nlp_put will cause the following |
2113 | * lpfc_els_free_iocb routine to trigger the rlease of | 2199 | * lpfc_els_free_iocb routine to trigger the rlease of |
2114 | * the node. | 2200 | * the node. |
@@ -2152,7 +2238,6 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) | |||
2152 | struct lpfc_hba *phba = vport->phba; | 2238 | struct lpfc_hba *phba = vport->phba; |
2153 | IOCB_t *icmd; | 2239 | IOCB_t *icmd; |
2154 | struct lpfc_iocbq *elsiocb; | 2240 | struct lpfc_iocbq *elsiocb; |
2155 | struct lpfc_sli_ring *pring; | ||
2156 | struct lpfc_sli *psli; | 2241 | struct lpfc_sli *psli; |
2157 | FARP *fp; | 2242 | FARP *fp; |
2158 | uint8_t *pcmd; | 2243 | uint8_t *pcmd; |
@@ -2162,7 +2247,6 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) | |||
2162 | struct lpfc_nodelist *ndlp; | 2247 | struct lpfc_nodelist *ndlp; |
2163 | 2248 | ||
2164 | psli = &phba->sli; | 2249 | psli = &phba->sli; |
2165 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | ||
2166 | cmdsize = (sizeof(uint32_t) + sizeof(FARP)); | 2250 | cmdsize = (sizeof(uint32_t) + sizeof(FARP)); |
2167 | 2251 | ||
2168 | ndlp = lpfc_findnode_did(vport, nportid); | 2252 | ndlp = lpfc_findnode_did(vport, nportid); |
@@ -2219,7 +2303,8 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) | |||
2219 | 2303 | ||
2220 | phba->fc_stat.elsXmitFARPR++; | 2304 | phba->fc_stat.elsXmitFARPR++; |
2221 | elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; | 2305 | elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; |
2222 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { | 2306 | if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) == |
2307 | IOCB_ERROR) { | ||
2223 | /* The additional lpfc_nlp_put will cause the following | 2308 | /* The additional lpfc_nlp_put will cause the following |
2224 | * lpfc_els_free_iocb routine to trigger the release of | 2309 | * lpfc_els_free_iocb routine to trigger the release of |
2225 | * the node. | 2310 | * the node. |
@@ -2949,6 +3034,14 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2949 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); | 3034 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); |
2950 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; | 3035 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; |
2951 | 3036 | ||
3037 | /* | ||
3038 | * This routine is used to register and unregister in previous SLI | ||
3039 | * modes. | ||
3040 | */ | ||
3041 | if ((pmb->u.mb.mbxCommand == MBX_UNREG_LOGIN) && | ||
3042 | (phba->sli_rev == LPFC_SLI_REV4)) | ||
3043 | lpfc_sli4_free_rpi(phba, pmb->u.mb.un.varUnregLogin.rpi); | ||
3044 | |||
2952 | pmb->context1 = NULL; | 3045 | pmb->context1 = NULL; |
2953 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 3046 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
2954 | kfree(mp); | 3047 | kfree(mp); |
@@ -2961,6 +3054,7 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2961 | */ | 3054 | */ |
2962 | lpfc_nlp_not_used(ndlp); | 3055 | lpfc_nlp_not_used(ndlp); |
2963 | } | 3056 | } |
3057 | |||
2964 | return; | 3058 | return; |
2965 | } | 3059 | } |
2966 | 3060 | ||
@@ -3170,7 +3264,6 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, | |||
3170 | IOCB_t *icmd; | 3264 | IOCB_t *icmd; |
3171 | IOCB_t *oldcmd; | 3265 | IOCB_t *oldcmd; |
3172 | struct lpfc_iocbq *elsiocb; | 3266 | struct lpfc_iocbq *elsiocb; |
3173 | struct lpfc_sli_ring *pring; | ||
3174 | struct lpfc_sli *psli; | 3267 | struct lpfc_sli *psli; |
3175 | uint8_t *pcmd; | 3268 | uint8_t *pcmd; |
3176 | uint16_t cmdsize; | 3269 | uint16_t cmdsize; |
@@ -3178,7 +3271,6 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, | |||
3178 | ELS_PKT *els_pkt_ptr; | 3271 | ELS_PKT *els_pkt_ptr; |
3179 | 3272 | ||
3180 | psli = &phba->sli; | 3273 | psli = &phba->sli; |
3181 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | ||
3182 | oldcmd = &oldiocb->iocb; | 3274 | oldcmd = &oldiocb->iocb; |
3183 | 3275 | ||
3184 | switch (flag) { | 3276 | switch (flag) { |
@@ -3266,7 +3358,7 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, | |||
3266 | } | 3358 | } |
3267 | 3359 | ||
3268 | phba->fc_stat.elsXmitACC++; | 3360 | phba->fc_stat.elsXmitACC++; |
3269 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); | 3361 | rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); |
3270 | if (rc == IOCB_ERROR) { | 3362 | if (rc == IOCB_ERROR) { |
3271 | lpfc_els_free_iocb(phba, elsiocb); | 3363 | lpfc_els_free_iocb(phba, elsiocb); |
3272 | return 1; | 3364 | return 1; |
@@ -3305,15 +3397,12 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError, | |||
3305 | IOCB_t *icmd; | 3397 | IOCB_t *icmd; |
3306 | IOCB_t *oldcmd; | 3398 | IOCB_t *oldcmd; |
3307 | struct lpfc_iocbq *elsiocb; | 3399 | struct lpfc_iocbq *elsiocb; |
3308 | struct lpfc_sli_ring *pring; | ||
3309 | struct lpfc_sli *psli; | 3400 | struct lpfc_sli *psli; |
3310 | uint8_t *pcmd; | 3401 | uint8_t *pcmd; |
3311 | uint16_t cmdsize; | 3402 | uint16_t cmdsize; |
3312 | int rc; | 3403 | int rc; |
3313 | 3404 | ||
3314 | psli = &phba->sli; | 3405 | psli = &phba->sli; |
3315 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | ||
3316 | |||
3317 | cmdsize = 2 * sizeof(uint32_t); | 3406 | cmdsize = 2 * sizeof(uint32_t); |
3318 | elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp, | 3407 | elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp, |
3319 | ndlp->nlp_DID, ELS_CMD_LS_RJT); | 3408 | ndlp->nlp_DID, ELS_CMD_LS_RJT); |
@@ -3346,7 +3435,7 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError, | |||
3346 | 3435 | ||
3347 | phba->fc_stat.elsXmitLSRJT++; | 3436 | phba->fc_stat.elsXmitLSRJT++; |
3348 | elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; | 3437 | elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; |
3349 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); | 3438 | rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); |
3350 | 3439 | ||
3351 | if (rc == IOCB_ERROR) { | 3440 | if (rc == IOCB_ERROR) { |
3352 | lpfc_els_free_iocb(phba, elsiocb); | 3441 | lpfc_els_free_iocb(phba, elsiocb); |
@@ -3379,8 +3468,6 @@ lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, | |||
3379 | struct lpfc_nodelist *ndlp) | 3468 | struct lpfc_nodelist *ndlp) |
3380 | { | 3469 | { |
3381 | struct lpfc_hba *phba = vport->phba; | 3470 | struct lpfc_hba *phba = vport->phba; |
3382 | struct lpfc_sli *psli = &phba->sli; | ||
3383 | struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING]; | ||
3384 | ADISC *ap; | 3471 | ADISC *ap; |
3385 | IOCB_t *icmd, *oldcmd; | 3472 | IOCB_t *icmd, *oldcmd; |
3386 | struct lpfc_iocbq *elsiocb; | 3473 | struct lpfc_iocbq *elsiocb; |
@@ -3422,7 +3509,7 @@ lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, | |||
3422 | 3509 | ||
3423 | phba->fc_stat.elsXmitACC++; | 3510 | phba->fc_stat.elsXmitACC++; |
3424 | elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; | 3511 | elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; |
3425 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); | 3512 | rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); |
3426 | if (rc == IOCB_ERROR) { | 3513 | if (rc == IOCB_ERROR) { |
3427 | lpfc_els_free_iocb(phba, elsiocb); | 3514 | lpfc_els_free_iocb(phba, elsiocb); |
3428 | return 1; | 3515 | return 1; |
@@ -3459,14 +3546,12 @@ lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, | |||
3459 | IOCB_t *icmd; | 3546 | IOCB_t *icmd; |
3460 | IOCB_t *oldcmd; | 3547 | IOCB_t *oldcmd; |
3461 | struct lpfc_iocbq *elsiocb; | 3548 | struct lpfc_iocbq *elsiocb; |
3462 | struct lpfc_sli_ring *pring; | ||
3463 | struct lpfc_sli *psli; | 3549 | struct lpfc_sli *psli; |
3464 | uint8_t *pcmd; | 3550 | uint8_t *pcmd; |
3465 | uint16_t cmdsize; | 3551 | uint16_t cmdsize; |
3466 | int rc; | 3552 | int rc; |
3467 | 3553 | ||
3468 | psli = &phba->sli; | 3554 | psli = &phba->sli; |
3469 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | ||
3470 | 3555 | ||
3471 | cmdsize = sizeof(uint32_t) + sizeof(PRLI); | 3556 | cmdsize = sizeof(uint32_t) + sizeof(PRLI); |
3472 | elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp, | 3557 | elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp, |
@@ -3520,7 +3605,7 @@ lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, | |||
3520 | phba->fc_stat.elsXmitACC++; | 3605 | phba->fc_stat.elsXmitACC++; |
3521 | elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; | 3606 | elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; |
3522 | 3607 | ||
3523 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); | 3608 | rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); |
3524 | if (rc == IOCB_ERROR) { | 3609 | if (rc == IOCB_ERROR) { |
3525 | lpfc_els_free_iocb(phba, elsiocb); | 3610 | lpfc_els_free_iocb(phba, elsiocb); |
3526 | return 1; | 3611 | return 1; |
@@ -3562,15 +3647,12 @@ lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format, | |||
3562 | RNID *rn; | 3647 | RNID *rn; |
3563 | IOCB_t *icmd, *oldcmd; | 3648 | IOCB_t *icmd, *oldcmd; |
3564 | struct lpfc_iocbq *elsiocb; | 3649 | struct lpfc_iocbq *elsiocb; |
3565 | struct lpfc_sli_ring *pring; | ||
3566 | struct lpfc_sli *psli; | 3650 | struct lpfc_sli *psli; |
3567 | uint8_t *pcmd; | 3651 | uint8_t *pcmd; |
3568 | uint16_t cmdsize; | 3652 | uint16_t cmdsize; |
3569 | int rc; | 3653 | int rc; |
3570 | 3654 | ||
3571 | psli = &phba->sli; | 3655 | psli = &phba->sli; |
3572 | pring = &psli->ring[LPFC_ELS_RING]; | ||
3573 | |||
3574 | cmdsize = sizeof(uint32_t) + sizeof(uint32_t) | 3656 | cmdsize = sizeof(uint32_t) + sizeof(uint32_t) |
3575 | + (2 * sizeof(struct lpfc_name)); | 3657 | + (2 * sizeof(struct lpfc_name)); |
3576 | if (format) | 3658 | if (format) |
@@ -3626,7 +3708,7 @@ lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format, | |||
3626 | elsiocb->context1 = NULL; /* Don't need ndlp for cmpl, | 3708 | elsiocb->context1 = NULL; /* Don't need ndlp for cmpl, |
3627 | * it could be freed */ | 3709 | * it could be freed */ |
3628 | 3710 | ||
3629 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); | 3711 | rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); |
3630 | if (rc == IOCB_ERROR) { | 3712 | if (rc == IOCB_ERROR) { |
3631 | lpfc_els_free_iocb(phba, elsiocb); | 3713 | lpfc_els_free_iocb(phba, elsiocb); |
3632 | return 1; | 3714 | return 1; |
@@ -3839,7 +3921,9 @@ lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did) | |||
3839 | payload_len -= sizeof(uint32_t); | 3921 | payload_len -= sizeof(uint32_t); |
3840 | switch (rscn_did.un.b.resv & RSCN_ADDRESS_FORMAT_MASK) { | 3922 | switch (rscn_did.un.b.resv & RSCN_ADDRESS_FORMAT_MASK) { |
3841 | case RSCN_ADDRESS_FORMAT_PORT: | 3923 | case RSCN_ADDRESS_FORMAT_PORT: |
3842 | if (ns_did.un.word == rscn_did.un.word) | 3924 | if ((ns_did.un.b.domain == rscn_did.un.b.domain) |
3925 | && (ns_did.un.b.area == rscn_did.un.b.area) | ||
3926 | && (ns_did.un.b.id == rscn_did.un.b.id)) | ||
3843 | goto return_did_out; | 3927 | goto return_did_out; |
3844 | break; | 3928 | break; |
3845 | case RSCN_ADDRESS_FORMAT_AREA: | 3929 | case RSCN_ADDRESS_FORMAT_AREA: |
@@ -4300,7 +4384,7 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
4300 | lpfc_init_link(phba, mbox, | 4384 | lpfc_init_link(phba, mbox, |
4301 | phba->cfg_topology, | 4385 | phba->cfg_topology, |
4302 | phba->cfg_link_speed); | 4386 | phba->cfg_link_speed); |
4303 | mbox->mb.un.varInitLnk.lipsr_AL_PA = 0; | 4387 | mbox->u.mb.un.varInitLnk.lipsr_AL_PA = 0; |
4304 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 4388 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
4305 | mbox->vport = vport; | 4389 | mbox->vport = vport; |
4306 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | 4390 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
@@ -4440,8 +4524,6 @@ lpfc_els_rcv_lirr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
4440 | static void | 4524 | static void |
4441 | lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | 4525 | lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
4442 | { | 4526 | { |
4443 | struct lpfc_sli *psli = &phba->sli; | ||
4444 | struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING]; | ||
4445 | MAILBOX_t *mb; | 4527 | MAILBOX_t *mb; |
4446 | IOCB_t *icmd; | 4528 | IOCB_t *icmd; |
4447 | RPS_RSP *rps_rsp; | 4529 | RPS_RSP *rps_rsp; |
@@ -4451,7 +4533,7 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
4451 | uint16_t xri, status; | 4533 | uint16_t xri, status; |
4452 | uint32_t cmdsize; | 4534 | uint32_t cmdsize; |
4453 | 4535 | ||
4454 | mb = &pmb->mb; | 4536 | mb = &pmb->u.mb; |
4455 | 4537 | ||
4456 | ndlp = (struct lpfc_nodelist *) pmb->context2; | 4538 | ndlp = (struct lpfc_nodelist *) pmb->context2; |
4457 | xri = (uint16_t) ((unsigned long)(pmb->context1)); | 4539 | xri = (uint16_t) ((unsigned long)(pmb->context1)); |
@@ -4507,7 +4589,7 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
4507 | ndlp->nlp_rpi); | 4589 | ndlp->nlp_rpi); |
4508 | elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; | 4590 | elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; |
4509 | phba->fc_stat.elsXmitACC++; | 4591 | phba->fc_stat.elsXmitACC++; |
4510 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) | 4592 | if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) == IOCB_ERROR) |
4511 | lpfc_els_free_iocb(phba, elsiocb); | 4593 | lpfc_els_free_iocb(phba, elsiocb); |
4512 | return; | 4594 | return; |
4513 | } | 4595 | } |
@@ -4616,8 +4698,6 @@ lpfc_els_rsp_rpl_acc(struct lpfc_vport *vport, uint16_t cmdsize, | |||
4616 | IOCB_t *icmd, *oldcmd; | 4698 | IOCB_t *icmd, *oldcmd; |
4617 | RPL_RSP rpl_rsp; | 4699 | RPL_RSP rpl_rsp; |
4618 | struct lpfc_iocbq *elsiocb; | 4700 | struct lpfc_iocbq *elsiocb; |
4619 | struct lpfc_sli *psli = &phba->sli; | ||
4620 | struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING]; | ||
4621 | uint8_t *pcmd; | 4701 | uint8_t *pcmd; |
4622 | 4702 | ||
4623 | elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp, | 4703 | elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp, |
@@ -4654,7 +4734,8 @@ lpfc_els_rsp_rpl_acc(struct lpfc_vport *vport, uint16_t cmdsize, | |||
4654 | ndlp->nlp_rpi); | 4734 | ndlp->nlp_rpi); |
4655 | elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; | 4735 | elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; |
4656 | phba->fc_stat.elsXmitACC++; | 4736 | phba->fc_stat.elsXmitACC++; |
4657 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { | 4737 | if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) == |
4738 | IOCB_ERROR) { | ||
4658 | lpfc_els_free_iocb(phba, elsiocb); | 4739 | lpfc_els_free_iocb(phba, elsiocb); |
4659 | return 1; | 4740 | return 1; |
4660 | } | 4741 | } |
@@ -4883,7 +4964,10 @@ lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
4883 | } else { | 4964 | } else { |
4884 | /* FAN verified - skip FLOGI */ | 4965 | /* FAN verified - skip FLOGI */ |
4885 | vport->fc_myDID = vport->fc_prevDID; | 4966 | vport->fc_myDID = vport->fc_prevDID; |
4886 | lpfc_issue_fabric_reglogin(vport); | 4967 | if (phba->sli_rev < LPFC_SLI_REV4) |
4968 | lpfc_issue_fabric_reglogin(vport); | ||
4969 | else | ||
4970 | lpfc_issue_reg_vfi(vport); | ||
4887 | } | 4971 | } |
4888 | } | 4972 | } |
4889 | return 0; | 4973 | return 0; |
@@ -5566,11 +5650,10 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
5566 | 5650 | ||
5567 | dropit: | 5651 | dropit: |
5568 | if (vport && !(vport->load_flag & FC_UNLOADING)) | 5652 | if (vport && !(vport->load_flag & FC_UNLOADING)) |
5569 | lpfc_printf_log(phba, KERN_ERR, LOG_ELS, | 5653 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
5570 | "(%d):0111 Dropping received ELS cmd " | 5654 | "0111 Dropping received ELS cmd " |
5571 | "Data: x%x x%x x%x\n", | 5655 | "Data: x%x x%x x%x\n", |
5572 | vport->vpi, icmd->ulpStatus, | 5656 | icmd->ulpStatus, icmd->un.ulpWord[4], icmd->ulpTimeout); |
5573 | icmd->un.ulpWord[4], icmd->ulpTimeout); | ||
5574 | phba->fc_stat.elsRcvDrop++; | 5657 | phba->fc_stat.elsRcvDrop++; |
5575 | } | 5658 | } |
5576 | 5659 | ||
@@ -5646,10 +5729,9 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
5646 | icmd->ulpCommand == CMD_IOCB_RCV_SEQ64_CX)) { | 5729 | icmd->ulpCommand == CMD_IOCB_RCV_SEQ64_CX)) { |
5647 | if (icmd->unsli3.rcvsli3.vpi == 0xffff) | 5730 | if (icmd->unsli3.rcvsli3.vpi == 0xffff) |
5648 | vport = phba->pport; | 5731 | vport = phba->pport; |
5649 | else { | 5732 | else |
5650 | uint16_t vpi = icmd->unsli3.rcvsli3.vpi; | 5733 | vport = lpfc_find_vport_by_vpid(phba, |
5651 | vport = lpfc_find_vport_by_vpid(phba, vpi); | 5734 | icmd->unsli3.rcvsli3.vpi - phba->vpi_base); |
5652 | } | ||
5653 | } | 5735 | } |
5654 | /* If there are no BDEs associated | 5736 | /* If there are no BDEs associated |
5655 | * with this IOCB, there is nothing to do. | 5737 | * with this IOCB, there is nothing to do. |
@@ -5781,7 +5863,7 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
5781 | struct lpfc_vport *vport = pmb->vport; | 5863 | struct lpfc_vport *vport = pmb->vport; |
5782 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 5864 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
5783 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; | 5865 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; |
5784 | MAILBOX_t *mb = &pmb->mb; | 5866 | MAILBOX_t *mb = &pmb->u.mb; |
5785 | 5867 | ||
5786 | spin_lock_irq(shost->host_lock); | 5868 | spin_lock_irq(shost->host_lock); |
5787 | vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; | 5869 | vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; |
@@ -5818,7 +5900,10 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
5818 | 5900 | ||
5819 | } else { | 5901 | } else { |
5820 | if (vport == phba->pport) | 5902 | if (vport == phba->pport) |
5821 | lpfc_issue_fabric_reglogin(vport); | 5903 | if (phba->sli_rev < LPFC_SLI_REV4) |
5904 | lpfc_issue_fabric_reglogin(vport); | ||
5905 | else | ||
5906 | lpfc_issue_reg_vfi(vport); | ||
5822 | else | 5907 | else |
5823 | lpfc_do_scr_ns_plogi(phba, vport); | 5908 | lpfc_do_scr_ns_plogi(phba, vport); |
5824 | } | 5909 | } |
@@ -5850,7 +5935,7 @@ lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport, | |||
5850 | 5935 | ||
5851 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 5936 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
5852 | if (mbox) { | 5937 | if (mbox) { |
5853 | lpfc_reg_vpi(phba, vport->vpi, vport->fc_myDID, mbox); | 5938 | lpfc_reg_vpi(vport, mbox); |
5854 | mbox->vport = vport; | 5939 | mbox->vport = vport; |
5855 | mbox->context2 = lpfc_nlp_get(ndlp); | 5940 | mbox->context2 = lpfc_nlp_get(ndlp); |
5856 | mbox->mbox_cmpl = lpfc_cmpl_reg_new_vport; | 5941 | mbox->mbox_cmpl = lpfc_cmpl_reg_new_vport; |
@@ -6036,9 +6121,17 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
6036 | icmd->un.elsreq64.myID = 0; | 6121 | icmd->un.elsreq64.myID = 0; |
6037 | icmd->un.elsreq64.fl = 1; | 6122 | icmd->un.elsreq64.fl = 1; |
6038 | 6123 | ||
6039 | /* For FDISC, Let FDISC rsp set the NPortID for this VPI */ | 6124 | if (phba->sli_rev == LPFC_SLI_REV4) { |
6040 | icmd->ulpCt_h = 1; | 6125 | /* FDISC needs to be 1 for WQE VPI */ |
6041 | icmd->ulpCt_l = 0; | 6126 | elsiocb->iocb.ulpCt_h = (SLI4_CT_VPI >> 1) & 1; |
6127 | elsiocb->iocb.ulpCt_l = SLI4_CT_VPI & 1 ; | ||
6128 | /* Set the ulpContext to the vpi */ | ||
6129 | elsiocb->iocb.ulpContext = vport->vpi + phba->vpi_base; | ||
6130 | } else { | ||
6131 | /* For FDISC, Let FDISC rsp set the NPortID for this VPI */ | ||
6132 | icmd->ulpCt_h = 1; | ||
6133 | icmd->ulpCt_l = 0; | ||
6134 | } | ||
6042 | 6135 | ||
6043 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); | 6136 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); |
6044 | *((uint32_t *) (pcmd)) = ELS_CMD_FDISC; | 6137 | *((uint32_t *) (pcmd)) = ELS_CMD_FDISC; |
@@ -6139,7 +6232,6 @@ lpfc_issue_els_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
6139 | { | 6232 | { |
6140 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 6233 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
6141 | struct lpfc_hba *phba = vport->phba; | 6234 | struct lpfc_hba *phba = vport->phba; |
6142 | struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; | ||
6143 | IOCB_t *icmd; | 6235 | IOCB_t *icmd; |
6144 | struct lpfc_iocbq *elsiocb; | 6236 | struct lpfc_iocbq *elsiocb; |
6145 | uint8_t *pcmd; | 6237 | uint8_t *pcmd; |
@@ -6169,7 +6261,8 @@ lpfc_issue_els_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
6169 | spin_lock_irq(shost->host_lock); | 6261 | spin_lock_irq(shost->host_lock); |
6170 | ndlp->nlp_flag |= NLP_LOGO_SND; | 6262 | ndlp->nlp_flag |= NLP_LOGO_SND; |
6171 | spin_unlock_irq(shost->host_lock); | 6263 | spin_unlock_irq(shost->host_lock); |
6172 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { | 6264 | if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) == |
6265 | IOCB_ERROR) { | ||
6173 | spin_lock_irq(shost->host_lock); | 6266 | spin_lock_irq(shost->host_lock); |
6174 | ndlp->nlp_flag &= ~NLP_LOGO_SND; | 6267 | ndlp->nlp_flag &= ~NLP_LOGO_SND; |
6175 | spin_unlock_irq(shost->host_lock); | 6268 | spin_unlock_irq(shost->host_lock); |
@@ -6224,7 +6317,6 @@ lpfc_resume_fabric_iocbs(struct lpfc_hba *phba) | |||
6224 | struct lpfc_iocbq *iocb; | 6317 | struct lpfc_iocbq *iocb; |
6225 | unsigned long iflags; | 6318 | unsigned long iflags; |
6226 | int ret; | 6319 | int ret; |
6227 | struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; | ||
6228 | IOCB_t *cmd; | 6320 | IOCB_t *cmd; |
6229 | 6321 | ||
6230 | repeat: | 6322 | repeat: |
@@ -6248,7 +6340,7 @@ repeat: | |||
6248 | "Fabric sched1: ste:x%x", | 6340 | "Fabric sched1: ste:x%x", |
6249 | iocb->vport->port_state, 0, 0); | 6341 | iocb->vport->port_state, 0, 0); |
6250 | 6342 | ||
6251 | ret = lpfc_sli_issue_iocb(phba, pring, iocb, 0); | 6343 | ret = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, iocb, 0); |
6252 | 6344 | ||
6253 | if (ret == IOCB_ERROR) { | 6345 | if (ret == IOCB_ERROR) { |
6254 | iocb->iocb_cmpl = iocb->fabric_iocb_cmpl; | 6346 | iocb->iocb_cmpl = iocb->fabric_iocb_cmpl; |
@@ -6394,7 +6486,6 @@ static int | |||
6394 | lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb) | 6486 | lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb) |
6395 | { | 6487 | { |
6396 | unsigned long iflags; | 6488 | unsigned long iflags; |
6397 | struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; | ||
6398 | int ready; | 6489 | int ready; |
6399 | int ret; | 6490 | int ret; |
6400 | 6491 | ||
@@ -6418,7 +6509,7 @@ lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb) | |||
6418 | "Fabric sched2: ste:x%x", | 6509 | "Fabric sched2: ste:x%x", |
6419 | iocb->vport->port_state, 0, 0); | 6510 | iocb->vport->port_state, 0, 0); |
6420 | 6511 | ||
6421 | ret = lpfc_sli_issue_iocb(phba, pring, iocb, 0); | 6512 | ret = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, iocb, 0); |
6422 | 6513 | ||
6423 | if (ret == IOCB_ERROR) { | 6514 | if (ret == IOCB_ERROR) { |
6424 | iocb->iocb_cmpl = iocb->fabric_iocb_cmpl; | 6515 | iocb->iocb_cmpl = iocb->fabric_iocb_cmpl; |
@@ -6524,3 +6615,38 @@ void lpfc_fabric_abort_hba(struct lpfc_hba *phba) | |||
6524 | lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT, | 6615 | lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT, |
6525 | IOERR_SLI_ABORTED); | 6616 | IOERR_SLI_ABORTED); |
6526 | } | 6617 | } |
6618 | |||
6619 | /** | ||
6620 | * lpfc_sli4_els_xri_aborted - Slow-path process of els xri abort | ||
6621 | * @phba: pointer to lpfc hba data structure. | ||
6622 | * @axri: pointer to the els xri abort wcqe structure. | ||
6623 | * | ||
6624 | * This routine is invoked by the worker thread to process a SLI4 slow-path | ||
6625 | * ELS aborted xri. | ||
6626 | **/ | ||
6627 | void | ||
6628 | lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba, | ||
6629 | struct sli4_wcqe_xri_aborted *axri) | ||
6630 | { | ||
6631 | uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri); | ||
6632 | struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL; | ||
6633 | unsigned long iflag = 0; | ||
6634 | |||
6635 | spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock, iflag); | ||
6636 | list_for_each_entry_safe(sglq_entry, sglq_next, | ||
6637 | &phba->sli4_hba.lpfc_abts_els_sgl_list, list) { | ||
6638 | if (sglq_entry->sli4_xritag == xri) { | ||
6639 | list_del(&sglq_entry->list); | ||
6640 | spin_unlock_irqrestore( | ||
6641 | &phba->sli4_hba.abts_sgl_list_lock, | ||
6642 | iflag); | ||
6643 | spin_lock_irqsave(&phba->hbalock, iflag); | ||
6644 | |||
6645 | list_add_tail(&sglq_entry->list, | ||
6646 | &phba->sli4_hba.lpfc_sgl_list); | ||
6647 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
6648 | return; | ||
6649 | } | ||
6650 | } | ||
6651 | spin_unlock_irqrestore(&phba->sli4_hba.abts_sgl_list_lock, iflag); | ||
6652 | } | ||