| .. | .. |
|---|
| 1 | 1 | /******************************************************************* |
|---|
| 2 | 2 | * This file is part of the Emulex Linux Device Driver for * |
|---|
| 3 | 3 | * Fibre Channel Host Bus Adapters. * |
|---|
| 4 | | - * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
|---|
| 4 | + * Copyright (C) 2017-2019 Broadcom. All Rights Reserved. The term * |
|---|
| 5 | 5 | * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * |
|---|
| 6 | 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * |
|---|
| 7 | 7 | * EMULEX and SLI are trademarks of Emulex. * |
|---|
| .. | .. |
|---|
| 31 | 31 | #include <scsi/scsi_host.h> |
|---|
| 32 | 32 | #include <scsi/scsi_transport_fc.h> |
|---|
| 33 | 33 | #include <scsi/fc/fc_fs.h> |
|---|
| 34 | | - |
|---|
| 35 | | -#include <linux/nvme-fc-driver.h> |
|---|
| 36 | 34 | |
|---|
| 37 | 35 | #include "lpfc_hw4.h" |
|---|
| 38 | 36 | #include "lpfc_hw.h" |
|---|
| .. | .. |
|---|
| 154 | 152 | memcpy(&ndlp->nlp_portname, &sp->portName, sizeof (struct lpfc_name)); |
|---|
| 155 | 153 | return 1; |
|---|
| 156 | 154 | bad_service_param: |
|---|
| 157 | | - lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, |
|---|
| 155 | + lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
|---|
| 158 | 156 | "0207 Device %x " |
|---|
| 159 | 157 | "(%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x) sent " |
|---|
| 160 | 158 | "invalid service parameters. Ignoring device.\n", |
|---|
| .. | .. |
|---|
| 279 | 277 | lpfc_cancel_retry_delay_tmo(phba->pport, ndlp); |
|---|
| 280 | 278 | } |
|---|
| 281 | 279 | |
|---|
| 280 | +/* lpfc_defer_pt2pt_acc - Complete SLI3 pt2pt processing on link up |
|---|
| 281 | + * @phba: pointer to lpfc hba data structure. |
|---|
| 282 | + * @link_mbox: pointer to CONFIG_LINK mailbox object |
|---|
| 283 | + * |
|---|
| 284 | + * This routine is only called if we are SLI3, direct connect pt2pt |
|---|
| 285 | + * mode and the remote NPort issues the PLOGI after link up. |
|---|
| 286 | + */ |
|---|
| 287 | +static void |
|---|
| 288 | +lpfc_defer_pt2pt_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *link_mbox) |
|---|
| 289 | +{ |
|---|
| 290 | + LPFC_MBOXQ_t *login_mbox; |
|---|
| 291 | + MAILBOX_t *mb = &link_mbox->u.mb; |
|---|
| 292 | + struct lpfc_iocbq *save_iocb; |
|---|
| 293 | + struct lpfc_nodelist *ndlp; |
|---|
| 294 | + int rc; |
|---|
| 295 | + |
|---|
| 296 | + ndlp = link_mbox->ctx_ndlp; |
|---|
| 297 | + login_mbox = link_mbox->context3; |
|---|
| 298 | + save_iocb = login_mbox->context3; |
|---|
| 299 | + link_mbox->context3 = NULL; |
|---|
| 300 | + login_mbox->context3 = NULL; |
|---|
| 301 | + |
|---|
| 302 | + /* Check for CONFIG_LINK error */ |
|---|
| 303 | + if (mb->mbxStatus) { |
|---|
| 304 | + lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, |
|---|
| 305 | + "4575 CONFIG_LINK fails pt2pt discovery: %x\n", |
|---|
| 306 | + mb->mbxStatus); |
|---|
| 307 | + mempool_free(login_mbox, phba->mbox_mem_pool); |
|---|
| 308 | + mempool_free(link_mbox, phba->mbox_mem_pool); |
|---|
| 309 | + kfree(save_iocb); |
|---|
| 310 | + return; |
|---|
| 311 | + } |
|---|
| 312 | + |
|---|
| 313 | + /* Now that CONFIG_LINK completed, and our SID is configured, |
|---|
| 314 | + * we can now proceed with sending the PLOGI ACC. |
|---|
| 315 | + */ |
|---|
| 316 | + rc = lpfc_els_rsp_acc(link_mbox->vport, ELS_CMD_PLOGI, |
|---|
| 317 | + save_iocb, ndlp, login_mbox); |
|---|
| 318 | + if (rc) { |
|---|
| 319 | + lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, |
|---|
| 320 | + "4576 PLOGI ACC fails pt2pt discovery: %x\n", |
|---|
| 321 | + rc); |
|---|
| 322 | + mempool_free(login_mbox, phba->mbox_mem_pool); |
|---|
| 323 | + } |
|---|
| 324 | + |
|---|
| 325 | + mempool_free(link_mbox, phba->mbox_mem_pool); |
|---|
| 326 | + kfree(save_iocb); |
|---|
| 327 | +} |
|---|
| 328 | + |
|---|
| 329 | +/** |
|---|
| 330 | + * lpfc_defer_tgt_acc - Progress SLI4 target rcv PLOGI handler |
|---|
| 331 | + * @phba: Pointer to HBA context object. |
|---|
| 332 | + * @pmb: Pointer to mailbox object. |
|---|
| 333 | + * |
|---|
| 334 | + * This function provides the unreg rpi mailbox completion handler for a tgt. |
|---|
| 335 | + * The routine frees the memory resources associated with the completed |
|---|
| 336 | + * mailbox command and transmits the ELS ACC. |
|---|
| 337 | + * |
|---|
| 338 | + * This routine is only called if we are SLI4, acting in target |
|---|
| 339 | + * mode and the remote NPort issues the PLOGI after link up. |
|---|
| 340 | + **/ |
|---|
| 341 | +static void |
|---|
| 342 | +lpfc_defer_acc_rsp(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
|---|
| 343 | +{ |
|---|
| 344 | + struct lpfc_vport *vport = pmb->vport; |
|---|
| 345 | + struct lpfc_nodelist *ndlp = pmb->ctx_ndlp; |
|---|
| 346 | + LPFC_MBOXQ_t *mbox = pmb->context3; |
|---|
| 347 | + struct lpfc_iocbq *piocb = NULL; |
|---|
| 348 | + int rc; |
|---|
| 349 | + |
|---|
| 350 | + if (mbox) { |
|---|
| 351 | + pmb->context3 = NULL; |
|---|
| 352 | + piocb = mbox->context3; |
|---|
| 353 | + mbox->context3 = NULL; |
|---|
| 354 | + } |
|---|
| 355 | + |
|---|
| 356 | + /* |
|---|
| 357 | + * Complete the unreg rpi mbx request, and update flags. |
|---|
| 358 | + * This will also restart any deferred events. |
|---|
| 359 | + */ |
|---|
| 360 | + lpfc_nlp_get(ndlp); |
|---|
| 361 | + lpfc_sli4_unreg_rpi_cmpl_clr(phba, pmb); |
|---|
| 362 | + |
|---|
| 363 | + if (!piocb) { |
|---|
| 364 | + lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
|---|
| 365 | + "4578 PLOGI ACC fail\n"); |
|---|
| 366 | + if (mbox) |
|---|
| 367 | + mempool_free(mbox, phba->mbox_mem_pool); |
|---|
| 368 | + goto out; |
|---|
| 369 | + } |
|---|
| 370 | + |
|---|
| 371 | + rc = lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, piocb, ndlp, mbox); |
|---|
| 372 | + if (rc) { |
|---|
| 373 | + lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
|---|
| 374 | + "4579 PLOGI ACC fail %x\n", rc); |
|---|
| 375 | + if (mbox) |
|---|
| 376 | + mempool_free(mbox, phba->mbox_mem_pool); |
|---|
| 377 | + } |
|---|
| 378 | + kfree(piocb); |
|---|
| 379 | +out: |
|---|
| 380 | + lpfc_nlp_put(ndlp); |
|---|
| 381 | +} |
|---|
| 382 | + |
|---|
| 282 | 383 | static int |
|---|
| 283 | 384 | lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
|---|
| 284 | 385 | struct lpfc_iocbq *cmdiocb) |
|---|
| .. | .. |
|---|
| 291 | 392 | IOCB_t *icmd; |
|---|
| 292 | 393 | struct serv_parm *sp; |
|---|
| 293 | 394 | uint32_t ed_tov; |
|---|
| 294 | | - LPFC_MBOXQ_t *mbox; |
|---|
| 395 | + LPFC_MBOXQ_t *link_mbox; |
|---|
| 396 | + LPFC_MBOXQ_t *login_mbox; |
|---|
| 397 | + struct lpfc_iocbq *save_iocb; |
|---|
| 295 | 398 | struct ls_rjt stat; |
|---|
| 296 | 399 | uint32_t vid, flag; |
|---|
| 297 | | - int rc; |
|---|
| 400 | + u16 rpi; |
|---|
| 401 | + int rc, defer_acc; |
|---|
| 298 | 402 | |
|---|
| 299 | 403 | memset(&stat, 0, sizeof (struct ls_rjt)); |
|---|
| 300 | 404 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; |
|---|
| 301 | 405 | lp = (uint32_t *) pcmd->virt; |
|---|
| 302 | 406 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); |
|---|
| 303 | 407 | if (wwn_to_u64(sp->portName.u.wwn) == 0) { |
|---|
| 304 | | - lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
|---|
| 408 | + lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
|---|
| 305 | 409 | "0140 PLOGI Reject: invalid nname\n"); |
|---|
| 306 | 410 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
|---|
| 307 | 411 | stat.un.b.lsRjtRsnCodeExp = LSEXP_INVALID_PNAME; |
|---|
| .. | .. |
|---|
| 310 | 414 | return 0; |
|---|
| 311 | 415 | } |
|---|
| 312 | 416 | if (wwn_to_u64(sp->nodeName.u.wwn) == 0) { |
|---|
| 313 | | - lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
|---|
| 417 | + lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
|---|
| 314 | 418 | "0141 PLOGI Reject: invalid pname\n"); |
|---|
| 315 | 419 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
|---|
| 316 | 420 | stat.un.b.lsRjtRsnCodeExp = LSEXP_INVALID_NNAME; |
|---|
| .. | .. |
|---|
| 343 | 447 | else |
|---|
| 344 | 448 | ndlp->nlp_fcp_info |= CLASS3; |
|---|
| 345 | 449 | |
|---|
| 450 | + defer_acc = 0; |
|---|
| 346 | 451 | ndlp->nlp_class_sup = 0; |
|---|
| 347 | 452 | if (sp->cls1.classValid) |
|---|
| 348 | 453 | ndlp->nlp_class_sup |= FC_COS_CLASS1; |
|---|
| .. | .. |
|---|
| 354 | 459 | ndlp->nlp_class_sup |= FC_COS_CLASS4; |
|---|
| 355 | 460 | ndlp->nlp_maxframe = |
|---|
| 356 | 461 | ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb; |
|---|
| 357 | | - |
|---|
| 358 | 462 | /* if already logged in, do implicit logout */ |
|---|
| 359 | 463 | switch (ndlp->nlp_state) { |
|---|
| 360 | 464 | case NLP_STE_NPR_NODE: |
|---|
| 361 | 465 | if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) |
|---|
| 362 | 466 | break; |
|---|
| 467 | + fallthrough; |
|---|
| 363 | 468 | case NLP_STE_REG_LOGIN_ISSUE: |
|---|
| 364 | 469 | case NLP_STE_PRLI_ISSUE: |
|---|
| 365 | 470 | case NLP_STE_UNMAPPED_NODE: |
|---|
| .. | .. |
|---|
| 376 | 481 | } |
|---|
| 377 | 482 | if (nlp_portwwn != 0 && |
|---|
| 378 | 483 | nlp_portwwn != wwn_to_u64(sp->portName.u.wwn)) |
|---|
| 379 | | - lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
|---|
| 484 | + lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
|---|
| 380 | 485 | "0143 PLOGI recv'd from DID: x%x " |
|---|
| 381 | 486 | "WWPN changed: old %llx new %llx\n", |
|---|
| 382 | 487 | ndlp->nlp_DID, |
|---|
| 383 | 488 | (unsigned long long)nlp_portwwn, |
|---|
| 384 | 489 | (unsigned long long) |
|---|
| 385 | 490 | wwn_to_u64(sp->portName.u.wwn)); |
|---|
| 491 | + |
|---|
| 492 | + /* Notify transport of connectivity loss to trigger cleanup. */ |
|---|
| 493 | + if (phba->nvmet_support && |
|---|
| 494 | + ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) |
|---|
| 495 | + lpfc_nvmet_invalidate_host(phba, ndlp); |
|---|
| 386 | 496 | |
|---|
| 387 | 497 | ndlp->nlp_prev_state = ndlp->nlp_state; |
|---|
| 388 | 498 | /* rport needs to be unregistered first */ |
|---|
| .. | .. |
|---|
| 394 | 504 | ndlp->nlp_type &= ~(NLP_NVME_TARGET | NLP_NVME_INITIATOR); |
|---|
| 395 | 505 | ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE; |
|---|
| 396 | 506 | ndlp->nlp_flag &= ~NLP_FIRSTBURST; |
|---|
| 507 | + |
|---|
| 508 | + login_mbox = NULL; |
|---|
| 509 | + link_mbox = NULL; |
|---|
| 510 | + save_iocb = NULL; |
|---|
| 397 | 511 | |
|---|
| 398 | 512 | /* Check for Nport to NPort pt2pt protocol */ |
|---|
| 399 | 513 | if ((vport->fc_flag & FC_PT2PT) && |
|---|
| .. | .. |
|---|
| 422 | 536 | if (phba->sli_rev == LPFC_SLI_REV4) |
|---|
| 423 | 537 | lpfc_issue_reg_vfi(vport); |
|---|
| 424 | 538 | else { |
|---|
| 425 | | - mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
|---|
| 426 | | - if (mbox == NULL) |
|---|
| 539 | + defer_acc = 1; |
|---|
| 540 | + link_mbox = mempool_alloc(phba->mbox_mem_pool, |
|---|
| 541 | + GFP_KERNEL); |
|---|
| 542 | + if (!link_mbox) |
|---|
| 427 | 543 | goto out; |
|---|
| 428 | | - lpfc_config_link(phba, mbox); |
|---|
| 429 | | - mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
|---|
| 430 | | - mbox->vport = vport; |
|---|
| 431 | | - rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
|---|
| 432 | | - if (rc == MBX_NOT_FINISHED) { |
|---|
| 433 | | - mempool_free(mbox, phba->mbox_mem_pool); |
|---|
| 544 | + lpfc_config_link(phba, link_mbox); |
|---|
| 545 | + link_mbox->mbox_cmpl = lpfc_defer_pt2pt_acc; |
|---|
| 546 | + link_mbox->vport = vport; |
|---|
| 547 | + link_mbox->ctx_ndlp = ndlp; |
|---|
| 548 | + |
|---|
| 549 | + save_iocb = kzalloc(sizeof(*save_iocb), GFP_KERNEL); |
|---|
| 550 | + if (!save_iocb) |
|---|
| 434 | 551 | goto out; |
|---|
| 435 | | - } |
|---|
| 552 | + /* Save info from cmd IOCB used in rsp */ |
|---|
| 553 | + memcpy((uint8_t *)save_iocb, (uint8_t *)cmdiocb, |
|---|
| 554 | + sizeof(struct lpfc_iocbq)); |
|---|
| 436 | 555 | } |
|---|
| 437 | 556 | |
|---|
| 438 | 557 | lpfc_can_disctmo(vport); |
|---|
| .. | .. |
|---|
| 447 | 566 | ndlp->nlp_flag |= NLP_SUPPRESS_RSP; |
|---|
| 448 | 567 | } |
|---|
| 449 | 568 | |
|---|
| 450 | | - mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
|---|
| 451 | | - if (!mbox) |
|---|
| 569 | + login_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
|---|
| 570 | + if (!login_mbox) |
|---|
| 452 | 571 | goto out; |
|---|
| 453 | 572 | |
|---|
| 454 | 573 | /* Registering an existing RPI behaves differently for SLI3 vs SLI4 */ |
|---|
| 455 | | - if (phba->sli_rev == LPFC_SLI_REV4) |
|---|
| 574 | + if (phba->nvmet_support && !defer_acc) { |
|---|
| 575 | + link_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
|---|
| 576 | + if (!link_mbox) |
|---|
| 577 | + goto out; |
|---|
| 578 | + |
|---|
| 579 | + /* As unique identifiers such as iotag would be overwritten |
|---|
| 580 | + * with those from the cmdiocb, allocate separate temporary |
|---|
| 581 | + * storage for the copy. |
|---|
| 582 | + */ |
|---|
| 583 | + save_iocb = kzalloc(sizeof(*save_iocb), GFP_KERNEL); |
|---|
| 584 | + if (!save_iocb) |
|---|
| 585 | + goto out; |
|---|
| 586 | + |
|---|
| 587 | + /* Unreg RPI is required for SLI4. */ |
|---|
| 588 | + rpi = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]; |
|---|
| 589 | + lpfc_unreg_login(phba, vport->vpi, rpi, link_mbox); |
|---|
| 590 | + link_mbox->vport = vport; |
|---|
| 591 | + link_mbox->ctx_ndlp = ndlp; |
|---|
| 592 | + link_mbox->mbox_cmpl = lpfc_defer_acc_rsp; |
|---|
| 593 | + |
|---|
| 594 | + if (((ndlp->nlp_DID & Fabric_DID_MASK) != Fabric_DID_MASK) && |
|---|
| 595 | + (!(vport->fc_flag & FC_OFFLINE_MODE))) |
|---|
| 596 | + ndlp->nlp_flag |= NLP_UNREG_INP; |
|---|
| 597 | + |
|---|
| 598 | + /* Save info from cmd IOCB used in rsp */ |
|---|
| 599 | + memcpy(save_iocb, cmdiocb, sizeof(*save_iocb)); |
|---|
| 600 | + |
|---|
| 601 | + /* Delay sending ACC till unreg RPI completes. */ |
|---|
| 602 | + defer_acc = 1; |
|---|
| 603 | + } else if (phba->sli_rev == LPFC_SLI_REV4) |
|---|
| 456 | 604 | lpfc_unreg_rpi(vport, ndlp); |
|---|
| 457 | 605 | |
|---|
| 458 | 606 | rc = lpfc_reg_rpi(phba, vport->vpi, icmd->un.rcvels.remoteID, |
|---|
| 459 | | - (uint8_t *) sp, mbox, ndlp->nlp_rpi); |
|---|
| 460 | | - if (rc) { |
|---|
| 461 | | - mempool_free(mbox, phba->mbox_mem_pool); |
|---|
| 607 | + (uint8_t *)sp, login_mbox, ndlp->nlp_rpi); |
|---|
| 608 | + if (rc) |
|---|
| 462 | 609 | goto out; |
|---|
| 463 | | - } |
|---|
| 464 | 610 | |
|---|
| 465 | 611 | /* ACC PLOGI rsp command needs to execute first, |
|---|
| 466 | | - * queue this mbox command to be processed later. |
|---|
| 612 | + * queue this login_mbox command to be processed later. |
|---|
| 467 | 613 | */ |
|---|
| 468 | | - mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; |
|---|
| 614 | + login_mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; |
|---|
| 469 | 615 | /* |
|---|
| 470 | | - * mbox->context2 = lpfc_nlp_get(ndlp) deferred until mailbox |
|---|
| 616 | + * login_mbox->ctx_ndlp = lpfc_nlp_get(ndlp) deferred until mailbox |
|---|
| 471 | 617 | * command issued in lpfc_cmpl_els_acc(). |
|---|
| 472 | 618 | */ |
|---|
| 473 | | - mbox->vport = vport; |
|---|
| 619 | + login_mbox->vport = vport; |
|---|
| 474 | 620 | spin_lock_irq(shost->host_lock); |
|---|
| 475 | 621 | ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI); |
|---|
| 476 | 622 | spin_unlock_irq(shost->host_lock); |
|---|
| .. | .. |
|---|
| 494 | 640 | if ((vport->port_type == LPFC_NPIV_PORT && |
|---|
| 495 | 641 | vport->cfg_restrict_login)) { |
|---|
| 496 | 642 | |
|---|
| 643 | + /* no deferred ACC */ |
|---|
| 644 | + kfree(save_iocb); |
|---|
| 645 | + |
|---|
| 497 | 646 | /* In order to preserve RPIs, we want to cleanup |
|---|
| 498 | 647 | * the default RPI the firmware created to rcv |
|---|
| 499 | 648 | * this ELS request. The only way to do this is |
|---|
| .. | .. |
|---|
| 505 | 654 | stat.un.b.lsRjtRsnCode = LSRJT_INVALID_CMD; |
|---|
| 506 | 655 | stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; |
|---|
| 507 | 656 | rc = lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, |
|---|
| 508 | | - ndlp, mbox); |
|---|
| 657 | + ndlp, login_mbox); |
|---|
| 509 | 658 | if (rc) |
|---|
| 510 | | - mempool_free(mbox, phba->mbox_mem_pool); |
|---|
| 659 | + mempool_free(login_mbox, phba->mbox_mem_pool); |
|---|
| 511 | 660 | return 1; |
|---|
| 512 | 661 | } |
|---|
| 513 | | - rc = lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox); |
|---|
| 662 | + if (defer_acc) { |
|---|
| 663 | + /* So the order here should be: |
|---|
| 664 | + * SLI3 pt2pt |
|---|
| 665 | + * Issue CONFIG_LINK mbox |
|---|
| 666 | + * CONFIG_LINK cmpl |
|---|
| 667 | + * SLI4 tgt |
|---|
| 668 | + * Issue UNREG RPI mbx |
|---|
| 669 | + * UNREG RPI cmpl |
|---|
| 670 | + * Issue PLOGI ACC |
|---|
| 671 | + * PLOGI ACC cmpl |
|---|
| 672 | + * Issue REG_LOGIN mbox |
|---|
| 673 | + */ |
|---|
| 674 | + |
|---|
| 675 | + /* Save the REG_LOGIN mbox for and rcv IOCB copy later */ |
|---|
| 676 | + link_mbox->context3 = login_mbox; |
|---|
| 677 | + login_mbox->context3 = save_iocb; |
|---|
| 678 | + |
|---|
| 679 | + /* Start the ball rolling by issuing CONFIG_LINK here */ |
|---|
| 680 | + rc = lpfc_sli_issue_mbox(phba, link_mbox, MBX_NOWAIT); |
|---|
| 681 | + if (rc == MBX_NOT_FINISHED) |
|---|
| 682 | + goto out; |
|---|
| 683 | + return 1; |
|---|
| 684 | + } |
|---|
| 685 | + |
|---|
| 686 | + rc = lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, login_mbox); |
|---|
| 514 | 687 | if (rc) |
|---|
| 515 | | - mempool_free(mbox, phba->mbox_mem_pool); |
|---|
| 688 | + mempool_free(login_mbox, phba->mbox_mem_pool); |
|---|
| 516 | 689 | return 1; |
|---|
| 517 | 690 | out: |
|---|
| 691 | + if (defer_acc) |
|---|
| 692 | + lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, |
|---|
| 693 | + "4577 discovery failure: %p %p %p\n", |
|---|
| 694 | + save_iocb, link_mbox, login_mbox); |
|---|
| 695 | + kfree(save_iocb); |
|---|
| 696 | + if (link_mbox) |
|---|
| 697 | + mempool_free(link_mbox, phba->mbox_mem_pool); |
|---|
| 698 | + if (login_mbox) |
|---|
| 699 | + mempool_free(login_mbox, phba->mbox_mem_pool); |
|---|
| 700 | + |
|---|
| 518 | 701 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
|---|
| 519 | 702 | stat.un.b.lsRjtRsnCodeExp = LSEXP_OUT_OF_RESOURCE; |
|---|
| 520 | 703 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL); |
|---|
| .. | .. |
|---|
| 537 | 720 | struct lpfc_nodelist *ndlp; |
|---|
| 538 | 721 | uint32_t cmd; |
|---|
| 539 | 722 | |
|---|
| 540 | | - elsiocb = (struct lpfc_iocbq *)mboxq->context1; |
|---|
| 541 | | - ndlp = (struct lpfc_nodelist *) mboxq->context2; |
|---|
| 723 | + elsiocb = (struct lpfc_iocbq *)mboxq->ctx_buf; |
|---|
| 724 | + ndlp = (struct lpfc_nodelist *)mboxq->ctx_ndlp; |
|---|
| 542 | 725 | vport = mboxq->vport; |
|---|
| 543 | 726 | cmd = elsiocb->drvrTimeout; |
|---|
| 544 | 727 | |
|---|
| .. | .. |
|---|
| 614 | 797 | ndlp, NULL); |
|---|
| 615 | 798 | } |
|---|
| 616 | 799 | out: |
|---|
| 617 | | - /* If we are authenticated, move to the proper state */ |
|---|
| 618 | | - if (ndlp->nlp_type & NLP_FCP_TARGET) |
|---|
| 619 | | - lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE); |
|---|
| 620 | | - else |
|---|
| 621 | | - lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
|---|
| 800 | + /* If we are authenticated, move to the proper state. |
|---|
| 801 | + * It is possible an ADISC arrived and the remote nport |
|---|
| 802 | + * is already in MAPPED or UNMAPPED state. Catch this |
|---|
| 803 | + * condition and don't set the nlp_state again because |
|---|
| 804 | + * it causes an unnecessary transport unregister/register. |
|---|
| 805 | + */ |
|---|
| 806 | + if (ndlp->nlp_type & (NLP_FCP_TARGET | NLP_NVME_TARGET)) { |
|---|
| 807 | + if (ndlp->nlp_state != NLP_STE_MAPPED_NODE) |
|---|
| 808 | + lpfc_nlp_set_state(vport, ndlp, |
|---|
| 809 | + NLP_STE_MAPPED_NODE); |
|---|
| 810 | + } |
|---|
| 622 | 811 | |
|---|
| 623 | 812 | return 1; |
|---|
| 624 | 813 | } |
|---|
| .. | .. |
|---|
| 661 | 850 | lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL); |
|---|
| 662 | 851 | else |
|---|
| 663 | 852 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); |
|---|
| 853 | + |
|---|
| 854 | + /* Notify transport of connectivity loss to trigger cleanup. */ |
|---|
| 855 | + if (phba->nvmet_support && |
|---|
| 856 | + ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) |
|---|
| 857 | + lpfc_nvmet_invalidate_host(phba, ndlp); |
|---|
| 858 | + |
|---|
| 664 | 859 | if (ndlp->nlp_DID == Fabric_DID) { |
|---|
| 665 | | - if (vport->port_state <= LPFC_FDISC) |
|---|
| 860 | + if (vport->port_state <= LPFC_FDISC || |
|---|
| 861 | + vport->fc_flag & FC_PT2PT) |
|---|
| 666 | 862 | goto out; |
|---|
| 667 | 863 | lpfc_linkdown_port(vport); |
|---|
| 668 | 864 | spin_lock_irq(shost->host_lock); |
|---|
| .. | .. |
|---|
| 805 | 1001 | if (npr->writeXferRdyDis) |
|---|
| 806 | 1002 | ndlp->nlp_flag |= NLP_FIRSTBURST; |
|---|
| 807 | 1003 | } |
|---|
| 808 | | - if (npr->Retry) |
|---|
| 1004 | + if (npr->Retry && ndlp->nlp_type & |
|---|
| 1005 | + (NLP_FCP_INITIATOR | NLP_FCP_TARGET)) |
|---|
| 809 | 1006 | ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE; |
|---|
| 1007 | + |
|---|
| 1008 | + if (npr->Retry && phba->nsler && |
|---|
| 1009 | + ndlp->nlp_type & (NLP_NVME_INITIATOR | NLP_NVME_TARGET)) |
|---|
| 1010 | + ndlp->nlp_nvme_info |= NLP_NVME_NSLER; |
|---|
| 1011 | + |
|---|
| 810 | 1012 | |
|---|
| 811 | 1013 | /* If this driver is in nvme target mode, set the ndlp's fc4 |
|---|
| 812 | 1014 | * type to NVME provided the PRLI response claims NVME FC4 |
|---|
| .. | .. |
|---|
| 832 | 1034 | "rport rolechg: role:x%x did:x%x flg:x%x", |
|---|
| 833 | 1035 | roles, ndlp->nlp_DID, ndlp->nlp_flag); |
|---|
| 834 | 1036 | |
|---|
| 835 | | - if (phba->cfg_enable_fc4_type != LPFC_ENABLE_NVME) |
|---|
| 1037 | + if (vport->cfg_enable_fc4_type != LPFC_ENABLE_NVME) |
|---|
| 836 | 1038 | fc_remote_port_rolechg(rport, roles); |
|---|
| 837 | 1039 | } |
|---|
| 838 | 1040 | } |
|---|
| .. | .. |
|---|
| 872 | 1074 | * lpfc_release_rpi - Release a RPI by issuing unreg_login mailbox cmd. |
|---|
| 873 | 1075 | * @phba : Pointer to lpfc_hba structure. |
|---|
| 874 | 1076 | * @vport: Pointer to lpfc_vport structure. |
|---|
| 1077 | + * @ndlp: Pointer to lpfc_nodelist structure. |
|---|
| 875 | 1078 | * @rpi : rpi to be release. |
|---|
| 876 | 1079 | * |
|---|
| 877 | 1080 | * This function will send a unreg_login mailbox command to the firmware |
|---|
| 878 | 1081 | * to release a rpi. |
|---|
| 879 | 1082 | **/ |
|---|
| 880 | | -void |
|---|
| 881 | | -lpfc_release_rpi(struct lpfc_hba *phba, |
|---|
| 882 | | - struct lpfc_vport *vport, |
|---|
| 883 | | - uint16_t rpi) |
|---|
| 1083 | +static void |
|---|
| 1084 | +lpfc_release_rpi(struct lpfc_hba *phba, struct lpfc_vport *vport, |
|---|
| 1085 | + struct lpfc_nodelist *ndlp, uint16_t rpi) |
|---|
| 884 | 1086 | { |
|---|
| 885 | 1087 | LPFC_MBOXQ_t *pmb; |
|---|
| 886 | 1088 | int rc; |
|---|
| 887 | 1089 | |
|---|
| 1090 | + /* If there is already an UNREG in progress for this ndlp, |
|---|
| 1091 | + * no need to queue up another one. |
|---|
| 1092 | + */ |
|---|
| 1093 | + if (ndlp->nlp_flag & NLP_UNREG_INP) { |
|---|
| 1094 | + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, |
|---|
| 1095 | + "1435 release_rpi SKIP UNREG x%x on " |
|---|
| 1096 | + "NPort x%x deferred x%x flg x%x " |
|---|
| 1097 | + "Data: x%px\n", |
|---|
| 1098 | + ndlp->nlp_rpi, ndlp->nlp_DID, |
|---|
| 1099 | + ndlp->nlp_defer_did, |
|---|
| 1100 | + ndlp->nlp_flag, ndlp); |
|---|
| 1101 | + return; |
|---|
| 1102 | + } |
|---|
| 1103 | + |
|---|
| 888 | 1104 | pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, |
|---|
| 889 | 1105 | GFP_KERNEL); |
|---|
| 890 | 1106 | if (!pmb) |
|---|
| 891 | | - lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, |
|---|
| 892 | | - "2796 mailbox memory allocation failed \n"); |
|---|
| 1107 | + lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
|---|
| 1108 | + "2796 mailbox memory allocation failed \n"); |
|---|
| 893 | 1109 | else { |
|---|
| 894 | 1110 | lpfc_unreg_login(phba, vport->vpi, rpi, pmb); |
|---|
| 895 | 1111 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
|---|
| 1112 | + pmb->vport = vport; |
|---|
| 1113 | + pmb->ctx_ndlp = ndlp; |
|---|
| 1114 | + |
|---|
| 1115 | + if (((ndlp->nlp_DID & Fabric_DID_MASK) != Fabric_DID_MASK) && |
|---|
| 1116 | + (!(vport->fc_flag & FC_OFFLINE_MODE))) |
|---|
| 1117 | + ndlp->nlp_flag |= NLP_UNREG_INP; |
|---|
| 1118 | + |
|---|
| 1119 | + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, |
|---|
| 1120 | + "1437 release_rpi UNREG x%x " |
|---|
| 1121 | + "on NPort x%x flg x%x\n", |
|---|
| 1122 | + ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag); |
|---|
| 1123 | + |
|---|
| 896 | 1124 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); |
|---|
| 897 | 1125 | if (rc == MBX_NOT_FINISHED) |
|---|
| 898 | 1126 | mempool_free(pmb, phba->mbox_mem_pool); |
|---|
| .. | .. |
|---|
| 913 | 1141 | (evt == NLP_EVT_CMPL_REG_LOGIN) && |
|---|
| 914 | 1142 | (!pmb->u.mb.mbxStatus)) { |
|---|
| 915 | 1143 | rpi = pmb->u.mb.un.varWords[0]; |
|---|
| 916 | | - lpfc_release_rpi(phba, vport, rpi); |
|---|
| 1144 | + lpfc_release_rpi(phba, vport, ndlp, rpi); |
|---|
| 917 | 1145 | } |
|---|
| 918 | | - lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, |
|---|
| 1146 | + lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
|---|
| 919 | 1147 | "0271 Illegal State Transition: node x%x " |
|---|
| 920 | 1148 | "event x%x, state x%x Data: x%x x%x\n", |
|---|
| 921 | 1149 | ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi, |
|---|
| .. | .. |
|---|
| 933 | 1161 | * to stop it. |
|---|
| 934 | 1162 | */ |
|---|
| 935 | 1163 | if (!(ndlp->nlp_flag & NLP_RCV_PLOGI)) { |
|---|
| 936 | | - lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, |
|---|
| 937 | | - "0272 Illegal State Transition: node x%x " |
|---|
| 938 | | - "event x%x, state x%x Data: x%x x%x\n", |
|---|
| 939 | | - ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi, |
|---|
| 940 | | - ndlp->nlp_flag); |
|---|
| 1164 | + lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
|---|
| 1165 | + "0272 Illegal State Transition: node x%x " |
|---|
| 1166 | + "event x%x, state x%x Data: x%x x%x\n", |
|---|
| 1167 | + ndlp->nlp_DID, evt, ndlp->nlp_state, |
|---|
| 1168 | + ndlp->nlp_rpi, ndlp->nlp_flag); |
|---|
| 941 | 1169 | } |
|---|
| 942 | 1170 | return ndlp->nlp_state; |
|---|
| 943 | 1171 | } |
|---|
| .. | .. |
|---|
| 1157 | 1385 | if ((ndlp->nlp_DID != FDMI_DID) && |
|---|
| 1158 | 1386 | (wwn_to_u64(sp->portName.u.wwn) == 0 || |
|---|
| 1159 | 1387 | wwn_to_u64(sp->nodeName.u.wwn) == 0)) { |
|---|
| 1160 | | - lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
|---|
| 1388 | + lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
|---|
| 1161 | 1389 | "0142 PLOGI RSP: Invalid WWN.\n"); |
|---|
| 1162 | 1390 | goto out; |
|---|
| 1163 | 1391 | } |
|---|
| .. | .. |
|---|
| 1219 | 1447 | } else { |
|---|
| 1220 | 1448 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
|---|
| 1221 | 1449 | if (!mbox) { |
|---|
| 1222 | | - lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
|---|
| 1450 | + lpfc_printf_vlog(vport, KERN_ERR, |
|---|
| 1451 | + LOG_TRACE_EVENT, |
|---|
| 1223 | 1452 | "0133 PLOGI: no memory " |
|---|
| 1224 | 1453 | "for config_link " |
|---|
| 1225 | 1454 | "Data: x%x x%x x%x x%x\n", |
|---|
| .. | .. |
|---|
| 1244 | 1473 | |
|---|
| 1245 | 1474 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
|---|
| 1246 | 1475 | if (!mbox) { |
|---|
| 1247 | | - lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
|---|
| 1476 | + lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
|---|
| 1248 | 1477 | "0018 PLOGI: no memory for reg_login " |
|---|
| 1249 | 1478 | "Data: x%x x%x x%x x%x\n", |
|---|
| 1250 | 1479 | ndlp->nlp_DID, ndlp->nlp_state, |
|---|
| .. | .. |
|---|
| 1265 | 1494 | ndlp->nlp_flag |= NLP_REG_LOGIN_SEND; |
|---|
| 1266 | 1495 | mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; |
|---|
| 1267 | 1496 | } |
|---|
| 1268 | | - mbox->context2 = lpfc_nlp_get(ndlp); |
|---|
| 1497 | + mbox->ctx_ndlp = lpfc_nlp_get(ndlp); |
|---|
| 1269 | 1498 | mbox->vport = vport; |
|---|
| 1270 | 1499 | if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) |
|---|
| 1271 | 1500 | != MBX_NOT_FINISHED) { |
|---|
| .. | .. |
|---|
| 1279 | 1508 | * command |
|---|
| 1280 | 1509 | */ |
|---|
| 1281 | 1510 | lpfc_nlp_put(ndlp); |
|---|
| 1282 | | - mp = (struct lpfc_dmabuf *) mbox->context1; |
|---|
| 1511 | + mp = (struct lpfc_dmabuf *)mbox->ctx_buf; |
|---|
| 1283 | 1512 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
|---|
| 1284 | 1513 | kfree(mp); |
|---|
| 1285 | 1514 | mempool_free(mbox, phba->mbox_mem_pool); |
|---|
| 1286 | 1515 | |
|---|
| 1287 | | - lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
|---|
| 1516 | + lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
|---|
| 1288 | 1517 | "0134 PLOGI: cannot issue reg_login " |
|---|
| 1289 | 1518 | "Data: x%x x%x x%x x%x\n", |
|---|
| 1290 | 1519 | ndlp->nlp_DID, ndlp->nlp_state, |
|---|
| .. | .. |
|---|
| 1292 | 1521 | } else { |
|---|
| 1293 | 1522 | mempool_free(mbox, phba->mbox_mem_pool); |
|---|
| 1294 | 1523 | |
|---|
| 1295 | | - lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
|---|
| 1524 | + lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
|---|
| 1296 | 1525 | "0135 PLOGI: cannot format reg_login " |
|---|
| 1297 | 1526 | "Data: x%x x%x x%x x%x\n", |
|---|
| 1298 | 1527 | ndlp->nlp_DID, ndlp->nlp_state, |
|---|
| .. | .. |
|---|
| 1303 | 1532 | out: |
|---|
| 1304 | 1533 | if (ndlp->nlp_DID == NameServer_DID) { |
|---|
| 1305 | 1534 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
|---|
| 1306 | | - lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
|---|
| 1535 | + lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
|---|
| 1307 | 1536 | "0261 Cannot Register NameServer login\n"); |
|---|
| 1308 | 1537 | } |
|---|
| 1309 | 1538 | |
|---|
| .. | .. |
|---|
| 1341 | 1570 | if (!(phba->pport->load_flag & FC_UNLOADING) && |
|---|
| 1342 | 1571 | !mb->mbxStatus) { |
|---|
| 1343 | 1572 | rpi = pmb->u.mb.un.varWords[0]; |
|---|
| 1344 | | - lpfc_release_rpi(phba, vport, rpi); |
|---|
| 1573 | + lpfc_release_rpi(phba, vport, ndlp, rpi); |
|---|
| 1345 | 1574 | } |
|---|
| 1346 | 1575 | return ndlp->nlp_state; |
|---|
| 1347 | 1576 | } |
|---|
| .. | .. |
|---|
| 1522 | 1751 | } |
|---|
| 1523 | 1752 | } |
|---|
| 1524 | 1753 | |
|---|
| 1525 | | - if (ndlp->nlp_type & NLP_FCP_TARGET) { |
|---|
| 1754 | + if (ndlp->nlp_type & NLP_FCP_TARGET) |
|---|
| 1755 | + ndlp->nlp_fc4_type |= NLP_FC4_FCP; |
|---|
| 1756 | + |
|---|
| 1757 | + if (ndlp->nlp_type & NLP_NVME_TARGET) |
|---|
| 1758 | + ndlp->nlp_fc4_type |= NLP_FC4_NVME; |
|---|
| 1759 | + |
|---|
| 1760 | + if (ndlp->nlp_type & (NLP_FCP_TARGET | NLP_NVME_TARGET)) { |
|---|
| 1526 | 1761 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; |
|---|
| 1527 | 1762 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE); |
|---|
| 1528 | 1763 | } else { |
|---|
| .. | .. |
|---|
| 1642 | 1877 | LPFC_MBOXQ_t *mb; |
|---|
| 1643 | 1878 | LPFC_MBOXQ_t *nextmb; |
|---|
| 1644 | 1879 | struct lpfc_dmabuf *mp; |
|---|
| 1880 | + struct lpfc_nodelist *ns_ndlp; |
|---|
| 1645 | 1881 | |
|---|
| 1646 | 1882 | cmdiocb = (struct lpfc_iocbq *) arg; |
|---|
| 1647 | 1883 | |
|---|
| 1648 | 1884 | /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ |
|---|
| 1649 | 1885 | if ((mb = phba->sli.mbox_active)) { |
|---|
| 1650 | 1886 | if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) && |
|---|
| 1651 | | - (ndlp == (struct lpfc_nodelist *) mb->context2)) { |
|---|
| 1887 | + (ndlp == (struct lpfc_nodelist *)mb->ctx_ndlp)) { |
|---|
| 1652 | 1888 | ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND; |
|---|
| 1653 | 1889 | lpfc_nlp_put(ndlp); |
|---|
| 1654 | | - mb->context2 = NULL; |
|---|
| 1890 | + mb->ctx_ndlp = NULL; |
|---|
| 1655 | 1891 | mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
|---|
| 1656 | 1892 | } |
|---|
| 1657 | 1893 | } |
|---|
| .. | .. |
|---|
| 1659 | 1895 | spin_lock_irq(&phba->hbalock); |
|---|
| 1660 | 1896 | list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { |
|---|
| 1661 | 1897 | if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) && |
|---|
| 1662 | | - (ndlp == (struct lpfc_nodelist *) mb->context2)) { |
|---|
| 1663 | | - mp = (struct lpfc_dmabuf *) (mb->context1); |
|---|
| 1898 | + (ndlp == (struct lpfc_nodelist *)mb->ctx_ndlp)) { |
|---|
| 1899 | + mp = (struct lpfc_dmabuf *)(mb->ctx_buf); |
|---|
| 1664 | 1900 | if (mp) { |
|---|
| 1665 | 1901 | __lpfc_mbuf_free(phba, mp->virt, mp->phys); |
|---|
| 1666 | 1902 | kfree(mp); |
|---|
| .. | .. |
|---|
| 1673 | 1909 | } |
|---|
| 1674 | 1910 | } |
|---|
| 1675 | 1911 | spin_unlock_irq(&phba->hbalock); |
|---|
| 1912 | + |
|---|
| 1913 | + /* software abort if any GID_FT is outstanding */ |
|---|
| 1914 | + if (vport->cfg_enable_fc4_type != LPFC_ENABLE_FCP) { |
|---|
| 1915 | + ns_ndlp = lpfc_findnode_did(vport, NameServer_DID); |
|---|
| 1916 | + if (ns_ndlp && NLP_CHK_NODE_ACT(ns_ndlp)) |
|---|
| 1917 | + lpfc_els_abort(phba, ns_ndlp); |
|---|
| 1918 | + } |
|---|
| 1676 | 1919 | |
|---|
| 1677 | 1920 | lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO); |
|---|
| 1678 | 1921 | return ndlp->nlp_state; |
|---|
| .. | .. |
|---|
| 1714 | 1957 | LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg; |
|---|
| 1715 | 1958 | MAILBOX_t *mb = &pmb->u.mb; |
|---|
| 1716 | 1959 | uint32_t did = mb->un.varWords[1]; |
|---|
| 1717 | | - int rc = 0; |
|---|
| 1718 | 1960 | |
|---|
| 1719 | 1961 | if (mb->mbxStatus) { |
|---|
| 1720 | 1962 | /* RegLogin failed */ |
|---|
| 1721 | | - lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, |
|---|
| 1722 | | - "0246 RegLogin failed Data: x%x x%x x%x x%x " |
|---|
| 1963 | + lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
|---|
| 1964 | + "0246 RegLogin failed Data: x%x x%x x%x x%x " |
|---|
| 1723 | 1965 | "x%x\n", |
|---|
| 1724 | 1966 | did, mb->mbxStatus, vport->port_state, |
|---|
| 1725 | 1967 | mb->un.varRegLogin.vpi, |
|---|
| .. | .. |
|---|
| 1769 | 2011 | * is configured try it. |
|---|
| 1770 | 2012 | */ |
|---|
| 1771 | 2013 | ndlp->nlp_fc4_type |= NLP_FC4_FCP; |
|---|
| 1772 | | - if ((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) || |
|---|
| 1773 | | - (phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) { |
|---|
| 2014 | + if ((!(vport->fc_flag & FC_PT2PT_NO_NVME)) && |
|---|
| 2015 | + (vport->cfg_enable_fc4_type == LPFC_ENABLE_BOTH || |
|---|
| 2016 | + vport->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) { |
|---|
| 1774 | 2017 | ndlp->nlp_fc4_type |= NLP_FC4_NVME; |
|---|
| 1775 | 2018 | /* We need to update the localport also */ |
|---|
| 1776 | 2019 | lpfc_nvme_update_localport(vport); |
|---|
| .. | .. |
|---|
| 1780 | 2023 | ndlp->nlp_fc4_type |= NLP_FC4_FCP; |
|---|
| 1781 | 2024 | |
|---|
| 1782 | 2025 | } else if (ndlp->nlp_fc4_type == 0) { |
|---|
| 1783 | | - rc = lpfc_ns_cmd(vport, SLI_CTNS_GFT_ID, |
|---|
| 1784 | | - 0, ndlp->nlp_DID); |
|---|
| 1785 | | - return ndlp->nlp_state; |
|---|
| 2026 | + /* If we are only configured for FCP, the driver |
|---|
| 2027 | + * should just issue PRLI for FCP. Otherwise issue |
|---|
| 2028 | + * GFT_ID to determine if remote port supports NVME. |
|---|
| 2029 | + */ |
|---|
| 2030 | + if (vport->cfg_enable_fc4_type != LPFC_ENABLE_FCP) { |
|---|
| 2031 | + lpfc_ns_cmd(vport, SLI_CTNS_GFT_ID, 0, |
|---|
| 2032 | + ndlp->nlp_DID); |
|---|
| 2033 | + return ndlp->nlp_state; |
|---|
| 2034 | + } |
|---|
| 2035 | + ndlp->nlp_fc4_type = NLP_FC4_FCP; |
|---|
| 1786 | 2036 | } |
|---|
| 1787 | 2037 | |
|---|
| 1788 | 2038 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; |
|---|
| 1789 | 2039 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE); |
|---|
| 1790 | | - lpfc_issue_els_prli(vport, ndlp, 0); |
|---|
| 2040 | + if (lpfc_issue_els_prli(vport, ndlp, 0)) { |
|---|
| 2041 | + lpfc_issue_els_logo(vport, ndlp, 0); |
|---|
| 2042 | + ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; |
|---|
| 2043 | + lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
|---|
| 2044 | + } |
|---|
| 1791 | 2045 | } else { |
|---|
| 1792 | 2046 | if ((vport->fc_flag & FC_PT2PT) && phba->nvmet_support) |
|---|
| 1793 | 2047 | phba->targetport->port_id = vport->fc_myDID; |
|---|
| .. | .. |
|---|
| 1984 | 2238 | /* Complete setting up the remote ndlp personality. */ |
|---|
| 1985 | 2239 | if (bf_get_be32(prli_init, nvpr)) |
|---|
| 1986 | 2240 | ndlp->nlp_type |= NLP_NVME_INITIATOR; |
|---|
| 2241 | + |
|---|
| 2242 | + if (phba->nsler && bf_get_be32(prli_nsler, nvpr) && |
|---|
| 2243 | + bf_get_be32(prli_conf, nvpr)) |
|---|
| 2244 | + |
|---|
| 2245 | + ndlp->nlp_nvme_info |= NLP_NVME_NSLER; |
|---|
| 2246 | + else |
|---|
| 2247 | + ndlp->nlp_nvme_info &= ~NLP_NVME_NSLER; |
|---|
| 1987 | 2248 | |
|---|
| 1988 | 2249 | /* Target driver cannot solicit NVME FB. */ |
|---|
| 1989 | 2250 | if (bf_get_be32(prli_tgt, nvpr)) { |
|---|
| .. | .. |
|---|
| 2864 | 3125 | uint32_t(*func) (struct lpfc_vport *, struct lpfc_nodelist *, void *, |
|---|
| 2865 | 3126 | uint32_t); |
|---|
| 2866 | 3127 | uint32_t got_ndlp = 0; |
|---|
| 3128 | + uint32_t data1; |
|---|
| 2867 | 3129 | |
|---|
| 2868 | 3130 | if (lpfc_nlp_get(ndlp)) |
|---|
| 2869 | 3131 | got_ndlp = 1; |
|---|
| 2870 | 3132 | |
|---|
| 2871 | 3133 | cur_state = ndlp->nlp_state; |
|---|
| 2872 | 3134 | |
|---|
| 3135 | + data1 = (((uint32_t)ndlp->nlp_fc4_type << 16) | |
|---|
| 3136 | + ((uint32_t)ndlp->nlp_type)); |
|---|
| 2873 | 3137 | /* DSM in event <evt> on NPort <nlp_DID> in state <cur_state> */ |
|---|
| 2874 | 3138 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, |
|---|
| 2875 | 3139 | "0211 DSM in event x%x on NPort x%x in " |
|---|
| 2876 | | - "state %d Data: x%x x%x\n", |
|---|
| 2877 | | - evt, ndlp->nlp_DID, cur_state, |
|---|
| 2878 | | - ndlp->nlp_flag, ndlp->nlp_fc4_type); |
|---|
| 3140 | + "state %d rpi x%x Data: x%x x%x\n", |
|---|
| 3141 | + evt, ndlp->nlp_DID, cur_state, ndlp->nlp_rpi, |
|---|
| 3142 | + ndlp->nlp_flag, data1); |
|---|
| 2879 | 3143 | |
|---|
| 2880 | 3144 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM, |
|---|
| 2881 | 3145 | "DSM in: evt:%d ste:%d did:x%x", |
|---|
| .. | .. |
|---|
| 2886 | 3150 | |
|---|
| 2887 | 3151 | /* DSM out state <rc> on NPort <nlp_DID> */ |
|---|
| 2888 | 3152 | if (got_ndlp) { |
|---|
| 3153 | + data1 = (((uint32_t)ndlp->nlp_fc4_type << 16) | |
|---|
| 3154 | + ((uint32_t)ndlp->nlp_type)); |
|---|
| 2889 | 3155 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, |
|---|
| 2890 | | - "0212 DSM out state %d on NPort x%x Data: x%x\n", |
|---|
| 2891 | | - rc, ndlp->nlp_DID, ndlp->nlp_flag); |
|---|
| 3156 | + "0212 DSM out state %d on NPort x%x " |
|---|
| 3157 | + "rpi x%x Data: x%x x%x\n", |
|---|
| 3158 | + rc, ndlp->nlp_DID, ndlp->nlp_rpi, ndlp->nlp_flag, |
|---|
| 3159 | + data1); |
|---|
| 2892 | 3160 | |
|---|
| 2893 | 3161 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM, |
|---|
| 2894 | 3162 | "DSM out: ste:%d did:x%x flg:x%x", |
|---|