Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * QLogic Fibre Channel HBA Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * Copyright (c)  2003-2014 QLogic Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6) #include "qla_def.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7) #include "qla_target.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) #include <linux/utsname.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) static int qla2x00_sns_gnn_id(scsi_qla_host_t *, sw_info_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) static int qla2x00_sns_rft_id(scsi_qla_host_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) static int qla2x00_sns_rnn_id(scsi_qla_host_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) static int qla_async_rftid(scsi_qla_host_t *, port_id_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) static int qla_async_rffid(scsi_qla_host_t *, port_id_t *, u8, u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) static int qla_async_rnnid(scsi_qla_host_t *, port_id_t *, u8*);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) static int qla_async_rsnn_nn(scsi_qla_host_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24)  * qla2x00_prep_ms_iocb() - Prepare common MS/CT IOCB fields for SNS CT query.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26)  * @arg: CT arguments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28)  * Returns a pointer to the @vha's ms_iocb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) void *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) qla2x00_prep_ms_iocb(scsi_qla_host_t *vha, struct ct_arg *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 	ms_iocb_entry_t *ms_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 	ms_pkt = (ms_iocb_entry_t *)arg->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 	memset(ms_pkt, 0, sizeof(ms_iocb_entry_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 	ms_pkt->entry_type = MS_IOCB_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 	ms_pkt->entry_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 	SET_TARGET_ID(ha, ms_pkt->loop_id, SIMPLE_NAME_SERVER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 	ms_pkt->control_flags = cpu_to_le16(CF_READ | CF_HEAD_TAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 	ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	ms_pkt->cmd_dsd_count = cpu_to_le16(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 	ms_pkt->total_dsd_count = cpu_to_le16(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 	ms_pkt->rsp_bytecount = cpu_to_le32(arg->rsp_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 	ms_pkt->req_bytecount = cpu_to_le32(arg->req_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	put_unaligned_le64(arg->req_dma, &ms_pkt->req_dsd.address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	ms_pkt->req_dsd.length = ms_pkt->req_bytecount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 	put_unaligned_le64(arg->rsp_dma, &ms_pkt->rsp_dsd.address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 	ms_pkt->rsp_dsd.length = ms_pkt->rsp_bytecount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 	vha->qla_stats.control_requests++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 	return (ms_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61)  * qla24xx_prep_ms_iocb() - Prepare common CT IOCB fields for SNS CT query.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63)  * @arg: CT arguments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65)  * Returns a pointer to the @ha's ms_iocb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) void *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) qla24xx_prep_ms_iocb(scsi_qla_host_t *vha, struct ct_arg *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 	struct ct_entry_24xx *ct_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	ct_pkt = (struct ct_entry_24xx *)arg->iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 	memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 	ct_pkt->entry_type = CT_IOCB_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	ct_pkt->entry_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	ct_pkt->nport_handle = cpu_to_le16(arg->nport_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 	ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	ct_pkt->cmd_dsd_count = cpu_to_le16(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	ct_pkt->rsp_dsd_count = cpu_to_le16(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 	ct_pkt->rsp_byte_count = cpu_to_le32(arg->rsp_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	ct_pkt->cmd_byte_count = cpu_to_le32(arg->req_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	put_unaligned_le64(arg->req_dma, &ct_pkt->dsd[0].address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	ct_pkt->dsd[0].length = ct_pkt->cmd_byte_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	put_unaligned_le64(arg->rsp_dma, &ct_pkt->dsd[1].address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	ct_pkt->dsd[1].length = ct_pkt->rsp_byte_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	ct_pkt->vp_index = vha->vp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	vha->qla_stats.control_requests++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	return (ct_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98)  * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99)  * @p: CT request buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100)  * @cmd: GS command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101)  * @rsp_size: response size in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103)  * Returns a pointer to the intitialized @ct_req.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) static inline struct ct_sns_req *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) qla2x00_prep_ct_req(struct ct_sns_pkt *p, uint16_t cmd, uint16_t rsp_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	memset(p, 0, sizeof(struct ct_sns_pkt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	p->p.req.header.revision = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	p->p.req.header.gs_type = 0xFC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	p->p.req.header.gs_subtype = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	p->p.req.command = cpu_to_be16(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	return &p->p.req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t *ms_pkt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121)     struct ct_sns_rsp *ct_rsp, const char *routine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	uint16_t comp_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	bool lid_is_sns = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	if (ms_pkt->entry_status != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 		ql_dbg(ql_dbg_disc, vha, 0x2031,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 		    "%s failed, error status (%x) on port_id: %02x%02x%02x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 		    routine, ms_pkt->entry_status, vha->d_id.b.domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 		    vha->d_id.b.area, vha->d_id.b.al_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 		if (IS_FWI2_CAPABLE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 			comp_status = le16_to_cpu(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 			    ((struct ct_entry_24xx *)ms_pkt)->comp_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 			comp_status = le16_to_cpu(ms_pkt->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 		switch (comp_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 		case CS_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 		case CS_DATA_UNDERRUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 		case CS_DATA_OVERRUN:		/* Overrun? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 			if (ct_rsp->header.response !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 			    cpu_to_be16(CT_ACCEPT_RESPONSE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 				ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2077,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 				    "%s failed rejected request on port_id: %02x%02x%02x Completion status 0x%x, response 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 				    routine, vha->d_id.b.domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 				    vha->d_id.b.area, vha->d_id.b.al_pa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 				    comp_status, ct_rsp->header.response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 				ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 				    0x2078, ct_rsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 				    offsetof(typeof(*ct_rsp), rsp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 				rval = QLA_INVALID_COMMAND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 				rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 		case CS_PORT_LOGGED_OUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 			if (IS_FWI2_CAPABLE(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 				if (le16_to_cpu(ms_pkt->loop_id.extended) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 				    NPH_SNS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 					lid_is_sns = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 				if (le16_to_cpu(ms_pkt->loop_id.extended) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 				    SIMPLE_NAME_SERVER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 					lid_is_sns = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 			if (lid_is_sns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 				ql_dbg(ql_dbg_async, vha, 0x502b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 					"%s failed, Name server has logged out",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 					routine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 				rval = QLA_NOT_LOGGED_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 				set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 				set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 		case CS_TIMEOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 			rval = QLA_FUNCTION_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 			ql_dbg(ql_dbg_disc, vha, 0x2033,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 			    "%s failed, completion status (%x) on port_id: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 			    "%02x%02x%02x.\n", routine, comp_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 			    vha->d_id.b.domain, vha->d_id.b.area,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 			    vha->d_id.b.al_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193)  * qla2x00_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195)  * @fcport: fcport entry to updated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	int		rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	ms_iocb_entry_t	*ms_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	struct ct_sns_req	*ct_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	struct ct_sns_rsp	*ct_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	struct ct_arg arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	if (IS_QLA2100(ha) || IS_QLA2200(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 		return qla2x00_sns_ga_nxt(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	arg.iocb = ha->ms_iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	arg.req_dma = ha->ct_sns_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	arg.rsp_dma = ha->ct_sns_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	arg.req_size = GA_NXT_REQ_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	arg.rsp_size = GA_NXT_RSP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	arg.nport_handle = NPH_SNS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	/* Issue GA_NXT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	/* Prepare common MS IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	/* Prepare CT request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	ct_req = qla2x00_prep_ct_req(ha->ct_sns, GA_NXT_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	    GA_NXT_RSP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	ct_rsp = &ha->ct_sns->p.rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	/* Prepare CT arguments -- port_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	ct_req->req.port_id.port_id = port_id_to_be_id(fcport->d_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	/* Execute MS IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	    sizeof(ms_iocb_entry_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 		/*EMPTY*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 		ql_dbg(ql_dbg_disc, vha, 0x2062,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 		    "GA_NXT issue IOCB failed (%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	} else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GA_NXT") !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	    QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 		rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 		/* Populate fc_port_t entry. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 		fcport->d_id = be_to_port_id(ct_rsp->rsp.ga_nxt.port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 		memcpy(fcport->node_name, ct_rsp->rsp.ga_nxt.node_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 		    WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 		memcpy(fcport->port_name, ct_rsp->rsp.ga_nxt.port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 		    WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 		fcport->fc4_type = (ct_rsp->rsp.ga_nxt.fc4_types[2] & BIT_0) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 		    FS_FC4TYPE_FCP : FC4_TYPE_OTHER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 		if (ct_rsp->rsp.ga_nxt.port_type != NS_N_PORT_TYPE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 		    ct_rsp->rsp.ga_nxt.port_type != NS_NL_PORT_TYPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 			fcport->d_id.b.domain = 0xf0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 		ql_dbg(ql_dbg_disc, vha, 0x2063,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 		    "GA_NXT entry - nn %8phN pn %8phN "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 		    "port_id=%02x%02x%02x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 		    fcport->node_name, fcport->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 		    fcport->d_id.b.domain, fcport->d_id.b.area,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 		    fcport->d_id.b.al_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) qla2x00_gid_pt_rsp_size(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	return vha->hw->max_fibre_devices * 4 + 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276)  * qla2x00_gid_pt() - SNS scan for fabric devices via GID_PT command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278)  * @list: switch info entries to populate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280)  * NOTE: Non-Nx_Ports are not requested.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) qla2x00_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	int		rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	uint16_t	i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	ms_iocb_entry_t	*ms_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	struct ct_sns_req	*ct_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	struct ct_sns_rsp	*ct_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	struct ct_sns_gid_pt_data *gid_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	uint16_t gid_pt_rsp_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	struct ct_arg arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	if (IS_QLA2100(ha) || IS_QLA2200(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 		return qla2x00_sns_gid_pt(vha, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	gid_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	gid_pt_rsp_size = qla2x00_gid_pt_rsp_size(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	arg.iocb = ha->ms_iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	arg.req_dma = ha->ct_sns_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	arg.rsp_dma = ha->ct_sns_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	arg.req_size = GID_PT_REQ_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	arg.rsp_size = gid_pt_rsp_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	arg.nport_handle = NPH_SNS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	/* Issue GID_PT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	/* Prepare common MS IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	/* Prepare CT request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	ct_req = qla2x00_prep_ct_req(ha->ct_sns, GID_PT_CMD, gid_pt_rsp_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	ct_rsp = &ha->ct_sns->p.rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	/* Prepare CT arguments -- port_type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	ct_req->req.gid_pt.port_type = NS_NX_PORT_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	/* Execute MS IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	    sizeof(ms_iocb_entry_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 		/*EMPTY*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 		ql_dbg(ql_dbg_disc, vha, 0x2055,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 		    "GID_PT issue IOCB failed (%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	} else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GID_PT") !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	    QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 		rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 		/* Set port IDs in switch info list. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 		for (i = 0; i < ha->max_fibre_devices; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 			gid_data = &ct_rsp->rsp.gid_pt.entries[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 			list[i].d_id = be_to_port_id(gid_data->port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 			memset(list[i].fabric_port_name, 0, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 			list[i].fp_speed = PORT_SPEED_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 			/* Last one exit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 			if (gid_data->control_byte & BIT_7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 				list[i].d_id.b.rsvd_1 = gid_data->control_byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 		 * If we've used all available slots, then the switch is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 		 * reporting back more devices than we can handle with this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 		 * single call.  Return a failed status, and let GA_NXT handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 		 * the overload.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 		if (i == ha->max_fibre_devices)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 			rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362)  * qla2x00_gpn_id() - SNS Get Port Name (GPN_ID) query.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364)  * @list: switch info entries to populate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) qla2x00_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	int		rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	uint16_t	i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	ms_iocb_entry_t	*ms_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	struct ct_sns_req	*ct_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	struct ct_sns_rsp	*ct_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	struct ct_arg arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	if (IS_QLA2100(ha) || IS_QLA2200(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 		return qla2x00_sns_gpn_id(vha, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	arg.iocb = ha->ms_iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	arg.req_dma = ha->ct_sns_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	arg.rsp_dma = ha->ct_sns_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	arg.req_size = GPN_ID_REQ_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	arg.rsp_size = GPN_ID_RSP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	arg.nport_handle = NPH_SNS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	for (i = 0; i < ha->max_fibre_devices; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 		/* Issue GPN_ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 		/* Prepare common MS IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 		ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 		/* Prepare CT request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 		ct_req = qla2x00_prep_ct_req(ha->ct_sns, GPN_ID_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 		    GPN_ID_RSP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 		ct_rsp = &ha->ct_sns->p.rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 		/* Prepare CT arguments -- port_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 		ct_req->req.port_id.port_id = port_id_to_be_id(list[i].d_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 		/* Execute MS IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 		rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 		    sizeof(ms_iocb_entry_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 		if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 			/*EMPTY*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 			ql_dbg(ql_dbg_disc, vha, 0x2056,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 			    "GPN_ID issue IOCB failed (%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 		} else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 		    "GPN_ID") != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 			rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 			/* Save portname */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 			memcpy(list[i].port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 			    ct_rsp->rsp.gpn_id.port_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 		/* Last device exit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 		if (list[i].d_id.b.rsvd_1 != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430)  * qla2x00_gnn_id() - SNS Get Node Name (GNN_ID) query.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432)  * @list: switch info entries to populate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	int		rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	uint16_t	i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	ms_iocb_entry_t	*ms_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	struct ct_sns_req	*ct_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	struct ct_sns_rsp	*ct_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	struct ct_arg arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	if (IS_QLA2100(ha) || IS_QLA2200(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 		return qla2x00_sns_gnn_id(vha, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	arg.iocb = ha->ms_iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	arg.req_dma = ha->ct_sns_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	arg.rsp_dma = ha->ct_sns_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	arg.req_size = GNN_ID_REQ_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	arg.rsp_size = GNN_ID_RSP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	arg.nport_handle = NPH_SNS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	for (i = 0; i < ha->max_fibre_devices; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 		/* Issue GNN_ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 		/* Prepare common MS IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 		ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 		/* Prepare CT request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 		ct_req = qla2x00_prep_ct_req(ha->ct_sns, GNN_ID_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 		    GNN_ID_RSP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 		ct_rsp = &ha->ct_sns->p.rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 		/* Prepare CT arguments -- port_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 		ct_req->req.port_id.port_id = port_id_to_be_id(list[i].d_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 		/* Execute MS IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 		rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 		    sizeof(ms_iocb_entry_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 		if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 			/*EMPTY*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 			ql_dbg(ql_dbg_disc, vha, 0x2057,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 			    "GNN_ID issue IOCB failed (%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 		} else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 		    "GNN_ID") != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 			rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 			/* Save nodename */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 			memcpy(list[i].node_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 			    ct_rsp->rsp.gnn_id.node_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 			ql_dbg(ql_dbg_disc, vha, 0x2058,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 			    "GID_PT entry - nn %8phN pn %8phN "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 			    "portid=%02x%02x%02x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 			    list[i].node_name, list[i].port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 			    list[i].d_id.b.domain, list[i].d_id.b.area,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 			    list[i].d_id.b.al_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 		/* Last device exit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 		if (list[i].d_id.b.rsvd_1 != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) static void qla2x00_async_sns_sp_done(srb_t *sp, int rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	struct scsi_qla_host *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	struct ct_sns_pkt *ct_sns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	struct qla_work_evt *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	sp->rc = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	if (rc == QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 		ql_dbg(ql_dbg_disc, vha, 0x204f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 		    "Async done-%s exiting normally.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 		    sp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	} else if (rc == QLA_FUNCTION_TIMEOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 		ql_dbg(ql_dbg_disc, vha, 0x204f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 		    "Async done-%s timeout\n", sp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 		ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 		memset(ct_sns, 0, sizeof(*ct_sns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 		sp->retry_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 		if (sp->retry_count > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 			goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 		ql_dbg(ql_dbg_disc, vha, 0x204f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 		    "Async done-%s fail rc %x.  Retry count %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		    sp->name, rc, sp->retry_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 		e = qla2x00_alloc_work(vha, QLA_EVT_SP_RETRY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 		if (!e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 			goto err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 		del_timer(&sp->u.iocb_cmd.timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 		e->u.iosb.sp = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 		qla2x00_post_work(vha, e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	e = qla2x00_alloc_work(vha, QLA_EVT_UNMAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) err2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	if (!e) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 		/* please ignore kernel warning. otherwise, we have mem leak. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 		if (sp->u.iocb_cmd.u.ctarg.req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 			dma_free_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 			    sp->u.iocb_cmd.u.ctarg.req_allocated_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 			    sp->u.iocb_cmd.u.ctarg.req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 			    sp->u.iocb_cmd.u.ctarg.req_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 			sp->u.iocb_cmd.u.ctarg.req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 		if (sp->u.iocb_cmd.u.ctarg.rsp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 			dma_free_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 			    sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 			    sp->u.iocb_cmd.u.ctarg.rsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 			    sp->u.iocb_cmd.u.ctarg.rsp_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 			sp->u.iocb_cmd.u.ctarg.rsp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 		sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	e->u.iosb.sp = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	qla2x00_post_work(vha, e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569)  * qla2x00_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) qla2x00_rft_id(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	if (IS_QLA2100(ha) || IS_QLA2200(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 		return qla2x00_sns_rft_id(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	return qla_async_rftid(vha, &vha->d_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) static int qla_async_rftid(scsi_qla_host_t *vha, port_id_t *d_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	int rval = QLA_MEMORY_ALLOC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	struct ct_sns_req *ct_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	srb_t *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	struct ct_sns_pkt *ct_sns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	if (!vha->flags.online)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	sp->type = SRB_CT_PTHRU_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	sp->name = "rft_id";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	    sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	    GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	if (!sp->u.iocb_cmd.u.ctarg.req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 		ql_log(ql_log_warn, vha, 0xd041,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 		    "%s: Failed to allocate ct_sns request.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 		    __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	    sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	    GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	if (!sp->u.iocb_cmd.u.ctarg.rsp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 		ql_log(ql_log_warn, vha, 0xd042,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 		    "%s: Failed to allocate ct_sns request.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 		    __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	memset(ct_sns, 0, sizeof(*ct_sns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	/* Prepare CT request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	ct_req = qla2x00_prep_ct_req(ct_sns, RFT_ID_CMD, RFT_ID_RSP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	/* Prepare CT arguments -- port_id, FC-4 types */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	ct_req->req.rft_id.port_id = port_id_to_be_id(vha->d_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	ct_req->req.rft_id.fc4_types[2] = 0x01;		/* FCP-3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	if (vha->flags.nvme_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 		ct_req->req.rft_id.fc4_types[6] = 1;    /* NVMe type 28h */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	sp->u.iocb_cmd.u.ctarg.req_size = RFT_ID_REQ_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	sp->u.iocb_cmd.u.ctarg.rsp_size = RFT_ID_RSP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	sp->done = qla2x00_async_sns_sp_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	ql_dbg(ql_dbg_disc, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	    "Async-%s - hdl=%x portid %06x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	    sp->name, sp->handle, d_id->b24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	rval = qla2x00_start_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 		ql_dbg(ql_dbg_disc, vha, 0x2043,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 		    "RFT_ID issue IOCB failed (%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) done_free_sp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662)  * qla2x00_rff_id() - SNS Register FC-4 Features (RFF_ID) supported by the HBA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664)  * @type: not used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) qla2x00_rff_id(scsi_qla_host_t *vha, u8 type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 		ql_dbg(ql_dbg_disc, vha, 0x2046,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 		    "RFF_ID call not supported on ISP2100/ISP2200.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 		return (QLA_SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	return qla_async_rffid(vha, &vha->d_id, qlt_rff_id(vha), type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) static int qla_async_rffid(scsi_qla_host_t *vha, port_id_t *d_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683)     u8 fc4feature, u8 fc4type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	int rval = QLA_MEMORY_ALLOC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	struct ct_sns_req *ct_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	srb_t *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	struct ct_sns_pkt *ct_sns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	sp->type = SRB_CT_PTHRU_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	sp->name = "rff_id";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	    sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	    GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	if (!sp->u.iocb_cmd.u.ctarg.req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 		ql_log(ql_log_warn, vha, 0xd041,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 		    "%s: Failed to allocate ct_sns request.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 		    __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	    sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	    GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	if (!sp->u.iocb_cmd.u.ctarg.rsp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 		ql_log(ql_log_warn, vha, 0xd042,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 		    "%s: Failed to allocate ct_sns request.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 		    __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	memset(ct_sns, 0, sizeof(*ct_sns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 	/* Prepare CT request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	ct_req = qla2x00_prep_ct_req(ct_sns, RFF_ID_CMD, RFF_ID_RSP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	/* Prepare CT arguments -- port_id, FC-4 feature, FC-4 type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	ct_req->req.rff_id.port_id = port_id_to_be_id(*d_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	ct_req->req.rff_id.fc4_feature = fc4feature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	ct_req->req.rff_id.fc4_type = fc4type;		/* SCSI-FCP or FC-NVMe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	sp->u.iocb_cmd.u.ctarg.req_size = RFF_ID_REQ_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	sp->u.iocb_cmd.u.ctarg.rsp_size = RFF_ID_RSP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	sp->done = qla2x00_async_sns_sp_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	ql_dbg(ql_dbg_disc, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	    "Async-%s - hdl=%x portid %06x feature %x type %x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	    sp->name, sp->handle, d_id->b24, fc4feature, fc4type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	rval = qla2x00_start_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 		ql_dbg(ql_dbg_disc, vha, 0x2047,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 		    "RFF_ID issue IOCB failed (%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) done_free_sp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757)  * qla2x00_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) qla2x00_rnn_id(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	if (IS_QLA2100(ha) || IS_QLA2200(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 		return qla2x00_sns_rnn_id(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	return  qla_async_rnnid(vha, &vha->d_id, vha->node_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) static int qla_async_rnnid(scsi_qla_host_t *vha, port_id_t *d_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	u8 *node_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	int rval = QLA_MEMORY_ALLOC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	struct ct_sns_req *ct_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	srb_t *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	struct ct_sns_pkt *ct_sns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	sp->type = SRB_CT_PTHRU_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	sp->name = "rnid";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	    sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	    GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	if (!sp->u.iocb_cmd.u.ctarg.req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 		ql_log(ql_log_warn, vha, 0xd041,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 		    "%s: Failed to allocate ct_sns request.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 		    __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	    sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	    GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	if (!sp->u.iocb_cmd.u.ctarg.rsp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 		ql_log(ql_log_warn, vha, 0xd042,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 		    "%s: Failed to allocate ct_sns request.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 		    __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	memset(ct_sns, 0, sizeof(*ct_sns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 	ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	/* Prepare CT request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	ct_req = qla2x00_prep_ct_req(ct_sns, RNN_ID_CMD, RNN_ID_RSP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	/* Prepare CT arguments -- port_id, node_name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	ct_req->req.rnn_id.port_id = port_id_to_be_id(vha->d_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	memcpy(ct_req->req.rnn_id.node_name, vha->node_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	sp->u.iocb_cmd.u.ctarg.req_size = RNN_ID_REQ_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	sp->u.iocb_cmd.u.ctarg.rsp_size = RNN_ID_RSP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	sp->done = qla2x00_async_sns_sp_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	ql_dbg(ql_dbg_disc, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	    "Async-%s - hdl=%x portid %06x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	    sp->name, sp->handle, d_id->b24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	rval = qla2x00_start_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 		ql_dbg(ql_dbg_disc, vha, 0x204d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 		    "RNN_ID issue IOCB failed (%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) done_free_sp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) size_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) qla2x00_get_sym_node_name(scsi_qla_host_t *vha, uint8_t *snn, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	if (IS_QLAFX00(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 		return scnprintf(snn, size, "%s FW:v%s DVR:v%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 		    ha->model_number, ha->mr.fw_version, qla2x00_version_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	return scnprintf(snn, size, "%s FW:v%d.%02d.%02d DVR:v%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	    ha->model_number, ha->fw_major_version, ha->fw_minor_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	    ha->fw_subminor_version, qla2x00_version_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862)  * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) qla2x00_rsnn_nn(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 		ql_dbg(ql_dbg_disc, vha, 0x2050,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 		    "RSNN_ID call unsupported on ISP2100/ISP2200.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 		return (QLA_SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	return qla_async_rsnn_nn(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) static int qla_async_rsnn_nn(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	int rval = QLA_MEMORY_ALLOC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	struct ct_sns_req *ct_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	srb_t *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	struct ct_sns_pkt *ct_sns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	sp->type = SRB_CT_PTHRU_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	sp->name = "rsnn_nn";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	    sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	    GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	if (!sp->u.iocb_cmd.u.ctarg.req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 		ql_log(ql_log_warn, vha, 0xd041,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 		    "%s: Failed to allocate ct_sns request.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 		    __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	    sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	    GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	if (!sp->u.iocb_cmd.u.ctarg.rsp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 		ql_log(ql_log_warn, vha, 0xd042,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 		    "%s: Failed to allocate ct_sns request.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 		    __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	memset(ct_sns, 0, sizeof(*ct_sns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	/* Prepare CT request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	ct_req = qla2x00_prep_ct_req(ct_sns, RSNN_NN_CMD, RSNN_NN_RSP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	/* Prepare CT arguments -- node_name, symbolic node_name, size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	memcpy(ct_req->req.rsnn_nn.node_name, vha->node_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	/* Prepare the Symbolic Node Name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	qla2x00_get_sym_node_name(vha, ct_req->req.rsnn_nn.sym_node_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	    sizeof(ct_req->req.rsnn_nn.sym_node_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	ct_req->req.rsnn_nn.name_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	    (uint8_t)strlen(ct_req->req.rsnn_nn.sym_node_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	sp->u.iocb_cmd.u.ctarg.req_size = 24 + 1 + ct_req->req.rsnn_nn.name_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	sp->u.iocb_cmd.u.ctarg.rsp_size = RSNN_NN_RSP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	sp->done = qla2x00_async_sns_sp_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	ql_dbg(ql_dbg_disc, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	    "Async-%s - hdl=%x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	    sp->name, sp->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	rval = qla2x00_start_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 		ql_dbg(ql_dbg_disc, vha, 0x2043,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 		    "RFT_ID issue IOCB failed (%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) done_free_sp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961)  * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963)  * @cmd: GS command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964)  * @scmd_len: Subcommand length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965)  * @data_size: response size in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967)  * Returns a pointer to the @ha's sns_cmd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) static inline struct sns_cmd_pkt *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) qla2x00_prep_sns_cmd(scsi_qla_host_t *vha, uint16_t cmd, uint16_t scmd_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971)     uint16_t data_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	uint16_t		wc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	struct sns_cmd_pkt	*sns_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	sns_cmd = ha->sns_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	memset(sns_cmd, 0, sizeof(struct sns_cmd_pkt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	wc = data_size / 2;			/* Size in 16bit words. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	sns_cmd->p.cmd.buffer_length = cpu_to_le16(wc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	put_unaligned_le64(ha->sns_cmd_dma, &sns_cmd->p.cmd.buffer_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	sns_cmd->p.cmd.subcommand_length = cpu_to_le16(scmd_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	sns_cmd->p.cmd.subcommand = cpu_to_le16(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	wc = (data_size - 16) / 4;		/* Size in 32bit words. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	sns_cmd->p.cmd.size = cpu_to_le16(wc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	vha->qla_stats.control_requests++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	return (sns_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993)  * qla2x00_sns_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995)  * @fcport: fcport entry to updated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997)  * This command uses the old Exectute SNS Command mailbox routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) qla2x00_sns_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	int		rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	struct sns_cmd_pkt	*sns_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	/* Issue GA_NXT. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	/* Prepare SNS command request. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	sns_cmd = qla2x00_prep_sns_cmd(vha, GA_NXT_CMD, GA_NXT_SNS_SCMD_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	    GA_NXT_SNS_DATA_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	/* Prepare SNS command arguments -- port_id. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	sns_cmd->p.cmd.param[0] = fcport->d_id.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	sns_cmd->p.cmd.param[1] = fcport->d_id.b.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	sns_cmd->p.cmd.param[2] = fcport->d_id.b.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	/* Execute SNS command. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GA_NXT_SNS_CMD_SIZE / 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	    sizeof(struct sns_cmd_pkt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 		/*EMPTY*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		ql_dbg(ql_dbg_disc, vha, 0x205f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 		    "GA_NXT Send SNS failed (%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	} else if (sns_cmd->p.gan_data[8] != 0x80 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	    sns_cmd->p.gan_data[9] != 0x02) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 		ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2084,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 		    "GA_NXT failed, rejected request ga_nxt_rsp:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 		ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2074,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 		    sns_cmd->p.gan_data, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 		rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 		/* Populate fc_port_t entry. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 		fcport->d_id.b.domain = sns_cmd->p.gan_data[17];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 		fcport->d_id.b.area = sns_cmd->p.gan_data[18];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 		fcport->d_id.b.al_pa = sns_cmd->p.gan_data[19];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 		memcpy(fcport->node_name, &sns_cmd->p.gan_data[284], WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 		memcpy(fcport->port_name, &sns_cmd->p.gan_data[20], WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 		if (sns_cmd->p.gan_data[16] != NS_N_PORT_TYPE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 		    sns_cmd->p.gan_data[16] != NS_NL_PORT_TYPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 			fcport->d_id.b.domain = 0xf0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 		ql_dbg(ql_dbg_disc, vha, 0x2061,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		    "GA_NXT entry - nn %8phN pn %8phN "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 		    "port_id=%02x%02x%02x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 		    fcport->node_name, fcport->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 		    fcport->d_id.b.domain, fcport->d_id.b.area,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 		    fcport->d_id.b.al_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)  * qla2x00_sns_gid_pt() - SNS scan for fabric devices via GID_PT command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)  * @list: switch info entries to populate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)  * This command uses the old Exectute SNS Command mailbox routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)  * NOTE: Non-Nx_Ports are not requested.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) qla2x00_sns_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	int		rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	uint16_t	i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	uint8_t		*entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	struct sns_cmd_pkt	*sns_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	uint16_t gid_pt_sns_data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	gid_pt_sns_data_size = qla2x00_gid_pt_rsp_size(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	/* Issue GID_PT. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	/* Prepare SNS command request. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	sns_cmd = qla2x00_prep_sns_cmd(vha, GID_PT_CMD, GID_PT_SNS_SCMD_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	    gid_pt_sns_data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	/* Prepare SNS command arguments -- port_type. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	sns_cmd->p.cmd.param[0] = NS_NX_PORT_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	/* Execute SNS command. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GID_PT_SNS_CMD_SIZE / 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	    sizeof(struct sns_cmd_pkt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 		/*EMPTY*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 		ql_dbg(ql_dbg_disc, vha, 0x206d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 		    "GID_PT Send SNS failed (%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	} else if (sns_cmd->p.gid_data[8] != 0x80 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	    sns_cmd->p.gid_data[9] != 0x02) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 		ql_dbg(ql_dbg_disc, vha, 0x202f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 		    "GID_PT failed, rejected request, gid_rsp:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 		ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2081,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 		    sns_cmd->p.gid_data, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 		rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 		/* Set port IDs in switch info list. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 		for (i = 0; i < ha->max_fibre_devices; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 			entry = &sns_cmd->p.gid_data[(i * 4) + 16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 			list[i].d_id.b.domain = entry[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 			list[i].d_id.b.area = entry[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 			list[i].d_id.b.al_pa = entry[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 			/* Last one exit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 			if (entry[0] & BIT_7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 				list[i].d_id.b.rsvd_1 = entry[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 		 * If we've used all available slots, then the switch is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 		 * reporting back more devices that we can handle with this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 		 * single call.  Return a failed status, and let GA_NXT handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 		 * the overload.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 		if (i == ha->max_fibre_devices)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 			rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)  * qla2x00_sns_gpn_id() - SNS Get Port Name (GPN_ID) query.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)  * @list: switch info entries to populate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)  * This command uses the old Exectute SNS Command mailbox routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) qla2x00_sns_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 	int		rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	uint16_t	i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	struct sns_cmd_pkt	*sns_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	for (i = 0; i < ha->max_fibre_devices; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 		/* Issue GPN_ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 		/* Prepare SNS command request. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 		sns_cmd = qla2x00_prep_sns_cmd(vha, GPN_ID_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 		    GPN_ID_SNS_SCMD_LEN, GPN_ID_SNS_DATA_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 		/* Prepare SNS command arguments -- port_id. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 		sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 		sns_cmd->p.cmd.param[1] = list[i].d_id.b.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 		sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 		/* Execute SNS command. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 		rval = qla2x00_send_sns(vha, ha->sns_cmd_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 		    GPN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 		if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 			/*EMPTY*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 			ql_dbg(ql_dbg_disc, vha, 0x2032,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 			    "GPN_ID Send SNS failed (%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 		} else if (sns_cmd->p.gpn_data[8] != 0x80 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 		    sns_cmd->p.gpn_data[9] != 0x02) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 			ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 			    "GPN_ID failed, rejected request, gpn_rsp:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 			ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 			    sns_cmd->p.gpn_data, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 			rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 			/* Save portname */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 			memcpy(list[i].port_name, &sns_cmd->p.gpn_data[16],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 			    WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 		/* Last device exit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 		if (list[i].d_id.b.rsvd_1 != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)  * qla2x00_sns_gnn_id() - SNS Get Node Name (GNN_ID) query.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)  * @list: switch info entries to populate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)  * This command uses the old Exectute SNS Command mailbox routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) qla2x00_sns_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 	int		rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	uint16_t	i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	struct sns_cmd_pkt	*sns_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	for (i = 0; i < ha->max_fibre_devices; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 		/* Issue GNN_ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 		/* Prepare SNS command request. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 		sns_cmd = qla2x00_prep_sns_cmd(vha, GNN_ID_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 		    GNN_ID_SNS_SCMD_LEN, GNN_ID_SNS_DATA_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 		/* Prepare SNS command arguments -- port_id. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 		sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 		sns_cmd->p.cmd.param[1] = list[i].d_id.b.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 		sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 		/* Execute SNS command. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 		rval = qla2x00_send_sns(vha, ha->sns_cmd_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 		    GNN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 		if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 			/*EMPTY*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 			ql_dbg(ql_dbg_disc, vha, 0x203f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 			    "GNN_ID Send SNS failed (%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 		} else if (sns_cmd->p.gnn_data[8] != 0x80 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 		    sns_cmd->p.gnn_data[9] != 0x02) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 			ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2082,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 			    "GNN_ID failed, rejected request, gnn_rsp:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 			ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 			    sns_cmd->p.gnn_data, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 			rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 			/* Save nodename */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 			memcpy(list[i].node_name, &sns_cmd->p.gnn_data[16],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 			    WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 			ql_dbg(ql_dbg_disc, vha, 0x206e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 			    "GID_PT entry - nn %8phN pn %8phN "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 			    "port_id=%02x%02x%02x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 			    list[i].node_name, list[i].port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 			    list[i].d_id.b.domain, list[i].d_id.b.area,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 			    list[i].d_id.b.al_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 		/* Last device exit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 		if (list[i].d_id.b.rsvd_1 != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)  * qla2x00_snd_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)  * This command uses the old Exectute SNS Command mailbox routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) qla2x00_sns_rft_id(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	int		rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 	struct sns_cmd_pkt	*sns_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	/* Issue RFT_ID. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 	/* Prepare SNS command request. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	sns_cmd = qla2x00_prep_sns_cmd(vha, RFT_ID_CMD, RFT_ID_SNS_SCMD_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	    RFT_ID_SNS_DATA_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	/* Prepare SNS command arguments -- port_id, FC-4 types */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	sns_cmd->p.cmd.param[1] = vha->d_id.b.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	sns_cmd->p.cmd.param[2] = vha->d_id.b.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 	sns_cmd->p.cmd.param[5] = 0x01;			/* FCP-3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 	/* Execute SNS command. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RFT_ID_SNS_CMD_SIZE / 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	    sizeof(struct sns_cmd_pkt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 		/*EMPTY*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 		ql_dbg(ql_dbg_disc, vha, 0x2060,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 		    "RFT_ID Send SNS failed (%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	} else if (sns_cmd->p.rft_data[8] != 0x80 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	    sns_cmd->p.rft_data[9] != 0x02) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 		ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2083,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 		    "RFT_ID failed, rejected request rft_rsp:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 		ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2080,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 		    sns_cmd->p.rft_data, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 		rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 		ql_dbg(ql_dbg_disc, vha, 0x2073,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 		    "RFT_ID exiting normally.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)  * qla2x00_sns_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)  * This command uses the old Exectute SNS Command mailbox routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) qla2x00_sns_rnn_id(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 	int		rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 	struct sns_cmd_pkt	*sns_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 	/* Issue RNN_ID. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 	/* Prepare SNS command request. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 	sns_cmd = qla2x00_prep_sns_cmd(vha, RNN_ID_CMD, RNN_ID_SNS_SCMD_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 	    RNN_ID_SNS_DATA_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	/* Prepare SNS command arguments -- port_id, nodename. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 	sns_cmd->p.cmd.param[1] = vha->d_id.b.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	sns_cmd->p.cmd.param[2] = vha->d_id.b.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	sns_cmd->p.cmd.param[4] = vha->node_name[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	sns_cmd->p.cmd.param[5] = vha->node_name[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	sns_cmd->p.cmd.param[6] = vha->node_name[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	sns_cmd->p.cmd.param[7] = vha->node_name[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 	sns_cmd->p.cmd.param[8] = vha->node_name[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	sns_cmd->p.cmd.param[9] = vha->node_name[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	sns_cmd->p.cmd.param[10] = vha->node_name[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 	sns_cmd->p.cmd.param[11] = vha->node_name[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	/* Execute SNS command. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 	rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RNN_ID_SNS_CMD_SIZE / 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 	    sizeof(struct sns_cmd_pkt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 		/*EMPTY*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 		ql_dbg(ql_dbg_disc, vha, 0x204a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 		    "RNN_ID Send SNS failed (%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	} else if (sns_cmd->p.rnn_data[8] != 0x80 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	    sns_cmd->p.rnn_data[9] != 0x02) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 		ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 		    "RNN_ID failed, rejected request, rnn_rsp:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 		ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 		    sns_cmd->p.rnn_data, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 		rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 		ql_dbg(ql_dbg_disc, vha, 0x204c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 		    "RNN_ID exiting normally.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354)  * qla2x00_mgmt_svr_login() - Login to fabric Management Service.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) qla2x00_mgmt_svr_login(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 	int ret, rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	uint16_t mb[MAILBOX_REGISTER_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 	ret = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 	if (vha->flags.management_server_logged_in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 	rval = ha->isp_ops->fabric_login(vha, vha->mgmt_svr_loop_id, 0xff, 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	    0xfa, mb, BIT_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 	if (rval != QLA_SUCCESS || mb[0] != MBS_COMMAND_COMPLETE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 		if (rval == QLA_MEMORY_ALLOC_FAILED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 			ql_dbg(ql_dbg_disc, vha, 0x2085,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 			    "Failed management_server login: loopid=%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 			    "rval=%d\n", vha->mgmt_svr_loop_id, rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 			ql_dbg(ql_dbg_disc, vha, 0x2024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 			    "Failed management_server login: loopid=%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 			    "mb[0]=%x mb[1]=%x mb[2]=%x mb[6]=%x mb[7]=%x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 			    vha->mgmt_svr_loop_id, mb[0], mb[1], mb[2], mb[6],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 			    mb[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 		ret = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 		vha->flags.management_server_logged_in = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)  * qla2x00_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)  * @req_size: request size in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)  * @rsp_size: response size in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396)  * Returns a pointer to the @ha's ms_iocb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) void *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400)     uint32_t rsp_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 	ms_iocb_entry_t *ms_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 	ms_pkt = ha->ms_iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 	memset(ms_pkt, 0, sizeof(ms_iocb_entry_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 	ms_pkt->entry_type = MS_IOCB_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 	ms_pkt->entry_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 	SET_TARGET_ID(ha, ms_pkt->loop_id, vha->mgmt_svr_loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 	ms_pkt->control_flags = cpu_to_le16(CF_READ | CF_HEAD_TAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 	ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 	ms_pkt->cmd_dsd_count = cpu_to_le16(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 	ms_pkt->total_dsd_count = cpu_to_le16(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 	ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 	ms_pkt->req_bytecount = cpu_to_le32(req_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	put_unaligned_le64(ha->ct_sns_dma, &ms_pkt->req_dsd.address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	ms_pkt->req_dsd.length = ms_pkt->req_bytecount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	put_unaligned_le64(ha->ct_sns_dma, &ms_pkt->rsp_dsd.address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 	ms_pkt->rsp_dsd.length = ms_pkt->rsp_bytecount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	return ms_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428)  * qla24xx_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)  * @req_size: request size in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)  * @rsp_size: response size in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)  * Returns a pointer to the @ha's ms_iocb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) void *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)     uint32_t rsp_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 	struct ct_entry_24xx *ct_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 	ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 	memset(ct_pkt, 0, sizeof(struct ct_entry_24xx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 	ct_pkt->entry_type = CT_IOCB_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 	ct_pkt->entry_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 	ct_pkt->nport_handle = cpu_to_le16(vha->mgmt_svr_loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 	ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 	ct_pkt->cmd_dsd_count = cpu_to_le16(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 	ct_pkt->rsp_dsd_count = cpu_to_le16(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 	ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 	ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 	put_unaligned_le64(ha->ct_sns_dma, &ct_pkt->dsd[0].address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 	ct_pkt->dsd[0].length = ct_pkt->cmd_byte_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 	put_unaligned_le64(ha->ct_sns_dma, &ct_pkt->dsd[1].address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 	ct_pkt->dsd[1].length = ct_pkt->rsp_byte_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 	ct_pkt->vp_index = vha->vp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 	return ct_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 	ms_iocb_entry_t *ms_pkt = ha->ms_iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 	struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 	if (IS_FWI2_CAPABLE(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 		ct_pkt->cmd_byte_count = cpu_to_le32(req_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 		ct_pkt->dsd[0].length = ct_pkt->cmd_byte_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 		ms_pkt->req_bytecount = cpu_to_le32(req_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 		ms_pkt->req_dsd.length = ms_pkt->req_bytecount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)  * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)  * @p: CT request buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)  * @cmd: GS command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)  * @rsp_size: response size in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486)  * Returns a pointer to the intitialized @ct_req.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) static inline struct ct_sns_req *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) qla2x00_prep_ct_fdmi_req(struct ct_sns_pkt *p, uint16_t cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)     uint16_t rsp_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 	memset(p, 0, sizeof(struct ct_sns_pkt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 	p->p.req.header.revision = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 	p->p.req.header.gs_type = 0xFA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 	p->p.req.header.gs_subtype = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 	p->p.req.command = cpu_to_be16(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 	p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 	return &p->p.req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) uint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) qla25xx_fdmi_port_speed_capability(struct qla_hw_data *ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 	uint speeds = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 	if (IS_CNA_CAPABLE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 		return FDMI_PORT_SPEED_10GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 	if (IS_QLA28XX(ha) || IS_QLA27XX(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 		if (ha->max_supported_speed == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 			if (ha->min_supported_speed <= 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 				speeds |= FDMI_PORT_SPEED_64GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 		if (ha->max_supported_speed == 2 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 		    ha->max_supported_speed == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 			if (ha->min_supported_speed <= 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 				speeds |= FDMI_PORT_SPEED_32GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 		if (ha->max_supported_speed == 2 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 		    ha->max_supported_speed == 1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 		    ha->max_supported_speed == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 			if (ha->min_supported_speed <= 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 				speeds |= FDMI_PORT_SPEED_16GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 		if (ha->max_supported_speed == 1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 		    ha->max_supported_speed == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 			if (ha->min_supported_speed <= 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 				speeds |= FDMI_PORT_SPEED_8GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 		if (ha->max_supported_speed == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 			if (ha->min_supported_speed <= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 				speeds |= FDMI_PORT_SPEED_4GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 		return speeds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 	if (IS_QLA2031(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 		if ((ha->pdev->subsystem_vendor == 0x103C) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 		    (ha->pdev->subsystem_device == 0x8002)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 			speeds = FDMI_PORT_SPEED_16GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 			speeds = FDMI_PORT_SPEED_16GB|FDMI_PORT_SPEED_8GB|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 				FDMI_PORT_SPEED_4GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 		return speeds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 	if (IS_QLA25XX(ha) || IS_QLAFX00(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 		return FDMI_PORT_SPEED_8GB|FDMI_PORT_SPEED_4GB|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 			FDMI_PORT_SPEED_2GB|FDMI_PORT_SPEED_1GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 	if (IS_QLA24XX_TYPE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 		return FDMI_PORT_SPEED_4GB|FDMI_PORT_SPEED_2GB|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 			FDMI_PORT_SPEED_1GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 	if (IS_QLA23XX(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 		return FDMI_PORT_SPEED_2GB|FDMI_PORT_SPEED_1GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 	return FDMI_PORT_SPEED_1GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) uint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) qla25xx_fdmi_port_speed_currently(struct qla_hw_data *ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	switch (ha->link_data_rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 	case PORT_SPEED_1GB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 		return FDMI_PORT_SPEED_1GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 	case PORT_SPEED_2GB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 		return FDMI_PORT_SPEED_2GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 	case PORT_SPEED_4GB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 		return FDMI_PORT_SPEED_4GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	case PORT_SPEED_8GB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 		return FDMI_PORT_SPEED_8GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 	case PORT_SPEED_10GB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 		return FDMI_PORT_SPEED_10GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 	case PORT_SPEED_16GB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 		return FDMI_PORT_SPEED_16GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 	case PORT_SPEED_32GB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 		return FDMI_PORT_SPEED_32GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 	case PORT_SPEED_64GB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 		return FDMI_PORT_SPEED_64GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 		return FDMI_PORT_SPEED_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584)  * qla2x00_hba_attributes() perform HBA attributes registration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586)  * @entries: number of entries to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587)  * @callopt: Option to issue extended or standard FDMI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588)  *           command parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) static unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) qla2x00_hba_attributes(scsi_qla_host_t *vha, void *entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 	unsigned int callopt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 	struct init_cb_24xx *icb24 = (void *)ha->init_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 	struct new_utsname *p_sysid = utsname();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 	struct ct_fdmi_hba_attr *eiter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 	uint16_t alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 	unsigned long size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 	/* Nodename. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 	eiter->type = cpu_to_be16(FDMI_HBA_NODE_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 	memcpy(eiter->a.node_name, vha->node_name, sizeof(eiter->a.node_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 	alen = sizeof(eiter->a.node_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 	ql_dbg(ql_dbg_disc, vha, 0x20a0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 	    "NODENAME = %016llx.\n", wwn_to_u64(eiter->a.node_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 	/* Manufacturer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 	eiter->type = cpu_to_be16(FDMI_HBA_MANUFACTURER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 	alen = scnprintf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 		eiter->a.manufacturer, sizeof(eiter->a.manufacturer),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 		"%s", "QLogic Corporation");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 	alen += FDMI_ATTR_ALIGNMENT(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 	ql_dbg(ql_dbg_disc, vha, 0x20a1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 	    "MANUFACTURER = %s.\n", eiter->a.manufacturer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 	/* Serial number. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 	eiter->type = cpu_to_be16(FDMI_HBA_SERIAL_NUMBER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 	alen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 	if (IS_FWI2_CAPABLE(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 		alen = qla2xxx_get_vpd_field(vha, "SN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 		    eiter->a.serial_num, sizeof(eiter->a.serial_num));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 	if (!alen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 		uint32_t sn = ((ha->serial0 & 0x1f) << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 			(ha->serial2 << 8) | ha->serial1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 		alen = scnprintf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 			eiter->a.serial_num, sizeof(eiter->a.serial_num),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 			"%c%05d", 'A' + sn / 100000, sn % 100000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 	alen += FDMI_ATTR_ALIGNMENT(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 	ql_dbg(ql_dbg_disc, vha, 0x20a2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 	    "SERIAL NUMBER = %s.\n", eiter->a.serial_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 	/* Model name. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 	eiter->type = cpu_to_be16(FDMI_HBA_MODEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 	alen = scnprintf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 		eiter->a.model, sizeof(eiter->a.model),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 		"%s", ha->model_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 	alen += FDMI_ATTR_ALIGNMENT(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 	ql_dbg(ql_dbg_disc, vha, 0x20a3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 	    "MODEL NAME = %s.\n", eiter->a.model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 	/* Model description. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 	eiter->type = cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 	alen = scnprintf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 		eiter->a.model_desc, sizeof(eiter->a.model_desc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 		"%s", ha->model_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 	alen += FDMI_ATTR_ALIGNMENT(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 	ql_dbg(ql_dbg_disc, vha, 0x20a4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 	    "MODEL DESCRIPTION = %s.\n", eiter->a.model_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 	/* Hardware version. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 	eiter->type = cpu_to_be16(FDMI_HBA_HARDWARE_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 	alen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 	if (IS_FWI2_CAPABLE(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 		if (!alen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 			alen = qla2xxx_get_vpd_field(vha, "MN",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 			    eiter->a.hw_version, sizeof(eiter->a.hw_version));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 		if (!alen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 			alen = qla2xxx_get_vpd_field(vha, "EC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 			    eiter->a.hw_version, sizeof(eiter->a.hw_version));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 	if (!alen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 		alen = scnprintf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 			eiter->a.hw_version, sizeof(eiter->a.hw_version),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 			"HW:%s", ha->adapter_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 	alen += FDMI_ATTR_ALIGNMENT(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 	ql_dbg(ql_dbg_disc, vha, 0x20a5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 	    "HARDWARE VERSION = %s.\n", eiter->a.hw_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 	/* Driver version. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 	eiter->type = cpu_to_be16(FDMI_HBA_DRIVER_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 	alen = scnprintf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 		eiter->a.driver_version, sizeof(eiter->a.driver_version),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 		"%s", qla2x00_version_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 	alen += FDMI_ATTR_ALIGNMENT(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 	ql_dbg(ql_dbg_disc, vha, 0x20a6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 	    "DRIVER VERSION = %s.\n", eiter->a.driver_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 	/* Option ROM version. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 	eiter->type = cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 	alen = scnprintf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 		eiter->a.orom_version, sizeof(eiter->a.orom_version),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 		"%d.%02d", ha->bios_revision[1], ha->bios_revision[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 	alen += FDMI_ATTR_ALIGNMENT(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 	ql_dbg(ql_dbg_disc, vha, 0x20a7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 	    "OPTROM VERSION = %d.%02d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 	    eiter->a.orom_version[1], eiter->a.orom_version[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 	/* Firmware version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 	eiter->type = cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 	ha->isp_ops->fw_version_str(vha, eiter->a.fw_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 	    sizeof(eiter->a.fw_version));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 	alen += FDMI_ATTR_ALIGNMENT(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 	ql_dbg(ql_dbg_disc, vha, 0x20a8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 	    "FIRMWARE VERSION = %s.\n", eiter->a.fw_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 	if (callopt == CALLOPT_FDMI1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 	/* OS Name and Version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 	eiter->type = cpu_to_be16(FDMI_HBA_OS_NAME_AND_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 	alen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 	if (p_sysid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 		alen = scnprintf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 			eiter->a.os_version, sizeof(eiter->a.os_version),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 			"%s %s %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 			p_sysid->sysname, p_sysid->release, p_sysid->machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 	if (!alen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 		alen = scnprintf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 			eiter->a.os_version, sizeof(eiter->a.os_version),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 			"%s %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 			"Linux", fc_host_system_hostname(vha->host));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 	alen += FDMI_ATTR_ALIGNMENT(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 	ql_dbg(ql_dbg_disc, vha, 0x20a9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 	    "OS VERSION = %s.\n", eiter->a.os_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 	/* MAX CT Payload Length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 	eiter->type = cpu_to_be16(FDMI_HBA_MAXIMUM_CT_PAYLOAD_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 	eiter->a.max_ct_len = cpu_to_be32(le16_to_cpu(IS_FWI2_CAPABLE(ha) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 		icb24->frame_payload_size : ha->init_cb->frame_payload_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 	alen = sizeof(eiter->a.max_ct_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 	ql_dbg(ql_dbg_disc, vha, 0x20aa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 	    "CT PAYLOAD LENGTH = 0x%x.\n", be32_to_cpu(eiter->a.max_ct_len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 	/* Node Sybolic Name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 	eiter->type = cpu_to_be16(FDMI_HBA_NODE_SYMBOLIC_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 	alen = qla2x00_get_sym_node_name(vha, eiter->a.sym_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 	    sizeof(eiter->a.sym_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 	alen += FDMI_ATTR_ALIGNMENT(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 	ql_dbg(ql_dbg_disc, vha, 0x20ab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 	    "SYMBOLIC NAME = %s.\n", eiter->a.sym_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 	/* Vendor Specific information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 	eiter->type = cpu_to_be16(FDMI_HBA_VENDOR_SPECIFIC_INFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 	eiter->a.vendor_specific_info = cpu_to_be32(PCI_VENDOR_ID_QLOGIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 	alen = sizeof(eiter->a.vendor_specific_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 	ql_dbg(ql_dbg_disc, vha, 0x20ac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 	    "VENDOR SPECIFIC INFO = 0x%x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 	    be32_to_cpu(eiter->a.vendor_specific_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 	/* Num Ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 	eiter->type = cpu_to_be16(FDMI_HBA_NUM_PORTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 	eiter->a.num_ports = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 	alen = sizeof(eiter->a.num_ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 	ql_dbg(ql_dbg_disc, vha, 0x20ad,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 	    "PORT COUNT = %x.\n", be32_to_cpu(eiter->a.num_ports));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 	/* Fabric Name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 	eiter->type = cpu_to_be16(FDMI_HBA_FABRIC_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 	memcpy(eiter->a.fabric_name, vha->fabric_node_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 	    sizeof(eiter->a.fabric_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 	alen = sizeof(eiter->a.fabric_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 	ql_dbg(ql_dbg_disc, vha, 0x20ae,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 	    "FABRIC NAME = %016llx.\n", wwn_to_u64(eiter->a.fabric_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 	/* BIOS Version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 	eiter->type = cpu_to_be16(FDMI_HBA_BOOT_BIOS_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 	alen = scnprintf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 		eiter->a.bios_name, sizeof(eiter->a.bios_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 		"BIOS %d.%02d", ha->bios_revision[1], ha->bios_revision[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 	alen += FDMI_ATTR_ALIGNMENT(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 	ql_dbg(ql_dbg_disc, vha, 0x20af,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 	    "BIOS NAME = %s\n", eiter->a.bios_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 	/* Vendor Identifier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 	eiter->type = cpu_to_be16(FDMI_HBA_VENDOR_IDENTIFIER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 	alen = scnprintf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 		eiter->a.vendor_identifier, sizeof(eiter->a.vendor_identifier),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 		"%s", "QLGC");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 	alen += FDMI_ATTR_ALIGNMENT(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 	ql_dbg(ql_dbg_disc, vha, 0x20b0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 	    "VENDOR IDENTIFIER = %s.\n", eiter->a.vendor_identifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 	return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)  * qla2x00_port_attributes() perform Port attributes registration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841)  * @entries: number of entries to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842)  * @callopt: Option to issue extended or standard FDMI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843)  *           command parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) static unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) qla2x00_port_attributes(scsi_qla_host_t *vha, void *entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 	unsigned int callopt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 	struct init_cb_24xx *icb24 = (void *)ha->init_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 	struct new_utsname *p_sysid = utsname();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 	char *hostname = p_sysid ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 		p_sysid->nodename : fc_host_system_hostname(vha->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 	struct ct_fdmi_port_attr *eiter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 	uint16_t alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 	unsigned long size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 	/* FC4 types. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 	eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 	eiter->a.fc4_types[0] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 	eiter->a.fc4_types[1] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 	eiter->a.fc4_types[2] = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 	eiter->a.fc4_types[3] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 	alen = sizeof(eiter->a.fc4_types);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 	ql_dbg(ql_dbg_disc, vha, 0x20c0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 	    "FC4 TYPES = %016llx.\n", *(uint64_t *)eiter->a.fc4_types);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 	if (vha->flags.nvme_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 		eiter->a.fc4_types[6] = 1;      /* NVMe type 28h */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 		ql_dbg(ql_dbg_disc, vha, 0x211f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 		    "NVME FC4 Type = %02x 0x0 0x0 0x0 0x0 0x0.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 		    eiter->a.fc4_types[6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 	/* Supported speed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 	eiter->type = cpu_to_be16(FDMI_PORT_SUPPORT_SPEED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 	eiter->a.sup_speed = cpu_to_be32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 		qla25xx_fdmi_port_speed_capability(ha));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 	alen = sizeof(eiter->a.sup_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 	ql_dbg(ql_dbg_disc, vha, 0x20c1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 	    "SUPPORTED SPEED = %x.\n", be32_to_cpu(eiter->a.sup_speed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 	/* Current speed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 	eiter->type = cpu_to_be16(FDMI_PORT_CURRENT_SPEED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 	eiter->a.cur_speed = cpu_to_be32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 		qla25xx_fdmi_port_speed_currently(ha));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 	alen = sizeof(eiter->a.cur_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 	ql_dbg(ql_dbg_disc, vha, 0x20c2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 	    "CURRENT SPEED = %x.\n", be32_to_cpu(eiter->a.cur_speed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 	/* Max frame size. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 	eiter->type = cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 	eiter->a.max_frame_size = cpu_to_be32(le16_to_cpu(IS_FWI2_CAPABLE(ha) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 		icb24->frame_payload_size : ha->init_cb->frame_payload_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 	alen = sizeof(eiter->a.max_frame_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 	ql_dbg(ql_dbg_disc, vha, 0x20c3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 	    "MAX FRAME SIZE = %x.\n", be32_to_cpu(eiter->a.max_frame_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 	/* OS device name. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 	eiter->type = cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 	alen = scnprintf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 		eiter->a.os_dev_name, sizeof(eiter->a.os_dev_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 		"%s:host%lu", QLA2XXX_DRIVER_NAME, vha->host_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 	alen += FDMI_ATTR_ALIGNMENT(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 	ql_dbg(ql_dbg_disc, vha, 0x20c4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 	    "OS DEVICE NAME = %s.\n", eiter->a.os_dev_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 	/* Hostname. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 	eiter->type = cpu_to_be16(FDMI_PORT_HOST_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 	if (!*hostname || !strncmp(hostname, "(none)", 6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 		hostname = "Linux-default";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 	alen = scnprintf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 		eiter->a.host_name, sizeof(eiter->a.host_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 		"%s", hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 	alen += FDMI_ATTR_ALIGNMENT(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 	ql_dbg(ql_dbg_disc, vha, 0x20c5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 	    "HOSTNAME = %s.\n", eiter->a.host_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 	if (callopt == CALLOPT_FDMI1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 	/* Node Name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 	eiter->type = cpu_to_be16(FDMI_PORT_NODE_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 	memcpy(eiter->a.node_name, vha->node_name, sizeof(eiter->a.node_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 	alen = sizeof(eiter->a.node_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 	ql_dbg(ql_dbg_disc, vha, 0x20c6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 	    "NODENAME = %016llx.\n", wwn_to_u64(eiter->a.node_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 	/* Port Name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 	eiter->type = cpu_to_be16(FDMI_PORT_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 	memcpy(eiter->a.port_name, vha->port_name, sizeof(eiter->a.port_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 	alen = sizeof(eiter->a.port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 	ql_dbg(ql_dbg_disc, vha, 0x20c7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 	    "PORTNAME = %016llx.\n", wwn_to_u64(eiter->a.port_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 	/* Port Symbolic Name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 	eiter->type = cpu_to_be16(FDMI_PORT_SYM_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 	alen = qla2x00_get_sym_node_name(vha, eiter->a.port_sym_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 	    sizeof(eiter->a.port_sym_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 	alen += FDMI_ATTR_ALIGNMENT(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 	ql_dbg(ql_dbg_disc, vha, 0x20c8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 	    "PORT SYMBOLIC NAME = %s\n", eiter->a.port_sym_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 	/* Port Type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 	eiter->type = cpu_to_be16(FDMI_PORT_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 	eiter->a.port_type = cpu_to_be32(NS_NX_PORT_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 	alen = sizeof(eiter->a.port_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 	ql_dbg(ql_dbg_disc, vha, 0x20c9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 	    "PORT TYPE = %x.\n", be32_to_cpu(eiter->a.port_type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 	/* Supported Class of Service */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 	eiter->type = cpu_to_be16(FDMI_PORT_SUPP_COS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 	eiter->a.port_supported_cos = cpu_to_be32(FC_CLASS_3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 	alen = sizeof(eiter->a.port_supported_cos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 	ql_dbg(ql_dbg_disc, vha, 0x20ca,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 	    "SUPPORTED COS = %08x\n", be32_to_cpu(eiter->a.port_supported_cos));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 	/* Port Fabric Name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 	eiter->type = cpu_to_be16(FDMI_PORT_FABRIC_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 	memcpy(eiter->a.fabric_name, vha->fabric_node_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 	    sizeof(eiter->a.fabric_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 	alen = sizeof(eiter->a.fabric_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 	ql_dbg(ql_dbg_disc, vha, 0x20cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 	    "FABRIC NAME = %016llx.\n", wwn_to_u64(eiter->a.fabric_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 	/* FC4_type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 	eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 	eiter->a.port_fc4_type[0] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 	eiter->a.port_fc4_type[1] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 	eiter->a.port_fc4_type[2] = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 	eiter->a.port_fc4_type[3] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 	alen = sizeof(eiter->a.port_fc4_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 	ql_dbg(ql_dbg_disc, vha, 0x20cc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 	    "PORT ACTIVE FC4 TYPE = %016llx.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 	    *(uint64_t *)eiter->a.port_fc4_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 	/* Port State */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 	eiter->type = cpu_to_be16(FDMI_PORT_STATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 	eiter->a.port_state = cpu_to_be32(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 	alen = sizeof(eiter->a.port_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 	ql_dbg(ql_dbg_disc, vha, 0x20cd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 	    "PORT_STATE = %x.\n", be32_to_cpu(eiter->a.port_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 	/* Number of Ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 	eiter->type = cpu_to_be16(FDMI_PORT_COUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 	eiter->a.num_ports = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 	alen = sizeof(eiter->a.num_ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 	ql_dbg(ql_dbg_disc, vha, 0x20ce,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 	    "PORT COUNT = %x.\n", be32_to_cpu(eiter->a.num_ports));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 	/* Port Identifier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 	eiter->type = cpu_to_be16(FDMI_PORT_IDENTIFIER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 	eiter->a.port_id = cpu_to_be32(vha->d_id.b24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 	alen = sizeof(eiter->a.port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 	ql_dbg(ql_dbg_disc, vha, 0x20cf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 	    "PORT ID = %x.\n", be32_to_cpu(eiter->a.port_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 	if (callopt == CALLOPT_FDMI2 || !ql2xsmartsan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 	/* Smart SAN Service Category (Populate Smart SAN Initiator)*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 	eiter->type = cpu_to_be16(FDMI_SMARTSAN_SERVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 	alen = scnprintf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 		eiter->a.smartsan_service, sizeof(eiter->a.smartsan_service),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 		"%s", "Smart SAN Initiator");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 	alen += FDMI_ATTR_ALIGNMENT(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 	ql_dbg(ql_dbg_disc, vha, 0x20d0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 	    "SMARTSAN SERVICE CATEGORY = %s.\n", eiter->a.smartsan_service);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 	/* Smart SAN GUID (NWWN+PWWN) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 	eiter->type = cpu_to_be16(FDMI_SMARTSAN_GUID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 	memcpy(eiter->a.smartsan_guid, vha->node_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 	memcpy(eiter->a.smartsan_guid + WWN_SIZE, vha->port_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 	alen = sizeof(eiter->a.smartsan_guid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 	ql_dbg(ql_dbg_disc, vha, 0x20d1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 	    "Smart SAN GUID = %016llx-%016llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 	    wwn_to_u64(eiter->a.smartsan_guid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 	    wwn_to_u64(eiter->a.smartsan_guid + WWN_SIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 	/* Smart SAN Version (populate "Smart SAN Version 1.0") */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 	eiter->type = cpu_to_be16(FDMI_SMARTSAN_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 	alen = scnprintf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 		eiter->a.smartsan_version, sizeof(eiter->a.smartsan_version),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 		"%s", "Smart SAN Version 2.0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 	alen += FDMI_ATTR_ALIGNMENT(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 	ql_dbg(ql_dbg_disc, vha, 0x20d2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 	    "SMARTSAN VERSION = %s\n", eiter->a.smartsan_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 	/* Smart SAN Product Name (Specify Adapter Model No) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 	eiter->type = cpu_to_be16(FDMI_SMARTSAN_PROD_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 	alen = scnprintf(eiter->a.smartsan_prod_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 		sizeof(eiter->a.smartsan_prod_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 		"ISP%04x", ha->pdev->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 	alen += FDMI_ATTR_ALIGNMENT(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) 	ql_dbg(ql_dbg_disc, vha, 0x20d3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 	    "SMARTSAN PRODUCT NAME = %s\n", eiter->a.smartsan_prod_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 	/* Smart SAN Port Info (specify: 1=Physical, 2=NPIV, 3=SRIOV) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) 	eiter->type = cpu_to_be16(FDMI_SMARTSAN_PORT_INFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 	eiter->a.smartsan_port_info = cpu_to_be32(vha->vp_idx ? 2 : 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 	alen = sizeof(eiter->a.smartsan_port_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 	ql_dbg(ql_dbg_disc, vha, 0x20d4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 	    "SMARTSAN PORT INFO = %x\n", eiter->a.smartsan_port_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 	/* Smart SAN Security Support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 	eiter = entries + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 	eiter->type = cpu_to_be16(FDMI_SMARTSAN_SECURITY_SUPPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) 	eiter->a.smartsan_security_support = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 	alen = sizeof(eiter->a.smartsan_security_support);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 	alen += FDMI_ATTR_TYPELEN(eiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) 	eiter->len = cpu_to_be16(alen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 	size += alen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 	ql_dbg(ql_dbg_disc, vha, 0x20d6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 	    "SMARTSAN SECURITY SUPPORT = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 	    be32_to_cpu(eiter->a.smartsan_security_support));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 	return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142)  * qla2x00_fdmi_rhba() - perform RHBA FDMI registration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144)  * @callopt: Option to issue FDMI registration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) qla2x00_fdmi_rhba(scsi_qla_host_t *vha, unsigned int callopt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 	unsigned long size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 	unsigned int rval, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 	ms_iocb_entry_t *ms_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 	struct ct_sns_req *ct_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 	struct ct_sns_rsp *ct_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 	void *entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 	count = callopt != CALLOPT_FDMI1 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) 	    FDMI2_HBA_ATTR_COUNT : FDMI1_HBA_ATTR_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 	size = RHBA_RSP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 	ql_dbg(ql_dbg_disc, vha, 0x20e0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 	    "RHBA (callopt=%x count=%u size=%lu).\n", callopt, count, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 	/*   Request size adjusted after CT preparation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 	ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 	/* Prepare CT request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 	ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RHBA_CMD, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 	ct_rsp = &ha->ct_sns->p.rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 	/* Prepare FDMI command entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 	memcpy(ct_req->req.rhba.hba_identifier, vha->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 	    sizeof(ct_req->req.rhba.hba_identifier));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 	size += sizeof(ct_req->req.rhba.hba_identifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 	ct_req->req.rhba.entry_count = cpu_to_be32(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 	size += sizeof(ct_req->req.rhba.entry_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 	memcpy(ct_req->req.rhba.port_name, vha->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 	    sizeof(ct_req->req.rhba.port_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 	size += sizeof(ct_req->req.rhba.port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 	/* Attribute count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) 	ct_req->req.rhba.attrs.count = cpu_to_be32(count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 	size += sizeof(ct_req->req.rhba.attrs.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 	/* Attribute block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 	entries = &ct_req->req.rhba.attrs.entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 	size += qla2x00_hba_attributes(vha, entries, callopt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 	/* Update MS request size. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 	qla2x00_update_ms_fdmi_iocb(vha, size + 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 	ql_dbg(ql_dbg_disc, vha, 0x20e1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 	    "RHBA %016llx %016llx.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 	    wwn_to_u64(ct_req->req.rhba.hba_identifier),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 	    wwn_to_u64(ct_req->req.rhba.port_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 	ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x20e2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 	    entries, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 	/* Execute MS IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 	rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 	    sizeof(*ha->ms_iocb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 	if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 		ql_dbg(ql_dbg_disc, vha, 0x20e3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 		    "RHBA iocb failed (%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 	rval = qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RHBA");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 	if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 		if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 		    ct_rsp->header.explanation_code ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 		    CT_EXPL_ALREADY_REGISTERED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 			ql_dbg(ql_dbg_disc, vha, 0x20e4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 			    "RHBA already registered.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 			return QLA_ALREADY_REGISTERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) 		ql_dbg(ql_dbg_disc, vha, 0x20e5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) 		    "RHBA failed, CT Reason %#x, CT Explanation %#x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) 		    ct_rsp->header.reason_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) 		    ct_rsp->header.explanation_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 	ql_dbg(ql_dbg_disc, vha, 0x20e6, "RHBA exiting normally.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) qla2x00_fdmi_dhba(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 	ms_iocb_entry_t *ms_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 	struct ct_sns_req *ct_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 	struct ct_sns_rsp *ct_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 	/* Issue RPA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 	/* Prepare common MS IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 	ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, DHBA_REQ_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 	    DHBA_RSP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 	/* Prepare CT request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 	ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, DHBA_CMD, DHBA_RSP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 	ct_rsp = &ha->ct_sns->p.rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 	/* Prepare FDMI command arguments -- portname. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 	memcpy(ct_req->req.dhba.port_name, vha->port_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 	ql_dbg(ql_dbg_disc, vha, 0x2036,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 	    "DHBA portname = %8phN.\n", ct_req->req.dhba.port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 	/* Execute MS IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 	rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 	    sizeof(ms_iocb_entry_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 		/*EMPTY*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 		ql_dbg(ql_dbg_disc, vha, 0x2037,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 		    "DHBA issue IOCB failed (%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 	} else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "DHBA") !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 	    QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 		rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 		ql_dbg(ql_dbg_disc, vha, 0x2038,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 		    "DHBA exiting normally.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274)  * qla2x00_fdmi_rprt() perform RPRT registration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276)  * @callopt: Option to issue extended or standard FDMI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277)  *           command parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) qla2x00_fdmi_rprt(scsi_qla_host_t *vha, int callopt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) 	struct scsi_qla_host *base_vha = pci_get_drvdata(vha->hw->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 	ulong size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 	uint rval, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 	ms_iocb_entry_t *ms_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 	struct ct_sns_req *ct_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 	struct ct_sns_rsp *ct_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 	void *entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 	count = callopt == CALLOPT_FDMI2_SMARTSAN && ql2xsmartsan ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 		FDMI2_SMARTSAN_PORT_ATTR_COUNT :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 		callopt != CALLOPT_FDMI1 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 		FDMI2_PORT_ATTR_COUNT : FDMI1_PORT_ATTR_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 	size = RPRT_RSP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 	ql_dbg(ql_dbg_disc, vha, 0x20e8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 	    "RPRT (callopt=%x count=%u size=%lu).\n", callopt, count, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 	/* Request size adjusted after CT preparation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 	ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 	/* Prepare CT request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 	ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RPRT_CMD, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 	ct_rsp = &ha->ct_sns->p.rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 	/* Prepare FDMI command entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 	memcpy(ct_req->req.rprt.hba_identifier, base_vha->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 	    sizeof(ct_req->req.rprt.hba_identifier));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 	size += sizeof(ct_req->req.rprt.hba_identifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 	memcpy(ct_req->req.rprt.port_name, vha->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 	    sizeof(ct_req->req.rprt.port_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 	size += sizeof(ct_req->req.rprt.port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 	/* Attribute count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 	ct_req->req.rprt.attrs.count = cpu_to_be32(count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 	size += sizeof(ct_req->req.rprt.attrs.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 	/* Attribute block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 	entries = ct_req->req.rprt.attrs.entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 	size += qla2x00_port_attributes(vha, entries, callopt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 	/* Update MS request size. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 	qla2x00_update_ms_fdmi_iocb(vha, size + 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 	ql_dbg(ql_dbg_disc, vha, 0x20e9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 	    "RPRT %016llx  %016llx.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 	    wwn_to_u64(ct_req->req.rprt.port_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 	    wwn_to_u64(ct_req->req.rprt.port_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 	ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x20ea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 	    entries, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 	/* Execute MS IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 	rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 	    sizeof(*ha->ms_iocb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 	if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 		ql_dbg(ql_dbg_disc, vha, 0x20eb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 		    "RPRT iocb failed (%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 	rval = qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RPRT");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 	if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 		if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 		    ct_rsp->header.explanation_code ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 		    CT_EXPL_ALREADY_REGISTERED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 			ql_dbg(ql_dbg_disc, vha, 0x20ec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 			    "RPRT already registered.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 			return QLA_ALREADY_REGISTERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 		ql_dbg(ql_dbg_disc, vha, 0x20ed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 		    "RPRT failed, CT Reason code: %#x, CT Explanation %#x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 		    ct_rsp->header.reason_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 		    ct_rsp->header.explanation_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 	ql_dbg(ql_dbg_disc, vha, 0x20ee, "RPRT exiting normally.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355)  * qla2x00_fdmi_rpa() - perform RPA registration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357)  * @callopt: Option to issue FDMI registration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) qla2x00_fdmi_rpa(scsi_qla_host_t *vha, uint callopt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 	ulong size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 	uint rval, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 	ms_iocb_entry_t *ms_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 	struct ct_sns_req *ct_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 	struct ct_sns_rsp *ct_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 	void *entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 	count =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 	    callopt == CALLOPT_FDMI2_SMARTSAN && ql2xsmartsan ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 		FDMI2_SMARTSAN_PORT_ATTR_COUNT :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 	    callopt != CALLOPT_FDMI1 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 		FDMI2_PORT_ATTR_COUNT : FDMI1_PORT_ATTR_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 	size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 	    callopt != CALLOPT_FDMI1 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 		SMARTSAN_RPA_RSP_SIZE : RPA_RSP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 	ql_dbg(ql_dbg_disc, vha, 0x20f0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 	    "RPA (callopt=%x count=%u size=%lu).\n", callopt, count, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 	/* Request size adjusted after CT preparation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 	ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) 	/* Prepare CT request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 	ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RPA_CMD, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 	ct_rsp = &ha->ct_sns->p.rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 	/* Prepare FDMI command entries. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 	memcpy(ct_req->req.rpa.port_name, vha->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 	    sizeof(ct_req->req.rpa.port_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) 	size += sizeof(ct_req->req.rpa.port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) 	/* Attribute count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 	ct_req->req.rpa.attrs.count = cpu_to_be32(count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 	size += sizeof(ct_req->req.rpa.attrs.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 	/* Attribute block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 	entries = ct_req->req.rpa.attrs.entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 	size += qla2x00_port_attributes(vha, entries, callopt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 	/* Update MS request size. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 	qla2x00_update_ms_fdmi_iocb(vha, size + 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 	ql_dbg(ql_dbg_disc, vha, 0x20f1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 	    "RPA %016llx.\n", wwn_to_u64(ct_req->req.rpa.port_name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 	ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x20f2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 	    entries, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 	/* Execute MS IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 	rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 	    sizeof(*ha->ms_iocb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 	if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 		ql_dbg(ql_dbg_disc, vha, 0x20f3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 		    "RPA iocb failed (%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 	rval = qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RPA");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 	if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 		if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 		    ct_rsp->header.explanation_code ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 		    CT_EXPL_ALREADY_REGISTERED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 			ql_dbg(ql_dbg_disc, vha, 0x20f4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 			    "RPA already registered.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 			return QLA_ALREADY_REGISTERED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 		ql_dbg(ql_dbg_disc, vha, 0x20f5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 		    "RPA failed, CT Reason code: %#x, CT Explanation %#x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 		    ct_rsp->header.reason_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 		    ct_rsp->header.explanation_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 	ql_dbg(ql_dbg_disc, vha, 0x20f6, "RPA exiting normally.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446)  * qla2x00_fdmi_register() -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) qla2x00_fdmi_register(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 	int rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 	if (IS_QLA2100(ha) || IS_QLA2200(ha) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 	    IS_QLAFX00(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) 	rval = qla2x00_mgmt_svr_login(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 	if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 	/* For npiv/vport send rprt only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 	if (vha->vp_idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 		if (ql2xsmartsan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 			rval = qla2x00_fdmi_rprt(vha, CALLOPT_FDMI2_SMARTSAN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 		if (rval || !ql2xsmartsan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 			rval = qla2x00_fdmi_rprt(vha, CALLOPT_FDMI2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 		if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 			rval = qla2x00_fdmi_rprt(vha, CALLOPT_FDMI1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) 	/* Try fdmi2 first, if fails then try fdmi1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 	rval = qla2x00_fdmi_rhba(vha, CALLOPT_FDMI2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 	if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 		if (rval != QLA_ALREADY_REGISTERED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 			goto try_fdmi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 		rval = qla2x00_fdmi_dhba(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 		if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 			goto try_fdmi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) 		rval = qla2x00_fdmi_rhba(vha, CALLOPT_FDMI2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 		if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 			goto try_fdmi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 	if (ql2xsmartsan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 		rval = qla2x00_fdmi_rpa(vha, CALLOPT_FDMI2_SMARTSAN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 	if (rval || !ql2xsmartsan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 		rval = qla2x00_fdmi_rpa(vha, CALLOPT_FDMI2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 	if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 		goto try_fdmi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) try_fdmi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 	rval = qla2x00_fdmi_rhba(vha, CALLOPT_FDMI1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 	if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 		if (rval != QLA_ALREADY_REGISTERED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 			return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 		rval = qla2x00_fdmi_dhba(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 		if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 			return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 		rval = qla2x00_fdmi_rhba(vha, CALLOPT_FDMI1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 		if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 			return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 	rval = qla2x00_fdmi_rpa(vha, CALLOPT_FDMI1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522)  * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524)  * @list: switch info entries to populate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) qla2x00_gfpn_id(scsi_qla_host_t *vha, sw_info_t *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 	int		rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 	uint16_t	i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 	ms_iocb_entry_t	*ms_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 	struct ct_sns_req	*ct_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 	struct ct_sns_rsp	*ct_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 	struct ct_arg arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 	if (!IS_IIDMA_CAPABLE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 	arg.iocb = ha->ms_iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 	arg.req_dma = ha->ct_sns_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 	arg.rsp_dma = ha->ct_sns_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 	arg.req_size = GFPN_ID_REQ_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 	arg.rsp_size = GFPN_ID_RSP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 	arg.nport_handle = NPH_SNS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 	for (i = 0; i < ha->max_fibre_devices; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 		/* Issue GFPN_ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 		/* Prepare common MS IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 		ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 		/* Prepare CT request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 		ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFPN_ID_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 		    GFPN_ID_RSP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 		ct_rsp = &ha->ct_sns->p.rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 		/* Prepare CT arguments -- port_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 		ct_req->req.port_id.port_id = port_id_to_be_id(list[i].d_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 		/* Execute MS IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 		rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 		    sizeof(ms_iocb_entry_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 		if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 			/*EMPTY*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 			ql_dbg(ql_dbg_disc, vha, 0x2023,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) 			    "GFPN_ID issue IOCB failed (%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 		} else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 		    "GFPN_ID") != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 			rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 			/* Save fabric portname */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) 			memcpy(list[i].fabric_port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 			    ct_rsp->rsp.gfpn_id.port_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 		/* Last device exit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 		if (list[i].d_id.b.rsvd_1 != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) static inline struct ct_sns_req *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) qla24xx_prep_ct_fm_req(struct ct_sns_pkt *p, uint16_t cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591)     uint16_t rsp_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) 	memset(p, 0, sizeof(struct ct_sns_pkt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) 	p->p.req.header.revision = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 	p->p.req.header.gs_type = 0xFA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) 	p->p.req.header.gs_subtype = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 	p->p.req.command = cpu_to_be16(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 	p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 	return &p->p.req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) static uint16_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) qla2x00_port_speed_capability(uint16_t speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 	switch (speed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 	case BIT_15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 		return PORT_SPEED_1GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 	case BIT_14:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 		return PORT_SPEED_2GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 	case BIT_13:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 		return PORT_SPEED_4GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) 	case BIT_12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 		return PORT_SPEED_10GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 	case BIT_11:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 		return PORT_SPEED_8GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 	case BIT_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 		return PORT_SPEED_16GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) 	case BIT_8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 		return PORT_SPEED_32GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) 	case BIT_7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) 		return PORT_SPEED_64GB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) 		return PORT_SPEED_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630)  * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632)  * @list: switch info entries to populate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 	int		rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 	uint16_t	i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) 	ms_iocb_entry_t *ms_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 	struct ct_sns_req	*ct_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) 	struct ct_sns_rsp	*ct_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) 	struct ct_arg arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) 	if (!IS_IIDMA_CAPABLE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 	if (!ha->flags.gpsc_supported)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) 	rval = qla2x00_mgmt_svr_login(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) 	if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 	arg.iocb = ha->ms_iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 	arg.req_dma = ha->ct_sns_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 	arg.rsp_dma = ha->ct_sns_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 	arg.req_size = GPSC_REQ_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 	arg.rsp_size = GPSC_RSP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 	arg.nport_handle = vha->mgmt_svr_loop_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 	for (i = 0; i < ha->max_fibre_devices; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) 		/* Issue GFPN_ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) 		/* Prepare common MS IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) 		ms_pkt = qla24xx_prep_ms_iocb(vha, &arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) 		/* Prepare CT request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) 		ct_req = qla24xx_prep_ct_fm_req(ha->ct_sns, GPSC_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 		    GPSC_RSP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) 		ct_rsp = &ha->ct_sns->p.rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 		/* Prepare CT arguments -- port_name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 		memcpy(ct_req->req.gpsc.port_name, list[i].fabric_port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 		    WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 		/* Execute MS IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 		rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 		    sizeof(ms_iocb_entry_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) 		if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 			/*EMPTY*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 			ql_dbg(ql_dbg_disc, vha, 0x2059,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 			    "GPSC issue IOCB failed (%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 		} else if ((rval = qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 		    "GPSC")) != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 			/* FM command unsupported? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 			if (rval == QLA_INVALID_COMMAND &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 			    (ct_rsp->header.reason_code ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 				CT_REASON_INVALID_COMMAND_CODE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 			     ct_rsp->header.reason_code ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) 				CT_REASON_COMMAND_UNSUPPORTED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 				ql_dbg(ql_dbg_disc, vha, 0x205a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) 				    "GPSC command unsupported, disabling "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 				    "query.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 				ha->flags.gpsc_supported = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) 				rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) 			rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 			list->fp_speed = qla2x00_port_speed_capability(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 			    be16_to_cpu(ct_rsp->rsp.gpsc.speed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) 			ql_dbg(ql_dbg_disc, vha, 0x205b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 			    "GPSC ext entry - fpn "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) 			    "%8phN speeds=%04x speed=%04x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 			    list[i].fabric_port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 			    be16_to_cpu(ct_rsp->rsp.gpsc.speeds),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 			    be16_to_cpu(ct_rsp->rsp.gpsc.speed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) 		/* Last device exit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 		if (list[i].d_id.b.rsvd_1 != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720)  * qla2x00_gff_id() - SNS Get FC-4 Features (GFF_ID) query.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723)  * @list: switch info entries to populate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) 	int		rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) 	uint16_t	i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) 	ms_iocb_entry_t	*ms_pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) 	struct ct_sns_req	*ct_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) 	struct ct_sns_rsp	*ct_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) 	uint8_t fcp_scsi_features = 0, nvme_features = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) 	struct ct_arg arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) 	for (i = 0; i < ha->max_fibre_devices; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) 		/* Set default FC4 Type as UNKNOWN so the default is to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) 		 * Process this port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) 		list[i].fc4_type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) 		/* Do not attempt GFF_ID if we are not FWI_2 capable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) 		if (!IS_FWI2_CAPABLE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 		arg.iocb = ha->ms_iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) 		arg.req_dma = ha->ct_sns_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 		arg.rsp_dma = ha->ct_sns_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) 		arg.req_size = GFF_ID_REQ_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 		arg.rsp_size = GFF_ID_RSP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) 		arg.nport_handle = NPH_SNS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 		/* Prepare common MS IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 		ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 		/* Prepare CT request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 		ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFF_ID_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 		    GFF_ID_RSP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 		ct_rsp = &ha->ct_sns->p.rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) 		/* Prepare CT arguments -- port_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) 		ct_req->req.port_id.port_id = port_id_to_be_id(list[i].d_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 		/* Execute MS IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 		rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 		   sizeof(ms_iocb_entry_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) 		if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) 			ql_dbg(ql_dbg_disc, vha, 0x205c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) 			    "GFF_ID issue IOCB failed (%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) 		} else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) 			       "GFF_ID") != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) 			ql_dbg(ql_dbg_disc, vha, 0x205d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) 			    "GFF_ID IOCB status had a failure status code.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 			fcp_scsi_features =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 			   ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 			fcp_scsi_features &= 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 			if (fcp_scsi_features) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 				list[i].fc4_type = FS_FC4TYPE_FCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 				list[i].fc4_features = fcp_scsi_features;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 			nvme_features =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 			    ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 			nvme_features &= 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 			if (nvme_features) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) 				list[i].fc4_type |= FS_FC4TYPE_NVME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) 				list[i].fc4_features = nvme_features;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) 		/* Last device exit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) 		if (list[i].d_id.b.rsvd_1 != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) int qla24xx_post_gpsc_work(struct scsi_qla_host *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) 	struct qla_work_evt *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) 	e = qla2x00_alloc_work(vha, QLA_EVT_GPSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) 	if (!e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) 	e->u.fcport.fcport = fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) 	return qla2x00_post_work(vha, e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) void qla24xx_handle_gpsc_event(scsi_qla_host_t *vha, struct event_arg *ea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 	struct fc_port *fcport = ea->fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 	ql_dbg(ql_dbg_disc, vha, 0x20d8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 	    "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d lid %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 	    __func__, fcport->port_name, fcport->disc_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 	    fcport->fw_login_state, ea->rc, ea->sp->gen2, fcport->login_gen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 	    ea->sp->gen2, fcport->rscn_gen|ea->sp->gen1, fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 	if (fcport->disc_state == DSC_DELETE_PEND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) 	if (ea->sp->gen2 != fcport->login_gen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 		/* target side must have changed it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) 		ql_dbg(ql_dbg_disc, vha, 0x20d3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) 		    "%s %8phC generation changed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) 		    __func__, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 	} else if (ea->sp->gen1 != fcport->rscn_gen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 	qla_post_iidma_work(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) static void qla24xx_async_gpsc_sp_done(srb_t *sp, int res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 	struct scsi_qla_host *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) 	fc_port_t *fcport = sp->fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 	struct ct_sns_rsp       *ct_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 	struct event_arg ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) 	ct_rsp = &fcport->ct_desc.ct_sns->p.rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 	ql_dbg(ql_dbg_disc, vha, 0x2053,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 	    "Async done-%s res %x, WWPN %8phC \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 	    sp->name, res, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 	fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 	if (res == QLA_FUNCTION_TIMEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 	if (res == (DID_ERROR << 16)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) 		/* entry status error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) 	} else if (res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) 		if ((ct_rsp->header.reason_code ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) 			 CT_REASON_INVALID_COMMAND_CODE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) 			(ct_rsp->header.reason_code ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 			CT_REASON_COMMAND_UNSUPPORTED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) 			ql_dbg(ql_dbg_disc, vha, 0x2019,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) 			    "GPSC command unsupported, disabling query.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) 			ha->flags.gpsc_supported = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) 		fcport->fp_speed = qla2x00_port_speed_capability(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) 		    be16_to_cpu(ct_rsp->rsp.gpsc.speed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 		ql_dbg(ql_dbg_disc, vha, 0x2054,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 		    "Async-%s OUT WWPN %8phC speeds=%04x speed=%04x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 		    sp->name, fcport->fabric_port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 		    be16_to_cpu(ct_rsp->rsp.gpsc.speeds),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 		    be16_to_cpu(ct_rsp->rsp.gpsc.speed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 	memset(&ea, 0, sizeof(ea));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 	ea.rc = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) 	ea.fcport = fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 	ea.sp = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) 	qla24xx_handle_gpsc_event(vha, &ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) int qla24xx_async_gpsc(scsi_qla_host_t *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) 	int rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 	struct ct_sns_req       *ct_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 	srb_t *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 	if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 	if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 	sp->type = SRB_CT_PTHRU_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 	sp->name = "gpsc";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 	sp->gen1 = fcport->rscn_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 	sp->gen2 = fcport->login_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 	/* CT_IU preamble  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) 	ct_req = qla24xx_prep_ct_fm_req(fcport->ct_desc.ct_sns, GPSC_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) 		GPSC_RSP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) 	/* GPSC req */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 	memcpy(ct_req->req.gpsc.port_name, fcport->fabric_port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) 		WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 	sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) 	sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) 	sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) 	sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) 	sp->u.iocb_cmd.u.ctarg.req_size = GPSC_REQ_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 	sp->u.iocb_cmd.u.ctarg.rsp_size = GPSC_RSP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) 	sp->u.iocb_cmd.u.ctarg.nport_handle = vha->mgmt_svr_loop_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) 	sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 	sp->done = qla24xx_async_gpsc_sp_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 	ql_dbg(ql_dbg_disc, vha, 0x205e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) 	    "Async-%s %8phC hdl=%x loopid=%x portid=%02x%02x%02x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 	    sp->name, fcport->port_name, sp->handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 	    fcport->loop_id, fcport->d_id.b.domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 	    fcport->d_id.b.area, fcport->d_id.b.al_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) 	rval = qla2x00_start_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) 	if (rval != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) done_free_sp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) int qla24xx_post_gpnid_work(struct scsi_qla_host *vha, port_id_t *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) 	struct qla_work_evt *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) 	if (test_bit(UNLOADING, &vha->dpc_flags) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) 	    (vha->vp_idx && test_bit(VPORT_DELETE, &vha->dpc_flags)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) 	e = qla2x00_alloc_work(vha, QLA_EVT_GPNID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) 	if (!e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) 	e->u.gpnid.id = *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) 	return qla2x00_post_work(vha, e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) void qla24xx_sp_unmap(scsi_qla_host_t *vha, srb_t *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) 	struct srb_iocb *c = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) 	switch (sp->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) 	case SRB_ELS_DCMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) 		qla2x00_els_dcmd2_free(vha, &c->u.els_plogi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) 	case SRB_CT_PTHRU_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) 		if (sp->u.iocb_cmd.u.ctarg.req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) 			dma_free_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) 			    sp->u.iocb_cmd.u.ctarg.req_allocated_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) 			    sp->u.iocb_cmd.u.ctarg.req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) 			    sp->u.iocb_cmd.u.ctarg.req_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) 			sp->u.iocb_cmd.u.ctarg.req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) 		if (sp->u.iocb_cmd.u.ctarg.rsp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) 			dma_free_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) 			    sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) 			    sp->u.iocb_cmd.u.ctarg.rsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) 			    sp->u.iocb_cmd.u.ctarg.rsp_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) 			sp->u.iocb_cmd.u.ctarg.rsp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) 	fc_port_t *fcport, *conflict, *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) 	u16 data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) 	ql_dbg(ql_dbg_disc, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) 	    "%s %d port_id: %06x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) 	    __func__, __LINE__, ea->id.b24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) 	if (ea->rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) 		/* cable is disconnected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) 		list_for_each_entry_safe(fcport, t, &vha->vp_fcports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) 			if (fcport->d_id.b24 == ea->id.b24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) 				fcport->scan_state = QLA_FCPORT_SCAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) 			qlt_schedule_sess_for_deletion(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) 		/* cable is connected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) 		fcport = qla2x00_find_fcport_by_wwpn(vha, ea->port_name, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) 		if (fcport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) 			list_for_each_entry_safe(conflict, t, &vha->vp_fcports,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) 			    list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) 				if ((conflict->d_id.b24 == ea->id.b24) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) 				    (fcport != conflict))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) 					/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) 					 * 2 fcports with conflict Nport ID or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) 					 * an existing fcport is having nport ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) 					 * conflict with new fcport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) 					 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) 					conflict->scan_state = QLA_FCPORT_SCAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) 				qlt_schedule_sess_for_deletion(conflict);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) 			fcport->scan_needed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) 			fcport->rscn_gen++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) 			fcport->scan_state = QLA_FCPORT_FOUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) 			fcport->flags |= FCF_FABRIC_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) 			if (fcport->login_retry == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) 				fcport->login_retry =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) 					vha->hw->login_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) 				ql_dbg(ql_dbg_disc, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) 				    "Port login retry %8phN, lid 0x%04x cnt=%d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) 				    fcport->port_name, fcport->loop_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) 				    fcport->login_retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) 			switch (fcport->disc_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) 			case DSC_LOGIN_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) 				/* recheck session is still intact. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) 				ql_dbg(ql_dbg_disc, vha, 0x210d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) 				    "%s %d %8phC revalidate session with ADISC\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) 				    __func__, __LINE__, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) 				data[0] = data[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) 				qla2x00_post_async_adisc_work(vha, fcport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) 				    data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) 			case DSC_DELETED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) 				ql_dbg(ql_dbg_disc, vha, 0x210d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) 				    "%s %d %8phC login\n", __func__, __LINE__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) 				    fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) 				fcport->d_id = ea->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) 				qla24xx_fcport_handle_login(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 			case DSC_DELETE_PEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) 				fcport->d_id = ea->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) 			default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) 				fcport->d_id = ea->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) 			list_for_each_entry_safe(conflict, t, &vha->vp_fcports,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) 			    list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) 				if (conflict->d_id.b24 == ea->id.b24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) 					/* 2 fcports with conflict Nport ID or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) 					 * an existing fcport is having nport ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) 					 * conflict with new fcport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) 					 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) 					ql_dbg(ql_dbg_disc, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) 					    "%s %d %8phC DS %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) 					    __func__, __LINE__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) 					    conflict->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) 					    conflict->disc_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) 					conflict->scan_state = QLA_FCPORT_SCAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) 					qlt_schedule_sess_for_deletion(conflict);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) 			/* create new fcport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) 			ql_dbg(ql_dbg_disc, vha, 0x2065,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) 			    "%s %d %8phC post new sess\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) 			    __func__, __LINE__, ea->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) 			qla24xx_post_newsess_work(vha, &ea->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) 			    ea->port_name, NULL, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) static void qla2x00_async_gpnid_sp_done(srb_t *sp, int res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) 	struct scsi_qla_host *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) 	struct ct_sns_req *ct_req =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) 	    (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) 	struct ct_sns_rsp *ct_rsp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) 	    (struct ct_sns_rsp *)sp->u.iocb_cmd.u.ctarg.rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) 	struct event_arg ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) 	struct qla_work_evt *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) 	if (res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) 		ql_dbg(ql_dbg_disc, vha, 0x2066,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) 		    "Async done-%s fail res %x rscn gen %d ID %3phC. %8phC\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) 		    sp->name, res, sp->gen1, &ct_req->req.port_id.port_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) 		    ct_rsp->rsp.gpn_id.port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) 		ql_dbg(ql_dbg_disc, vha, 0x2066,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) 		    "Async done-%s good rscn gen %d ID %3phC. %8phC\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) 		    sp->name, sp->gen1, &ct_req->req.port_id.port_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) 		    ct_rsp->rsp.gpn_id.port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) 	memset(&ea, 0, sizeof(ea));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) 	memcpy(ea.port_name, ct_rsp->rsp.gpn_id.port_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) 	ea.sp = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) 	ea.id = be_to_port_id(ct_req->req.port_id.port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) 	ea.rc = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) 	spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) 	list_del(&sp->elem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) 	spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) 	if (res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) 		if (res == QLA_FUNCTION_TIMEOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) 			qla24xx_post_gpnid_work(sp->vha, &ea.id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) 			sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) 	} else if (sp->gen1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) 		/* There was another RSCN for this Nport ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) 		qla24xx_post_gpnid_work(sp->vha, &ea.id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) 		sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) 	qla24xx_handle_gpnid_event(vha, &ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) 	e = qla2x00_alloc_work(vha, QLA_EVT_UNMAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) 	if (!e) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) 		/* please ignore kernel warning. otherwise, we have mem leak. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) 		dma_free_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) 				  sp->u.iocb_cmd.u.ctarg.req_allocated_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) 				  sp->u.iocb_cmd.u.ctarg.req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) 				  sp->u.iocb_cmd.u.ctarg.req_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) 		sp->u.iocb_cmd.u.ctarg.req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) 		dma_free_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) 				  sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) 				  sp->u.iocb_cmd.u.ctarg.rsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) 				  sp->u.iocb_cmd.u.ctarg.rsp_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) 		sp->u.iocb_cmd.u.ctarg.rsp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) 		sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) 	e->u.iosb.sp = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) 	qla2x00_post_work(vha, e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) /* Get WWPN with Nport ID. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) 	int rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) 	struct ct_sns_req       *ct_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) 	srb_t *sp, *tsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) 	struct ct_sns_pkt *ct_sns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) 	if (!vha->flags.online)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) 	sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) 	if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) 	sp->type = SRB_CT_PTHRU_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) 	sp->name = "gpnid";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) 	sp->u.iocb_cmd.u.ctarg.id = *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) 	sp->gen1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) 	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) 	spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) 	list_for_each_entry(tsp, &vha->gpnid_list, elem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) 		if (tsp->u.iocb_cmd.u.ctarg.id.b24 == id->b24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) 			tsp->gen1++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) 			spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) 			sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) 	list_add_tail(&sp->elem, &vha->gpnid_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) 	spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) 	sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) 		sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) 		GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) 	sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) 	if (!sp->u.iocb_cmd.u.ctarg.req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) 		ql_log(ql_log_warn, vha, 0xd041,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) 		    "Failed to allocate ct_sns request.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) 	sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) 		sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) 		GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) 	sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) 	if (!sp->u.iocb_cmd.u.ctarg.rsp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) 		ql_log(ql_log_warn, vha, 0xd042,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) 		    "Failed to allocate ct_sns request.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) 	ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) 	memset(ct_sns, 0, sizeof(*ct_sns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) 	ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) 	/* CT_IU preamble  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) 	ct_req = qla2x00_prep_ct_req(ct_sns, GPN_ID_CMD, GPN_ID_RSP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) 	/* GPN_ID req */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) 	ct_req->req.port_id.port_id = port_id_to_be_id(*id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) 	sp->u.iocb_cmd.u.ctarg.req_size = GPN_ID_REQ_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) 	sp->u.iocb_cmd.u.ctarg.rsp_size = GPN_ID_RSP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) 	sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) 	sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) 	sp->done = qla2x00_async_gpnid_sp_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) 	ql_dbg(ql_dbg_disc, vha, 0x2067,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) 	    "Async-%s hdl=%x ID %3phC.\n", sp->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) 	    sp->handle, &ct_req->req.port_id.port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) 	rval = qla2x00_start_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) 	if (rval != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) done_free_sp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) 	spin_lock_irqsave(&vha->hw->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) 	list_del(&sp->elem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) 	spin_unlock_irqrestore(&vha->hw->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) 	if (sp->u.iocb_cmd.u.ctarg.req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) 		dma_free_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) 			sizeof(struct ct_sns_pkt),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) 			sp->u.iocb_cmd.u.ctarg.req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) 			sp->u.iocb_cmd.u.ctarg.req_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) 		sp->u.iocb_cmd.u.ctarg.req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) 	if (sp->u.iocb_cmd.u.ctarg.rsp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) 		dma_free_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) 			sizeof(struct ct_sns_pkt),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) 			sp->u.iocb_cmd.u.ctarg.rsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) 			sp->u.iocb_cmd.u.ctarg.rsp_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) 		sp->u.iocb_cmd.u.ctarg.rsp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) 	fc_port_t *fcport = ea->fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) 	qla24xx_post_gnl_work(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) void qla24xx_async_gffid_sp_done(srb_t *sp, int res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) 	struct scsi_qla_host *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) 	fc_port_t *fcport = sp->fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) 	struct ct_sns_rsp *ct_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) 	struct event_arg ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) 	uint8_t fc4_scsi_feat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) 	uint8_t fc4_nvme_feat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) 	ql_dbg(ql_dbg_disc, vha, 0x2133,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) 	       "Async done-%s res %x ID %x. %8phC\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) 	       sp->name, res, fcport->d_id.b24, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) 	fcport->flags &= ~FCF_ASYNC_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) 	ct_rsp = &fcport->ct_desc.ct_sns->p.rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) 	fc4_scsi_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) 	fc4_nvme_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) 	 * FC-GS-7, 5.2.3.12 FC-4 Features - format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) 	 * The format of the FC-4 Features object, as defined by the FC-4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) 	 * Shall be an array of 4-bit values, one for each type code value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) 	if (!res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) 		if (fc4_scsi_feat & 0xf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) 			/* w1 b00:03 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) 			fcport->fc4_type = FS_FC4TYPE_FCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) 			fcport->fc4_features = fc4_scsi_feat & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) 		if (fc4_nvme_feat & 0xf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) 			/* w5 [00:03]/28h */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) 			fcport->fc4_type |= FS_FC4TYPE_NVME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) 			fcport->fc4_features = fc4_nvme_feat & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) 	memset(&ea, 0, sizeof(ea));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) 	ea.sp = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) 	ea.fcport = sp->fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) 	ea.rc = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) 	qla24xx_handle_gffid_event(vha, &ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) /* Get FC4 Feature with Nport ID. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) 	int rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) 	struct ct_sns_req       *ct_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) 	srb_t *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) 	if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) 	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) 	if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) 	fcport->flags |= FCF_ASYNC_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) 	sp->type = SRB_CT_PTHRU_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) 	sp->name = "gffid";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) 	sp->gen1 = fcport->rscn_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) 	sp->gen2 = fcport->login_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) 	sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) 	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) 	/* CT_IU preamble  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) 	ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GFF_ID_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) 	    GFF_ID_RSP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) 	ct_req->req.gff_id.port_id[0] = fcport->d_id.b.domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) 	ct_req->req.gff_id.port_id[1] = fcport->d_id.b.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) 	ct_req->req.gff_id.port_id[2] = fcport->d_id.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) 	sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) 	sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) 	sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) 	sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) 	sp->u.iocb_cmd.u.ctarg.req_size = GFF_ID_REQ_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) 	sp->u.iocb_cmd.u.ctarg.rsp_size = GFF_ID_RSP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) 	sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) 	sp->done = qla24xx_async_gffid_sp_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) 	ql_dbg(ql_dbg_disc, vha, 0x2132,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) 	    "Async-%s hdl=%x  %8phC.\n", sp->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) 	    sp->handle, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) 	rval = qla2x00_start_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) 	if (rval != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) done_free_sp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) 	fcport->flags &= ~FCF_ASYNC_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) /* GPN_FT + GNN_FT*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) static int qla2x00_is_a_vp(scsi_qla_host_t *vha, u64 wwn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) 	scsi_qla_host_t *vp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) 	u64 twwn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) 	if (!ha->num_vhosts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) 	spin_lock_irqsave(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) 	list_for_each_entry(vp, &ha->vp_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) 		twwn = wwn_to_u64(vp->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) 		if (wwn == twwn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) 			rc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) 	spin_unlock_irqrestore(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) 	fc_port_t *fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) 	u32 i, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) 	bool found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) 	struct fab_scan_rp *rp, *trp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) 	u8 recheck = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) 	u16 dup = 0, dup_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) 	ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) 	    "%s enter\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) 	if (sp->gen1 != vha->hw->base_qpair->chip_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) 		ql_dbg(ql_dbg_disc, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) 		    "%s scan stop due to chip reset %x/%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) 		    sp->name, sp->gen1, vha->hw->base_qpair->chip_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) 	rc = sp->rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) 	if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) 		vha->scan.scan_retry++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) 		if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) 			set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) 			set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) 			ql_dbg(ql_dbg_disc, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) 			    "%s: Fabric scan failed for %d retries.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) 			    __func__, vha->scan.scan_retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) 			 * Unable to scan any rports. logout loop below
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) 			 * will unregister all sessions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) 			list_for_each_entry(fcport, &vha->vp_fcports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) 				if ((fcport->flags & FCF_FABRIC_DEVICE) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) 					fcport->scan_state = QLA_FCPORT_SCAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) 			goto login_logout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) 	vha->scan.scan_retry = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) 	list_for_each_entry(fcport, &vha->vp_fcports, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) 		fcport->scan_state = QLA_FCPORT_SCAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) 	for (i = 0; i < vha->hw->max_fibre_devices; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) 		u64 wwn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) 		int k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) 		rp = &vha->scan.l[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) 		found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) 		wwn = wwn_to_u64(rp->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) 		if (wwn == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) 		/* Remove duplicate NPORT ID entries from switch data base */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) 		for (k = i + 1; k < vha->hw->max_fibre_devices; k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) 			trp = &vha->scan.l[k];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) 			if (rp->id.b24 == trp->id.b24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) 				dup = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) 				dup_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) 				ql_dbg(ql_dbg_disc + ql_dbg_verbose,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) 				    vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) 				    "Detected duplicate NPORT ID from switch data base: ID %06x WWN %8phN WWN %8phN\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) 				    rp->id.b24, rp->port_name, trp->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) 				memset(trp, 0, sizeof(*trp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) 		if (!memcmp(rp->port_name, vha->port_name, WWN_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) 		/* Bypass reserved domain fields. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) 		if ((rp->id.b.domain & 0xf0) == 0xf0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) 		/* Bypass virtual ports of the same host. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) 		if (qla2x00_is_a_vp(vha, wwn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) 		list_for_each_entry(fcport, &vha->vp_fcports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) 			if (memcmp(rp->port_name, fcport->port_name, WWN_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) 			fcport->scan_state = QLA_FCPORT_FOUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) 			fcport->last_rscn_gen = fcport->rscn_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) 			found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) 			 * If device was not a fabric device before.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) 			if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) 				qla2x00_clear_loop_id(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) 				fcport->flags |= FCF_FABRIC_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) 			} else if (fcport->d_id.b24 != rp->id.b24 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) 				   (fcport->scan_needed &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) 				    fcport->port_type != FCT_INITIATOR &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) 				    fcport->port_type != FCT_NVME_INITIATOR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) 				qlt_schedule_sess_for_deletion(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) 			fcport->d_id.b24 = rp->id.b24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) 			fcport->scan_needed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) 		if (!found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) 			ql_dbg(ql_dbg_disc, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) 			    "%s %d %8phC post new sess\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) 			    __func__, __LINE__, rp->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) 			qla24xx_post_newsess_work(vha, &rp->id, rp->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) 			    rp->node_name, NULL, rp->fc4type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) 	if (dup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) 		ql_log(ql_log_warn, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) 		    "Detected %d duplicate NPORT ID(s) from switch data base\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) 		    dup_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) login_logout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) 	 * Logout all previous fabric dev marked lost, except FCP2 devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) 	list_for_each_entry(fcport, &vha->vp_fcports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) 		if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) 			fcport->scan_needed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) 		if (fcport->scan_state != QLA_FCPORT_FOUND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) 			bool do_delete = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) 			if (fcport->scan_needed &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) 			    fcport->disc_state == DSC_LOGIN_PEND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) 				/* Cable got disconnected after we sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) 				 * a login. Do delete to prevent timeout.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) 				fcport->logout_on_delete = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) 				do_delete = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) 			fcport->scan_needed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) 			if (((qla_dual_mode_enabled(vha) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) 			      qla_ini_mode_enabled(vha)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) 			    atomic_read(&fcport->state) == FCS_ONLINE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) 				do_delete) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) 				if (fcport->loop_id != FC_NO_LOOP_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) 					if (fcport->flags & FCF_FCP2_DEVICE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) 						fcport->logout_on_delete = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) 					ql_dbg(ql_dbg_disc, vha, 0x20f0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) 					    "%s %d %8phC post del sess\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) 					    __func__, __LINE__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) 					    fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) 					qlt_schedule_sess_for_deletion(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) 			if (fcport->scan_needed ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) 			    fcport->disc_state != DSC_LOGIN_COMPLETE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) 				if (fcport->login_retry == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) 					fcport->login_retry =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) 						vha->hw->login_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) 					ql_dbg(ql_dbg_disc, vha, 0x20a3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) 					    "Port login retry %8phN, lid 0x%04x retry cnt=%d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) 					    fcport->port_name, fcport->loop_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) 					    fcport->login_retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) 				fcport->scan_needed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) 				qla24xx_fcport_handle_login(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) 	recheck = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) 	qla24xx_sp_unmap(vha, sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) 	spin_lock_irqsave(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) 	vha->scan.scan_flags &= ~SF_SCANNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) 	spin_unlock_irqrestore(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) 	if (recheck) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) 		list_for_each_entry(fcport, &vha->vp_fcports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) 			if (fcport->scan_needed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) 				set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) 				set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) static int qla2x00_post_gnnft_gpnft_done_work(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605)     srb_t *sp, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) 	struct qla_work_evt *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) 	if (cmd != QLA_EVT_GPNFT_DONE && cmd != QLA_EVT_GNNFT_DONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) 		return QLA_PARAMETER_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) 	e = qla2x00_alloc_work(vha, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) 	if (!e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) 	e->u.iosb.sp = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) 	return qla2x00_post_work(vha, e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) static int qla2x00_post_nvme_gpnft_work(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622)     srb_t *sp, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) 	struct qla_work_evt *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) 	if (cmd != QLA_EVT_GPNFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) 		return QLA_PARAMETER_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) 	e = qla2x00_alloc_work(vha, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) 	if (!e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) 	e->u.gpnft.fc4_type = FC4_TYPE_NVME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) 	e->u.gpnft.sp = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) 	return qla2x00_post_work(vha, e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) static void qla2x00_find_free_fcp_nvme_slot(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) 	struct srb *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) 	int num_fibre_dev = ha->max_fibre_devices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) 	struct ct_sns_req *ct_req =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) 		(struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) 	struct ct_sns_gpnft_rsp *ct_rsp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) 		(struct ct_sns_gpnft_rsp *)sp->u.iocb_cmd.u.ctarg.rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) 	struct ct_sns_gpn_ft_data *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) 	struct fab_scan_rp *rp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) 	u16 cmd = be16_to_cpu(ct_req->command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) 	u8 fc4_type = sp->gen2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) 	int i, j, k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) 	port_id_t id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) 	u8 found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) 	u64 wwn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) 	j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) 	for (i = 0; i < num_fibre_dev; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) 		d  = &ct_rsp->entries[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) 		id.b.rsvd_1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) 		id.b.domain = d->port_id[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) 		id.b.area   = d->port_id[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) 		id.b.al_pa  = d->port_id[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) 		wwn = wwn_to_u64(d->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) 		if (id.b24 == 0 || wwn == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) 		if (fc4_type == FC4_TYPE_FCP_SCSI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) 			if (cmd == GPN_FT_CMD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) 				rp = &vha->scan.l[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) 				rp->id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) 				memcpy(rp->port_name, d->port_name, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) 				j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) 				rp->fc4type = FS_FC4TYPE_FCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) 				for (k = 0; k < num_fibre_dev; k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) 					rp = &vha->scan.l[k];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) 					if (id.b24 == rp->id.b24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) 						memcpy(rp->node_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) 						    d->port_name, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) 						break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) 			/* Search if the fibre device supports FC4_TYPE_NVME */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) 			if (cmd == GPN_FT_CMD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) 				found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) 				for (k = 0; k < num_fibre_dev; k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) 					rp = &vha->scan.l[k];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) 					if (!memcmp(rp->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) 					    d->port_name, 8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) 						/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) 						 * Supports FC-NVMe & FCP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) 						 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) 						rp->fc4type |= FS_FC4TYPE_NVME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) 						found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) 						break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) 				/* We found new FC-NVMe only port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) 				if (!found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) 					for (k = 0; k < num_fibre_dev; k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) 						rp = &vha->scan.l[k];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) 						if (wwn_to_u64(rp->port_name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) 							continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) 						} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) 							rp->id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) 							memcpy(rp->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) 							    d->port_name, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) 							rp->fc4type =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) 							    FS_FC4TYPE_NVME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) 							break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) 						}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) 				for (k = 0; k < num_fibre_dev; k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) 					rp = &vha->scan.l[k];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) 					if (id.b24 == rp->id.b24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) 						memcpy(rp->node_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) 						    d->port_name, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) 						break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) 	struct scsi_qla_host *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) 	struct ct_sns_req *ct_req =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) 		(struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) 	u16 cmd = be16_to_cpu(ct_req->command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) 	u8 fc4_type = sp->gen2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) 	/* gen2 field is holding the fc4type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) 	ql_dbg(ql_dbg_disc, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) 	    "Async done-%s res %x FC4Type %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) 	    sp->name, res, sp->gen2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) 	del_timer(&sp->u.iocb_cmd.timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) 	sp->rc = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) 	if (res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) 		unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) 		const char *name = sp->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) 		if (res == QLA_OS_TIMER_EXPIRED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) 			/* switch is ignoring all commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) 			 * This might be a zone disable behavior.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) 			 * This means we hit 64s timeout.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) 			 * 22s GPNFT + 44s Abort = 64s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) 			ql_dbg(ql_dbg_disc, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) 			       "%s: Switch Zone check please .\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) 			       name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) 			qla2x00_mark_all_devices_lost(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) 		 * We are in an Interrupt context, queue up this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) 		 * sp for GNNFT_DONE work. This will allow all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) 		 * the resource to get freed up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) 		rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) 		    QLA_EVT_GNNFT_DONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) 		if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) 			/* Cleanup here to prevent memory leak */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) 			qla24xx_sp_unmap(vha, sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) 			spin_lock_irqsave(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) 			vha->scan.scan_flags &= ~SF_SCANNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) 			vha->scan.scan_retry++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) 			spin_unlock_irqrestore(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) 			if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) 				set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) 				set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) 				qla2xxx_wake_dpc(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) 				ql_dbg(ql_dbg_disc, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) 				    "Async done-%s rescan failed on all retries.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) 				    name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) 	qla2x00_find_free_fcp_nvme_slot(vha, sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) 	if ((fc4_type == FC4_TYPE_FCP_SCSI) && vha->flags.nvme_enabled &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) 	    cmd == GNN_FT_CMD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) 		spin_lock_irqsave(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) 		vha->scan.scan_flags &= ~SF_SCANNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) 		spin_unlock_irqrestore(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) 		sp->rc = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) 		rc = qla2x00_post_nvme_gpnft_work(vha, sp, QLA_EVT_GPNFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) 		if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) 			qla24xx_sp_unmap(vha, sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) 			set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) 			set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) 	if (cmd == GPN_FT_CMD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) 		rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) 		    QLA_EVT_GPNFT_DONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) 		rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) 		    QLA_EVT_GNNFT_DONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) 	if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) 		qla24xx_sp_unmap(vha, sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) 		set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) 		set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832)  * Get WWNN list for fc4_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834)  * It is assumed the same SRB is re-used from GPNFT to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835)  * mem free & re-alloc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838)     u8 fc4_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) 	int rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) 	struct ct_sns_req *ct_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) 	struct ct_sns_pkt *ct_sns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) 	if (!vha->flags.online) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) 		spin_lock_irqsave(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) 		vha->scan.scan_flags &= ~SF_SCANNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) 		spin_unlock_irqrestore(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) 	if (!sp->u.iocb_cmd.u.ctarg.req || !sp->u.iocb_cmd.u.ctarg.rsp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) 		ql_log(ql_log_warn, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) 		    "%s: req %p rsp %p are not setup\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) 		    __func__, sp->u.iocb_cmd.u.ctarg.req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) 		    sp->u.iocb_cmd.u.ctarg.rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) 		spin_lock_irqsave(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) 		vha->scan.scan_flags &= ~SF_SCANNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) 		spin_unlock_irqrestore(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) 		WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) 		set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) 		set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) 	ql_dbg(ql_dbg_disc, vha, 0xfffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) 	    "%s: FC4Type %x, CT-PASSTHRU %s command ctarg rsp size %d, ctarg req size %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) 	    __func__, fc4_type, sp->name, sp->u.iocb_cmd.u.ctarg.rsp_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) 	     sp->u.iocb_cmd.u.ctarg.req_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) 	sp->type = SRB_CT_PTHRU_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) 	sp->name = "gnnft";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) 	sp->gen1 = vha->hw->base_qpair->chip_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) 	sp->gen2 = fc4_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) 	sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) 	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) 	memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) 	memset(sp->u.iocb_cmd.u.ctarg.req, 0, sp->u.iocb_cmd.u.ctarg.req_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) 	ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) 	/* CT_IU preamble  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) 	ct_req = qla2x00_prep_ct_req(ct_sns, GNN_FT_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) 	    sp->u.iocb_cmd.u.ctarg.rsp_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) 	/* GPN_FT req */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) 	ct_req->req.gpn_ft.port_type = fc4_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) 	sp->u.iocb_cmd.u.ctarg.req_size = GNN_FT_REQ_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) 	sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) 	sp->done = qla2x00_async_gpnft_gnnft_sp_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) 	ql_dbg(ql_dbg_disc, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) 	    "Async-%s hdl=%x FC4Type %x.\n", sp->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) 	    sp->handle, ct_req->req.gpn_ft.port_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) 	rval = qla2x00_start_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) done_free_sp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) 	if (sp->u.iocb_cmd.u.ctarg.req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) 		dma_free_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) 		    sp->u.iocb_cmd.u.ctarg.req_allocated_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) 		    sp->u.iocb_cmd.u.ctarg.req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) 		    sp->u.iocb_cmd.u.ctarg.req_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) 		sp->u.iocb_cmd.u.ctarg.req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) 	if (sp->u.iocb_cmd.u.ctarg.rsp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) 		dma_free_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) 		    sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) 		    sp->u.iocb_cmd.u.ctarg.rsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) 		    sp->u.iocb_cmd.u.ctarg.rsp_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) 		sp->u.iocb_cmd.u.ctarg.rsp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) 	spin_lock_irqsave(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) 	vha->scan.scan_flags &= ~SF_SCANNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) 	if (vha->scan.scan_flags == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) 		ql_dbg(ql_dbg_disc, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) 		    "%s: schedule\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) 		vha->scan.scan_flags |= SF_QUEUED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) 		schedule_delayed_work(&vha->scan.scan_work, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) 	spin_unlock_irqrestore(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) } /* GNNFT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) void qla24xx_async_gpnft_done(scsi_qla_host_t *vha, srb_t *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) 	ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) 	    "%s enter\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) 	qla24xx_async_gnnft(vha, sp, sp->gen2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) /* Get WWPN list for certain fc4_type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) 	int rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) 	struct ct_sns_req       *ct_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) 	struct ct_sns_pkt *ct_sns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) 	u32 rspsz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) 	ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) 	    "%s enter\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) 	if (!vha->flags.online)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) 	spin_lock_irqsave(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) 	if (vha->scan.scan_flags & SF_SCANNING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) 		spin_unlock_irqrestore(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) 		ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) 		    "%s: scan active\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) 	vha->scan.scan_flags |= SF_SCANNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) 	spin_unlock_irqrestore(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) 	if (fc4_type == FC4_TYPE_FCP_SCSI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) 		ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) 		    "%s: Performing FCP Scan\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) 		if (sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) 			sp->free(sp); /* should not happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) 		sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) 		if (!sp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) 			spin_lock_irqsave(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) 			vha->scan.scan_flags &= ~SF_SCANNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) 			spin_unlock_irqrestore(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) 			return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) 		sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) 								sizeof(struct ct_sns_pkt),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) 								&sp->u.iocb_cmd.u.ctarg.req_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) 								GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) 		sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) 		if (!sp->u.iocb_cmd.u.ctarg.req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) 			ql_log(ql_log_warn, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) 			    "Failed to allocate ct_sns request.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) 			spin_lock_irqsave(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) 			vha->scan.scan_flags &= ~SF_SCANNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) 			spin_unlock_irqrestore(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) 			qla2x00_rel_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) 			return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) 		sp->u.iocb_cmd.u.ctarg.req_size = GPN_FT_REQ_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) 		rspsz = sizeof(struct ct_sns_gpnft_rsp) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) 			((vha->hw->max_fibre_devices - 1) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) 			    sizeof(struct ct_sns_gpn_ft_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) 		sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) 								rspsz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) 								&sp->u.iocb_cmd.u.ctarg.rsp_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) 								GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) 		sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = rspsz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) 		if (!sp->u.iocb_cmd.u.ctarg.rsp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) 			ql_log(ql_log_warn, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) 			    "Failed to allocate ct_sns request.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) 			spin_lock_irqsave(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) 			vha->scan.scan_flags &= ~SF_SCANNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) 			spin_unlock_irqrestore(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) 			dma_free_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) 			    sp->u.iocb_cmd.u.ctarg.req_allocated_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) 			    sp->u.iocb_cmd.u.ctarg.req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) 			    sp->u.iocb_cmd.u.ctarg.req_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) 			sp->u.iocb_cmd.u.ctarg.req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) 			qla2x00_rel_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) 			return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) 		sp->u.iocb_cmd.u.ctarg.rsp_size = rspsz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) 		ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) 		    "%s scan list size %d\n", __func__, vha->scan.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) 		memset(vha->scan.l, 0, vha->scan.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) 	} else if (!sp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) 		ql_dbg(ql_dbg_disc, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) 		    "NVME scan did not provide SP\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) 	sp->type = SRB_CT_PTHRU_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) 	sp->name = "gpnft";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) 	sp->gen1 = vha->hw->base_qpair->chip_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) 	sp->gen2 = fc4_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) 	sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) 	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) 	rspsz = sp->u.iocb_cmd.u.ctarg.rsp_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) 	memset(sp->u.iocb_cmd.u.ctarg.rsp, 0, sp->u.iocb_cmd.u.ctarg.rsp_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) 	memset(sp->u.iocb_cmd.u.ctarg.req, 0, sp->u.iocb_cmd.u.ctarg.req_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) 	ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) 	/* CT_IU preamble  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) 	ct_req = qla2x00_prep_ct_req(ct_sns, GPN_FT_CMD, rspsz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) 	/* GPN_FT req */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) 	ct_req->req.gpn_ft.port_type = fc4_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) 	sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) 	sp->done = qla2x00_async_gpnft_gnnft_sp_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) 	ql_dbg(ql_dbg_disc, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) 	    "Async-%s hdl=%x FC4Type %x.\n", sp->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) 	    sp->handle, ct_req->req.gpn_ft.port_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) 	rval = qla2x00_start_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) done_free_sp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) 	if (sp->u.iocb_cmd.u.ctarg.req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) 		dma_free_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) 		    sp->u.iocb_cmd.u.ctarg.req_allocated_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) 		    sp->u.iocb_cmd.u.ctarg.req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) 		    sp->u.iocb_cmd.u.ctarg.req_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) 		sp->u.iocb_cmd.u.ctarg.req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) 	if (sp->u.iocb_cmd.u.ctarg.rsp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) 		dma_free_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) 		    sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) 		    sp->u.iocb_cmd.u.ctarg.rsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) 		    sp->u.iocb_cmd.u.ctarg.rsp_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) 		sp->u.iocb_cmd.u.ctarg.rsp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) 	spin_lock_irqsave(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) 	vha->scan.scan_flags &= ~SF_SCANNING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) 	if (vha->scan.scan_flags == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) 		ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) 		    "%s: Scan scheduled.\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) 		vha->scan.scan_flags |= SF_QUEUED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) 		schedule_delayed_work(&vha->scan.scan_work, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) 	spin_unlock_irqrestore(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) void qla_scan_work_fn(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) 	struct fab_scan *s = container_of(to_delayed_work(work),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) 	    struct fab_scan, scan_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) 	struct scsi_qla_host *vha = container_of(s, struct scsi_qla_host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) 	    scan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) 	ql_dbg(ql_dbg_disc, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) 	    "%s: schedule loop resync\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) 	set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) 	set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) 	qla2xxx_wake_dpc(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) 	spin_lock_irqsave(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) 	vha->scan.scan_flags &= ~SF_QUEUED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) 	spin_unlock_irqrestore(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) /* GNN_ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) void qla24xx_handle_gnnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) 	qla24xx_post_gnl_work(vha, ea->fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) static void qla2x00_async_gnnid_sp_done(srb_t *sp, int res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) 	struct scsi_qla_host *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) 	fc_port_t *fcport = sp->fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) 	u8 *node_name = fcport->ct_desc.ct_sns->p.rsp.rsp.gnn_id.node_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) 	struct event_arg ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) 	u64 wwnn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) 	fcport->flags &= ~FCF_ASYNC_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) 	wwnn = wwn_to_u64(node_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) 	if (wwnn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) 		memcpy(fcport->node_name, node_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) 	memset(&ea, 0, sizeof(ea));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) 	ea.fcport = fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) 	ea.sp = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) 	ea.rc = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) 	ql_dbg(ql_dbg_disc, vha, 0x204f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) 	    "Async done-%s res %x, WWPN %8phC %8phC\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) 	    sp->name, res, fcport->port_name, fcport->node_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) 	qla24xx_handle_gnnid_event(vha, &ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) int qla24xx_async_gnnid(scsi_qla_host_t *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) 	int rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) 	struct ct_sns_req       *ct_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) 	srb_t *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) 	if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) 	qla2x00_set_fcport_disc_state(fcport, DSC_GNN_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) 	sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) 	if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) 	fcport->flags |= FCF_ASYNC_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) 	sp->type = SRB_CT_PTHRU_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) 	sp->name = "gnnid";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) 	sp->gen1 = fcport->rscn_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) 	sp->gen2 = fcport->login_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) 	sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) 	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) 	/* CT_IU preamble  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) 	ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GNN_ID_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) 	    GNN_ID_RSP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) 	/* GNN_ID req */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) 	ct_req->req.port_id.port_id = port_id_to_be_id(fcport->d_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) 	/* req & rsp use the same buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) 	sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) 	sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) 	sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) 	sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) 	sp->u.iocb_cmd.u.ctarg.req_size = GNN_ID_REQ_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) 	sp->u.iocb_cmd.u.ctarg.rsp_size = GNN_ID_RSP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) 	sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) 	sp->done = qla2x00_async_gnnid_sp_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) 	ql_dbg(ql_dbg_disc, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) 	    "Async-%s - %8phC hdl=%x loopid=%x portid %06x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) 	    sp->name, fcport->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) 	    sp->handle, fcport->loop_id, fcport->d_id.b24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) 	rval = qla2x00_start_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) 	if (rval != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) done_free_sp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) 	fcport->flags &= ~FCF_ASYNC_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) int qla24xx_post_gnnid_work(struct scsi_qla_host *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) 	struct qla_work_evt *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) 	int ls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) 	ls = atomic_read(&vha->loop_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) 	if (((ls != LOOP_READY) && (ls != LOOP_UP)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) 		test_bit(UNLOADING, &vha->dpc_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) 	e = qla2x00_alloc_work(vha, QLA_EVT_GNNID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) 	if (!e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) 	e->u.fcport.fcport = fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) 	return qla2x00_post_work(vha, e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) /* GPFN_ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) void qla24xx_handle_gfpnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) 	fc_port_t *fcport = ea->fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) 	ql_dbg(ql_dbg_disc, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) 	    "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d fcpcnt %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) 	    __func__, fcport->port_name, fcport->disc_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) 	    fcport->fw_login_state, ea->rc, fcport->login_gen, ea->sp->gen2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) 	    fcport->rscn_gen, ea->sp->gen1, vha->fcport_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) 	if (fcport->disc_state == DSC_DELETE_PEND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) 	if (ea->sp->gen2 != fcport->login_gen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) 		/* target side must have changed it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) 		ql_dbg(ql_dbg_disc, vha, 0x20d3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) 		    "%s %8phC generation changed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) 		    __func__, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) 	} else if (ea->sp->gen1 != fcport->rscn_gen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) 	qla24xx_post_gpsc_work(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) static void qla2x00_async_gfpnid_sp_done(srb_t *sp, int res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) 	struct scsi_qla_host *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) 	fc_port_t *fcport = sp->fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) 	u8 *fpn = fcport->ct_desc.ct_sns->p.rsp.rsp.gfpn_id.port_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) 	struct event_arg ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) 	u64 wwn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) 	wwn = wwn_to_u64(fpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) 	if (wwn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) 		memcpy(fcport->fabric_port_name, fpn, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) 	memset(&ea, 0, sizeof(ea));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) 	ea.fcport = fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) 	ea.sp = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) 	ea.rc = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) 	ql_dbg(ql_dbg_disc, vha, 0x204f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) 	    "Async done-%s res %x, WWPN %8phC %8phC\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) 	    sp->name, res, fcport->port_name, fcport->fabric_port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) 	qla24xx_handle_gfpnid_event(vha, &ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) int qla24xx_async_gfpnid(scsi_qla_host_t *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) 	int rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) 	struct ct_sns_req       *ct_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) 	srb_t *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) 	if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) 	sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) 	if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) 	sp->type = SRB_CT_PTHRU_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) 	sp->name = "gfpnid";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) 	sp->gen1 = fcport->rscn_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) 	sp->gen2 = fcport->login_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) 	sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) 	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) 	/* CT_IU preamble  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) 	ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GFPN_ID_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) 	    GFPN_ID_RSP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) 	/* GFPN_ID req */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) 	ct_req->req.port_id.port_id = port_id_to_be_id(fcport->d_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) 	/* req & rsp use the same buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) 	sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) 	sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) 	sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) 	sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) 	sp->u.iocb_cmd.u.ctarg.req_size = GFPN_ID_REQ_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) 	sp->u.iocb_cmd.u.ctarg.rsp_size = GFPN_ID_RSP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) 	sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) 	sp->done = qla2x00_async_gfpnid_sp_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) 	ql_dbg(ql_dbg_disc, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) 	    "Async-%s - %8phC hdl=%x loopid=%x portid %06x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) 	    sp->name, fcport->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) 	    sp->handle, fcport->loop_id, fcport->d_id.b24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) 	rval = qla2x00_start_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) 	if (rval != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) done_free_sp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) int qla24xx_post_gfpnid_work(struct scsi_qla_host *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) 	struct qla_work_evt *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) 	int ls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) 	ls = atomic_read(&vha->loop_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) 	if (((ls != LOOP_READY) && (ls != LOOP_UP)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) 		test_bit(UNLOADING, &vha->dpc_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) 	e = qla2x00_alloc_work(vha, QLA_EVT_GFPNID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) 	if (!e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) 	e->u.fcport.fcport = fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) 	return qla2x00_post_work(vha, e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) }