brintos

brintos / linux-shallow public Read only

0
0
Text · 106.9 KiB · 134bc96 Raw
3808 lines · c
1/*******************************************************************2 * This file is part of the Emulex Linux Device Driver for         *3 * Fibre Channel Host Bus Adapters.                                *4 * Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term *5 * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.     *6 * Copyright (C) 2004-2016 Emulex.  All rights reserved.           *7 * EMULEX and SLI are trademarks of Emulex.                        *8 * www.broadcom.com                                                *9 *                                                                 *10 * This program is free software; you can redistribute it and/or   *11 * modify it under the terms of version 2 of the GNU General       *12 * Public License as published by the Free Software Foundation.    *13 * This program is distributed in the hope that it will be useful. *14 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *15 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *16 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *17 * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *18 * TO BE LEGALLY INVALID.  See the GNU General Public License for  *19 * more details, a copy of which can be found in the file COPYING  *20 * included with this package.                                     *21 *******************************************************************/22 23/*24 * Fibre Channel SCSI LAN Device Driver CT support: FC Generic Services FC-GS25 */26 27#include <linux/blkdev.h>28#include <linux/pci.h>29#include <linux/interrupt.h>30#include <linux/slab.h>31#include <linux/utsname.h>32 33#include <scsi/scsi.h>34#include <scsi/scsi_device.h>35#include <scsi/scsi_host.h>36#include <scsi/scsi_transport_fc.h>37#include <scsi/fc/fc_fs.h>38 39#include "lpfc_hw4.h"40#include "lpfc_hw.h"41#include "lpfc_sli.h"42#include "lpfc_sli4.h"43#include "lpfc_nl.h"44#include "lpfc_disc.h"45#include "lpfc.h"46#include "lpfc_scsi.h"47#include "lpfc_logmsg.h"48#include "lpfc_crtn.h"49#include "lpfc_version.h"50#include "lpfc_vport.h"51#include "lpfc_debugfs.h"52 53/* FDMI Port Speed definitions - FC-GS-7 */54#define HBA_PORTSPEED_1GFC		0x00000001	/* 1G FC */55#define HBA_PORTSPEED_2GFC		0x00000002	/* 2G FC */56#define HBA_PORTSPEED_4GFC		0x00000008	/* 4G FC */57#define HBA_PORTSPEED_10GFC		0x00000004	/* 10G FC */58#define HBA_PORTSPEED_8GFC		0x00000010	/* 8G FC */59#define HBA_PORTSPEED_16GFC		0x00000020	/* 16G FC */60#define HBA_PORTSPEED_32GFC		0x00000040	/* 32G FC */61#define HBA_PORTSPEED_20GFC		0x00000080	/* 20G FC */62#define HBA_PORTSPEED_40GFC		0x00000100	/* 40G FC */63#define HBA_PORTSPEED_128GFC		0x00000200	/* 128G FC */64#define HBA_PORTSPEED_64GFC		0x00000400	/* 64G FC */65#define HBA_PORTSPEED_256GFC		0x00000800	/* 256G FC */66#define HBA_PORTSPEED_UNKNOWN		0x00008000	/* Unknown */67#define HBA_PORTSPEED_10GE		0x00010000	/* 10G E */68#define HBA_PORTSPEED_40GE		0x00020000	/* 40G E */69#define HBA_PORTSPEED_100GE		0x00040000	/* 100G E */70#define HBA_PORTSPEED_25GE		0x00080000	/* 25G E */71#define HBA_PORTSPEED_50GE		0x00100000	/* 50G E */72#define HBA_PORTSPEED_400GE		0x00200000	/* 400G E */73 74#define FOURBYTES	475 76 77static char *lpfc_release_version = LPFC_DRIVER_VERSION;78static void79lpfc_cmpl_ct_cmd_vmid(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,80		      struct lpfc_iocbq *rspiocb);81 82static void83lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,84			  struct lpfc_dmabuf *mp, uint32_t size)85{86	if (!mp) {87		lpfc_printf_log(phba, KERN_INFO, LOG_ELS,88				"0146 Ignoring unsolicited CT No HBQ "89				"status = x%x\n",90				get_job_ulpstatus(phba, piocbq));91	}92	lpfc_printf_log(phba, KERN_INFO, LOG_ELS,93			"0145 Ignoring unsolicited CT HBQ Size:%d "94			"status = x%x\n",95			size, get_job_ulpstatus(phba, piocbq));96}97 98static void99lpfc_ct_unsol_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,100		     struct lpfc_dmabuf *mp, uint32_t size)101{102	lpfc_ct_ignore_hbq_buffer(phba, piocbq, mp, size);103}104 105/**106 * lpfc_ct_unsol_cmpl : Completion callback function for unsol ct commands107 * @phba : pointer to lpfc hba data structure.108 * @cmdiocb : pointer to lpfc command iocb data structure.109 * @rspiocb : pointer to lpfc response iocb data structure.110 *111 * This routine is the callback function for issuing unsol ct reject command.112 * The memory allocated in the reject command path is freed up here.113 **/114static void115lpfc_ct_unsol_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,116		   struct lpfc_iocbq *rspiocb)117{118	struct lpfc_nodelist *ndlp;119	struct lpfc_dmabuf *mp, *bmp;120 121	ndlp = cmdiocb->ndlp;122	if (ndlp)123		lpfc_nlp_put(ndlp);124 125	mp = cmdiocb->rsp_dmabuf;126	bmp = cmdiocb->bpl_dmabuf;127	if (mp) {128		lpfc_mbuf_free(phba, mp->virt, mp->phys);129		kfree(mp);130		cmdiocb->rsp_dmabuf = NULL;131	}132 133	if (bmp) {134		lpfc_mbuf_free(phba, bmp->virt, bmp->phys);135		kfree(bmp);136		cmdiocb->bpl_dmabuf = NULL;137	}138 139	lpfc_sli_release_iocbq(phba, cmdiocb);140}141 142/**143 * lpfc_ct_reject_event - Issue reject for unhandled CT MIB commands144 * @ndlp: pointer to a node-list data structure.145 * @ct_req: pointer to the CT request data structure.146 * @ulp_context: context of received UNSOL CT command147 * @ox_id: ox_id of the UNSOL CT command148 *149 * This routine is invoked by the lpfc_ct_handle_mibreq routine for sending150 * a reject response. Reject response is sent for the unhandled commands.151 **/152static void153lpfc_ct_reject_event(struct lpfc_nodelist *ndlp,154		     struct lpfc_sli_ct_request *ct_req,155		     u16 ulp_context, u16 ox_id)156{157	struct lpfc_vport *vport = ndlp->vport;158	struct lpfc_hba *phba = vport->phba;159	struct lpfc_sli_ct_request *ct_rsp;160	struct lpfc_iocbq *cmdiocbq = NULL;161	struct lpfc_dmabuf *bmp = NULL;162	struct lpfc_dmabuf *mp = NULL;163	struct ulp_bde64 *bpl;164	u8 rc = 0;165	u32 tmo;166 167	/* fill in BDEs for command */168	mp = kmalloc(sizeof(*mp), GFP_KERNEL);169	if (!mp) {170		rc = 1;171		goto ct_exit;172	}173 174	mp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &mp->phys);175	if (!mp->virt) {176		rc = 2;177		goto ct_free_mp;178	}179 180	/* Allocate buffer for Buffer ptr list */181	bmp = kmalloc(sizeof(*bmp), GFP_KERNEL);182	if (!bmp) {183		rc = 3;184		goto ct_free_mpvirt;185	}186 187	bmp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &bmp->phys);188	if (!bmp->virt) {189		rc = 4;190		goto ct_free_bmp;191	}192 193	INIT_LIST_HEAD(&mp->list);194	INIT_LIST_HEAD(&bmp->list);195 196	bpl = (struct ulp_bde64 *)bmp->virt;197	memset(bpl, 0, sizeof(struct ulp_bde64));198	bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys));199	bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys));200	bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64;201	bpl->tus.f.bdeSize = (LPFC_CT_PREAMBLE - 4);202	bpl->tus.w = le32_to_cpu(bpl->tus.w);203 204	ct_rsp = (struct lpfc_sli_ct_request *)mp->virt;205	memset(ct_rsp, 0, sizeof(struct lpfc_sli_ct_request));206 207	ct_rsp->RevisionId.bits.Revision = SLI_CT_REVISION;208	ct_rsp->RevisionId.bits.InId = 0;209	ct_rsp->FsType = ct_req->FsType;210	ct_rsp->FsSubType = ct_req->FsSubType;211	ct_rsp->CommandResponse.bits.Size = 0;212	ct_rsp->CommandResponse.bits.CmdRsp =213		cpu_to_be16(SLI_CT_RESPONSE_FS_RJT);214	ct_rsp->ReasonCode = SLI_CT_REQ_NOT_SUPPORTED;215	ct_rsp->Explanation = SLI_CT_NO_ADDITIONAL_EXPL;216 217	cmdiocbq = lpfc_sli_get_iocbq(phba);218	if (!cmdiocbq) {219		rc = 5;220		goto ct_free_bmpvirt;221	}222 223	if (phba->sli_rev == LPFC_SLI_REV4) {224		lpfc_sli_prep_xmit_seq64(phba, cmdiocbq, bmp,225					 phba->sli4_hba.rpi_ids[ndlp->nlp_rpi],226					 ox_id, 1, FC_RCTL_DD_SOL_CTL, 1,227					 CMD_XMIT_SEQUENCE64_WQE);228	} else {229		lpfc_sli_prep_xmit_seq64(phba, cmdiocbq, bmp, 0, ulp_context, 1,230					 FC_RCTL_DD_SOL_CTL, 1,231					 CMD_XMIT_SEQUENCE64_CX);232	}233 234	/* Save for completion so we can release these resources */235	cmdiocbq->rsp_dmabuf = mp;236	cmdiocbq->bpl_dmabuf = bmp;237	cmdiocbq->cmd_cmpl = lpfc_ct_unsol_cmpl;238	tmo = (3 * phba->fc_ratov);239 240	cmdiocbq->retry = 0;241	cmdiocbq->vport = vport;242	cmdiocbq->drvrTimeout = tmo + LPFC_DRVR_TIMEOUT;243 244	cmdiocbq->ndlp = lpfc_nlp_get(ndlp);245	if (!cmdiocbq->ndlp)246		goto ct_no_ndlp;247 248	rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, cmdiocbq, 0);249	if (rc) {250		lpfc_nlp_put(ndlp);251		goto ct_no_ndlp;252	}253	return;254 255ct_no_ndlp:256	rc = 6;257	lpfc_sli_release_iocbq(phba, cmdiocbq);258ct_free_bmpvirt:259	lpfc_mbuf_free(phba, bmp->virt, bmp->phys);260ct_free_bmp:261	kfree(bmp);262ct_free_mpvirt:263	lpfc_mbuf_free(phba, mp->virt, mp->phys);264ct_free_mp:265	kfree(mp);266ct_exit:267	lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,268			 "6440 Unsol CT: Rsp err %d Data: x%lx\n",269			 rc, vport->fc_flag);270}271 272/**273 * lpfc_ct_handle_mibreq - Process an unsolicited CT MIB request data buffer274 * @phba: pointer to lpfc hba data structure.275 * @ctiocbq: pointer to lpfc CT command iocb data structure.276 *277 * This routine is used for processing the IOCB associated with a unsolicited278 * CT MIB request. It first determines whether there is an existing ndlp that279 * matches the DID from the unsolicited IOCB. If not, it will return.280 **/281static void282lpfc_ct_handle_mibreq(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocbq)283{284	struct lpfc_sli_ct_request *ct_req;285	struct lpfc_nodelist *ndlp = NULL;286	struct lpfc_vport *vport = ctiocbq->vport;287	u32 ulp_status = get_job_ulpstatus(phba, ctiocbq);288	u32 ulp_word4 = get_job_word4(phba, ctiocbq);289	u32 did;290	u16 mi_cmd;291 292	did = bf_get(els_rsp64_sid, &ctiocbq->wqe.xmit_els_rsp);293	if (ulp_status) {294		lpfc_vlog_msg(vport, KERN_WARNING, LOG_ELS,295			      "6438 Unsol CT: status:x%x/x%x did : x%x\n",296			      ulp_status, ulp_word4, did);297		return;298	}299 300	/* Ignore traffic received during vport shutdown */301	if (test_bit(FC_UNLOADING, &vport->load_flag))302		return;303 304	ndlp = lpfc_findnode_did(vport, did);305	if (!ndlp) {306		lpfc_vlog_msg(vport, KERN_WARNING, LOG_ELS,307			      "6439 Unsol CT: NDLP Not Found for DID : x%x",308			      did);309		return;310	}311 312	ct_req = (struct lpfc_sli_ct_request *)ctiocbq->cmd_dmabuf->virt;313 314	mi_cmd = be16_to_cpu(ct_req->CommandResponse.bits.CmdRsp);315	lpfc_vlog_msg(vport, KERN_WARNING, LOG_ELS,316		      "6442 MI Cmd : x%x Not Supported\n", mi_cmd);317	lpfc_ct_reject_event(ndlp, ct_req,318			     bf_get(wqe_ctxt_tag,319				    &ctiocbq->wqe.xmit_els_rsp.wqe_com),320			     bf_get(wqe_rcvoxid,321				    &ctiocbq->wqe.xmit_els_rsp.wqe_com));322}323 324/**325 * lpfc_ct_unsol_event - Process an unsolicited event from a ct sli ring326 * @phba: pointer to lpfc hba data structure.327 * @pring: pointer to a SLI ring.328 * @ctiocbq: pointer to lpfc ct iocb data structure.329 *330 * This routine is used to process an unsolicited event received from a SLI331 * (Service Level Interface) ring. The actual processing of the data buffer332 * associated with the unsolicited event is done by invoking appropriate routine333 * after properly set up the iocb buffer from the SLI ring on which the334 * unsolicited event was received.335 **/336void337lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,338		    struct lpfc_iocbq *ctiocbq)339{340	struct lpfc_dmabuf *mp = NULL;341	IOCB_t *icmd = &ctiocbq->iocb;342	int i;343	struct lpfc_iocbq *iocbq;344	struct lpfc_iocbq *iocb;345	dma_addr_t dma_addr;346	uint32_t size;347	struct list_head head;348	struct lpfc_sli_ct_request *ct_req;349	struct lpfc_dmabuf *bdeBuf1 = ctiocbq->cmd_dmabuf;350	struct lpfc_dmabuf *bdeBuf2 = ctiocbq->bpl_dmabuf;351	u32 status, parameter, bde_count = 0;352	struct lpfc_wcqe_complete *wcqe_cmpl = NULL;353 354	ctiocbq->cmd_dmabuf = NULL;355	ctiocbq->rsp_dmabuf = NULL;356	ctiocbq->bpl_dmabuf = NULL;357 358	wcqe_cmpl = &ctiocbq->wcqe_cmpl;359	status = get_job_ulpstatus(phba, ctiocbq);360	parameter = get_job_word4(phba, ctiocbq);361	if (phba->sli_rev == LPFC_SLI_REV4)362		bde_count = wcqe_cmpl->word3;363	else364		bde_count = icmd->ulpBdeCount;365 366	if (unlikely(status == IOSTAT_NEED_BUFFER)) {367		lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ);368	} else if ((status == IOSTAT_LOCAL_REJECT) &&369		   ((parameter & IOERR_PARAM_MASK) ==370		   IOERR_RCV_BUFFER_WAITING)) {371		/* Not enough posted buffers; Try posting more buffers */372		phba->fc_stat.NoRcvBuf++;373		if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED))374			lpfc_sli3_post_buffer(phba, pring, 2);375		return;376	}377 378	/* If there are no BDEs associated379	 * with this IOCB, there is nothing to do.380	 */381	if (bde_count == 0)382		return;383 384	ctiocbq->cmd_dmabuf = bdeBuf1;385	if (bde_count == 2)386		ctiocbq->bpl_dmabuf = bdeBuf2;387 388	ct_req = (struct lpfc_sli_ct_request *)ctiocbq->cmd_dmabuf->virt;389 390	if (ct_req->FsType == SLI_CT_MANAGEMENT_SERVICE &&391	    ct_req->FsSubType == SLI_CT_MIB_Subtypes) {392		lpfc_ct_handle_mibreq(phba, ctiocbq);393	} else {394		if (!lpfc_bsg_ct_unsol_event(phba, pring, ctiocbq))395			return;396	}397 398	if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {399		INIT_LIST_HEAD(&head);400		list_add_tail(&head, &ctiocbq->list);401		list_for_each_entry(iocb, &head, list) {402			if (phba->sli_rev == LPFC_SLI_REV4)403				bde_count = iocb->wcqe_cmpl.word3;404			else405				bde_count = iocb->iocb.ulpBdeCount;406 407			if (!bde_count)408				continue;409			bdeBuf1 = iocb->cmd_dmabuf;410			iocb->cmd_dmabuf = NULL;411			if (phba->sli_rev == LPFC_SLI_REV4)412				size = iocb->wqe.gen_req.bde.tus.f.bdeSize;413			else414				size  = iocb->iocb.un.cont64[0].tus.f.bdeSize;415			lpfc_ct_unsol_buffer(phba, ctiocbq, bdeBuf1, size);416			lpfc_in_buf_free(phba, bdeBuf1);417			if (bde_count == 2) {418				bdeBuf2 = iocb->bpl_dmabuf;419				iocb->bpl_dmabuf = NULL;420				if (phba->sli_rev == LPFC_SLI_REV4)421					size = iocb->unsol_rcv_len;422				else423					size = iocb->iocb.unsli3.rcvsli3.bde2.tus.f.bdeSize;424				lpfc_ct_unsol_buffer(phba, ctiocbq, bdeBuf2,425						     size);426				lpfc_in_buf_free(phba, bdeBuf2);427			}428		}429		list_del(&head);430	} else {431		INIT_LIST_HEAD(&head);432		list_add_tail(&head, &ctiocbq->list);433		list_for_each_entry(iocbq, &head, list) {434			icmd = &iocbq->iocb;435			if (icmd->ulpBdeCount == 0)436				lpfc_ct_unsol_buffer(phba, iocbq, NULL, 0);437			for (i = 0; i < icmd->ulpBdeCount; i++) {438				dma_addr = getPaddr(icmd->un.cont64[i].addrHigh,439						    icmd->un.cont64[i].addrLow);440				mp = lpfc_sli_ringpostbuf_get(phba, pring,441							      dma_addr);442				size = icmd->un.cont64[i].tus.f.bdeSize;443				lpfc_ct_unsol_buffer(phba, iocbq, mp, size);444				lpfc_in_buf_free(phba, mp);445			}446			lpfc_sli3_post_buffer(phba, pring, i);447		}448		list_del(&head);449	}450}451 452/**453 * lpfc_ct_handle_unsol_abort - ct upper level protocol abort handler454 * @phba: Pointer to HBA context object.455 * @dmabuf: pointer to a dmabuf that describes the FC sequence456 *457 * This function serves as the upper level protocol abort handler for CT458 * protocol.459 *460 * Return 1 if abort has been handled, 0 otherwise.461 **/462int463lpfc_ct_handle_unsol_abort(struct lpfc_hba *phba, struct hbq_dmabuf *dmabuf)464{465	int handled;466 467	/* CT upper level goes through BSG */468	handled = lpfc_bsg_ct_unsol_abort(phba, dmabuf);469 470	return handled;471}472 473static void474lpfc_free_ct_rsp(struct lpfc_hba *phba, struct lpfc_dmabuf *mlist)475{476	struct lpfc_dmabuf *mlast, *next_mlast;477 478	list_for_each_entry_safe(mlast, next_mlast, &mlist->list, list) {479		list_del(&mlast->list);480		lpfc_mbuf_free(phba, mlast->virt, mlast->phys);481		kfree(mlast);482	}483	lpfc_mbuf_free(phba, mlist->virt, mlist->phys);484	kfree(mlist);485	return;486}487 488static struct lpfc_dmabuf *489lpfc_alloc_ct_rsp(struct lpfc_hba *phba, __be16 cmdcode, struct ulp_bde64 *bpl,490		  uint32_t size, int *entries)491{492	struct lpfc_dmabuf *mlist = NULL;493	struct lpfc_dmabuf *mp;494	int cnt, i = 0;495 496	/* We get chunks of FCELSSIZE */497	cnt = size > FCELSSIZE ? FCELSSIZE: size;498 499	while (size) {500		/* Allocate buffer for rsp payload */501		mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);502		if (!mp) {503			if (mlist)504				lpfc_free_ct_rsp(phba, mlist);505			return NULL;506		}507 508		INIT_LIST_HEAD(&mp->list);509 510		if (be16_to_cpu(cmdcode) == SLI_CTNS_GID_FT ||511		    be16_to_cpu(cmdcode) == SLI_CTNS_GFF_ID)512			mp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(mp->phys));513		else514			mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys));515 516		if (!mp->virt) {517			kfree(mp);518			if (mlist)519				lpfc_free_ct_rsp(phba, mlist);520			return NULL;521		}522 523		/* Queue it to a linked list */524		if (!mlist)525			mlist = mp;526		else527			list_add_tail(&mp->list, &mlist->list);528 529		bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64I;530		/* build buffer ptr list for IOCB */531		bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys) );532		bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys) );533		bpl->tus.f.bdeSize = (uint16_t) cnt;534		bpl->tus.w = le32_to_cpu(bpl->tus.w);535		bpl++;536 537		i++;538		size -= cnt;539	}540 541	*entries = i;542	return mlist;543}544 545int546lpfc_ct_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocb)547{548	struct lpfc_dmabuf *buf_ptr;549 550	/* IOCBQ job structure gets cleaned during release.  Just release551	 * the dma buffers here.552	 */553	if (ctiocb->cmd_dmabuf) {554		buf_ptr = ctiocb->cmd_dmabuf;555		lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);556		kfree(buf_ptr);557		ctiocb->cmd_dmabuf = NULL;558	}559	if (ctiocb->rsp_dmabuf) {560		lpfc_free_ct_rsp(phba, ctiocb->rsp_dmabuf);561		ctiocb->rsp_dmabuf = NULL;562	}563 564	if (ctiocb->bpl_dmabuf) {565		buf_ptr = ctiocb->bpl_dmabuf;566		lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);567		kfree(buf_ptr);568		ctiocb->bpl_dmabuf = NULL;569	}570	lpfc_sli_release_iocbq(phba, ctiocb);571	return 0;572}573 574/*575 * lpfc_gen_req - Build and issue a GEN_REQUEST command  to the SLI Layer576 * @vport: pointer to a host virtual N_Port data structure.577 * @bmp: Pointer to BPL for SLI command578 * @inp: Pointer to data buffer for response data.579 * @outp: Pointer to data buffer that hold the CT command.580 * @cmpl: completion routine to call when command completes581 * @ndlp: Destination NPort nodelist entry582 *583 * This function as the final part for issuing a CT command.584 */585static int586lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,587	     struct lpfc_dmabuf *inp, struct lpfc_dmabuf *outp,588	     void (*cmpl)(struct lpfc_hba *, struct lpfc_iocbq *,589			  struct lpfc_iocbq *),590	     struct lpfc_nodelist *ndlp, uint32_t event_tag, uint32_t num_entry,591	     uint32_t tmo, uint8_t retry)592{593	struct lpfc_hba  *phba = vport->phba;594	struct lpfc_iocbq *geniocb;595	int rc;596	u16 ulp_context;597 598	/* Allocate buffer for  command iocb */599	geniocb = lpfc_sli_get_iocbq(phba);600 601	if (geniocb == NULL)602		return 1;603 604	/* Update the num_entry bde count */605	geniocb->num_bdes = num_entry;606 607	geniocb->bpl_dmabuf = bmp;608 609	/* Save for completion so we can release these resources */610	geniocb->cmd_dmabuf = inp;611	geniocb->rsp_dmabuf = outp;612 613	geniocb->event_tag = event_tag;614 615	if (!tmo) {616		 /* FC spec states we need 3 * ratov for CT requests */617		tmo = (3 * phba->fc_ratov);618	}619 620	if (phba->sli_rev == LPFC_SLI_REV4)621		ulp_context = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];622	else623		ulp_context = ndlp->nlp_rpi;624 625	lpfc_sli_prep_gen_req(phba, geniocb, bmp, ulp_context, num_entry, tmo);626 627	/* Issue GEN REQ IOCB for NPORT <did> */628	lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,629			 "0119 Issue GEN REQ IOCB to NPORT x%x "630			 "Data: x%x x%x\n",631			 ndlp->nlp_DID, geniocb->iotag,632			 vport->port_state);633	geniocb->cmd_cmpl = cmpl;634	geniocb->drvrTimeout = tmo + LPFC_DRVR_TIMEOUT;635	geniocb->vport = vport;636	geniocb->retry = retry;637	geniocb->ndlp = lpfc_nlp_get(ndlp);638	if (!geniocb->ndlp)639		goto out;640 641	rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, geniocb, 0);642	if (rc == IOCB_ERROR) {643		lpfc_nlp_put(ndlp);644		goto out;645	}646 647	return 0;648out:649	lpfc_sli_release_iocbq(phba, geniocb);650	return 1;651}652 653/*654 * lpfc_ct_cmd - Build and issue a CT command655 * @vport: pointer to a host virtual N_Port data structure.656 * @inmp: Pointer to data buffer for response data.657 * @bmp: Pointer to BPL for SLI command658 * @ndlp: Destination NPort nodelist entry659 * @cmpl: completion routine to call when command completes660 *661 * This function is called for issuing a CT command.662 */663static int664lpfc_ct_cmd(struct lpfc_vport *vport, struct lpfc_dmabuf *inmp,665	    struct lpfc_dmabuf *bmp, struct lpfc_nodelist *ndlp,666	    void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,667			  struct lpfc_iocbq *),668	    uint32_t rsp_size, uint8_t retry)669{670	struct lpfc_hba  *phba = vport->phba;671	struct ulp_bde64 *bpl = (struct ulp_bde64 *) bmp->virt;672	struct lpfc_dmabuf *outmp;673	int cnt = 0, status;674	__be16 cmdcode = ((struct lpfc_sli_ct_request *)inmp->virt)->675		CommandResponse.bits.CmdRsp;676 677	bpl++;			/* Skip past ct request */678 679	/* Put buffer(s) for ct rsp in bpl */680	outmp = lpfc_alloc_ct_rsp(phba, cmdcode, bpl, rsp_size, &cnt);681	if (!outmp)682		return -ENOMEM;683	/*684	 * Form the CT IOCB.  The total number of BDEs in this IOCB685	 * is the single command plus response count from686	 * lpfc_alloc_ct_rsp.687	 */688	cnt += 1;689	status = lpfc_gen_req(vport, bmp, inmp, outmp, cmpl, ndlp,690			phba->fc_eventTag, cnt, 0, retry);691	if (status) {692		lpfc_free_ct_rsp(phba, outmp);693		return -ENOMEM;694	}695	return 0;696}697 698struct lpfc_vport *699lpfc_find_vport_by_did(struct lpfc_hba *phba, uint32_t did) {700	struct lpfc_vport *vport_curr;701	unsigned long flags;702 703	spin_lock_irqsave(&phba->port_list_lock, flags);704	list_for_each_entry(vport_curr, &phba->port_list, listentry) {705		if ((vport_curr->fc_myDID) && (vport_curr->fc_myDID == did)) {706			spin_unlock_irqrestore(&phba->port_list_lock, flags);707			return vport_curr;708		}709	}710	spin_unlock_irqrestore(&phba->port_list_lock, flags);711	return NULL;712}713 714static void715lpfc_prep_node_fc4type(struct lpfc_vport *vport, uint32_t Did, uint8_t fc4_type)716{717	struct lpfc_nodelist *ndlp;718 719	if ((vport->port_type != LPFC_NPIV_PORT) ||720	    !(vport->ct_flags & FC_CT_RFF_ID) || !vport->cfg_restrict_login) {721 722		ndlp = lpfc_setup_disc_node(vport, Did);723 724		if (ndlp) {725			lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,726				"Parse GID_FTrsp: did:x%x flg:x%lx x%x",727				Did, ndlp->nlp_flag, vport->fc_flag);728 729			/* By default, the driver expects to support FCP FC4 */730			if (fc4_type == FC_TYPE_FCP)731				ndlp->nlp_fc4_type |= NLP_FC4_FCP;732 733			if (fc4_type == FC_TYPE_NVME)734				ndlp->nlp_fc4_type |= NLP_FC4_NVME;735 736			lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,737					 "0238 Process x%06x NameServer Rsp "738					 "Data: x%x x%x x%x x%lx x%x\n", Did,739					 ndlp->nlp_flag, ndlp->nlp_fc4_type,740					 ndlp->nlp_state, vport->fc_flag,741					 vport->fc_rscn_id_cnt);742 743			/* if ndlp needs to be discovered and prior744			 * state of ndlp hit devloss, change state to745			 * allow rediscovery.746			 */747			if (ndlp->nlp_flag & NLP_NPR_2B_DISC &&748			    ndlp->nlp_state == NLP_STE_UNUSED_NODE) {749				lpfc_nlp_set_state(vport, ndlp,750						   NLP_STE_NPR_NODE);751			}752		} else {753			lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,754				"Skip1 GID_FTrsp: did:x%x flg:x%lx cnt:%d",755				Did, vport->fc_flag, vport->fc_rscn_id_cnt);756 757			lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,758					 "0239 Skip x%06x NameServer Rsp "759					 "Data: x%lx x%x x%px\n",760					 Did, vport->fc_flag,761					 vport->fc_rscn_id_cnt, ndlp);762		}763	} else {764		if (!test_bit(FC_RSCN_MODE, &vport->fc_flag) ||765		    lpfc_rscn_payload_check(vport, Did)) {766			lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,767				"Query GID_FTrsp: did:x%x flg:x%lx cnt:%d",768				Did, vport->fc_flag, vport->fc_rscn_id_cnt);769 770			/*771			 * This NPortID was previously a FCP/NVMe target,772			 * Don't even bother to send GFF_ID.773			 */774			ndlp = lpfc_findnode_did(vport, Did);775			if (ndlp &&776			    (ndlp->nlp_type &777			    (NLP_FCP_TARGET | NLP_NVME_TARGET))) {778				if (fc4_type == FC_TYPE_FCP)779					ndlp->nlp_fc4_type |= NLP_FC4_FCP;780				if (fc4_type == FC_TYPE_NVME)781					ndlp->nlp_fc4_type |= NLP_FC4_NVME;782				lpfc_setup_disc_node(vport, Did);783			} else if (lpfc_ns_cmd(vport, SLI_CTNS_GFF_ID,784				   0, Did) == 0)785				vport->num_disc_nodes++;786			else787				lpfc_setup_disc_node(vport, Did);788		} else {789			lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,790				"Skip2 GID_FTrsp: did:x%x flg:x%lx cnt:%d",791				Did, vport->fc_flag, vport->fc_rscn_id_cnt);792 793			lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,794					 "0245 Skip x%06x NameServer Rsp "795					 "Data: x%lx x%x\n", Did,796					 vport->fc_flag,797					 vport->fc_rscn_id_cnt);798		}799	}800}801 802static void803lpfc_ns_rsp_audit_did(struct lpfc_vport *vport, uint32_t Did, uint8_t fc4_type)804{805	struct lpfc_hba *phba = vport->phba;806	struct lpfc_nodelist *ndlp = NULL;807	char *str;808 809	if (phba->cfg_ns_query == LPFC_NS_QUERY_GID_FT)810		str = "GID_FT";811	else812		str = "GID_PT";813	lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,814			 "6430 Process %s rsp for %08x type %x %s %s\n",815			 str, Did, fc4_type,816			 (fc4_type == FC_TYPE_FCP) ?  "FCP" : " ",817			 (fc4_type == FC_TYPE_NVME) ?  "NVME" : " ");818	/*819	 * To conserve rpi's, filter out addresses for other820	 * vports on the same physical HBAs.821	 */822	if (Did != vport->fc_myDID &&823	    (!lpfc_find_vport_by_did(phba, Did) ||824	     vport->cfg_peer_port_login)) {825		if (!phba->nvmet_support) {826			/* FCPI/NVMEI path. Process Did */827			lpfc_prep_node_fc4type(vport, Did, fc4_type);828			return;829		}830		/* NVMET path.  NVMET only cares about NVMEI nodes. */831		list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {832			if (ndlp->nlp_type != NLP_NVME_INITIATOR ||833			    ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)834				continue;835			spin_lock_irq(&ndlp->lock);836			if (ndlp->nlp_DID == Did)837				ndlp->nlp_flag &= ~NLP_NVMET_RECOV;838			else839				ndlp->nlp_flag |= NLP_NVMET_RECOV;840			spin_unlock_irq(&ndlp->lock);841		}842	}843}844 845static int846lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint8_t fc4_type,847	    uint32_t Size)848{849	struct lpfc_sli_ct_request *Response =850		(struct lpfc_sli_ct_request *) mp->virt;851	struct lpfc_dmabuf *mlast, *next_mp;852	uint32_t *ctptr = (uint32_t *) & Response->un.gid.PortType;853	uint32_t Did, CTentry;854	int Cnt;855	struct list_head head;856	struct lpfc_nodelist *ndlp = NULL;857 858	lpfc_set_disctmo(vport);859	vport->num_disc_nodes = 0;860	vport->fc_ns_retry = 0;861 862 863	list_add_tail(&head, &mp->list);864	list_for_each_entry_safe(mp, next_mp, &head, list) {865		mlast = mp;866 867		Cnt = Size  > FCELSSIZE ? FCELSSIZE : Size;868 869		Size -= Cnt;870 871		if (!ctptr) {872			ctptr = (uint32_t *) mlast->virt;873		} else874			Cnt -= 16;	/* subtract length of CT header */875 876		/* Loop through entire NameServer list of DIDs */877		while (Cnt >= sizeof(uint32_t)) {878			/* Get next DID from NameServer List */879			CTentry = *ctptr++;880			Did = ((be32_to_cpu(CTentry)) & Mask_DID);881			lpfc_ns_rsp_audit_did(vport, Did, fc4_type);882			if (CTentry & (cpu_to_be32(SLI_CT_LAST_ENTRY)))883				goto nsout1;884 885			Cnt -= sizeof(uint32_t);886		}887		ctptr = NULL;888 889	}890 891	/* All GID_FT entries processed.  If the driver is running in892	 * in target mode, put impacted nodes into recovery and drop893	 * the RPI to flush outstanding IO.894	 */895	if (vport->phba->nvmet_support) {896		list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {897			if (!(ndlp->nlp_flag & NLP_NVMET_RECOV))898				continue;899			lpfc_disc_state_machine(vport, ndlp, NULL,900						NLP_EVT_DEVICE_RECOVERY);901			spin_lock_irq(&ndlp->lock);902			ndlp->nlp_flag &= ~NLP_NVMET_RECOV;903			spin_unlock_irq(&ndlp->lock);904		}905	}906 907nsout1:908	list_del(&head);909	return 0;910}911 912static void913lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,914			struct lpfc_iocbq *rspiocb)915{916	struct lpfc_vport *vport = cmdiocb->vport;917	struct lpfc_dmabuf *outp;918	struct lpfc_dmabuf *inp;919	struct lpfc_sli_ct_request *CTrsp;920	struct lpfc_sli_ct_request *CTreq;921	struct lpfc_nodelist *ndlp;922	u32 ulp_status = get_job_ulpstatus(phba, rspiocb);923	u32 ulp_word4 = get_job_word4(phba, rspiocb);924	int rc, type;925 926	/* First save ndlp, before we overwrite it */927	ndlp = cmdiocb->ndlp;928 929	/* we pass cmdiocb to state machine which needs rspiocb as well */930	cmdiocb->rsp_iocb = rspiocb;931	inp = cmdiocb->cmd_dmabuf;932	outp = cmdiocb->rsp_dmabuf;933 934	lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,935		 "GID_FT cmpl:     status:x%x/x%x rtry:%d",936		ulp_status, ulp_word4, vport->fc_ns_retry);937 938	/* Ignore response if link flipped after this request was made */939	if (cmdiocb->event_tag != phba->fc_eventTag) {940		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,941				 "9043 Event tag mismatch. Ignoring NS rsp\n");942		goto out;943	}944 945	/* Skip processing response on pport if unloading */946	if (vport == phba->pport && test_bit(FC_UNLOADING, &vport->load_flag)) {947		if (test_bit(FC_RSCN_MODE, &vport->fc_flag))948			lpfc_els_flush_rscn(vport);949		goto out;950	}951 952	if (lpfc_els_chk_latt(vport)) {953		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,954				 "0216 Link event during NS query\n");955		if (test_bit(FC_RSCN_MODE, &vport->fc_flag))956			lpfc_els_flush_rscn(vport);957		lpfc_vport_set_state(vport, FC_VPORT_FAILED);958		goto out;959	}960	if (lpfc_error_lost_link(vport, ulp_status, ulp_word4)) {961		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,962				 "0226 NS query failed due to link event: "963				 "ulp_status x%x ulp_word4 x%x fc_flag x%lx "964				 "port_state x%x gidft_inp x%x\n",965				 ulp_status, ulp_word4, vport->fc_flag,966				 vport->port_state, vport->gidft_inp);967		if (test_bit(FC_RSCN_MODE, &vport->fc_flag))968			lpfc_els_flush_rscn(vport);969		if (vport->gidft_inp)970			vport->gidft_inp--;971		goto out;972	}973 974	if (test_and_clear_bit(FC_RSCN_DEFERRED, &vport->fc_flag)) {975		/* This is a GID_FT completing so the gidft_inp counter was976		 * incremented before the GID_FT was issued to the wire.977		 */978		if (vport->gidft_inp)979			vport->gidft_inp--;980 981		/*982		 * Skip processing the NS response983		 * Re-issue the NS cmd984		 */985		lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,986				 "0151 Process Deferred RSCN Data: x%lx x%x\n",987				 vport->fc_flag, vport->fc_rscn_id_cnt);988		lpfc_els_handle_rscn(vport);989 990		goto out;991	}992 993	if (ulp_status) {994		/* Check for retry */995		if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {996			if (ulp_status != IOSTAT_LOCAL_REJECT ||997			    (ulp_word4 & IOERR_PARAM_MASK) !=998			    IOERR_NO_RESOURCES)999				vport->fc_ns_retry++;1000 1001			type = lpfc_get_gidft_type(vport, cmdiocb);1002			if (type == 0)1003				goto out;1004 1005			/* CT command is being retried */1006			rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT,1007					 vport->fc_ns_retry, type);1008			if (rc == 0)1009				goto out;1010			else { /* Unable to send NS cmd */1011				if (vport->gidft_inp)1012					vport->gidft_inp--;1013			}1014		}1015		if (test_bit(FC_RSCN_MODE, &vport->fc_flag))1016			lpfc_els_flush_rscn(vport);1017		lpfc_vport_set_state(vport, FC_VPORT_FAILED);1018		lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,1019				 "0257 GID_FT Query error: 0x%x 0x%x\n",1020				 ulp_status, vport->fc_ns_retry);1021	} else {1022		/* Good status, continue checking */1023		CTreq = (struct lpfc_sli_ct_request *) inp->virt;1024		CTrsp = (struct lpfc_sli_ct_request *) outp->virt;1025		if (CTrsp->CommandResponse.bits.CmdRsp ==1026		    cpu_to_be16(SLI_CT_RESPONSE_FS_ACC)) {1027			lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,1028					 "0208 NameServer Rsp Data: x%lx x%x "1029					 "x%x x%x sz x%x\n",1030					 vport->fc_flag,1031					 CTreq->un.gid.Fc4Type,1032					 vport->num_disc_nodes,1033					 vport->gidft_inp,1034					 get_job_data_placed(phba, rspiocb));1035 1036			lpfc_ns_rsp(vport,1037				    outp,1038				    CTreq->un.gid.Fc4Type,1039				    get_job_data_placed(phba, rspiocb));1040		} else if (be16_to_cpu(CTrsp->CommandResponse.bits.CmdRsp) ==1041			   SLI_CT_RESPONSE_FS_RJT) {1042			/* NameServer Rsp Error */1043			if ((CTrsp->ReasonCode == SLI_CT_UNABLE_TO_PERFORM_REQ)1044			    && (CTrsp->Explanation == SLI_CT_NO_FC4_TYPES)) {1045				lpfc_printf_vlog(vport, KERN_INFO,1046					LOG_DISCOVERY,1047					"0269 No NameServer Entries "1048					"Data: x%x x%x x%x x%lx\n",1049					be16_to_cpu(CTrsp->CommandResponse.bits.CmdRsp),1050					(uint32_t) CTrsp->ReasonCode,1051					(uint32_t) CTrsp->Explanation,1052					vport->fc_flag);1053 1054				lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,1055				"GID_FT no entry  cmd:x%x rsn:x%x exp:x%x",1056				be16_to_cpu(CTrsp->CommandResponse.bits.CmdRsp),1057				(uint32_t) CTrsp->ReasonCode,1058				(uint32_t) CTrsp->Explanation);1059			} else {1060				lpfc_printf_vlog(vport, KERN_INFO,1061					LOG_DISCOVERY,1062					"0240 NameServer Rsp Error "1063					"Data: x%x x%x x%x x%lx\n",1064					be16_to_cpu(CTrsp->CommandResponse.bits.CmdRsp),1065					(uint32_t) CTrsp->ReasonCode,1066					(uint32_t) CTrsp->Explanation,1067					vport->fc_flag);1068 1069				lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,1070				"GID_FT rsp err1  cmd:x%x rsn:x%x exp:x%x",1071				be16_to_cpu(CTrsp->CommandResponse.bits.CmdRsp),1072				(uint32_t) CTrsp->ReasonCode,1073				(uint32_t) CTrsp->Explanation);1074			}1075 1076 1077		} else {1078			/* NameServer Rsp Error */1079			lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,1080					"0241 NameServer Rsp Error "1081					"Data: x%x x%x x%x x%lx\n",1082					be16_to_cpu(CTrsp->CommandResponse.bits.CmdRsp),1083					(uint32_t) CTrsp->ReasonCode,1084					(uint32_t) CTrsp->Explanation,1085					vport->fc_flag);1086 1087			lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,1088				"GID_FT rsp err2  cmd:x%x rsn:x%x exp:x%x",1089				be16_to_cpu(CTrsp->CommandResponse.bits.CmdRsp),1090				(uint32_t) CTrsp->ReasonCode,1091				(uint32_t) CTrsp->Explanation);1092		}1093		if (vport->gidft_inp)1094			vport->gidft_inp--;1095	}1096 1097	lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,1098			 "4216 GID_FT cmpl inp %d disc %d\n",1099			 vport->gidft_inp, vport->num_disc_nodes);1100 1101	/* Link up / RSCN discovery */1102	if ((vport->num_disc_nodes == 0) &&1103	    (vport->gidft_inp == 0)) {1104		/*1105		 * The driver has cycled through all Nports in the RSCN payload.1106		 * Complete the handling by cleaning up and marking the1107		 * current driver state.1108		 */1109		if (vport->port_state >= LPFC_DISC_AUTH) {1110			if (test_bit(FC_RSCN_MODE, &vport->fc_flag)) {1111				lpfc_els_flush_rscn(vport);1112				/* RSCN still */1113				set_bit(FC_RSCN_MODE, &vport->fc_flag);1114			} else {1115				lpfc_els_flush_rscn(vport);1116			}1117		}1118 1119		lpfc_disc_start(vport);1120	}1121out:1122	lpfc_ct_free_iocb(phba, cmdiocb);1123	lpfc_nlp_put(ndlp);1124	return;1125}1126 1127static void1128lpfc_cmpl_ct_cmd_gid_pt(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,1129			struct lpfc_iocbq *rspiocb)1130{1131	struct lpfc_vport *vport = cmdiocb->vport;1132	struct lpfc_dmabuf *outp;1133	struct lpfc_dmabuf *inp;1134	struct lpfc_sli_ct_request *CTrsp;1135	struct lpfc_sli_ct_request *CTreq;1136	struct lpfc_nodelist *ndlp;1137	u32 ulp_status = get_job_ulpstatus(phba, rspiocb);1138	u32 ulp_word4 = get_job_word4(phba, rspiocb);1139	int rc;1140 1141	/* First save ndlp, before we overwrite it */1142	ndlp = cmdiocb->ndlp;1143 1144	/* we pass cmdiocb to state machine which needs rspiocb as well */1145	cmdiocb->rsp_iocb = rspiocb;1146	inp = cmdiocb->cmd_dmabuf;1147	outp = cmdiocb->rsp_dmabuf;1148 1149	lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,1150			      "GID_PT cmpl:     status:x%x/x%x rtry:%d",1151			      ulp_status, ulp_word4,1152			      vport->fc_ns_retry);1153 1154	/* Ignore response if link flipped after this request was made */1155	if (cmdiocb->event_tag != phba->fc_eventTag) {1156		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,1157				 "9044 Event tag mismatch. Ignoring NS rsp\n");1158		goto out;1159	}1160 1161	/* Skip processing response on pport if unloading */1162	if (vport == phba->pport && test_bit(FC_UNLOADING, &vport->load_flag)) {1163		if (test_bit(FC_RSCN_MODE, &vport->fc_flag))1164			lpfc_els_flush_rscn(vport);1165		goto out;1166	}1167 1168	if (lpfc_els_chk_latt(vport)) {1169		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,1170				 "4108 Link event during NS query\n");1171		if (test_bit(FC_RSCN_MODE, &vport->fc_flag))1172			lpfc_els_flush_rscn(vport);1173		lpfc_vport_set_state(vport, FC_VPORT_FAILED);1174		goto out;1175	}1176	if (lpfc_error_lost_link(vport, ulp_status, ulp_word4)) {1177		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,1178				 "4166 NS query failed due to link event: "1179				 "ulp_status x%x ulp_word4 x%x fc_flag x%lx "1180				 "port_state x%x gidft_inp x%x\n",1181				 ulp_status, ulp_word4, vport->fc_flag,1182				 vport->port_state, vport->gidft_inp);1183		if (test_bit(FC_RSCN_MODE, &vport->fc_flag))1184			lpfc_els_flush_rscn(vport);1185		if (vport->gidft_inp)1186			vport->gidft_inp--;1187		goto out;1188	}1189 1190	if (test_and_clear_bit(FC_RSCN_DEFERRED, &vport->fc_flag)) {1191		/* This is a GID_PT completing so the gidft_inp counter was1192		 * incremented before the GID_PT was issued to the wire.1193		 */1194		if (vport->gidft_inp)1195			vport->gidft_inp--;1196 1197		/*1198		 * Skip processing the NS response1199		 * Re-issue the NS cmd1200		 */1201		lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,1202				 "4167 Process Deferred RSCN Data: x%lx x%x\n",1203				 vport->fc_flag, vport->fc_rscn_id_cnt);1204		lpfc_els_handle_rscn(vport);1205 1206		goto out;1207	}1208 1209	if (ulp_status) {1210		/* Check for retry */1211		if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {1212			if (ulp_status != IOSTAT_LOCAL_REJECT ||1213			    (ulp_word4 & IOERR_PARAM_MASK) !=1214			    IOERR_NO_RESOURCES)1215				vport->fc_ns_retry++;1216 1217			/* CT command is being retried */1218			rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_PT,1219					 vport->fc_ns_retry, GID_PT_N_PORT);1220			if (rc == 0)1221				goto out;1222			else { /* Unable to send NS cmd */1223				if (vport->gidft_inp)1224					vport->gidft_inp--;1225			}1226		}1227		if (test_bit(FC_RSCN_MODE, &vport->fc_flag))1228			lpfc_els_flush_rscn(vport);1229		lpfc_vport_set_state(vport, FC_VPORT_FAILED);1230		lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,1231				 "4103 GID_FT Query error: 0x%x 0x%x\n",1232				 ulp_status, vport->fc_ns_retry);1233	} else {1234		/* Good status, continue checking */1235		CTreq = (struct lpfc_sli_ct_request *)inp->virt;1236		CTrsp = (struct lpfc_sli_ct_request *)outp->virt;1237		if (be16_to_cpu(CTrsp->CommandResponse.bits.CmdRsp) ==1238		    SLI_CT_RESPONSE_FS_ACC) {1239			lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,1240					 "4105 NameServer Rsp Data: x%lx x%x "1241					 "x%x x%x sz x%x\n",1242					 vport->fc_flag,1243					 CTreq->un.gid.Fc4Type,1244					 vport->num_disc_nodes,1245					 vport->gidft_inp,1246					 get_job_data_placed(phba, rspiocb));1247 1248			lpfc_ns_rsp(vport,1249				    outp,1250				    CTreq->un.gid.Fc4Type,1251				    get_job_data_placed(phba, rspiocb));1252		} else if (be16_to_cpu(CTrsp->CommandResponse.bits.CmdRsp) ==1253			   SLI_CT_RESPONSE_FS_RJT) {1254			/* NameServer Rsp Error */1255			if ((CTrsp->ReasonCode == SLI_CT_UNABLE_TO_PERFORM_REQ)1256			    && (CTrsp->Explanation == SLI_CT_NO_FC4_TYPES)) {1257				lpfc_printf_vlog(1258					vport, KERN_INFO, LOG_DISCOVERY,1259					"4106 No NameServer Entries "1260					"Data: x%x x%x x%x x%lx\n",1261					be16_to_cpu(CTrsp->CommandResponse.bits.CmdRsp),1262					(uint32_t)CTrsp->ReasonCode,1263					(uint32_t)CTrsp->Explanation,1264					vport->fc_flag);1265 1266				lpfc_debugfs_disc_trc(1267				vport, LPFC_DISC_TRC_CT,1268				"GID_PT no entry  cmd:x%x rsn:x%x exp:x%x",1269				be16_to_cpu(CTrsp->CommandResponse.bits.CmdRsp),1270				(uint32_t)CTrsp->ReasonCode,1271				(uint32_t)CTrsp->Explanation);1272			} else {1273				lpfc_printf_vlog(1274					vport, KERN_INFO, LOG_DISCOVERY,1275					"4107 NameServer Rsp Error "1276					"Data: x%x x%x x%x x%lx\n",1277					be16_to_cpu(CTrsp->CommandResponse.bits.CmdRsp),1278					(uint32_t)CTrsp->ReasonCode,1279					(uint32_t)CTrsp->Explanation,1280					vport->fc_flag);1281 1282				lpfc_debugfs_disc_trc(1283				vport, LPFC_DISC_TRC_CT,1284				"GID_PT rsp err1  cmd:x%x rsn:x%x exp:x%x",1285				be16_to_cpu(CTrsp->CommandResponse.bits.CmdRsp),1286				(uint32_t)CTrsp->ReasonCode,1287				(uint32_t)CTrsp->Explanation);1288			}1289		} else {1290			/* NameServer Rsp Error */1291			lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,1292					 "4109 NameServer Rsp Error "1293					 "Data: x%x x%x x%x x%lx\n",1294					 be16_to_cpu(CTrsp->CommandResponse.bits.CmdRsp),1295					 (uint32_t)CTrsp->ReasonCode,1296					 (uint32_t)CTrsp->Explanation,1297					 vport->fc_flag);1298 1299			lpfc_debugfs_disc_trc(1300				vport, LPFC_DISC_TRC_CT,1301				"GID_PT rsp err2  cmd:x%x rsn:x%x exp:x%x",1302				be16_to_cpu(CTrsp->CommandResponse.bits.CmdRsp),1303				(uint32_t)CTrsp->ReasonCode,1304				(uint32_t)CTrsp->Explanation);1305		}1306		if (vport->gidft_inp)1307			vport->gidft_inp--;1308	}1309 1310	lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,1311			 "6450 GID_PT cmpl inp %d disc %d\n",1312			 vport->gidft_inp, vport->num_disc_nodes);1313 1314	/* Link up / RSCN discovery */1315	if ((vport->num_disc_nodes == 0) &&1316	    (vport->gidft_inp == 0)) {1317		/*1318		 * The driver has cycled through all Nports in the RSCN payload.1319		 * Complete the handling by cleaning up and marking the1320		 * current driver state.1321		 */1322		if (vport->port_state >= LPFC_DISC_AUTH) {1323			if (test_bit(FC_RSCN_MODE, &vport->fc_flag)) {1324				lpfc_els_flush_rscn(vport);1325				/* RSCN still */1326				set_bit(FC_RSCN_MODE, &vport->fc_flag);1327			} else {1328				lpfc_els_flush_rscn(vport);1329			}1330		}1331 1332		lpfc_disc_start(vport);1333	}1334out:1335	lpfc_ct_free_iocb(phba, cmdiocb);1336	lpfc_nlp_put(ndlp);1337}1338 1339static void1340lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,1341			struct lpfc_iocbq *rspiocb)1342{1343	struct lpfc_vport *vport = cmdiocb->vport;1344	struct lpfc_dmabuf *inp = cmdiocb->cmd_dmabuf;1345	struct lpfc_dmabuf *outp = cmdiocb->rsp_dmabuf;1346	struct lpfc_sli_ct_request *CTrsp;1347	int did, rc, retry;1348	uint8_t fbits;1349	struct lpfc_nodelist *ndlp = NULL, *free_ndlp = NULL;1350	u32 ulp_status = get_job_ulpstatus(phba, rspiocb);1351	u32 ulp_word4 = get_job_word4(phba, rspiocb);1352 1353	did = ((struct lpfc_sli_ct_request *) inp->virt)->un.gff.PortId;1354	did = be32_to_cpu(did);1355 1356	lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,1357		"GFF_ID cmpl:     status:x%x/x%x did:x%x",1358		ulp_status, ulp_word4, did);1359 1360	/* Ignore response if link flipped after this request was made */1361	if (cmdiocb->event_tag != phba->fc_eventTag) {1362		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,1363				 "9045 Event tag mismatch. Ignoring NS rsp\n");1364		goto iocb_free;1365	}1366 1367	if (ulp_status == IOSTAT_SUCCESS) {1368		/* Good status, continue checking */1369		CTrsp = (struct lpfc_sli_ct_request *) outp->virt;1370		fbits = CTrsp->un.gff_acc.fbits[FCP_TYPE_FEATURE_OFFSET];1371 1372		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,1373				 "6431 Process GFF_ID rsp for %08x "1374				 "fbits %02x %s %s\n",1375				 did, fbits,1376				 (fbits & FC4_FEATURE_INIT) ? "Initiator" : " ",1377				 (fbits & FC4_FEATURE_TARGET) ? "Target" : " ");1378 1379		if (be16_to_cpu(CTrsp->CommandResponse.bits.CmdRsp) ==1380		    SLI_CT_RESPONSE_FS_ACC) {1381			if ((fbits & FC4_FEATURE_INIT) &&1382			    !(fbits & FC4_FEATURE_TARGET)) {1383				lpfc_printf_vlog(vport, KERN_INFO,1384						 LOG_DISCOVERY,1385						 "0270 Skip x%x GFF "1386						 "NameServer Rsp Data: (init) "1387						 "x%x x%x\n", did, fbits,1388						 vport->fc_rscn_id_cnt);1389				goto out;1390			}1391		}1392	}1393	else {1394		/* Check for retry */1395		if (cmdiocb->retry < LPFC_MAX_NS_RETRY) {1396			retry = 1;1397			if (ulp_status == IOSTAT_LOCAL_REJECT) {1398				switch ((ulp_word4 &1399					IOERR_PARAM_MASK)) {1400 1401				case IOERR_NO_RESOURCES:1402					/* We don't increment the retry1403					 * count for this case.1404					 */1405					break;1406				case IOERR_LINK_DOWN:1407				case IOERR_SLI_ABORTED:1408				case IOERR_SLI_DOWN:1409					retry = 0;1410					break;1411				default:1412					cmdiocb->retry++;1413				}1414			}1415			else1416				cmdiocb->retry++;1417 1418			if (retry) {1419				/* CT command is being retried */1420				rc = lpfc_ns_cmd(vport, SLI_CTNS_GFF_ID,1421					 cmdiocb->retry, did);1422				if (rc == 0) {1423					/* success */1424					free_ndlp = cmdiocb->ndlp;1425					lpfc_ct_free_iocb(phba, cmdiocb);1426					lpfc_nlp_put(free_ndlp);1427					return;1428				}1429			}1430		}1431		lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,1432				 "0267 NameServer GFF Rsp "1433				 "x%x Error (%d %d) Data: x%lx x%x\n",1434				 did, ulp_status, ulp_word4,1435				 vport->fc_flag, vport->fc_rscn_id_cnt);1436	}1437 1438	/* This is a target port, unregistered port, or the GFF_ID failed */1439	ndlp = lpfc_setup_disc_node(vport, did);1440	if (ndlp) {1441		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,1442				 "0242 Process x%x GFF "1443				 "NameServer Rsp Data: x%x x%lx x%x\n",1444				 did, ndlp->nlp_flag, vport->fc_flag,1445				 vport->fc_rscn_id_cnt);1446	} else {1447		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,1448				 "0243 Skip x%x GFF "1449				 "NameServer Rsp Data: x%lx x%x\n", did,1450				 vport->fc_flag, vport->fc_rscn_id_cnt);1451	}1452out:1453	/* Link up / RSCN discovery */1454	if (vport->num_disc_nodes)1455		vport->num_disc_nodes--;1456 1457	lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,1458			 "6451 GFF_ID cmpl inp %d disc %d\n",1459			 vport->gidft_inp, vport->num_disc_nodes);1460 1461	if (vport->num_disc_nodes == 0) {1462		/*1463		 * The driver has cycled through all Nports in the RSCN payload.1464		 * Complete the handling by cleaning up and marking the1465		 * current driver state.1466		 */1467		if (vport->port_state >= LPFC_DISC_AUTH) {1468			if (test_bit(FC_RSCN_MODE, &vport->fc_flag)) {1469				lpfc_els_flush_rscn(vport);1470				/* RSCN still */1471				set_bit(FC_RSCN_MODE, &vport->fc_flag);1472			} else {1473				lpfc_els_flush_rscn(vport);1474			}1475		}1476		lpfc_disc_start(vport);1477	}1478 1479iocb_free:1480	free_ndlp = cmdiocb->ndlp;1481	lpfc_ct_free_iocb(phba, cmdiocb);1482	lpfc_nlp_put(free_ndlp);1483	return;1484}1485 1486static void1487lpfc_cmpl_ct_cmd_gft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,1488			struct lpfc_iocbq *rspiocb)1489{1490	struct lpfc_vport *vport = cmdiocb->vport;1491	struct lpfc_dmabuf *inp = cmdiocb->cmd_dmabuf;1492	struct lpfc_dmabuf *outp = cmdiocb->rsp_dmabuf;1493	struct lpfc_sli_ct_request *CTrsp;1494	int did;1495	struct lpfc_nodelist *ndlp = NULL;1496	struct lpfc_nodelist *ns_ndlp = cmdiocb->ndlp;1497	uint32_t fc4_data_0, fc4_data_1;1498	u32 ulp_status = get_job_ulpstatus(phba, rspiocb);1499	u32 ulp_word4 = get_job_word4(phba, rspiocb);1500 1501	did = ((struct lpfc_sli_ct_request *)inp->virt)->un.gft.PortId;1502	did = be32_to_cpu(did);1503 1504	lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,1505			      "GFT_ID cmpl: status:x%x/x%x did:x%x",1506			      ulp_status, ulp_word4, did);1507 1508	/* Ignore response if link flipped after this request was made */1509	if ((uint32_t)cmdiocb->event_tag != phba->fc_eventTag) {1510		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,1511				 "9046 Event tag mismatch. Ignoring NS rsp\n");1512		goto out;1513	}1514 1515	if (ulp_status == IOSTAT_SUCCESS) {1516		/* Good status, continue checking */1517		CTrsp = (struct lpfc_sli_ct_request *)outp->virt;1518		fc4_data_0 = be32_to_cpu(CTrsp->un.gft_acc.fc4_types[0]);1519		fc4_data_1 = be32_to_cpu(CTrsp->un.gft_acc.fc4_types[1]);1520 1521		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,1522				 "6432 Process GFT_ID rsp for %08x "1523				 "Data %08x %08x %s %s\n",1524				 did, fc4_data_0, fc4_data_1,1525				 (fc4_data_0 & LPFC_FC4_TYPE_BITMASK) ?1526				  "FCP" : " ",1527				 (fc4_data_1 & LPFC_FC4_TYPE_BITMASK) ?1528				  "NVME" : " ");1529 1530		/* Lookup the NPort_ID queried in the GFT_ID and find the1531		 * driver's local node.  It's an error if the driver1532		 * doesn't have one.1533		 */1534		ndlp = lpfc_findnode_did(vport, did);1535		if (ndlp) {1536			/* The bitmask value for FCP and NVME FCP types is1537			 * the same because they are 32 bits distant from1538			 * each other in word0 and word0.1539			 */1540			if (fc4_data_0 & LPFC_FC4_TYPE_BITMASK)1541				ndlp->nlp_fc4_type |= NLP_FC4_FCP;1542			if (fc4_data_1 &  LPFC_FC4_TYPE_BITMASK)1543				ndlp->nlp_fc4_type |= NLP_FC4_NVME;1544			lpfc_printf_vlog(vport, KERN_INFO,1545					 LOG_DISCOVERY | LOG_NODE,1546					 "3064 Setting ndlp x%px, DID x%06x "1547					 "with FC4 x%08x, Data: x%08x x%08x "1548					 "%d\n",1549					 ndlp, did, ndlp->nlp_fc4_type,1550					 FC_TYPE_FCP, FC_TYPE_NVME,1551					 ndlp->nlp_state);1552 1553			if (ndlp->nlp_state == NLP_STE_REG_LOGIN_ISSUE &&1554			    ndlp->nlp_fc4_type) {1555				ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;1556				lpfc_nlp_set_state(vport, ndlp,1557						   NLP_STE_PRLI_ISSUE);1558				lpfc_issue_els_prli(vport, ndlp, 0);1559			} else if (!ndlp->nlp_fc4_type) {1560				/* If fc4 type is still unknown, then LOGO */1561				lpfc_printf_vlog(vport, KERN_INFO,1562						 LOG_DISCOVERY | LOG_NODE,1563						 "6443 Sending LOGO ndlp x%px, "1564						 "DID x%06x with fc4_type: "1565						 "x%08x, state: %d\n",1566						 ndlp, did, ndlp->nlp_fc4_type,1567						 ndlp->nlp_state);1568				lpfc_issue_els_logo(vport, ndlp, 0);1569				ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;1570				lpfc_nlp_set_state(vport, ndlp,1571						   NLP_STE_NPR_NODE);1572			}1573		}1574	} else1575		lpfc_vlog_msg(vport, KERN_WARNING, LOG_DISCOVERY,1576			      "3065 GFT_ID status x%08x\n", ulp_status);1577 1578out:1579	lpfc_ct_free_iocb(phba, cmdiocb);1580	lpfc_nlp_put(ns_ndlp);1581}1582 1583static void1584lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,1585	     struct lpfc_iocbq *rspiocb)1586{1587	struct lpfc_vport *vport = cmdiocb->vport;1588	struct lpfc_dmabuf *inp;1589	struct lpfc_dmabuf *outp;1590	struct lpfc_sli_ct_request *CTrsp;1591	struct lpfc_nodelist *ndlp;1592	int cmdcode, rc;1593	uint8_t retry;1594	uint32_t latt;1595	u32 ulp_status = get_job_ulpstatus(phba, rspiocb);1596	u32 ulp_word4 = get_job_word4(phba, rspiocb);1597 1598	/* First save ndlp, before we overwrite it */1599	ndlp = cmdiocb->ndlp;1600 1601	/* we pass cmdiocb to state machine which needs rspiocb as well */1602	cmdiocb->rsp_iocb = rspiocb;1603 1604	inp = cmdiocb->cmd_dmabuf;1605	outp = cmdiocb->rsp_dmabuf;1606 1607	cmdcode = be16_to_cpu(((struct lpfc_sli_ct_request *) inp->virt)->1608					CommandResponse.bits.CmdRsp);1609	CTrsp = (struct lpfc_sli_ct_request *) outp->virt;1610 1611	latt = lpfc_els_chk_latt(vport);1612 1613	/* RFT request completes status <ulp_status> CmdRsp <CmdRsp> */1614	lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,1615			 "0209 CT Request completes, latt %d, "1616			 "ulp_status x%x CmdRsp x%x, Context x%x, Tag x%x\n",1617			 latt, ulp_status,1618			 be16_to_cpu(CTrsp->CommandResponse.bits.CmdRsp),1619			 get_job_ulpcontext(phba, cmdiocb), cmdiocb->iotag);1620 1621	lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,1622		"CT cmd cmpl:     status:x%x/x%x cmd:x%x",1623		ulp_status, ulp_word4, cmdcode);1624 1625	if (ulp_status) {1626		lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,1627				 "0268 NS cmd x%x Error (x%x x%x)\n",1628				 cmdcode, ulp_status, ulp_word4);1629 1630		if (ulp_status == IOSTAT_LOCAL_REJECT &&1631		    (((ulp_word4 & IOERR_PARAM_MASK) ==1632		      IOERR_SLI_DOWN) ||1633		     ((ulp_word4 & IOERR_PARAM_MASK) ==1634		      IOERR_SLI_ABORTED)))1635			goto out;1636 1637		retry = cmdiocb->retry;1638		if (retry >= LPFC_MAX_NS_RETRY)1639			goto out;1640 1641		retry++;1642		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,1643				 "0250 Retrying NS cmd %x\n", cmdcode);1644		rc = lpfc_ns_cmd(vport, cmdcode, retry, 0);1645		if (rc == 0)1646			goto out;1647	}1648 1649out:1650	/* If the caller wanted a synchronous DA_ID completion, signal the1651	 * wait obj and clear flag to reset the vport.1652	 */1653	if (ndlp->save_flags & NLP_WAIT_FOR_DA_ID) {1654		if (ndlp->da_id_waitq)1655			wake_up(ndlp->da_id_waitq);1656	}1657 1658	spin_lock_irq(&ndlp->lock);1659	ndlp->save_flags &= ~NLP_WAIT_FOR_DA_ID;1660	spin_unlock_irq(&ndlp->lock);1661 1662	lpfc_ct_free_iocb(phba, cmdiocb);1663	lpfc_nlp_put(ndlp);1664	return;1665}1666 1667static void1668lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,1669			struct lpfc_iocbq *rspiocb)1670{1671	struct lpfc_vport *vport = cmdiocb->vport;1672	u32 ulp_status = get_job_ulpstatus(phba, rspiocb);1673 1674	if (ulp_status == IOSTAT_SUCCESS) {1675		struct lpfc_dmabuf *outp;1676		struct lpfc_sli_ct_request *CTrsp;1677 1678		outp = cmdiocb->rsp_dmabuf;1679		CTrsp = (struct lpfc_sli_ct_request *)outp->virt;1680		if (be16_to_cpu(CTrsp->CommandResponse.bits.CmdRsp) ==1681		    SLI_CT_RESPONSE_FS_ACC)1682			vport->ct_flags |= FC_CT_RFT_ID;1683	}1684	lpfc_cmpl_ct(phba, cmdiocb, rspiocb);1685	return;1686}1687 1688static void1689lpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,1690			struct lpfc_iocbq *rspiocb)1691{1692	struct lpfc_vport *vport = cmdiocb->vport;1693	u32 ulp_status = get_job_ulpstatus(phba, rspiocb);1694 1695	if (ulp_status == IOSTAT_SUCCESS) {1696		struct lpfc_dmabuf *outp;1697		struct lpfc_sli_ct_request *CTrsp;1698 1699		outp = cmdiocb->rsp_dmabuf;1700		CTrsp = (struct lpfc_sli_ct_request *) outp->virt;1701		if (be16_to_cpu(CTrsp->CommandResponse.bits.CmdRsp) ==1702		    SLI_CT_RESPONSE_FS_ACC)1703			vport->ct_flags |= FC_CT_RNN_ID;1704	}1705	lpfc_cmpl_ct(phba, cmdiocb, rspiocb);1706	return;1707}1708 1709static void1710lpfc_cmpl_ct_cmd_rspn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,1711			 struct lpfc_iocbq *rspiocb)1712{1713	struct lpfc_vport *vport = cmdiocb->vport;1714	u32 ulp_status = get_job_ulpstatus(phba, rspiocb);1715 1716	if (ulp_status == IOSTAT_SUCCESS) {1717		struct lpfc_dmabuf *outp;1718		struct lpfc_sli_ct_request *CTrsp;1719 1720		outp = cmdiocb->rsp_dmabuf;1721		CTrsp = (struct lpfc_sli_ct_request *)outp->virt;1722		if (be16_to_cpu(CTrsp->CommandResponse.bits.CmdRsp) ==1723		    SLI_CT_RESPONSE_FS_ACC)1724			vport->ct_flags |= FC_CT_RSPN_ID;1725	}1726	lpfc_cmpl_ct(phba, cmdiocb, rspiocb);1727	return;1728}1729 1730static void1731lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,1732			 struct lpfc_iocbq *rspiocb)1733{1734	struct lpfc_vport *vport = cmdiocb->vport;1735	u32 ulp_status = get_job_ulpstatus(phba, rspiocb);1736 1737	if (ulp_status == IOSTAT_SUCCESS) {1738		struct lpfc_dmabuf *outp;1739		struct lpfc_sli_ct_request *CTrsp;1740 1741		outp = cmdiocb->rsp_dmabuf;1742		CTrsp = (struct lpfc_sli_ct_request *) outp->virt;1743		if (be16_to_cpu(CTrsp->CommandResponse.bits.CmdRsp) ==1744		    SLI_CT_RESPONSE_FS_ACC)1745			vport->ct_flags |= FC_CT_RSNN_NN;1746	}1747	lpfc_cmpl_ct(phba, cmdiocb, rspiocb);1748	return;1749}1750 1751static void1752lpfc_cmpl_ct_cmd_da_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,1753 struct lpfc_iocbq *rspiocb)1754{1755	struct lpfc_vport *vport = cmdiocb->vport;1756 1757	/* even if it fails we will act as though it succeeded. */1758	vport->ct_flags = 0;1759	lpfc_cmpl_ct(phba, cmdiocb, rspiocb);1760	return;1761}1762 1763static void1764lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,1765			struct lpfc_iocbq *rspiocb)1766{1767	struct lpfc_vport *vport = cmdiocb->vport;1768	u32 ulp_status = get_job_ulpstatus(phba, rspiocb);1769 1770	if (ulp_status == IOSTAT_SUCCESS) {1771		struct lpfc_dmabuf *outp;1772		struct lpfc_sli_ct_request *CTrsp;1773 1774		outp = cmdiocb->rsp_dmabuf;1775		CTrsp = (struct lpfc_sli_ct_request *)outp->virt;1776		if (be16_to_cpu(CTrsp->CommandResponse.bits.CmdRsp) ==1777		    SLI_CT_RESPONSE_FS_ACC)1778			vport->ct_flags |= FC_CT_RFF_ID;1779	}1780	lpfc_cmpl_ct(phba, cmdiocb, rspiocb);1781	return;1782}1783 1784/*1785 * Although the symbolic port name is thought to be an integer1786 * as of January 18, 2016, leave it as a string until more of1787 * the record state becomes defined.1788 */1789int1790lpfc_vport_symbolic_port_name(struct lpfc_vport *vport, char *symbol,1791	size_t size)1792{1793	int n;1794 1795	/*1796	 * Use the lpfc board number as the Symbolic Port1797	 * Name object.  NPIV is not in play so this integer1798	 * value is sufficient and unique per FC-ID.1799	 */1800	n = scnprintf(symbol, size, "%d", vport->phba->brd_no);1801	return n;1802}1803 1804 1805int1806lpfc_vport_symbolic_node_name(struct lpfc_vport *vport, char *symbol,1807	size_t size)1808{1809	char fwrev[FW_REV_STR_SIZE] = {0};1810	char tmp[MAXHOSTNAMELEN] = {0};1811 1812	memset(symbol, 0, size);1813 1814	scnprintf(tmp, sizeof(tmp), "Emulex %s", vport->phba->ModelName);1815	if (strlcat(symbol, tmp, size) >= size)1816		goto buffer_done;1817 1818	lpfc_decode_firmware_rev(vport->phba, fwrev, 0);1819	scnprintf(tmp, sizeof(tmp), " FV%s", fwrev);1820	if (strlcat(symbol, tmp, size) >= size)1821		goto buffer_done;1822 1823	scnprintf(tmp, sizeof(tmp), " DV%s", lpfc_release_version);1824	if (strlcat(symbol, tmp, size) >= size)1825		goto buffer_done;1826 1827	scnprintf(tmp, sizeof(tmp), " HN:%s", vport->phba->os_host_name);1828	if (strlcat(symbol, tmp, size) >= size)1829		goto buffer_done;1830 1831	/* Note :- OS name is "Linux" */1832	scnprintf(tmp, sizeof(tmp), " OS:%s", init_utsname()->sysname);1833	strlcat(symbol, tmp, size);1834 1835buffer_done:1836	return strnlen(symbol, size);1837 1838}1839 1840static uint32_t1841lpfc_find_map_node(struct lpfc_vport *vport)1842{1843	struct lpfc_nodelist *ndlp, *next_ndlp;1844	unsigned long iflags;1845	uint32_t cnt = 0;1846 1847	spin_lock_irqsave(&vport->fc_nodes_list_lock, iflags);1848	list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {1849		if (ndlp->nlp_type & NLP_FABRIC)1850			continue;1851		if ((ndlp->nlp_state == NLP_STE_MAPPED_NODE) ||1852		    (ndlp->nlp_state == NLP_STE_UNMAPPED_NODE))1853			cnt++;1854	}1855	spin_unlock_irqrestore(&vport->fc_nodes_list_lock, iflags);1856	return cnt;1857}1858 1859/*1860 * This routine will return the FC4 Type associated with the CT1861 * GID_FT command.1862 */1863int1864lpfc_get_gidft_type(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb)1865{1866	struct lpfc_sli_ct_request *CtReq;1867	struct lpfc_dmabuf *mp;1868	uint32_t type;1869 1870	mp = cmdiocb->cmd_dmabuf;1871	if (mp == NULL)1872		return 0;1873	CtReq = (struct lpfc_sli_ct_request *)mp->virt;1874	type = (uint32_t)CtReq->un.gid.Fc4Type;1875	if ((type != SLI_CTPT_FCP) && (type != SLI_CTPT_NVME))1876		return 0;1877	return type;1878}1879 1880/*1881 * lpfc_ns_cmd1882 * Description:1883 *    Issue Cmd to NameServer1884 *       SLI_CTNS_GID_FT1885 *       LI_CTNS_RFT_ID1886 */1887int1888lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,1889	    uint8_t retry, uint32_t context)1890{1891	struct lpfc_nodelist * ndlp;1892	struct lpfc_hba *phba = vport->phba;1893	struct lpfc_dmabuf *mp, *bmp;1894	struct lpfc_sli_ct_request *CtReq;1895	struct ulp_bde64 *bpl;1896	void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *,1897		      struct lpfc_iocbq *) = NULL;1898	uint32_t *ptr;1899	uint32_t rsp_size = 1024;1900	size_t   size;1901	int rc = 0;1902 1903	ndlp = lpfc_findnode_did(vport, NameServer_DID);1904	if (!ndlp || ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) {1905		rc=1;1906		goto ns_cmd_exit;1907	}1908 1909	/* fill in BDEs for command */1910	/* Allocate buffer for command payload */1911	mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);1912	if (!mp) {1913		rc=2;1914		goto ns_cmd_exit;1915	}1916 1917	INIT_LIST_HEAD(&mp->list);1918	mp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(mp->phys));1919	if (!mp->virt) {1920		rc=3;1921		goto ns_cmd_free_mp;1922	}1923 1924	/* Allocate buffer for Buffer ptr list */1925	bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);1926	if (!bmp) {1927		rc=4;1928		goto ns_cmd_free_mpvirt;1929	}1930 1931	INIT_LIST_HEAD(&bmp->list);1932	bmp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(bmp->phys));1933	if (!bmp->virt) {1934		rc=5;1935		goto ns_cmd_free_bmp;1936	}1937 1938	/* NameServer Req */1939	lpfc_printf_vlog(vport, KERN_INFO ,LOG_DISCOVERY,1940			 "0236 NameServer Req Data: x%x x%lx x%x x%x\n",1941			 cmdcode, vport->fc_flag, vport->fc_rscn_id_cnt,1942			 context);1943 1944	bpl = (struct ulp_bde64 *) bmp->virt;1945	memset(bpl, 0, sizeof(struct ulp_bde64));1946	bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys) );1947	bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys) );1948	bpl->tus.f.bdeFlags = 0;1949	if (cmdcode == SLI_CTNS_GID_FT)1950		bpl->tus.f.bdeSize = GID_REQUEST_SZ;1951	else if (cmdcode == SLI_CTNS_GID_PT)1952		bpl->tus.f.bdeSize = GID_REQUEST_SZ;1953	else if (cmdcode == SLI_CTNS_GFF_ID)1954		bpl->tus.f.bdeSize = GFF_REQUEST_SZ;1955	else if (cmdcode == SLI_CTNS_GFT_ID)1956		bpl->tus.f.bdeSize = GFT_REQUEST_SZ;1957	else if (cmdcode == SLI_CTNS_RFT_ID)1958		bpl->tus.f.bdeSize = RFT_REQUEST_SZ;1959	else if (cmdcode == SLI_CTNS_RNN_ID)1960		bpl->tus.f.bdeSize = RNN_REQUEST_SZ;1961	else if (cmdcode == SLI_CTNS_RSPN_ID)1962		bpl->tus.f.bdeSize = RSPN_REQUEST_SZ;1963	else if (cmdcode == SLI_CTNS_RSNN_NN)1964		bpl->tus.f.bdeSize = RSNN_REQUEST_SZ;1965	else if (cmdcode == SLI_CTNS_DA_ID)1966		bpl->tus.f.bdeSize = DA_ID_REQUEST_SZ;1967	else if (cmdcode == SLI_CTNS_RFF_ID)1968		bpl->tus.f.bdeSize = RFF_REQUEST_SZ;1969	else1970		bpl->tus.f.bdeSize = 0;1971	bpl->tus.w = le32_to_cpu(bpl->tus.w);1972 1973	CtReq = (struct lpfc_sli_ct_request *) mp->virt;1974	memset(CtReq, 0, sizeof(struct lpfc_sli_ct_request));1975	CtReq->RevisionId.bits.Revision = SLI_CT_REVISION;1976	CtReq->RevisionId.bits.InId = 0;1977	CtReq->FsType = SLI_CT_DIRECTORY_SERVICE;1978	CtReq->FsSubType = SLI_CT_DIRECTORY_NAME_SERVER;1979	CtReq->CommandResponse.bits.Size = 0;1980	switch (cmdcode) {1981	case SLI_CTNS_GID_FT:1982		CtReq->CommandResponse.bits.CmdRsp =1983		    cpu_to_be16(SLI_CTNS_GID_FT);1984		CtReq->un.gid.Fc4Type = context;1985 1986		if (vport->port_state < LPFC_NS_QRY)1987			vport->port_state = LPFC_NS_QRY;1988		lpfc_set_disctmo(vport);1989		cmpl = lpfc_cmpl_ct_cmd_gid_ft;1990		rsp_size = FC_MAX_NS_RSP;1991		break;1992 1993	case SLI_CTNS_GID_PT:1994		CtReq->CommandResponse.bits.CmdRsp =1995		    cpu_to_be16(SLI_CTNS_GID_PT);1996		CtReq->un.gid.PortType = context;1997 1998		if (vport->port_state < LPFC_NS_QRY)1999			vport->port_state = LPFC_NS_QRY;2000		lpfc_set_disctmo(vport);2001		cmpl = lpfc_cmpl_ct_cmd_gid_pt;2002		rsp_size = FC_MAX_NS_RSP;2003		break;2004 2005	case SLI_CTNS_GFF_ID:2006		CtReq->CommandResponse.bits.CmdRsp =2007			cpu_to_be16(SLI_CTNS_GFF_ID);2008		CtReq->un.gff.PortId = cpu_to_be32(context);2009		cmpl = lpfc_cmpl_ct_cmd_gff_id;2010		break;2011 2012	case SLI_CTNS_GFT_ID:2013		CtReq->CommandResponse.bits.CmdRsp =2014			cpu_to_be16(SLI_CTNS_GFT_ID);2015		CtReq->un.gft.PortId = cpu_to_be32(context);2016		cmpl = lpfc_cmpl_ct_cmd_gft_id;2017		break;2018 2019	case SLI_CTNS_RFT_ID:2020		vport->ct_flags &= ~FC_CT_RFT_ID;2021		CtReq->CommandResponse.bits.CmdRsp =2022		    cpu_to_be16(SLI_CTNS_RFT_ID);2023		CtReq->un.rft.port_id = cpu_to_be32(vport->fc_myDID);2024 2025		/* Register Application Services type if vmid enabled. */2026		if (phba->cfg_vmid_app_header)2027			CtReq->un.rft.app_serv_reg =2028				cpu_to_be32(RFT_APP_SERV_REG);2029 2030		/* Register FC4 FCP type if enabled.  */2031		if (vport->cfg_enable_fc4_type == LPFC_ENABLE_BOTH ||2032		    vport->cfg_enable_fc4_type == LPFC_ENABLE_FCP)2033			CtReq->un.rft.fcp_reg = cpu_to_be32(RFT_FCP_REG);2034 2035		/* Register NVME type if enabled. */2036		if (vport->cfg_enable_fc4_type == LPFC_ENABLE_BOTH ||2037		    vport->cfg_enable_fc4_type == LPFC_ENABLE_NVME)2038			CtReq->un.rft.nvme_reg = cpu_to_be32(RFT_NVME_REG);2039 2040		ptr = (uint32_t *)CtReq;2041		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,2042				 "6433 Issue RFT (%s %s %s): %08x %08x %08x "2043				 "%08x %08x %08x %08x %08x\n",2044				 CtReq->un.rft.fcp_reg ? "FCP" : " ",2045				 CtReq->un.rft.nvme_reg ? "NVME" : " ",2046				 CtReq->un.rft.app_serv_reg ? "APPS" : " ",2047				 *ptr, *(ptr + 1), *(ptr + 2), *(ptr + 3),2048				 *(ptr + 4), *(ptr + 5),2049				 *(ptr + 6), *(ptr + 7));2050		cmpl = lpfc_cmpl_ct_cmd_rft_id;2051		break;2052 2053	case SLI_CTNS_RNN_ID:2054		vport->ct_flags &= ~FC_CT_RNN_ID;2055		CtReq->CommandResponse.bits.CmdRsp =2056		    cpu_to_be16(SLI_CTNS_RNN_ID);2057		CtReq->un.rnn.PortId = cpu_to_be32(vport->fc_myDID);2058		memcpy(CtReq->un.rnn.wwnn,  &vport->fc_nodename,2059		       sizeof(struct lpfc_name));2060		cmpl = lpfc_cmpl_ct_cmd_rnn_id;2061		break;2062 2063	case SLI_CTNS_RSPN_ID:2064		vport->ct_flags &= ~FC_CT_RSPN_ID;2065		CtReq->CommandResponse.bits.CmdRsp =2066		    cpu_to_be16(SLI_CTNS_RSPN_ID);2067		CtReq->un.rspn.PortId = cpu_to_be32(vport->fc_myDID);2068		size = sizeof(CtReq->un.rspn.symbname);2069		CtReq->un.rspn.len =2070			lpfc_vport_symbolic_port_name(vport,2071			CtReq->un.rspn.symbname, size);2072		cmpl = lpfc_cmpl_ct_cmd_rspn_id;2073		break;2074	case SLI_CTNS_RSNN_NN:2075		vport->ct_flags &= ~FC_CT_RSNN_NN;2076		CtReq->CommandResponse.bits.CmdRsp =2077		    cpu_to_be16(SLI_CTNS_RSNN_NN);2078		memcpy(CtReq->un.rsnn.wwnn, &vport->fc_nodename,2079		       sizeof(struct lpfc_name));2080		size = sizeof(CtReq->un.rsnn.symbname);2081		CtReq->un.rsnn.len =2082			lpfc_vport_symbolic_node_name(vport,2083			CtReq->un.rsnn.symbname, size);2084		cmpl = lpfc_cmpl_ct_cmd_rsnn_nn;2085		break;2086	case SLI_CTNS_DA_ID:2087		/* Implement DA_ID Nameserver request */2088		CtReq->CommandResponse.bits.CmdRsp =2089			cpu_to_be16(SLI_CTNS_DA_ID);2090		CtReq->un.da_id.port_id = cpu_to_be32(vport->fc_myDID);2091		cmpl = lpfc_cmpl_ct_cmd_da_id;2092		break;2093	case SLI_CTNS_RFF_ID:2094		vport->ct_flags &= ~FC_CT_RFF_ID;2095		CtReq->CommandResponse.bits.CmdRsp =2096		    cpu_to_be16(SLI_CTNS_RFF_ID);2097		CtReq->un.rff.PortId = cpu_to_be32(vport->fc_myDID);2098		CtReq->un.rff.fbits = FC4_FEATURE_INIT;2099 2100		/* The driver always supports FC_TYPE_FCP.  However, the2101		 * caller can specify NVME (type x28) as well.  But only2102		 * these that FC4 type is supported.2103		 */2104		if (((vport->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||2105		     (vport->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) &&2106		    (context == FC_TYPE_NVME)) {2107			if ((vport == phba->pport) && phba->nvmet_support) {2108				CtReq->un.rff.fbits = (FC4_FEATURE_TARGET |2109					FC4_FEATURE_NVME_DISC);2110				lpfc_nvmet_update_targetport(phba);2111			} else {2112				lpfc_nvme_update_localport(vport);2113			}2114			CtReq->un.rff.type_code = context;2115 2116		} else if (((vport->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||2117			    (vport->cfg_enable_fc4_type == LPFC_ENABLE_FCP)) &&2118			   (context == FC_TYPE_FCP))2119			CtReq->un.rff.type_code = context;2120 2121		else2122			goto ns_cmd_free_bmpvirt;2123 2124		ptr = (uint32_t *)CtReq;2125		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,2126				 "6434 Issue RFF (%s): %08x %08x %08x %08x "2127				 "%08x %08x %08x %08x\n",2128				 (context == FC_TYPE_NVME) ? "NVME" : "FCP",2129				 *ptr, *(ptr + 1), *(ptr + 2), *(ptr + 3),2130				 *(ptr + 4), *(ptr + 5),2131				 *(ptr + 6), *(ptr + 7));2132		cmpl = lpfc_cmpl_ct_cmd_rff_id;2133		break;2134	}2135	/* The lpfc_ct_cmd/lpfc_get_req shall increment ndlp reference count2136	 * to hold ndlp reference for the corresponding callback function.2137	 */2138	if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size, retry)) {2139		/* On success, The cmpl function will free the buffers */2140		lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,2141			"Issue CT cmd:    cmd:x%x did:x%x",2142			cmdcode, ndlp->nlp_DID, 0);2143		return 0;2144	}2145	rc=6;2146 2147ns_cmd_free_bmpvirt:2148	lpfc_mbuf_free(phba, bmp->virt, bmp->phys);2149ns_cmd_free_bmp:2150	kfree(bmp);2151ns_cmd_free_mpvirt:2152	lpfc_mbuf_free(phba, mp->virt, mp->phys);2153ns_cmd_free_mp:2154	kfree(mp);2155ns_cmd_exit:2156	lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,2157			 "0266 Issue NameServer Req x%x err %d Data: x%lx "2158			 "x%x\n",2159			 cmdcode, rc, vport->fc_flag, vport->fc_rscn_id_cnt);2160	return 1;2161}2162 2163/**2164 * lpfc_fdmi_rprt_defer - Check for any deferred FDMI RPRT commands2165 * @phba: Pointer to HBA context object.2166 * @mask: Initial port attributes mask2167 *2168 * This function checks to see if any vports have deferred their FDMI RPRT.2169 * A vports RPRT may be deferred if it is issued before the primary ports2170 * RHBA completes.2171 */2172static void2173lpfc_fdmi_rprt_defer(struct lpfc_hba *phba, uint32_t mask)2174{2175	struct lpfc_vport **vports;2176	struct lpfc_vport *vport;2177	struct lpfc_nodelist *ndlp;2178	int i;2179 2180	set_bit(HBA_RHBA_CMPL, &phba->hba_flag);2181	vports = lpfc_create_vport_work_array(phba);2182	if (vports) {2183		for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {2184			vport = vports[i];2185			ndlp = lpfc_findnode_did(phba->pport, FDMI_DID);2186			if (!ndlp)2187				continue;2188			if (vport->ct_flags & FC_CT_RPRT_DEFER) {2189				vport->ct_flags &= ~FC_CT_RPRT_DEFER;2190				vport->fdmi_port_mask = mask;2191				lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPRT, 0);2192			}2193		}2194	}2195	lpfc_destroy_vport_work_array(phba, vports);2196}2197 2198/**2199 * lpfc_cmpl_ct_disc_fdmi - Handle a discovery FDMI completion2200 * @phba: Pointer to HBA context object.2201 * @cmdiocb: Pointer to the command IOCBQ.2202 * @rspiocb: Pointer to the response IOCBQ.2203 *2204 * This function to handle the completion of a driver initiated FDMI2205 * CT command issued during discovery.2206 */2207static void2208lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,2209		       struct lpfc_iocbq *rspiocb)2210{2211	struct lpfc_vport *vport = cmdiocb->vport;2212	struct lpfc_dmabuf *inp = cmdiocb->cmd_dmabuf;2213	struct lpfc_dmabuf *outp = cmdiocb->rsp_dmabuf;2214	struct lpfc_sli_ct_request *CTcmd = inp->virt;2215	struct lpfc_sli_ct_request *CTrsp = outp->virt;2216	__be16 fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp;2217	__be16 fdmi_rsp = CTrsp->CommandResponse.bits.CmdRsp;2218	struct lpfc_nodelist *ndlp, *free_ndlp = NULL;2219	uint32_t latt, cmd, err;2220	u32 ulp_status = get_job_ulpstatus(phba, rspiocb);2221	u32 ulp_word4 = get_job_word4(phba, rspiocb);2222 2223	latt = lpfc_els_chk_latt(vport);2224	lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT,2225		"FDMI cmpl:       status:x%x/x%x latt:%d",2226		ulp_status, ulp_word4, latt);2227 2228	if (latt || ulp_status) {2229 2230		/* Look for a retryable error */2231		if (ulp_status == IOSTAT_LOCAL_REJECT) {2232			switch ((ulp_word4 & IOERR_PARAM_MASK)) {2233			case IOERR_SLI_ABORTED:2234			case IOERR_SLI_DOWN:2235				/* Driver aborted this IO.  No retry as error2236				 * is likely Offline->Online or some adapter2237				 * error.  Recovery will try again.2238				 */2239				break;2240			case IOERR_ABORT_IN_PROGRESS:2241			case IOERR_SEQUENCE_TIMEOUT:2242			case IOERR_ILLEGAL_FRAME:2243			case IOERR_NO_RESOURCES:2244			case IOERR_ILLEGAL_COMMAND:2245				cmdiocb->retry++;2246				if (cmdiocb->retry >= LPFC_FDMI_MAX_RETRY)2247					break;2248 2249				/* Retry the same FDMI command */2250				err = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING,2251							  cmdiocb, 0);2252				if (err == IOCB_ERROR)2253					break;2254				return;2255			default:2256				break;2257			}2258		}2259 2260		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,2261				 "0229 FDMI cmd %04x latt = %d "2262				 "ulp_status: x%x, rid x%x\n",2263				 be16_to_cpu(fdmi_cmd), latt, ulp_status,2264				 ulp_word4);2265	}2266 2267	free_ndlp = cmdiocb->ndlp;2268	lpfc_ct_free_iocb(phba, cmdiocb);2269	lpfc_nlp_put(free_ndlp);2270 2271	ndlp = lpfc_findnode_did(vport, FDMI_DID);2272	if (!ndlp)2273		return;2274 2275	/* Check for a CT LS_RJT response */2276	cmd =  be16_to_cpu(fdmi_cmd);2277	if (be16_to_cpu(fdmi_rsp) == SLI_CT_RESPONSE_FS_RJT) {2278		/* Log FDMI reject */2279		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY | LOG_ELS,2280				 "0220 FDMI cmd FS_RJT Data: x%x", cmd);2281 2282		/* Should we fallback to FDMI-2 / FDMI-1 ? */2283		switch (cmd) {2284		case SLI_MGMT_RHBA:2285			if (vport->fdmi_hba_mask == LPFC_FDMI2_HBA_ATTR) {2286				/* Fallback to FDMI-1 for HBA attributes */2287				vport->fdmi_hba_mask = LPFC_FDMI1_HBA_ATTR;2288 2289				/* If HBA attributes are FDMI1, so should2290				 * port attributes be for consistency.2291				 */2292				vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR;2293				/* Start over */2294				lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0);2295			}2296			return;2297 2298		case SLI_MGMT_RPRT:2299			if (vport->port_type != LPFC_PHYSICAL_PORT) {2300				ndlp = lpfc_findnode_did(phba->pport, FDMI_DID);2301				if (!ndlp)2302					return;2303			}2304			if (vport->fdmi_port_mask == LPFC_FDMI2_PORT_ATTR) {2305				/* Fallback to FDMI-1 */2306				vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR;2307				/* Start over */2308				lpfc_fdmi_cmd(vport, ndlp, cmd, 0);2309				return;2310			}2311			if (vport->fdmi_port_mask == LPFC_FDMI2_SMART_ATTR) {2312				vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR;2313				/* Retry the same command */2314				lpfc_fdmi_cmd(vport, ndlp, cmd, 0);2315			}2316			return;2317 2318		case SLI_MGMT_RPA:2319			/* No retry on Vendor, RPA only done on physical port */2320			if (phba->link_flag & LS_CT_VEN_RPA) {2321				phba->link_flag &= ~LS_CT_VEN_RPA;2322				if (phba->cmf_active_mode == LPFC_CFG_OFF)2323					return;2324				lpfc_printf_log(phba, KERN_WARNING,2325						LOG_DISCOVERY | LOG_ELS,2326						"6460 VEN FDMI RPA RJT\n");2327				return;2328			}2329			if (vport->fdmi_port_mask == LPFC_FDMI2_PORT_ATTR) {2330				/* Fallback to FDMI-1 */2331				vport->fdmi_hba_mask = LPFC_FDMI1_HBA_ATTR;2332				vport->fdmi_port_mask = LPFC_FDMI1_PORT_ATTR;2333				/* Start over */2334				lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0);2335				return;2336			}2337			if (vport->fdmi_port_mask == LPFC_FDMI2_SMART_ATTR) {2338				vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR;2339				/* Retry the same command */2340				lpfc_fdmi_cmd(vport, ndlp, cmd, 0);2341			}2342			return;2343		}2344	}2345 2346	/*2347	 * On success, need to cycle thru FDMI registration for discovery2348	 * DHBA -> DPRT -> RHBA -> RPA  (physical port)2349	 * DPRT -> RPRT (vports)2350	 */2351	switch (cmd) {2352	case SLI_MGMT_RHBA:2353		/* Check for any RPRTs deferred till after RHBA completes */2354		lpfc_fdmi_rprt_defer(phba, vport->fdmi_port_mask);2355 2356		lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA, 0);2357		break;2358 2359	case SLI_MGMT_DHBA:2360		lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT, 0);2361		break;2362 2363	case SLI_MGMT_DPRT:2364		if (vport->port_type == LPFC_PHYSICAL_PORT) {2365			lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RHBA, 0);2366		} else {2367			ndlp = lpfc_findnode_did(phba->pport, FDMI_DID);2368			if (!ndlp)2369				return;2370 2371			/* Only issue a RPRT for the vport if the RHBA2372			 * for the physical port completes successfully.2373			 * We may have to defer the RPRT accordingly.2374			 */2375			if (test_bit(HBA_RHBA_CMPL, &phba->hba_flag)) {2376				lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPRT, 0);2377			} else {2378				lpfc_printf_vlog(vport, KERN_INFO,2379						 LOG_DISCOVERY,2380						 "6078 RPRT deferred\n");2381				vport->ct_flags |= FC_CT_RPRT_DEFER;2382			}2383		}2384		break;2385	case SLI_MGMT_RPA:2386		if (vport->port_type == LPFC_PHYSICAL_PORT &&2387		    phba->sli4_hba.pc_sli4_params.mi_ver) {2388			/* mi is only for the phyical port, no vports */2389			if (phba->link_flag & LS_CT_VEN_RPA) {2390				lpfc_printf_vlog(vport, KERN_INFO,2391						 LOG_DISCOVERY | LOG_ELS |2392						 LOG_CGN_MGMT,2393						 "6449 VEN RPA FDMI Success\n");2394				phba->link_flag &= ~LS_CT_VEN_RPA;2395				break;2396			}2397 2398			lpfc_printf_log(phba, KERN_INFO,2399					LOG_DISCOVERY | LOG_CGN_MGMT,2400					"6210 Issue Vendor MI FDMI %x\n",2401					phba->sli4_hba.pc_sli4_params.mi_ver);2402 2403			/* CGN is only for the physical port, no vports */2404			if (lpfc_fdmi_cmd(vport, ndlp, cmd,2405					  LPFC_FDMI_VENDOR_ATTR_mi) == 0)2406				phba->link_flag |= LS_CT_VEN_RPA;2407			lpfc_printf_log(phba, KERN_INFO,2408					LOG_DISCOVERY | LOG_ELS,2409					"6458 Send MI FDMI:%x Flag x%x\n",2410					phba->sli4_hba.pc_sli4_params.mi_ver,2411					phba->link_flag);2412		} else {2413			lpfc_printf_log(phba, KERN_INFO,2414					LOG_DISCOVERY | LOG_ELS,2415					"6459 No FDMI VEN MI support - "2416					"RPA Success\n");2417		}2418		break;2419	}2420	return;2421}2422 2423 2424/**2425 * lpfc_fdmi_change_check - Check for changed FDMI parameters2426 * @vport: pointer to a host virtual N_Port data structure.2427 *2428 * Check how many mapped NPorts we are connected to2429 * Check if our hostname changed2430 * Called from hbeat timeout routine to check if any FDMI parameters2431 * changed. If so, re-register those Attributes.2432 */2433void2434lpfc_fdmi_change_check(struct lpfc_vport *vport)2435{2436	struct lpfc_hba *phba = vport->phba;2437	struct lpfc_nodelist *ndlp;2438	uint16_t cnt;2439 2440	if (!lpfc_is_link_up(phba))2441		return;2442 2443	/* Must be connected to a Fabric */2444	if (!test_bit(FC_FABRIC, &vport->fc_flag))2445		return;2446 2447	ndlp = lpfc_findnode_did(vport, FDMI_DID);2448	if (!ndlp)2449		return;2450 2451	/* Check if system hostname changed */2452	if (strcmp(phba->os_host_name, init_utsname()->nodename)) {2453		memset(phba->os_host_name, 0, sizeof(phba->os_host_name));2454		scnprintf(phba->os_host_name, sizeof(phba->os_host_name), "%s",2455			  init_utsname()->nodename);2456		lpfc_ns_cmd(vport, SLI_CTNS_RSNN_NN, 0, 0);2457 2458		/* Since this effects multiple HBA and PORT attributes, we need2459		 * de-register and go thru the whole FDMI registration cycle.2460		 * DHBA -> DPRT -> RHBA -> RPA  (physical port)2461		 * DPRT -> RPRT (vports)2462		 */2463		if (vport->port_type == LPFC_PHYSICAL_PORT) {2464			/* For extra Vendor RPA */2465			phba->link_flag &= ~LS_CT_VEN_RPA;2466			lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0);2467		} else {2468			ndlp = lpfc_findnode_did(phba->pport, FDMI_DID);2469			if (!ndlp)2470				return;2471			lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT, 0);2472		}2473 2474		/* Since this code path registers all the port attributes2475		 * we can just return without further checking.2476		 */2477		return;2478	}2479 2480	if (!(vport->fdmi_port_mask & LPFC_FDMI_PORT_ATTR_num_disc))2481		return;2482 2483	/* Check if the number of mapped NPorts changed */2484	cnt = lpfc_find_map_node(vport);2485	if (cnt == vport->fdmi_num_disc)2486		return;2487 2488	if (vport->port_type == LPFC_PHYSICAL_PORT) {2489		lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA,2490			      LPFC_FDMI_PORT_ATTR_num_disc);2491	} else {2492		ndlp = lpfc_findnode_did(phba->pport, FDMI_DID);2493		if (!ndlp)2494			return;2495		lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPRT,2496			      LPFC_FDMI_PORT_ATTR_num_disc);2497	}2498}2499 2500static inline int2501lpfc_fdmi_set_attr_u32(void *attr, uint16_t attrtype, uint32_t attrval)2502{2503	struct lpfc_fdmi_attr_u32 *ae = attr;2504	int size = sizeof(*ae);2505 2506	ae->type = cpu_to_be16(attrtype);2507	ae->len = cpu_to_be16(size);2508	ae->value_u32 = cpu_to_be32(attrval);2509 2510	return size;2511}2512 2513static inline int2514lpfc_fdmi_set_attr_wwn(void *attr, uint16_t attrtype, struct lpfc_name *wwn)2515{2516	struct lpfc_fdmi_attr_wwn *ae = attr;2517	int size = sizeof(*ae);2518 2519	ae->type = cpu_to_be16(attrtype);2520	ae->len = cpu_to_be16(size);2521	/* WWN's assumed to be bytestreams - Big Endian presentation */2522	memcpy(ae->name, wwn,2523	       min_t(size_t, sizeof(struct lpfc_name), sizeof(__be64)));2524 2525	return size;2526}2527 2528static inline int2529lpfc_fdmi_set_attr_fullwwn(void *attr, uint16_t attrtype,2530			   struct lpfc_name *wwnn, struct lpfc_name *wwpn)2531{2532	struct lpfc_fdmi_attr_fullwwn *ae = attr;2533	u8 *nname = ae->nname;2534	u8 *pname = ae->pname;2535	int size = sizeof(*ae);2536 2537	ae->type = cpu_to_be16(attrtype);2538	ae->len = cpu_to_be16(size);2539	/* WWN's assumed to be bytestreams - Big Endian presentation */2540	memcpy(nname, wwnn,2541	       min_t(size_t, sizeof(struct lpfc_name), sizeof(__be64)));2542	memcpy(pname, wwpn,2543	       min_t(size_t, sizeof(struct lpfc_name), sizeof(__be64)));2544 2545	return size;2546}2547 2548static inline int2549lpfc_fdmi_set_attr_string(void *attr, uint16_t attrtype, char *attrstring)2550{2551	struct lpfc_fdmi_attr_string *ae = attr;2552	int len, size;2553 2554	/*2555	 * We are trusting the caller that if a fdmi string field2556	 * is capped at 64 bytes, the caller passes in a string of2557	 * 64 bytes or less.2558	 */2559 2560	strscpy(ae->value_string, attrstring, sizeof(ae->value_string));2561	len = strnlen(ae->value_string, sizeof(ae->value_string));2562	/* round string length to a 32bit boundary */2563	len += (len & 3) ? (4 - (len & 3)) : 4;2564	/* size is Type/Len (4 bytes) plus string length */2565	size = FOURBYTES + len;2566 2567	ae->type = cpu_to_be16(attrtype);2568	ae->len = cpu_to_be16(size);2569 2570	return size;2571}2572 2573/* Bitfields for FC4 Types that can be reported */2574#define ATTR_FC4_CT	0x000000012575#define ATTR_FC4_FCP	0x000000022576#define ATTR_FC4_NVME	0x000000042577 2578static inline int2579lpfc_fdmi_set_attr_fc4types(void *attr, uint16_t attrtype, uint32_t typemask)2580{2581	struct lpfc_fdmi_attr_fc4types *ae = attr;2582	int size = sizeof(*ae);2583 2584	ae->type = cpu_to_be16(attrtype);2585	ae->len = cpu_to_be16(size);2586 2587	if (typemask & ATTR_FC4_FCP)2588		ae->value_types[2] = 0x01; /* Type 0x8 - FCP */2589 2590	if (typemask & ATTR_FC4_CT)2591		ae->value_types[7] = 0x01; /* Type 0x20 - CT */2592 2593	if (typemask & ATTR_FC4_NVME)2594		ae->value_types[6] = 0x01; /* Type 0x28 - NVME */2595 2596	return size;2597}2598 2599/* Routines for all individual HBA attributes */2600static int2601lpfc_fdmi_hba_attr_wwnn(struct lpfc_vport *vport, void *attr)2602{2603	return lpfc_fdmi_set_attr_wwn(attr, RHBA_NODENAME,2604			&vport->fc_sparam.nodeName);2605}2606 2607static int2608lpfc_fdmi_hba_attr_manufacturer(struct lpfc_vport *vport, void *attr)2609{2610	/* This string MUST be consistent with other FC platforms2611	 * supported by Broadcom.2612	 */2613	return lpfc_fdmi_set_attr_string(attr, RHBA_MANUFACTURER,2614			"Emulex Corporation");2615}2616 2617static int2618lpfc_fdmi_hba_attr_sn(struct lpfc_vport *vport, void *attr)2619{2620	struct lpfc_hba *phba = vport->phba;2621 2622	return lpfc_fdmi_set_attr_string(attr, RHBA_SERIAL_NUMBER,2623			phba->SerialNumber);2624}2625 2626static int2627lpfc_fdmi_hba_attr_model(struct lpfc_vport *vport, void *attr)2628{2629	struct lpfc_hba *phba = vport->phba;2630 2631	return lpfc_fdmi_set_attr_string(attr, RHBA_MODEL,2632			phba->ModelName);2633}2634 2635static int2636lpfc_fdmi_hba_attr_description(struct lpfc_vport *vport, void *attr)2637{2638	struct lpfc_hba *phba = vport->phba;2639 2640	return lpfc_fdmi_set_attr_string(attr, RHBA_MODEL_DESCRIPTION,2641			phba->ModelDesc);2642}2643 2644static int2645lpfc_fdmi_hba_attr_hdw_ver(struct lpfc_vport *vport, void *attr)2646{2647	struct lpfc_hba *phba = vport->phba;2648	lpfc_vpd_t *vp = &phba->vpd;2649	char buf[16] = { 0 };2650 2651	snprintf(buf, sizeof(buf), "%08x", vp->rev.biuRev);2652 2653	return lpfc_fdmi_set_attr_string(attr, RHBA_HARDWARE_VERSION, buf);2654}2655 2656static int2657lpfc_fdmi_hba_attr_drvr_ver(struct lpfc_vport *vport, void *attr)2658{2659	return lpfc_fdmi_set_attr_string(attr, RHBA_DRIVER_VERSION,2660			lpfc_release_version);2661}2662 2663static int2664lpfc_fdmi_hba_attr_rom_ver(struct lpfc_vport *vport, void *attr)2665{2666	struct lpfc_hba *phba = vport->phba;2667	char buf[64] = { 0 };2668 2669	if (phba->sli_rev == LPFC_SLI_REV4) {2670		lpfc_decode_firmware_rev(phba, buf, 1);2671 2672		return lpfc_fdmi_set_attr_string(attr, RHBA_OPTION_ROM_VERSION,2673				buf);2674	}2675 2676	return lpfc_fdmi_set_attr_string(attr, RHBA_OPTION_ROM_VERSION,2677			phba->OptionROMVersion);2678}2679 2680static int2681lpfc_fdmi_hba_attr_fmw_ver(struct lpfc_vport *vport, void *attr)2682{2683	struct lpfc_hba *phba = vport->phba;2684	char buf[64] = { 0 };2685 2686	lpfc_decode_firmware_rev(phba, buf, 1);2687 2688	return lpfc_fdmi_set_attr_string(attr, RHBA_FIRMWARE_VERSION, buf);2689}2690 2691static int2692lpfc_fdmi_hba_attr_os_ver(struct lpfc_vport *vport, void *attr)2693{2694	char buf[256] = { 0 };2695 2696	snprintf(buf, sizeof(buf), "%s %s %s",2697		 init_utsname()->sysname,2698		 init_utsname()->release,2699		 init_utsname()->version);2700 2701	return lpfc_fdmi_set_attr_string(attr, RHBA_OS_NAME_VERSION, buf);2702}2703 2704static int2705lpfc_fdmi_hba_attr_ct_len(struct lpfc_vport *vport, void *attr)2706{2707	return lpfc_fdmi_set_attr_u32(attr, RHBA_MAX_CT_PAYLOAD_LEN,2708			LPFC_MAX_CT_SIZE);2709}2710 2711static int2712lpfc_fdmi_hba_attr_symbolic_name(struct lpfc_vport *vport, void *attr)2713{2714	char buf[256] = { 0 };2715 2716	lpfc_vport_symbolic_node_name(vport, buf, sizeof(buf));2717 2718	return lpfc_fdmi_set_attr_string(attr, RHBA_SYM_NODENAME, buf);2719}2720 2721static int2722lpfc_fdmi_hba_attr_vendor_info(struct lpfc_vport *vport, void *attr)2723{2724	return lpfc_fdmi_set_attr_u32(attr, RHBA_VENDOR_INFO, 0);2725}2726 2727static int2728lpfc_fdmi_hba_attr_num_ports(struct lpfc_vport *vport, void *attr)2729{2730	/* Each driver instance corresponds to a single port */2731	return lpfc_fdmi_set_attr_u32(attr, RHBA_NUM_PORTS, 1);2732}2733 2734static int2735lpfc_fdmi_hba_attr_fabric_wwnn(struct lpfc_vport *vport, void *attr)2736{2737	return lpfc_fdmi_set_attr_wwn(attr, RHBA_FABRIC_WWNN,2738			&vport->fabric_nodename);2739}2740 2741static int2742lpfc_fdmi_hba_attr_bios_ver(struct lpfc_vport *vport, void *attr)2743{2744	struct lpfc_hba *phba = vport->phba;2745 2746	return lpfc_fdmi_set_attr_string(attr, RHBA_BIOS_VERSION,2747			phba->BIOSVersion);2748}2749 2750static int2751lpfc_fdmi_hba_attr_bios_state(struct lpfc_vport *vport, void *attr)2752{2753	/* Driver doesn't have access to this information */2754	return lpfc_fdmi_set_attr_u32(attr, RHBA_BIOS_STATE, 0);2755}2756 2757static int2758lpfc_fdmi_hba_attr_vendor_id(struct lpfc_vport *vport, void *attr)2759{2760	return lpfc_fdmi_set_attr_string(attr, RHBA_VENDOR_ID, "EMULEX");2761}2762 2763/*2764 * Routines for all individual PORT attributes2765 */2766 2767static int2768lpfc_fdmi_port_attr_fc4type(struct lpfc_vport *vport, void *attr)2769{2770	struct lpfc_hba   *phba = vport->phba;2771	u32 fc4types;2772 2773	fc4types = (ATTR_FC4_CT | ATTR_FC4_FCP);2774 2775	/* Check to see if Firmware supports NVME and on physical port */2776	if ((phba->sli_rev == LPFC_SLI_REV4) && (vport == phba->pport) &&2777	    phba->sli4_hba.pc_sli4_params.nvme)2778		fc4types |= ATTR_FC4_NVME;2779 2780	return lpfc_fdmi_set_attr_fc4types(attr, RPRT_SUPPORTED_FC4_TYPES,2781			fc4types);2782}2783 2784static int2785lpfc_fdmi_port_attr_support_speed(struct lpfc_vport *vport, void *attr)2786{2787	struct lpfc_hba *phba = vport->phba;2788	u32 speeds = 0;2789	u32 tcfg;2790	u8 i, cnt;2791 2792	if (!test_bit(HBA_FCOE_MODE, &phba->hba_flag)) {2793		cnt = 0;2794		if (phba->sli_rev == LPFC_SLI_REV4) {2795			tcfg = phba->sli4_hba.conf_trunk;2796			for (i = 0; i < 4; i++, tcfg >>= 1)2797				if (tcfg & 1)2798					cnt++;2799		}2800 2801		if (cnt > 2) { /* 4 lane trunk group */2802			if (phba->lmt & LMT_64Gb)2803				speeds |= HBA_PORTSPEED_256GFC;2804			if (phba->lmt & LMT_32Gb)2805				speeds |= HBA_PORTSPEED_128GFC;2806			if (phba->lmt & LMT_16Gb)2807				speeds |= HBA_PORTSPEED_64GFC;2808		} else if (cnt) { /* 2 lane trunk group */2809			if (phba->lmt & LMT_128Gb)2810				speeds |= HBA_PORTSPEED_256GFC;2811			if (phba->lmt & LMT_64Gb)2812				speeds |= HBA_PORTSPEED_128GFC;2813			if (phba->lmt & LMT_32Gb)2814				speeds |= HBA_PORTSPEED_64GFC;2815			if (phba->lmt & LMT_16Gb)2816				speeds |= HBA_PORTSPEED_32GFC;2817		} else {2818			if (phba->lmt & LMT_256Gb)2819				speeds |= HBA_PORTSPEED_256GFC;2820			if (phba->lmt & LMT_128Gb)2821				speeds |= HBA_PORTSPEED_128GFC;2822			if (phba->lmt & LMT_64Gb)2823				speeds |= HBA_PORTSPEED_64GFC;2824			if (phba->lmt & LMT_32Gb)2825				speeds |= HBA_PORTSPEED_32GFC;2826			if (phba->lmt & LMT_16Gb)2827				speeds |= HBA_PORTSPEED_16GFC;2828			if (phba->lmt & LMT_10Gb)2829				speeds |= HBA_PORTSPEED_10GFC;2830			if (phba->lmt & LMT_8Gb)2831				speeds |= HBA_PORTSPEED_8GFC;2832			if (phba->lmt & LMT_4Gb)2833				speeds |= HBA_PORTSPEED_4GFC;2834			if (phba->lmt & LMT_2Gb)2835				speeds |= HBA_PORTSPEED_2GFC;2836			if (phba->lmt & LMT_1Gb)2837				speeds |= HBA_PORTSPEED_1GFC;2838		}2839	} else {2840		/* FCoE links support only one speed */2841		switch (phba->fc_linkspeed) {2842		case LPFC_ASYNC_LINK_SPEED_10GBPS:2843			speeds = HBA_PORTSPEED_10GE;2844			break;2845		case LPFC_ASYNC_LINK_SPEED_25GBPS:2846			speeds = HBA_PORTSPEED_25GE;2847			break;2848		case LPFC_ASYNC_LINK_SPEED_40GBPS:2849			speeds = HBA_PORTSPEED_40GE;2850			break;2851		case LPFC_ASYNC_LINK_SPEED_100GBPS:2852			speeds = HBA_PORTSPEED_100GE;2853			break;2854		}2855	}2856 2857	return lpfc_fdmi_set_attr_u32(attr, RPRT_SUPPORTED_SPEED, speeds);2858}2859 2860static int2861lpfc_fdmi_port_attr_speed(struct lpfc_vport *vport, void *attr)2862{2863	struct lpfc_hba   *phba = vport->phba;2864	u32 speeds = 0;2865 2866	if (!test_bit(HBA_FCOE_MODE, &phba->hba_flag)) {2867		switch (phba->fc_linkspeed) {2868		case LPFC_LINK_SPEED_1GHZ:2869			speeds = HBA_PORTSPEED_1GFC;2870			break;2871		case LPFC_LINK_SPEED_2GHZ:2872			speeds = HBA_PORTSPEED_2GFC;2873			break;2874		case LPFC_LINK_SPEED_4GHZ:2875			speeds = HBA_PORTSPEED_4GFC;2876			break;2877		case LPFC_LINK_SPEED_8GHZ:2878			speeds = HBA_PORTSPEED_8GFC;2879			break;2880		case LPFC_LINK_SPEED_10GHZ:2881			speeds = HBA_PORTSPEED_10GFC;2882			break;2883		case LPFC_LINK_SPEED_16GHZ:2884			speeds = HBA_PORTSPEED_16GFC;2885			break;2886		case LPFC_LINK_SPEED_32GHZ:2887			speeds = HBA_PORTSPEED_32GFC;2888			break;2889		case LPFC_LINK_SPEED_64GHZ:2890			speeds = HBA_PORTSPEED_64GFC;2891			break;2892		case LPFC_LINK_SPEED_128GHZ:2893			speeds = HBA_PORTSPEED_128GFC;2894			break;2895		case LPFC_LINK_SPEED_256GHZ:2896			speeds = HBA_PORTSPEED_256GFC;2897			break;2898		default:2899			speeds = HBA_PORTSPEED_UNKNOWN;2900			break;2901		}2902	} else {2903		switch (phba->fc_linkspeed) {2904		case LPFC_ASYNC_LINK_SPEED_10GBPS:2905			speeds = HBA_PORTSPEED_10GE;2906			break;2907		case LPFC_ASYNC_LINK_SPEED_25GBPS:2908			speeds = HBA_PORTSPEED_25GE;2909			break;2910		case LPFC_ASYNC_LINK_SPEED_40GBPS:2911			speeds = HBA_PORTSPEED_40GE;2912			break;2913		case LPFC_ASYNC_LINK_SPEED_100GBPS:2914			speeds = HBA_PORTSPEED_100GE;2915			break;2916		default:2917			speeds = HBA_PORTSPEED_UNKNOWN;2918			break;2919		}2920	}2921 2922	return lpfc_fdmi_set_attr_u32(attr, RPRT_PORT_SPEED, speeds);2923}2924 2925static int2926lpfc_fdmi_port_attr_max_frame(struct lpfc_vport *vport, void *attr)2927{2928	struct serv_parm *hsp = (struct serv_parm *)&vport->fc_sparam;2929 2930	return lpfc_fdmi_set_attr_u32(attr, RPRT_MAX_FRAME_SIZE,2931			(((uint32_t)hsp->cmn.bbRcvSizeMsb & 0x0F) << 8) |2932			  (uint32_t)hsp->cmn.bbRcvSizeLsb);2933}2934 2935static int2936lpfc_fdmi_port_attr_os_devname(struct lpfc_vport *vport, void *attr)2937{2938	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);2939	char buf[64] = { 0 };2940 2941	snprintf(buf, sizeof(buf), "/sys/class/scsi_host/host%d",2942		 shost->host_no);2943 2944	return lpfc_fdmi_set_attr_string(attr, RPRT_OS_DEVICE_NAME, buf);2945}2946 2947static int2948lpfc_fdmi_port_attr_host_name(struct lpfc_vport *vport, void *attr)2949{2950	char buf[64] = { 0 };2951 2952	scnprintf(buf, sizeof(buf), "%s", vport->phba->os_host_name);2953 2954	return lpfc_fdmi_set_attr_string(attr, RPRT_HOST_NAME, buf);2955}2956 2957static int2958lpfc_fdmi_port_attr_wwnn(struct lpfc_vport *vport, void *attr)2959{2960	return lpfc_fdmi_set_attr_wwn(attr, RPRT_NODENAME,2961			&vport->fc_sparam.nodeName);2962}2963 2964static int2965lpfc_fdmi_port_attr_wwpn(struct lpfc_vport *vport, void *attr)2966{2967	return lpfc_fdmi_set_attr_wwn(attr, RPRT_PORTNAME,2968			&vport->fc_sparam.portName);2969}2970 2971static int2972lpfc_fdmi_port_attr_symbolic_name(struct lpfc_vport *vport, void *attr)2973{2974	char buf[256] = { 0 };2975 2976	lpfc_vport_symbolic_port_name(vport, buf, sizeof(buf));2977 2978	return lpfc_fdmi_set_attr_string(attr, RPRT_SYM_PORTNAME, buf);2979}2980 2981static int2982lpfc_fdmi_port_attr_port_type(struct lpfc_vport *vport, void *attr)2983{2984	struct lpfc_hba *phba = vport->phba;2985 2986	return lpfc_fdmi_set_attr_u32(attr, RPRT_PORT_TYPE,2987			(phba->fc_topology == LPFC_TOPOLOGY_LOOP) ?2988				LPFC_FDMI_PORTTYPE_NLPORT :2989				LPFC_FDMI_PORTTYPE_NPORT);2990}2991 2992static int2993lpfc_fdmi_port_attr_class(struct lpfc_vport *vport, void *attr)2994{2995	return lpfc_fdmi_set_attr_u32(attr, RPRT_SUPPORTED_CLASS,2996			FC_COS_CLASS2 | FC_COS_CLASS3);2997}2998 2999static int3000lpfc_fdmi_port_attr_fabric_wwpn(struct lpfc_vport *vport, void *attr)3001{3002	return lpfc_fdmi_set_attr_wwn(attr, RPRT_FABRICNAME,3003			&vport->fabric_portname);3004}3005 3006static int3007lpfc_fdmi_port_attr_active_fc4type(struct lpfc_vport *vport, void *attr)3008{3009	struct lpfc_hba *phba = vport->phba;3010	u32 fc4types;3011 3012	fc4types = (ATTR_FC4_CT | ATTR_FC4_FCP);3013 3014	/* Check to see if NVME is configured or not */3015	if (vport == phba->pport &&3016	    phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME)3017		fc4types |= ATTR_FC4_NVME;3018 3019	return lpfc_fdmi_set_attr_fc4types(attr, RPRT_ACTIVE_FC4_TYPES,3020			fc4types);3021}3022 3023static int3024lpfc_fdmi_port_attr_port_state(struct lpfc_vport *vport, void *attr)3025{3026	return lpfc_fdmi_set_attr_u32(attr, RPRT_PORT_STATE,3027			LPFC_FDMI_PORTSTATE_ONLINE);3028}3029 3030static int3031lpfc_fdmi_port_attr_num_disc(struct lpfc_vport *vport, void *attr)3032{3033	vport->fdmi_num_disc = lpfc_find_map_node(vport);3034 3035	return lpfc_fdmi_set_attr_u32(attr, RPRT_DISC_PORT,3036			vport->fdmi_num_disc);3037}3038 3039static int3040lpfc_fdmi_port_attr_nportid(struct lpfc_vport *vport, void *attr)3041{3042	return lpfc_fdmi_set_attr_u32(attr, RPRT_PORT_ID, vport->fc_myDID);3043}3044 3045static int3046lpfc_fdmi_smart_attr_service(struct lpfc_vport *vport, void *attr)3047{3048	return lpfc_fdmi_set_attr_string(attr, RPRT_SMART_SERVICE,3049			"Smart SAN Initiator");3050}3051 3052static int3053lpfc_fdmi_smart_attr_guid(struct lpfc_vport *vport, void *attr)3054{3055	return lpfc_fdmi_set_attr_fullwwn(attr, RPRT_SMART_GUID,3056			&vport->fc_sparam.nodeName,3057			&vport->fc_sparam.portName);3058}3059 3060static int3061lpfc_fdmi_smart_attr_version(struct lpfc_vport *vport, void *attr)3062{3063	return lpfc_fdmi_set_attr_string(attr, RPRT_SMART_VERSION,3064			"Smart SAN Version 2.0");3065}3066 3067static int3068lpfc_fdmi_smart_attr_model(struct lpfc_vport *vport, void *attr)3069{3070	struct lpfc_hba *phba = vport->phba;3071 3072	return lpfc_fdmi_set_attr_string(attr, RPRT_SMART_MODEL,3073			phba->ModelName);3074}3075 3076static int3077lpfc_fdmi_smart_attr_port_info(struct lpfc_vport *vport, void *attr)3078{3079	/* SRIOV (type 3) is not supported */3080 3081	return lpfc_fdmi_set_attr_u32(attr, RPRT_SMART_PORT_INFO,3082			(vport->vpi) ?  2 /* NPIV */ : 1 /* Physical */);3083}3084 3085static int3086lpfc_fdmi_smart_attr_qos(struct lpfc_vport *vport, void *attr)3087{3088	return lpfc_fdmi_set_attr_u32(attr, RPRT_SMART_QOS, 0);3089}3090 3091static int3092lpfc_fdmi_smart_attr_security(struct lpfc_vport *vport, void *attr)3093{3094	return lpfc_fdmi_set_attr_u32(attr, RPRT_SMART_SECURITY, 1);3095}3096 3097static int3098lpfc_fdmi_vendor_attr_mi(struct lpfc_vport *vport, void *attr)3099{3100	struct lpfc_hba *phba = vport->phba;3101	char buf[32] = { 0 };3102 3103	sprintf(buf, "ELXE2EM:%04d", phba->sli4_hba.pc_sli4_params.mi_ver);3104 3105	return lpfc_fdmi_set_attr_string(attr, RPRT_VENDOR_MI, buf);3106}3107 3108/* RHBA attribute jump table */3109static int (*lpfc_fdmi_hba_action[])3110	(struct lpfc_vport *vport, void *attrbuf) = {3111	/* Action routine                 Mask bit     Attribute type */3112	lpfc_fdmi_hba_attr_wwnn,	  /* bit0     RHBA_NODENAME           */3113	lpfc_fdmi_hba_attr_manufacturer,  /* bit1     RHBA_MANUFACTURER       */3114	lpfc_fdmi_hba_attr_sn,		  /* bit2     RHBA_SERIAL_NUMBER      */3115	lpfc_fdmi_hba_attr_model,	  /* bit3     RHBA_MODEL              */3116	lpfc_fdmi_hba_attr_description,	  /* bit4     RHBA_MODEL_DESCRIPTION  */3117	lpfc_fdmi_hba_attr_hdw_ver,	  /* bit5     RHBA_HARDWARE_VERSION   */3118	lpfc_fdmi_hba_attr_drvr_ver,	  /* bit6     RHBA_DRIVER_VERSION     */3119	lpfc_fdmi_hba_attr_rom_ver,	  /* bit7     RHBA_OPTION_ROM_VERSION */3120	lpfc_fdmi_hba_attr_fmw_ver,	  /* bit8     RHBA_FIRMWARE_VERSION   */3121	lpfc_fdmi_hba_attr_os_ver,	  /* bit9     RHBA_OS_NAME_VERSION    */3122	lpfc_fdmi_hba_attr_ct_len,	  /* bit10    RHBA_MAX_CT_PAYLOAD_LEN */3123	lpfc_fdmi_hba_attr_symbolic_name, /* bit11    RHBA_SYM_NODENAME       */3124	lpfc_fdmi_hba_attr_vendor_info,	  /* bit12    RHBA_VENDOR_INFO        */3125	lpfc_fdmi_hba_attr_num_ports,	  /* bit13    RHBA_NUM_PORTS          */3126	lpfc_fdmi_hba_attr_fabric_wwnn,	  /* bit14    RHBA_FABRIC_WWNN        */3127	lpfc_fdmi_hba_attr_bios_ver,	  /* bit15    RHBA_BIOS_VERSION       */3128	lpfc_fdmi_hba_attr_bios_state,	  /* bit16    RHBA_BIOS_STATE         */3129	lpfc_fdmi_hba_attr_vendor_id,	  /* bit17    RHBA_VENDOR_ID          */3130};3131 3132/* RPA / RPRT attribute jump table */3133static int (*lpfc_fdmi_port_action[])3134	(struct lpfc_vport *vport, void *attrbuf) = {3135	/* Action routine                   Mask bit   Attribute type */3136	lpfc_fdmi_port_attr_fc4type,        /* bit0   RPRT_SUPPORT_FC4_TYPES  */3137	lpfc_fdmi_port_attr_support_speed,  /* bit1   RPRT_SUPPORTED_SPEED    */3138	lpfc_fdmi_port_attr_speed,          /* bit2   RPRT_PORT_SPEED         */3139	lpfc_fdmi_port_attr_max_frame,      /* bit3   RPRT_MAX_FRAME_SIZE     */3140	lpfc_fdmi_port_attr_os_devname,     /* bit4   RPRT_OS_DEVICE_NAME     */3141	lpfc_fdmi_port_attr_host_name,      /* bit5   RPRT_HOST_NAME          */3142	lpfc_fdmi_port_attr_wwnn,           /* bit6   RPRT_NODENAME           */3143	lpfc_fdmi_port_attr_wwpn,           /* bit7   RPRT_PORTNAME           */3144	lpfc_fdmi_port_attr_symbolic_name,  /* bit8   RPRT_SYM_PORTNAME       */3145	lpfc_fdmi_port_attr_port_type,      /* bit9   RPRT_PORT_TYPE          */3146	lpfc_fdmi_port_attr_class,          /* bit10  RPRT_SUPPORTED_CLASS    */3147	lpfc_fdmi_port_attr_fabric_wwpn,    /* bit11  RPRT_FABRICNAME         */3148	lpfc_fdmi_port_attr_active_fc4type, /* bit12  RPRT_ACTIVE_FC4_TYPES   */3149	lpfc_fdmi_port_attr_port_state,     /* bit13  RPRT_PORT_STATE         */3150	lpfc_fdmi_port_attr_num_disc,       /* bit14  RPRT_DISC_PORT          */3151	lpfc_fdmi_port_attr_nportid,        /* bit15  RPRT_PORT_ID            */3152	lpfc_fdmi_smart_attr_service,       /* bit16  RPRT_SMART_SERVICE      */3153	lpfc_fdmi_smart_attr_guid,          /* bit17  RPRT_SMART_GUID         */3154	lpfc_fdmi_smart_attr_version,       /* bit18  RPRT_SMART_VERSION      */3155	lpfc_fdmi_smart_attr_model,         /* bit19  RPRT_SMART_MODEL        */3156	lpfc_fdmi_smart_attr_port_info,     /* bit20  RPRT_SMART_PORT_INFO    */3157	lpfc_fdmi_smart_attr_qos,           /* bit21  RPRT_SMART_QOS          */3158	lpfc_fdmi_smart_attr_security,      /* bit22  RPRT_SMART_SECURITY     */3159	lpfc_fdmi_vendor_attr_mi,           /* bit23  RPRT_VENDOR_MI          */3160};3161 3162/**3163 * lpfc_fdmi_cmd - Build and send a FDMI cmd to the specified NPort3164 * @vport: pointer to a host virtual N_Port data structure.3165 * @ndlp: ndlp to send FDMI cmd to (if NULL use FDMI_DID)3166 * @cmdcode: FDMI command to send3167 * @new_mask: Mask of HBA or PORT Attributes to send3168 *3169 * Builds and sends a FDMI command using the CT subsystem.3170 */3171int3172lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,3173	      int cmdcode, uint32_t new_mask)3174{3175	struct lpfc_hba *phba = vport->phba;3176	struct lpfc_dmabuf *rq, *rsp;3177	struct lpfc_sli_ct_request *CtReq;3178	struct ulp_bde64_le *bde;3179	uint32_t bit_pos;3180	uint32_t size, addsz;3181	uint32_t rsp_size;3182	uint32_t mask;3183	struct lpfc_fdmi_reg_hba *rh;3184	struct lpfc_fdmi_port_entry *pe;3185	struct lpfc_fdmi_reg_portattr *pab = NULL, *base = NULL;3186	struct lpfc_fdmi_attr_block *ab = NULL;3187	int  (*func)(struct lpfc_vport *vport, void *attrbuf);3188	void (*cmpl)(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,3189		     struct lpfc_iocbq *rspiocb);3190 3191	if (!ndlp)3192		return 0;3193 3194	cmpl = lpfc_cmpl_ct_disc_fdmi; /* called from discovery */3195 3196	/* fill in BDEs for command */3197	/* Allocate buffer for command payload */3198	rq = kmalloc(sizeof(*rq), GFP_KERNEL);3199	if (!rq)3200		goto fdmi_cmd_exit;3201 3202	rq->virt = lpfc_mbuf_alloc(phba, 0, &rq->phys);3203	if (!rq->virt)3204		goto fdmi_cmd_free_rq;3205 3206	/* Allocate buffer for Buffer ptr list */3207	rsp = kmalloc(sizeof(*rsp), GFP_KERNEL);3208	if (!rsp)3209		goto fdmi_cmd_free_rqvirt;3210 3211	rsp->virt = lpfc_mbuf_alloc(phba, 0, &rsp->phys);3212	if (!rsp->virt)3213		goto fdmi_cmd_free_rsp;3214 3215	INIT_LIST_HEAD(&rq->list);3216	INIT_LIST_HEAD(&rsp->list);3217 3218	/* mbuf buffers are 1K in length - aka LPFC_BPL_SIZE */3219	memset(rq->virt, 0, LPFC_BPL_SIZE);3220	rsp_size = LPFC_BPL_SIZE;3221 3222	/* FDMI request */3223	lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,3224			 "0218 FDMI Request x%x mask x%x Data: x%x x%lx x%x\n",3225			 cmdcode, new_mask, vport->fdmi_port_mask,3226			 vport->fc_flag, vport->port_state);3227 3228	CtReq = (struct lpfc_sli_ct_request *)rq->virt;3229 3230	/* First populate the CT_IU preamble */3231	CtReq->RevisionId.bits.Revision = SLI_CT_REVISION;3232	CtReq->RevisionId.bits.InId = 0;3233 3234	CtReq->FsType = SLI_CT_MANAGEMENT_SERVICE;3235	CtReq->FsSubType = SLI_CT_FDMI_Subtypes;3236 3237	CtReq->CommandResponse.bits.CmdRsp = cpu_to_be16(cmdcode);3238 3239	size = 0;3240 3241	/* Next fill in the specific FDMI cmd information */3242	switch (cmdcode) {3243	case SLI_MGMT_RHAT:3244	case SLI_MGMT_RHBA:3245		rh = (struct lpfc_fdmi_reg_hba *)&CtReq->un;3246		/* HBA Identifier */3247		memcpy(&rh->hi.PortName, &phba->pport->fc_sparam.portName,3248		       sizeof(struct lpfc_name));3249		size += sizeof(struct lpfc_fdmi_hba_ident);3250 3251		if (cmdcode == SLI_MGMT_RHBA) {3252			/* Registered Port List */3253			/* One entry (port) per adapter */3254			rh->rpl.EntryCnt = cpu_to_be32(1);3255			memcpy(&rh->rpl.pe.PortName,3256			       &phba->pport->fc_sparam.portName,3257			       sizeof(struct lpfc_name));3258			size += sizeof(struct lpfc_fdmi_reg_port_list);3259		}3260 3261		ab = (struct lpfc_fdmi_attr_block *)((uint8_t *)rh + size);3262		ab->EntryCnt = 0;3263		size += FOURBYTES;	/* add length of EntryCnt field */3264 3265		bit_pos = 0;3266		if (new_mask)3267			mask = new_mask;3268		else3269			mask = vport->fdmi_hba_mask;3270 3271		/* Mask will dictate what attributes to build in the request */3272		while (mask) {3273			if (mask & 0x1) {3274				func = lpfc_fdmi_hba_action[bit_pos];3275				addsz = func(vport, ((uint8_t *)rh + size));3276				if (addsz) {3277					ab->EntryCnt++;3278					size += addsz;3279				}3280				/* check if another attribute fits */3281				if ((size + FDMI_MAX_ATTRLEN) >3282				    (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))3283					goto hba_out;3284			}3285			mask = mask >> 1;3286			bit_pos++;3287		}3288hba_out:3289		ab->EntryCnt = cpu_to_be32(ab->EntryCnt);3290		/* Total size */3291		size += GID_REQUEST_SZ - 4;3292		break;3293 3294	case SLI_MGMT_RPRT:3295		if (vport->port_type != LPFC_PHYSICAL_PORT) {3296			ndlp = lpfc_findnode_did(phba->pport, FDMI_DID);3297			if (!ndlp)3298				return 0;3299		}3300		fallthrough;3301	case SLI_MGMT_RPA:3302		/* Store base ptr right after preamble */3303		base = (struct lpfc_fdmi_reg_portattr *)&CtReq->un;3304 3305		if (cmdcode == SLI_MGMT_RPRT) {3306			rh = (struct lpfc_fdmi_reg_hba *)base;3307			/* HBA Identifier */3308			memcpy(&rh->hi.PortName,3309			       &phba->pport->fc_sparam.portName,3310			       sizeof(struct lpfc_name));3311			pab = (struct lpfc_fdmi_reg_portattr *)3312				((uint8_t *)base + sizeof(struct lpfc_name));3313			size += sizeof(struct lpfc_name);3314		} else {3315			pab = base;3316		}3317 3318		memcpy((uint8_t *)&pab->PortName,3319		       (uint8_t *)&vport->fc_sparam.portName,3320		       sizeof(struct lpfc_name));3321		pab->ab.EntryCnt = 0;3322		/* add length of name and EntryCnt field */3323		size += sizeof(struct lpfc_name) + FOURBYTES;3324 3325		bit_pos = 0;3326		if (new_mask)3327			mask = new_mask;3328		else3329			mask = vport->fdmi_port_mask;3330 3331		/* Mask will dictate what attributes to build in the request */3332		while (mask) {3333			if (mask & 0x1) {3334				func = lpfc_fdmi_port_action[bit_pos];3335				addsz = func(vport, ((uint8_t *)base + size));3336				if (addsz) {3337					pab->ab.EntryCnt++;3338					size += addsz;3339				}3340				/* check if another attribute fits */3341				if ((size + FDMI_MAX_ATTRLEN) >3342				    (LPFC_BPL_SIZE - LPFC_CT_PREAMBLE))3343					goto port_out;3344			}3345			mask = mask >> 1;3346			bit_pos++;3347		}3348port_out:3349		pab->ab.EntryCnt = cpu_to_be32(pab->ab.EntryCnt);3350		size += GID_REQUEST_SZ - 4;3351		break;3352 3353	case SLI_MGMT_GHAT:3354	case SLI_MGMT_GRPL:3355		rsp_size = FC_MAX_NS_RSP;3356		fallthrough;3357	case SLI_MGMT_DHBA:3358	case SLI_MGMT_DHAT:3359		pe = (struct lpfc_fdmi_port_entry *)&CtReq->un;3360		memcpy((uint8_t *)&pe->PortName,3361		       (uint8_t *)&vport->fc_sparam.portName,3362		       sizeof(struct lpfc_name));3363		size = GID_REQUEST_SZ - 4 + sizeof(struct lpfc_name);3364		break;3365 3366	case SLI_MGMT_GPAT:3367	case SLI_MGMT_GPAS:3368		rsp_size = FC_MAX_NS_RSP;3369		fallthrough;3370	case SLI_MGMT_DPRT:3371		if (vport->port_type != LPFC_PHYSICAL_PORT) {3372			ndlp = lpfc_findnode_did(phba->pport, FDMI_DID);3373			if (!ndlp)3374				return 0;3375		}3376		fallthrough;3377	case SLI_MGMT_DPA:3378		pe = (struct lpfc_fdmi_port_entry *)&CtReq->un;3379		memcpy((uint8_t *)&pe->PortName,3380		       (uint8_t *)&vport->fc_sparam.portName,3381		       sizeof(struct lpfc_name));3382		size = GID_REQUEST_SZ - 4 + sizeof(struct lpfc_name);3383		break;3384	case SLI_MGMT_GRHL:3385		size = GID_REQUEST_SZ - 4;3386		break;3387	default:3388		lpfc_printf_vlog(vport, KERN_WARNING, LOG_DISCOVERY,3389				 "0298 FDMI cmdcode x%x not supported\n",3390				 cmdcode);3391		goto fdmi_cmd_free_rspvirt;3392	}3393	CtReq->CommandResponse.bits.Size = cpu_to_be16(rsp_size);3394 3395	bde = (struct ulp_bde64_le *)rsp->virt;3396	bde->addr_high = cpu_to_le32(putPaddrHigh(rq->phys));3397	bde->addr_low = cpu_to_le32(putPaddrLow(rq->phys));3398	bde->type_size = cpu_to_le32(ULP_BDE64_TYPE_BDE_64 <<3399				     ULP_BDE64_TYPE_SHIFT);3400	bde->type_size |= cpu_to_le32(size);3401 3402	/*3403	 * The lpfc_ct_cmd/lpfc_get_req shall increment ndlp reference count3404	 * to hold ndlp reference for the corresponding callback function.3405	 */3406	if (!lpfc_ct_cmd(vport, rq, rsp, ndlp, cmpl, rsp_size, 0))3407		return 0;3408 3409fdmi_cmd_free_rspvirt:3410	lpfc_mbuf_free(phba, rsp->virt, rsp->phys);3411fdmi_cmd_free_rsp:3412	kfree(rsp);3413fdmi_cmd_free_rqvirt:3414	lpfc_mbuf_free(phba, rq->virt, rq->phys);3415fdmi_cmd_free_rq:3416	kfree(rq);3417fdmi_cmd_exit:3418	/* Issue FDMI request failed */3419	lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,3420			 "0244 Issue FDMI request failed Data: x%x\n",3421			 cmdcode);3422	return 1;3423}3424 3425/**3426 * lpfc_delayed_disc_tmo - Timeout handler for delayed discovery timer.3427 * @t: Context object of the timer.3428 *3429 * This function set the WORKER_DELAYED_DISC_TMO flag and wake up3430 * the worker thread.3431 **/3432void3433lpfc_delayed_disc_tmo(struct timer_list *t)3434{3435	struct lpfc_vport *vport = from_timer(vport, t, delayed_disc_tmo);3436	struct lpfc_hba   *phba = vport->phba;3437	uint32_t tmo_posted;3438	unsigned long iflag;3439 3440	spin_lock_irqsave(&vport->work_port_lock, iflag);3441	tmo_posted = vport->work_port_events & WORKER_DELAYED_DISC_TMO;3442	if (!tmo_posted)3443		vport->work_port_events |= WORKER_DELAYED_DISC_TMO;3444	spin_unlock_irqrestore(&vport->work_port_lock, iflag);3445 3446	if (!tmo_posted)3447		lpfc_worker_wake_up(phba);3448	return;3449}3450 3451/**3452 * lpfc_delayed_disc_timeout_handler - Function called by worker thread to3453 *      handle delayed discovery.3454 * @vport: pointer to a host virtual N_Port data structure.3455 *3456 * This function start nport discovery of the vport.3457 **/3458void3459lpfc_delayed_disc_timeout_handler(struct lpfc_vport *vport)3460{3461	if (!test_and_clear_bit(FC_DISC_DELAYED, &vport->fc_flag))3462		return;3463 3464	lpfc_do_scr_ns_plogi(vport->phba, vport);3465}3466 3467void3468lpfc_decode_firmware_rev(struct lpfc_hba *phba, char *fwrevision, int flag)3469{3470	struct lpfc_sli *psli = &phba->sli;3471	lpfc_vpd_t *vp = &phba->vpd;3472	uint32_t b1, b2, b3, b4, i, rev;3473	char c;3474	uint32_t *ptr, str[4];3475	uint8_t *fwname;3476 3477	if (phba->sli_rev == LPFC_SLI_REV4)3478		snprintf(fwrevision, FW_REV_STR_SIZE, "%s", vp->rev.opFwName);3479	else if (vp->rev.rBit) {3480		if (psli->sli_flag & LPFC_SLI_ACTIVE)3481			rev = vp->rev.sli2FwRev;3482		else3483			rev = vp->rev.sli1FwRev;3484 3485		b1 = (rev & 0x0000f000) >> 12;3486		b2 = (rev & 0x00000f00) >> 8;3487		b3 = (rev & 0x000000c0) >> 6;3488		b4 = (rev & 0x00000030) >> 4;3489 3490		switch (b4) {3491		case 0:3492			c = 'N';3493			break;3494		case 1:3495			c = 'A';3496			break;3497		case 2:3498			c = 'B';3499			break;3500		case 3:3501			c = 'X';3502			break;3503		default:3504			c = 0;3505			break;3506		}3507		b4 = (rev & 0x0000000f);3508 3509		if (psli->sli_flag & LPFC_SLI_ACTIVE)3510			fwname = vp->rev.sli2FwName;3511		else3512			fwname = vp->rev.sli1FwName;3513 3514		for (i = 0; i < 16; i++)3515			if (fwname[i] == 0x20)3516				fwname[i] = 0;3517 3518		ptr = (uint32_t*)fwname;3519 3520		for (i = 0; i < 3; i++)3521			str[i] = be32_to_cpu(*ptr++);3522 3523		if (c == 0) {3524			if (flag)3525				sprintf(fwrevision, "%d.%d%d (%s)",3526					b1, b2, b3, (char *)str);3527			else3528				sprintf(fwrevision, "%d.%d%d", b1,3529					b2, b3);3530		} else {3531			if (flag)3532				sprintf(fwrevision, "%d.%d%d%c%d (%s)",3533					b1, b2, b3, c,3534					b4, (char *)str);3535			else3536				sprintf(fwrevision, "%d.%d%d%c%d",3537					b1, b2, b3, c, b4);3538		}3539	} else {3540		rev = vp->rev.smFwRev;3541 3542		b1 = (rev & 0xff000000) >> 24;3543		b2 = (rev & 0x00f00000) >> 20;3544		b3 = (rev & 0x000f0000) >> 16;3545		c  = (rev & 0x0000ff00) >> 8;3546		b4 = (rev & 0x000000ff);3547 3548		sprintf(fwrevision, "%d.%d%d%c%d", b1, b2, b3, c, b4);3549	}3550	return;3551}3552 3553static void3554lpfc_cmpl_ct_cmd_vmid(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,3555		      struct lpfc_iocbq *rspiocb)3556{3557	struct lpfc_vport *vport = cmdiocb->vport;3558	struct lpfc_dmabuf *inp = cmdiocb->cmd_dmabuf;3559	struct lpfc_dmabuf *outp = cmdiocb->rsp_dmabuf;3560	struct lpfc_sli_ct_request *ctcmd = inp->virt;3561	struct lpfc_sli_ct_request *ctrsp = outp->virt;3562	__be16 rsp = ctrsp->CommandResponse.bits.CmdRsp;3563	struct app_id_object *app;3564	struct lpfc_nodelist *ndlp = cmdiocb->ndlp;3565	u32 cmd, hash, bucket;3566	struct lpfc_vmid *vmp, *cur;3567	u8 *data = outp->virt;3568	int i;3569 3570	cmd = be16_to_cpu(ctcmd->CommandResponse.bits.CmdRsp);3571	if (cmd == SLI_CTAS_DALLAPP_ID)3572		lpfc_ct_free_iocb(phba, cmdiocb);3573 3574	if (lpfc_els_chk_latt(vport) || get_job_ulpstatus(phba, rspiocb)) {3575		if (cmd != SLI_CTAS_DALLAPP_ID)3576			goto free_res;3577	}3578	/* Check for a CT LS_RJT response */3579	if (be16_to_cpu(rsp) == SLI_CT_RESPONSE_FS_RJT) {3580		if (cmd != SLI_CTAS_DALLAPP_ID)3581			lpfc_printf_vlog(vport, KERN_DEBUG, LOG_DISCOVERY,3582					 "3306 VMID FS_RJT Data: x%x x%x x%x\n",3583					 cmd, ctrsp->ReasonCode,3584					 ctrsp->Explanation);3585		if ((cmd != SLI_CTAS_DALLAPP_ID) ||3586		    (ctrsp->ReasonCode != SLI_CT_UNABLE_TO_PERFORM_REQ) ||3587		    (ctrsp->Explanation != SLI_CT_APP_ID_NOT_AVAILABLE)) {3588			/* If DALLAPP_ID failed retry later */3589			if (cmd == SLI_CTAS_DALLAPP_ID)3590				set_bit(FC_DEREGISTER_ALL_APP_ID,3591					&vport->load_flag);3592			goto free_res;3593		}3594	}3595 3596	switch (cmd) {3597	case SLI_CTAS_RAPP_IDENT:3598		app = (struct app_id_object *)(RAPP_IDENT_OFFSET + data);3599		lpfc_printf_vlog(vport, KERN_DEBUG, LOG_DISCOVERY,3600				 "6712 RAPP_IDENT app id %d  port id x%x id "3601				 "len %d\n", be32_to_cpu(app->app_id),3602				 be32_to_cpu(app->port_id),3603				 app->obj.entity_id_len);3604 3605		if (app->obj.entity_id_len == 0 || app->port_id == 0)3606			goto free_res;3607 3608		hash = lpfc_vmid_hash_fn(app->obj.entity_id,3609					 app->obj.entity_id_len);3610		vmp = lpfc_get_vmid_from_hashtable(vport, hash,3611						  app->obj.entity_id);3612		if (vmp) {3613			write_lock(&vport->vmid_lock);3614			vmp->un.app_id = be32_to_cpu(app->app_id);3615			vmp->flag |= LPFC_VMID_REGISTERED;3616			vmp->flag &= ~LPFC_VMID_REQ_REGISTER;3617			write_unlock(&vport->vmid_lock);3618			/* Set IN USE flag */3619			vport->vmid_flag |= LPFC_VMID_IN_USE;3620		} else {3621			lpfc_printf_vlog(vport, KERN_DEBUG, LOG_DISCOVERY,3622					 "6901 No entry found %s hash %d\n",3623					 app->obj.entity_id, hash);3624		}3625		break;3626	case SLI_CTAS_DAPP_IDENT:3627		app = (struct app_id_object *)(DAPP_IDENT_OFFSET + data);3628		lpfc_printf_vlog(vport, KERN_DEBUG, LOG_DISCOVERY,3629				 "6713 DAPP_IDENT app id %d  port id x%x\n",3630				 be32_to_cpu(app->app_id),3631				 be32_to_cpu(app->port_id));3632		break;3633	case SLI_CTAS_DALLAPP_ID:3634		lpfc_printf_vlog(vport, KERN_DEBUG, LOG_DISCOVERY,3635				 "8856 Deregistered all app ids\n");3636		read_lock(&vport->vmid_lock);3637		for (i = 0; i < phba->cfg_max_vmid; i++) {3638			vmp = &vport->vmid[i];3639			if (vmp->flag != LPFC_VMID_SLOT_FREE)3640				memset(vmp, 0, sizeof(struct lpfc_vmid));3641		}3642		read_unlock(&vport->vmid_lock);3643		/* for all elements in the hash table */3644		if (!hash_empty(vport->hash_table))3645			hash_for_each(vport->hash_table, bucket, cur, hnode)3646				hash_del(&cur->hnode);3647		set_bit(FC_ALLOW_VMID, &vport->load_flag);3648		break;3649	default:3650		lpfc_printf_vlog(vport, KERN_DEBUG, LOG_DISCOVERY,3651				 "8857 Invalid command code\n");3652	}3653free_res:3654	lpfc_ct_free_iocb(phba, cmdiocb);3655	lpfc_nlp_put(ndlp);3656}3657 3658/**3659 * lpfc_vmid_cmd - Build and send a FDMI cmd to the specified NPort3660 * @vport: pointer to a host virtual N_Port data structure.3661 * @cmdcode: application server command code to send3662 * @vmid: pointer to vmid info structure3663 *3664 * Builds and sends a FDMI command using the CT subsystem.3665 */3666int3667lpfc_vmid_cmd(struct lpfc_vport *vport,3668	      int cmdcode, struct lpfc_vmid *vmid)3669{3670	struct lpfc_hba *phba = vport->phba;3671	struct lpfc_dmabuf *mp, *bmp;3672	struct lpfc_sli_ct_request *ctreq;3673	struct ulp_bde64 *bpl;3674	u32 size;3675	u32 rsp_size;3676	u8 *data;3677	struct lpfc_vmid_rapp_ident_list *rap;3678	struct lpfc_vmid_dapp_ident_list *dap;3679	u8 retry = 0;3680	struct lpfc_nodelist *ndlp;3681 3682	void (*cmpl)(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,3683		     struct lpfc_iocbq *rspiocb);3684 3685	ndlp = lpfc_findnode_did(vport, FDMI_DID);3686	if (!ndlp || ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)3687		return 0;3688 3689	cmpl = lpfc_cmpl_ct_cmd_vmid;3690 3691	/* fill in BDEs for command */3692	/* Allocate buffer for command payload */3693	mp = kmalloc(sizeof(*mp), GFP_KERNEL);3694	if (!mp)3695		goto vmid_free_mp_exit;3696 3697	mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);3698	if (!mp->virt)3699		goto vmid_free_mp_virt_exit;3700 3701	/* Allocate buffer for Buffer ptr list */3702	bmp = kmalloc(sizeof(*bmp), GFP_KERNEL);3703	if (!bmp)3704		goto vmid_free_bmp_exit;3705 3706	bmp->virt = lpfc_mbuf_alloc(phba, 0, &bmp->phys);3707	if (!bmp->virt)3708		goto vmid_free_bmp_virt_exit;3709 3710	INIT_LIST_HEAD(&mp->list);3711	INIT_LIST_HEAD(&bmp->list);3712 3713	lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,3714			 "3275 VMID Request Data: x%lx x%x x%x\n",3715			 vport->fc_flag, vport->port_state, cmdcode);3716	ctreq = (struct lpfc_sli_ct_request *)mp->virt;3717	data = mp->virt;3718	/* First populate the CT_IU preamble */3719	memset(data, 0, LPFC_BPL_SIZE);3720	ctreq->RevisionId.bits.Revision = SLI_CT_REVISION;3721	ctreq->RevisionId.bits.InId = 0;3722 3723	ctreq->FsType = SLI_CT_MANAGEMENT_SERVICE;3724	ctreq->FsSubType = SLI_CT_APP_SEV_Subtypes;3725 3726	ctreq->CommandResponse.bits.CmdRsp = cpu_to_be16(cmdcode);3727	rsp_size = LPFC_BPL_SIZE;3728	size = 0;3729 3730	switch (cmdcode) {3731	case SLI_CTAS_RAPP_IDENT:3732		lpfc_printf_vlog(vport, KERN_DEBUG, LOG_DISCOVERY,3733				 "1329 RAPP_IDENT for %s\n", vmid->host_vmid);3734		ctreq->un.PortID = cpu_to_be32(vport->fc_myDID);3735		rap = (struct lpfc_vmid_rapp_ident_list *)3736			(DAPP_IDENT_OFFSET + data);3737		rap->no_of_objects = cpu_to_be32(1);3738		rap->obj[0].entity_id_len = vmid->vmid_len;3739		memcpy(rap->obj[0].entity_id, vmid->host_vmid, vmid->vmid_len);3740		size = RAPP_IDENT_OFFSET +3741		       struct_size(rap, obj, be32_to_cpu(rap->no_of_objects));3742		retry = 1;3743		break;3744 3745	case SLI_CTAS_GALLAPPIA_ID:3746		ctreq->un.PortID = cpu_to_be32(vport->fc_myDID);3747		size = GALLAPPIA_ID_SIZE;3748		break;3749 3750	case SLI_CTAS_DAPP_IDENT:3751		lpfc_printf_vlog(vport, KERN_DEBUG, LOG_DISCOVERY,3752				 "1469 DAPP_IDENT for %s\n", vmid->host_vmid);3753		ctreq->un.PortID = cpu_to_be32(vport->fc_myDID);3754		dap = (struct lpfc_vmid_dapp_ident_list *)3755			(DAPP_IDENT_OFFSET + data);3756		dap->no_of_objects = cpu_to_be32(1);3757		dap->obj[0].entity_id_len = vmid->vmid_len;3758		memcpy(dap->obj[0].entity_id, vmid->host_vmid, vmid->vmid_len);3759		size = DAPP_IDENT_OFFSET +3760		       struct_size(dap, obj, be32_to_cpu(dap->no_of_objects));3761		write_lock(&vport->vmid_lock);3762		vmid->flag &= ~LPFC_VMID_REGISTERED;3763		write_unlock(&vport->vmid_lock);3764		retry = 1;3765		break;3766 3767	case SLI_CTAS_DALLAPP_ID:3768		ctreq->un.PortID = cpu_to_be32(vport->fc_myDID);3769		size = DALLAPP_ID_SIZE;3770		break;3771 3772	default:3773		lpfc_printf_vlog(vport, KERN_DEBUG, LOG_DISCOVERY,3774				 "7062 VMID cmdcode x%x not supported\n",3775				 cmdcode);3776		goto vmid_free_all_mem;3777	}3778 3779	ctreq->CommandResponse.bits.Size = cpu_to_be16(rsp_size);3780 3781	bpl = (struct ulp_bde64 *)bmp->virt;3782	bpl->addrHigh = putPaddrHigh(mp->phys);3783	bpl->addrLow = putPaddrLow(mp->phys);3784	bpl->tus.f.bdeFlags = 0;3785	bpl->tus.f.bdeSize = size;3786 3787	/* The lpfc_ct_cmd/lpfc_get_req shall increment ndlp reference count3788	 * to hold ndlp reference for the corresponding callback function.3789	 */3790	if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size, retry))3791		return 0;3792 3793 vmid_free_all_mem:3794	lpfc_mbuf_free(phba, bmp->virt, bmp->phys);3795 vmid_free_bmp_virt_exit:3796	kfree(bmp);3797 vmid_free_bmp_exit:3798	lpfc_mbuf_free(phba, mp->virt, mp->phys);3799 vmid_free_mp_virt_exit:3800	kfree(mp);3801 vmid_free_mp_exit:3802 3803	/* Issue CT request failed */3804	lpfc_printf_vlog(vport, KERN_DEBUG, LOG_DISCOVERY,3805			 "3276 VMID CT request failed Data: x%x\n", cmdcode);3806	return -EIO;3807}3808