^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*******************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * This file is part of the Emulex Linux Device Driver for *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Fibre Channel Host Bus Adapters. *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2004-2016 Emulex. All rights reserved. *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * EMULEX and SLI are trademarks of Emulex. *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * www.broadcom.com *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Portions Copyright (C) 2004-2005 Christoph Hellwig *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * This program is free software; you can redistribute it and/or *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * modify it under the terms of version 2 of the GNU General *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Public License as published by the Free Software Foundation. *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * This program is distributed in the hope that it will be useful. *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * TO BE LEGALLY INVALID. See the GNU General Public License for *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * more details, a copy of which can be found in the file COPYING *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * included with this package. *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *******************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /* See Fibre Channel protocol T11 FC-LS for details */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <scsi/scsi_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <scsi/scsi_transport_fc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <uapi/scsi/fc/fc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <uapi/scsi/fc/fc_els.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include "lpfc_hw4.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include "lpfc_hw.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include "lpfc_sli.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include "lpfc_sli4.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include "lpfc_nl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include "lpfc_disc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include "lpfc_scsi.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include "lpfc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include "lpfc_logmsg.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include "lpfc_crtn.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include "lpfc_vport.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include "lpfc_debugfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static int lpfc_els_retry(struct lpfc_hba *, struct lpfc_iocbq *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct lpfc_iocbq *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static void lpfc_cmpl_fabric_iocb(struct lpfc_hba *, struct lpfc_iocbq *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct lpfc_iocbq *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static void lpfc_fabric_abort_vport(struct lpfc_vport *vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static int lpfc_issue_els_fdisc(struct lpfc_vport *vport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct lpfc_nodelist *ndlp, uint8_t retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static int lpfc_issue_fabric_iocb(struct lpfc_hba *phba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct lpfc_iocbq *iocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static int lpfc_max_els_tries = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * lpfc_els_chk_latt - Check host link attention event for a vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * This routine checks whether there is an outstanding host link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * attention event during the discovery process with the @vport. It is done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * by reading the HBA's Host Attention (HA) register. If there is any host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * link attention events during this @vport's discovery process, the @vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * shall be marked as FC_ABORT_DISCOVERY, a host link attention clear shall
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * be issued if the link state is not already in host link cleared state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * and a return code shall indicate whether the host link attention event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * had happened.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * Note that, if either the host link is in state LPFC_LINK_DOWN or @vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * state in LPFC_VPORT_READY, the request for checking host link attention
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * event will be ignored and a return code shall indicate no host link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * attention event had happened.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * Return codes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * 0 - no host link attention event happened
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * 1 - host link attention event happened
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) lpfc_els_chk_latt(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) uint32_t ha_copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (vport->port_state >= LPFC_VPORT_READY ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) phba->link_state == LPFC_LINK_DOWN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) phba->sli_rev > LPFC_SLI_REV3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /* Read the HBA Host Attention Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (lpfc_readl(phba->HAregaddr, &ha_copy))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (!(ha_copy & HA_LATT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* Pending Link Event during Discovery */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) "0237 Pending Link Event during "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) "Discovery: State x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) phba->pport->port_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* CLEAR_LA should re-enable link attention events and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * we should then immediately take a LATT event. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * LATT processing should call lpfc_linkdown() which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * will cleanup any left over in-progress discovery
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) vport->fc_flag |= FC_ABORT_DISCOVERY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (phba->link_state != LPFC_CLEAR_LA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) lpfc_issue_clear_la(phba, vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * lpfc_prep_els_iocb - Allocate and prepare a lpfc iocb data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * @expectRsp: flag indicating whether response is expected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * @cmdSize: size of the ELS command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * @retry: number of retries to the command IOCB when it fails.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * @did: destination identifier.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * @elscmd: the ELS command code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * This routine is used for allocating a lpfc-IOCB data structure from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * the driver lpfc-IOCB free-list and prepare the IOCB with the parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * passed into the routine for discovery state machine to issue an Extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * Link Service (ELS) commands. It is a generic lpfc-IOCB allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * and preparation routine that is used by all the discovery state machine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * routines and the ELS command-specific fields will be later set up by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * the individual discovery machine routines after calling this routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * allocating and preparing a generic IOCB data structure. It fills in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * Buffer Descriptor Entries (BDEs), allocates buffers for both command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * payload and response payload (if expected). The reference count on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * ndlp is incremented by 1 and the reference to the ndlp is put into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * context1 of the IOCB data structure for this IOCB to hold the ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * reference for the command's callback function to access later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * Pointer to the newly allocated/prepared els iocb data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * NULL - when els iocb data structure allocation/preparation failed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct lpfc_iocbq *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) uint16_t cmdSize, uint8_t retry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct lpfc_nodelist *ndlp, uint32_t did,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) uint32_t elscmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct lpfc_iocbq *elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct lpfc_dmabuf *pcmd, *prsp, *pbuflist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct ulp_bde64 *bpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) IOCB_t *icmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (!lpfc_is_link_up(phba))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* Allocate buffer for command iocb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) elsiocb = lpfc_sli_get_iocbq(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (elsiocb == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * If this command is for fabric controller and HBA running
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * in FIP mode send FLOGI, FDISC and LOGO as FIP frames.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if ((did == Fabric_DID) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) (phba->hba_flag & HBA_FIP_SUPPORT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) ((elscmd == ELS_CMD_FLOGI) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) (elscmd == ELS_CMD_FDISC) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) (elscmd == ELS_CMD_LOGO)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) switch (elscmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) case ELS_CMD_FLOGI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) elsiocb->iocb_flag |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) ((LPFC_ELS_ID_FLOGI << LPFC_FIP_ELS_ID_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) & LPFC_FIP_ELS_ID_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) case ELS_CMD_FDISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) elsiocb->iocb_flag |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) ((LPFC_ELS_ID_FDISC << LPFC_FIP_ELS_ID_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) & LPFC_FIP_ELS_ID_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) case ELS_CMD_LOGO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) elsiocb->iocb_flag |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) ((LPFC_ELS_ID_LOGO << LPFC_FIP_ELS_ID_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) & LPFC_FIP_ELS_ID_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) elsiocb->iocb_flag &= ~LPFC_FIP_ELS_ID_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) icmd = &elsiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /* fill in BDEs for command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /* Allocate buffer for command payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) pcmd = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (pcmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) pcmd->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &pcmd->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (!pcmd || !pcmd->virt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) goto els_iocb_free_pcmb_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) INIT_LIST_HEAD(&pcmd->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /* Allocate buffer for response payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (expectRsp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) prsp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (prsp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) prsp->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) &prsp->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (!prsp || !prsp->virt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) goto els_iocb_free_prsp_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) INIT_LIST_HEAD(&prsp->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) prsp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /* Allocate buffer for Buffer ptr list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) pbuflist = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (pbuflist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) &pbuflist->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (!pbuflist || !pbuflist->virt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) goto els_iocb_free_pbuf_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) INIT_LIST_HEAD(&pbuflist->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (expectRsp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) icmd->un.elsreq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) icmd->un.elsreq64.bdl.addrLow = putPaddrLow(pbuflist->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof(struct ulp_bde64));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) icmd->un.elsreq64.remoteID = did; /* DID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) icmd->ulpCommand = CMD_ELS_REQUEST64_CR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (elscmd == ELS_CMD_FLOGI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) icmd->ulpTimeout = FF_DEF_RATOV * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) else if (elscmd == ELS_CMD_LOGO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) icmd->ulpTimeout = phba->fc_ratov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) icmd->ulpTimeout = phba->fc_ratov * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) icmd->un.xseq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) icmd->un.xseq64.bdl.addrLow = putPaddrLow(pbuflist->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) icmd->un.xseq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) icmd->un.xseq64.bdl.bdeSize = sizeof(struct ulp_bde64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) icmd->un.xseq64.xmit_els_remoteID = did; /* DID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) icmd->ulpCommand = CMD_XMIT_ELS_RSP64_CX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) icmd->ulpBdeCount = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) icmd->ulpLe = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) icmd->ulpClass = CLASS3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * If we have NPIV enabled, we want to send ELS traffic by VPI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * For SLI4, since the driver controls VPIs we also want to include
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * all ELS pt2pt protocol traffic as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ((phba->sli_rev == LPFC_SLI_REV4) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) (vport->fc_flag & FC_PT2PT))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (expectRsp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) icmd->un.elsreq64.myID = vport->fc_myDID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /* For ELS_REQUEST64_CR, use the VPI by default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) icmd->ulpContext = phba->vpi_ids[vport->vpi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) icmd->ulpCt_h = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) /* The CT field must be 0=INVALID_RPI for the ECHO cmd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (elscmd == ELS_CMD_ECHO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) icmd->ulpCt_l = 0; /* context = invalid RPI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) icmd->ulpCt_l = 1; /* context = VPI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) bpl = (struct ulp_bde64 *) pbuflist->virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) bpl->addrLow = le32_to_cpu(putPaddrLow(pcmd->phys));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) bpl->addrHigh = le32_to_cpu(putPaddrHigh(pcmd->phys));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) bpl->tus.f.bdeSize = cmdSize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) bpl->tus.f.bdeFlags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) bpl->tus.w = le32_to_cpu(bpl->tus.w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (expectRsp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) bpl++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) bpl->addrLow = le32_to_cpu(putPaddrLow(prsp->phys));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) bpl->addrHigh = le32_to_cpu(putPaddrHigh(prsp->phys));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) bpl->tus.f.bdeSize = FCELSSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) bpl->tus.w = le32_to_cpu(bpl->tus.w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /* prevent preparing iocb with NULL ndlp reference */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) elsiocb->context1 = lpfc_nlp_get(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (!elsiocb->context1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) goto els_iocb_free_pbuf_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) elsiocb->context2 = pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) elsiocb->context3 = pbuflist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) elsiocb->retry = retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) elsiocb->vport = vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) elsiocb->drvrTimeout = (phba->fc_ratov << 1) + LPFC_DRVR_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (prsp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) list_add(&prsp->list, &pcmd->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (expectRsp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /* Xmit ELS command <elsCmd> to remote NPORT <did> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) "0116 Xmit ELS command x%x to remote "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) "NPORT x%x I/O tag: x%x, port state:x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) "rpi x%x fc_flag:x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) elscmd, did, elsiocb->iotag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) vport->port_state, ndlp->nlp_rpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) vport->fc_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /* Xmit ELS response <elsCmd> to remote NPORT <did> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) "0117 Xmit ELS response x%x to remote "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) "NPORT x%x I/O tag: x%x, size: x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) "port_state x%x rpi x%x fc_flag x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) elscmd, ndlp->nlp_DID, elsiocb->iotag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) cmdSize, vport->port_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) ndlp->nlp_rpi, vport->fc_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) els_iocb_free_pbuf_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (expectRsp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) kfree(pbuflist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) els_iocb_free_prsp_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) kfree(prsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) els_iocb_free_pcmb_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) kfree(pcmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) lpfc_sli_release_iocbq(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * lpfc_issue_fabric_reglogin - Issue fabric registration login for a vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * This routine issues a fabric registration login for a @vport. An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * active ndlp node with Fabric_DID must already exist for this @vport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * The routine invokes two mailbox commands to carry out fabric registration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * login through the HBA firmware: the first mailbox command requests the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * HBA to perform link configuration for the @vport; and the second mailbox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * command requests the HBA to perform the actual fabric registration login
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * with the @vport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * 0 - successfully issued fabric registration login for @vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * -ENXIO -- failed to issue fabric registration login for @vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) lpfc_issue_fabric_reglogin(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) LPFC_MBOXQ_t *mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct lpfc_dmabuf *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) struct serv_parm *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) sp = &phba->fc_fabparam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) ndlp = lpfc_findnode_did(vport, Fabric_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) err = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (!mbox) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) err = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) vport->port_state = LPFC_FABRIC_CFG_LINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) lpfc_config_link(phba, mbox);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) mbox->vport = vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (rc == MBX_NOT_FINISHED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) err = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) goto fail_free_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (!mbox) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) err = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) rc = lpfc_reg_rpi(phba, vport->vpi, Fabric_DID, (uint8_t *)sp, mbox,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) ndlp->nlp_rpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) err = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) goto fail_free_mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) mbox->vport = vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /* increment the reference count on ndlp to hold reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * for the callback routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) mbox->ctx_ndlp = lpfc_nlp_get(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (rc == MBX_NOT_FINISHED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) err = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) goto fail_issue_reg_login;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) fail_issue_reg_login:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /* decrement the reference count on ndlp just incremented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * for the failed mbox command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) mp = (struct lpfc_dmabuf *)mbox->ctx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) lpfc_mbuf_free(phba, mp->virt, mp->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) kfree(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) fail_free_mbox:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) mempool_free(mbox, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) lpfc_vport_set_state(vport, FC_VPORT_FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) "0249 Cannot issue Register Fabric login: Err %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * lpfc_issue_reg_vfi - Register VFI for this vport's fabric login
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * This routine issues a REG_VFI mailbox for the vfi, vpi, fcfi triplet for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) * the @vport. This mailbox command is necessary for SLI4 port only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * 0 - successfully issued REG_VFI for @vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * A failure code otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) lpfc_issue_reg_vfi(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) LPFC_MBOXQ_t *mboxq = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) struct lpfc_dmabuf *dmabuf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) /* move forward in case of SLI4 FC port loopback test and pt2pt mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if ((phba->sli_rev == LPFC_SLI_REV4) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) !(phba->link_flag & LS_LOOPBACK_MODE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) !(vport->fc_flag & FC_PT2PT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) ndlp = lpfc_findnode_did(vport, Fabric_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (!mboxq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* Supply CSP's only if we are fabric connect or pt-to-pt connect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if ((vport->fc_flag & FC_FABRIC) || (vport->fc_flag & FC_PT2PT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (!dmabuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) dmabuf->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &dmabuf->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (!dmabuf->virt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) memcpy(dmabuf->virt, &phba->fc_fabparam,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) sizeof(struct serv_parm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) vport->port_state = LPFC_FABRIC_CFG_LINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (dmabuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) lpfc_reg_vfi(mboxq, vport, dmabuf->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) lpfc_reg_vfi(mboxq, vport, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) mboxq->mbox_cmpl = lpfc_mbx_cmpl_reg_vfi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) mboxq->vport = vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) mboxq->ctx_buf = dmabuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (rc == MBX_NOT_FINISHED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) rc = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (mboxq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) mempool_free(mboxq, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (dmabuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (dmabuf->virt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) kfree(dmabuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) lpfc_vport_set_state(vport, FC_VPORT_FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) "0289 Issue Register VFI failed: Err %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) * lpfc_issue_unreg_vfi - Unregister VFI for this vport's fabric login
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * This routine issues a UNREG_VFI mailbox with the vfi, vpi, fcfi triplet for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) * the @vport. This mailbox command is necessary for SLI4 port only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * 0 - successfully issued REG_VFI for @vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * A failure code otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) lpfc_issue_unreg_vfi(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) struct Scsi_Host *shost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) LPFC_MBOXQ_t *mboxq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (!mboxq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) "2556 UNREG_VFI mbox allocation failed"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) "HBA state x%x\n", phba->pport->port_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) lpfc_unreg_vfi(mboxq, vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) mboxq->vport = vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) mboxq->mbox_cmpl = lpfc_unregister_vfi_cmpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) if (rc == MBX_NOT_FINISHED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) "2557 UNREG_VFI issue mbox failed rc x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) "HBA state x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) rc, phba->pport->port_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) mempool_free(mboxq, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) vport->fc_flag &= ~FC_VFI_REGISTERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) * lpfc_check_clean_addr_bit - Check whether assigned FCID is clean.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) * @sp: pointer to service parameter data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) * This routine is called from FLOGI/FDISC completion handler functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) * lpfc_check_clean_addr_bit return 1 when FCID/Fabric portname/ Fabric
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) * node nodename is changed in the completion service parameter else return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) * 0. This function also set flag in the vport data structure to delay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) * NP_Port discovery after the FLOGI/FDISC completion if Clean address bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) * in FLOGI/FDISC response is cleared and FCID/Fabric portname/ Fabric
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) * node nodename is changed in the completion service parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) * 0 - FCID and Fabric Nodename and Fabric portname is not changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) * 1 - FCID or Fabric Nodename or Fabric portname is changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) static uint8_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) lpfc_check_clean_addr_bit(struct lpfc_vport *vport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) struct serv_parm *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) uint8_t fabric_param_changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if ((vport->fc_prevDID != vport->fc_myDID) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) memcmp(&vport->fabric_portname, &sp->portName,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) sizeof(struct lpfc_name)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) memcmp(&vport->fabric_nodename, &sp->nodeName,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) sizeof(struct lpfc_name)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) (vport->vport_flag & FAWWPN_PARAM_CHG)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) fabric_param_changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) vport->vport_flag &= ~FAWWPN_PARAM_CHG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * Word 1 Bit 31 in common service parameter is overloaded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * Word 1 Bit 31 in FLOGI request is multiple NPort request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) * Word 1 Bit 31 in FLOGI response is clean address bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * If fabric parameter is changed and clean address bit is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * cleared delay nport discovery if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) * - vport->fc_prevDID != 0 (not initial discovery) OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) * - lpfc_delay_discovery module parameter is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (fabric_param_changed && !sp->cmn.clean_address_bit &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) (vport->fc_prevDID || phba->cfg_delay_discovery)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) vport->fc_flag |= FC_DISC_DELAYED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return fabric_param_changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) * lpfc_cmpl_els_flogi_fabric - Completion function for flogi to a fabric port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) * @sp: pointer to service parameter data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) * @irsp: pointer to the IOCB within the lpfc response IOCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) * This routine is invoked by the lpfc_cmpl_els_flogi() completion callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * function to handle the completion of a Fabric Login (FLOGI) into a fabric
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) * port in a fabric topology. It properly sets up the parameters to the @ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * from the IOCB response. It also check the newly assigned N_Port ID to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) * @vport against the previously assigned N_Port ID. If it is different from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) * the previously assigned Destination ID (DID), the lpfc_unreg_rpi() routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) * is invoked on all the remaining nodes with the @vport to unregister the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) * Remote Port Indicators (RPIs). Finally, the lpfc_issue_fabric_reglogin()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) * is invoked to register login to the fabric.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * 0 - Success (currently, always return 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) struct serv_parm *sp, IOCB_t *irsp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) struct lpfc_nodelist *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) struct lpfc_nodelist *next_np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) uint8_t fabric_param_changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) vport->fc_flag |= FC_FABRIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) phba->fc_edtov = be32_to_cpu(sp->cmn.e_d_tov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (sp->cmn.edtovResolution) /* E_D_TOV ticks are in nanoseconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) phba->fc_edtov = (phba->fc_edtov + 999999) / 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) phba->fc_edtovResol = sp->cmn.edtovResolution;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) phba->fc_ratov = (be32_to_cpu(sp->cmn.w2.r_a_tov) + 999) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) vport->fc_flag |= FC_PUBLIC_LOOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) vport->fc_myDID = irsp->un.ulpWord[4] & Mask_DID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) memcpy(&ndlp->nlp_portname, &sp->portName, sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) memcpy(&ndlp->nlp_nodename, &sp->nodeName, sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) ndlp->nlp_class_sup = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if (sp->cls1.classValid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) ndlp->nlp_class_sup |= FC_COS_CLASS1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (sp->cls2.classValid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) ndlp->nlp_class_sup |= FC_COS_CLASS2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (sp->cls3.classValid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) ndlp->nlp_class_sup |= FC_COS_CLASS3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (sp->cls4.classValid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) ndlp->nlp_class_sup |= FC_COS_CLASS4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) ndlp->nlp_maxframe = ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) sp->cmn.bbRcvSizeLsb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) fabric_param_changed = lpfc_check_clean_addr_bit(vport, sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (fabric_param_changed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) /* Reset FDMI attribute masks based on config parameter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) if (phba->cfg_enable_SmartSAN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) (phba->cfg_fdmi_on == LPFC_FDMI_SUPPORT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) /* Setup appropriate attribute masks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) vport->fdmi_hba_mask = LPFC_FDMI2_HBA_ATTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) if (phba->cfg_enable_SmartSAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) vport->fdmi_port_mask = LPFC_FDMI2_SMART_ATTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) vport->fdmi_hba_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) vport->fdmi_port_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) memcpy(&vport->fabric_portname, &sp->portName,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) memcpy(&vport->fabric_nodename, &sp->nodeName,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (sp->cmn.response_multiple_NPort) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) lpfc_printf_vlog(vport, KERN_WARNING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) LOG_ELS | LOG_VPORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) "1816 FLOGI NPIV supported, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) "response data 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) sp->cmn.response_multiple_NPort);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) spin_lock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) phba->link_flag |= LS_NPIV_FAB_SUPPORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) /* Because we asked f/w for NPIV it still expects us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) to call reg_vnpid atleast for the physcial host */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) lpfc_printf_vlog(vport, KERN_WARNING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) LOG_ELS | LOG_VPORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) "1817 Fabric does not support NPIV "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) "- configuring single port mode.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) spin_lock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) phba->link_flag &= ~LS_NPIV_FAB_SUPPORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * For FC we need to do some special processing because of the SLI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * Port's default settings of the Common Service Parameters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if ((phba->sli_rev == LPFC_SLI_REV4) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) /* If physical FC port changed, unreg VFI and ALL VPIs / RPIs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (fabric_param_changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) lpfc_unregister_fcf_prep(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) /* This should just update the VFI CSPs*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if (vport->fc_flag & FC_VFI_REGISTERED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) lpfc_issue_reg_vfi(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if (fabric_param_changed &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) !(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) /* If our NportID changed, we need to ensure all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) * remaining NPORTs get unreg_login'ed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) list_for_each_entry_safe(np, next_np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) &vport->fc_nodes, nlp_listp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (!NLP_CHK_NODE_ACT(np))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) if ((np->nlp_state != NLP_STE_NPR_NODE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) !(np->nlp_flag & NLP_NPR_ADISC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) np->nlp_flag &= ~NLP_NPR_ADISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) lpfc_unreg_rpi(vport, np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) lpfc_cleanup_pending_mbox(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (phba->sli_rev == LPFC_SLI_REV4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) lpfc_sli4_unreg_all_rpis(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) lpfc_mbx_unreg_vpi(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) * For SLI3 and SLI4, the VPI needs to be reregistered in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) * response to this fabric parameter change event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) } else if ((phba->sli_rev == LPFC_SLI_REV4) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) !(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) * Driver needs to re-reg VPI in order for f/w
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) * to update the MAC address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) lpfc_register_new_vport(phba, vport, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (phba->sli_rev < LPFC_SLI_REV4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) lpfc_nlp_set_state(vport, ndlp, NLP_STE_REG_LOGIN_ISSUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) lpfc_register_new_vport(phba, vport, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) lpfc_issue_fabric_reglogin(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) ndlp->nlp_type |= NLP_FABRIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if ((!(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) (vport->vpi_state & LPFC_VPI_REGISTERED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) lpfc_start_fdiscs(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) lpfc_do_scr_ns_plogi(phba, vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) } else if (vport->fc_flag & FC_VFI_REGISTERED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) lpfc_issue_init_vpi(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) "3135 Need register VFI: (x%x/%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) vport->fc_prevDID, vport->fc_myDID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) lpfc_issue_reg_vfi(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) * lpfc_cmpl_els_flogi_nport - Completion function for flogi to an N_Port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) * @sp: pointer to service parameter data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) * This routine is invoked by the lpfc_cmpl_els_flogi() completion callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) * function to handle the completion of a Fabric Login (FLOGI) into an N_Port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) * in a point-to-point topology. First, the @vport's N_Port Name is compared
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) * with the received N_Port Name: if the @vport's N_Port Name is greater than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) * the received N_Port Name lexicographically, this node shall assign local
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) * N_Port ID (PT2PT_LocalID: 1) and remote N_Port ID (PT2PT_RemoteID: 2) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) * will send out Port Login (PLOGI) with the N_Port IDs assigned. Otherwise,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) * this node shall just wait for the remote node to issue PLOGI and assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) * N_Port IDs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) * 0 - Success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) * -ENXIO - Fail
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) struct serv_parm *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) LPFC_MBOXQ_t *mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) vport->fc_flag |= FC_PT2PT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) /* If we are pt2pt with another NPort, force NPIV off! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) /* If physical FC port changed, unreg VFI and ALL VPIs / RPIs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if ((phba->sli_rev == LPFC_SLI_REV4) && phba->fc_topology_changed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) lpfc_unregister_fcf_prep(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) vport->fc_flag &= ~FC_VFI_REGISTERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) phba->fc_topology_changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) rc = memcmp(&vport->fc_portname, &sp->portName,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) sizeof(vport->fc_portname));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (rc >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) /* This side will initiate the PLOGI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) vport->fc_flag |= FC_PT2PT_PLOGI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) * N_Port ID cannot be 0, set our Id to LocalID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) * the other side will be RemoteID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) /* not equal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) vport->fc_myDID = PT2PT_LocalID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) /* Decrement ndlp reference count indicating that ndlp can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) * safely released when other references to it are done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) ndlp = lpfc_findnode_did(vport, PT2PT_RemoteID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) if (!ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) * Cannot find existing Fabric ndlp, so allocate a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) * new one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) ndlp = lpfc_nlp_init(vport, PT2PT_RemoteID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) if (!ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) } else if (!NLP_CHK_NODE_ACT(ndlp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) ndlp = lpfc_enable_node(vport, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) NLP_STE_UNUSED_NODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) if(!ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) memcpy(&ndlp->nlp_portname, &sp->portName,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) memcpy(&ndlp->nlp_nodename, &sp->nodeName,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) /* Set state will put ndlp onto node list if not already done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) ndlp->nlp_flag |= NLP_NPR_2B_DISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) if (!mbox)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) lpfc_config_link(phba, mbox);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) mbox->vport = vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (rc == MBX_NOT_FINISHED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) mempool_free(mbox, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) /* This side will wait for the PLOGI, decrement ndlp reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) * count indicating that ndlp can be released when other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) * references to it are done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) /* Start discovery - this should just do CLEAR_LA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) lpfc_disc_start(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) * lpfc_cmpl_els_flogi - Completion callback function for flogi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) * @rspiocb: pointer to lpfc response iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) * This routine is the top-level completion callback function for issuing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) * a Fabric Login (FLOGI) command. If the response IOCB reported error,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) * the lpfc_els_retry() routine shall be invoked to retry the FLOGI. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) * retry has been made (either immediately or delayed with lpfc_els_retry()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) * returning 1), the command IOCB will be released and function returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) * If the retry attempt has been given up (possibly reach the maximum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) * number of retries), one additional decrement of ndlp reference shall be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) * invoked before going out after releasing the command IOCB. This will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) * actually release the remote node (Note, lpfc_els_free_iocb() will also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) * invoke one decrement of ndlp reference count). If no error reported in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) * the IOCB status, the command Port ID field is used to determine whether
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) * this is a point-to-point topology or a fabric topology: if the Port ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) * field is assigned, it is a fabric topology; otherwise, it is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) * point-to-point topology. The routine lpfc_cmpl_els_flogi_fabric() or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) * lpfc_cmpl_els_flogi_nport() shall be invoked accordingly to handle the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) * specific topology completion conditions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) struct lpfc_iocbq *rspiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) struct lpfc_vport *vport = cmdiocb->vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) IOCB_t *irsp = &rspiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) struct lpfc_nodelist *ndlp = cmdiocb->context1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) struct serv_parm *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) uint16_t fcf_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) /* Check to see if link went down during discovery */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (lpfc_els_chk_latt(vport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) /* One additional decrement on node reference count to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) * trigger the release of the node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) "FLOGI cmpl: status:x%x/x%x state:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) irsp->ulpStatus, irsp->un.ulpWord[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) vport->port_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (irsp->ulpStatus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) * In case of FIP mode, perform roundrobin FCF failover
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) * due to new FCF discovery
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) if ((phba->hba_flag & HBA_FIP_SUPPORT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) (phba->fcf.fcf_flag & FCF_DISCOVERY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (phba->link_state < LPFC_LINK_UP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) goto stop_rr_fcf_flogi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) if ((phba->fcoe_cvl_eventtag_attn ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) phba->fcoe_cvl_eventtag) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) IOERR_SLI_ABORTED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) goto stop_rr_fcf_flogi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) phba->fcoe_cvl_eventtag_attn =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) phba->fcoe_cvl_eventtag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) lpfc_printf_log(phba, KERN_WARNING, LOG_FIP | LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) "2611 FLOGI failed on FCF (x%x), "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) "status:x%x/x%x, tmo:x%x, perform "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) "roundrobin FCF failover\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) phba->fcf.current_rec.fcf_indx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) irsp->ulpStatus, irsp->un.ulpWord[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) irsp->ulpTimeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) lpfc_sli4_set_fcf_flogi_fail(phba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) phba->fcf.current_rec.fcf_indx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) fcf_index = lpfc_sli4_fcf_rr_next_index_get(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) rc = lpfc_sli4_fcf_rr_next_proc(vport, fcf_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) stop_rr_fcf_flogi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) /* FLOGI failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) if (!(irsp->ulpStatus == IOSTAT_LOCAL_REJECT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) IOERR_LOOP_OPEN_FAILURE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) "2858 FLOGI failure Status:x%x/x%x TMO"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) ":x%x Data x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) irsp->ulpStatus, irsp->un.ulpWord[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) irsp->ulpTimeout, phba->hba_flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) phba->fcf.fcf_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) /* Check for retry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) if (lpfc_els_retry(phba, cmdiocb, rspiocb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) lpfc_printf_vlog(vport, KERN_WARNING, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) "0150 FLOGI failure Status:x%x/x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) "xri x%x TMO:x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) irsp->ulpStatus, irsp->un.ulpWord[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) cmdiocb->sli4_xritag, irsp->ulpTimeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) /* If this is not a loop open failure, bail out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) if (!(irsp->ulpStatus == IOSTAT_LOCAL_REJECT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) IOERR_LOOP_OPEN_FAILURE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) goto flogifail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) /* FLOGI failed, so there is no fabric */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) FC_PT2PT_NO_NVME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) /* If private loop, then allow max outstanding els to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) * LPFC_MAX_DISC_THREADS (32). Scanning in the case of no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) * alpa map would take too long otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) if (phba->alpa_map[0] == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) vport->cfg_discovery_threads = LPFC_MAX_DISC_THREADS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) if ((phba->sli_rev == LPFC_SLI_REV4) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) (!(vport->fc_flag & FC_VFI_REGISTERED) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) (vport->fc_prevDID != vport->fc_myDID) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) phba->fc_topology_changed)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) if (vport->fc_flag & FC_VFI_REGISTERED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) if (phba->fc_topology_changed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) lpfc_unregister_fcf_prep(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) vport->fc_flag &= ~FC_VFI_REGISTERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) phba->fc_topology_changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) lpfc_sli4_unreg_all_rpis(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) /* Do not register VFI if the driver aborted FLOGI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) if (!lpfc_error_lost_link(irsp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) lpfc_issue_reg_vfi(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) goto flogifail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) vport->fc_flag &= ~FC_VPORT_CVL_RCVD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) vport->fc_flag &= ~FC_VPORT_LOGO_RCVD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) * The FLogI succeeded. Sync the data for the CPU before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) * accessing it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) if (!prsp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) sp = prsp->virt + sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) /* FLOGI completes successfully */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) "0101 FLOGI completes successfully, I/O tag:x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) "xri x%x Data: x%x x%x x%x x%x x%x %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) cmdiocb->iotag, cmdiocb->sli4_xritag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) irsp->un.ulpWord[4], sp->cmn.e_d_tov,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) sp->cmn.w2.r_a_tov, sp->cmn.edtovResolution,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) vport->port_state, vport->fc_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) if (vport->port_state == LPFC_FLOGI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) * If Common Service Parameters indicate Nport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) * we are point to point, if Fport we are Fabric.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) if (sp->cmn.fPort)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) rc = lpfc_cmpl_els_flogi_fabric(vport, ndlp, sp, irsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) else if (!(phba->hba_flag & HBA_FCOE_MODE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) "2831 FLOGI response with cleared Fabric "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) "bit fcf_index 0x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) "Switch Name %02x%02x%02x%02x%02x%02x%02x%02x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) "Fabric Name "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) "%02x%02x%02x%02x%02x%02x%02x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) phba->fcf.current_rec.fcf_indx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) phba->fcf.current_rec.switch_name[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) phba->fcf.current_rec.switch_name[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) phba->fcf.current_rec.switch_name[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) phba->fcf.current_rec.switch_name[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) phba->fcf.current_rec.switch_name[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) phba->fcf.current_rec.switch_name[5],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) phba->fcf.current_rec.switch_name[6],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) phba->fcf.current_rec.switch_name[7],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) phba->fcf.current_rec.fabric_name[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) phba->fcf.current_rec.fabric_name[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) phba->fcf.current_rec.fabric_name[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) phba->fcf.current_rec.fabric_name[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) phba->fcf.current_rec.fabric_name[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) phba->fcf.current_rec.fabric_name[5],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) phba->fcf.current_rec.fabric_name[6],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) phba->fcf.current_rec.fabric_name[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) spin_lock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) phba->hba_flag &= ~(FCF_RR_INPROG | HBA_DEVLOSS_TMO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) phba->fcf.fcf_redisc_attempted = 0; /* reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) /* Mark the FCF discovery process done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) if (phba->hba_flag & HBA_FIP_SUPPORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) lpfc_printf_vlog(vport, KERN_INFO, LOG_FIP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) "2769 FLOGI to FCF (x%x) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) "completed successfully\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) phba->fcf.current_rec.fcf_indx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) spin_lock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) phba->hba_flag &= ~(FCF_RR_INPROG | HBA_DEVLOSS_TMO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) phba->fcf.fcf_redisc_attempted = 0; /* reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) } else if (vport->port_state > LPFC_FLOGI &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) vport->fc_flag & FC_PT2PT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) * In a p2p topology, it is possible that discovery has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) * already progressed, and this completion can be ignored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) * Recheck the indicated topology.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) if (!sp->cmn.fPort)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) flogifail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) spin_lock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) if (!lpfc_error_lost_link(irsp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) /* FLOGI failed, so just use loop map to make discovery list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) lpfc_disc_list_loopmap(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) /* Start discovery */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) lpfc_disc_start(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) } else if (((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) (((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) IOERR_SLI_ABORTED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) IOERR_SLI_DOWN))) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) (phba->link_state != LPFC_CLEAR_LA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) /* If FLOGI failed enable link interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) lpfc_issue_clear_la(phba, vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) lpfc_els_free_iocb(phba, cmdiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) * lpfc_cmpl_els_link_down - Completion callback function for ELS command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) * aborted during a link down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) * @rspiocb: pointer to lpfc response iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) lpfc_cmpl_els_link_down(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) struct lpfc_iocbq *rspiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) IOCB_t *irsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) uint32_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) uint32_t cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) pcmd = (uint32_t *)(((struct lpfc_dmabuf *)cmdiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) cmd = *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) irsp = &rspiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) "6445 ELS completes after LINK_DOWN: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) " Status %x/%x cmd x%x flg x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) irsp->ulpStatus, irsp->un.ulpWord[4], cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) cmdiocb->iocb_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) if (cmdiocb->iocb_flag & LPFC_IO_FABRIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) cmdiocb->iocb_flag &= ~LPFC_IO_FABRIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) atomic_dec(&phba->fabric_iocb_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) lpfc_els_free_iocb(phba, cmdiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) * lpfc_issue_els_flogi - Issue an flogi iocb command for a vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) * @retry: number of retries to the command IOCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) * This routine issues a Fabric Login (FLOGI) Request ELS command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) * for a @vport. The initiator service parameters are put into the payload
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) * of the FLOGI Request IOCB and the top-level callback function pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) * to lpfc_cmpl_els_flogi() routine is put to the IOCB completion callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) * function field. The lpfc_issue_fabric_iocb routine is invoked to send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) * out FLOGI ELS command with one outstanding fabric IOCB at a time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) * will be incremented by 1 for holding the ndlp and the reference to ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) * will be stored into the context1 field of the IOCB for the completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) * callback function to the FLOGI ELS command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) * 0 - successfully issued flogi iocb for @vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) * 1 - failed to issue flogi iocb for @vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) uint8_t retry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) struct serv_parm *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) IOCB_t *icmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) struct lpfc_iocbq *elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) struct lpfc_iocbq defer_flogi_acc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) uint8_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) uint16_t cmdsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) uint32_t tmo, did;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) ndlp->nlp_DID, ELS_CMD_FLOGI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) if (!elsiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) icmd = &elsiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) /* For FLOGI request, remainder of payload is service parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) *((uint32_t *) (pcmd)) = ELS_CMD_FLOGI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) pcmd += sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) memcpy(pcmd, &vport->fc_sparam, sizeof(struct serv_parm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) sp = (struct serv_parm *) pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) /* Setup CSPs accordingly for Fabric */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) sp->cmn.e_d_tov = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) sp->cmn.w2.r_a_tov = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) sp->cmn.virtual_fabric_support = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) sp->cls1.classValid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) if (sp->cmn.fcphLow < FC_PH3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) sp->cmn.fcphLow = FC_PH3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) if (sp->cmn.fcphHigh < FC_PH3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) sp->cmn.fcphHigh = FC_PH3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) if (phba->sli_rev == LPFC_SLI_REV4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) LPFC_SLI_INTF_IF_TYPE_0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) elsiocb->iocb.ulpCt_h = ((SLI4_CT_FCFI >> 1) & 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) elsiocb->iocb.ulpCt_l = (SLI4_CT_FCFI & 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) /* FLOGI needs to be 3 for WQE FCFI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) /* Set the fcfi to the fcfi we registered with */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) elsiocb->iocb.ulpContext = phba->fcf.fcfi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) /* Can't do SLI4 class2 without support sequence coalescing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) sp->cls2.classValid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) sp->cls2.seqDelivery = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) /* Historical, setting sequential-delivery bit for SLI3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) sp->cls2.seqDelivery = (sp->cls2.classValid) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) sp->cls3.seqDelivery = (sp->cls3.classValid) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) sp->cmn.request_multiple_Nport = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) /* For FLOGI, Let FLOGI rsp set the NPortID for VPI 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) icmd->ulpCt_h = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) icmd->ulpCt_l = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) sp->cmn.request_multiple_Nport = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) if (phba->fc_topology != LPFC_TOPOLOGY_LOOP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) icmd->un.elsreq64.myID = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) icmd->un.elsreq64.fl = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) tmo = phba->fc_ratov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) phba->fc_ratov = LPFC_DISC_FLOGI_TMO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) lpfc_set_disctmo(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) phba->fc_ratov = tmo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) phba->fc_stat.elsXmitFLOGI++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) elsiocb->iocb_cmpl = lpfc_cmpl_els_flogi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) "Issue FLOGI: opt:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) phba->sli3_options, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) rc = lpfc_issue_fabric_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) phba->hba_flag |= HBA_FLOGI_ISSUED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) /* Check for a deferred FLOGI ACC condition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) if (phba->defer_flogi_acc_flag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) did = vport->fc_myDID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) vport->fc_myDID = Fabric_DID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) memset(&defer_flogi_acc, 0, sizeof(struct lpfc_iocbq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) defer_flogi_acc.iocb.ulpContext = phba->defer_flogi_acc_rx_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) defer_flogi_acc.iocb.unsli3.rcvsli3.ox_id =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) phba->defer_flogi_acc_ox_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) "3354 Xmit deferred FLOGI ACC: rx_id: x%x,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) " ox_id: x%x, hba_flag x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) phba->defer_flogi_acc_rx_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) phba->defer_flogi_acc_ox_id, phba->hba_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) /* Send deferred FLOGI ACC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) lpfc_els_rsp_acc(vport, ELS_CMD_FLOGI, &defer_flogi_acc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) ndlp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) phba->defer_flogi_acc_flag = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) vport->fc_myDID = did;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) if (rc == IOCB_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) * lpfc_els_abort_flogi - Abort all outstanding flogi iocbs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) * This routine aborts all the outstanding Fabric Login (FLOGI) IOCBs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) * with a @phba. This routine walks all the outstanding IOCBs on the txcmplq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) * list and issues an abort IOCB commond on each outstanding IOCB that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) * contains a active Fabric_DID ndlp. Note that this function is to issue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) * the abort IOCB command on all the outstanding IOCBs, thus when this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) * function returns, it does not guarantee all the IOCBs are actually aborted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) * 0 - Successfully issued abort iocb on all outstanding flogis (Always 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) lpfc_els_abort_flogi(struct lpfc_hba *phba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) struct lpfc_sli_ring *pring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) struct lpfc_iocbq *iocb, *next_iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) IOCB_t *icmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) /* Abort outstanding I/O on NPort <nlp_DID> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) "0201 Abort outstanding I/O on NPort x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) Fabric_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) pring = lpfc_phba_elsring(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) if (unlikely(!pring))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) * Check the txcmplq for an iocb that matches the nport the driver is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) * searching for.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) spin_lock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) icmd = &iocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) ndlp = (struct lpfc_nodelist *)(iocb->context1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) (ndlp->nlp_DID == Fabric_DID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) lpfc_sli_issue_abort_iotag(phba, pring, iocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) * lpfc_initial_flogi - Issue an initial fabric login for a vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) * This routine issues an initial Fabric Login (FLOGI) for the @vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) * specified. It first searches the ndlp with the Fabric_DID (0xfffffe) from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) * the @vport's ndlp list. If no such ndlp found, it will create an ndlp and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) * put it into the @vport's ndlp list. If an inactive ndlp found on the list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) * it will just be enabled and made active. The lpfc_issue_els_flogi() routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) * is then invoked with the @vport and the ndlp to perform the FLOGI for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) * @vport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) * 0 - failed to issue initial flogi for @vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) * 1 - successfully issued initial flogi for @vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) lpfc_initial_flogi(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) vport->port_state = LPFC_FLOGI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) lpfc_set_disctmo(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) /* First look for the Fabric ndlp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) ndlp = lpfc_findnode_did(vport, Fabric_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) if (!ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) /* Cannot find existing Fabric ndlp, so allocate a new one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) ndlp = lpfc_nlp_init(vport, Fabric_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) if (!ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) /* Set the node type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) ndlp->nlp_type |= NLP_FABRIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) /* Put ndlp onto node list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) lpfc_enqueue_node(vport, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) } else if (!NLP_CHK_NODE_ACT(ndlp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) /* re-setup ndlp without removing from node list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) if (!ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) if (lpfc_issue_els_flogi(vport, ndlp, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) /* This decrement of reference count to node shall kick off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) * the release of the node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) * lpfc_initial_fdisc - Issue an initial fabric discovery for a vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) * This routine issues an initial Fabric Discover (FDISC) for the @vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) * specified. It first searches the ndlp with the Fabric_DID (0xfffffe) from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) * the @vport's ndlp list. If no such ndlp found, it will create an ndlp and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) * put it into the @vport's ndlp list. If an inactive ndlp found on the list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) * it will just be enabled and made active. The lpfc_issue_els_fdisc() routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) * is then invoked with the @vport and the ndlp to perform the FDISC for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) * @vport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) * 0 - failed to issue initial fdisc for @vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) * 1 - successfully issued initial fdisc for @vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) lpfc_initial_fdisc(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) /* First look for the Fabric ndlp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) ndlp = lpfc_findnode_did(vport, Fabric_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) if (!ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) /* Cannot find existing Fabric ndlp, so allocate a new one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) ndlp = lpfc_nlp_init(vport, Fabric_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) if (!ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) /* Put ndlp onto node list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) lpfc_enqueue_node(vport, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) } else if (!NLP_CHK_NODE_ACT(ndlp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) /* re-setup ndlp without removing from node list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) if (!ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) if (lpfc_issue_els_fdisc(vport, ndlp, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) /* decrement node reference count to trigger the release of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) * the node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) * lpfc_more_plogi - Check and issue remaining plogis for a vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) * This routine checks whether there are more remaining Port Logins
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) * (PLOGI) to be issued for the @vport. If so, it will invoke the routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) * lpfc_els_disc_plogi() to go through the Node Port Recovery (NPR) nodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) * to issue ELS PLOGIs up to the configured discover threads with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) * @vport (@vport->cfg_discovery_threads). The function also decrement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) * the @vport's num_disc_node by 1 if it is not already 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) lpfc_more_plogi(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) if (vport->num_disc_nodes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) vport->num_disc_nodes--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) /* Continue discovery with <num_disc_nodes> PLOGIs to go */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) "0232 Continue discovery with %d PLOGIs to go "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) "Data: x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) vport->num_disc_nodes, vport->fc_plogi_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) vport->fc_flag, vport->port_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) /* Check to see if there are more PLOGIs to be sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) if (vport->fc_flag & FC_NLP_MORE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) /* go thru NPR nodes and issue any remaining ELS PLOGIs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) lpfc_els_disc_plogi(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) * lpfc_plogi_confirm_nport - Confirm pologi wwpn matches stored ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) * @prsp: pointer to response IOCB payload.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) * This routine checks and indicates whether the WWPN of an N_Port, retrieved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) * from a PLOGI, matches the WWPN that is stored in the @ndlp for that N_POrt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) * The following cases are considered N_Port confirmed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) * 1) The N_Port is a Fabric ndlp; 2) The @ndlp is on vport list and matches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) * the WWPN of the N_Port logged into; 3) The @ndlp is not on vport list but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) * it does not have WWPN assigned either. If the WWPN is confirmed, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) * pointer to the @ndlp will be returned. If the WWPN is not confirmed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) * 1) if there is a node on vport list other than the @ndlp with the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) * WWPN of the N_Port PLOGI logged into, the lpfc_unreg_rpi() will be invoked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) * on that node to release the RPI associated with the node; 2) if there is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) * no node found on vport list with the same WWPN of the N_Port PLOGI logged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) * into, a new node shall be allocated (or activated). In either case, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) * parameters of the @ndlp shall be copied to the new_ndlp, the @ndlp shall
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) * be released and the new_ndlp shall be put on to the vport node list and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) * its pointer returned as the confirmed node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) * Note that before the @ndlp got "released", the keepDID from not-matching
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) * or inactive "new_ndlp" on the vport node list is assigned to the nlp_DID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) * of the @ndlp. This is because the release of @ndlp is actually to put it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) * into an inactive state on the vport node list and the vport node list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) * management algorithm does not allow two node with a same DID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) * pointer to the PLOGI N_Port @ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) static struct lpfc_nodelist *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) struct lpfc_vport *vport = ndlp->vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) struct lpfc_nodelist *new_ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) struct lpfc_rport_data *rdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) struct fc_rport *rport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) struct serv_parm *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) uint8_t name[sizeof(struct lpfc_name)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) uint32_t rc, keepDID = 0, keep_nlp_flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) uint32_t keep_new_nlp_flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) uint16_t keep_nlp_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) u32 keep_nlp_fc4_type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) struct lpfc_nvme_rport *keep_nrport = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) int put_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) int put_rport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) unsigned long *active_rrqs_xri_bitmap = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) /* Fabric nodes can have the same WWPN so we don't bother searching
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) * by WWPN. Just return the ndlp that was given to us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) if (ndlp->nlp_type & NLP_FABRIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) return ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) sp = (struct serv_parm *) ((uint8_t *) prsp + sizeof(uint32_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) memset(name, 0, sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) /* Now we find out if the NPort we are logging into, matches the WWPN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) * we have for that ndlp. If not, we have some work to do.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) new_ndlp = lpfc_findnode_wwpn(vport, &sp->portName);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) /* return immediately if the WWPN matches ndlp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) if (new_ndlp == ndlp && NLP_CHK_NODE_ACT(new_ndlp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) return ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) if (phba->sli_rev == LPFC_SLI_REV4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) active_rrqs_xri_bitmap = mempool_alloc(phba->active_rrq_pool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) if (active_rrqs_xri_bitmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) memset(active_rrqs_xri_bitmap, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) phba->cfg_rrq_xri_bitmap_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS | LOG_NODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) "3178 PLOGI confirm: ndlp x%x x%x x%x: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) "new_ndlp x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_fc4_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) (new_ndlp ? new_ndlp->nlp_DID : 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) (new_ndlp ? new_ndlp->nlp_flag : 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) (new_ndlp ? new_ndlp->nlp_fc4_type : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) if (!new_ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) rc = memcmp(&ndlp->nlp_portname, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) if (active_rrqs_xri_bitmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) mempool_free(active_rrqs_xri_bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) phba->active_rrq_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) return ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) new_ndlp = lpfc_nlp_init(vport, ndlp->nlp_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) if (!new_ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) if (active_rrqs_xri_bitmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) mempool_free(active_rrqs_xri_bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) phba->active_rrq_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) return ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) } else if (!NLP_CHK_NODE_ACT(new_ndlp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) rc = memcmp(&ndlp->nlp_portname, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) if (active_rrqs_xri_bitmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) mempool_free(active_rrqs_xri_bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) phba->active_rrq_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) return ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) new_ndlp = lpfc_enable_node(vport, new_ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) NLP_STE_UNUSED_NODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) if (!new_ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) if (active_rrqs_xri_bitmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) mempool_free(active_rrqs_xri_bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) phba->active_rrq_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) return ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) keepDID = new_ndlp->nlp_DID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) if ((phba->sli_rev == LPFC_SLI_REV4) && active_rrqs_xri_bitmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) memcpy(active_rrqs_xri_bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) new_ndlp->active_rrqs_xri_bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) phba->cfg_rrq_xri_bitmap_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) keepDID = new_ndlp->nlp_DID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) if (phba->sli_rev == LPFC_SLI_REV4 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) active_rrqs_xri_bitmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) memcpy(active_rrqs_xri_bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) new_ndlp->active_rrqs_xri_bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) phba->cfg_rrq_xri_bitmap_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) /* At this point in this routine, we know new_ndlp will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) * returned. however, any previous GID_FTs that were done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) * would have updated nlp_fc4_type in ndlp, so we must ensure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) * new_ndlp has the right value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) if (vport->fc_flag & FC_FABRIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) keep_nlp_fc4_type = new_ndlp->nlp_fc4_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) new_ndlp->nlp_fc4_type = ndlp->nlp_fc4_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) lpfc_unreg_rpi(vport, new_ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) new_ndlp->nlp_DID = ndlp->nlp_DID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) new_ndlp->nlp_prev_state = ndlp->nlp_prev_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) if (phba->sli_rev == LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) memcpy(new_ndlp->active_rrqs_xri_bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) ndlp->active_rrqs_xri_bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) phba->cfg_rrq_xri_bitmap_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) keep_new_nlp_flag = new_ndlp->nlp_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) keep_nlp_flag = ndlp->nlp_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) new_ndlp->nlp_flag = ndlp->nlp_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) /* if new_ndlp had NLP_UNREG_INP set, keep it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) if (keep_new_nlp_flag & NLP_UNREG_INP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) new_ndlp->nlp_flag |= NLP_UNREG_INP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) new_ndlp->nlp_flag &= ~NLP_UNREG_INP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) /* if new_ndlp had NLP_RPI_REGISTERED set, keep it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) if (keep_new_nlp_flag & NLP_RPI_REGISTERED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) new_ndlp->nlp_flag |= NLP_RPI_REGISTERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) new_ndlp->nlp_flag &= ~NLP_RPI_REGISTERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) ndlp->nlp_flag = keep_new_nlp_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) /* if ndlp had NLP_UNREG_INP set, keep it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) if (keep_nlp_flag & NLP_UNREG_INP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) ndlp->nlp_flag |= NLP_UNREG_INP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) ndlp->nlp_flag &= ~NLP_UNREG_INP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) /* if ndlp had NLP_RPI_REGISTERED set, keep it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) if (keep_nlp_flag & NLP_RPI_REGISTERED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) ndlp->nlp_flag |= NLP_RPI_REGISTERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) ndlp->nlp_flag &= ~NLP_RPI_REGISTERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) /* Set nlp_states accordingly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) keep_nlp_state = new_ndlp->nlp_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) lpfc_nlp_set_state(vport, new_ndlp, ndlp->nlp_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) /* interchange the nvme remoteport structs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) keep_nrport = new_ndlp->nrport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) new_ndlp->nrport = ndlp->nrport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) /* Move this back to NPR state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) if (memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) /* The new_ndlp is replacing ndlp totally, so we need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) * to put ndlp on UNUSED list and try to free it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) "3179 PLOGI confirm NEW: %x %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) new_ndlp->nlp_DID, keepDID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) /* Fix up the rport accordingly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) rport = ndlp->rport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) if (rport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) rdata = rport->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) if (rdata->pnode == ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) /* break the link before dropping the ref */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) ndlp->rport = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) rdata->pnode = lpfc_nlp_get(new_ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) new_ndlp->rport = rport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) new_ndlp->nlp_type = ndlp->nlp_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) /* Fix up the nvme rport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) if (ndlp->nrport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) ndlp->nrport = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) /* We shall actually free the ndlp with both nlp_DID and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) * nlp_portname fields equals 0 to avoid any ndlp on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) * nodelist never to be used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) if (ndlp->nlp_DID == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) spin_lock_irq(&phba->ndlp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) NLP_SET_FREE_REQ(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) spin_unlock_irq(&phba->ndlp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) /* Two ndlps cannot have the same did on the nodelist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) * Note: for this case, ndlp has a NULL WWPN so setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) * the nlp_fc4_type isn't required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) ndlp->nlp_DID = keepDID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) lpfc_nlp_set_state(vport, ndlp, keep_nlp_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) if (phba->sli_rev == LPFC_SLI_REV4 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) active_rrqs_xri_bitmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) memcpy(ndlp->active_rrqs_xri_bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) active_rrqs_xri_bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) phba->cfg_rrq_xri_bitmap_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) if (!NLP_CHK_NODE_ACT(ndlp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) lpfc_drop_node(vport, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) "3180 PLOGI confirm SWAP: %x %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) new_ndlp->nlp_DID, keepDID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) lpfc_unreg_rpi(vport, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) /* Two ndlps cannot have the same did and the fc4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) * type must be transferred because the ndlp is in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) * flight.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) ndlp->nlp_DID = keepDID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) ndlp->nlp_fc4_type = keep_nlp_fc4_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) if (phba->sli_rev == LPFC_SLI_REV4 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) active_rrqs_xri_bitmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) memcpy(ndlp->active_rrqs_xri_bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) active_rrqs_xri_bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) phba->cfg_rrq_xri_bitmap_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) /* Since we are switching over to the new_ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) * reset the old ndlp state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) if ((ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) (ndlp->nlp_state == NLP_STE_MAPPED_NODE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) keep_nlp_state = NLP_STE_NPR_NODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) lpfc_nlp_set_state(vport, ndlp, keep_nlp_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) /* Previous ndlp no longer active with nvme host transport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) * Remove reference from earlier registration unless the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) * nvme host took care of it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) if (ndlp->nrport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) ndlp->nrport = keep_nrport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) /* Fix up the rport accordingly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) rport = ndlp->rport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) if (rport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) rdata = rport->dd_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) put_node = rdata->pnode != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) put_rport = ndlp->rport != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) rdata->pnode = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) ndlp->rport = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) if (put_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) if (put_rport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) put_device(&rport->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) if (phba->sli_rev == LPFC_SLI_REV4 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) active_rrqs_xri_bitmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) mempool_free(active_rrqs_xri_bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) phba->active_rrq_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS | LOG_NODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) "3173 PLOGI confirm exit: new_ndlp x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) new_ndlp->nlp_DID, new_ndlp->nlp_flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) new_ndlp->nlp_fc4_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) return new_ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) * lpfc_end_rscn - Check and handle more rscn for a vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) * This routine checks whether more Registration State Change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) * Notifications (RSCNs) came in while the discovery state machine was in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) * the FC_RSCN_MODE. If so, the lpfc_els_handle_rscn() routine will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) * invoked to handle the additional RSCNs for the @vport. Otherwise, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) * FC_RSCN_MODE bit will be cleared with the @vport to mark as the end of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) * handling the RSCNs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) lpfc_end_rscn(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) if (vport->fc_flag & FC_RSCN_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) * Check to see if more RSCNs came in while we were
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) * processing this one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) if (vport->fc_rscn_id_cnt ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) (vport->fc_flag & FC_RSCN_DISCOVERY) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) lpfc_els_handle_rscn(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) vport->fc_flag &= ~FC_RSCN_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) * lpfc_cmpl_els_rrq - Completion handled for els RRQs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) * @rspiocb: pointer to lpfc response iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) * This routine will call the clear rrq function to free the rrq and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) * clear the xri's bit in the ndlp's xri_bitmap. If the ndlp does not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) * exist then the clear_rrq is still called because the rrq needs to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) * be freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) lpfc_cmpl_els_rrq(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) struct lpfc_iocbq *rspiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) struct lpfc_vport *vport = cmdiocb->vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) IOCB_t *irsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) struct lpfc_node_rrq *rrq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) /* we pass cmdiocb to state machine which needs rspiocb as well */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) rrq = cmdiocb->context_un.rrq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) cmdiocb->context_un.rsp_iocb = rspiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) irsp = &rspiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) "RRQ cmpl: status:x%x/x%x did:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) irsp->ulpStatus, irsp->un.ulpWord[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) irsp->un.elsreq64.remoteID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) ndlp = lpfc_findnode_did(vport, irsp->un.elsreq64.remoteID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) if (!ndlp || !NLP_CHK_NODE_ACT(ndlp) || ndlp != rrq->ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) "2882 RRQ completes to NPort x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) "with no ndlp. Data: x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) irsp->un.elsreq64.remoteID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) irsp->ulpStatus, irsp->un.ulpWord[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) irsp->ulpIoTag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) /* rrq completes to NPort <nlp_DID> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) "2880 RRQ completes to NPort x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) "Data: x%x x%x x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) irsp->ulpTimeout, rrq->xritag, rrq->rxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) if (irsp->ulpStatus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) /* Check for retry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) /* RRQ failed Don't print the vport to vport rjts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) if (irsp->ulpStatus != IOSTAT_LS_RJT ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) (((irsp->un.ulpWord[4]) >> 16 != LSRJT_INVALID_CMD) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) ((irsp->un.ulpWord[4]) >> 16 != LSRJT_UNABLE_TPC)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) (phba)->pport->cfg_log_verbose & LOG_ELS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) "2881 RRQ failure DID:%06X Status:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) "x%x/x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) ndlp->nlp_DID, irsp->ulpStatus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) irsp->un.ulpWord[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) if (rrq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) lpfc_clr_rrq_active(phba, rrq->xritag, rrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) lpfc_els_free_iocb(phba, cmdiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) * lpfc_cmpl_els_plogi - Completion callback function for plogi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) * @rspiocb: pointer to lpfc response iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) * This routine is the completion callback function for issuing the Port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) * Login (PLOGI) command. For PLOGI completion, there must be an active
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) * ndlp on the vport node list that matches the remote node ID from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) * PLOGI response IOCB. If such ndlp does not exist, the PLOGI is simply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) * ignored and command IOCB released. The PLOGI response IOCB status is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) * checked for error conditons. If there is error status reported, PLOGI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) * retry shall be attempted by invoking the lpfc_els_retry() routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) * Otherwise, the lpfc_plogi_confirm_nport() routine shall be invoked on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) * the ndlp and the NLP_EVT_CMPL_PLOGI state to the Discover State Machine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) * (DSM) is set for this PLOGI completion. Finally, it checks whether
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) * there are additional N_Port nodes with the vport that need to perform
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) * PLOGI. If so, the lpfc_more_plogi() routine is invoked to issue addition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) * PLOGIs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) struct lpfc_iocbq *rspiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) struct lpfc_vport *vport = cmdiocb->vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) IOCB_t *irsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) struct lpfc_dmabuf *prsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) int disc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) /* we pass cmdiocb to state machine which needs rspiocb as well */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) cmdiocb->context_un.rsp_iocb = rspiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) irsp = &rspiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) "PLOGI cmpl: status:x%x/x%x did:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) irsp->ulpStatus, irsp->un.ulpWord[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) irsp->un.elsreq64.remoteID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) ndlp = lpfc_findnode_did(vport, irsp->un.elsreq64.remoteID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) "0136 PLOGI completes to NPort x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) "with no ndlp. Data: x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) irsp->un.elsreq64.remoteID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) irsp->ulpStatus, irsp->un.ulpWord[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) irsp->ulpIoTag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) /* Since ndlp can be freed in the disc state machine, note if this node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) * is being used during discovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) /* PLOGI completes to NPort <nlp_DID> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) "0102 PLOGI completes to NPort x%06x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) "Data: x%x x%x x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) ndlp->nlp_DID, ndlp->nlp_fc4_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) irsp->ulpStatus, irsp->un.ulpWord[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) disc, vport->num_disc_nodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) /* Check to see if link went down during discovery */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) if (lpfc_els_chk_latt(vport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) ndlp->nlp_flag |= NLP_NPR_2B_DISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) if (irsp->ulpStatus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) /* Check for retry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) /* ELS command is being retried */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) if (disc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) ndlp->nlp_flag |= NLP_NPR_2B_DISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) /* PLOGI failed Don't print the vport to vport rjts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) if (irsp->ulpStatus != IOSTAT_LS_RJT ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) (((irsp->un.ulpWord[4]) >> 16 != LSRJT_INVALID_CMD) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) ((irsp->un.ulpWord[4]) >> 16 != LSRJT_UNABLE_TPC)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) (phba)->pport->cfg_log_verbose & LOG_ELS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) "2753 PLOGI failure DID:%06X Status:x%x/x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) ndlp->nlp_DID, irsp->ulpStatus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) irsp->un.ulpWord[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) if (!lpfc_error_lost_link(irsp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) lpfc_disc_state_machine(vport, ndlp, cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) NLP_EVT_CMPL_PLOGI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) /* Good status, call state machine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) prsp = list_entry(((struct lpfc_dmabuf *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) cmdiocb->context2)->list.next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) struct lpfc_dmabuf, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) ndlp = lpfc_plogi_confirm_nport(phba, prsp->virt, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) lpfc_disc_state_machine(vport, ndlp, cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) NLP_EVT_CMPL_PLOGI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) if (disc && vport->num_disc_nodes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) /* Check to see if there are more PLOGIs to be sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) lpfc_more_plogi(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) if (vport->num_disc_nodes == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) vport->fc_flag &= ~FC_NDISC_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) lpfc_can_disctmo(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) lpfc_end_rscn(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) lpfc_els_free_iocb(phba, cmdiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) * lpfc_issue_els_plogi - Issue an plogi iocb command for a vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) * @did: destination port identifier.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) * @retry: number of retries to the command IOCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) * This routine issues a Port Login (PLOGI) command to a remote N_Port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) * (with the @did) for a @vport. Before issuing a PLOGI to a remote N_Port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) * the ndlp with the remote N_Port DID must exist on the @vport's ndlp list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) * This routine constructs the proper feilds of the PLOGI IOCB and invokes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) * the lpfc_sli_issue_iocb() routine to send out PLOGI ELS command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) * will be incremented by 1 for holding the ndlp and the reference to ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) * will be stored into the context1 field of the IOCB for the completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) * callback function to the PLOGI ELS command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) * 0 - Successfully issued a plogi for @vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) * 1 - failed to issue a plogi for @vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) struct Scsi_Host *shost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) struct serv_parm *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) struct lpfc_iocbq *elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) uint8_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) uint16_t cmdsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) ndlp = lpfc_findnode_did(vport, did);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) if (ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) /* Defer the processing of the issue PLOGI until after the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) * outstanding UNREG_RPI mbox command completes, unless we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) * are going offline. This logic does not apply for Fabric DIDs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) if ((ndlp->nlp_flag & NLP_UNREG_INP) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) ((ndlp->nlp_DID & Fabric_DID_MASK) != Fabric_DID_MASK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) !(vport->fc_flag & FC_OFFLINE_MODE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) "4110 Issue PLOGI x%x deferred "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) "on NPort x%x rpi x%x Data: x%px\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) ndlp->nlp_defer_did, ndlp->nlp_DID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) ndlp->nlp_rpi, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) /* We can only defer 1st PLOGI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) if (ndlp->nlp_defer_did == NLP_EVT_NOTHING_PENDING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) ndlp->nlp_defer_did = did;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) if (!NLP_CHK_NODE_ACT(ndlp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) ndlp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) /* If ndlp is not NULL, we will bump the reference count on it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) ELS_CMD_PLOGI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) if (!elsiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) ndlp->nlp_flag &= ~NLP_FCP_PRLI_RJT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) /* For PLOGI request, remainder of payload is service parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) *((uint32_t *) (pcmd)) = ELS_CMD_PLOGI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) pcmd += sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) memcpy(pcmd, &vport->fc_sparam, sizeof(struct serv_parm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) sp = (struct serv_parm *) pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) * If we are a N-port connected to a Fabric, fix-up paramm's so logins
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) * to device on remote loops work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) if ((vport->fc_flag & FC_FABRIC) && !(vport->fc_flag & FC_PUBLIC_LOOP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) sp->cmn.altBbCredit = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) if (sp->cmn.fcphLow < FC_PH_4_3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) sp->cmn.fcphLow = FC_PH_4_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) if (sp->cmn.fcphHigh < FC_PH3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) sp->cmn.fcphHigh = FC_PH3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) sp->cmn.valid_vendor_ver_level = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) memset(sp->un.vendorVersion, 0, sizeof(sp->un.vendorVersion));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) sp->cmn.bbRcvSizeMsb &= 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) "Issue PLOGI: did:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) did, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) /* If our firmware supports this feature, convey that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) * information to the target using the vendor specific field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) if (phba->sli.sli_flag & LPFC_SLI_SUPPRESS_RSP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) sp->cmn.valid_vendor_ver_level = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) sp->un.vv.vid = cpu_to_be32(LPFC_VV_EMLX_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) sp->un.vv.flags = cpu_to_be32(LPFC_VV_SUPPRESS_RSP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) phba->fc_stat.elsXmitPLOGI++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) elsiocb->iocb_cmpl = lpfc_cmpl_els_plogi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) ret = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) if (ret == IOCB_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) * lpfc_cmpl_els_prli - Completion callback function for prli
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) * @rspiocb: pointer to lpfc response iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) * This routine is the completion callback function for a Process Login
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) * (PRLI) ELS command. The PRLI response IOCB status is checked for error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) * status. If there is error status reported, PRLI retry shall be attempted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) * by invoking the lpfc_els_retry() routine. Otherwise, the state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) * NLP_EVT_CMPL_PRLI is sent to the Discover State Machine (DSM) for this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) * ndlp to mark the PRLI completion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) struct lpfc_iocbq *rspiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) struct lpfc_vport *vport = cmdiocb->vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) IOCB_t *irsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) char *mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) u32 loglevel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) /* we pass cmdiocb to state machine which needs rspiocb as well */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) cmdiocb->context_un.rsp_iocb = rspiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) irsp = &(rspiocb->iocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) ndlp->nlp_flag &= ~NLP_PRLI_SND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) /* Driver supports multiple FC4 types. Counters matter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) vport->fc_prli_sent--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) ndlp->fc4_prli_sent--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) "PRLI cmpl: status:x%x/x%x did:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) irsp->ulpStatus, irsp->un.ulpWord[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) ndlp->nlp_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) /* PRLI completes to NPort <nlp_DID> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) "0103 PRLI completes to NPort x%06x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) "Data: x%x x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) vport->num_disc_nodes, ndlp->fc4_prli_sent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) /* Check to see if link went down during discovery */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) if (lpfc_els_chk_latt(vport))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) if (irsp->ulpStatus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) /* Check for retry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) /* ELS command is being retried */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) /* If we don't send GFT_ID to Fabric, a PRLI error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) * could be expected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) if ((vport->fc_flag & FC_FABRIC) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) (vport->cfg_enable_fc4_type != LPFC_ENABLE_BOTH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) mode = KERN_ERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) loglevel = LOG_TRACE_EVENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) mode = KERN_INFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) loglevel = LOG_ELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) /* PRLI failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) lpfc_printf_vlog(vport, mode, loglevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) "2754 PRLI failure DID:%06X Status:x%x/x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) "data: x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) ndlp->nlp_DID, irsp->ulpStatus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) irsp->un.ulpWord[4], ndlp->fc4_prli_sent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) if (lpfc_error_lost_link(irsp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) lpfc_disc_state_machine(vport, ndlp, cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) NLP_EVT_CMPL_PRLI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) /* Good status, call state machine. However, if another
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) * PRLI is outstanding, don't call the state machine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) * because final disposition to Mapped or Unmapped is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) * completed there.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) lpfc_disc_state_machine(vport, ndlp, cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) NLP_EVT_CMPL_PRLI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) lpfc_els_free_iocb(phba, cmdiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) * lpfc_issue_els_prli - Issue a prli iocb command for a vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) * @retry: number of retries to the command IOCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) * This routine issues a Process Login (PRLI) ELS command for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) * @vport. The PRLI service parameters are set up in the payload of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) * PRLI Request command and the pointer to lpfc_cmpl_els_prli() routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) * is put to the IOCB completion callback func field before invoking the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) * routine lpfc_sli_issue_iocb() to send out PRLI command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) * will be incremented by 1 for holding the ndlp and the reference to ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) * will be stored into the context1 field of the IOCB for the completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) * callback function to the PRLI ELS command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) * 0 - successfully issued prli iocb command for @vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) * 1 - failed to issue prli iocb command for @vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) uint8_t retry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) PRLI *npr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) struct lpfc_nvme_prli *npr_nvme;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) struct lpfc_iocbq *elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) uint8_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) uint16_t cmdsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) u32 local_nlp_type, elscmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) * If we are in RSCN mode, the FC4 types supported from a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) * previous GFT_ID command may not be accurate. So, if we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) * are a NVME Initiator, always look for the possibility of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) * the remote NPort beng a NVME Target.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) if (phba->sli_rev == LPFC_SLI_REV4 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) vport->fc_flag & FC_RSCN_MODE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) vport->nvmei_support)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) ndlp->nlp_fc4_type |= NLP_FC4_NVME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) local_nlp_type = ndlp->nlp_fc4_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) /* This routine will issue 1 or 2 PRLIs, so zero all the ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) * fields here before any of them can complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) ndlp->nlp_type &= ~(NLP_NVME_TARGET | NLP_NVME_INITIATOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) ndlp->nlp_flag &= ~(NLP_FIRSTBURST | NLP_NPR_2B_DISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) ndlp->nvme_fb_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) send_next_prli:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) if (local_nlp_type & NLP_FC4_FCP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) /* Payload is 4 + 16 = 20 x14 bytes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) cmdsize = (sizeof(uint32_t) + sizeof(PRLI));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) elscmd = ELS_CMD_PRLI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) } else if (local_nlp_type & NLP_FC4_NVME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) /* Payload is 4 + 20 = 24 x18 bytes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) cmdsize = (sizeof(uint32_t) + sizeof(struct lpfc_nvme_prli));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) elscmd = ELS_CMD_NVMEPRLI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) "3083 Unknown FC_TYPE x%x ndlp x%06x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) ndlp->nlp_fc4_type, ndlp->nlp_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) /* SLI3 ports don't support NVME. If this rport is a strict NVME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) * FC4 type, implicitly LOGO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) if (phba->sli_rev == LPFC_SLI_REV3 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) ndlp->nlp_fc4_type == NLP_FC4_NVME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) "3088 Rport fc4 type 0x%x not supported by SLI3 adapter\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) ndlp->nlp_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) ndlp->nlp_DID, elscmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) if (!elsiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) /* For PRLI request, remainder of payload is service parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) memset(pcmd, 0, cmdsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) if (local_nlp_type & NLP_FC4_FCP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) /* Remainder of payload is FCP PRLI parameter page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) * Note: this data structure is defined as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) * BE/LE in the structure definition so no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) * byte swap call is made.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) *((uint32_t *)(pcmd)) = ELS_CMD_PRLI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) pcmd += sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) npr = (PRLI *)pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) * If our firmware version is 3.20 or later,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) * set the following bits for FC-TAPE support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) if (phba->vpd.rev.feaLevelHigh >= 0x02) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) npr->ConfmComplAllowed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) npr->Retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) npr->TaskRetryIdReq = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) npr->estabImagePair = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) npr->readXferRdyDis = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) if (vport->cfg_first_burst_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) npr->writeXferRdyDis = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) /* For FCP support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) npr->prliType = PRLI_FCP_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) npr->initiatorFunc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) elsiocb->iocb_flag |= LPFC_PRLI_FCP_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) /* Remove FCP type - processed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) local_nlp_type &= ~NLP_FC4_FCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) } else if (local_nlp_type & NLP_FC4_NVME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) /* Remainder of payload is NVME PRLI parameter page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) * This data structure is the newer definition that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) * uses bf macros so a byte swap is required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) *((uint32_t *)(pcmd)) = ELS_CMD_NVMEPRLI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) pcmd += sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) npr_nvme = (struct lpfc_nvme_prli *)pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) bf_set(prli_type_code, npr_nvme, PRLI_NVME_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) bf_set(prli_estabImagePair, npr_nvme, 0); /* Should be 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) if (phba->nsler) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) bf_set(prli_nsler, npr_nvme, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) bf_set(prli_conf, npr_nvme, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) /* Only initiators request first burst. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) if ((phba->cfg_nvme_enable_fb) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) !phba->nvmet_support)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) bf_set(prli_fba, npr_nvme, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) if (phba->nvmet_support) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) bf_set(prli_tgt, npr_nvme, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) bf_set(prli_disc, npr_nvme, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) bf_set(prli_init, npr_nvme, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) bf_set(prli_conf, npr_nvme, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) npr_nvme->word1 = cpu_to_be32(npr_nvme->word1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) npr_nvme->word4 = cpu_to_be32(npr_nvme->word4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) elsiocb->iocb_flag |= LPFC_PRLI_NVME_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) /* Remove NVME type - processed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) local_nlp_type &= ~NLP_FC4_NVME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) "Issue PRLI: did:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) ndlp->nlp_DID, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) phba->fc_stat.elsXmitPRLI++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) elsiocb->iocb_cmpl = lpfc_cmpl_els_prli;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) ndlp->nlp_flag |= NLP_PRLI_SND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) /* The vport counters are used for lpfc_scan_finished, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) * the ndlp is used to track outstanding PRLIs for different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) * FC4 types.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) vport->fc_prli_sent++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) ndlp->fc4_prli_sent++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) IOCB_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) ndlp->nlp_flag &= ~NLP_PRLI_SND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) /* The driver supports 2 FC4 types. Make sure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) * a PRLI is issued for all types before exiting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) if (phba->sli_rev == LPFC_SLI_REV4 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) local_nlp_type & (NLP_FC4_FCP | NLP_FC4_NVME))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) goto send_next_prli;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) * lpfc_rscn_disc - Perform rscn discovery for a vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) * This routine performs Registration State Change Notification (RSCN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) * discovery for a @vport. If the @vport's node port recovery count is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) * zero, it will invoke the lpfc_els_disc_plogi() to perform PLOGI for all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) * the nodes that need recovery. If none of the PLOGI were needed through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) * the lpfc_els_disc_plogi() routine, the lpfc_end_rscn() routine shall be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) * invoked to check and handle possible more RSCN came in during the period
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) * of processing the current ones.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) lpfc_rscn_disc(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) lpfc_can_disctmo(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) /* RSCN discovery */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) /* go thru NPR nodes and issue ELS PLOGIs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) if (vport->fc_npr_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) if (lpfc_els_disc_plogi(vport))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) lpfc_end_rscn(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) * lpfc_adisc_done - Complete the adisc phase of discovery
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) * @vport: pointer to lpfc_vport hba data structure that finished all ADISCs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) * This function is called when the final ADISC is completed during discovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) * This function handles clearing link attention or issuing reg_vpi depending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) * on whether npiv is enabled. This function also kicks off the PLOGI phase of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) * discovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) * This function is called with no locks held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) lpfc_adisc_done(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) * For NPIV, cmpl_reg_vpi will set port_state to READY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) * and continue discovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) !(vport->fc_flag & FC_RSCN_MODE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) (phba->sli_rev < LPFC_SLI_REV4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) /* The ADISCs are complete. Doesn't matter if they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) * succeeded or failed because the ADISC completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) * routine guarantees to call the state machine and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) * the RPI is either unregistered (failed ADISC response)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) * or the RPI is still valid and the node is marked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) * mapped for a target. The exchanges should be in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) * correct state. This code is specific to SLI3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) lpfc_issue_clear_la(phba, vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) lpfc_issue_reg_vpi(phba, vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) * For SLI2, we need to set port_state to READY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) * and continue discovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) if (vport->port_state < LPFC_VPORT_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) /* If we get here, there is nothing to ADISC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) lpfc_issue_clear_la(phba, vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) if (!(vport->fc_flag & FC_ABORT_DISCOVERY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) vport->num_disc_nodes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) /* go thru NPR list, issue ELS PLOGIs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) if (vport->fc_npr_cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) lpfc_els_disc_plogi(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) if (!vport->num_disc_nodes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) vport->fc_flag &= ~FC_NDISC_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) lpfc_can_disctmo(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) lpfc_end_rscn(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) vport->port_state = LPFC_VPORT_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) lpfc_rscn_disc(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) * lpfc_more_adisc - Issue more adisc as needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) * This routine determines whether there are more ndlps on a @vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) * node list need to have Address Discover (ADISC) issued. If so, it will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) * invoke the lpfc_els_disc_adisc() routine to issue ADISC on the @vport's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) * remaining nodes which need to have ADISC sent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) lpfc_more_adisc(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) if (vport->num_disc_nodes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) vport->num_disc_nodes--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) /* Continue discovery with <num_disc_nodes> ADISCs to go */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) "0210 Continue discovery with %d ADISCs to go "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) "Data: x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) vport->num_disc_nodes, vport->fc_adisc_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) vport->fc_flag, vport->port_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) /* Check to see if there are more ADISCs to be sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) if (vport->fc_flag & FC_NLP_MORE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) lpfc_set_disctmo(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) /* go thru NPR nodes and issue any remaining ELS ADISCs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) lpfc_els_disc_adisc(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) if (!vport->num_disc_nodes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) lpfc_adisc_done(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) * lpfc_cmpl_els_adisc - Completion callback function for adisc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) * @rspiocb: pointer to lpfc response iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) * This routine is the completion function for issuing the Address Discover
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) * (ADISC) command. It first checks to see whether link went down during
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) * the discovery process. If so, the node will be marked as node port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) * recovery for issuing discover IOCB by the link attention handler and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) * exit. Otherwise, the response status is checked. If error was reported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) * in the response status, the ADISC command shall be retried by invoking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) * the lpfc_els_retry() routine. Otherwise, if no error was reported in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) * the response status, the state machine is invoked to set transition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) * with respect to NLP_EVT_CMPL_ADISC event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) struct lpfc_iocbq *rspiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) struct lpfc_vport *vport = cmdiocb->vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) IOCB_t *irsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) int disc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) /* we pass cmdiocb to state machine which needs rspiocb as well */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) cmdiocb->context_un.rsp_iocb = rspiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) irsp = &(rspiocb->iocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) "ADISC cmpl: status:x%x/x%x did:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) irsp->ulpStatus, irsp->un.ulpWord[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) ndlp->nlp_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) /* Since ndlp can be freed in the disc state machine, note if this node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) * is being used during discovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) ndlp->nlp_flag &= ~(NLP_ADISC_SND | NLP_NPR_2B_DISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) /* ADISC completes to NPort <nlp_DID> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) "0104 ADISC completes to NPort x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) "Data: x%x x%x x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) irsp->ulpTimeout, disc, vport->num_disc_nodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) /* Check to see if link went down during discovery */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) if (lpfc_els_chk_latt(vport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) ndlp->nlp_flag |= NLP_NPR_2B_DISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) if (irsp->ulpStatus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) /* Check for retry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) /* ELS command is being retried */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) if (disc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) ndlp->nlp_flag |= NLP_NPR_2B_DISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) lpfc_set_disctmo(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) /* ADISC failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) "2755 ADISC failure DID:%06X Status:x%x/x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) ndlp->nlp_DID, irsp->ulpStatus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) irsp->un.ulpWord[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) if (!lpfc_error_lost_link(irsp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) lpfc_disc_state_machine(vport, ndlp, cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) NLP_EVT_CMPL_ADISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) /* Good status, call state machine */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) lpfc_disc_state_machine(vport, ndlp, cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) NLP_EVT_CMPL_ADISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) /* Check to see if there are more ADISCs to be sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) if (disc && vport->num_disc_nodes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) lpfc_more_adisc(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) lpfc_els_free_iocb(phba, cmdiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) * lpfc_issue_els_adisc - Issue an address discover iocb to an node on a vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) * @vport: pointer to a virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) * @retry: number of retries to the command IOCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) * This routine issues an Address Discover (ADISC) for an @ndlp on a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) * @vport. It prepares the payload of the ADISC ELS command, updates the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) * and states of the ndlp, and invokes the lpfc_sli_issue_iocb() routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) * to issue the ADISC ELS command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) * will be incremented by 1 for holding the ndlp and the reference to ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) * will be stored into the context1 field of the IOCB for the completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) * callback function to the ADISC ELS command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) * 0 - successfully issued adisc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) * 1 - failed to issue adisc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) uint8_t retry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) ADISC *ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) struct lpfc_iocbq *elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) uint8_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) uint16_t cmdsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) cmdsize = (sizeof(uint32_t) + sizeof(ADISC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) ndlp->nlp_DID, ELS_CMD_ADISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) if (!elsiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) /* For ADISC request, remainder of payload is service parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) *((uint32_t *) (pcmd)) = ELS_CMD_ADISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) pcmd += sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) /* Fill in ADISC payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) ap = (ADISC *) pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) ap->hardAL_PA = phba->fc_pref_ALPA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) memcpy(&ap->portName, &vport->fc_portname, sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) memcpy(&ap->nodeName, &vport->fc_nodename, sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) ap->DID = be32_to_cpu(vport->fc_myDID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) "Issue ADISC: did:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) ndlp->nlp_DID, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) phba->fc_stat.elsXmitADISC++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) elsiocb->iocb_cmpl = lpfc_cmpl_els_adisc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) ndlp->nlp_flag |= NLP_ADISC_SND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) IOCB_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) ndlp->nlp_flag &= ~NLP_ADISC_SND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) * lpfc_cmpl_els_logo - Completion callback function for logo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) * @rspiocb: pointer to lpfc response iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) * This routine is the completion function for issuing the ELS Logout (LOGO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) * command. If no error status was reported from the LOGO response, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) * state machine of the associated ndlp shall be invoked for transition with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) * respect to NLP_EVT_CMPL_LOGO event. Otherwise, if error status was reported,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) * the lpfc_els_retry() routine will be invoked to retry the LOGO command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) struct lpfc_iocbq *rspiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) struct lpfc_vport *vport = ndlp->vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) IOCB_t *irsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) struct lpfcMboxq *mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) uint32_t skip_recovery = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) /* we pass cmdiocb to state machine which needs rspiocb as well */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) cmdiocb->context_un.rsp_iocb = rspiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) irsp = &(rspiocb->iocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) ndlp->nlp_flag &= ~NLP_LOGO_SND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) "LOGO cmpl: status:x%x/x%x did:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) irsp->ulpStatus, irsp->un.ulpWord[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) ndlp->nlp_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) /* LOGO completes to NPort <nlp_DID> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) "0105 LOGO completes to NPort x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) "Data: x%x x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) irsp->ulpTimeout, vport->num_disc_nodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) if (lpfc_els_chk_latt(vport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) skip_recovery = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) /* Check to see if link went down during discovery */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) if (ndlp->nlp_flag & NLP_TARGET_REMOVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) /* NLP_EVT_DEVICE_RM should unregister the RPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) * which should abort all outstanding IOs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) lpfc_disc_state_machine(vport, ndlp, cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) NLP_EVT_DEVICE_RM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) skip_recovery = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) /* The LOGO will not be retried on failure. A LOGO was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) * issued to the remote rport and a ACC or RJT or no Answer are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) * all acceptable. Note the failure and move forward with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) * discovery. The PLOGI will retry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) if (irsp->ulpStatus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) /* LOGO failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) "2756 LOGO failure, No Retry DID:%06X Status:x%x/x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) ndlp->nlp_DID, irsp->ulpStatus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) irsp->un.ulpWord[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) if (lpfc_error_lost_link(irsp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) skip_recovery = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) /* Call state machine. This will unregister the rpi if needed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_CMPL_LOGO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) lpfc_els_free_iocb(phba, cmdiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) /* If we are in pt2pt mode, we could rcv new S_ID on PLOGI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) if ((vport->fc_flag & FC_PT2PT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) !(vport->fc_flag & FC_PT2PT_PLOGI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) phba->pport->fc_myDID = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) if ((vport->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) (vport->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) if (phba->nvmet_support)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) lpfc_nvmet_update_targetport(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) lpfc_nvme_update_localport(phba->pport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) if (mbox) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) lpfc_config_link(phba, mbox);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) mbox->vport = vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) MBX_NOT_FINISHED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) mempool_free(mbox, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) skip_recovery = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) * If the node is a target, the handling attempts to recover the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) * For any other port type, the rpi is unregistered as an implicit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) * LOGO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) if (ndlp->nlp_type & (NLP_FCP_TARGET | NLP_NVME_TARGET) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) skip_recovery == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) lpfc_cancel_retry_delay_tmo(vport, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) spin_lock_irqsave(shost->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) ndlp->nlp_flag |= NLP_NPR_2B_DISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) spin_unlock_irqrestore(shost->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) "3187 LOGO completes to NPort x%x: Start "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) "Recovery Data: x%x x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) ndlp->nlp_DID, irsp->ulpStatus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) irsp->un.ulpWord[4], irsp->ulpTimeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) vport->num_disc_nodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) lpfc_disc_start(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) * lpfc_issue_els_logo - Issue a logo to an node on a vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) * @vport: pointer to a virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) * @retry: number of retries to the command IOCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) * This routine constructs and issues an ELS Logout (LOGO) iocb command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) * to a remote node, referred by an @ndlp on a @vport. It constructs the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) * payload of the IOCB, properly sets up the @ndlp state, and invokes the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) * lpfc_sli_issue_iocb() routine to send out the LOGO ELS command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) * will be incremented by 1 for holding the ndlp and the reference to ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) * will be stored into the context1 field of the IOCB for the completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) * callback function to the LOGO ELS command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) * Callers of this routine are expected to unregister the RPI first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) * 0 - successfully issued logo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) * 1 - failed to issue logo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) uint8_t retry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) struct lpfc_iocbq *elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) uint8_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) uint16_t cmdsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) if (ndlp->nlp_flag & NLP_LOGO_SND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) cmdsize = (2 * sizeof(uint32_t)) + sizeof(struct lpfc_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) ndlp->nlp_DID, ELS_CMD_LOGO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) if (!elsiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) *((uint32_t *) (pcmd)) = ELS_CMD_LOGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) pcmd += sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) /* Fill in LOGO payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) *((uint32_t *) (pcmd)) = be32_to_cpu(vport->fc_myDID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) pcmd += sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) memcpy(pcmd, &vport->fc_portname, sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) "Issue LOGO: did:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) ndlp->nlp_DID, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) phba->fc_stat.elsXmitLOGO++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) elsiocb->iocb_cmpl = lpfc_cmpl_els_logo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) ndlp->nlp_flag |= NLP_LOGO_SND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) ndlp->nlp_flag &= ~NLP_ISSUE_LOGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) if (rc == IOCB_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) ndlp->nlp_flag &= ~NLP_LOGO_SND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) ndlp->nlp_prev_state = ndlp->nlp_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) lpfc_nlp_set_state(vport, ndlp, NLP_STE_LOGO_ISSUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) * lpfc_cmpl_els_cmd - Completion callback function for generic els command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) * @rspiocb: pointer to lpfc response iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) * This routine is a generic completion callback function for ELS commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) * Specifically, it is the callback function which does not need to perform
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) * any command specific operations. It is currently used by the ELS command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) * issuing routines for RSCN, lpfc_issue_els_rscn, and the ELS Fibre Channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) * Address Resolution Protocol Response (FARPR) routine, lpfc_issue_els_farpr().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) * Other than certain debug loggings, this callback function simply invokes the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) * lpfc_els_chk_latt() routine to check whether link went down during the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) * discovery process.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) lpfc_cmpl_els_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) struct lpfc_iocbq *rspiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) struct lpfc_vport *vport = cmdiocb->vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) IOCB_t *irsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) irsp = &rspiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) "ELS cmd cmpl: status:x%x/x%x did:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) irsp->ulpStatus, irsp->un.ulpWord[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) irsp->un.elsreq64.remoteID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) /* ELS cmd tag <ulpIoTag> completes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) "0106 ELS cmd tag x%x completes Data: x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) irsp->ulpIoTag, irsp->ulpStatus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) irsp->un.ulpWord[4], irsp->ulpTimeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) /* Check to see if link went down during discovery */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) lpfc_els_chk_latt(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) lpfc_els_free_iocb(phba, cmdiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) * lpfc_cmpl_els_disc_cmd - Completion callback function for Discovery ELS cmd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) * @rspiocb: pointer to lpfc response iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) * This routine is a generic completion callback function for Discovery ELS cmd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) * Currently used by the ELS command issuing routines for the ELS State Change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) * Request (SCR), lpfc_issue_els_scr() and the ELS RDF, lpfc_issue_els_rdf().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) * These commands will be retried once only for ELS timeout errors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) lpfc_cmpl_els_disc_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) struct lpfc_iocbq *rspiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) struct lpfc_vport *vport = cmdiocb->vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) IOCB_t *irsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) struct lpfc_els_rdf_rsp *prdf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) struct lpfc_dmabuf *pcmd, *prsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) u32 *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) u32 cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) irsp = &rspiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) "ELS cmd cmpl: status:x%x/x%x did:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) irsp->ulpStatus, irsp->un.ulpWord[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) irsp->un.elsreq64.remoteID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) /* ELS cmd tag <ulpIoTag> completes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) "0217 ELS cmd tag x%x completes Data: x%x x%x x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) "x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) irsp->ulpIoTag, irsp->ulpStatus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) irsp->un.ulpWord[4], irsp->ulpTimeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) cmdiocb->retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) pcmd = (struct lpfc_dmabuf *)cmdiocb->context2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) if (!pcmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) pdata = (u32 *)pcmd->virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) if (!pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) cmd = *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) /* Only 1 retry for ELS Timeout only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) IOERR_SEQUENCE_TIMEOUT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) cmdiocb->retry++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) if (cmdiocb->retry <= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) case ELS_CMD_SCR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) lpfc_issue_els_scr(vport, cmdiocb->retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) case ELS_CMD_RDF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) cmdiocb->context1 = NULL; /* save ndlp refcnt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) lpfc_issue_els_rdf(vport, cmdiocb->retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) phba->fc_stat.elsRetryExceeded++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) if (irsp->ulpStatus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) /* ELS discovery cmd completes with error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) lpfc_printf_vlog(vport, KERN_WARNING, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) "4203 ELS cmd x%x error: x%x x%X\n", cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) irsp->ulpStatus, irsp->un.ulpWord[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) /* The RDF response doesn't have any impact on the running driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) * but the notification descriptors are dumped here for support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) if (cmd == ELS_CMD_RDF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) if (!prsp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) prdf = (struct lpfc_els_rdf_rsp *)prsp->virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) if (!prdf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) for (i = 0; i < ELS_RDF_REG_TAG_CNT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) i < be32_to_cpu(prdf->reg_d1.reg_desc.count); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) "4677 Fabric RDF Notification Grant Data: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) "0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) be32_to_cpu(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) prdf->reg_d1.desc_tags[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) /* Check to see if link went down during discovery */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) lpfc_els_chk_latt(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) lpfc_els_free_iocb(phba, cmdiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) * lpfc_issue_els_scr - Issue a scr to an node on a vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) * @retry: retry counter for the command IOCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) * This routine issues a State Change Request (SCR) to a fabric node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) * on a @vport. The remote node is Fabric Controller (0xfffffd). It
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) * first search the @vport node list to find the matching ndlp. If no such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) * ndlp is found, a new ndlp shall be created for this (SCR) purpose. An
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) * IOCB is allocated, payload prepared, and the lpfc_sli_issue_iocb()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) * routine is invoked to send the SCR IOCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) * will be incremented by 1 for holding the ndlp and the reference to ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) * will be stored into the context1 field of the IOCB for the completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) * callback function to the SCR ELS command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) * 0 - Successfully issued scr command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) * 1 - Failed to issue scr command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) lpfc_issue_els_scr(struct lpfc_vport *vport, uint8_t retry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) struct lpfc_iocbq *elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) uint8_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) uint16_t cmdsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) cmdsize = (sizeof(uint32_t) + sizeof(SCR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) ndlp = lpfc_findnode_did(vport, Fabric_Cntl_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) if (!ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) ndlp = lpfc_nlp_init(vport, Fabric_Cntl_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) if (!ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) lpfc_enqueue_node(vport, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) } else if (!NLP_CHK_NODE_ACT(ndlp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) if (!ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) ndlp->nlp_DID, ELS_CMD_SCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) if (!elsiocb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) /* This will trigger the release of the node just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) * allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) *((uint32_t *) (pcmd)) = ELS_CMD_SCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) pcmd += sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) /* For SCR, remainder of payload is SCR parameter page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) memset(pcmd, 0, sizeof(SCR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) ((SCR *) pcmd)->Function = SCR_FUNC_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) "Issue SCR: did:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) ndlp->nlp_DID, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) phba->fc_stat.elsXmitSCR++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) elsiocb->iocb_cmpl = lpfc_cmpl_els_disc_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) IOCB_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) /* The additional lpfc_nlp_put will cause the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) * lpfc_els_free_iocb routine to trigger the rlease of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) * the node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) /* This will cause the callback-function lpfc_cmpl_els_cmd to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) * trigger the release of node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) if (!(vport->fc_flag & FC_PT2PT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) * lpfc_issue_els_rscn - Issue an RSCN to the Fabric Controller (Fabric)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) * or the other nport (pt2pt).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) * @retry: number of retries to the command IOCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) * This routine issues a RSCN to the Fabric Controller (DID 0xFFFFFD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) * when connected to a fabric, or to the remote port when connected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) * in point-to-point mode. When sent to the Fabric Controller, it will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) * replay the RSCN to registered recipients.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) * will be incremented by 1 for holding the ndlp and the reference to ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) * will be stored into the context1 field of the IOCB for the completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) * callback function to the RSCN ELS command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) * 0 - Successfully issued RSCN command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) * 1 - Failed to issue RSCN command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) lpfc_issue_els_rscn(struct lpfc_vport *vport, uint8_t retry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) struct lpfc_iocbq *elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) struct fc_els_rscn rscn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) struct fc_els_rscn_page portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) } *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) uint32_t nportid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) uint16_t cmdsize = sizeof(*event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) /* Not supported for private loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) if (phba->fc_topology == LPFC_TOPOLOGY_LOOP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) !(vport->fc_flag & FC_PUBLIC_LOOP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) if (vport->fc_flag & FC_PT2PT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) /* find any mapped nport - that would be the other nport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) ndlp = lpfc_findnode_mapped(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) if (!ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) nportid = FC_FID_FCTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) /* find the fabric controller node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) ndlp = lpfc_findnode_did(vport, nportid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) if (!ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) /* if one didn't exist, make one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) ndlp = lpfc_nlp_init(vport, nportid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) if (!ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) lpfc_enqueue_node(vport, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) } else if (!NLP_CHK_NODE_ACT(ndlp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) ndlp = lpfc_enable_node(vport, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) NLP_STE_UNUSED_NODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) if (!ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) ndlp->nlp_DID, ELS_CMD_RSCN_XMT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) if (!elsiocb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) /* This will trigger the release of the node just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) * allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) event = ((struct lpfc_dmabuf *)elsiocb->context2)->virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) event->rscn.rscn_cmd = ELS_RSCN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) event->rscn.rscn_page_len = sizeof(struct fc_els_rscn_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) event->rscn.rscn_plen = cpu_to_be16(cmdsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) nportid = vport->fc_myDID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) /* appears that page flags must be 0 for fabric to broadcast RSCN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) event->portid.rscn_page_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) event->portid.rscn_fid[0] = (nportid & 0x00FF0000) >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) event->portid.rscn_fid[1] = (nportid & 0x0000FF00) >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) event->portid.rscn_fid[2] = nportid & 0x000000FF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) "Issue RSCN: did:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) ndlp->nlp_DID, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) phba->fc_stat.elsXmitRSCN++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) IOCB_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) /* The additional lpfc_nlp_put will cause the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) * lpfc_els_free_iocb routine to trigger the rlease of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) * the node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) /* This will cause the callback-function lpfc_cmpl_els_cmd to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) * trigger the release of node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) if (!(vport->fc_flag & FC_PT2PT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) * lpfc_issue_els_farpr - Issue a farp to an node on a vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) * @nportid: N_Port identifier to the remote node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) * @retry: number of retries to the command IOCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) * This routine issues a Fibre Channel Address Resolution Response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) * (FARPR) to a node on a vport. The remote node N_Port identifier (@nportid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) * is passed into the function. It first search the @vport node list to find
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) * the matching ndlp. If no such ndlp is found, a new ndlp shall be created
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) * for this (FARPR) purpose. An IOCB is allocated, payload prepared, and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) * lpfc_sli_issue_iocb() routine is invoked to send the FARPR ELS command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) * will be incremented by 1 for holding the ndlp and the reference to ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) * will be stored into the context1 field of the IOCB for the completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) * callback function to the PARPR ELS command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) * 0 - Successfully issued farpr command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) * 1 - Failed to issue farpr command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) struct lpfc_iocbq *elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) FARP *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) uint8_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) uint32_t *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) uint16_t cmdsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) struct lpfc_nodelist *ondlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) cmdsize = (sizeof(uint32_t) + sizeof(FARP));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) ndlp = lpfc_findnode_did(vport, nportid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) if (!ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) ndlp = lpfc_nlp_init(vport, nportid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) if (!ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) lpfc_enqueue_node(vport, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) } else if (!NLP_CHK_NODE_ACT(ndlp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) if (!ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) ndlp->nlp_DID, ELS_CMD_RNID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) if (!elsiocb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) /* This will trigger the release of the node just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) * allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) *((uint32_t *) (pcmd)) = ELS_CMD_FARPR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) pcmd += sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) /* Fill in FARPR payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) fp = (FARP *) (pcmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) memset(fp, 0, sizeof(FARP));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) lp = (uint32_t *) pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) *lp++ = be32_to_cpu(nportid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) *lp++ = be32_to_cpu(vport->fc_myDID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) fp->Rflags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) fp->Mflags = (FARP_MATCH_PORT | FARP_MATCH_NODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) memcpy(&fp->RportName, &vport->fc_portname, sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) memcpy(&fp->RnodeName, &vport->fc_nodename, sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) ondlp = lpfc_findnode_did(vport, nportid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) if (ondlp && NLP_CHK_NODE_ACT(ondlp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) memcpy(&fp->OportName, &ondlp->nlp_portname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) memcpy(&fp->OnodeName, &ondlp->nlp_nodename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) "Issue FARPR: did:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) ndlp->nlp_DID, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) phba->fc_stat.elsXmitFARPR++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) IOCB_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) /* The additional lpfc_nlp_put will cause the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) * lpfc_els_free_iocb routine to trigger the release of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) * the node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) /* This will cause the callback-function lpfc_cmpl_els_cmd to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) * trigger the release of the node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) /* Don't release reference count as RDF is likely outstanding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) * lpfc_issue_els_rdf - Register for diagnostic functions from the fabric.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) * @retry: retry counter for the command IOCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) * This routine issues an ELS RDF to the Fabric Controller to register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) * for diagnostic functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) * will be incremented by 1 for holding the ndlp and the reference to ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) * will be stored into the context1 field of the IOCB for the completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) * callback function to the RDF ELS command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) * 0 - Successfully issued rdf command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) * 1 - Failed to issue rdf command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) lpfc_issue_els_rdf(struct lpfc_vport *vport, uint8_t retry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) struct lpfc_iocbq *elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) struct lpfc_els_rdf_req *prdf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) uint16_t cmdsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) cmdsize = sizeof(*prdf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) ndlp = lpfc_findnode_did(vport, Fabric_Cntl_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) if (!ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) ndlp = lpfc_nlp_init(vport, Fabric_Cntl_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) if (!ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) lpfc_enqueue_node(vport, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) } else if (!NLP_CHK_NODE_ACT(ndlp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) if (!ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) /* RDF ELS is not required on an NPIV VN_Port. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) if (vport->port_type == LPFC_NPIV_PORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) ndlp->nlp_DID, ELS_CMD_RDF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) if (!elsiocb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) /* This will trigger the release of the node just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) * allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) /* Configure the payload for the supported FPIN events. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) prdf = (struct lpfc_els_rdf_req *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) (((struct lpfc_dmabuf *)elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) memset(prdf, 0, cmdsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) prdf->rdf.fpin_cmd = ELS_RDF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) prdf->rdf.desc_len = cpu_to_be32(sizeof(struct lpfc_els_rdf_req) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) sizeof(struct fc_els_rdf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) prdf->reg_d1.reg_desc.desc_tag = cpu_to_be32(ELS_DTAG_FPIN_REGISTER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) prdf->reg_d1.reg_desc.desc_len = cpu_to_be32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) FC_TLV_DESC_LENGTH_FROM_SZ(prdf->reg_d1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) prdf->reg_d1.reg_desc.count = cpu_to_be32(ELS_RDF_REG_TAG_CNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) prdf->reg_d1.desc_tags[0] = cpu_to_be32(ELS_DTAG_LNK_INTEGRITY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) prdf->reg_d1.desc_tags[1] = cpu_to_be32(ELS_DTAG_DELIVERY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) prdf->reg_d1.desc_tags[2] = cpu_to_be32(ELS_DTAG_PEER_CONGEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) prdf->reg_d1.desc_tags[3] = cpu_to_be32(ELS_DTAG_CONGESTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) "Issue RDF: did:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) ndlp->nlp_DID, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) "6444 Xmit RDF to remote NPORT x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) ndlp->nlp_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) elsiocb->iocb_cmpl = lpfc_cmpl_els_disc_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) IOCB_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) /* The additional lpfc_nlp_put will cause the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) * lpfc_els_free_iocb routine to trigger the rlease of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) * the node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) /* An RDF was issued - this put ensures the ndlp is cleaned up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) * when the RDF completes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) * lpfc_cancel_retry_delay_tmo - Cancel the timer with delayed iocb-cmd retry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) * @nlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) * This routine cancels the timer with a delayed IOCB-command retry for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) * a @vport's @ndlp. It stops the timer for the delayed function retrial and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) * removes the ELS retry event if it presents. In addition, if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) * NLP_NPR_2B_DISC bit is set in the @nlp's nlp_flag bitmap, ADISC IOCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) * commands are sent for the @vport's nodes that require issuing discovery
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) * ADISC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) struct lpfc_work_evt *evtp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) if (!(nlp->nlp_flag & NLP_DELAY_TMO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) nlp->nlp_flag &= ~NLP_DELAY_TMO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) del_timer_sync(&nlp->nlp_delayfunc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) nlp->nlp_last_elscmd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) if (!list_empty(&nlp->els_retry_evt.evt_listp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) list_del_init(&nlp->els_retry_evt.evt_listp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) /* Decrement nlp reference count held for the delayed retry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) evtp = &nlp->els_retry_evt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) lpfc_nlp_put((struct lpfc_nodelist *)evtp->evt_arg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) if (nlp->nlp_flag & NLP_NPR_2B_DISC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) nlp->nlp_flag &= ~NLP_NPR_2B_DISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) if (vport->num_disc_nodes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) if (vport->port_state < LPFC_VPORT_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) /* Check if there are more ADISCs to be sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) lpfc_more_adisc(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) /* Check if there are more PLOGIs to be sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) lpfc_more_plogi(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) if (vport->num_disc_nodes == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) vport->fc_flag &= ~FC_NDISC_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) lpfc_can_disctmo(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) lpfc_end_rscn(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) * lpfc_els_retry_delay - Timer function with a ndlp delayed function timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) * @t: pointer to the timer function associated data (ndlp).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) * This routine is invoked by the ndlp delayed-function timer to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) * whether there is any pending ELS retry event(s) with the node. If not, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) * simply returns. Otherwise, if there is at least one ELS delayed event, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) * adds the delayed events to the HBA work list and invokes the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) * lpfc_worker_wake_up() routine to wake up worker thread to process the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) * event. Note that lpfc_nlp_get() is called before posting the event to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) * the work list to hold reference count of ndlp so that it guarantees the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) * reference to ndlp will still be available when the worker thread gets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) * to the event associated with the ndlp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) lpfc_els_retry_delay(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) struct lpfc_nodelist *ndlp = from_timer(ndlp, t, nlp_delayfunc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) struct lpfc_vport *vport = ndlp->vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) struct lpfc_work_evt *evtp = &ndlp->els_retry_evt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) spin_lock_irqsave(&phba->hbalock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) if (!list_empty(&evtp->evt_listp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) spin_unlock_irqrestore(&phba->hbalock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) /* We need to hold the node by incrementing the reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) * count until the queued work is done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) evtp->evt_arg1 = lpfc_nlp_get(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) if (evtp->evt_arg1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) evtp->evt = LPFC_EVT_ELS_RETRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) list_add_tail(&evtp->evt_listp, &phba->work_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) lpfc_worker_wake_up(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) spin_unlock_irqrestore(&phba->hbalock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) * lpfc_els_retry_delay_handler - Work thread handler for ndlp delayed function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) * This routine is the worker-thread handler for processing the @ndlp delayed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) * event(s), posted by the lpfc_els_retry_delay() routine. It simply retrieves
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) * the last ELS command from the associated ndlp and invokes the proper ELS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) * function according to the delayed ELS command to retry the command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) struct lpfc_vport *vport = ndlp->vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) uint32_t cmd, retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) cmd = ndlp->nlp_last_elscmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) ndlp->nlp_last_elscmd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) ndlp->nlp_flag &= ~NLP_DELAY_TMO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) * If a discovery event readded nlp_delayfunc after timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) * firing and before processing the timer, cancel the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) * nlp_delayfunc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) del_timer_sync(&ndlp->nlp_delayfunc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) retry = ndlp->nlp_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) ndlp->nlp_retry = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) case ELS_CMD_FLOGI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) lpfc_issue_els_flogi(vport, ndlp, retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) case ELS_CMD_PLOGI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) if (!lpfc_issue_els_plogi(vport, ndlp->nlp_DID, retry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) ndlp->nlp_prev_state = ndlp->nlp_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) case ELS_CMD_ADISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) if (!lpfc_issue_els_adisc(vport, ndlp, retry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) ndlp->nlp_prev_state = ndlp->nlp_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) case ELS_CMD_PRLI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) case ELS_CMD_NVMEPRLI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) if (!lpfc_issue_els_prli(vport, ndlp, retry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) ndlp->nlp_prev_state = ndlp->nlp_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) case ELS_CMD_LOGO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) if (!lpfc_issue_els_logo(vport, ndlp, retry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) ndlp->nlp_prev_state = ndlp->nlp_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) lpfc_nlp_set_state(vport, ndlp, NLP_STE_LOGO_ISSUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) case ELS_CMD_FDISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) if (!(vport->fc_flag & FC_VPORT_NEEDS_INIT_VPI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) lpfc_issue_els_fdisc(vport, ndlp, retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) * lpfc_link_reset - Issue link reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) * @vport: pointer to a virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) * This routine performs link reset by sending INIT_LINK mailbox command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) * For SLI-3 adapter, link attention interrupt is enabled before issuing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) * INIT_LINK mailbox command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) * 0 - Link reset initiated successfully
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) * 1 - Failed to initiate link reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) lpfc_link_reset(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) LPFC_MBOXQ_t *mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) uint32_t control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) "2851 Attempt link reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) if (!mbox) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) "2852 Failed to allocate mbox memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) /* Enable Link attention interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) if (phba->sli_rev <= LPFC_SLI_REV3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) spin_lock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) phba->sli.sli_flag |= LPFC_PROCESS_LA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) control = readl(phba->HCregaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) control |= HC_LAINT_ENA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) writel(control, phba->HCregaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) readl(phba->HCregaddr); /* flush */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) lpfc_init_link(phba, mbox, phba->cfg_topology,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) phba->cfg_link_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) mbox->vport = vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) "2853 Failed to issue INIT_LINK "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) "mbox command, rc:x%x\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) mempool_free(mbox, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) * lpfc_els_retry - Make retry decision on an els command iocb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) * @rspiocb: pointer to lpfc response iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) * This routine makes a retry decision on an ELS command IOCB, which has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) * failed. The following ELS IOCBs use this function for retrying the command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) * when previously issued command responsed with error status: FLOGI, PLOGI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) * PRLI, ADISC, LOGO, and FDISC. Based on the ELS command type and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) * returned error status, it makes the decision whether a retry shall be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) * issued for the command, and whether a retry shall be made immediately or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) * delayed. In the former case, the corresponding ELS command issuing-function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) * is called to retry the command. In the later case, the ELS command shall
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) * be posted to the ndlp delayed event and delayed function timer set to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) * ndlp for the delayed command issusing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) * 0 - No retry of els command is made
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) * 1 - Immediate or delayed retry of els command is made
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) struct lpfc_iocbq *rspiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) struct lpfc_vport *vport = cmdiocb->vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) IOCB_t *irsp = &rspiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) uint32_t *elscmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) struct ls_rjt stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) int retry = 0, maxretry = lpfc_max_els_tries, delay = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) int logerr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) uint32_t cmd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) uint32_t did;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) int link_reset = 0, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) /* Note: context2 may be 0 for internal driver abort
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) * of delays ELS command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) if (pcmd && pcmd->virt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) elscmd = (uint32_t *) (pcmd->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) cmd = *elscmd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) if (ndlp && NLP_CHK_NODE_ACT(ndlp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) did = ndlp->nlp_DID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) /* We should only hit this case for retrying PLOGI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) did = irsp->un.elsreq64.remoteID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) ndlp = lpfc_findnode_did(vport, did);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) if ((!ndlp || !NLP_CHK_NODE_ACT(ndlp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) && (cmd != ELS_CMD_PLOGI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) "Retry ELS: wd7:x%x wd4:x%x did:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) *(((uint32_t *) irsp) + 7), irsp->un.ulpWord[4], ndlp->nlp_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) switch (irsp->ulpStatus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) case IOSTAT_FCP_RSP_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) case IOSTAT_REMOTE_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) if (phba->sli_rev == LPFC_SLI_REV4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) /* This IO was aborted by the target, we don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) * know the rxid and because we did not send the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) * ABTS we cannot generate and RRQ.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) lpfc_set_rrq_active(phba, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) cmdiocb->sli4_lxritag, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) case IOSTAT_LOCAL_REJECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) switch ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) case IOERR_LOOP_OPEN_FAILURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) if (cmd == ELS_CMD_FLOGI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) if (PCI_DEVICE_ID_HORNET ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) phba->pcidev->device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) phba->fc_topology = LPFC_TOPOLOGY_LOOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) phba->pport->fc_myDID = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) phba->alpa_map[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) phba->alpa_map[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) if (cmd == ELS_CMD_PLOGI && cmdiocb->retry == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) delay = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) case IOERR_ILLEGAL_COMMAND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) "0124 Retry illegal cmd x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) "retry:x%x delay:x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) cmd, cmdiocb->retry, delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) /* All command's retry policy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) maxretry = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) if (cmdiocb->retry > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) delay = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) case IOERR_NO_RESOURCES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) logerr = 1; /* HBA out of resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) if (cmdiocb->retry > 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) delay = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) maxretry = 250;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) case IOERR_ILLEGAL_FRAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) delay = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) case IOERR_INVALID_RPI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) if (cmd == ELS_CMD_PLOGI &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) did == NameServer_DID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) /* Continue forever if plogi to */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) /* the nameserver fails */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) maxretry = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) delay = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) case IOERR_SEQUENCE_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) if (cmd == ELS_CMD_PLOGI &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) did == NameServer_DID &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) (cmdiocb->retry + 1) == maxretry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) /* Reset the Link */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) link_reset = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) delay = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) case IOSTAT_NPORT_RJT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) case IOSTAT_FABRIC_RJT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) if (irsp->un.ulpWord[4] & RJT_UNAVAIL_TEMP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) case IOSTAT_NPORT_BSY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) case IOSTAT_FABRIC_BSY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) logerr = 1; /* Fabric / Remote NPort out of resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) case IOSTAT_LS_RJT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) stat.un.lsRjtError = be32_to_cpu(irsp->un.ulpWord[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) /* Added for Vendor specifc support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) * Just keep retrying for these Rsn / Exp codes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) if ((vport->fc_flag & FC_PT2PT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) cmd == ELS_CMD_NVMEPRLI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) switch (stat.un.b.lsRjtRsnCode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) case LSRJT_UNABLE_TPC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) case LSRJT_INVALID_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) case LSRJT_LOGICAL_ERR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) case LSRJT_CMD_UNSUPPORTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) lpfc_printf_vlog(vport, KERN_WARNING, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) "0168 NVME PRLI LS_RJT "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) "reason %x port doesn't "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) "support NVME, disabling NVME\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) stat.un.b.lsRjtRsnCode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) retry = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) vport->fc_flag |= FC_PT2PT_NO_NVME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) goto out_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) switch (stat.un.b.lsRjtRsnCode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) case LSRJT_UNABLE_TPC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) /* The driver has a VALID PLOGI but the rport has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) * rejected the PRLI - can't do it now. Delay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) * for 1 second and try again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) * However, if explanation is REQ_UNSUPPORTED there's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) * no point to retry PRLI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) if ((cmd == ELS_CMD_PRLI || cmd == ELS_CMD_NVMEPRLI) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) stat.un.b.lsRjtRsnCodeExp !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) LSEXP_REQ_UNSUPPORTED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) delay = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) maxretry = lpfc_max_els_tries + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) /* Legacy bug fix code for targets with PLOGI delays. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) if (stat.un.b.lsRjtRsnCodeExp ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) LSEXP_CMD_IN_PROGRESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) if (cmd == ELS_CMD_PLOGI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) delay = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) maxretry = 48;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) if (stat.un.b.lsRjtRsnCodeExp ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) LSEXP_CANT_GIVE_DATA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) if (cmd == ELS_CMD_PLOGI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) delay = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) maxretry = 48;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) if (cmd == ELS_CMD_PLOGI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) delay = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) maxretry = lpfc_max_els_tries + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) (cmd == ELS_CMD_FDISC) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) (stat.un.b.lsRjtRsnCodeExp == LSEXP_OUT_OF_RESOURCE)){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) lpfc_printf_vlog(vport, KERN_ERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) "0125 FDISC Failed (x%x). "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) "Fabric out of resources\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) stat.un.lsRjtError);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) lpfc_vport_set_state(vport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) FC_VPORT_NO_FABRIC_RSCS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) case LSRJT_LOGICAL_BSY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) if ((cmd == ELS_CMD_PLOGI) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) (cmd == ELS_CMD_PRLI) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) (cmd == ELS_CMD_NVMEPRLI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) delay = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) maxretry = 48;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) } else if (cmd == ELS_CMD_FDISC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) /* FDISC retry policy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) maxretry = 48;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) if (cmdiocb->retry >= 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) delay = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) case LSRJT_LOGICAL_ERR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) /* There are some cases where switches return this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) * error when they are not ready and should be returning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) * Logical Busy. We should delay every time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) if (cmd == ELS_CMD_FDISC &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) stat.un.b.lsRjtRsnCodeExp == LSEXP_PORT_LOGIN_REQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) maxretry = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) delay = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) } else if (cmd == ELS_CMD_FLOGI &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) stat.un.b.lsRjtRsnCodeExp ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) LSEXP_NOTHING_MORE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) vport->fc_sparam.cmn.bbRcvSizeMsb &= 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) lpfc_printf_vlog(vport, KERN_ERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) "0820 FLOGI Failed (x%x). "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) "BBCredit Not Supported\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) stat.un.lsRjtError);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) case LSRJT_PROTOCOL_ERR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) (cmd == ELS_CMD_FDISC) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) ((stat.un.b.lsRjtRsnCodeExp == LSEXP_INVALID_PNAME) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) (stat.un.b.lsRjtRsnCodeExp == LSEXP_INVALID_NPORT_ID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) lpfc_printf_vlog(vport, KERN_ERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) "0122 FDISC Failed (x%x). "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) "Fabric Detected Bad WWN\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) stat.un.lsRjtError);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) lpfc_vport_set_state(vport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) FC_VPORT_FABRIC_REJ_WWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) case LSRJT_VENDOR_UNIQUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) if ((stat.un.b.vendorUnique == 0x45) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) (cmd == ELS_CMD_FLOGI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) goto out_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) case LSRJT_CMD_UNSUPPORTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) /* lpfc nvmet returns this type of LS_RJT when it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) * receives an FCP PRLI because lpfc nvmet only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) * support NVME. ELS request is terminated for FCP4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) * on this rport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) if (stat.un.b.lsRjtRsnCodeExp ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) LSEXP_REQ_UNSUPPORTED && cmd == ELS_CMD_PRLI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) ndlp->nlp_flag |= NLP_FCP_PRLI_RJT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) retry = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) goto out_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) case IOSTAT_INTERMED_RSP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) case IOSTAT_BA_RJT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) if (link_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) rc = lpfc_link_reset(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) /* Do not give up. Retry PLOGI one more time and attempt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) * link reset if PLOGI fails again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) delay = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) goto out_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) if (did == FDMI_DID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) if ((cmd == ELS_CMD_FLOGI) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) (phba->fc_topology != LPFC_TOPOLOGY_LOOP) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) !lpfc_error_lost_link(irsp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) /* FLOGI retry policy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) /* retry FLOGI forever */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) if (phba->link_flag != LS_LOOPBACK_MODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) maxretry = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) maxretry = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) if (cmdiocb->retry >= 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) delay = 5000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) else if (cmdiocb->retry >= 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) delay = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) } else if ((cmd == ELS_CMD_FDISC) && !lpfc_error_lost_link(irsp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) /* retry FDISCs every second up to devloss */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) maxretry = vport->cfg_devloss_tmo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) delay = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) cmdiocb->retry++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) if (maxretry && (cmdiocb->retry >= maxretry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) phba->fc_stat.elsRetryExceeded++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) retry = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) if ((vport->load_flag & FC_UNLOADING) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) retry = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) out_retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) if (retry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) if ((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_FDISC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) /* Stop retrying PLOGI and FDISC if in FCF discovery */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) if (phba->fcf.fcf_flag & FCF_DISCOVERY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) "2849 Stop retry ELS command "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) "x%x to remote NPORT x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) "Data: x%x x%x\n", cmd, did,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) cmdiocb->retry, delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) /* Retry ELS command <elsCmd> to remote NPORT <did> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) "0107 Retry ELS command x%x to remote "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) "NPORT x%x Data: x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) cmd, did, cmdiocb->retry, delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) if (((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_ADISC)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) ((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) IOERR_NO_RESOURCES))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) /* Don't reset timer for no resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) /* If discovery / RSCN timer is running, reset it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) if (timer_pending(&vport->fc_disctmo) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) (vport->fc_flag & FC_RSCN_MODE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) lpfc_set_disctmo(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) phba->fc_stat.elsXmitRetry++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) if (ndlp && NLP_CHK_NODE_ACT(ndlp) && delay) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) phba->fc_stat.elsDelayRetry++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) ndlp->nlp_retry = cmdiocb->retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) /* delay is specified in milliseconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) mod_timer(&ndlp->nlp_delayfunc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) jiffies + msecs_to_jiffies(delay));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) ndlp->nlp_flag |= NLP_DELAY_TMO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) ndlp->nlp_prev_state = ndlp->nlp_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) if ((cmd == ELS_CMD_PRLI) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) (cmd == ELS_CMD_NVMEPRLI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) lpfc_nlp_set_state(vport, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) NLP_STE_PRLI_ISSUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) lpfc_nlp_set_state(vport, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) NLP_STE_NPR_NODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) ndlp->nlp_last_elscmd = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) case ELS_CMD_FLOGI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) lpfc_issue_els_flogi(vport, ndlp, cmdiocb->retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) case ELS_CMD_FDISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) lpfc_issue_els_fdisc(vport, ndlp, cmdiocb->retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) case ELS_CMD_PLOGI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) ndlp->nlp_prev_state = ndlp->nlp_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) lpfc_nlp_set_state(vport, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) NLP_STE_PLOGI_ISSUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) lpfc_issue_els_plogi(vport, did, cmdiocb->retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) case ELS_CMD_ADISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) ndlp->nlp_prev_state = ndlp->nlp_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) lpfc_issue_els_adisc(vport, ndlp, cmdiocb->retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) case ELS_CMD_PRLI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) case ELS_CMD_NVMEPRLI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) ndlp->nlp_prev_state = ndlp->nlp_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) lpfc_issue_els_prli(vport, ndlp, cmdiocb->retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) case ELS_CMD_LOGO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) ndlp->nlp_prev_state = ndlp->nlp_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) lpfc_nlp_set_state(vport, ndlp, NLP_STE_LOGO_ISSUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) lpfc_issue_els_logo(vport, ndlp, cmdiocb->retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) /* No retry ELS command <elsCmd> to remote NPORT <did> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) if (logerr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) "0137 No retry ELS command x%x to remote "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) "NPORT x%x: Out of Resources: Error:x%x/%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) cmd, did, irsp->ulpStatus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) irsp->un.ulpWord[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) "0108 No retry ELS command x%x to remote "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) "NPORT x%x Retried:%d Error:x%x/%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) cmd, did, cmdiocb->retry, irsp->ulpStatus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) irsp->un.ulpWord[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) * lpfc_els_free_data - Free lpfc dma buffer and data structure with an iocb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) * @buf_ptr1: pointer to the lpfc DMA buffer data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) * This routine releases the lpfc DMA (Direct Memory Access) buffer(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) * associated with a command IOCB back to the lpfc DMA buffer pool. It first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) * checks to see whether there is a lpfc DMA buffer associated with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) * response of the command IOCB. If so, it will be released before releasing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) * the lpfc DMA buffer associated with the IOCB itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) * 0 - Successfully released lpfc DMA buffer (currently, always return 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) lpfc_els_free_data(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) struct lpfc_dmabuf *buf_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) /* Free the response before processing the command. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) if (!list_empty(&buf_ptr1->list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) list_remove_head(&buf_ptr1->list, buf_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) struct lpfc_dmabuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) kfree(buf_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) lpfc_mbuf_free(phba, buf_ptr1->virt, buf_ptr1->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) kfree(buf_ptr1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) * lpfc_els_free_bpl - Free lpfc dma buffer and data structure with bpl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) * @buf_ptr: pointer to the lpfc dma buffer data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) * This routine releases the lpfc Direct Memory Access (DMA) buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) * associated with a Buffer Pointer List (BPL) back to the lpfc DMA buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) * pool.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) * 0 - Successfully released lpfc DMA buffer (currently, always return 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) lpfc_els_free_bpl(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) kfree(buf_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) * lpfc_els_free_iocb - Free a command iocb and its associated resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) * @elsiocb: pointer to lpfc els command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) * This routine frees a command IOCB and its associated resources. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) * command IOCB data structure contains the reference to various associated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) * resources, these fields must be set to NULL if the associated reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) * not present:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) * context1 - reference to ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) * context2 - reference to cmd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) * context2->next - reference to rsp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) * context3 - reference to bpl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) * It first properly decrements the reference count held on ndlp for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) * IOCB completion callback function. If LPFC_DELAY_MEM_FREE flag is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) * set, it invokes the lpfc_els_free_data() routine to release the Direct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) * Memory Access (DMA) buffers associated with the IOCB. Otherwise, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) * adds the DMA buffer the @phba data structure for the delayed release.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) * If reference to the Buffer Pointer List (BPL) is present, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) * lpfc_els_free_bpl() routine is invoked to release the DMA memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) * associated with BPL. Finally, the lpfc_sli_release_iocbq() routine is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) * invoked to release the IOCB data structure back to @phba IOCBQ list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) * 0 - Success (currently, always return 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) struct lpfc_dmabuf *buf_ptr, *buf_ptr1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) ndlp = (struct lpfc_nodelist *)elsiocb->context1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) if (ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) if (ndlp->nlp_flag & NLP_DEFER_RM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) /* If the ndlp is not being used by another discovery
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) * thread, free it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) if (!lpfc_nlp_not_used(ndlp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) /* If ndlp is being used by another discovery
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) * thread, just clear NLP_DEFER_RM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) ndlp->nlp_flag &= ~NLP_DEFER_RM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) elsiocb->context1 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) /* context2 = cmd, context2->next = rsp, context3 = bpl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) if (elsiocb->context2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) if (elsiocb->iocb_flag & LPFC_DELAY_MEM_FREE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) /* Firmware could still be in progress of DMAing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) * payload, so don't free data buffer till after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) * a hbeat.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) elsiocb->iocb_flag &= ~LPFC_DELAY_MEM_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) buf_ptr = elsiocb->context2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) elsiocb->context2 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) if (buf_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) buf_ptr1 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) spin_lock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) if (!list_empty(&buf_ptr->list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) list_remove_head(&buf_ptr->list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) buf_ptr1, struct lpfc_dmabuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) INIT_LIST_HEAD(&buf_ptr1->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) list_add_tail(&buf_ptr1->list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) &phba->elsbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) phba->elsbuf_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) INIT_LIST_HEAD(&buf_ptr->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) list_add_tail(&buf_ptr->list, &phba->elsbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) phba->elsbuf_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) buf_ptr1 = (struct lpfc_dmabuf *) elsiocb->context2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) lpfc_els_free_data(phba, buf_ptr1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) elsiocb->context2 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) if (elsiocb->context3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) buf_ptr = (struct lpfc_dmabuf *) elsiocb->context3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) lpfc_els_free_bpl(phba, buf_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) elsiocb->context3 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) lpfc_sli_release_iocbq(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) * lpfc_cmpl_els_logo_acc - Completion callback function to logo acc response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) * @rspiocb: pointer to lpfc response iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414) * This routine is the completion callback function to the Logout (LOGO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) * Accept (ACC) Response ELS command. This routine is invoked to indicate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) * the completion of the LOGO process. It invokes the lpfc_nlp_not_used() to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) * release the ndlp if it has the last reference remaining (reference count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) * is 1). If succeeded (meaning ndlp released), it sets the IOCB context1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) * field to NULL to inform the following lpfc_els_free_iocb() routine no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) * ndlp reference count needs to be decremented. Otherwise, the ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) * reference use-count shall be decremented by the lpfc_els_free_iocb()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) * routine. Finally, the lpfc_els_free_iocb() is invoked to release the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) * IOCB data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) struct lpfc_iocbq *rspiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) struct lpfc_vport *vport = cmdiocb->vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) IOCB_t *irsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) irsp = &rspiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) "ACC LOGO cmpl: status:x%x/x%x did:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) irsp->ulpStatus, irsp->un.ulpWord[4], ndlp->nlp_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) /* ACC to LOGO completes to NPort <nlp_DID> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) "0109 ACC to LOGO completes to NPort x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) "Data: x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) ndlp->nlp_rpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) if (ndlp->nlp_state == NLP_STE_NPR_NODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) /* NPort Recovery mode or node is just allocated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) if (!lpfc_nlp_not_used(ndlp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) /* If the ndlp is being used by another discovery
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) * thread, just unregister the RPI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) lpfc_unreg_rpi(vport, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) /* Indicate the node has already released, should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) * not reference to it from within lpfc_els_free_iocb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) cmdiocb->context1 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) * The driver received a LOGO from the rport and has ACK'd it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) * At this point, the driver is done so release the IOCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) lpfc_els_free_iocb(phba, cmdiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) * lpfc_mbx_cmpl_dflt_rpi - Completion callbk func for unreg dflt rpi mbox cmd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) * @pmb: pointer to the driver internal queue element for mailbox command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) * This routine is the completion callback function for unregister default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) * RPI (Remote Port Index) mailbox command to the @phba. It simply releases
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) * the associated lpfc Direct Memory Access (DMA) buffer back to the pool and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) * decrements the ndlp reference count held for this completion callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) * function. After that, it invokes the lpfc_nlp_not_used() to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) * whether there is only one reference left on the ndlp. If so, it will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) * perform one more decrement and trigger the release of the ndlp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *)(pmb->ctx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483) struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *)pmb->ctx_ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) pmb->ctx_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) pmb->ctx_ndlp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) lpfc_mbuf_free(phba, mp->virt, mp->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) kfree(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) mempool_free(pmb, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) if (ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) "0006 rpi%x DID:%x flg:%x %d map:%x x%px\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494) ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) kref_read(&ndlp->kref),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) ndlp->nlp_usg_map, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) if (NLP_CHK_NODE_ACT(ndlp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) /* This is the end of the default RPI cleanup logic for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) * this ndlp. If no other discovery threads are using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) * this ndlp, free all resources associated with it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503) lpfc_nlp_not_used(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) lpfc_drop_node(ndlp->vport, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) * lpfc_cmpl_els_rsp - Completion callback function for els response iocb cmd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) * @rspiocb: pointer to lpfc response iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) * This routine is the completion callback function for ELS Response IOCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) * command. In normal case, this callback function just properly sets the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) * nlp_flag bitmap in the ndlp data structure, if the mbox command reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) * field in the command IOCB is not NULL, the referred mailbox command will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) * be send out, and then invokes the lpfc_els_free_iocb() routine to release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) * the IOCB. Under error conditions, such as when a LS_RJT is returned or a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) * link down event occurred during the discovery, the lpfc_nlp_not_used()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) * routine shall be invoked trying to release the ndlp if no other threads
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) * are currently referring it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) struct lpfc_iocbq *rspiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) struct lpfc_vport *vport = ndlp ? ndlp->vport : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) struct Scsi_Host *shost = vport ? lpfc_shost_from_vport(vport) : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) IOCB_t *irsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) uint8_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) LPFC_MBOXQ_t *mbox = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) struct lpfc_dmabuf *mp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) uint32_t ls_rjt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) irsp = &rspiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) if (!vport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) "3177 ELS response failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) if (cmdiocb->context_un.mbox)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) mbox = cmdiocb->context_un.mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) /* First determine if this is a LS_RJT cmpl. Note, this callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) * function can have cmdiocb->contest1 (ndlp) field set to NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) /* A LS_RJT associated with Default RPI cleanup has its own
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) * separate code path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) if (!(ndlp->nlp_flag & NLP_RM_DFLT_RPI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) ls_rjt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) /* Check to see if link went down during discovery */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) if (!ndlp || !NLP_CHK_NODE_ACT(ndlp) || lpfc_els_chk_latt(vport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) if (mbox) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) mp = (struct lpfc_dmabuf *)mbox->ctx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) if (mp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) lpfc_mbuf_free(phba, mp->virt, mp->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) kfree(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) mempool_free(mbox, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) (ndlp->nlp_flag & NLP_RM_DFLT_RPI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) if (lpfc_nlp_not_used(ndlp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) ndlp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) /* Indicate the node has already released,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) * should not reference to it from within
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) * the routine lpfc_els_free_iocb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) cmdiocb->context1 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) "ELS rsp cmpl: status:x%x/x%x did:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) irsp->ulpStatus, irsp->un.ulpWord[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) cmdiocb->iocb.un.elsreq64.remoteID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) /* ELS response tag <ulpIoTag> completes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) "0110 ELS response tag x%x completes "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) "Data: x%x x%x x%x x%x x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) cmdiocb->iocb.ulpIoTag, rspiocb->iocb.ulpStatus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) rspiocb->iocb.un.ulpWord[4], rspiocb->iocb.ulpTimeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598) ndlp->nlp_rpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) if (mbox) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) if ((rspiocb->iocb.ulpStatus == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601) && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) if (!lpfc_unreg_rpi(vport, ndlp) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) (!(vport->fc_flag & FC_PT2PT)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605) ndlp->nlp_state == NLP_STE_REG_LOGIN_ISSUE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) lpfc_printf_vlog(vport, KERN_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) LOG_DISCOVERY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) "0314 PLOGI recov DID x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) "Data: x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610) ndlp->nlp_DID, ndlp->nlp_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611) ndlp->nlp_rpi, ndlp->nlp_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) mp = mbox->ctx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) if (mp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614) lpfc_mbuf_free(phba, mp->virt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) mp->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616) kfree(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) mempool_free(mbox, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622) /* Increment reference count to ndlp to hold the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) * reference to ndlp for the callback function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) mbox->ctx_ndlp = lpfc_nlp_get(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) mbox->vport = vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627) if (ndlp->nlp_flag & NLP_RM_DFLT_RPI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) mbox->mbox_flag |= LPFC_MBX_IMED_UNREG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629) mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632) mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) ndlp->nlp_prev_state = ndlp->nlp_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) lpfc_nlp_set_state(vport, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) NLP_STE_REG_LOGIN_ISSUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) ndlp->nlp_flag |= NLP_REG_LOGIN_SEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639) if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640) != MBX_NOT_FINISHED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) /* Decrement the ndlp reference count we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644) * set for this failed mailbox command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647) ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) /* ELS rsp: Cannot issue reg_login for <NPortid> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) "0138 ELS rsp: Cannot issue reg_login for x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652) "Data: x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654) ndlp->nlp_rpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) if (lpfc_nlp_not_used(ndlp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) ndlp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658) /* Indicate node has already been released,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659) * should not reference to it from within
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) * the routine lpfc_els_free_iocb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) cmdiocb->context1 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665) /* Do not drop node for lpfc_els_abort'ed ELS cmds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666) if (!lpfc_error_lost_link(irsp) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667) ndlp->nlp_flag & NLP_ACC_REGLOGIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668) if (lpfc_nlp_not_used(ndlp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669) ndlp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670) /* Indicate node has already been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671) * released, should not reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672) * to it from within the routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673) * lpfc_els_free_iocb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675) cmdiocb->context1 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679) mp = (struct lpfc_dmabuf *)mbox->ctx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) if (mp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681) lpfc_mbuf_free(phba, mp->virt, mp->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682) kfree(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) mempool_free(mbox, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687) if (ndlp && NLP_CHK_NODE_ACT(ndlp) && shost) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689) if (mbox)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690) ndlp->nlp_flag &= ~NLP_ACC_REGLOGIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691) ndlp->nlp_flag &= ~NLP_RM_DFLT_RPI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694) /* If the node is not being used by another discovery thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) * and we are sending a reject, we are done with it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) * Release driver reference count here and free associated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697) * resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699) if (ls_rjt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) if (lpfc_nlp_not_used(ndlp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701) /* Indicate node has already been released,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702) * should not reference to it from within
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703) * the routine lpfc_els_free_iocb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705) cmdiocb->context1 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709) lpfc_els_free_iocb(phba, cmdiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714) * lpfc_els_rsp_acc - Prepare and issue an acc response iocb command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) * @flag: the els command code to be accepted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717) * @oldiocb: pointer to the original lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719) * @mbox: pointer to the driver internal queue element for mailbox command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721) * This routine prepares and issues an Accept (ACC) response IOCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722) * command. It uses the @flag to properly set up the IOCB field for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) * specific ACC response command to be issued and invokes the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) * lpfc_sli_issue_iocb() routine to send out ACC response IOCB. If a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725) * @mbox pointer is passed in, it will be put into the context_un.mbox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726) * field of the IOCB for the completion callback function to issue the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) * mailbox command to the HBA later when callback is invoked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730) * will be incremented by 1 for holding the ndlp and the reference to ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731) * will be stored into the context1 field of the IOCB for the completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) * callback function to the corresponding response ELS IOCB command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735) * 0 - Successfully issued acc response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) * 1 - Failed to issue acc response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740) struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) LPFC_MBOXQ_t *mbox)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745) IOCB_t *icmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746) IOCB_t *oldcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747) struct lpfc_iocbq *elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) uint8_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) struct serv_parm *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750) uint16_t cmdsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) ELS_PKT *els_pkt_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754) oldcmd = &oldiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) switch (flag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757) case ELS_CMD_ACC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) cmdsize = sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760) ndlp, ndlp->nlp_DID, ELS_CMD_ACC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761) if (!elsiocb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763) ndlp->nlp_flag &= ~NLP_LOGO_ACC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768) icmd = &elsiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) icmd->ulpContext = oldcmd->ulpContext; /* Xri / rx_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770) icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771) pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772) *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773) pcmd += sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776) "Issue ACC: did:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) ndlp->nlp_DID, ndlp->nlp_flag, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779) case ELS_CMD_FLOGI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780) case ELS_CMD_PLOGI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) cmdsize = (sizeof(struct serv_parm) + sizeof(uint32_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783) ndlp, ndlp->nlp_DID, ELS_CMD_ACC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784) if (!elsiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787) icmd = &elsiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788) icmd->ulpContext = oldcmd->ulpContext; /* Xri / rx_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789) icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790) pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792) if (mbox)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793) elsiocb->context_un.mbox = mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795) *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796) pcmd += sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797) sp = (struct serv_parm *)pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) if (flag == ELS_CMD_FLOGI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800) /* Copy the received service parameters back */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801) memcpy(sp, &phba->fc_fabparam,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802) sizeof(struct serv_parm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804) /* Clear the F_Port bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) sp->cmn.fPort = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) /* Mark all class service parameters as invalid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808) sp->cls1.classValid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) sp->cls2.classValid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810) sp->cls3.classValid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) sp->cls4.classValid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813) /* Copy our worldwide names */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814) memcpy(&sp->portName, &vport->fc_sparam.portName,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815) sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816) memcpy(&sp->nodeName, &vport->fc_sparam.nodeName,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817) sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819) memcpy(pcmd, &vport->fc_sparam,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820) sizeof(struct serv_parm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822) sp->cmn.valid_vendor_ver_level = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823) memset(sp->un.vendorVersion, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824) sizeof(sp->un.vendorVersion));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825) sp->cmn.bbRcvSizeMsb &= 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827) /* If our firmware supports this feature, convey that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828) * info to the target using the vendor specific field.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830) if (phba->sli.sli_flag & LPFC_SLI_SUPPRESS_RSP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) sp->cmn.valid_vendor_ver_level = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832) sp->un.vv.vid = cpu_to_be32(LPFC_VV_EMLX_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833) sp->un.vv.flags =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834) cpu_to_be32(LPFC_VV_SUPPRESS_RSP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) "Issue ACC FLOGI/PLOGI: did:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840) ndlp->nlp_DID, ndlp->nlp_flag, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842) case ELS_CMD_PRLO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843) cmdsize = sizeof(uint32_t) + sizeof(PRLO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845) ndlp, ndlp->nlp_DID, ELS_CMD_PRLO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846) if (!elsiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849) icmd = &elsiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850) icmd->ulpContext = oldcmd->ulpContext; /* Xri / rx_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851) icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852) pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854) memcpy(pcmd, ((struct lpfc_dmabuf *) oldiocb->context2)->virt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855) sizeof(uint32_t) + sizeof(PRLO));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856) *((uint32_t *) (pcmd)) = ELS_CMD_PRLO_ACC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857) els_pkt_ptr = (ELS_PKT *) pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) els_pkt_ptr->un.prlo.acceptRspCode = PRLO_REQ_EXECUTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) "Issue ACC PRLO: did:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862) ndlp->nlp_DID, ndlp->nlp_flag, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867) if (ndlp->nlp_flag & NLP_LOGO_ACC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) if (!(ndlp->nlp_flag & NLP_RPI_REGISTERED ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870) ndlp->nlp_flag & NLP_REG_LOGIN_SEND))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871) ndlp->nlp_flag &= ~NLP_LOGO_ACC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873) elsiocb->iocb_cmpl = lpfc_cmpl_els_logo_acc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878) phba->fc_stat.elsXmitACC++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879) rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) if (rc == IOCB_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888) * lpfc_els_rsp_reject - Propare and issue a rjt response iocb command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889) * @vport: pointer to a virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890) * @rejectError: reject response to issue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891) * @oldiocb: pointer to the original lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893) * @mbox: pointer to the driver internal queue element for mailbox command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895) * This routine prepares and issue an Reject (RJT) response IOCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896) * command. If a @mbox pointer is passed in, it will be put into the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) * context_un.mbox field of the IOCB for the completion callback function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898) * to issue to the HBA later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900) * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901) * will be incremented by 1 for holding the ndlp and the reference to ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902) * will be stored into the context1 field of the IOCB for the completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903) * callback function to the reject response ELS IOCB command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906) * 0 - Successfully issued reject response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907) * 1 - Failed to issue reject response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910) lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911) struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912) LPFC_MBOXQ_t *mbox)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915) IOCB_t *icmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916) IOCB_t *oldcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917) struct lpfc_iocbq *elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) uint8_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919) uint16_t cmdsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922) cmdsize = 2 * sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923) elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4924) ndlp->nlp_DID, ELS_CMD_LS_RJT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4925) if (!elsiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4926) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4928) icmd = &elsiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4929) oldcmd = &oldiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4930) icmd->ulpContext = oldcmd->ulpContext; /* Xri / rx_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4931) icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4932) pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4934) *((uint32_t *) (pcmd)) = ELS_CMD_LS_RJT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4935) pcmd += sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4936) *((uint32_t *) (pcmd)) = rejectError;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4938) if (mbox)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4939) elsiocb->context_un.mbox = mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4941) /* Xmit ELS RJT <err> response tag <ulpIoTag> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4942) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4943) "0129 Xmit ELS RJT x%x response tag x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4944) "xri x%x, did x%x, nlp_flag x%x, nlp_state x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4945) "rpi x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4946) rejectError, elsiocb->iotag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4947) elsiocb->iocb.ulpContext, ndlp->nlp_DID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4948) ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4949) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4950) "Issue LS_RJT: did:x%x flg:x%x err:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4951) ndlp->nlp_DID, ndlp->nlp_flag, rejectError);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4953) phba->fc_stat.elsXmitLSRJT++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4954) elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4955) rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4957) if (rc == IOCB_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4958) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4959) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4961) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4964) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4965) * lpfc_els_rsp_adisc_acc - Prepare and issue acc response to adisc iocb cmd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4966) * @vport: pointer to a virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4967) * @oldiocb: pointer to the original lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4968) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4969) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4970) * This routine prepares and issues an Accept (ACC) response to Address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4971) * Discover (ADISC) ELS command. It simply prepares the payload of the IOCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4972) * and invokes the lpfc_sli_issue_iocb() routine to send out the command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4973) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4974) * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4975) * will be incremented by 1 for holding the ndlp and the reference to ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4976) * will be stored into the context1 field of the IOCB for the completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4977) * callback function to the ADISC Accept response ELS IOCB command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4978) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4979) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4980) * 0 - Successfully issued acc adisc response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4981) * 1 - Failed to issue adisc acc response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4982) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4983) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4984) lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4985) struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4986) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4987) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4988) ADISC *ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4989) IOCB_t *icmd, *oldcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4990) struct lpfc_iocbq *elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4991) uint8_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4992) uint16_t cmdsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4993) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4995) cmdsize = sizeof(uint32_t) + sizeof(ADISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4996) elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4997) ndlp->nlp_DID, ELS_CMD_ACC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4998) if (!elsiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4999) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5001) icmd = &elsiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5002) oldcmd = &oldiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5003) icmd->ulpContext = oldcmd->ulpContext; /* Xri / rx_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5004) icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5006) /* Xmit ADISC ACC response tag <ulpIoTag> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5007) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5008) "0130 Xmit ADISC ACC response iotag x%x xri: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5009) "x%x, did x%x, nlp_flag x%x, nlp_state x%x rpi x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5010) elsiocb->iotag, elsiocb->iocb.ulpContext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5011) ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5012) ndlp->nlp_rpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5013) pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5015) *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5016) pcmd += sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5018) ap = (ADISC *) (pcmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5019) ap->hardAL_PA = phba->fc_pref_ALPA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5020) memcpy(&ap->portName, &vport->fc_portname, sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5021) memcpy(&ap->nodeName, &vport->fc_nodename, sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5022) ap->DID = be32_to_cpu(vport->fc_myDID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5024) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5025) "Issue ACC ADISC: did:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5026) ndlp->nlp_DID, ndlp->nlp_flag, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5028) phba->fc_stat.elsXmitACC++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5029) elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5030) rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5031) if (rc == IOCB_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5032) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5033) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5036) /* Xmit ELS ACC response tag <ulpIoTag> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5037) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5038) "0128 Xmit ELS ACC response Status: x%x, IoTag: x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5039) "XRI: x%x, DID: x%x, nlp_flag: x%x nlp_state: x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5040) "RPI: x%x, fc_flag x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5041) rc, elsiocb->iotag, elsiocb->sli4_xritag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5042) ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5043) ndlp->nlp_rpi, vport->fc_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5044) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5047) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5048) * lpfc_els_rsp_prli_acc - Prepare and issue acc response to prli iocb cmd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5049) * @vport: pointer to a virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5050) * @oldiocb: pointer to the original lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5051) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5052) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5053) * This routine prepares and issues an Accept (ACC) response to Process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5054) * Login (PRLI) ELS command. It simply prepares the payload of the IOCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5055) * and invokes the lpfc_sli_issue_iocb() routine to send out the command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5056) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5057) * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5058) * will be incremented by 1 for holding the ndlp and the reference to ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5059) * will be stored into the context1 field of the IOCB for the completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5060) * callback function to the PRLI Accept response ELS IOCB command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5061) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5062) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5063) * 0 - Successfully issued acc prli response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5064) * 1 - Failed to issue acc prli response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5065) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5066) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5067) lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5068) struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5069) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5070) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5071) PRLI *npr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5072) struct lpfc_nvme_prli *npr_nvme;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5073) lpfc_vpd_t *vpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5074) IOCB_t *icmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5075) IOCB_t *oldcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5076) struct lpfc_iocbq *elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5077) uint8_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5078) uint16_t cmdsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5079) uint32_t prli_fc4_req, *req_payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5080) struct lpfc_dmabuf *req_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5081) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5082) u32 elsrspcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5084) /* Need the incoming PRLI payload to determine if the ACC is for an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5085) * FC4 or NVME PRLI type. The PRLI type is at word 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5086) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5087) req_buf = (struct lpfc_dmabuf *)oldiocb->context2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5088) req_payload = (((uint32_t *)req_buf->virt) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5090) /* PRLI type payload is at byte 3 for FCP or NVME. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5091) prli_fc4_req = be32_to_cpu(*req_payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5092) prli_fc4_req = (prli_fc4_req >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5093) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5094) "6127 PRLI_ACC: Req Type x%x, Word1 x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5095) prli_fc4_req, *((uint32_t *)req_payload));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5097) if (prli_fc4_req == PRLI_FCP_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5098) cmdsize = sizeof(uint32_t) + sizeof(PRLI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5099) elsrspcmd = (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5100) } else if (prli_fc4_req & PRLI_NVME_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5101) cmdsize = sizeof(uint32_t) + sizeof(struct lpfc_nvme_prli);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5102) elsrspcmd = (ELS_CMD_ACC | (ELS_CMD_NVMEPRLI & ~ELS_RSP_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5103) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5104) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5107) elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5108) ndlp->nlp_DID, elsrspcmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5109) if (!elsiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5110) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5112) icmd = &elsiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5113) oldcmd = &oldiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5114) icmd->ulpContext = oldcmd->ulpContext; /* Xri / rx_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5115) icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5117) /* Xmit PRLI ACC response tag <ulpIoTag> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5118) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5119) "0131 Xmit PRLI ACC response tag x%x xri x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5120) "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5121) elsiocb->iotag, elsiocb->iocb.ulpContext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5122) ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5123) ndlp->nlp_rpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5124) pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5125) memset(pcmd, 0, cmdsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5127) *((uint32_t *)(pcmd)) = elsrspcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5128) pcmd += sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5130) /* For PRLI, remainder of payload is PRLI parameter page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5131) vpd = &phba->vpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5133) if (prli_fc4_req == PRLI_FCP_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5134) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5135) * If the remote port is a target and our firmware version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5136) * is 3.20 or later, set the following bits for FC-TAPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5137) * support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5139) npr = (PRLI *) pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5140) if ((ndlp->nlp_type & NLP_FCP_TARGET) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5141) (vpd->rev.feaLevelHigh >= 0x02)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5142) npr->ConfmComplAllowed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5143) npr->Retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5144) npr->TaskRetryIdReq = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5146) npr->acceptRspCode = PRLI_REQ_EXECUTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5147) npr->estabImagePair = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5148) npr->readXferRdyDis = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5149) npr->ConfmComplAllowed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5150) npr->prliType = PRLI_FCP_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5151) npr->initiatorFunc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5152) } else if (prli_fc4_req & PRLI_NVME_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5153) /* Respond with an NVME PRLI Type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5154) npr_nvme = (struct lpfc_nvme_prli *) pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5155) bf_set(prli_type_code, npr_nvme, PRLI_NVME_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5156) bf_set(prli_estabImagePair, npr_nvme, 0); /* Should be 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5157) bf_set(prli_acc_rsp_code, npr_nvme, PRLI_REQ_EXECUTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5158) if (phba->nvmet_support) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5159) bf_set(prli_tgt, npr_nvme, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5160) bf_set(prli_disc, npr_nvme, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5161) if (phba->cfg_nvme_enable_fb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5162) bf_set(prli_fba, npr_nvme, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5164) /* TBD. Target mode needs to post buffers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5165) * that support the configured first burst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5166) * byte size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5167) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5168) bf_set(prli_fb_sz, npr_nvme,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5169) phba->cfg_nvmet_fb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5171) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5172) bf_set(prli_init, npr_nvme, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5175) lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5176) "6015 NVME issue PRLI ACC word1 x%08x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5177) "word4 x%08x word5 x%08x flag x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5178) "fcp_info x%x nlp_type x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5179) npr_nvme->word1, npr_nvme->word4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5180) npr_nvme->word5, ndlp->nlp_flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5181) ndlp->nlp_fcp_info, ndlp->nlp_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5182) npr_nvme->word1 = cpu_to_be32(npr_nvme->word1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5183) npr_nvme->word4 = cpu_to_be32(npr_nvme->word4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5184) npr_nvme->word5 = cpu_to_be32(npr_nvme->word5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5185) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5186) lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5187) "6128 Unknown FC_TYPE x%x x%x ndlp x%06x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5188) prli_fc4_req, ndlp->nlp_fc4_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5189) ndlp->nlp_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5191) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5192) "Issue ACC PRLI: did:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5193) ndlp->nlp_DID, ndlp->nlp_flag, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5195) phba->fc_stat.elsXmitACC++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5196) elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5198) rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5199) if (rc == IOCB_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5200) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5201) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5203) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5206) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5207) * lpfc_els_rsp_rnid_acc - Issue rnid acc response iocb command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5208) * @vport: pointer to a virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5209) * @format: rnid command format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5210) * @oldiocb: pointer to the original lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5211) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5212) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5213) * This routine issues a Request Node Identification Data (RNID) Accept
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5214) * (ACC) response. It constructs the RNID ACC response command according to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5215) * the proper @format and then calls the lpfc_sli_issue_iocb() routine to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5216) * issue the response. Note that this command does not need to hold the ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5217) * reference count for the callback. So, the ndlp reference count taken by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5218) * the lpfc_prep_els_iocb() routine is put back and the context1 field of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5219) * IOCB is set to NULL to indicate to the lpfc_els_free_iocb() routine that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5220) * there is no ndlp reference available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5221) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5222) * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5223) * will be incremented by 1 for holding the ndlp and the reference to ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5224) * will be stored into the context1 field of the IOCB for the completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5225) * callback function. However, for the RNID Accept Response ELS command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5226) * this is undone later by this routine after the IOCB is allocated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5227) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5228) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5229) * 0 - Successfully issued acc rnid response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5230) * 1 - Failed to issue acc rnid response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5231) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5232) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5233) lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5234) struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5236) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5237) RNID *rn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5238) IOCB_t *icmd, *oldcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5239) struct lpfc_iocbq *elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5240) uint8_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5241) uint16_t cmdsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5242) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5244) cmdsize = sizeof(uint32_t) + sizeof(uint32_t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5245) + (2 * sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5246) if (format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5247) cmdsize += sizeof(RNID_TOP_DISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5249) elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5250) ndlp->nlp_DID, ELS_CMD_ACC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5251) if (!elsiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5252) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5254) icmd = &elsiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5255) oldcmd = &oldiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5256) icmd->ulpContext = oldcmd->ulpContext; /* Xri / rx_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5257) icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5259) /* Xmit RNID ACC response tag <ulpIoTag> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5260) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5261) "0132 Xmit RNID ACC response tag x%x xri x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5262) elsiocb->iotag, elsiocb->iocb.ulpContext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5263) pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5264) *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5265) pcmd += sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5267) memset(pcmd, 0, sizeof(RNID));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5268) rn = (RNID *) (pcmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5269) rn->Format = format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5270) rn->CommonLen = (2 * sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5271) memcpy(&rn->portName, &vport->fc_portname, sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5272) memcpy(&rn->nodeName, &vport->fc_nodename, sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5273) switch (format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5274) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5275) rn->SpecificLen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5276) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5277) case RNID_TOPOLOGY_DISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5278) rn->SpecificLen = sizeof(RNID_TOP_DISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5279) memcpy(&rn->un.topologyDisc.portName,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5280) &vport->fc_portname, sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5281) rn->un.topologyDisc.unitType = RNID_HBA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5282) rn->un.topologyDisc.physPort = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5283) rn->un.topologyDisc.attachedNodes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5284) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5285) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5286) rn->CommonLen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5287) rn->SpecificLen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5288) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5291) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5292) "Issue ACC RNID: did:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5293) ndlp->nlp_DID, ndlp->nlp_flag, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5295) phba->fc_stat.elsXmitACC++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5296) elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5298) rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5299) if (rc == IOCB_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5300) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5301) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5303) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5306) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5307) * lpfc_els_clear_rrq - Clear the rq that this rrq describes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5308) * @vport: pointer to a virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5309) * @iocb: pointer to the lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5310) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5311) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5312) * Return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5313) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5314) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5315) lpfc_els_clear_rrq(struct lpfc_vport *vport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5316) struct lpfc_iocbq *iocb, struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5318) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5319) uint8_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5320) struct RRQ *rrq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5321) uint16_t rxid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5322) uint16_t xri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5323) struct lpfc_node_rrq *prrq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5326) pcmd = (uint8_t *) (((struct lpfc_dmabuf *) iocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5327) pcmd += sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5328) rrq = (struct RRQ *)pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5329) rrq->rrq_exchg = be32_to_cpu(rrq->rrq_exchg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5330) rxid = bf_get(rrq_rxid, rrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5332) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5333) "2883 Clear RRQ for SID:x%x OXID:x%x RXID:x%x"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5334) " x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5335) be32_to_cpu(bf_get(rrq_did, rrq)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5336) bf_get(rrq_oxid, rrq),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5337) rxid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5338) iocb->iotag, iocb->iocb.ulpContext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5340) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5341) "Clear RRQ: did:x%x flg:x%x exchg:x%.08x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5342) ndlp->nlp_DID, ndlp->nlp_flag, rrq->rrq_exchg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5343) if (vport->fc_myDID == be32_to_cpu(bf_get(rrq_did, rrq)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5344) xri = bf_get(rrq_oxid, rrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5345) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5346) xri = rxid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5347) prrq = lpfc_get_active_rrq(vport, xri, ndlp->nlp_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5348) if (prrq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5349) lpfc_clr_rrq_active(phba, xri, prrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5350) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5353) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5354) * lpfc_els_rsp_echo_acc - Issue echo acc response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5355) * @vport: pointer to a virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5356) * @data: pointer to echo data to return in the accept.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5357) * @oldiocb: pointer to the original lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5358) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5359) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5360) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5361) * 0 - Successfully issued acc echo response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5362) * 1 - Failed to issue acc echo response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5363) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5364) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5365) lpfc_els_rsp_echo_acc(struct lpfc_vport *vport, uint8_t *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5366) struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5368) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5369) struct lpfc_iocbq *elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5370) uint8_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5371) uint16_t cmdsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5372) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5374) cmdsize = oldiocb->iocb.unsli3.rcvsli3.acc_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5376) /* The accumulated length can exceed the BPL_SIZE. For
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5377) * now, use this as the limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5378) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5379) if (cmdsize > LPFC_BPL_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5380) cmdsize = LPFC_BPL_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5381) elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5382) ndlp->nlp_DID, ELS_CMD_ACC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5383) if (!elsiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5384) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5386) elsiocb->iocb.ulpContext = oldiocb->iocb.ulpContext; /* Xri / rx_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5387) elsiocb->iocb.unsli3.rcvsli3.ox_id = oldiocb->iocb.unsli3.rcvsli3.ox_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5389) /* Xmit ECHO ACC response tag <ulpIoTag> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5390) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5391) "2876 Xmit ECHO ACC response tag x%x xri x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5392) elsiocb->iotag, elsiocb->iocb.ulpContext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5393) pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5394) *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5395) pcmd += sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5396) memcpy(pcmd, data, cmdsize - sizeof(uint32_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5398) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5399) "Issue ACC ECHO: did:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5400) ndlp->nlp_DID, ndlp->nlp_flag, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5402) phba->fc_stat.elsXmitACC++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5403) elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5405) rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5406) if (rc == IOCB_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5407) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5408) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5410) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5413) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5414) * lpfc_els_disc_adisc - Issue remaining adisc iocbs to npr nodes of a vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5415) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5416) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5417) * This routine issues Address Discover (ADISC) ELS commands to those
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5418) * N_Ports which are in node port recovery state and ADISC has not been issued
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5419) * for the @vport. Each time an ELS ADISC IOCB is issued by invoking the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5420) * lpfc_issue_els_adisc() routine, the per @vport number of discover count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5421) * (num_disc_nodes) shall be incremented. If the num_disc_nodes reaches a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5422) * pre-configured threshold (cfg_discovery_threads), the @vport fc_flag will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5423) * be marked with FC_NLP_MORE bit and the process of issuing remaining ADISC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5424) * IOCBs quit for later pick up. On the other hand, after walking through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5425) * all the ndlps with the @vport and there is none ADISC IOCB issued, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5426) * @vport fc_flag shall be cleared with FC_NLP_MORE bit indicating there is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5427) * no more ADISC need to be sent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5428) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5429) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5430) * The number of N_Ports with adisc issued.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5431) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5432) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5433) lpfc_els_disc_adisc(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5435) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5436) struct lpfc_nodelist *ndlp, *next_ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5437) int sentadisc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5439) /* go thru NPR nodes and issue any remaining ELS ADISCs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5440) list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5441) if (!NLP_CHK_NODE_ACT(ndlp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5442) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5443) if (ndlp->nlp_state == NLP_STE_NPR_NODE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5444) (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5445) (ndlp->nlp_flag & NLP_NPR_ADISC) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5446) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5447) ndlp->nlp_flag &= ~NLP_NPR_ADISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5448) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5449) ndlp->nlp_prev_state = ndlp->nlp_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5450) lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5451) lpfc_issue_els_adisc(vport, ndlp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5452) sentadisc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5453) vport->num_disc_nodes++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5454) if (vport->num_disc_nodes >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5455) vport->cfg_discovery_threads) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5456) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5457) vport->fc_flag |= FC_NLP_MORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5458) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5459) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5463) if (sentadisc == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5464) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5465) vport->fc_flag &= ~FC_NLP_MORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5466) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5468) return sentadisc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5471) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5472) * lpfc_els_disc_plogi - Issue plogi for all npr nodes of a vport before adisc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5473) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5474) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5475) * This routine issues Port Login (PLOGI) ELS commands to all the N_Ports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5476) * which are in node port recovery state, with a @vport. Each time an ELS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5477) * ADISC PLOGI IOCB is issued by invoking the lpfc_issue_els_plogi() routine,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5478) * the per @vport number of discover count (num_disc_nodes) shall be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5479) * incremented. If the num_disc_nodes reaches a pre-configured threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5480) * (cfg_discovery_threads), the @vport fc_flag will be marked with FC_NLP_MORE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5481) * bit set and quit the process of issuing remaining ADISC PLOGIN IOCBs for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5482) * later pick up. On the other hand, after walking through all the ndlps with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5483) * the @vport and there is none ADISC PLOGI IOCB issued, the @vport fc_flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5484) * shall be cleared with the FC_NLP_MORE bit indicating there is no more ADISC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5485) * PLOGI need to be sent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5486) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5487) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5488) * The number of N_Ports with plogi issued.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5489) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5490) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5491) lpfc_els_disc_plogi(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5493) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5494) struct lpfc_nodelist *ndlp, *next_ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5495) int sentplogi = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5497) /* go thru NPR nodes and issue any remaining ELS PLOGIs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5498) list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5499) if (!NLP_CHK_NODE_ACT(ndlp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5500) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5501) if (ndlp->nlp_state == NLP_STE_NPR_NODE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5502) (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5503) (ndlp->nlp_flag & NLP_DELAY_TMO) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5504) (ndlp->nlp_flag & NLP_NPR_ADISC) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5505) ndlp->nlp_prev_state = ndlp->nlp_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5506) lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5507) lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5508) sentplogi++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5509) vport->num_disc_nodes++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5510) if (vport->num_disc_nodes >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5511) vport->cfg_discovery_threads) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5512) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5513) vport->fc_flag |= FC_NLP_MORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5514) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5515) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5520) lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5521) "6452 Discover PLOGI %d flag x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5522) sentplogi, vport->fc_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5524) if (sentplogi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5525) lpfc_set_disctmo(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5527) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5528) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5529) vport->fc_flag &= ~FC_NLP_MORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5530) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5532) return sentplogi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5535) static uint32_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5536) lpfc_rdp_res_link_service(struct fc_rdp_link_service_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5537) uint32_t word0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5540) desc->tag = cpu_to_be32(RDP_LINK_SERVICE_DESC_TAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5541) desc->payload.els_req = word0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5542) desc->length = cpu_to_be32(sizeof(desc->payload));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5544) return sizeof(struct fc_rdp_link_service_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5547) static uint32_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5548) lpfc_rdp_res_sfp_desc(struct fc_rdp_sfp_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5549) uint8_t *page_a0, uint8_t *page_a2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5551) uint16_t wavelength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5552) uint16_t temperature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5553) uint16_t rx_power;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5554) uint16_t tx_bias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5555) uint16_t tx_power;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5556) uint16_t vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5557) uint16_t flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5558) struct sff_trasnceiver_codes_byte4 *trasn_code_byte4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5559) struct sff_trasnceiver_codes_byte5 *trasn_code_byte5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5561) desc->tag = cpu_to_be32(RDP_SFP_DESC_TAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5563) trasn_code_byte4 = (struct sff_trasnceiver_codes_byte4 *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5564) &page_a0[SSF_TRANSCEIVER_CODE_B4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5565) trasn_code_byte5 = (struct sff_trasnceiver_codes_byte5 *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5566) &page_a0[SSF_TRANSCEIVER_CODE_B5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5568) if ((trasn_code_byte4->fc_sw_laser) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5569) (trasn_code_byte5->fc_sw_laser_sl) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5570) (trasn_code_byte5->fc_sw_laser_sn)) { /* check if its short WL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5571) flag |= (SFP_FLAG_PT_SWLASER << SFP_FLAG_PT_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5572) } else if (trasn_code_byte4->fc_lw_laser) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5573) wavelength = (page_a0[SSF_WAVELENGTH_B1] << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5574) page_a0[SSF_WAVELENGTH_B0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5575) if (wavelength == SFP_WAVELENGTH_LC1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5576) flag |= SFP_FLAG_PT_LWLASER_LC1310 << SFP_FLAG_PT_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5577) if (wavelength == SFP_WAVELENGTH_LL1550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5578) flag |= SFP_FLAG_PT_LWLASER_LL1550 << SFP_FLAG_PT_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5580) /* check if its SFP+ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5581) flag |= ((page_a0[SSF_IDENTIFIER] == SFF_PG0_IDENT_SFP) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5582) SFP_FLAG_CT_SFP_PLUS : SFP_FLAG_CT_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5583) << SFP_FLAG_CT_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5585) /* check if its OPTICAL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5586) flag |= ((page_a0[SSF_CONNECTOR] == SFF_PG0_CONNECTOR_LC) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5587) SFP_FLAG_IS_OPTICAL_PORT : 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5588) << SFP_FLAG_IS_OPTICAL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5590) temperature = (page_a2[SFF_TEMPERATURE_B1] << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5591) page_a2[SFF_TEMPERATURE_B0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5592) vcc = (page_a2[SFF_VCC_B1] << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5593) page_a2[SFF_VCC_B0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5594) tx_power = (page_a2[SFF_TXPOWER_B1] << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5595) page_a2[SFF_TXPOWER_B0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5596) tx_bias = (page_a2[SFF_TX_BIAS_CURRENT_B1] << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5597) page_a2[SFF_TX_BIAS_CURRENT_B0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5598) rx_power = (page_a2[SFF_RXPOWER_B1] << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5599) page_a2[SFF_RXPOWER_B0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5600) desc->sfp_info.temperature = cpu_to_be16(temperature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5601) desc->sfp_info.rx_power = cpu_to_be16(rx_power);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5602) desc->sfp_info.tx_bias = cpu_to_be16(tx_bias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5603) desc->sfp_info.tx_power = cpu_to_be16(tx_power);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5604) desc->sfp_info.vcc = cpu_to_be16(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5606) desc->sfp_info.flags = cpu_to_be16(flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5607) desc->length = cpu_to_be32(sizeof(desc->sfp_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5609) return sizeof(struct fc_rdp_sfp_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5612) static uint32_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5613) lpfc_rdp_res_link_error(struct fc_rdp_link_error_status_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5614) READ_LNK_VAR *stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5616) uint32_t type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5618) desc->tag = cpu_to_be32(RDP_LINK_ERROR_STATUS_DESC_TAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5620) type = VN_PT_PHY_PF_PORT << VN_PT_PHY_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5622) desc->info.port_type = cpu_to_be32(type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5624) desc->info.link_status.link_failure_cnt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5625) cpu_to_be32(stat->linkFailureCnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5626) desc->info.link_status.loss_of_synch_cnt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5627) cpu_to_be32(stat->lossSyncCnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5628) desc->info.link_status.loss_of_signal_cnt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5629) cpu_to_be32(stat->lossSignalCnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5630) desc->info.link_status.primitive_seq_proto_err =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5631) cpu_to_be32(stat->primSeqErrCnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5632) desc->info.link_status.invalid_trans_word =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5633) cpu_to_be32(stat->invalidXmitWord);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5634) desc->info.link_status.invalid_crc_cnt = cpu_to_be32(stat->crcCnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5636) desc->length = cpu_to_be32(sizeof(desc->info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5638) return sizeof(struct fc_rdp_link_error_status_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5641) static uint32_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5642) lpfc_rdp_res_bbc_desc(struct fc_rdp_bbc_desc *desc, READ_LNK_VAR *stat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5643) struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5645) uint32_t bbCredit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5647) desc->tag = cpu_to_be32(RDP_BBC_DESC_TAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5649) bbCredit = vport->fc_sparam.cmn.bbCreditLsb |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5650) (vport->fc_sparam.cmn.bbCreditMsb << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5651) desc->bbc_info.port_bbc = cpu_to_be32(bbCredit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5652) if (vport->phba->fc_topology != LPFC_TOPOLOGY_LOOP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5653) bbCredit = vport->phba->fc_fabparam.cmn.bbCreditLsb |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5654) (vport->phba->fc_fabparam.cmn.bbCreditMsb << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5655) desc->bbc_info.attached_port_bbc = cpu_to_be32(bbCredit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5656) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5657) desc->bbc_info.attached_port_bbc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5660) desc->bbc_info.rtt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5661) desc->length = cpu_to_be32(sizeof(desc->bbc_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5663) return sizeof(struct fc_rdp_bbc_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5666) static uint32_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5667) lpfc_rdp_res_oed_temp_desc(struct lpfc_hba *phba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5668) struct fc_rdp_oed_sfp_desc *desc, uint8_t *page_a2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5670) uint32_t flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5672) desc->tag = cpu_to_be32(RDP_OED_DESC_TAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5674) desc->oed_info.hi_alarm = page_a2[SSF_TEMP_HIGH_ALARM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5675) desc->oed_info.lo_alarm = page_a2[SSF_TEMP_LOW_ALARM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5676) desc->oed_info.hi_warning = page_a2[SSF_TEMP_HIGH_WARNING];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5677) desc->oed_info.lo_warning = page_a2[SSF_TEMP_LOW_WARNING];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5679) if (phba->sfp_alarm & LPFC_TRANSGRESSION_HIGH_TEMPERATURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5680) flags |= RDP_OET_HIGH_ALARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5681) if (phba->sfp_alarm & LPFC_TRANSGRESSION_LOW_TEMPERATURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5682) flags |= RDP_OET_LOW_ALARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5683) if (phba->sfp_warning & LPFC_TRANSGRESSION_HIGH_TEMPERATURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5684) flags |= RDP_OET_HIGH_WARNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5685) if (phba->sfp_warning & LPFC_TRANSGRESSION_LOW_TEMPERATURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5686) flags |= RDP_OET_LOW_WARNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5688) flags |= ((0xf & RDP_OED_TEMPERATURE) << RDP_OED_TYPE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5689) desc->oed_info.function_flags = cpu_to_be32(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5690) desc->length = cpu_to_be32(sizeof(desc->oed_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5691) return sizeof(struct fc_rdp_oed_sfp_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5694) static uint32_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5695) lpfc_rdp_res_oed_voltage_desc(struct lpfc_hba *phba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5696) struct fc_rdp_oed_sfp_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5697) uint8_t *page_a2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5699) uint32_t flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5701) desc->tag = cpu_to_be32(RDP_OED_DESC_TAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5703) desc->oed_info.hi_alarm = page_a2[SSF_VOLTAGE_HIGH_ALARM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5704) desc->oed_info.lo_alarm = page_a2[SSF_VOLTAGE_LOW_ALARM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5705) desc->oed_info.hi_warning = page_a2[SSF_VOLTAGE_HIGH_WARNING];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5706) desc->oed_info.lo_warning = page_a2[SSF_VOLTAGE_LOW_WARNING];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5708) if (phba->sfp_alarm & LPFC_TRANSGRESSION_HIGH_VOLTAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5709) flags |= RDP_OET_HIGH_ALARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5710) if (phba->sfp_alarm & LPFC_TRANSGRESSION_LOW_VOLTAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5711) flags |= RDP_OET_LOW_ALARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5712) if (phba->sfp_warning & LPFC_TRANSGRESSION_HIGH_VOLTAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5713) flags |= RDP_OET_HIGH_WARNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5714) if (phba->sfp_warning & LPFC_TRANSGRESSION_LOW_VOLTAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5715) flags |= RDP_OET_LOW_WARNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5717) flags |= ((0xf & RDP_OED_VOLTAGE) << RDP_OED_TYPE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5718) desc->oed_info.function_flags = cpu_to_be32(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5719) desc->length = cpu_to_be32(sizeof(desc->oed_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5720) return sizeof(struct fc_rdp_oed_sfp_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5723) static uint32_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5724) lpfc_rdp_res_oed_txbias_desc(struct lpfc_hba *phba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5725) struct fc_rdp_oed_sfp_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5726) uint8_t *page_a2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5728) uint32_t flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5730) desc->tag = cpu_to_be32(RDP_OED_DESC_TAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5732) desc->oed_info.hi_alarm = page_a2[SSF_BIAS_HIGH_ALARM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5733) desc->oed_info.lo_alarm = page_a2[SSF_BIAS_LOW_ALARM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5734) desc->oed_info.hi_warning = page_a2[SSF_BIAS_HIGH_WARNING];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5735) desc->oed_info.lo_warning = page_a2[SSF_BIAS_LOW_WARNING];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5737) if (phba->sfp_alarm & LPFC_TRANSGRESSION_HIGH_TXBIAS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5738) flags |= RDP_OET_HIGH_ALARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5739) if (phba->sfp_alarm & LPFC_TRANSGRESSION_LOW_TXBIAS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5740) flags |= RDP_OET_LOW_ALARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5741) if (phba->sfp_warning & LPFC_TRANSGRESSION_HIGH_TXBIAS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5742) flags |= RDP_OET_HIGH_WARNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5743) if (phba->sfp_warning & LPFC_TRANSGRESSION_LOW_TXBIAS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5744) flags |= RDP_OET_LOW_WARNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5746) flags |= ((0xf & RDP_OED_TXBIAS) << RDP_OED_TYPE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5747) desc->oed_info.function_flags = cpu_to_be32(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5748) desc->length = cpu_to_be32(sizeof(desc->oed_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5749) return sizeof(struct fc_rdp_oed_sfp_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5752) static uint32_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5753) lpfc_rdp_res_oed_txpower_desc(struct lpfc_hba *phba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5754) struct fc_rdp_oed_sfp_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5755) uint8_t *page_a2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5757) uint32_t flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5759) desc->tag = cpu_to_be32(RDP_OED_DESC_TAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5761) desc->oed_info.hi_alarm = page_a2[SSF_TXPOWER_HIGH_ALARM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5762) desc->oed_info.lo_alarm = page_a2[SSF_TXPOWER_LOW_ALARM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5763) desc->oed_info.hi_warning = page_a2[SSF_TXPOWER_HIGH_WARNING];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5764) desc->oed_info.lo_warning = page_a2[SSF_TXPOWER_LOW_WARNING];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5766) if (phba->sfp_alarm & LPFC_TRANSGRESSION_HIGH_TXPOWER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5767) flags |= RDP_OET_HIGH_ALARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5768) if (phba->sfp_alarm & LPFC_TRANSGRESSION_LOW_TXPOWER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5769) flags |= RDP_OET_LOW_ALARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5770) if (phba->sfp_warning & LPFC_TRANSGRESSION_HIGH_TXPOWER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5771) flags |= RDP_OET_HIGH_WARNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5772) if (phba->sfp_warning & LPFC_TRANSGRESSION_LOW_TXPOWER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5773) flags |= RDP_OET_LOW_WARNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5775) flags |= ((0xf & RDP_OED_TXPOWER) << RDP_OED_TYPE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5776) desc->oed_info.function_flags = cpu_to_be32(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5777) desc->length = cpu_to_be32(sizeof(desc->oed_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5778) return sizeof(struct fc_rdp_oed_sfp_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5782) static uint32_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5783) lpfc_rdp_res_oed_rxpower_desc(struct lpfc_hba *phba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5784) struct fc_rdp_oed_sfp_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5785) uint8_t *page_a2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5786) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5787) uint32_t flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5789) desc->tag = cpu_to_be32(RDP_OED_DESC_TAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5791) desc->oed_info.hi_alarm = page_a2[SSF_RXPOWER_HIGH_ALARM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5792) desc->oed_info.lo_alarm = page_a2[SSF_RXPOWER_LOW_ALARM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5793) desc->oed_info.hi_warning = page_a2[SSF_RXPOWER_HIGH_WARNING];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5794) desc->oed_info.lo_warning = page_a2[SSF_RXPOWER_LOW_WARNING];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5796) if (phba->sfp_alarm & LPFC_TRANSGRESSION_HIGH_RXPOWER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5797) flags |= RDP_OET_HIGH_ALARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5798) if (phba->sfp_alarm & LPFC_TRANSGRESSION_LOW_RXPOWER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5799) flags |= RDP_OET_LOW_ALARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5800) if (phba->sfp_warning & LPFC_TRANSGRESSION_HIGH_RXPOWER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5801) flags |= RDP_OET_HIGH_WARNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5802) if (phba->sfp_warning & LPFC_TRANSGRESSION_LOW_RXPOWER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5803) flags |= RDP_OET_LOW_WARNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5805) flags |= ((0xf & RDP_OED_RXPOWER) << RDP_OED_TYPE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5806) desc->oed_info.function_flags = cpu_to_be32(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5807) desc->length = cpu_to_be32(sizeof(desc->oed_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5808) return sizeof(struct fc_rdp_oed_sfp_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5811) static uint32_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5812) lpfc_rdp_res_opd_desc(struct fc_rdp_opd_sfp_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5813) uint8_t *page_a0, struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5815) desc->tag = cpu_to_be32(RDP_OPD_DESC_TAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5816) memcpy(desc->opd_info.vendor_name, &page_a0[SSF_VENDOR_NAME], 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5817) memcpy(desc->opd_info.model_number, &page_a0[SSF_VENDOR_PN], 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5818) memcpy(desc->opd_info.serial_number, &page_a0[SSF_VENDOR_SN], 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5819) memcpy(desc->opd_info.revision, &page_a0[SSF_VENDOR_REV], 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5820) memcpy(desc->opd_info.date, &page_a0[SSF_DATE_CODE], 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5821) desc->length = cpu_to_be32(sizeof(desc->opd_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5822) return sizeof(struct fc_rdp_opd_sfp_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5825) static uint32_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5826) lpfc_rdp_res_fec_desc(struct fc_fec_rdp_desc *desc, READ_LNK_VAR *stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5827) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5828) if (bf_get(lpfc_read_link_stat_gec2, stat) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5829) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5830) desc->tag = cpu_to_be32(RDP_FEC_DESC_TAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5832) desc->info.CorrectedBlocks =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5833) cpu_to_be32(stat->fecCorrBlkCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5834) desc->info.UncorrectableBlocks =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5835) cpu_to_be32(stat->fecUncorrBlkCount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5837) desc->length = cpu_to_be32(sizeof(desc->info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5839) return sizeof(struct fc_fec_rdp_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5842) static uint32_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5843) lpfc_rdp_res_speed(struct fc_rdp_port_speed_desc *desc, struct lpfc_hba *phba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5844) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5845) uint16_t rdp_cap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5846) uint16_t rdp_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5848) desc->tag = cpu_to_be32(RDP_PORT_SPEED_DESC_TAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5850) switch (phba->fc_linkspeed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5851) case LPFC_LINK_SPEED_1GHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5852) rdp_speed = RDP_PS_1GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5853) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5854) case LPFC_LINK_SPEED_2GHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5855) rdp_speed = RDP_PS_2GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5856) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5857) case LPFC_LINK_SPEED_4GHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5858) rdp_speed = RDP_PS_4GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5859) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5860) case LPFC_LINK_SPEED_8GHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5861) rdp_speed = RDP_PS_8GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5862) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5863) case LPFC_LINK_SPEED_10GHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5864) rdp_speed = RDP_PS_10GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5865) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5866) case LPFC_LINK_SPEED_16GHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5867) rdp_speed = RDP_PS_16GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5868) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5869) case LPFC_LINK_SPEED_32GHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5870) rdp_speed = RDP_PS_32GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5871) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5872) case LPFC_LINK_SPEED_64GHZ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5873) rdp_speed = RDP_PS_64GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5874) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5875) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5876) rdp_speed = RDP_PS_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5877) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5880) desc->info.port_speed.speed = cpu_to_be16(rdp_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5882) if (phba->lmt & LMT_128Gb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5883) rdp_cap |= RDP_PS_128GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5884) if (phba->lmt & LMT_64Gb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5885) rdp_cap |= RDP_PS_64GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5886) if (phba->lmt & LMT_32Gb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5887) rdp_cap |= RDP_PS_32GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5888) if (phba->lmt & LMT_16Gb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5889) rdp_cap |= RDP_PS_16GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5890) if (phba->lmt & LMT_10Gb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5891) rdp_cap |= RDP_PS_10GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5892) if (phba->lmt & LMT_8Gb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5893) rdp_cap |= RDP_PS_8GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5894) if (phba->lmt & LMT_4Gb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5895) rdp_cap |= RDP_PS_4GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5896) if (phba->lmt & LMT_2Gb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5897) rdp_cap |= RDP_PS_2GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5898) if (phba->lmt & LMT_1Gb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5899) rdp_cap |= RDP_PS_1GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5901) if (rdp_cap == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5902) rdp_cap = RDP_CAP_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5903) if (phba->cfg_link_speed != LPFC_USER_LINK_SPEED_AUTO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5904) rdp_cap |= RDP_CAP_USER_CONFIGURED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5906) desc->info.port_speed.capabilities = cpu_to_be16(rdp_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5907) desc->length = cpu_to_be32(sizeof(desc->info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5908) return sizeof(struct fc_rdp_port_speed_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5911) static uint32_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5912) lpfc_rdp_res_diag_port_names(struct fc_rdp_port_name_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5913) struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5914) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5916) desc->tag = cpu_to_be32(RDP_PORT_NAMES_DESC_TAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5918) memcpy(desc->port_names.wwnn, &vport->fc_nodename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5919) sizeof(desc->port_names.wwnn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5921) memcpy(desc->port_names.wwpn, &vport->fc_portname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5922) sizeof(desc->port_names.wwpn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5924) desc->length = cpu_to_be32(sizeof(desc->port_names));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5925) return sizeof(struct fc_rdp_port_name_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5928) static uint32_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5929) lpfc_rdp_res_attach_port_names(struct fc_rdp_port_name_desc *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5930) struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5931) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5933) desc->tag = cpu_to_be32(RDP_PORT_NAMES_DESC_TAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5934) if (vport->fc_flag & FC_FABRIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5935) memcpy(desc->port_names.wwnn, &vport->fabric_nodename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5936) sizeof(desc->port_names.wwnn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5938) memcpy(desc->port_names.wwpn, &vport->fabric_portname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5939) sizeof(desc->port_names.wwpn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5940) } else { /* Point to Point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5941) memcpy(desc->port_names.wwnn, &ndlp->nlp_nodename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5942) sizeof(desc->port_names.wwnn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5944) memcpy(desc->port_names.wwpn, &ndlp->nlp_portname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5945) sizeof(desc->port_names.wwpn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5948) desc->length = cpu_to_be32(sizeof(desc->port_names));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5949) return sizeof(struct fc_rdp_port_name_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5952) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5953) lpfc_els_rdp_cmpl(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5954) int status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5955) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5956) struct lpfc_nodelist *ndlp = rdp_context->ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5957) struct lpfc_vport *vport = ndlp->vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5958) struct lpfc_iocbq *elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5959) struct ulp_bde64 *bpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5960) IOCB_t *icmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5961) uint8_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5962) struct ls_rjt *stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5963) struct fc_rdp_res_frame *rdp_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5964) uint32_t cmdsize, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5965) uint16_t *flag_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5966) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5968) if (status != SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5969) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5971) /* This will change once we know the true size of the RDP payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5972) cmdsize = sizeof(struct fc_rdp_res_frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5974) elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5975) lpfc_max_els_tries, rdp_context->ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5976) rdp_context->ndlp->nlp_DID, ELS_CMD_ACC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5977) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5978) if (!elsiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5979) goto free_rdp_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5981) icmd = &elsiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5982) icmd->ulpContext = rdp_context->rx_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5983) icmd->unsli3.rcvsli3.ox_id = rdp_context->ox_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5985) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5986) "2171 Xmit RDP response tag x%x xri x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5987) "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5988) elsiocb->iotag, elsiocb->iocb.ulpContext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5989) ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5990) ndlp->nlp_rpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5991) rdp_res = (struct fc_rdp_res_frame *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5992) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5993) pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5994) memset(pcmd, 0, sizeof(struct fc_rdp_res_frame));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5995) *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5997) /* Update Alarm and Warning */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5998) flag_ptr = (uint16_t *)(rdp_context->page_a2 + SSF_ALARM_FLAGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5999) phba->sfp_alarm |= *flag_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6000) flag_ptr = (uint16_t *)(rdp_context->page_a2 + SSF_WARNING_FLAGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6001) phba->sfp_warning |= *flag_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6003) /* For RDP payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6004) len = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6005) len += lpfc_rdp_res_link_service((struct fc_rdp_link_service_desc *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6006) (len + pcmd), ELS_CMD_RDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6008) len += lpfc_rdp_res_sfp_desc((struct fc_rdp_sfp_desc *)(len + pcmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6009) rdp_context->page_a0, rdp_context->page_a2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6010) len += lpfc_rdp_res_speed((struct fc_rdp_port_speed_desc *)(len + pcmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6011) phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6012) len += lpfc_rdp_res_link_error((struct fc_rdp_link_error_status_desc *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6013) (len + pcmd), &rdp_context->link_stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6014) len += lpfc_rdp_res_diag_port_names((struct fc_rdp_port_name_desc *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6015) (len + pcmd), vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6016) len += lpfc_rdp_res_attach_port_names((struct fc_rdp_port_name_desc *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6017) (len + pcmd), vport, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6018) len += lpfc_rdp_res_fec_desc((struct fc_fec_rdp_desc *)(len + pcmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6019) &rdp_context->link_stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6020) len += lpfc_rdp_res_bbc_desc((struct fc_rdp_bbc_desc *)(len + pcmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6021) &rdp_context->link_stat, vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6022) len += lpfc_rdp_res_oed_temp_desc(phba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6023) (struct fc_rdp_oed_sfp_desc *)(len + pcmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6024) rdp_context->page_a2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6025) len += lpfc_rdp_res_oed_voltage_desc(phba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6026) (struct fc_rdp_oed_sfp_desc *)(len + pcmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6027) rdp_context->page_a2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6028) len += lpfc_rdp_res_oed_txbias_desc(phba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6029) (struct fc_rdp_oed_sfp_desc *)(len + pcmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6030) rdp_context->page_a2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6031) len += lpfc_rdp_res_oed_txpower_desc(phba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6032) (struct fc_rdp_oed_sfp_desc *)(len + pcmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6033) rdp_context->page_a2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6034) len += lpfc_rdp_res_oed_rxpower_desc(phba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6035) (struct fc_rdp_oed_sfp_desc *)(len + pcmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6036) rdp_context->page_a2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6037) len += lpfc_rdp_res_opd_desc((struct fc_rdp_opd_sfp_desc *)(len + pcmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6038) rdp_context->page_a0, vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6040) rdp_res->length = cpu_to_be32(len - 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6041) elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6043) /* Now that we know the true size of the payload, update the BPL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6044) bpl = (struct ulp_bde64 *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6045) (((struct lpfc_dmabuf *)(elsiocb->context3))->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6046) bpl->tus.f.bdeSize = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6047) bpl->tus.f.bdeFlags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6048) bpl->tus.w = le32_to_cpu(bpl->tus.w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6050) phba->fc_stat.elsXmitACC++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6051) rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6052) if (rc == IOCB_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6053) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6055) kfree(rdp_context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6057) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6058) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6059) cmdsize = 2 * sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6060) elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, lpfc_max_els_tries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6061) ndlp, ndlp->nlp_DID, ELS_CMD_LS_RJT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6062) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6063) if (!elsiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6064) goto free_rdp_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6066) icmd = &elsiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6067) icmd->ulpContext = rdp_context->rx_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6068) icmd->unsli3.rcvsli3.ox_id = rdp_context->ox_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6069) pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6071) *((uint32_t *) (pcmd)) = ELS_CMD_LS_RJT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6072) stat = (struct ls_rjt *)(pcmd + sizeof(uint32_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6073) stat->un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6075) phba->fc_stat.elsXmitLSRJT++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6076) elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6077) rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6079) if (rc == IOCB_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6080) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6081) free_rdp_context:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6082) kfree(rdp_context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6085) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6086) lpfc_get_rdp_info(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6087) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6088) LPFC_MBOXQ_t *mbox = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6089) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6091) mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6092) if (!mbox) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6093) lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6094) "7105 failed to allocate mailbox memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6095) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6098) if (lpfc_sli4_dump_page_a0(phba, mbox))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6099) goto prep_mbox_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6100) mbox->vport = rdp_context->ndlp->vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6101) mbox->mbox_cmpl = lpfc_mbx_cmpl_rdp_page_a0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6102) mbox->ctx_ndlp = (struct lpfc_rdp_context *)rdp_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6103) rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6104) if (rc == MBX_NOT_FINISHED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6105) goto issue_mbox_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6107) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6109) prep_mbox_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6110) issue_mbox_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6111) mempool_free(mbox, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6112) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6115) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6116) * lpfc_els_rcv_rdp - Process an unsolicited RDP ELS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6117) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6118) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6119) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6120) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6121) * This routine processes an unsolicited RDP(Read Diagnostic Parameters)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6122) * IOCB. First, the payload of the unsolicited RDP is checked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6123) * Then it will (1) send MBX_DUMP_MEMORY, Embedded DMP_LMSD sub command TYPE-3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6124) * for Page A0, (2) send MBX_DUMP_MEMORY, DMP_LMSD for Page A2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6125) * (3) send MBX_READ_LNK_STAT to get link stat, (4) Call lpfc_els_rdp_cmpl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6126) * gather all data and send RDP response.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6127) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6128) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6129) * 0 - Sent the acc response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6130) * 1 - Sent the reject response.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6131) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6132) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6133) lpfc_els_rcv_rdp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6134) struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6136) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6137) struct lpfc_dmabuf *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6138) uint8_t rjt_err, rjt_expl = LSEXP_NOTHING_MORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6139) struct fc_rdp_req_frame *rdp_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6140) struct lpfc_rdp_context *rdp_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6141) IOCB_t *cmd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6142) struct ls_rjt stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6144) if (phba->sli_rev < LPFC_SLI_REV4 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6145) bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6146) LPFC_SLI_INTF_IF_TYPE_2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6147) rjt_err = LSRJT_UNABLE_TPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6148) rjt_expl = LSEXP_REQ_UNSUPPORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6149) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6152) if (phba->sli_rev < LPFC_SLI_REV4 || (phba->hba_flag & HBA_FCOE_MODE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6153) rjt_err = LSRJT_UNABLE_TPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6154) rjt_expl = LSEXP_REQ_UNSUPPORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6155) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6158) pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6159) rdp_req = (struct fc_rdp_req_frame *) pcmd->virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6161) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6162) "2422 ELS RDP Request "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6163) "dec len %d tag x%x port_id %d len %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6164) be32_to_cpu(rdp_req->rdp_des_length),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6165) be32_to_cpu(rdp_req->nport_id_desc.tag),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6166) be32_to_cpu(rdp_req->nport_id_desc.nport_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6167) be32_to_cpu(rdp_req->nport_id_desc.length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6169) if (sizeof(struct fc_rdp_nport_desc) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6170) be32_to_cpu(rdp_req->rdp_des_length))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6171) goto rjt_logerr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6172) if (RDP_N_PORT_DESC_TAG != be32_to_cpu(rdp_req->nport_id_desc.tag))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6173) goto rjt_logerr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6174) if (RDP_NPORT_ID_SIZE !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6175) be32_to_cpu(rdp_req->nport_id_desc.length))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6176) goto rjt_logerr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6177) rdp_context = kzalloc(sizeof(struct lpfc_rdp_context), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6178) if (!rdp_context) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6179) rjt_err = LSRJT_UNABLE_TPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6180) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6183) cmd = &cmdiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6184) rdp_context->ndlp = lpfc_nlp_get(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6185) rdp_context->ox_id = cmd->unsli3.rcvsli3.ox_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6186) rdp_context->rx_id = cmd->ulpContext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6187) rdp_context->cmpl = lpfc_els_rdp_cmpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6188) if (lpfc_get_rdp_info(phba, rdp_context)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6189) lpfc_printf_vlog(ndlp->vport, KERN_WARNING, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6190) "2423 Unable to send mailbox");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6191) kfree(rdp_context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6192) rjt_err = LSRJT_UNABLE_TPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6193) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6194) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6197) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6199) rjt_logerr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6200) rjt_err = LSRJT_LOGICAL_ERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6202) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6203) memset(&stat, 0, sizeof(stat));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6204) stat.un.b.lsRjtRsnCode = rjt_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6205) stat.un.b.lsRjtRsnCodeExp = rjt_expl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6206) lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6207) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6211) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6212) lpfc_els_lcb_rsp(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6214) MAILBOX_t *mb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6215) IOCB_t *icmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6216) uint8_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6217) struct lpfc_iocbq *elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6218) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6219) struct ls_rjt *stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6220) union lpfc_sli4_cfg_shdr *shdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6221) struct lpfc_lcb_context *lcb_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6222) struct fc_lcb_res_frame *lcb_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6223) uint32_t cmdsize, shdr_status, shdr_add_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6224) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6226) mb = &pmb->u.mb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6227) lcb_context = (struct lpfc_lcb_context *)pmb->ctx_ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6228) ndlp = lcb_context->ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6229) pmb->ctx_ndlp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6230) pmb->ctx_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6232) shdr = (union lpfc_sli4_cfg_shdr *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6233) &pmb->u.mqe.un.beacon_config.header.cfg_shdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6234) shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6235) shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6237) lpfc_printf_log(phba, KERN_INFO, LOG_MBOX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6238) "0194 SET_BEACON_CONFIG mailbox "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6239) "completed with status x%x add_status x%x,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6240) " mbx status x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6241) shdr_status, shdr_add_status, mb->mbxStatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6243) if ((mb->mbxStatus != MBX_SUCCESS) || shdr_status ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6244) (shdr_add_status == ADD_STATUS_OPERATION_ALREADY_ACTIVE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6245) (shdr_add_status == ADD_STATUS_INVALID_REQUEST)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6246) mempool_free(pmb, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6247) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6250) mempool_free(pmb, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6251) cmdsize = sizeof(struct fc_lcb_res_frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6252) elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6253) lpfc_max_els_tries, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6254) ndlp->nlp_DID, ELS_CMD_ACC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6256) /* Decrement the ndlp reference count from previous mbox command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6257) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6259) if (!elsiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6260) goto free_lcb_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6262) lcb_res = (struct fc_lcb_res_frame *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6263) (((struct lpfc_dmabuf *)elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6265) memset(lcb_res, 0, sizeof(struct fc_lcb_res_frame));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6266) icmd = &elsiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6267) icmd->ulpContext = lcb_context->rx_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6268) icmd->unsli3.rcvsli3.ox_id = lcb_context->ox_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6270) pcmd = (uint8_t *)(((struct lpfc_dmabuf *)elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6271) *((uint32_t *)(pcmd)) = ELS_CMD_ACC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6272) lcb_res->lcb_sub_command = lcb_context->sub_command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6273) lcb_res->lcb_type = lcb_context->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6274) lcb_res->capability = lcb_context->capability;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6275) lcb_res->lcb_frequency = lcb_context->frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6276) lcb_res->lcb_duration = lcb_context->duration;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6277) elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6278) phba->fc_stat.elsXmitACC++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6279) rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6280) if (rc == IOCB_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6281) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6283) kfree(lcb_context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6284) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6286) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6287) cmdsize = sizeof(struct fc_lcb_res_frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6288) elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6289) lpfc_max_els_tries, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6290) ndlp->nlp_DID, ELS_CMD_LS_RJT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6291) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6292) if (!elsiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6293) goto free_lcb_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6295) icmd = &elsiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6296) icmd->ulpContext = lcb_context->rx_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6297) icmd->unsli3.rcvsli3.ox_id = lcb_context->ox_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6298) pcmd = (uint8_t *)(((struct lpfc_dmabuf *)elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6300) *((uint32_t *)(pcmd)) = ELS_CMD_LS_RJT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6301) stat = (struct ls_rjt *)(pcmd + sizeof(uint32_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6302) stat->un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6304) if (shdr_add_status == ADD_STATUS_OPERATION_ALREADY_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6305) stat->un.b.lsRjtRsnCodeExp = LSEXP_CMD_IN_PROGRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6307) elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6308) phba->fc_stat.elsXmitLSRJT++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6309) rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6310) if (rc == IOCB_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6311) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6312) free_lcb_context:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6313) kfree(lcb_context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6316) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6317) lpfc_sli4_set_beacon(struct lpfc_vport *vport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6318) struct lpfc_lcb_context *lcb_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6319) uint32_t beacon_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6321) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6322) union lpfc_sli4_cfg_shdr *cfg_shdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6323) LPFC_MBOXQ_t *mbox = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6324) uint32_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6325) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6327) mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6328) if (!mbox)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6329) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6331) cfg_shdr = &mbox->u.mqe.un.sli4_config.header.cfg_shdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6332) len = sizeof(struct lpfc_mbx_set_beacon_config) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6333) sizeof(struct lpfc_sli4_cfg_mhdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6334) lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_COMMON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6335) LPFC_MBOX_OPCODE_SET_BEACON_CONFIG, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6336) LPFC_SLI4_MBX_EMBED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6337) mbox->ctx_ndlp = (void *)lcb_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6338) mbox->vport = phba->pport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6339) mbox->mbox_cmpl = lpfc_els_lcb_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6340) bf_set(lpfc_mbx_set_beacon_port_num, &mbox->u.mqe.un.beacon_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6341) phba->sli4_hba.physical_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6342) bf_set(lpfc_mbx_set_beacon_state, &mbox->u.mqe.un.beacon_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6343) beacon_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6344) mbox->u.mqe.un.beacon_config.word5 = 0; /* Reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6346) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6347) * Check bv1s bit before issuing the mailbox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6348) * if bv1s == 1, LCB V1 supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6349) * else, LCB V0 supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6350) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6352) if (phba->sli4_hba.pc_sli4_params.bv1s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6353) /* COMMON_SET_BEACON_CONFIG_V1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6354) cfg_shdr->request.word9 = BEACON_VERSION_V1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6355) lcb_context->capability |= LCB_CAPABILITY_DURATION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6356) bf_set(lpfc_mbx_set_beacon_port_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6357) &mbox->u.mqe.un.beacon_config, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6358) bf_set(lpfc_mbx_set_beacon_duration_v1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6359) &mbox->u.mqe.un.beacon_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6360) be16_to_cpu(lcb_context->duration));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6361) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6362) /* COMMON_SET_BEACON_CONFIG_V0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6363) if (be16_to_cpu(lcb_context->duration) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6364) mempool_free(mbox, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6365) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6367) cfg_shdr->request.word9 = BEACON_VERSION_V0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6368) lcb_context->capability &= ~(LCB_CAPABILITY_DURATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6369) bf_set(lpfc_mbx_set_beacon_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6370) &mbox->u.mqe.un.beacon_config, beacon_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6371) bf_set(lpfc_mbx_set_beacon_port_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6372) &mbox->u.mqe.un.beacon_config, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6373) bf_set(lpfc_mbx_set_beacon_duration,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6374) &mbox->u.mqe.un.beacon_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6375) be16_to_cpu(lcb_context->duration));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6378) rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6379) if (rc == MBX_NOT_FINISHED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6380) mempool_free(mbox, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6381) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6384) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6388) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6389) * lpfc_els_rcv_lcb - Process an unsolicited LCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6390) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6391) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6392) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6393) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6394) * This routine processes an unsolicited LCB(LINK CABLE BEACON) IOCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6395) * First, the payload of the unsolicited LCB is checked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6396) * Then based on Subcommand beacon will either turn on or off.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6397) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6398) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6399) * 0 - Sent the acc response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6400) * 1 - Sent the reject response.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6401) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6402) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6403) lpfc_els_rcv_lcb(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6404) struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6406) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6407) struct lpfc_dmabuf *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6408) uint8_t *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6409) struct fc_lcb_request_frame *beacon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6410) struct lpfc_lcb_context *lcb_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6411) uint8_t state, rjt_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6412) struct ls_rjt stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6414) pcmd = (struct lpfc_dmabuf *)cmdiocb->context2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6415) lp = (uint8_t *)pcmd->virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6416) beacon = (struct fc_lcb_request_frame *)pcmd->virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6418) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6419) "0192 ELS LCB Data x%x x%x x%x x%x sub x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6420) "type x%x frequency %x duration x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6421) lp[0], lp[1], lp[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6422) beacon->lcb_command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6423) beacon->lcb_sub_command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6424) beacon->lcb_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6425) beacon->lcb_frequency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6426) be16_to_cpu(beacon->lcb_duration));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6428) if (beacon->lcb_sub_command != LPFC_LCB_ON &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6429) beacon->lcb_sub_command != LPFC_LCB_OFF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6430) rjt_err = LSRJT_CMD_UNSUPPORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6431) goto rjt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6434) if (phba->sli_rev < LPFC_SLI_REV4 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6435) phba->hba_flag & HBA_FCOE_MODE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6436) (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6437) LPFC_SLI_INTF_IF_TYPE_2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6438) rjt_err = LSRJT_CMD_UNSUPPORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6439) goto rjt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6442) lcb_context = kmalloc(sizeof(*lcb_context), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6443) if (!lcb_context) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6444) rjt_err = LSRJT_UNABLE_TPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6445) goto rjt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6448) state = (beacon->lcb_sub_command == LPFC_LCB_ON) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6449) lcb_context->sub_command = beacon->lcb_sub_command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6450) lcb_context->capability = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6451) lcb_context->type = beacon->lcb_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6452) lcb_context->frequency = beacon->lcb_frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6453) lcb_context->duration = beacon->lcb_duration;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6454) lcb_context->ox_id = cmdiocb->iocb.unsli3.rcvsli3.ox_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6455) lcb_context->rx_id = cmdiocb->iocb.ulpContext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6456) lcb_context->ndlp = lpfc_nlp_get(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6457) if (lpfc_sli4_set_beacon(vport, lcb_context, state)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6458) lpfc_printf_vlog(ndlp->vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6459) "0193 failed to send mail box");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6460) kfree(lcb_context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6461) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6462) rjt_err = LSRJT_UNABLE_TPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6463) goto rjt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6465) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6466) rjt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6467) memset(&stat, 0, sizeof(stat));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6468) stat.un.b.lsRjtRsnCode = rjt_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6469) lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6470) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6474) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6475) * lpfc_els_flush_rscn - Clean up any rscn activities with a vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6476) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6477) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6478) * This routine cleans up any Registration State Change Notification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6479) * (RSCN) activity with a @vport. Note that the fc_rscn_flush flag of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6480) * @vport together with the host_lock is used to prevent multiple thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6481) * trying to access the RSCN array on a same @vport at the same time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6482) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6483) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6484) lpfc_els_flush_rscn(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6486) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6487) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6488) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6490) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6491) if (vport->fc_rscn_flush) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6492) /* Another thread is walking fc_rscn_id_list on this vport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6493) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6494) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6496) /* Indicate we are walking lpfc_els_flush_rscn on this vport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6497) vport->fc_rscn_flush = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6498) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6500) for (i = 0; i < vport->fc_rscn_id_cnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6501) lpfc_in_buf_free(phba, vport->fc_rscn_id_list[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6502) vport->fc_rscn_id_list[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6504) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6505) vport->fc_rscn_id_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6506) vport->fc_flag &= ~(FC_RSCN_MODE | FC_RSCN_DISCOVERY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6507) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6508) lpfc_can_disctmo(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6509) /* Indicate we are done walking this fc_rscn_id_list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6510) vport->fc_rscn_flush = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6513) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6514) * lpfc_rscn_payload_check - Check whether there is a pending rscn to a did
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6515) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6516) * @did: remote destination port identifier.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6517) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6518) * This routine checks whether there is any pending Registration State
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6519) * Configuration Notification (RSCN) to a @did on @vport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6520) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6521) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6522) * None zero - The @did matched with a pending rscn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6523) * 0 - not able to match @did with a pending rscn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6524) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6525) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6526) lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6528) D_ID ns_did;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6529) D_ID rscn_did;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6530) uint32_t *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6531) uint32_t payload_len, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6532) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6534) ns_did.un.word = did;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6536) /* Never match fabric nodes for RSCNs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6537) if ((did & Fabric_DID_MASK) == Fabric_DID_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6538) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6540) /* If we are doing a FULL RSCN rediscovery, match everything */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6541) if (vport->fc_flag & FC_RSCN_DISCOVERY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6542) return did;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6544) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6545) if (vport->fc_rscn_flush) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6546) /* Another thread is walking fc_rscn_id_list on this vport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6547) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6548) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6550) /* Indicate we are walking fc_rscn_id_list on this vport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6551) vport->fc_rscn_flush = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6552) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6553) for (i = 0; i < vport->fc_rscn_id_cnt; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6554) lp = vport->fc_rscn_id_list[i]->virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6555) payload_len = be32_to_cpu(*lp++ & ~ELS_CMD_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6556) payload_len -= sizeof(uint32_t); /* take off word 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6557) while (payload_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6558) rscn_did.un.word = be32_to_cpu(*lp++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6559) payload_len -= sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6560) switch (rscn_did.un.b.resv & RSCN_ADDRESS_FORMAT_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6561) case RSCN_ADDRESS_FORMAT_PORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6562) if ((ns_did.un.b.domain == rscn_did.un.b.domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6563) && (ns_did.un.b.area == rscn_did.un.b.area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6564) && (ns_did.un.b.id == rscn_did.un.b.id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6565) goto return_did_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6566) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6567) case RSCN_ADDRESS_FORMAT_AREA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6568) if ((ns_did.un.b.domain == rscn_did.un.b.domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6569) && (ns_did.un.b.area == rscn_did.un.b.area))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6570) goto return_did_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6571) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6572) case RSCN_ADDRESS_FORMAT_DOMAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6573) if (ns_did.un.b.domain == rscn_did.un.b.domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6574) goto return_did_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6575) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6576) case RSCN_ADDRESS_FORMAT_FABRIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6577) goto return_did_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6581) /* Indicate we are done with walking fc_rscn_id_list on this vport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6582) vport->fc_rscn_flush = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6583) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6584) return_did_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6585) /* Indicate we are done with walking fc_rscn_id_list on this vport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6586) vport->fc_rscn_flush = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6587) return did;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6590) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6591) * lpfc_rscn_recovery_check - Send recovery event to vport nodes matching rscn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6592) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6593) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6594) * This routine sends recovery (NLP_EVT_DEVICE_RECOVERY) event to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6595) * state machine for a @vport's nodes that are with pending RSCN (Registration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6596) * State Change Notification).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6597) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6598) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6599) * 0 - Successful (currently alway return 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6600) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6601) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6602) lpfc_rscn_recovery_check(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6604) struct lpfc_nodelist *ndlp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6606) /* Move all affected nodes by pending RSCNs to NPR state. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6607) list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6608) if (!NLP_CHK_NODE_ACT(ndlp) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6609) (ndlp->nlp_state == NLP_STE_UNUSED_NODE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6610) !lpfc_rscn_payload_check(vport, ndlp->nlp_DID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6611) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6613) /* NVME Target mode does not do RSCN Recovery. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6614) if (vport->phba->nvmet_support)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6615) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6617) /* If we are in the process of doing discovery on this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6618) * NPort, let it continue on its own.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6619) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6620) switch (ndlp->nlp_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6621) case NLP_STE_PLOGI_ISSUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6622) case NLP_STE_ADISC_ISSUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6623) case NLP_STE_REG_LOGIN_ISSUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6624) case NLP_STE_PRLI_ISSUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6625) case NLP_STE_LOGO_ISSUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6626) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6629) /* Check to see if we need to NVME rescan this target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6630) * remoteport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6631) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6632) if (ndlp->nlp_fc4_type & NLP_FC4_NVME &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6633) ndlp->nlp_type & (NLP_NVME_TARGET | NLP_NVME_DISCOVERY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6634) lpfc_nvme_rescan_port(vport, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6636) lpfc_disc_state_machine(vport, ndlp, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6637) NLP_EVT_DEVICE_RECOVERY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6638) lpfc_cancel_retry_delay_tmo(vport, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6640) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6643) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6644) * lpfc_send_rscn_event - Send an RSCN event to management application
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6645) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6646) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6647) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6648) * lpfc_send_rscn_event sends an RSCN netlink event to management
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6649) * applications.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6650) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6651) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6652) lpfc_send_rscn_event(struct lpfc_vport *vport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6653) struct lpfc_iocbq *cmdiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6655) struct lpfc_dmabuf *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6656) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6657) uint32_t *payload_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6658) uint32_t payload_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6659) struct lpfc_rscn_event_header *rscn_event_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6661) pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6662) payload_ptr = (uint32_t *) pcmd->virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6663) payload_len = be32_to_cpu(*payload_ptr & ~ELS_CMD_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6665) rscn_event_data = kmalloc(sizeof(struct lpfc_rscn_event_header) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6666) payload_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6667) if (!rscn_event_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6668) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6669) "0147 Failed to allocate memory for RSCN event\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6670) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6672) rscn_event_data->event_type = FC_REG_RSCN_EVENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6673) rscn_event_data->payload_length = payload_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6674) memcpy(rscn_event_data->rscn_payload, payload_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6675) payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6677) fc_host_post_vendor_event(shost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6678) fc_get_event_number(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6679) sizeof(struct lpfc_rscn_event_header) + payload_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6680) (char *)rscn_event_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6681) LPFC_NL_VENDOR_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6683) kfree(rscn_event_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6686) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6687) * lpfc_els_rcv_rscn - Process an unsolicited rscn iocb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6688) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6689) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6690) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6691) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6692) * This routine processes an unsolicited RSCN (Registration State Change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6693) * Notification) IOCB. First, the payload of the unsolicited RSCN is walked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6694) * to invoke fc_host_post_event() routine to the FC transport layer. If the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6695) * discover state machine is about to begin discovery, it just accepts the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6696) * RSCN and the discovery process will satisfy the RSCN. If this RSCN only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6697) * contains N_Port IDs for other vports on this HBA, it just accepts the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6698) * RSCN and ignore processing it. If the state machine is in the recovery
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6699) * state, the fc_rscn_id_list of this @vport is walked and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6700) * lpfc_rscn_recovery_check() routine is invoked to send recovery event for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6701) * all nodes that match RSCN payload. Otherwise, the lpfc_els_handle_rscn()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6702) * routine is invoked to handle the RSCN event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6703) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6704) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6705) * 0 - Just sent the acc response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6706) * 1 - Sent the acc response and waited for name server completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6707) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6708) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6709) lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6710) struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6711) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6712) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6713) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6714) struct lpfc_dmabuf *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6715) uint32_t *lp, *datap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6716) uint32_t payload_len, length, nportid, *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6717) int rscn_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6718) int rscn_id = 0, hba_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6719) int i, tmo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6721) pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6722) lp = (uint32_t *) pcmd->virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6724) payload_len = be32_to_cpu(*lp++ & ~ELS_CMD_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6725) payload_len -= sizeof(uint32_t); /* take off word 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6726) /* RSCN received */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6727) lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6728) "0214 RSCN received Data: x%x x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6729) vport->fc_flag, payload_len, *lp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6730) vport->fc_rscn_id_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6732) /* Send an RSCN event to the management application */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6733) lpfc_send_rscn_event(vport, cmdiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6735) for (i = 0; i < payload_len/sizeof(uint32_t); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6736) fc_host_post_event(shost, fc_get_event_number(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6737) FCH_EVT_RSCN, lp[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6739) /* Check if RSCN is coming from a direct-connected remote NPort */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6740) if (vport->fc_flag & FC_PT2PT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6741) /* If so, just ACC it, no other action needed for now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6742) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6743) "2024 pt2pt RSCN %08x Data: x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6744) *lp, vport->fc_flag, payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6745) lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6747) /* Check to see if we need to NVME rescan this target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6748) * remoteport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6749) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6750) if (ndlp->nlp_fc4_type & NLP_FC4_NVME &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6751) ndlp->nlp_type & (NLP_NVME_TARGET | NLP_NVME_DISCOVERY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6752) lpfc_nvme_rescan_port(vport, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6753) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6756) /* If we are about to begin discovery, just ACC the RSCN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6757) * Discovery processing will satisfy it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6758) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6759) if (vport->port_state <= LPFC_NS_QRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6760) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6761) "RCV RSCN ignore: did:x%x/ste:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6762) ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6764) lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6765) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6768) /* If this RSCN just contains NPortIDs for other vports on this HBA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6769) * just ACC and ignore it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6770) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6771) if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6772) !(vport->cfg_peer_port_login)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6773) i = payload_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6774) datap = lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6775) while (i > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6776) nportid = *datap++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6777) nportid = ((be32_to_cpu(nportid)) & Mask_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6778) i -= sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6779) rscn_id++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6780) if (lpfc_find_vport_by_did(phba, nportid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6781) hba_id++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6783) if (rscn_id == hba_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6784) /* ALL NPortIDs in RSCN are on HBA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6785) lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6786) "0219 Ignore RSCN "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6787) "Data: x%x x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6788) vport->fc_flag, payload_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6789) *lp, vport->fc_rscn_id_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6790) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6791) "RCV RSCN vport: did:x%x/ste:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6792) ndlp->nlp_DID, vport->port_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6793) ndlp->nlp_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6795) lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6796) ndlp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6797) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6801) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6802) if (vport->fc_rscn_flush) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6803) /* Another thread is walking fc_rscn_id_list on this vport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6804) vport->fc_flag |= FC_RSCN_DISCOVERY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6805) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6806) /* Send back ACC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6807) lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6808) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6810) /* Indicate we are walking fc_rscn_id_list on this vport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6811) vport->fc_rscn_flush = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6812) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6813) /* Get the array count after successfully have the token */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6814) rscn_cnt = vport->fc_rscn_id_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6815) /* If we are already processing an RSCN, save the received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6816) * RSCN payload buffer, cmdiocb->context2 to process later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6817) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6818) if (vport->fc_flag & (FC_RSCN_MODE | FC_NDISC_ACTIVE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6819) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6820) "RCV RSCN defer: did:x%x/ste:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6821) ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6823) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6824) vport->fc_flag |= FC_RSCN_DEFERRED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6826) /* Restart disctmo if its already running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6827) if (vport->fc_flag & FC_DISC_TMO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6828) tmo = ((phba->fc_ratov * 3) + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6829) mod_timer(&vport->fc_disctmo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6830) jiffies + msecs_to_jiffies(1000 * tmo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6832) if ((rscn_cnt < FC_MAX_HOLD_RSCN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6833) !(vport->fc_flag & FC_RSCN_DISCOVERY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6834) vport->fc_flag |= FC_RSCN_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6835) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6836) if (rscn_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6837) cmd = vport->fc_rscn_id_list[rscn_cnt-1]->virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6838) length = be32_to_cpu(*cmd & ~ELS_CMD_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6840) if ((rscn_cnt) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6841) (payload_len + length <= LPFC_BPL_SIZE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6842) *cmd &= ELS_CMD_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6843) *cmd |= cpu_to_be32(payload_len + length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6844) memcpy(((uint8_t *)cmd) + length, lp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6845) payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6846) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6847) vport->fc_rscn_id_list[rscn_cnt] = pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6848) vport->fc_rscn_id_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6849) /* If we zero, cmdiocb->context2, the calling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6850) * routine will not try to free it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6851) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6852) cmdiocb->context2 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6854) /* Deferred RSCN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6855) lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6856) "0235 Deferred RSCN "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6857) "Data: x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6858) vport->fc_rscn_id_cnt, vport->fc_flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6859) vport->port_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6860) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6861) vport->fc_flag |= FC_RSCN_DISCOVERY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6862) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6863) /* ReDiscovery RSCN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6864) lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6865) "0234 ReDiscovery RSCN "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6866) "Data: x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6867) vport->fc_rscn_id_cnt, vport->fc_flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6868) vport->port_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6870) /* Indicate we are done walking fc_rscn_id_list on this vport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6871) vport->fc_rscn_flush = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6872) /* Send back ACC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6873) lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6874) /* send RECOVERY event for ALL nodes that match RSCN payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6875) lpfc_rscn_recovery_check(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6876) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6878) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6879) "RCV RSCN: did:x%x/ste:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6880) ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6882) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6883) vport->fc_flag |= FC_RSCN_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6884) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6885) vport->fc_rscn_id_list[vport->fc_rscn_id_cnt++] = pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6886) /* Indicate we are done walking fc_rscn_id_list on this vport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6887) vport->fc_rscn_flush = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6888) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6889) * If we zero, cmdiocb->context2, the calling routine will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6890) * not try to free it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6891) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6892) cmdiocb->context2 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6893) lpfc_set_disctmo(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6894) /* Send back ACC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6895) lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6896) /* send RECOVERY event for ALL nodes that match RSCN payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6897) lpfc_rscn_recovery_check(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6898) return lpfc_els_handle_rscn(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6901) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6902) * lpfc_els_handle_rscn - Handle rscn for a vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6903) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6904) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6905) * This routine handles the Registration State Configuration Notification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6906) * (RSCN) for a @vport. If login to NameServer does not exist, a new ndlp shall
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6907) * be created and a Port Login (PLOGI) to the NameServer is issued. Otherwise,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6908) * if the ndlp to NameServer exists, a Common Transport (CT) command to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6909) * NameServer shall be issued. If CT command to the NameServer fails to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6910) * issued, the lpfc_els_flush_rscn() routine shall be invoked to clean up any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6911) * RSCN activities with the @vport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6912) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6913) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6914) * 0 - Cleaned up rscn on the @vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6915) * 1 - Wait for plogi to name server before proceed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6916) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6917) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6918) lpfc_els_handle_rscn(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6919) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6920) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6921) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6923) /* Ignore RSCN if the port is being torn down. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6924) if (vport->load_flag & FC_UNLOADING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6925) lpfc_els_flush_rscn(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6926) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6929) /* Start timer for RSCN processing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6930) lpfc_set_disctmo(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6932) /* RSCN processed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6933) lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6934) "0215 RSCN processed Data: x%x x%x x%x x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6935) vport->fc_flag, 0, vport->fc_rscn_id_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6936) vport->port_state, vport->num_disc_nodes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6937) vport->gidft_inp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6939) /* To process RSCN, first compare RSCN data with NameServer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6940) vport->fc_ns_retry = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6941) vport->num_disc_nodes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6943) ndlp = lpfc_findnode_did(vport, NameServer_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6944) if (ndlp && NLP_CHK_NODE_ACT(ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6945) && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6946) /* Good ndlp, issue CT Request to NameServer. Need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6947) * know how many gidfts were issued. If none, then just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6948) * flush the RSCN. Otherwise, the outstanding requests
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6949) * need to complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6950) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6951) if (phba->cfg_ns_query == LPFC_NS_QUERY_GID_FT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6952) if (lpfc_issue_gidft(vport) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6953) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6954) } else if (phba->cfg_ns_query == LPFC_NS_QUERY_GID_PT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6955) if (lpfc_issue_gidpt(vport) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6956) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6957) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6958) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6960) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6961) /* Nameserver login in question. Revalidate. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6962) if (ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6963) ndlp = lpfc_enable_node(vport, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6964) NLP_STE_PLOGI_ISSUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6965) if (!ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6966) lpfc_els_flush_rscn(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6967) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6969) ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6970) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6971) ndlp = lpfc_nlp_init(vport, NameServer_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6972) if (!ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6973) lpfc_els_flush_rscn(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6974) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6976) ndlp->nlp_prev_state = ndlp->nlp_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6977) lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6979) ndlp->nlp_type |= NLP_FABRIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6980) lpfc_issue_els_plogi(vport, NameServer_DID, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6981) /* Wait for NameServer login cmpl before we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6982) * continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6983) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6984) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6987) lpfc_els_flush_rscn(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6988) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6991) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6992) * lpfc_els_rcv_flogi - Process an unsolicited flogi iocb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6993) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6994) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6995) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6996) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6997) * This routine processes Fabric Login (FLOGI) IOCB received as an ELS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6998) * unsolicited event. An unsolicited FLOGI can be received in a point-to-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6999) * point topology. As an unsolicited FLOGI should not be received in a loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7000) * mode, any unsolicited FLOGI received in loop mode shall be ignored. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7001) * lpfc_check_sparm() routine is invoked to check the parameters in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7002) * unsolicited FLOGI. If parameters validation failed, the routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7003) * lpfc_els_rsp_reject() shall be called with reject reason code set to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7004) * LSEXP_SPARM_OPTIONS to reject the FLOGI. Otherwise, the Port WWN in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7005) * FLOGI shall be compared with the Port WWN of the @vport to determine who
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7006) * will initiate PLOGI. The higher lexicographical value party shall has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7007) * higher priority (as the winning port) and will initiate PLOGI and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7008) * communicate Port_IDs (Addresses) for both nodes in PLOGI. The result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7009) * of this will be marked in the @vport fc_flag field with FC_PT2PT_PLOGI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7010) * and then the lpfc_els_rsp_acc() routine is invoked to accept the FLOGI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7011) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7012) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7013) * 0 - Successfully processed the unsolicited flogi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7014) * 1 - Failed to process the unsolicited flogi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7015) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7016) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7017) lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7018) struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7019) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7020) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7021) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7022) struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7023) uint32_t *lp = (uint32_t *) pcmd->virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7024) IOCB_t *icmd = &cmdiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7025) struct serv_parm *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7026) LPFC_MBOXQ_t *mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7027) uint32_t cmd, did;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7028) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7029) uint32_t fc_flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7030) uint32_t port_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7032) cmd = *lp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7033) sp = (struct serv_parm *) lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7035) /* FLOGI received */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7037) lpfc_set_disctmo(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7039) if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7040) /* We should never receive a FLOGI in loop mode, ignore it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7041) did = icmd->un.elsreq64.remoteID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7043) /* An FLOGI ELS command <elsCmd> was received from DID <did> in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7044) Loop Mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7045) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7046) "0113 An FLOGI ELS command x%x was "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7047) "received from DID x%x in Loop Mode\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7048) cmd, did);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7049) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7052) (void) lpfc_check_sparm(vport, ndlp, sp, CLASS3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7054) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7055) * If our portname is greater than the remote portname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7056) * then we initiate Nport login.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7057) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7059) rc = memcmp(&vport->fc_portname, &sp->portName,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7060) sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7062) if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7063) if (phba->sli_rev < LPFC_SLI_REV4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7064) mbox = mempool_alloc(phba->mbox_mem_pool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7065) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7066) if (!mbox)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7067) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7068) lpfc_linkdown(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7069) lpfc_init_link(phba, mbox,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7070) phba->cfg_topology,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7071) phba->cfg_link_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7072) mbox->u.mb.un.varInitLnk.lipsr_AL_PA = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7073) mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7074) mbox->vport = vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7075) rc = lpfc_sli_issue_mbox(phba, mbox,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7076) MBX_NOWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7077) lpfc_set_loopback_flag(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7078) if (rc == MBX_NOT_FINISHED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7079) mempool_free(mbox, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7080) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7083) /* abort the flogi coming back to ourselves
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7084) * due to external loopback on the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7085) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7086) lpfc_els_abort_flogi(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7087) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7089) } else if (rc > 0) { /* greater than */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7090) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7091) vport->fc_flag |= FC_PT2PT_PLOGI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7092) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7094) /* If we have the high WWPN we can assign our own
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7095) * myDID; otherwise, we have to WAIT for a PLOGI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7096) * from the remote NPort to find out what it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7097) * will be.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7098) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7099) vport->fc_myDID = PT2PT_LocalID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7100) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7101) vport->fc_myDID = PT2PT_RemoteID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7104) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7105) * The vport state should go to LPFC_FLOGI only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7106) * AFTER we issue a FLOGI, not receive one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7107) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7108) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7109) fc_flag = vport->fc_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7110) port_state = vport->port_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7111) vport->fc_flag |= FC_PT2PT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7112) vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7114) /* Acking an unsol FLOGI. Count 1 for link bounce
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7115) * work-around.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7116) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7117) vport->rcv_flogi_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7118) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7119) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7120) "3311 Rcv Flogi PS x%x new PS x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7121) "fc_flag x%x new fc_flag x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7122) port_state, vport->port_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7123) fc_flag, vport->fc_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7125) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7126) * We temporarily set fc_myDID to make it look like we are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7127) * a Fabric. This is done just so we end up with the right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7128) * did / sid on the FLOGI ACC rsp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7129) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7130) did = vport->fc_myDID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7131) vport->fc_myDID = Fabric_DID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7133) memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7135) /* Defer ACC response until AFTER we issue a FLOGI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7136) if (!(phba->hba_flag & HBA_FLOGI_ISSUED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7137) phba->defer_flogi_acc_rx_id = cmdiocb->iocb.ulpContext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7138) phba->defer_flogi_acc_ox_id =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7139) cmdiocb->iocb.unsli3.rcvsli3.ox_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7141) vport->fc_myDID = did;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7143) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7144) "3344 Deferring FLOGI ACC: rx_id: x%x,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7145) " ox_id: x%x, hba_flag x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7146) phba->defer_flogi_acc_rx_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7147) phba->defer_flogi_acc_ox_id, phba->hba_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7149) phba->defer_flogi_acc_flag = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7151) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7154) /* Send back ACC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7155) lpfc_els_rsp_acc(vport, ELS_CMD_FLOGI, cmdiocb, ndlp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7157) /* Now lets put fc_myDID back to what its supposed to be */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7158) vport->fc_myDID = did;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7160) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7163) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7164) * lpfc_els_rcv_rnid - Process an unsolicited rnid iocb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7165) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7166) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7167) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7168) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7169) * This routine processes Request Node Identification Data (RNID) IOCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7170) * received as an ELS unsolicited event. Only when the RNID specified format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7171) * 0x0 or 0xDF (Topology Discovery Specific Node Identification Data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7172) * present, this routine will invoke the lpfc_els_rsp_rnid_acc() routine to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7173) * Accept (ACC) the RNID ELS command. All the other RNID formats are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7174) * rejected by invoking the lpfc_els_rsp_reject() routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7175) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7176) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7177) * 0 - Successfully processed rnid iocb (currently always return 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7178) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7179) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7180) lpfc_els_rcv_rnid(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7181) struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7183) struct lpfc_dmabuf *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7184) uint32_t *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7185) RNID *rn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7186) struct ls_rjt stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7188) pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7189) lp = (uint32_t *) pcmd->virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7191) lp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7192) rn = (RNID *) lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7194) /* RNID received */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7196) switch (rn->Format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7197) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7198) case RNID_TOPOLOGY_DISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7199) /* Send back ACC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7200) lpfc_els_rsp_rnid_acc(vport, rn->Format, cmdiocb, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7201) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7202) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7203) /* Reject this request because format not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7204) stat.un.b.lsRjtRsvd0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7205) stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7206) stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7207) stat.un.b.vendorUnique = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7208) lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7209) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7211) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7214) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7215) * lpfc_els_rcv_echo - Process an unsolicited echo iocb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7216) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7217) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7218) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7219) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7220) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7221) * 0 - Successfully processed echo iocb (currently always return 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7222) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7223) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7224) lpfc_els_rcv_echo(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7225) struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7227) uint8_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7229) pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7231) /* skip over first word of echo command to find echo data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7232) pcmd += sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7234) lpfc_els_rsp_echo_acc(vport, pcmd, cmdiocb, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7235) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7238) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7239) * lpfc_els_rcv_lirr - Process an unsolicited lirr iocb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7240) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7241) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7242) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7243) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7244) * This routine processes a Link Incident Report Registration(LIRR) IOCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7245) * received as an ELS unsolicited event. Currently, this function just invokes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7246) * the lpfc_els_rsp_reject() routine to reject the LIRR IOCB unconditionally.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7247) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7248) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7249) * 0 - Successfully processed lirr iocb (currently always return 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7250) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7251) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7252) lpfc_els_rcv_lirr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7253) struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7255) struct ls_rjt stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7257) /* For now, unconditionally reject this command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7258) stat.un.b.lsRjtRsvd0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7259) stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7260) stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7261) stat.un.b.vendorUnique = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7262) lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7263) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7266) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7267) * lpfc_els_rcv_rrq - Process an unsolicited rrq iocb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7268) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7269) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7270) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7271) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7272) * This routine processes a Reinstate Recovery Qualifier (RRQ) IOCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7273) * received as an ELS unsolicited event. A request to RRQ shall only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7274) * be accepted if the Originator Nx_Port N_Port_ID or the Responder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7275) * Nx_Port N_Port_ID of the target Exchange is the same as the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7276) * N_Port_ID of the Nx_Port that makes the request. If the RRQ is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7277) * not accepted, an LS_RJT with reason code "Unable to perform
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7278) * command request" and reason code explanation "Invalid Originator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7279) * S_ID" shall be returned. For now, we just unconditionally accept
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7280) * RRQ from the target.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7281) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7282) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7283) lpfc_els_rcv_rrq(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7284) struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7286) lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7287) if (vport->phba->sli_rev == LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7288) lpfc_els_clear_rrq(vport, cmdiocb, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7291) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7292) * lpfc_els_rsp_rls_acc - Completion callbk func for MBX_READ_LNK_STAT mbox cmd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7293) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7294) * @pmb: pointer to the driver internal queue element for mailbox command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7295) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7296) * This routine is the completion callback function for the MBX_READ_LNK_STAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7297) * mailbox command. This callback function is to actually send the Accept
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7298) * (ACC) response to a Read Port Status (RPS) unsolicited IOCB event. It
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7299) * collects the link statistics from the completion of the MBX_READ_LNK_STAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7300) * mailbox command, constructs the RPS response with the link statistics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7301) * collected, and then invokes the lpfc_sli_issue_iocb() routine to send ACC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7302) * response to the RPS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7303) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7304) * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7305) * will be incremented by 1 for holding the ndlp and the reference to ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7306) * will be stored into the context1 field of the IOCB for the completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7307) * callback function to the RPS Accept Response ELS IOCB command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7308) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7309) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7310) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7311) lpfc_els_rsp_rls_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7313) MAILBOX_t *mb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7314) IOCB_t *icmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7315) struct RLS_RSP *rls_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7316) uint8_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7317) struct lpfc_iocbq *elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7318) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7319) uint16_t oxid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7320) uint16_t rxid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7321) uint32_t cmdsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7323) mb = &pmb->u.mb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7325) ndlp = (struct lpfc_nodelist *)pmb->ctx_ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7326) rxid = (uint16_t)((unsigned long)(pmb->ctx_buf) & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7327) oxid = (uint16_t)(((unsigned long)(pmb->ctx_buf) >> 16) & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7328) pmb->ctx_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7329) pmb->ctx_ndlp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7331) if (mb->mbxStatus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7332) mempool_free(pmb, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7333) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7336) cmdsize = sizeof(struct RLS_RSP) + sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7337) elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7338) lpfc_max_els_tries, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7339) ndlp->nlp_DID, ELS_CMD_ACC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7341) /* Decrement the ndlp reference count from previous mbox command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7342) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7344) if (!elsiocb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7345) mempool_free(pmb, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7346) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7349) icmd = &elsiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7350) icmd->ulpContext = rxid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7351) icmd->unsli3.rcvsli3.ox_id = oxid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7353) pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7354) *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7355) pcmd += sizeof(uint32_t); /* Skip past command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7356) rls_rsp = (struct RLS_RSP *)pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7358) rls_rsp->linkFailureCnt = cpu_to_be32(mb->un.varRdLnk.linkFailureCnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7359) rls_rsp->lossSyncCnt = cpu_to_be32(mb->un.varRdLnk.lossSyncCnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7360) rls_rsp->lossSignalCnt = cpu_to_be32(mb->un.varRdLnk.lossSignalCnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7361) rls_rsp->primSeqErrCnt = cpu_to_be32(mb->un.varRdLnk.primSeqErrCnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7362) rls_rsp->invalidXmitWord = cpu_to_be32(mb->un.varRdLnk.invalidXmitWord);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7363) rls_rsp->crcCnt = cpu_to_be32(mb->un.varRdLnk.crcCnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7364) mempool_free(pmb, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7365) /* Xmit ELS RLS ACC response tag <ulpIoTag> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7366) lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7367) "2874 Xmit ELS RLS ACC response tag x%x xri x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7368) "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7369) elsiocb->iotag, elsiocb->iocb.ulpContext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7370) ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7371) ndlp->nlp_rpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7372) elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7373) phba->fc_stat.elsXmitACC++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7374) if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) == IOCB_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7375) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7378) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7379) * lpfc_els_rcv_rls - Process an unsolicited rls iocb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7380) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7381) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7382) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7383) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7384) * This routine processes Read Link Status (RLS) IOCB received as an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7385) * ELS unsolicited event. It first checks the remote port state. If the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7386) * remote port is not in NLP_STE_UNMAPPED_NODE state or NLP_STE_MAPPED_NODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7387) * state, it invokes the lpfc_els_rsl_reject() routine to send the reject
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7388) * response. Otherwise, it issue the MBX_READ_LNK_STAT mailbox command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7389) * for reading the HBA link statistics. It is for the callback function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7390) * lpfc_els_rsp_rls_acc(), set to the MBX_READ_LNK_STAT mailbox command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7391) * to actually sending out RPL Accept (ACC) response.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7392) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7393) * Return codes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7394) * 0 - Successfully processed rls iocb (currently always return 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7395) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7396) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7397) lpfc_els_rcv_rls(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7398) struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7400) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7401) LPFC_MBOXQ_t *mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7402) struct ls_rjt stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7404) if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7405) (ndlp->nlp_state != NLP_STE_MAPPED_NODE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7406) /* reject the unsolicited RLS request and done with it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7407) goto reject_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7409) mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7410) if (mbox) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7411) lpfc_read_lnk_stat(phba, mbox);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7412) mbox->ctx_buf = (void *)((unsigned long)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7413) ((cmdiocb->iocb.unsli3.rcvsli3.ox_id << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7414) cmdiocb->iocb.ulpContext)); /* rx_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7415) mbox->ctx_ndlp = lpfc_nlp_get(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7416) mbox->vport = vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7417) mbox->mbox_cmpl = lpfc_els_rsp_rls_acc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7418) if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7419) != MBX_NOT_FINISHED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7420) /* Mbox completion will send ELS Response */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7421) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7422) /* Decrement reference count used for the failed mbox
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7423) * command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7424) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7425) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7426) mempool_free(mbox, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7428) reject_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7429) /* issue rejection response */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7430) stat.un.b.lsRjtRsvd0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7431) stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7432) stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7433) stat.un.b.vendorUnique = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7434) lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7435) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7438) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7439) * lpfc_els_rcv_rtv - Process an unsolicited rtv iocb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7440) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7441) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7442) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7443) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7444) * This routine processes Read Timout Value (RTV) IOCB received as an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7445) * ELS unsolicited event. It first checks the remote port state. If the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7446) * remote port is not in NLP_STE_UNMAPPED_NODE state or NLP_STE_MAPPED_NODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7447) * state, it invokes the lpfc_els_rsl_reject() routine to send the reject
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7448) * response. Otherwise, it sends the Accept(ACC) response to a Read Timeout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7449) * Value (RTV) unsolicited IOCB event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7450) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7451) * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7452) * will be incremented by 1 for holding the ndlp and the reference to ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7453) * will be stored into the context1 field of the IOCB for the completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7454) * callback function to the RTV Accept Response ELS IOCB command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7455) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7456) * Return codes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7457) * 0 - Successfully processed rtv iocb (currently always return 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7458) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7459) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7460) lpfc_els_rcv_rtv(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7461) struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7463) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7464) struct ls_rjt stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7465) struct RTV_RSP *rtv_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7466) uint8_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7467) struct lpfc_iocbq *elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7468) uint32_t cmdsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7471) if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7472) (ndlp->nlp_state != NLP_STE_MAPPED_NODE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7473) /* reject the unsolicited RTV request and done with it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7474) goto reject_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7476) cmdsize = sizeof(struct RTV_RSP) + sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7477) elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7478) lpfc_max_els_tries, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7479) ndlp->nlp_DID, ELS_CMD_ACC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7481) if (!elsiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7482) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7484) pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7485) *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7486) pcmd += sizeof(uint32_t); /* Skip past command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7488) /* use the command's xri in the response */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7489) elsiocb->iocb.ulpContext = cmdiocb->iocb.ulpContext; /* Xri / rx_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7490) elsiocb->iocb.unsli3.rcvsli3.ox_id = cmdiocb->iocb.unsli3.rcvsli3.ox_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7492) rtv_rsp = (struct RTV_RSP *)pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7494) /* populate RTV payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7495) rtv_rsp->ratov = cpu_to_be32(phba->fc_ratov * 1000); /* report msecs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7496) rtv_rsp->edtov = cpu_to_be32(phba->fc_edtov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7497) bf_set(qtov_edtovres, rtv_rsp, phba->fc_edtovResol ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7498) bf_set(qtov_rttov, rtv_rsp, 0); /* Field is for FC ONLY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7499) rtv_rsp->qtov = cpu_to_be32(rtv_rsp->qtov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7501) /* Xmit ELS RLS ACC response tag <ulpIoTag> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7502) lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7503) "2875 Xmit ELS RTV ACC response tag x%x xri x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7504) "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7505) "Data: x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7506) elsiocb->iotag, elsiocb->iocb.ulpContext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7507) ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7508) ndlp->nlp_rpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7509) rtv_rsp->ratov, rtv_rsp->edtov, rtv_rsp->qtov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7510) elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7511) phba->fc_stat.elsXmitACC++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7512) if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) == IOCB_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7513) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7514) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7516) reject_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7517) /* issue rejection response */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7518) stat.un.b.lsRjtRsvd0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7519) stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7520) stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7521) stat.un.b.vendorUnique = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7522) lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7523) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7526) /* lpfc_issue_els_rrq - Process an unsolicited rrq iocb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7527) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7528) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7529) * @did: DID of the target.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7530) * @rrq: Pointer to the rrq struct.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7531) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7532) * Build a ELS RRQ command and send it to the target. If the issue_iocb is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7533) * Successful the the completion handler will clear the RRQ.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7534) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7535) * Return codes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7536) * 0 - Successfully sent rrq els iocb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7537) * 1 - Failed to send rrq els iocb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7538) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7539) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7540) lpfc_issue_els_rrq(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7541) uint32_t did, struct lpfc_node_rrq *rrq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7543) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7544) struct RRQ *els_rrq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7545) struct lpfc_iocbq *elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7546) uint8_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7547) uint16_t cmdsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7548) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7551) if (ndlp != rrq->ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7552) ndlp = rrq->ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7553) if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7554) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7556) /* If ndlp is not NULL, we will bump the reference count on it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7557) cmdsize = (sizeof(uint32_t) + sizeof(struct RRQ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7558) elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, 0, ndlp, did,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7559) ELS_CMD_RRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7560) if (!elsiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7561) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7563) pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7565) /* For RRQ request, remainder of payload is Exchange IDs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7566) *((uint32_t *) (pcmd)) = ELS_CMD_RRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7567) pcmd += sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7568) els_rrq = (struct RRQ *) pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7570) bf_set(rrq_oxid, els_rrq, phba->sli4_hba.xri_ids[rrq->xritag]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7571) bf_set(rrq_rxid, els_rrq, rrq->rxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7572) bf_set(rrq_did, els_rrq, vport->fc_myDID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7573) els_rrq->rrq = cpu_to_be32(els_rrq->rrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7574) els_rrq->rrq_exchg = cpu_to_be32(els_rrq->rrq_exchg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7577) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7578) "Issue RRQ: did:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7579) did, rrq->xritag, rrq->rxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7580) elsiocb->context_un.rrq = rrq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7581) elsiocb->iocb_cmpl = lpfc_cmpl_els_rrq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7582) ret = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7584) if (ret == IOCB_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7585) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7586) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7588) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7591) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7592) * lpfc_send_rrq - Sends ELS RRQ if needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7593) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7594) * @rrq: pointer to the active rrq.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7595) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7596) * This routine will call the lpfc_issue_els_rrq if the rrq is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7597) * still active for the xri. If this function returns a failure then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7598) * the caller needs to clean up the RRQ by calling lpfc_clr_active_rrq.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7599) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7600) * Returns 0 Success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7601) * 1 Failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7602) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7603) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7604) lpfc_send_rrq(struct lpfc_hba *phba, struct lpfc_node_rrq *rrq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7605) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7606) struct lpfc_nodelist *ndlp = lpfc_findnode_did(rrq->vport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7607) rrq->nlp_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7608) if (!ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7609) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7611) if (lpfc_test_rrq_active(phba, ndlp, rrq->xritag))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7612) return lpfc_issue_els_rrq(rrq->vport, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7613) rrq->nlp_DID, rrq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7614) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7615) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7618) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7619) * lpfc_els_rsp_rpl_acc - Issue an accept rpl els command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7620) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7621) * @cmdsize: size of the ELS command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7622) * @oldiocb: pointer to the original lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7623) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7624) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7625) * This routine issuees an Accept (ACC) Read Port List (RPL) ELS command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7626) * It is to be called by the lpfc_els_rcv_rpl() routine to accept the RPL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7627) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7628) * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7629) * will be incremented by 1 for holding the ndlp and the reference to ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7630) * will be stored into the context1 field of the IOCB for the completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7631) * callback function to the RPL Accept Response ELS command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7632) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7633) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7634) * 0 - Successfully issued ACC RPL ELS command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7635) * 1 - Failed to issue ACC RPL ELS command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7636) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7637) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7638) lpfc_els_rsp_rpl_acc(struct lpfc_vport *vport, uint16_t cmdsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7639) struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7641) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7642) IOCB_t *icmd, *oldcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7643) RPL_RSP rpl_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7644) struct lpfc_iocbq *elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7645) uint8_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7647) elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7648) ndlp->nlp_DID, ELS_CMD_ACC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7650) if (!elsiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7651) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7653) icmd = &elsiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7654) oldcmd = &oldiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7655) icmd->ulpContext = oldcmd->ulpContext; /* Xri / rx_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7656) icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7658) pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7659) *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7660) pcmd += sizeof(uint16_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7661) *((uint16_t *)(pcmd)) = be16_to_cpu(cmdsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7662) pcmd += sizeof(uint16_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7664) /* Setup the RPL ACC payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7665) rpl_rsp.listLen = be32_to_cpu(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7666) rpl_rsp.index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7667) rpl_rsp.port_num_blk.portNum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7668) rpl_rsp.port_num_blk.portID = be32_to_cpu(vport->fc_myDID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7669) memcpy(&rpl_rsp.port_num_blk.portName, &vport->fc_portname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7670) sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7671) memcpy(pcmd, &rpl_rsp, cmdsize - sizeof(uint32_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7672) /* Xmit ELS RPL ACC response tag <ulpIoTag> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7673) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7674) "0120 Xmit ELS RPL ACC response tag x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7675) "xri x%x, did x%x, nlp_flag x%x, nlp_state x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7676) "rpi x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7677) elsiocb->iotag, elsiocb->iocb.ulpContext,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7678) ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7679) ndlp->nlp_rpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7680) elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7681) phba->fc_stat.elsXmitACC++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7682) if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7683) IOCB_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7684) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7685) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7687) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7690) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7691) * lpfc_els_rcv_rpl - Process an unsolicited rpl iocb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7692) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7693) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7694) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7695) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7696) * This routine processes Read Port List (RPL) IOCB received as an ELS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7697) * unsolicited event. It first checks the remote port state. If the remote
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7698) * port is not in NLP_STE_UNMAPPED_NODE and NLP_STE_MAPPED_NODE states, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7699) * invokes the lpfc_els_rsp_reject() routine to send reject response.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7700) * Otherwise, this routine then invokes the lpfc_els_rsp_rpl_acc() routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7701) * to accept the RPL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7702) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7703) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7704) * 0 - Successfully processed rpl iocb (currently always return 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7705) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7706) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7707) lpfc_els_rcv_rpl(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7708) struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7710) struct lpfc_dmabuf *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7711) uint32_t *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7712) uint32_t maxsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7713) uint16_t cmdsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7714) RPL *rpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7715) struct ls_rjt stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7717) if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7718) (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7719) /* issue rejection response */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7720) stat.un.b.lsRjtRsvd0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7721) stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7722) stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7723) stat.un.b.vendorUnique = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7724) lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7725) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7726) /* rejected the unsolicited RPL request and done with it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7727) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7730) pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7731) lp = (uint32_t *) pcmd->virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7732) rpl = (RPL *) (lp + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7733) maxsize = be32_to_cpu(rpl->maxsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7735) /* We support only one port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7736) if ((rpl->index == 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7737) ((maxsize == 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7738) ((maxsize * sizeof(uint32_t)) >= sizeof(RPL_RSP)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7739) cmdsize = sizeof(uint32_t) + sizeof(RPL_RSP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7740) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7741) cmdsize = sizeof(uint32_t) + maxsize * sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7743) lpfc_els_rsp_rpl_acc(vport, cmdsize, cmdiocb, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7745) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7748) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7749) * lpfc_els_rcv_farp - Process an unsolicited farp request els command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7750) * @vport: pointer to a virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7751) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7752) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7753) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7754) * This routine processes Fibre Channel Address Resolution Protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7755) * (FARP) Request IOCB received as an ELS unsolicited event. Currently,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7756) * the lpfc driver only supports matching on WWPN or WWNN for FARP. As such,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7757) * FARP_MATCH_PORT flag and FARP_MATCH_NODE flag are checked against the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7758) * Match Flag in the FARP request IOCB: if FARP_MATCH_PORT flag is set, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7759) * remote PortName is compared against the FC PortName stored in the @vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7760) * data structure; if FARP_MATCH_NODE flag is set, the remote NodeName is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7761) * compared against the FC NodeName stored in the @vport data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7762) * If any of these matches and the FARP_REQUEST_FARPR flag is set in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7763) * FARP request IOCB Response Flag, the lpfc_issue_els_farpr() routine is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7764) * invoked to send out FARP Response to the remote node. Before sending the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7765) * FARP Response, however, the FARP_REQUEST_PLOGI flag is check in the FARP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7766) * request IOCB Response Flag and, if it is set, the lpfc_issue_els_plogi()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7767) * routine is invoked to log into the remote port first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7768) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7769) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7770) * 0 - Either the FARP Match Mode not supported or successfully processed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7771) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7772) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7773) lpfc_els_rcv_farp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7774) struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7776) struct lpfc_dmabuf *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7777) uint32_t *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7778) IOCB_t *icmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7779) FARP *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7780) uint32_t cnt, did;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7782) icmd = &cmdiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7783) did = icmd->un.elsreq64.remoteID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7784) pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7785) lp = (uint32_t *) pcmd->virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7787) lp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7788) fp = (FARP *) lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7789) /* FARP-REQ received from DID <did> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7790) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7791) "0601 FARP-REQ received from DID x%x\n", did);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7792) /* We will only support match on WWPN or WWNN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7793) if (fp->Mflags & ~(FARP_MATCH_NODE | FARP_MATCH_PORT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7794) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7797) cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7798) /* If this FARP command is searching for my portname */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7799) if (fp->Mflags & FARP_MATCH_PORT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7800) if (memcmp(&fp->RportName, &vport->fc_portname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7801) sizeof(struct lpfc_name)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7802) cnt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7805) /* If this FARP command is searching for my nodename */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7806) if (fp->Mflags & FARP_MATCH_NODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7807) if (memcmp(&fp->RnodeName, &vport->fc_nodename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7808) sizeof(struct lpfc_name)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7809) cnt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7812) if (cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7813) if ((ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7814) (ndlp->nlp_state == NLP_STE_MAPPED_NODE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7815) /* Log back into the node before sending the FARP. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7816) if (fp->Rflags & FARP_REQUEST_PLOGI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7817) ndlp->nlp_prev_state = ndlp->nlp_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7818) lpfc_nlp_set_state(vport, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7819) NLP_STE_PLOGI_ISSUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7820) lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7823) /* Send a FARP response to that node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7824) if (fp->Rflags & FARP_REQUEST_FARPR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7825) lpfc_issue_els_farpr(vport, did, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7828) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7831) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7832) * lpfc_els_rcv_farpr - Process an unsolicited farp response iocb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7833) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7834) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7835) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7836) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7837) * This routine processes Fibre Channel Address Resolution Protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7838) * Response (FARPR) IOCB received as an ELS unsolicited event. It simply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7839) * invokes the lpfc_els_rsp_acc() routine to the remote node to accept
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7840) * the FARP response request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7841) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7842) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7843) * 0 - Successfully processed FARPR IOCB (currently always return 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7844) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7845) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7846) lpfc_els_rcv_farpr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7847) struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7849) struct lpfc_dmabuf *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7850) uint32_t *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7851) IOCB_t *icmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7852) uint32_t did;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7854) icmd = &cmdiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7855) did = icmd->un.elsreq64.remoteID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7856) pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7857) lp = (uint32_t *) pcmd->virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7859) lp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7860) /* FARP-RSP received from DID <did> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7861) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7862) "0600 FARP-RSP received from DID x%x\n", did);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7863) /* ACCEPT the Farp resp request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7864) lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7866) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7869) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7870) * lpfc_els_rcv_fan - Process an unsolicited fan iocb command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7871) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7872) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7873) * @fan_ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7874) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7875) * This routine processes a Fabric Address Notification (FAN) IOCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7876) * command received as an ELS unsolicited event. The FAN ELS command will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7877) * only be processed on a physical port (i.e., the @vport represents the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7878) * physical port). The fabric NodeName and PortName from the FAN IOCB are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7879) * compared against those in the phba data structure. If any of those is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7880) * different, the lpfc_initial_flogi() routine is invoked to initialize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7881) * Fabric Login (FLOGI) to the fabric to start the discover over. Otherwise,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7882) * if both of those are identical, the lpfc_issue_fabric_reglogin() routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7883) * is invoked to register login to the fabric.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7884) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7885) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7886) * 0 - Successfully processed fan iocb (currently always return 0).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7887) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7888) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7889) lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7890) struct lpfc_nodelist *fan_ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7892) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7893) uint32_t *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7894) FAN *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7896) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "0265 FAN received\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7897) lp = (uint32_t *)((struct lpfc_dmabuf *)cmdiocb->context2)->virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7898) fp = (FAN *) ++lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7899) /* FAN received; Fan does not have a reply sequence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7900) if ((vport == phba->pport) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7901) (vport->port_state == LPFC_LOCAL_CFG_LINK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7902) if ((memcmp(&phba->fc_fabparam.nodeName, &fp->FnodeName,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7903) sizeof(struct lpfc_name))) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7904) (memcmp(&phba->fc_fabparam.portName, &fp->FportName,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7905) sizeof(struct lpfc_name)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7906) /* This port has switched fabrics. FLOGI is required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7907) lpfc_issue_init_vfi(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7908) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7909) /* FAN verified - skip FLOGI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7910) vport->fc_myDID = vport->fc_prevDID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7911) if (phba->sli_rev < LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7912) lpfc_issue_fabric_reglogin(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7913) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7914) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7915) "3138 Need register VFI: (x%x/%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7916) vport->fc_prevDID, vport->fc_myDID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7917) lpfc_issue_reg_vfi(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7921) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7924) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7925) * lpfc_els_timeout - Handler funciton to the els timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7926) * @t: timer context used to obtain the vport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7927) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7928) * This routine is invoked by the ELS timer after timeout. It posts the ELS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7929) * timer timeout event by setting the WORKER_ELS_TMO bit to the work port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7930) * event bitmap and then invokes the lpfc_worker_wake_up() routine to wake
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7931) * up the worker thread. It is for the worker thread to invoke the routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7932) * lpfc_els_timeout_handler() to work on the posted event WORKER_ELS_TMO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7933) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7934) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7935) lpfc_els_timeout(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7936) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7937) struct lpfc_vport *vport = from_timer(vport, t, els_tmofunc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7938) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7939) uint32_t tmo_posted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7940) unsigned long iflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7942) spin_lock_irqsave(&vport->work_port_lock, iflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7943) tmo_posted = vport->work_port_events & WORKER_ELS_TMO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7944) if ((!tmo_posted) && (!(vport->load_flag & FC_UNLOADING)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7945) vport->work_port_events |= WORKER_ELS_TMO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7946) spin_unlock_irqrestore(&vport->work_port_lock, iflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7948) if ((!tmo_posted) && (!(vport->load_flag & FC_UNLOADING)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7949) lpfc_worker_wake_up(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7950) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7954) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7955) * lpfc_els_timeout_handler - Process an els timeout event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7956) * @vport: pointer to a virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7957) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7958) * This routine is the actual handler function that processes an ELS timeout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7959) * event. It walks the ELS ring to get and abort all the IOCBs (except the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7960) * ABORT/CLOSE/FARP/FARPR/FDISC), which are associated with the @vport by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7961) * invoking the lpfc_sli_issue_abort_iotag() routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7962) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7963) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7964) lpfc_els_timeout_handler(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7966) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7967) struct lpfc_sli_ring *pring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7968) struct lpfc_iocbq *tmp_iocb, *piocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7969) IOCB_t *cmd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7970) struct lpfc_dmabuf *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7971) uint32_t els_command = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7972) uint32_t timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7973) uint32_t remote_ID = 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7974) LIST_HEAD(abort_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7977) timeout = (uint32_t)(phba->fc_ratov << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7979) pring = lpfc_phba_elsring(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7980) if (unlikely(!pring))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7981) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7983) if (phba->pport->load_flag & FC_UNLOADING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7984) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7986) spin_lock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7987) if (phba->sli_rev == LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7988) spin_lock(&pring->ring_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7990) list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7991) cmd = &piocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7993) if ((piocb->iocb_flag & LPFC_IO_LIBDFC) != 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7994) piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7995) piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7996) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7998) if (piocb->vport != vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7999) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8001) pcmd = (struct lpfc_dmabuf *) piocb->context2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8002) if (pcmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8003) els_command = *(uint32_t *) (pcmd->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8005) if (els_command == ELS_CMD_FARP ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8006) els_command == ELS_CMD_FARPR ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8007) els_command == ELS_CMD_FDISC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8008) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8010) if (piocb->drvrTimeout > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8011) if (piocb->drvrTimeout >= timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8012) piocb->drvrTimeout -= timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8013) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8014) piocb->drvrTimeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8015) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8018) remote_ID = 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8019) if (cmd->ulpCommand != CMD_GEN_REQUEST64_CR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8020) remote_ID = cmd->un.elsreq64.remoteID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8021) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8022) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8023) ndlp = __lpfc_findnode_rpi(vport, cmd->ulpContext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8024) if (ndlp && NLP_CHK_NODE_ACT(ndlp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8025) remote_ID = ndlp->nlp_DID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8027) list_add_tail(&piocb->dlist, &abort_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8029) if (phba->sli_rev == LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8030) spin_unlock(&pring->ring_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8031) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8033) list_for_each_entry_safe(piocb, tmp_iocb, &abort_list, dlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8034) cmd = &piocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8035) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8036) "0127 ELS timeout Data: x%x x%x x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8037) "x%x\n", els_command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8038) remote_ID, cmd->ulpCommand, cmd->ulpIoTag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8039) spin_lock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8040) list_del_init(&piocb->dlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8041) lpfc_sli_issue_abort_iotag(phba, pring, piocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8042) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8045) if (!list_empty(&pring->txcmplq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8046) if (!(phba->pport->load_flag & FC_UNLOADING))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8047) mod_timer(&vport->els_tmofunc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8048) jiffies + msecs_to_jiffies(1000 * timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8051) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8052) * lpfc_els_flush_cmd - Clean up the outstanding els commands to a vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8053) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8054) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8055) * This routine is used to clean up all the outstanding ELS commands on a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8056) * @vport. It first aborts the @vport by invoking lpfc_fabric_abort_vport()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8057) * routine. After that, it walks the ELS transmit queue to remove all the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8058) * IOCBs with the @vport other than the QUE_RING and ABORT/CLOSE IOCBs. For
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8059) * the IOCBs with a non-NULL completion callback function, the callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8060) * function will be invoked with the status set to IOSTAT_LOCAL_REJECT and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8061) * un.ulpWord[4] set to IOERR_SLI_ABORTED. For IOCBs with a NULL completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8062) * callback function, the IOCB will simply be released. Finally, it walks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8063) * the ELS transmit completion queue to issue an abort IOCB to any transmit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8064) * completion queue IOCB that is associated with the @vport and is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8065) * an IOCB from libdfc (i.e., the management plane IOCBs that are not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8066) * part of the discovery state machine) out to HBA by invoking the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8067) * lpfc_sli_issue_abort_iotag() routine. Note that this function issues the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8068) * abort IOCB to any transmit completion queueed IOCB, it does not guarantee
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8069) * the IOCBs are aborted when this function returns.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8070) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8071) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8072) lpfc_els_flush_cmd(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8073) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8074) LIST_HEAD(abort_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8075) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8076) struct lpfc_sli_ring *pring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8077) struct lpfc_iocbq *tmp_iocb, *piocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8078) IOCB_t *cmd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8079) unsigned long iflags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8081) lpfc_fabric_abort_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8083) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8084) * For SLI3, only the hbalock is required. But SLI4 needs to coordinate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8085) * with the ring insert operation. Because lpfc_sli_issue_abort_iotag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8086) * ultimately grabs the ring_lock, the driver must splice the list into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8087) * a working list and release the locks before calling the abort.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8088) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8089) spin_lock_irqsave(&phba->hbalock, iflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8090) pring = lpfc_phba_elsring(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8092) /* Bail out if we've no ELS wq, like in PCI error recovery case. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8093) if (unlikely(!pring)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8094) spin_unlock_irqrestore(&phba->hbalock, iflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8095) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8098) if (phba->sli_rev == LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8099) spin_lock(&pring->ring_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8101) /* First we need to issue aborts to outstanding cmds on txcmpl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8102) list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8103) if (piocb->iocb_flag & LPFC_IO_LIBDFC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8104) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8106) if (piocb->vport != vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8107) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8109) if (piocb->iocb_flag & LPFC_DRIVER_ABORTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8110) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8112) /* On the ELS ring we can have ELS_REQUESTs or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8113) * GEN_REQUESTs waiting for a response.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8114) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8115) cmd = &piocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8116) if (cmd->ulpCommand == CMD_ELS_REQUEST64_CR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8117) list_add_tail(&piocb->dlist, &abort_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8119) /* If the link is down when flushing ELS commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8120) * the firmware will not complete them till after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8121) * the link comes back up. This may confuse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8122) * discovery for the new link up, so we need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8123) * change the compl routine to just clean up the iocb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8124) * and avoid any retry logic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8125) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8126) if (phba->link_state == LPFC_LINK_DOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8127) piocb->iocb_cmpl = lpfc_cmpl_els_link_down;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8129) if (cmd->ulpCommand == CMD_GEN_REQUEST64_CR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8130) list_add_tail(&piocb->dlist, &abort_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8133) if (phba->sli_rev == LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8134) spin_unlock(&pring->ring_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8135) spin_unlock_irqrestore(&phba->hbalock, iflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8137) /* Abort each txcmpl iocb on aborted list and remove the dlist links. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8138) list_for_each_entry_safe(piocb, tmp_iocb, &abort_list, dlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8139) spin_lock_irqsave(&phba->hbalock, iflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8140) list_del_init(&piocb->dlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8141) lpfc_sli_issue_abort_iotag(phba, pring, piocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8142) spin_unlock_irqrestore(&phba->hbalock, iflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8144) if (!list_empty(&abort_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8145) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8146) "3387 abort list for txq not empty\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8147) INIT_LIST_HEAD(&abort_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8149) spin_lock_irqsave(&phba->hbalock, iflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8150) if (phba->sli_rev == LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8151) spin_lock(&pring->ring_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8153) /* No need to abort the txq list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8154) * just queue them up for lpfc_sli_cancel_iocbs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8155) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8156) list_for_each_entry_safe(piocb, tmp_iocb, &pring->txq, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8157) cmd = &piocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8159) if (piocb->iocb_flag & LPFC_IO_LIBDFC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8160) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8163) /* Do not flush out the QUE_RING and ABORT/CLOSE iocbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8164) if (cmd->ulpCommand == CMD_QUE_RING_BUF_CN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8165) cmd->ulpCommand == CMD_QUE_RING_BUF64_CN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8166) cmd->ulpCommand == CMD_CLOSE_XRI_CN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8167) cmd->ulpCommand == CMD_ABORT_XRI_CN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8168) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8170) if (piocb->vport != vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8171) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8173) list_del_init(&piocb->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8174) list_add_tail(&piocb->list, &abort_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8177) /* The same holds true for any FLOGI/FDISC on the fabric_iocb_list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8178) if (vport == phba->pport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8179) list_for_each_entry_safe(piocb, tmp_iocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8180) &phba->fabric_iocb_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8181) cmd = &piocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8182) list_del_init(&piocb->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8183) list_add_tail(&piocb->list, &abort_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8187) if (phba->sli_rev == LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8188) spin_unlock(&pring->ring_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8189) spin_unlock_irqrestore(&phba->hbalock, iflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8191) /* Cancel all the IOCBs from the completions list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8192) lpfc_sli_cancel_iocbs(phba, &abort_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8193) IOSTAT_LOCAL_REJECT, IOERR_SLI_ABORTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8195) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8198) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8199) * lpfc_els_flush_all_cmd - Clean up all the outstanding els commands to a HBA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8200) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8201) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8202) * This routine is used to clean up all the outstanding ELS commands on a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8203) * @phba. It first aborts the @phba by invoking the lpfc_fabric_abort_hba()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8204) * routine. After that, it walks the ELS transmit queue to remove all the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8205) * IOCBs to the @phba other than the QUE_RING and ABORT/CLOSE IOCBs. For
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8206) * the IOCBs with the completion callback function associated, the callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8207) * function will be invoked with the status set to IOSTAT_LOCAL_REJECT and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8208) * un.ulpWord[4] set to IOERR_SLI_ABORTED. For IOCBs without the completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8209) * callback function associated, the IOCB will simply be released. Finally,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8210) * it walks the ELS transmit completion queue to issue an abort IOCB to any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8211) * transmit completion queue IOCB that is not an IOCB from libdfc (i.e., the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8212) * management plane IOCBs that are not part of the discovery state machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8213) * out to HBA by invoking the lpfc_sli_issue_abort_iotag() routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8214) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8215) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8216) lpfc_els_flush_all_cmd(struct lpfc_hba *phba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8218) struct lpfc_vport *vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8220) spin_lock_irq(&phba->port_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8221) list_for_each_entry(vport, &phba->port_list, listentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8222) lpfc_els_flush_cmd(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8223) spin_unlock_irq(&phba->port_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8225) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8228) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8229) * lpfc_send_els_failure_event - Posts an ELS command failure event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8230) * @phba: Pointer to hba context object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8231) * @cmdiocbp: Pointer to command iocb which reported error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8232) * @rspiocbp: Pointer to response iocb which reported error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8233) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8234) * This function sends an event when there is an ELS command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8235) * failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8236) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8237) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8238) lpfc_send_els_failure_event(struct lpfc_hba *phba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8239) struct lpfc_iocbq *cmdiocbp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8240) struct lpfc_iocbq *rspiocbp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8242) struct lpfc_vport *vport = cmdiocbp->vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8243) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8244) struct lpfc_lsrjt_event lsrjt_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8245) struct lpfc_fabric_event_header fabric_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8246) struct ls_rjt stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8247) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8248) uint32_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8250) ndlp = cmdiocbp->context1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8251) if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8252) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8254) if (rspiocbp->iocb.ulpStatus == IOSTAT_LS_RJT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8255) lsrjt_event.header.event_type = FC_REG_ELS_EVENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8256) lsrjt_event.header.subcategory = LPFC_EVENT_LSRJT_RCV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8257) memcpy(lsrjt_event.header.wwpn, &ndlp->nlp_portname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8258) sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8259) memcpy(lsrjt_event.header.wwnn, &ndlp->nlp_nodename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8260) sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8261) pcmd = (uint32_t *) (((struct lpfc_dmabuf *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8262) cmdiocbp->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8263) lsrjt_event.command = (pcmd != NULL) ? *pcmd : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8264) stat.un.lsRjtError = be32_to_cpu(rspiocbp->iocb.un.ulpWord[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8265) lsrjt_event.reason_code = stat.un.b.lsRjtRsnCode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8266) lsrjt_event.explanation = stat.un.b.lsRjtRsnCodeExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8267) fc_host_post_vendor_event(shost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8268) fc_get_event_number(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8269) sizeof(lsrjt_event),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8270) (char *)&lsrjt_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8271) LPFC_NL_VENDOR_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8272) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8274) if ((rspiocbp->iocb.ulpStatus == IOSTAT_NPORT_BSY) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8275) (rspiocbp->iocb.ulpStatus == IOSTAT_FABRIC_BSY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8276) fabric_event.event_type = FC_REG_FABRIC_EVENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8277) if (rspiocbp->iocb.ulpStatus == IOSTAT_NPORT_BSY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8278) fabric_event.subcategory = LPFC_EVENT_PORT_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8279) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8280) fabric_event.subcategory = LPFC_EVENT_FABRIC_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8281) memcpy(fabric_event.wwpn, &ndlp->nlp_portname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8282) sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8283) memcpy(fabric_event.wwnn, &ndlp->nlp_nodename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8284) sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8285) fc_host_post_vendor_event(shost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8286) fc_get_event_number(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8287) sizeof(fabric_event),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8288) (char *)&fabric_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8289) LPFC_NL_VENDOR_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8290) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8295) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8296) * lpfc_send_els_event - Posts unsolicited els event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8297) * @vport: Pointer to vport object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8298) * @ndlp: Pointer FC node object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8299) * @payload: ELS command code type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8300) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8301) * This function posts an event when there is an incoming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8302) * unsolicited ELS command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8303) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8304) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8305) lpfc_send_els_event(struct lpfc_vport *vport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8306) struct lpfc_nodelist *ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8307) uint32_t *payload)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8309) struct lpfc_els_event_header *els_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8310) struct lpfc_logo_event *logo_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8311) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8313) if (*payload == ELS_CMD_LOGO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8314) logo_data = kmalloc(sizeof(struct lpfc_logo_event), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8315) if (!logo_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8316) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8317) "0148 Failed to allocate memory "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8318) "for LOGO event\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8319) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8321) els_data = &logo_data->header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8322) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8323) els_data = kmalloc(sizeof(struct lpfc_els_event_header),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8324) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8325) if (!els_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8326) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8327) "0149 Failed to allocate memory "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8328) "for ELS event\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8329) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8332) els_data->event_type = FC_REG_ELS_EVENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8333) switch (*payload) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8334) case ELS_CMD_PLOGI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8335) els_data->subcategory = LPFC_EVENT_PLOGI_RCV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8336) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8337) case ELS_CMD_PRLO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8338) els_data->subcategory = LPFC_EVENT_PRLO_RCV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8339) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8340) case ELS_CMD_ADISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8341) els_data->subcategory = LPFC_EVENT_ADISC_RCV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8342) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8343) case ELS_CMD_LOGO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8344) els_data->subcategory = LPFC_EVENT_LOGO_RCV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8345) /* Copy the WWPN in the LOGO payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8346) memcpy(logo_data->logo_wwpn, &payload[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8347) sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8348) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8349) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8350) kfree(els_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8351) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8353) memcpy(els_data->wwpn, &ndlp->nlp_portname, sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8354) memcpy(els_data->wwnn, &ndlp->nlp_nodename, sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8355) if (*payload == ELS_CMD_LOGO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8356) fc_host_post_vendor_event(shost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8357) fc_get_event_number(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8358) sizeof(struct lpfc_logo_event),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8359) (char *)logo_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8360) LPFC_NL_VENDOR_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8361) kfree(logo_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8362) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8363) fc_host_post_vendor_event(shost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8364) fc_get_event_number(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8365) sizeof(struct lpfc_els_event_header),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8366) (char *)els_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8367) LPFC_NL_VENDOR_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8368) kfree(els_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8371) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8375) DECLARE_ENUM2STR_LOOKUP(lpfc_get_tlv_dtag_nm, fc_ls_tlv_dtag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8376) FC_LS_TLV_DTAG_INIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8378) DECLARE_ENUM2STR_LOOKUP(lpfc_get_fpin_li_event_nm, fc_fpin_li_event_types,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8379) FC_FPIN_LI_EVT_TYPES_INIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8381) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8382) * lpfc_els_rcv_fpin_li - Process an FPIN Link Integrity Event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8383) * @vport: Pointer to vport object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8384) * @tlv: Pointer to the Link Integrity Notification Descriptor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8385) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8386) * This function processes a link integrity FPIN event by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8387) * logging a message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8388) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8389) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8390) lpfc_els_rcv_fpin_li(struct lpfc_vport *vport, struct fc_tlv_desc *tlv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8392) struct fc_fn_li_desc *li = (struct fc_fn_li_desc *)tlv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8393) const char *li_evt_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8394) u32 li_evt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8396) li_evt = be16_to_cpu(li->event_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8397) li_evt_str = lpfc_get_fpin_li_event_nm(li_evt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8399) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8400) "4680 FPIN Link Integrity %s (x%x) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8401) "Detecting PN x%016llx Attached PN x%016llx "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8402) "Duration %d mSecs Count %d Port Cnt %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8403) li_evt_str, li_evt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8404) be64_to_cpu(li->detecting_wwpn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8405) be64_to_cpu(li->attached_wwpn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8406) be32_to_cpu(li->event_threshold),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8407) be32_to_cpu(li->event_count),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8408) be32_to_cpu(li->pname_count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8411) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8412) lpfc_els_rcv_fpin(struct lpfc_vport *vport, struct fc_els_fpin *fpin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8413) u32 fpin_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8415) struct fc_tlv_desc *tlv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8416) const char *dtag_nm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8417) uint32_t desc_cnt = 0, bytes_remain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8418) u32 dtag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8420) /* FPINs handled only if we are in the right discovery state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8421) if (vport->port_state < LPFC_DISC_AUTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8422) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8424) /* make sure there is the full fpin header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8425) if (fpin_length < sizeof(struct fc_els_fpin))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8426) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8428) tlv = (struct fc_tlv_desc *)&fpin->fpin_desc[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8429) bytes_remain = fpin_length - offsetof(struct fc_els_fpin, fpin_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8430) bytes_remain = min_t(u32, bytes_remain, be32_to_cpu(fpin->desc_len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8432) /* process each descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8433) while (bytes_remain >= FC_TLV_DESC_HDR_SZ &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8434) bytes_remain >= FC_TLV_DESC_SZ_FROM_LENGTH(tlv)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8436) dtag = be32_to_cpu(tlv->desc_tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8437) switch (dtag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8438) case ELS_DTAG_LNK_INTEGRITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8439) lpfc_els_rcv_fpin_li(vport, tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8440) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8441) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8442) dtag_nm = lpfc_get_tlv_dtag_nm(dtag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8443) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8444) "4678 skipped FPIN descriptor[%d]: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8445) "tag x%x (%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8446) desc_cnt, dtag, dtag_nm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8447) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8450) desc_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8451) bytes_remain -= FC_TLV_DESC_SZ_FROM_LENGTH(tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8452) tlv = fc_tlv_next_desc(tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8455) fc_host_fpin_rcv(lpfc_shost_from_vport(vport), fpin_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8456) (char *)fpin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8459) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8460) * lpfc_els_unsol_buffer - Process an unsolicited event data buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8461) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8462) * @pring: pointer to a SLI ring.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8463) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8464) * @elsiocb: pointer to lpfc els command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8465) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8466) * This routine is used for processing the IOCB associated with a unsolicited
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8467) * event. It first determines whether there is an existing ndlp that matches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8468) * the DID from the unsolicited IOCB. If not, it will create a new one with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8469) * the DID from the unsolicited IOCB. The ELS command from the unsolicited
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8470) * IOCB is then used to invoke the proper routine and to set up proper state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8471) * of the discovery state machine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8472) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8473) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8474) lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8475) struct lpfc_vport *vport, struct lpfc_iocbq *elsiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8477) struct Scsi_Host *shost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8478) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8479) struct ls_rjt stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8480) uint32_t *payload, payload_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8481) uint32_t cmd, did, newnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8482) uint8_t rjt_exp, rjt_err = 0, init_link = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8483) IOCB_t *icmd = &elsiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8484) LPFC_MBOXQ_t *mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8486) if (!vport || !(elsiocb->context2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8487) goto dropit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8489) newnode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8490) payload = ((struct lpfc_dmabuf *)elsiocb->context2)->virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8491) payload_len = elsiocb->iocb.unsli3.rcvsli3.acc_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8492) cmd = *payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8493) if ((phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8494) lpfc_post_buffer(phba, pring, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8496) did = icmd->un.rcvels.remoteID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8497) if (icmd->ulpStatus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8498) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8499) "RCV Unsol ELS: status:x%x/x%x did:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8500) icmd->ulpStatus, icmd->un.ulpWord[4], did);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8501) goto dropit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8504) /* Check to see if link went down during discovery */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8505) if (lpfc_els_chk_latt(vport))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8506) goto dropit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8508) /* Ignore traffic received during vport shutdown. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8509) if (vport->load_flag & FC_UNLOADING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8510) goto dropit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8512) /* If NPort discovery is delayed drop incoming ELS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8513) if ((vport->fc_flag & FC_DISC_DELAYED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8514) (cmd != ELS_CMD_PLOGI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8515) goto dropit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8517) ndlp = lpfc_findnode_did(vport, did);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8518) if (!ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8519) /* Cannot find existing Fabric ndlp, so allocate a new one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8520) ndlp = lpfc_nlp_init(vport, did);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8521) if (!ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8522) goto dropit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8523) lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8524) newnode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8525) if ((did & Fabric_DID_MASK) == Fabric_DID_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8526) ndlp->nlp_type |= NLP_FABRIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8527) } else if (!NLP_CHK_NODE_ACT(ndlp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8528) ndlp = lpfc_enable_node(vport, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8529) NLP_STE_UNUSED_NODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8530) if (!ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8531) goto dropit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8532) lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8533) newnode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8534) if ((did & Fabric_DID_MASK) == Fabric_DID_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8535) ndlp->nlp_type |= NLP_FABRIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8536) } else if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8537) /* This is similar to the new node path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8538) ndlp = lpfc_nlp_get(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8539) if (!ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8540) goto dropit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8541) lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8542) newnode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8545) phba->fc_stat.elsRcvFrame++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8547) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8548) * Do not process any unsolicited ELS commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8549) * if the ndlp is in DEV_LOSS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8550) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8551) shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8552) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8553) if (ndlp->nlp_flag & NLP_IN_DEV_LOSS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8554) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8555) if (newnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8556) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8557) goto dropit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8559) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8561) elsiocb->context1 = lpfc_nlp_get(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8562) elsiocb->vport = vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8564) if ((cmd & ELS_CMD_MASK) == ELS_CMD_RSCN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8565) cmd &= ELS_CMD_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8567) /* ELS command <elsCmd> received from NPORT <did> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8568) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8569) "0112 ELS command x%x received from NPORT x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8570) "Data: x%x x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8571) cmd, did, vport->port_state, vport->fc_flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8572) vport->fc_myDID, vport->fc_prevDID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8574) /* reject till our FLOGI completes or PLOGI assigned DID via PT2PT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8575) if ((vport->port_state < LPFC_FABRIC_CFG_LINK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8576) (cmd != ELS_CMD_FLOGI) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8577) !((cmd == ELS_CMD_PLOGI) && (vport->fc_flag & FC_PT2PT))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8578) rjt_err = LSRJT_LOGICAL_BSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8579) rjt_exp = LSEXP_NOTHING_MORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8580) goto lsrjt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8583) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8584) case ELS_CMD_PLOGI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8585) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8586) "RCV PLOGI: did:x%x/ste:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8587) did, vport->port_state, ndlp->nlp_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8589) phba->fc_stat.elsRcvPLOGI++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8590) ndlp = lpfc_plogi_confirm_nport(phba, payload, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8591) if (phba->sli_rev == LPFC_SLI_REV4 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8592) (phba->pport->fc_flag & FC_PT2PT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8593) vport->fc_prevDID = vport->fc_myDID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8594) /* Our DID needs to be updated before registering
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8595) * the vfi. This is done in lpfc_rcv_plogi but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8596) * that is called after the reg_vfi.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8597) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8598) vport->fc_myDID = elsiocb->iocb.un.rcvels.parmRo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8599) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8600) "3312 Remote port assigned DID x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8601) "%x\n", vport->fc_myDID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8602) vport->fc_prevDID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8605) lpfc_send_els_event(vport, ndlp, payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8607) /* If Nport discovery is delayed, reject PLOGIs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8608) if (vport->fc_flag & FC_DISC_DELAYED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8609) rjt_err = LSRJT_UNABLE_TPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8610) rjt_exp = LSEXP_NOTHING_MORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8611) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8614) if (vport->port_state < LPFC_DISC_AUTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8615) if (!(phba->pport->fc_flag & FC_PT2PT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8616) (phba->pport->fc_flag & FC_PT2PT_PLOGI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8617) rjt_err = LSRJT_UNABLE_TPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8618) rjt_exp = LSEXP_NOTHING_MORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8619) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8623) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8624) ndlp->nlp_flag &= ~NLP_TARGET_REMOVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8625) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8627) lpfc_disc_state_machine(vport, ndlp, elsiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8628) NLP_EVT_RCV_PLOGI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8630) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8631) case ELS_CMD_FLOGI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8632) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8633) "RCV FLOGI: did:x%x/ste:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8634) did, vport->port_state, ndlp->nlp_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8636) phba->fc_stat.elsRcvFLOGI++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8638) /* If the driver believes fabric discovery is done and is ready,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8639) * bounce the link. There is some descrepancy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8640) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8641) if (vport->port_state >= LPFC_LOCAL_CFG_LINK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8642) vport->fc_flag & FC_PT2PT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8643) vport->rcv_flogi_cnt >= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8644) rjt_err = LSRJT_LOGICAL_BSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8645) rjt_exp = LSEXP_NOTHING_MORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8646) init_link++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8647) goto lsrjt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8650) lpfc_els_rcv_flogi(vport, elsiocb, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8651) if (newnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8652) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8653) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8654) case ELS_CMD_LOGO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8655) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8656) "RCV LOGO: did:x%x/ste:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8657) did, vport->port_state, ndlp->nlp_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8659) phba->fc_stat.elsRcvLOGO++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8660) lpfc_send_els_event(vport, ndlp, payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8661) if (vport->port_state < LPFC_DISC_AUTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8662) rjt_err = LSRJT_UNABLE_TPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8663) rjt_exp = LSEXP_NOTHING_MORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8664) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8666) lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_LOGO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8667) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8668) case ELS_CMD_PRLO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8669) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8670) "RCV PRLO: did:x%x/ste:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8671) did, vport->port_state, ndlp->nlp_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8673) phba->fc_stat.elsRcvPRLO++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8674) lpfc_send_els_event(vport, ndlp, payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8675) if (vport->port_state < LPFC_DISC_AUTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8676) rjt_err = LSRJT_UNABLE_TPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8677) rjt_exp = LSEXP_NOTHING_MORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8678) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8680) lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8681) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8682) case ELS_CMD_LCB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8683) phba->fc_stat.elsRcvLCB++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8684) lpfc_els_rcv_lcb(vport, elsiocb, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8685) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8686) case ELS_CMD_RDP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8687) phba->fc_stat.elsRcvRDP++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8688) lpfc_els_rcv_rdp(vport, elsiocb, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8689) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8690) case ELS_CMD_RSCN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8691) phba->fc_stat.elsRcvRSCN++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8692) lpfc_els_rcv_rscn(vport, elsiocb, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8693) if (newnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8694) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8695) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8696) case ELS_CMD_ADISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8697) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8698) "RCV ADISC: did:x%x/ste:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8699) did, vport->port_state, ndlp->nlp_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8701) lpfc_send_els_event(vport, ndlp, payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8702) phba->fc_stat.elsRcvADISC++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8703) if (vport->port_state < LPFC_DISC_AUTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8704) rjt_err = LSRJT_UNABLE_TPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8705) rjt_exp = LSEXP_NOTHING_MORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8706) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8708) lpfc_disc_state_machine(vport, ndlp, elsiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8709) NLP_EVT_RCV_ADISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8710) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8711) case ELS_CMD_PDISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8712) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8713) "RCV PDISC: did:x%x/ste:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8714) did, vport->port_state, ndlp->nlp_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8716) phba->fc_stat.elsRcvPDISC++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8717) if (vport->port_state < LPFC_DISC_AUTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8718) rjt_err = LSRJT_UNABLE_TPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8719) rjt_exp = LSEXP_NOTHING_MORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8720) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8722) lpfc_disc_state_machine(vport, ndlp, elsiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8723) NLP_EVT_RCV_PDISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8724) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8725) case ELS_CMD_FARPR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8726) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8727) "RCV FARPR: did:x%x/ste:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8728) did, vport->port_state, ndlp->nlp_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8730) phba->fc_stat.elsRcvFARPR++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8731) lpfc_els_rcv_farpr(vport, elsiocb, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8732) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8733) case ELS_CMD_FARP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8734) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8735) "RCV FARP: did:x%x/ste:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8736) did, vport->port_state, ndlp->nlp_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8738) phba->fc_stat.elsRcvFARP++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8739) lpfc_els_rcv_farp(vport, elsiocb, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8740) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8741) case ELS_CMD_FAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8742) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8743) "RCV FAN: did:x%x/ste:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8744) did, vport->port_state, ndlp->nlp_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8746) phba->fc_stat.elsRcvFAN++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8747) lpfc_els_rcv_fan(vport, elsiocb, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8748) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8749) case ELS_CMD_PRLI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8750) case ELS_CMD_NVMEPRLI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8751) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8752) "RCV PRLI: did:x%x/ste:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8753) did, vport->port_state, ndlp->nlp_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8755) phba->fc_stat.elsRcvPRLI++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8756) if ((vport->port_state < LPFC_DISC_AUTH) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8757) (vport->fc_flag & FC_FABRIC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8758) rjt_err = LSRJT_UNABLE_TPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8759) rjt_exp = LSEXP_NOTHING_MORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8760) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8762) lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8763) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8764) case ELS_CMD_LIRR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8765) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8766) "RCV LIRR: did:x%x/ste:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8767) did, vport->port_state, ndlp->nlp_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8769) phba->fc_stat.elsRcvLIRR++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8770) lpfc_els_rcv_lirr(vport, elsiocb, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8771) if (newnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8772) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8773) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8774) case ELS_CMD_RLS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8775) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8776) "RCV RLS: did:x%x/ste:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8777) did, vport->port_state, ndlp->nlp_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8779) phba->fc_stat.elsRcvRLS++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8780) lpfc_els_rcv_rls(vport, elsiocb, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8781) if (newnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8782) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8783) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8784) case ELS_CMD_RPL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8785) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8786) "RCV RPL: did:x%x/ste:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8787) did, vport->port_state, ndlp->nlp_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8789) phba->fc_stat.elsRcvRPL++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8790) lpfc_els_rcv_rpl(vport, elsiocb, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8791) if (newnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8792) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8793) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8794) case ELS_CMD_RNID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8795) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8796) "RCV RNID: did:x%x/ste:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8797) did, vport->port_state, ndlp->nlp_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8799) phba->fc_stat.elsRcvRNID++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8800) lpfc_els_rcv_rnid(vport, elsiocb, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8801) if (newnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8802) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8803) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8804) case ELS_CMD_RTV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8805) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8806) "RCV RTV: did:x%x/ste:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8807) did, vport->port_state, ndlp->nlp_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8808) phba->fc_stat.elsRcvRTV++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8809) lpfc_els_rcv_rtv(vport, elsiocb, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8810) if (newnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8811) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8812) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8813) case ELS_CMD_RRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8814) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8815) "RCV RRQ: did:x%x/ste:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8816) did, vport->port_state, ndlp->nlp_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8818) phba->fc_stat.elsRcvRRQ++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8819) lpfc_els_rcv_rrq(vport, elsiocb, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8820) if (newnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8821) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8822) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8823) case ELS_CMD_ECHO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8824) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8825) "RCV ECHO: did:x%x/ste:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8826) did, vport->port_state, ndlp->nlp_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8828) phba->fc_stat.elsRcvECHO++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8829) lpfc_els_rcv_echo(vport, elsiocb, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8830) if (newnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8831) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8832) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8833) case ELS_CMD_REC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8834) /* receive this due to exchange closed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8835) rjt_err = LSRJT_UNABLE_TPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8836) rjt_exp = LSEXP_INVALID_OX_RX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8837) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8838) case ELS_CMD_FPIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8839) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8840) "RCV FPIN: did:x%x/ste:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8841) did, vport->port_state, ndlp->nlp_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8843) lpfc_els_rcv_fpin(vport, (struct fc_els_fpin *)payload,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8844) payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8846) /* There are no replies, so no rjt codes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8847) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8848) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8849) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8850) "RCV ELS cmd: cmd:x%x did:x%x/ste:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8851) cmd, did, vport->port_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8853) /* Unsupported ELS command, reject */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8854) rjt_err = LSRJT_CMD_UNSUPPORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8855) rjt_exp = LSEXP_NOTHING_MORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8857) /* Unknown ELS command <elsCmd> received from NPORT <did> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8858) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8859) "0115 Unknown ELS command x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8860) "received from NPORT x%x\n", cmd, did);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8861) if (newnode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8862) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8863) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8866) lsrjt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8867) /* check if need to LS_RJT received ELS cmd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8868) if (rjt_err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8869) memset(&stat, 0, sizeof(stat));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8870) stat.un.b.lsRjtRsnCode = rjt_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8871) stat.un.b.lsRjtRsnCodeExp = rjt_exp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8872) lpfc_els_rsp_reject(vport, stat.un.lsRjtError, elsiocb, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8873) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8876) lpfc_nlp_put(elsiocb->context1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8877) elsiocb->context1 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8879) /* Special case. Driver received an unsolicited command that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8880) * unsupportable given the driver's current state. Reset the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8881) * link and start over.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8882) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8883) if (init_link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8884) mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8885) if (!mbox)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8886) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8887) lpfc_linkdown(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8888) lpfc_init_link(phba, mbox,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8889) phba->cfg_topology,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8890) phba->cfg_link_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8891) mbox->u.mb.un.varInitLnk.lipsr_AL_PA = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8892) mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8893) mbox->vport = vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8894) if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8895) MBX_NOT_FINISHED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8896) mempool_free(mbox, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8899) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8901) dropit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8902) if (vport && !(vport->load_flag & FC_UNLOADING))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8903) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8904) "0111 Dropping received ELS cmd "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8905) "Data: x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8906) icmd->ulpStatus, icmd->un.ulpWord[4], icmd->ulpTimeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8907) phba->fc_stat.elsRcvDrop++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8910) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8911) * lpfc_els_unsol_event - Process an unsolicited event from an els sli ring
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8912) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8913) * @pring: pointer to a SLI ring.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8914) * @elsiocb: pointer to lpfc els iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8915) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8916) * This routine is used to process an unsolicited event received from a SLI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8917) * (Service Level Interface) ring. The actual processing of the data buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8918) * associated with the unsolicited event is done by invoking the routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8919) * lpfc_els_unsol_buffer() after properly set up the iocb buffer from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8920) * SLI ring on which the unsolicited event was received.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8921) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8922) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8923) lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8924) struct lpfc_iocbq *elsiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8925) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8926) struct lpfc_vport *vport = phba->pport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8927) IOCB_t *icmd = &elsiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8928) dma_addr_t paddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8929) struct lpfc_dmabuf *bdeBuf1 = elsiocb->context2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8930) struct lpfc_dmabuf *bdeBuf2 = elsiocb->context3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8932) elsiocb->context1 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8933) elsiocb->context2 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8934) elsiocb->context3 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8936) if (icmd->ulpStatus == IOSTAT_NEED_BUFFER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8937) lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8938) } else if (icmd->ulpStatus == IOSTAT_LOCAL_REJECT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8939) (icmd->un.ulpWord[4] & IOERR_PARAM_MASK) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8940) IOERR_RCV_BUFFER_WAITING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8941) phba->fc_stat.NoRcvBuf++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8942) /* Not enough posted buffers; Try posting more buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8943) if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8944) lpfc_post_buffer(phba, pring, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8945) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8948) if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8949) (icmd->ulpCommand == CMD_IOCB_RCV_ELS64_CX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8950) icmd->ulpCommand == CMD_IOCB_RCV_SEQ64_CX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8951) if (icmd->unsli3.rcvsli3.vpi == 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8952) vport = phba->pport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8953) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8954) vport = lpfc_find_vport_by_vpid(phba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8955) icmd->unsli3.rcvsli3.vpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8958) /* If there are no BDEs associated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8959) * with this IOCB, there is nothing to do.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8960) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8961) if (icmd->ulpBdeCount == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8962) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8964) /* type of ELS cmd is first 32bit word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8965) * in packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8966) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8967) if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8968) elsiocb->context2 = bdeBuf1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8969) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8970) paddr = getPaddr(icmd->un.cont64[0].addrHigh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8971) icmd->un.cont64[0].addrLow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8972) elsiocb->context2 = lpfc_sli_ringpostbuf_get(phba, pring,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8973) paddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8976) lpfc_els_unsol_buffer(phba, pring, vport, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8977) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8978) * The different unsolicited event handlers would tell us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8979) * if they are done with "mp" by setting context2 to NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8980) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8981) if (elsiocb->context2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8982) lpfc_in_buf_free(phba, (struct lpfc_dmabuf *)elsiocb->context2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8983) elsiocb->context2 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8986) /* RCV_ELS64_CX provide for 2 BDEs - process 2nd if included */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8987) if ((phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8988) icmd->ulpBdeCount == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8989) elsiocb->context2 = bdeBuf2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8990) lpfc_els_unsol_buffer(phba, pring, vport, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8991) /* free mp if we are done with it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8992) if (elsiocb->context2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8993) lpfc_in_buf_free(phba, elsiocb->context2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8994) elsiocb->context2 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8999) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9000) lpfc_start_fdmi(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9002) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9004) /* If this is the first time, allocate an ndlp and initialize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9005) * it. Otherwise, make sure the node is enabled and then do the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9006) * login.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9007) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9008) ndlp = lpfc_findnode_did(vport, FDMI_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9009) if (!ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9010) ndlp = lpfc_nlp_init(vport, FDMI_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9011) if (ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9012) ndlp->nlp_type |= NLP_FABRIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9013) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9014) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9017) if (!NLP_CHK_NODE_ACT(ndlp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9018) ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_NPR_NODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9020) if (ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9021) lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9022) lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9026) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9027) * lpfc_do_scr_ns_plogi - Issue a plogi to the name server for scr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9028) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9029) * @vport: pointer to a virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9030) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9031) * This routine issues a Port Login (PLOGI) to the Name Server with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9032) * State Change Request (SCR) for a @vport. This routine will create an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9033) * ndlp for the Name Server associated to the @vport if such node does
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9034) * not already exist. The PLOGI to Name Server is issued by invoking the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9035) * lpfc_issue_els_plogi() routine. If Fabric-Device Management Interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9036) * (FDMI) is configured to the @vport, a FDMI node will be created and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9037) * the PLOGI to FDMI is issued by invoking lpfc_issue_els_plogi() routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9038) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9039) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9040) lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9041) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9042) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9043) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9045) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9046) * If lpfc_delay_discovery parameter is set and the clean address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9047) * bit is cleared and fc fabric parameters chenged, delay FC NPort
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9048) * discovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9049) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9050) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9051) if (vport->fc_flag & FC_DISC_DELAYED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9052) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9053) lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9054) "3334 Delay fc port discovery for %d seconds\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9055) phba->fc_ratov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9056) mod_timer(&vport->delayed_disc_tmo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9057) jiffies + msecs_to_jiffies(1000 * phba->fc_ratov));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9058) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9060) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9062) ndlp = lpfc_findnode_did(vport, NameServer_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9063) if (!ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9064) ndlp = lpfc_nlp_init(vport, NameServer_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9065) if (!ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9066) if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9067) lpfc_disc_start(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9068) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9070) lpfc_vport_set_state(vport, FC_VPORT_FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9071) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9072) "0251 NameServer login: no memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9073) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9075) } else if (!NLP_CHK_NODE_ACT(ndlp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9076) ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9077) if (!ndlp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9078) if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9079) lpfc_disc_start(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9080) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9082) lpfc_vport_set_state(vport, FC_VPORT_FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9083) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9084) "0348 NameServer login: node freed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9085) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9088) ndlp->nlp_type |= NLP_FABRIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9090) lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9092) if (lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9093) lpfc_vport_set_state(vport, FC_VPORT_FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9094) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9095) "0252 Cannot issue NameServer login\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9096) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9099) if ((phba->cfg_enable_SmartSAN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9100) (phba->cfg_fdmi_on == LPFC_FDMI_SUPPORT)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9101) (vport->load_flag & FC_ALLOW_FDMI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9102) lpfc_start_fdmi(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9105) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9106) * lpfc_cmpl_reg_new_vport - Completion callback function to register new vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9107) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9108) * @pmb: pointer to the driver internal queue element for mailbox command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9109) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9110) * This routine is the completion callback function to register new vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9111) * mailbox command. If the new vport mailbox command completes successfully,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9112) * the fabric registration login shall be performed on physical port (the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9113) * new vport created is actually a physical port, with VPI 0) or the port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9114) * login to Name Server for State Change Request (SCR) will be performed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9115) * on virtual port (real virtual port, with VPI greater than 0).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9116) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9117) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9118) lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9120) struct lpfc_vport *vport = pmb->vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9121) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9122) struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *)pmb->ctx_ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9123) MAILBOX_t *mb = &pmb->u.mb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9124) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9126) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9127) vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9128) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9130) if (mb->mbxStatus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9131) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9132) "0915 Register VPI failed : Status: x%x"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9133) " upd bit: x%x \n", mb->mbxStatus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9134) mb->un.varRegVpi.upd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9135) if (phba->sli_rev == LPFC_SLI_REV4 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9136) mb->un.varRegVpi.upd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9137) goto mbox_err_exit ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9139) switch (mb->mbxStatus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9140) case 0x11: /* unsupported feature */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9141) case 0x9603: /* max_vpi exceeded */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9142) case 0x9602: /* Link event since CLEAR_LA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9143) /* giving up on vport registration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9144) lpfc_vport_set_state(vport, FC_VPORT_FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9145) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9146) vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9147) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9148) lpfc_can_disctmo(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9149) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9150) /* If reg_vpi fail with invalid VPI status, re-init VPI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9151) case 0x20:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9152) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9153) vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9154) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9155) lpfc_init_vpi(phba, pmb, vport->vpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9156) pmb->vport = vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9157) pmb->mbox_cmpl = lpfc_init_vpi_cmpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9158) rc = lpfc_sli_issue_mbox(phba, pmb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9159) MBX_NOWAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9160) if (rc == MBX_NOT_FINISHED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9161) lpfc_printf_vlog(vport, KERN_ERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9162) LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9163) "2732 Failed to issue INIT_VPI"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9164) " mailbox command\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9165) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9166) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9167) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9169) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9170) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9171) /* Try to recover from this error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9172) if (phba->sli_rev == LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9173) lpfc_sli4_unreg_all_rpis(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9174) lpfc_mbx_unreg_vpi(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9175) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9176) vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9177) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9178) if (mb->mbxStatus == MBX_NOT_FINISHED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9179) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9180) if ((vport->port_type == LPFC_PHYSICAL_PORT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9181) !(vport->fc_flag & FC_LOGO_RCVD_DID_CHNG)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9182) if (phba->sli_rev == LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9183) lpfc_issue_init_vfi(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9184) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9185) lpfc_initial_flogi(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9186) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9187) lpfc_initial_fdisc(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9189) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9191) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9192) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9193) vport->vpi_state |= LPFC_VPI_REGISTERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9194) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9195) if (vport == phba->pport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9196) if (phba->sli_rev < LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9197) lpfc_issue_fabric_reglogin(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9198) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9199) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9200) * If the physical port is instantiated using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9201) * FDISC, do not start vport discovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9202) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9203) if (vport->port_state != LPFC_FDISC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9204) lpfc_start_fdiscs(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9205) lpfc_do_scr_ns_plogi(phba, vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9207) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9208) lpfc_do_scr_ns_plogi(phba, vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9210) mbox_err_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9211) /* Now, we decrement the ndlp reference count held for this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9212) * callback function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9213) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9214) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9216) mempool_free(pmb, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9217) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9220) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9221) * lpfc_register_new_vport - Register a new vport with a HBA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9222) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9223) * @vport: pointer to a host virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9224) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9225) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9226) * This routine registers the @vport as a new virtual port with a HBA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9227) * It is done through a registering vpi mailbox command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9228) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9229) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9230) lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9231) struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9233) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9234) LPFC_MBOXQ_t *mbox;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9236) mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9237) if (mbox) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9238) lpfc_reg_vpi(vport, mbox);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9239) mbox->vport = vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9240) mbox->ctx_ndlp = lpfc_nlp_get(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9241) mbox->mbox_cmpl = lpfc_cmpl_reg_new_vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9242) if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9243) == MBX_NOT_FINISHED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9244) /* mailbox command not success, decrement ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9245) * reference count for this command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9246) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9247) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9248) mempool_free(mbox, phba->mbox_mem_pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9250) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9251) "0253 Register VPI: Can't send mbox\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9252) goto mbox_err_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9254) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9255) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9256) "0254 Register VPI: no memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9257) goto mbox_err_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9259) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9261) mbox_err_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9262) lpfc_vport_set_state(vport, FC_VPORT_FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9263) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9264) vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9265) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9266) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9269) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9270) * lpfc_cancel_all_vport_retry_delay_timer - Cancel all vport retry delay timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9271) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9272) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9273) * This routine cancels the retry delay timers to all the vports.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9274) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9275) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9276) lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *phba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9278) struct lpfc_vport **vports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9279) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9280) uint32_t link_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9281) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9283) /* Treat this failure as linkdown for all vports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9284) link_state = phba->link_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9285) lpfc_linkdown(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9286) phba->link_state = link_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9288) vports = lpfc_create_vport_work_array(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9290) if (vports) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9291) for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9292) ndlp = lpfc_findnode_did(vports[i], Fabric_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9293) if (ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9294) lpfc_cancel_retry_delay_tmo(vports[i], ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9295) lpfc_els_flush_cmd(vports[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9297) lpfc_destroy_vport_work_array(phba, vports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9301) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9302) * lpfc_retry_pport_discovery - Start timer to retry FLOGI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9303) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9304) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9305) * This routine abort all pending discovery commands and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9306) * start a timer to retry FLOGI for the physical port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9307) * discovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9308) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9309) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9310) lpfc_retry_pport_discovery(struct lpfc_hba *phba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9312) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9313) struct Scsi_Host *shost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9315) /* Cancel the all vports retry delay retry timers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9316) lpfc_cancel_all_vport_retry_delay_timer(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9318) /* If fabric require FLOGI, then re-instantiate physical login */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9319) ndlp = lpfc_findnode_did(phba->pport, Fabric_DID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9320) if (!ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9321) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9323) shost = lpfc_shost_from_vport(phba->pport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9324) mod_timer(&ndlp->nlp_delayfunc, jiffies + msecs_to_jiffies(1000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9325) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9326) ndlp->nlp_flag |= NLP_DELAY_TMO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9327) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9328) ndlp->nlp_last_elscmd = ELS_CMD_FLOGI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9329) phba->pport->port_state = LPFC_FLOGI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9330) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9333) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9334) * lpfc_fabric_login_reqd - Check if FLOGI required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9335) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9336) * @cmdiocb: pointer to FDISC command iocb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9337) * @rspiocb: pointer to FDISC response iocb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9338) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9339) * This routine checks if a FLOGI is reguired for FDISC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9340) * to succeed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9341) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9342) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9343) lpfc_fabric_login_reqd(struct lpfc_hba *phba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9344) struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9345) struct lpfc_iocbq *rspiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9348) if ((rspiocb->iocb.ulpStatus != IOSTAT_FABRIC_RJT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9349) (rspiocb->iocb.un.ulpWord[4] != RJT_LOGIN_REQUIRED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9350) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9351) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9352) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9355) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9356) * lpfc_cmpl_els_fdisc - Completion function for fdisc iocb command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9357) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9358) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9359) * @rspiocb: pointer to lpfc response iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9360) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9361) * This routine is the completion callback function to a Fabric Discover
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9362) * (FDISC) ELS command. Since all the FDISC ELS commands are issued
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9363) * single threaded, each FDISC completion callback function will reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9364) * the discovery timer for all vports such that the timers will not get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9365) * unnecessary timeout. The function checks the FDISC IOCB status. If error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9366) * detected, the vport will be set to FC_VPORT_FAILED state. Otherwise,the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9367) * vport will set to FC_VPORT_ACTIVE state. It then checks whether the DID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9368) * assigned to the vport has been changed with the completion of the FDISC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9369) * command. If so, both RPI (Remote Port Index) and VPI (Virtual Port Index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9370) * are unregistered from the HBA, and then the lpfc_register_new_vport()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9371) * routine is invoked to register new vport with the HBA. Otherwise, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9372) * lpfc_do_scr_ns_plogi() routine is invoked to issue a PLOGI to the Name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9373) * Server for State Change Request (SCR).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9374) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9375) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9376) lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9377) struct lpfc_iocbq *rspiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9379) struct lpfc_vport *vport = cmdiocb->vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9380) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9381) struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9382) struct lpfc_nodelist *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9383) struct lpfc_nodelist *next_np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9384) IOCB_t *irsp = &rspiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9385) struct lpfc_iocbq *piocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9386) struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9387) struct serv_parm *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9388) uint8_t fabric_param_changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9390) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9391) "0123 FDISC completes. x%x/x%x prevDID: x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9392) irsp->ulpStatus, irsp->un.ulpWord[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9393) vport->fc_prevDID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9394) /* Since all FDISCs are being single threaded, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9395) * must reset the discovery timer for ALL vports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9396) * waiting to send FDISC when one completes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9397) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9398) list_for_each_entry(piocb, &phba->fabric_iocb_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9399) lpfc_set_disctmo(piocb->vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9402) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9403) "FDISC cmpl: status:x%x/x%x prevdid:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9404) irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_prevDID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9406) if (irsp->ulpStatus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9408) if (lpfc_fabric_login_reqd(phba, cmdiocb, rspiocb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9409) lpfc_retry_pport_discovery(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9410) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9413) /* Check for retry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9414) if (lpfc_els_retry(phba, cmdiocb, rspiocb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9415) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9416) /* FDISC failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9417) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9418) "0126 FDISC failed. (x%x/x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9419) irsp->ulpStatus, irsp->un.ulpWord[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9420) goto fdisc_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9422) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9423) vport->fc_flag &= ~FC_VPORT_CVL_RCVD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9424) vport->fc_flag &= ~FC_VPORT_LOGO_RCVD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9425) vport->fc_flag |= FC_FABRIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9426) if (vport->phba->fc_topology == LPFC_TOPOLOGY_LOOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9427) vport->fc_flag |= FC_PUBLIC_LOOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9428) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9430) vport->fc_myDID = irsp->un.ulpWord[4] & Mask_DID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9431) lpfc_vport_set_state(vport, FC_VPORT_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9432) prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9433) if (!prsp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9434) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9435) sp = prsp->virt + sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9436) fabric_param_changed = lpfc_check_clean_addr_bit(vport, sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9437) memcpy(&vport->fabric_portname, &sp->portName,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9438) sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9439) memcpy(&vport->fabric_nodename, &sp->nodeName,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9440) sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9441) if (fabric_param_changed &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9442) !(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9443) /* If our NportID changed, we need to ensure all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9444) * remaining NPORTs get unreg_login'ed so we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9445) * issue unreg_vpi.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9446) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9447) list_for_each_entry_safe(np, next_np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9448) &vport->fc_nodes, nlp_listp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9449) if (!NLP_CHK_NODE_ACT(ndlp) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9450) (np->nlp_state != NLP_STE_NPR_NODE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9451) !(np->nlp_flag & NLP_NPR_ADISC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9452) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9453) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9454) np->nlp_flag &= ~NLP_NPR_ADISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9455) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9456) lpfc_unreg_rpi(vport, np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9458) lpfc_cleanup_pending_mbox(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9460) if (phba->sli_rev == LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9461) lpfc_sli4_unreg_all_rpis(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9463) lpfc_mbx_unreg_vpi(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9464) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9465) vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9466) if (phba->sli_rev == LPFC_SLI_REV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9467) vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9468) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9469) vport->fc_flag |= FC_LOGO_RCVD_DID_CHNG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9470) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9471) } else if ((phba->sli_rev == LPFC_SLI_REV4) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9472) !(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9473) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9474) * Driver needs to re-reg VPI in order for f/w
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9475) * to update the MAC address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9476) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9477) lpfc_register_new_vport(phba, vport, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9478) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9481) if (vport->fc_flag & FC_VPORT_NEEDS_INIT_VPI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9482) lpfc_issue_init_vpi(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9483) else if (vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9484) lpfc_register_new_vport(phba, vport, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9485) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9486) lpfc_do_scr_ns_plogi(phba, vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9487) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9488) fdisc_failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9489) if (vport->fc_vport &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9490) (vport->fc_vport->vport_state != FC_VPORT_NO_FABRIC_RSCS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9491) lpfc_vport_set_state(vport, FC_VPORT_FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9492) /* Cancel discovery timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9493) lpfc_can_disctmo(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9494) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9495) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9496) lpfc_els_free_iocb(phba, cmdiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9499) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9500) * lpfc_issue_els_fdisc - Issue a fdisc iocb command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9501) * @vport: pointer to a virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9502) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9503) * @retry: number of retries to the command IOCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9504) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9505) * This routine prepares and issues a Fabric Discover (FDISC) IOCB to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9506) * a remote node (@ndlp) off a @vport. It uses the lpfc_issue_fabric_iocb()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9507) * routine to issue the IOCB, which makes sure only one outstanding fabric
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9508) * IOCB will be sent off HBA at any given time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9509) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9510) * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9511) * will be incremented by 1 for holding the ndlp and the reference to ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9512) * will be stored into the context1 field of the IOCB for the completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9513) * callback function to the FDISC ELS command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9514) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9515) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9516) * 0 - Successfully issued fdisc iocb command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9517) * 1 - Failed to issue fdisc iocb command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9518) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9519) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9520) lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9521) uint8_t retry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9523) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9524) IOCB_t *icmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9525) struct lpfc_iocbq *elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9526) struct serv_parm *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9527) uint8_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9528) uint16_t cmdsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9529) int did = ndlp->nlp_DID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9530) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9532) vport->port_state = LPFC_FDISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9533) vport->fc_myDID = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9534) cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9535) elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9536) ELS_CMD_FDISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9537) if (!elsiocb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9538) lpfc_vport_set_state(vport, FC_VPORT_FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9539) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9540) "0255 Issue FDISC: no IOCB\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9541) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9544) icmd = &elsiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9545) icmd->un.elsreq64.myID = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9546) icmd->un.elsreq64.fl = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9548) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9549) * SLI3 ports require a different context type value than SLI4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9550) * Catch SLI3 ports here and override the prep.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9551) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9552) if (phba->sli_rev == LPFC_SLI_REV3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9553) icmd->ulpCt_h = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9554) icmd->ulpCt_l = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9557) pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9558) *((uint32_t *) (pcmd)) = ELS_CMD_FDISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9559) pcmd += sizeof(uint32_t); /* CSP Word 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9560) memcpy(pcmd, &vport->phba->pport->fc_sparam, sizeof(struct serv_parm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9561) sp = (struct serv_parm *) pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9562) /* Setup CSPs accordingly for Fabric */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9563) sp->cmn.e_d_tov = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9564) sp->cmn.w2.r_a_tov = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9565) sp->cmn.virtual_fabric_support = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9566) sp->cls1.classValid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9567) sp->cls2.seqDelivery = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9568) sp->cls3.seqDelivery = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9570) pcmd += sizeof(uint32_t); /* CSP Word 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9571) pcmd += sizeof(uint32_t); /* CSP Word 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9572) pcmd += sizeof(uint32_t); /* CSP Word 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9573) pcmd += sizeof(uint32_t); /* Port Name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9574) memcpy(pcmd, &vport->fc_portname, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9575) pcmd += sizeof(uint32_t); /* Node Name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9576) pcmd += sizeof(uint32_t); /* Node Name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9577) memcpy(pcmd, &vport->fc_nodename, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9578) sp->cmn.valid_vendor_ver_level = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9579) memset(sp->un.vendorVersion, 0, sizeof(sp->un.vendorVersion));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9580) lpfc_set_disctmo(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9582) phba->fc_stat.elsXmitFDISC++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9583) elsiocb->iocb_cmpl = lpfc_cmpl_els_fdisc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9585) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9586) "Issue FDISC: did:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9587) did, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9589) rc = lpfc_issue_fabric_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9590) if (rc == IOCB_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9591) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9592) lpfc_vport_set_state(vport, FC_VPORT_FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9593) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9594) "0256 Issue FDISC: Cannot send IOCB\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9595) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9597) lpfc_vport_set_state(vport, FC_VPORT_INITIALIZING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9598) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9601) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9602) * lpfc_cmpl_els_npiv_logo - Completion function with vport logo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9603) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9604) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9605) * @rspiocb: pointer to lpfc response iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9606) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9607) * This routine is the completion callback function to the issuing of a LOGO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9608) * ELS command off a vport. It frees the command IOCB and then decrement the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9609) * reference count held on ndlp for this completion function, indicating that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9610) * the reference to the ndlp is no long needed. Note that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9611) * lpfc_els_free_iocb() routine decrements the ndlp reference held for this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9612) * callback function and an additional explicit ndlp reference decrementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9613) * will trigger the actual release of the ndlp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9614) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9615) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9616) lpfc_cmpl_els_npiv_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9617) struct lpfc_iocbq *rspiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9619) struct lpfc_vport *vport = cmdiocb->vport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9620) IOCB_t *irsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9621) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9622) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9624) ndlp = (struct lpfc_nodelist *)cmdiocb->context1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9625) irsp = &rspiocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9626) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9627) "LOGO npiv cmpl: status:x%x/x%x did:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9628) irsp->ulpStatus, irsp->un.ulpWord[4], irsp->un.rcvels.remoteID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9630) lpfc_els_free_iocb(phba, cmdiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9631) vport->unreg_vpi_cmpl = VPORT_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9633) /* Trigger the release of the ndlp after logo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9634) lpfc_nlp_put(ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9636) /* NPIV LOGO completes to NPort <nlp_DID> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9637) lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9638) "2928 NPIV LOGO completes to NPort x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9639) "Data: x%x x%x x%x x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9640) ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9641) irsp->ulpTimeout, vport->num_disc_nodes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9643) if (irsp->ulpStatus == IOSTAT_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9644) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9645) vport->fc_flag &= ~FC_NDISC_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9646) vport->fc_flag &= ~FC_FABRIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9647) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9648) lpfc_can_disctmo(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9652) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9653) * lpfc_issue_els_npiv_logo - Issue a logo off a vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9654) * @vport: pointer to a virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9655) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9656) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9657) * This routine issues a LOGO ELS command to an @ndlp off a @vport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9658) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9659) * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9660) * will be incremented by 1 for holding the ndlp and the reference to ndlp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9661) * will be stored into the context1 field of the IOCB for the completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9662) * callback function to the LOGO ELS command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9663) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9664) * Return codes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9665) * 0 - Successfully issued logo off the @vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9666) * 1 - Failed to issue logo off the @vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9667) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9668) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9669) lpfc_issue_els_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9671) struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9672) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9673) struct lpfc_iocbq *elsiocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9674) uint8_t *pcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9675) uint16_t cmdsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9677) cmdsize = 2 * sizeof(uint32_t) + sizeof(struct lpfc_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9678) elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, 0, ndlp, ndlp->nlp_DID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9679) ELS_CMD_LOGO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9680) if (!elsiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9681) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9683) pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9684) *((uint32_t *) (pcmd)) = ELS_CMD_LOGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9685) pcmd += sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9687) /* Fill in LOGO payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9688) *((uint32_t *) (pcmd)) = be32_to_cpu(vport->fc_myDID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9689) pcmd += sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9690) memcpy(pcmd, &vport->fc_portname, sizeof(struct lpfc_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9692) lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9693) "Issue LOGO npiv did:x%x flg:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9694) ndlp->nlp_DID, ndlp->nlp_flag, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9696) elsiocb->iocb_cmpl = lpfc_cmpl_els_npiv_logo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9697) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9698) ndlp->nlp_flag |= NLP_LOGO_SND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9699) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9700) if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9701) IOCB_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9702) spin_lock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9703) ndlp->nlp_flag &= ~NLP_LOGO_SND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9704) spin_unlock_irq(shost->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9705) lpfc_els_free_iocb(phba, elsiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9706) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9708) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9711) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9712) * lpfc_fabric_block_timeout - Handler function to the fabric block timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9713) * @t: timer context used to obtain the lpfc hba.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9714) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9715) * This routine is invoked by the fabric iocb block timer after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9716) * timeout. It posts the fabric iocb block timeout event by setting the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9717) * WORKER_FABRIC_BLOCK_TMO bit to work port event bitmap and then invokes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9718) * lpfc_worker_wake_up() routine to wake up the worker thread. It is for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9719) * the worker thread to invoke the lpfc_unblock_fabric_iocbs() on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9720) * posted event WORKER_FABRIC_BLOCK_TMO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9721) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9722) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9723) lpfc_fabric_block_timeout(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9724) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9725) struct lpfc_hba *phba = from_timer(phba, t, fabric_block_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9726) unsigned long iflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9727) uint32_t tmo_posted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9729) spin_lock_irqsave(&phba->pport->work_port_lock, iflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9730) tmo_posted = phba->pport->work_port_events & WORKER_FABRIC_BLOCK_TMO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9731) if (!tmo_posted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9732) phba->pport->work_port_events |= WORKER_FABRIC_BLOCK_TMO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9733) spin_unlock_irqrestore(&phba->pport->work_port_lock, iflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9735) if (!tmo_posted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9736) lpfc_worker_wake_up(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9737) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9740) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9741) * lpfc_resume_fabric_iocbs - Issue a fabric iocb from driver internal list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9742) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9743) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9744) * This routine issues one fabric iocb from the driver internal list to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9745) * the HBA. It first checks whether it's ready to issue one fabric iocb to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9746) * the HBA (whether there is no outstanding fabric iocb). If so, it shall
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9747) * remove one pending fabric iocb from the driver internal list and invokes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9748) * lpfc_sli_issue_iocb() routine to send the fabric iocb to the HBA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9749) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9750) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9751) lpfc_resume_fabric_iocbs(struct lpfc_hba *phba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9752) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9753) struct lpfc_iocbq *iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9754) unsigned long iflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9755) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9756) IOCB_t *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9758) repeat:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9759) iocb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9760) spin_lock_irqsave(&phba->hbalock, iflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9761) /* Post any pending iocb to the SLI layer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9762) if (atomic_read(&phba->fabric_iocb_count) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9763) list_remove_head(&phba->fabric_iocb_list, iocb, typeof(*iocb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9764) list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9765) if (iocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9766) /* Increment fabric iocb count to hold the position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9767) atomic_inc(&phba->fabric_iocb_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9769) spin_unlock_irqrestore(&phba->hbalock, iflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9770) if (iocb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9771) iocb->fabric_iocb_cmpl = iocb->iocb_cmpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9772) iocb->iocb_cmpl = lpfc_cmpl_fabric_iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9773) iocb->iocb_flag |= LPFC_IO_FABRIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9775) lpfc_debugfs_disc_trc(iocb->vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9776) "Fabric sched1: ste:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9777) iocb->vport->port_state, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9779) ret = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, iocb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9781) if (ret == IOCB_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9782) iocb->iocb_cmpl = iocb->fabric_iocb_cmpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9783) iocb->fabric_iocb_cmpl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9784) iocb->iocb_flag &= ~LPFC_IO_FABRIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9785) cmd = &iocb->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9786) cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9787) cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9788) iocb->iocb_cmpl(phba, iocb, iocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9790) atomic_dec(&phba->fabric_iocb_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9791) goto repeat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9795) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9798) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9799) * lpfc_unblock_fabric_iocbs - Unblock issuing fabric iocb command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9800) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9801) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9802) * This routine unblocks the issuing fabric iocb command. The function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9803) * will clear the fabric iocb block bit and then invoke the routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9804) * lpfc_resume_fabric_iocbs() to issue one of the pending fabric iocb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9805) * from the driver internal fabric iocb list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9806) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9807) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9808) lpfc_unblock_fabric_iocbs(struct lpfc_hba *phba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9809) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9810) clear_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9812) lpfc_resume_fabric_iocbs(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9813) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9816) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9817) * lpfc_block_fabric_iocbs - Block issuing fabric iocb command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9818) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9819) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9820) * This routine blocks the issuing fabric iocb for a specified amount of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9821) * time (currently 100 ms). This is done by set the fabric iocb block bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9822) * and set up a timeout timer for 100ms. When the block bit is set, no more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9823) * fabric iocb will be issued out of the HBA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9824) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9825) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9826) lpfc_block_fabric_iocbs(struct lpfc_hba *phba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9827) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9828) int blocked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9830) blocked = test_and_set_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9831) /* Start a timer to unblock fabric iocbs after 100ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9832) if (!blocked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9833) mod_timer(&phba->fabric_block_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9834) jiffies + msecs_to_jiffies(100));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9836) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9839) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9840) * lpfc_cmpl_fabric_iocb - Completion callback function for fabric iocb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9841) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9842) * @cmdiocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9843) * @rspiocb: pointer to lpfc response iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9844) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9845) * This routine is the callback function that is put to the fabric iocb's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9846) * callback function pointer (iocb->iocb_cmpl). The original iocb's callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9847) * function pointer has been stored in iocb->fabric_iocb_cmpl. This callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9848) * function first restores and invokes the original iocb's callback function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9849) * and then invokes the lpfc_resume_fabric_iocbs() routine to issue the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9850) * fabric bound iocb from the driver internal fabric iocb list onto the wire.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9851) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9852) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9853) lpfc_cmpl_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9854) struct lpfc_iocbq *rspiocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9855) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9856) struct ls_rjt stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9858) BUG_ON((cmdiocb->iocb_flag & LPFC_IO_FABRIC) != LPFC_IO_FABRIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9860) switch (rspiocb->iocb.ulpStatus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9861) case IOSTAT_NPORT_RJT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9862) case IOSTAT_FABRIC_RJT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9863) if (rspiocb->iocb.un.ulpWord[4] & RJT_UNAVAIL_TEMP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9864) lpfc_block_fabric_iocbs(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9866) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9868) case IOSTAT_NPORT_BSY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9869) case IOSTAT_FABRIC_BSY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9870) lpfc_block_fabric_iocbs(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9871) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9873) case IOSTAT_LS_RJT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9874) stat.un.lsRjtError =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9875) be32_to_cpu(rspiocb->iocb.un.ulpWord[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9876) if ((stat.un.b.lsRjtRsnCode == LSRJT_UNABLE_TPC) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9877) (stat.un.b.lsRjtRsnCode == LSRJT_LOGICAL_BSY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9878) lpfc_block_fabric_iocbs(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9879) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9882) BUG_ON(atomic_read(&phba->fabric_iocb_count) == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9884) cmdiocb->iocb_cmpl = cmdiocb->fabric_iocb_cmpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9885) cmdiocb->fabric_iocb_cmpl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9886) cmdiocb->iocb_flag &= ~LPFC_IO_FABRIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9887) cmdiocb->iocb_cmpl(phba, cmdiocb, rspiocb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9889) atomic_dec(&phba->fabric_iocb_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9890) if (!test_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9891) /* Post any pending iocbs to HBA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9892) lpfc_resume_fabric_iocbs(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9896) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9897) * lpfc_issue_fabric_iocb - Issue a fabric iocb command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9898) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9899) * @iocb: pointer to lpfc command iocb data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9900) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9901) * This routine is used as the top-level API for issuing a fabric iocb command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9902) * such as FLOGI and FDISC. To accommodate certain switch fabric, this driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9903) * function makes sure that only one fabric bound iocb will be outstanding at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9904) * any given time. As such, this function will first check to see whether there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9905) * is already an outstanding fabric iocb on the wire. If so, it will put the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9906) * newly issued iocb onto the driver internal fabric iocb list, waiting to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9907) * issued later. Otherwise, it will issue the iocb on the wire and update the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9908) * fabric iocb count it indicate that there is one fabric iocb on the wire.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9909) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9910) * Note, this implementation has a potential sending out fabric IOCBs out of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9911) * order. The problem is caused by the construction of the "ready" boolen does
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9912) * not include the condition that the internal fabric IOCB list is empty. As
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9913) * such, it is possible a fabric IOCB issued by this routine might be "jump"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9914) * ahead of the fabric IOCBs in the internal list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9915) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9916) * Return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9917) * IOCB_SUCCESS - either fabric iocb put on the list or issued successfully
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9918) * IOCB_ERROR - failed to issue fabric iocb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9919) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9920) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9921) lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9923) unsigned long iflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9924) int ready;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9925) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9927) BUG_ON(atomic_read(&phba->fabric_iocb_count) > 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9929) spin_lock_irqsave(&phba->hbalock, iflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9930) ready = atomic_read(&phba->fabric_iocb_count) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9931) !test_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9933) if (ready)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9934) /* Increment fabric iocb count to hold the position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9935) atomic_inc(&phba->fabric_iocb_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9936) spin_unlock_irqrestore(&phba->hbalock, iflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9937) if (ready) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9938) iocb->fabric_iocb_cmpl = iocb->iocb_cmpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9939) iocb->iocb_cmpl = lpfc_cmpl_fabric_iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9940) iocb->iocb_flag |= LPFC_IO_FABRIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9942) lpfc_debugfs_disc_trc(iocb->vport, LPFC_DISC_TRC_ELS_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9943) "Fabric sched2: ste:x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9944) iocb->vport->port_state, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9946) ret = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, iocb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9948) if (ret == IOCB_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9949) iocb->iocb_cmpl = iocb->fabric_iocb_cmpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9950) iocb->fabric_iocb_cmpl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9951) iocb->iocb_flag &= ~LPFC_IO_FABRIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9952) atomic_dec(&phba->fabric_iocb_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9954) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9955) spin_lock_irqsave(&phba->hbalock, iflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9956) list_add_tail(&iocb->list, &phba->fabric_iocb_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9957) spin_unlock_irqrestore(&phba->hbalock, iflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9958) ret = IOCB_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9960) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9963) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9964) * lpfc_fabric_abort_vport - Abort a vport's iocbs from driver fabric iocb list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9965) * @vport: pointer to a virtual N_Port data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9966) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9967) * This routine aborts all the IOCBs associated with a @vport from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9968) * driver internal fabric IOCB list. The list contains fabric IOCBs to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9969) * issued to the ELS IOCB ring. This abort function walks the fabric IOCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9970) * list, removes each IOCB associated with the @vport off the list, set the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9971) * status feild to IOSTAT_LOCAL_REJECT, and invokes the callback function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9972) * associated with the IOCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9973) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9974) static void lpfc_fabric_abort_vport(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9975) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9976) LIST_HEAD(completions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9977) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9978) struct lpfc_iocbq *tmp_iocb, *piocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9980) spin_lock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9981) list_for_each_entry_safe(piocb, tmp_iocb, &phba->fabric_iocb_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9982) list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9984) if (piocb->vport != vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9985) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9987) list_move_tail(&piocb->list, &completions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9989) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9991) /* Cancel all the IOCBs from the completions list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9992) lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9993) IOERR_SLI_ABORTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9996) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9997) * lpfc_fabric_abort_nport - Abort a ndlp's iocbs from driver fabric iocb list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9998) * @ndlp: pointer to a node-list data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9999) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10000) * This routine aborts all the IOCBs associated with an @ndlp from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10001) * driver internal fabric IOCB list. The list contains fabric IOCBs to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10002) * issued to the ELS IOCB ring. This abort function walks the fabric IOCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10003) * list, removes each IOCB associated with the @ndlp off the list, set the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10004) * status feild to IOSTAT_LOCAL_REJECT, and invokes the callback function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10005) * associated with the IOCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10006) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10007) void lpfc_fabric_abort_nport(struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10008) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10009) LIST_HEAD(completions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10010) struct lpfc_hba *phba = ndlp->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10011) struct lpfc_iocbq *tmp_iocb, *piocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10012) struct lpfc_sli_ring *pring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10014) pring = lpfc_phba_elsring(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10016) if (unlikely(!pring))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10017) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10019) spin_lock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10020) list_for_each_entry_safe(piocb, tmp_iocb, &phba->fabric_iocb_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10021) list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10022) if ((lpfc_check_sli_ndlp(phba, pring, piocb, ndlp))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10024) list_move_tail(&piocb->list, &completions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10027) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10029) /* Cancel all the IOCBs from the completions list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10030) lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10031) IOERR_SLI_ABORTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10034) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10035) * lpfc_fabric_abort_hba - Abort all iocbs on driver fabric iocb list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10036) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10037) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10038) * This routine aborts all the IOCBs currently on the driver internal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10039) * fabric IOCB list. The list contains fabric IOCBs to be issued to the ELS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10040) * IOCB ring. This function takes the entire IOCB list off the fabric IOCB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10041) * list, removes IOCBs off the list, set the status feild to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10042) * IOSTAT_LOCAL_REJECT, and invokes the callback function associated with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10043) * the IOCB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10044) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10045) void lpfc_fabric_abort_hba(struct lpfc_hba *phba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10047) LIST_HEAD(completions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10049) spin_lock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10050) list_splice_init(&phba->fabric_iocb_list, &completions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10051) spin_unlock_irq(&phba->hbalock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10053) /* Cancel all the IOCBs from the completions list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10054) lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10055) IOERR_SLI_ABORTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10058) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10059) * lpfc_sli4_vport_delete_els_xri_aborted -Remove all ndlp references for vport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10060) * @vport: pointer to lpfc vport data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10061) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10062) * This routine is invoked by the vport cleanup for deletions and the cleanup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10063) * for an ndlp on removal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10064) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10065) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10066) lpfc_sli4_vport_delete_els_xri_aborted(struct lpfc_vport *vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10067) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10068) struct lpfc_hba *phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10069) struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10070) unsigned long iflag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10072) spin_lock_irqsave(&phba->hbalock, iflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10073) spin_lock(&phba->sli4_hba.sgl_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10074) list_for_each_entry_safe(sglq_entry, sglq_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10075) &phba->sli4_hba.lpfc_abts_els_sgl_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10076) if (sglq_entry->ndlp && sglq_entry->ndlp->vport == vport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10077) sglq_entry->ndlp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10079) spin_unlock(&phba->sli4_hba.sgl_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10080) spin_unlock_irqrestore(&phba->hbalock, iflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10081) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10084) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10085) * lpfc_sli4_els_xri_aborted - Slow-path process of els xri abort
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10086) * @phba: pointer to lpfc hba data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10087) * @axri: pointer to the els xri abort wcqe structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10088) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10089) * This routine is invoked by the worker thread to process a SLI4 slow-path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10090) * ELS aborted xri.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10091) **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10092) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10093) lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10094) struct sli4_wcqe_xri_aborted *axri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10095) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10096) uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10097) uint16_t rxid = bf_get(lpfc_wcqe_xa_remote_xid, axri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10098) uint16_t lxri = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10100) struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10101) unsigned long iflag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10102) struct lpfc_nodelist *ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10103) struct lpfc_sli_ring *pring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10105) pring = lpfc_phba_elsring(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10107) spin_lock_irqsave(&phba->hbalock, iflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10108) spin_lock(&phba->sli4_hba.sgl_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10109) list_for_each_entry_safe(sglq_entry, sglq_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10110) &phba->sli4_hba.lpfc_abts_els_sgl_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10111) if (sglq_entry->sli4_xritag == xri) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10112) list_del(&sglq_entry->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10113) ndlp = sglq_entry->ndlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10114) sglq_entry->ndlp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10115) list_add_tail(&sglq_entry->list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10116) &phba->sli4_hba.lpfc_els_sgl_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10117) sglq_entry->state = SGL_FREED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10118) spin_unlock(&phba->sli4_hba.sgl_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10119) spin_unlock_irqrestore(&phba->hbalock, iflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10120) lpfc_set_rrq_active(phba, ndlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10121) sglq_entry->sli4_lxritag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10122) rxid, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10124) /* Check if TXQ queue needs to be serviced */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10125) if (pring && !list_empty(&pring->txq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10126) lpfc_worker_wake_up(phba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10127) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10130) spin_unlock(&phba->sli4_hba.sgl_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10131) lxri = lpfc_sli4_xri_inrange(phba, xri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10132) if (lxri == NO_XRI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10133) spin_unlock_irqrestore(&phba->hbalock, iflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10134) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10136) spin_lock(&phba->sli4_hba.sgl_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10137) sglq_entry = __lpfc_get_active_sglq(phba, lxri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10138) if (!sglq_entry || (sglq_entry->sli4_xritag != xri)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10139) spin_unlock(&phba->sli4_hba.sgl_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10140) spin_unlock_irqrestore(&phba->hbalock, iflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10141) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10143) sglq_entry->state = SGL_XRI_ABORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10144) spin_unlock(&phba->sli4_hba.sgl_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10145) spin_unlock_irqrestore(&phba->hbalock, iflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10146) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10149) /* lpfc_sli_abts_recover_port - Recover a port that failed a BLS_ABORT req.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10150) * @vport: pointer to virtual port object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10151) * @ndlp: nodelist pointer for the impacted node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10152) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10153) * The driver calls this routine in response to an SLI4 XRI ABORT CQE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10154) * or an SLI3 ASYNC_STATUS_CN event from the port. For either event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10155) * the driver is required to send a LOGO to the remote node before it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10156) * attempts to recover its login to the remote node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10157) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10158) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10159) lpfc_sli_abts_recover_port(struct lpfc_vport *vport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10160) struct lpfc_nodelist *ndlp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10162) struct Scsi_Host *shost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10163) struct lpfc_hba *phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10164) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10166) shost = lpfc_shost_from_vport(vport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10167) phba = vport->phba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10168) if (ndlp->nlp_state != NLP_STE_MAPPED_NODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10169) lpfc_printf_log(phba, KERN_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10170) LOG_SLI, "3093 No rport recovery needed. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10171) "rport in state 0x%x\n", ndlp->nlp_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10172) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10174) lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10175) "3094 Start rport recovery on shost id 0x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10176) "fc_id 0x%06x vpi 0x%x rpi 0x%x state 0x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10177) "flags 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10178) shost->host_no, ndlp->nlp_DID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10179) vport->vpi, ndlp->nlp_rpi, ndlp->nlp_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10180) ndlp->nlp_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10181) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10182) * The rport is not responding. Remove the FCP-2 flag to prevent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10183) * an ADISC in the follow-up recovery code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10184) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10185) spin_lock_irqsave(shost->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10186) ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10187) ndlp->nlp_flag |= NLP_ISSUE_LOGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10188) spin_unlock_irqrestore(shost->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10189) lpfc_unreg_rpi(vport, ndlp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10191)