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_gbl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include "qla_devtbl.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #ifdef CONFIG_SPARC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <asm/prom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include "qla_target.h"
^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) *  QLogic ISP2x00 Hardware Support Function Prototypes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) static int qla2x00_isp_firmware(scsi_qla_host_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) static int qla2x00_setup_chip(scsi_qla_host_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) static int qla2x00_fw_ready(scsi_qla_host_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) static int qla2x00_configure_hba(scsi_qla_host_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) static int qla2x00_configure_loop(scsi_qla_host_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) static int qla2x00_configure_local_loop(scsi_qla_host_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) static int qla2x00_configure_fabric(scsi_qla_host_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) static int qla2x00_find_all_fabric_devs(scsi_qla_host_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) static int qla2x00_restart_isp(scsi_qla_host_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) static struct qla_chip_state_84xx *qla84xx_get_chip(struct scsi_qla_host *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) static int qla84xx_init_chip(scsi_qla_host_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) static int qla25xx_init_queues(struct qla_hw_data *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) static int qla24xx_post_prli_work(struct scsi_qla_host*, fc_port_t *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) static void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 				      struct event_arg *ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) static void qla24xx_handle_prli_done_event(struct scsi_qla_host *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41)     struct event_arg *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) static void __qla24xx_handle_gpdb_event(scsi_qla_host_t *, struct event_arg *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) /* SRB Extensions ---------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) qla2x00_sp_timeout(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	srb_t *sp = from_timer(sp, t, u.iocb_cmd.timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	struct srb_iocb *iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 	WARN_ON(irqs_disabled());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 	iocb = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 	iocb->timeout(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) void qla2x00_sp_free(srb_t *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	struct srb_iocb *iocb = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	del_timer(&iocb->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 	qla2x00_rel_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) void qla2xxx_rel_done_warning(srb_t *sp, int res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 	WARN_ONCE(1, "Calling done() of an already freed srb %p object\n", sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) void qla2xxx_rel_free_warning(srb_t *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 	WARN_ONCE(1, "Calling free() of an already freed srb %p object\n", sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) /* Asynchronous Login/Logout Routines -------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) qla2x00_get_async_timeout(struct scsi_qla_host *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	unsigned long tmo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	/* Firmware should use switch negotiated r_a_tov for timeout. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 	tmo = ha->r_a_tov / 10 * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	if (IS_QLAFX00(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 		tmo = FX00_DEF_RATOV * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	} else if (!IS_FWI2_CAPABLE(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 		 * Except for earlier ISPs where the timeout is seeded from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 		 * initialization control block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 		tmo = ha->login_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	return tmo;
^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) static void qla24xx_abort_iocb_timeout(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	srb_t *sp = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	struct srb_iocb *abt = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	struct qla_qpair *qpair = sp->qpair;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	u32 handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	if (sp->cmd_sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 		ql_dbg(ql_dbg_async, sp->vha, 0x507c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 		    "Abort timeout - cmd hdl=%x, cmd type=%x hdl=%x, type=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 		    sp->cmd_sp->handle, sp->cmd_sp->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 		    sp->handle, sp->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 		ql_dbg(ql_dbg_async, sp->vha, 0x507c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 		    "Abort timeout 2 - hdl=%x, type=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 		    sp->handle, sp->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	spin_lock_irqsave(qpair->qp_lock_ptr, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	for (handle = 1; handle < qpair->req->num_outstanding_cmds; handle++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 		if (sp->cmd_sp && (qpair->req->outstanding_cmds[handle] ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 		    sp->cmd_sp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 			qpair->req->outstanding_cmds[handle] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 		/* removing the abort */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 		if (qpair->req->outstanding_cmds[handle] == sp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 			qpair->req->outstanding_cmds[handle] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	if (sp->cmd_sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 		sp->cmd_sp->done(sp->cmd_sp, QLA_OS_TIMER_EXPIRED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	abt->u.abt.comp_status = cpu_to_le16(CS_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	sp->done(sp, QLA_OS_TIMER_EXPIRED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) static void qla24xx_abort_sp_done(srb_t *sp, int res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	struct srb_iocb *abt = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	del_timer(&sp->u.iocb_cmd.timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	if (sp->flags & SRB_WAKEUP_ON_COMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 		complete(&abt->u.abt.comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 		sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	scsi_qla_host_t *vha = cmd_sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	struct srb_iocb *abt_iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	srb_t *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	int rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	sp = qla2xxx_get_qpair_sp(cmd_sp->vha, cmd_sp->qpair, cmd_sp->fcport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 				  GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	abt_iocb = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	sp->type = SRB_ABT_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	sp->name = "abort";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	sp->qpair = cmd_sp->qpair;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	sp->cmd_sp = cmd_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	if (wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 		sp->flags = SRB_WAKEUP_ON_COMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	abt_iocb->timeout = qla24xx_abort_iocb_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	init_completion(&abt_iocb->u.abt.comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	/* FW can send 2 x ABTS's timeout/20s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	qla2x00_init_timer(sp, 42);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	abt_iocb->u.abt.cmd_hndl = cmd_sp->handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	abt_iocb->u.abt.req_que_no = cpu_to_le16(cmd_sp->qpair->req->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	sp->done = qla24xx_abort_sp_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	ql_dbg(ql_dbg_async, vha, 0x507c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	       "Abort command issued - hdl=%x, type=%x\n", cmd_sp->handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	       cmd_sp->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	rval = qla2x00_start_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 		sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	if (wait) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 		wait_for_completion(&abt_iocb->u.abt.comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 		rval = abt_iocb->u.abt.comp_status == CS_COMPLETE ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 			QLA_SUCCESS : QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 		sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) qla2x00_async_iocb_timeout(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	srb_t *sp = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	fc_port_t *fcport = sp->fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	struct srb_iocb *lio = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	int rc, h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	if (fcport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 		ql_dbg(ql_dbg_disc, fcport->vha, 0x2071,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 		    "Async-%s timeout - hdl=%x portid=%06x %8phC.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 		    sp->name, sp->handle, fcport->d_id.b24, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 		fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 		pr_info("Async-%s timeout - hdl=%x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 		    sp->name, sp->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	switch (sp->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	case SRB_LOGIN_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 		rc = qla24xx_async_abort_cmd(sp, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 		if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 			/* Retry as needed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 			lio->u.logio.data[0] = MBS_COMMAND_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 			lio->u.logio.data[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 				lio->u.logio.flags & SRB_LOGIN_RETRIED ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 				QLA_LOGIO_LOGIN_RETRIED : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 			spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 			for (h = 1; h < sp->qpair->req->num_outstanding_cmds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 			    h++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 				if (sp->qpair->req->outstanding_cmds[h] ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 				    sp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 					sp->qpair->req->outstanding_cmds[h] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 					    NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 			spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 			sp->done(sp, QLA_FUNCTION_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	case SRB_LOGOUT_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	case SRB_CT_PTHRU_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	case SRB_MB_IOCB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	case SRB_NACK_PLOGI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	case SRB_NACK_PRLI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	case SRB_NACK_LOGO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	case SRB_CTRL_VP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 		rc = qla24xx_async_abort_cmd(sp, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 		if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 			spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 			for (h = 1; h < sp->qpair->req->num_outstanding_cmds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 			    h++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 				if (sp->qpair->req->outstanding_cmds[h] ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 				    sp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 					sp->qpair->req->outstanding_cmds[h] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 					    NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 			spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 			sp->done(sp, QLA_FUNCTION_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 		break;
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) static void qla2x00_async_login_sp_done(srb_t *sp, int res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	struct scsi_qla_host *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	struct srb_iocb *lio = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	struct event_arg ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	ql_dbg(ql_dbg_disc, vha, 0x20dd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	    "%s %8phC res %d \n", __func__, sp->fcport->port_name, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	if (!test_bit(UNLOADING, &vha->dpc_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 		memset(&ea, 0, sizeof(ea));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 		ea.fcport = sp->fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 		ea.data[0] = lio->u.logio.data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 		ea.data[1] = lio->u.logio.data[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 		ea.iop[0] = lio->u.logio.iop[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 		ea.iop[1] = lio->u.logio.iop[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 		ea.sp = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 		qla24xx_handle_plogi_done_event(vha, &ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) static inline bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) fcport_is_smaller(fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	if (wwn_to_u64(fcport->port_name) <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	    wwn_to_u64(fcport->vha->port_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) static inline bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) fcport_is_bigger(fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	return !fcport_is_smaller(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310)     uint16_t *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	srb_t *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	struct srb_iocb *lio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	int rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	    fcport->loop_id == FC_NO_LOOP_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		ql_log(ql_log_warn, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 		    "%s: %8phC - not sending command.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 		    __func__, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_PEND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	fcport->flags |= FCF_ASYNC_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	fcport->logout_completed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	sp->type = SRB_LOGIN_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	sp->name = "login";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	sp->gen1 = fcport->rscn_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	sp->gen2 = fcport->login_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	lio = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	lio->timeout = qla2x00_async_iocb_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	sp->done = qla2x00_async_login_sp_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	if (N2N_TOPO(fcport->vha->hw) && fcport_is_bigger(fcport))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 		lio->u.logio.flags |= SRB_LOGIN_PRLI_ONLY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 		lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	if (NVME_TARGET(vha->hw, fcport))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 		lio->u.logio.flags |= SRB_LOGIN_SKIP_PRLI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	ql_dbg(ql_dbg_disc, vha, 0x2072,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	    "Async-login - %8phC hdl=%x, loopid=%x portid=%02x%02x%02x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 		"retries=%d.\n", fcport->port_name, sp->handle, fcport->loop_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	    fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	    fcport->login_retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	rval = qla2x00_start_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 		fcport->flags |= FCF_LOGIN_NEEDED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 		set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) done_free_sp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	fcport->flags &= ~FCF_ASYNC_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	fcport->flags &= ~FCF_ASYNC_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) static void qla2x00_async_logout_sp_done(srb_t *sp, int res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	sp->fcport->login_gen++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	qlt_logo_completion_handler(sp->fcport, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	srb_t *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	struct srb_iocb *lio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	int rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	fcport->flags |= FCF_ASYNC_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	sp->type = SRB_LOGOUT_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	sp->name = "logout";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	lio = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	lio->timeout = qla2x00_async_iocb_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	sp->done = qla2x00_async_logout_sp_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	ql_dbg(ql_dbg_disc, vha, 0x2070,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	    "Async-logout - hdl=%x loop-id=%x portid=%02x%02x%02x %8phC.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	    sp->handle, fcport->loop_id, fcport->d_id.b.domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 		fcport->d_id.b.area, fcport->d_id.b.al_pa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 		fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	rval = qla2x00_start_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	if (rval != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) done_free_sp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) qla2x00_async_prlo_done(struct scsi_qla_host *vha, fc_port_t *fcport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422)     uint16_t *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	fcport->flags &= ~FCF_ASYNC_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	/* Don't re-login in target mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	if (!fcport->tgt_session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 		qla2x00_mark_device_lost(vha, fcport, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	qlt_logo_completion_handler(fcport, data[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) static void qla2x00_async_prlo_sp_done(srb_t *sp, int res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	struct srb_iocb *lio = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	struct scsi_qla_host *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	sp->fcport->flags &= ~FCF_ASYNC_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	if (!test_bit(UNLOADING, &vha->dpc_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 		qla2x00_post_async_prlo_done_work(sp->fcport->vha, sp->fcport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 		    lio->u.logio.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) qla2x00_async_prlo(struct scsi_qla_host *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	srb_t *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	struct srb_iocb *lio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	sp->type = SRB_PRLO_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	sp->name = "prlo";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	lio = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	lio->timeout = qla2x00_async_iocb_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	sp->done = qla2x00_async_prlo_sp_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	ql_dbg(ql_dbg_disc, vha, 0x2070,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	    "Async-prlo - hdl=%x loop-id=%x portid=%02x%02x%02x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	    sp->handle, fcport->loop_id, fcport->d_id.b.domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	    fcport->d_id.b.area, fcport->d_id.b.al_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	rval = qla2x00_start_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	if (rval != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) done_free_sp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	fcport->flags &= ~FCF_ASYNC_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) void qla24xx_handle_adisc_event(scsi_qla_host_t *vha, struct event_arg *ea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	struct fc_port *fcport = ea->fcport;
^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, 0x20d2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	    "%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  489) 	    __func__, fcport->port_name, fcport->disc_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	    fcport->fw_login_state, ea->rc, fcport->login_gen, ea->sp->gen2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	    fcport->rscn_gen, ea->sp->gen1, fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	WARN_ONCE(!qla2xxx_is_valid_mbs(ea->data[0]), "mbs: %#x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 		  ea->data[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	if (ea->data[0] != MBS_COMMAND_COMPLETE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 		ql_dbg(ql_dbg_disc, vha, 0x2066,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 		    "%s %8phC: adisc fail: post delete\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 		    __func__, ea->fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 		/* deleted = 0 & logout_on_delete = force fw cleanup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 		fcport->deleted = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 		fcport->logout_on_delete = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 		qlt_schedule_sess_for_deletion(ea->fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	if (ea->fcport->disc_state == DSC_DELETE_PEND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	if (ea->sp->gen2 != ea->fcport->login_gen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 		/* target side must have changed it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 		ql_dbg(ql_dbg_disc, vha, 0x20d3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 		    "%s %8phC generation changed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 		    __func__, ea->fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	} else if (ea->sp->gen1 != ea->fcport->rscn_gen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 		qla_rscn_replay(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 		qlt_schedule_sess_for_deletion(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	__qla24xx_handle_gpdb_event(vha, ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) static int qla_post_els_plogi_work(struct scsi_qla_host *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	struct qla_work_evt *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	e = qla2x00_alloc_work(vha, QLA_EVT_ELS_PLOGI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	if (!e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	e->u.fcport.fcport = fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	fcport->flags |= FCF_ASYNC_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_PEND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	return qla2x00_post_work(vha, e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) static void qla2x00_async_adisc_sp_done(srb_t *sp, int res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	struct scsi_qla_host *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	struct event_arg ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	struct srb_iocb *lio = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	ql_dbg(ql_dbg_disc, vha, 0x2066,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	    "Async done-%s res %x %8phC\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	    sp->name, res, sp->fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	memset(&ea, 0, sizeof(ea));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	ea.rc = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	ea.data[0] = lio->u.logio.data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	ea.data[1] = lio->u.logio.data[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	ea.iop[0] = lio->u.logio.iop[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	ea.iop[1] = lio->u.logio.iop[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	ea.fcport = sp->fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	ea.sp = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	qla24xx_handle_adisc_event(vha, &ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567)     uint16_t *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	srb_t *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	struct srb_iocb *lio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	int rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	if (IS_SESSION_DELETED(fcport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 		ql_log(ql_log_warn, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 		       "%s: %8phC is being delete - not sending command.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 		       __func__, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 		fcport->flags &= ~FCF_ASYNC_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	fcport->flags |= FCF_ASYNC_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	sp->type = SRB_ADISC_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	sp->name = "adisc";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	lio = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	lio->timeout = qla2x00_async_iocb_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	sp->gen1 = fcport->rscn_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	sp->gen2 = fcport->login_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	sp->done = qla2x00_async_adisc_sp_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 		lio->u.logio.flags |= SRB_LOGIN_RETRIED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	ql_dbg(ql_dbg_disc, vha, 0x206f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	    "Async-adisc - hdl=%x loopid=%x portid=%06x %8phC.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	    sp->handle, fcport->loop_id, fcport->d_id.b24, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	rval = qla2x00_start_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	if (rval != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) done_free_sp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	qla2x00_post_async_adisc_work(vha, fcport, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) static bool qla2x00_is_reserved_id(scsi_qla_host_t *vha, uint16_t loop_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	if (IS_FWI2_CAPABLE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 		return loop_id > NPH_LAST_HANDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	return (loop_id > ha->max_loop_id && loop_id < SNS_FIRST_LOOP_ID) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 		loop_id == MANAGEMENT_SERVER || loop_id == BROADCAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632)  * qla2x00_find_new_loop_id - scan through our port list and find a new usable loop ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633)  * @vha: adapter state pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634)  * @dev: port structure pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637)  *	qla2x00 local function return status code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639)  * Context:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640)  *	Kernel context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) static int qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	int	rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	spin_lock_irqsave(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	dev->loop_id = find_first_zero_bit(ha->loop_id_map, LOOPID_MAP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	if (dev->loop_id >= LOOPID_MAP_SIZE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	    qla2x00_is_reserved_id(vha, dev->loop_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 		dev->loop_id = FC_NO_LOOP_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 		rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 		set_bit(dev->loop_id, ha->loop_id_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 	spin_unlock_irqrestore(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	if (rval == QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 		ql_dbg(ql_dbg_disc, dev->vha, 0x2086,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		       "Assigning new loopid=%x, portid=%x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 		       dev->loop_id, dev->d_id.b24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 		ql_log(ql_log_warn, dev->vha, 0x2087,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		       "No loop_id's available, portid=%x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 		       dev->d_id.b24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) void qla2x00_clear_loop_id(fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	struct qla_hw_data *ha = fcport->vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	if (fcport->loop_id == FC_NO_LOOP_ID ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	    qla2x00_is_reserved_id(fcport->vha, fcport->loop_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	clear_bit(fcport->loop_id, ha->loop_id_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	fcport->loop_id = FC_NO_LOOP_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	struct event_arg *ea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	fc_port_t *fcport, *conflict_fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	struct get_name_list_extended *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	u16 i, n, found = 0, loop_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	port_id_t id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 	u64 wwn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	u16 data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	u8 current_login_state, nvme_cls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	fcport = ea->fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	ql_dbg(ql_dbg_disc, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	    "%s %8phC DS %d LS rc %d %d login %d|%d rscn %d|%d lid %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	    __func__, fcport->port_name, fcport->disc_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	    fcport->fw_login_state, ea->rc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	    fcport->login_gen, fcport->last_login_gen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	    fcport->rscn_gen, fcport->last_rscn_gen, vha->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	if (fcport->disc_state == DSC_DELETE_PEND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	if (ea->rc) { /* rval */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 		if (fcport->login_retry == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 			ql_dbg(ql_dbg_disc, vha, 0x20de,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 			    "GNL failed Port login retry %8phN, retry cnt=%d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 			    fcport->port_name, fcport->login_retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	if (fcport->last_rscn_gen != fcport->rscn_gen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 		qla_rscn_replay(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 		qlt_schedule_sess_for_deletion(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	} else if (fcport->last_login_gen != fcport->login_gen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 		ql_dbg(ql_dbg_disc, vha, 0x20e0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		    "%s %8phC login gen changed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 		    __func__, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	n = ea->data[0] / sizeof(struct get_name_list_extended);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	ql_dbg(ql_dbg_disc, vha, 0x20e1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	    "%s %d %8phC n %d %02x%02x%02x lid %d \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	    __func__, __LINE__, fcport->port_name, n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	    fcport->d_id.b.domain, fcport->d_id.b.area,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	    fcport->d_id.b.al_pa, fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	for (i = 0; i < n; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 		e = &vha->gnl.l[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		wwn = wwn_to_u64(e->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 		id.b.domain = e->port_id[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 		id.b.area = e->port_id[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 		id.b.al_pa = e->port_id[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 		id.b.rsvd_1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 		if (memcmp((u8 *)&wwn, fcport->port_name, WWN_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 		if (IS_SW_RESV_ADDR(id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 		found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 		loop_id = le16_to_cpu(e->nport_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		loop_id = (loop_id & 0x7fff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 		nvme_cls = e->current_login_state >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 		current_login_state = e->current_login_state & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 		if (PRLI_PHASE(nvme_cls)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 			current_login_state = nvme_cls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 			fcport->fc4_type &= ~FS_FC4TYPE_FCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 			fcport->fc4_type |= FS_FC4TYPE_NVME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 		} else if (PRLI_PHASE(current_login_state)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 			fcport->fc4_type |= FS_FC4TYPE_FCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 			fcport->fc4_type &= ~FS_FC4TYPE_NVME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		ql_dbg(ql_dbg_disc, vha, 0x20e2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 		    "%s found %8phC CLS [%x|%x] fc4_type %d ID[%06x|%06x] lid[%d|%d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 		    __func__, fcport->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		    e->current_login_state, fcport->fw_login_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 		    fcport->fc4_type, id.b24, fcport->d_id.b24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 		    loop_id, fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 		switch (fcport->disc_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 		case DSC_DELETE_PEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 		case DSC_DELETED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 			if ((id.b24 != fcport->d_id.b24 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 			    fcport->d_id.b24 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 			    fcport->loop_id != FC_NO_LOOP_ID) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 			    (fcport->loop_id != FC_NO_LOOP_ID &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 				fcport->loop_id != loop_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 				ql_dbg(ql_dbg_disc, vha, 0x20e3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 				    "%s %d %8phC post del sess\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 				    __func__, __LINE__, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 				if (fcport->n2n_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 					fcport->d_id.b24 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 				qlt_schedule_sess_for_deletion(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 				return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 		fcport->loop_id = loop_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 		if (fcport->n2n_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 			fcport->d_id.b24 = id.b24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 		wwn = wwn_to_u64(fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 		qlt_find_sess_invalidate_other(vha, wwn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 			id, loop_id, &conflict_fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 		if (conflict_fcport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 			 * Another share fcport share the same loop_id &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 			 * nport id. Conflict fcport needs to finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 			 * cleanup before this fcport can proceed to login.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 			conflict_fcport->conflict = fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 			fcport->login_pause = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		switch (vha->hw->current_topology) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 			switch (current_login_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 			case DSC_LS_PRLI_COMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 				ql_dbg(ql_dbg_disc + ql_dbg_verbose,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 				    vha, 0x20e4, "%s %d %8phC post gpdb\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 				    __func__, __LINE__, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 				if ((e->prli_svc_param_word_3[0] & BIT_4) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 					fcport->port_type = FCT_INITIATOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 					fcport->port_type = FCT_TARGET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 				data[0] = data[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 				qla2x00_post_async_adisc_work(vha, fcport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 				    data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 			case DSC_LS_PORT_UNAVAIL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 			default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 				if (fcport->loop_id == FC_NO_LOOP_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 					qla2x00_find_new_loop_id(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 					fcport->fw_login_state =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 					    DSC_LS_PORT_UNAVAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 				ql_dbg(ql_dbg_disc, vha, 0x20e5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 				    "%s %d %8phC\n", __func__, __LINE__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 				    fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 				qla24xx_fcport_handle_login(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 		case ISP_CFG_N:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 			fcport->fw_login_state = current_login_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 			fcport->d_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 			switch (current_login_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 			case DSC_LS_PRLI_PEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 				 * In the middle of PRLI. Let it finish.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 				 * Allow relogin code to recheck state again
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 				 * with GNL. Push disc_state back to DELETED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 				 * so GNL can go out again
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 				qla2x00_set_fcport_disc_state(fcport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 				    DSC_DELETED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 			case DSC_LS_PRLI_COMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 				if ((e->prli_svc_param_word_3[0] & BIT_4) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 					fcport->port_type = FCT_INITIATOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 					fcport->port_type = FCT_TARGET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 				data[0] = data[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 				qla2x00_post_async_adisc_work(vha, fcport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 				    data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 			case DSC_LS_PLOGI_COMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 				if (fcport_is_bigger(fcport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 					/* local adapter is smaller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 					if (fcport->loop_id != FC_NO_LOOP_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 						qla2x00_clear_loop_id(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 					fcport->loop_id = loop_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 					qla24xx_fcport_handle_login(vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 					    fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 				fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 			default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 				if (fcport_is_smaller(fcport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 					/* local adapter is bigger */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 					if (fcport->loop_id != FC_NO_LOOP_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 						qla2x00_clear_loop_id(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 					fcport->loop_id = loop_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 					qla24xx_fcport_handle_login(vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 					    fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 		} /* switch (ha->current_topology) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	if (!found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 		switch (vha->hw->current_topology) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 		case ISP_CFG_F:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 		case ISP_CFG_FL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 			for (i = 0; i < n; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 				e = &vha->gnl.l[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 				id.b.domain = e->port_id[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 				id.b.area = e->port_id[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 				id.b.al_pa = e->port_id[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 				id.b.rsvd_1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 				loop_id = le16_to_cpu(e->nport_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 				if (fcport->d_id.b24 == id.b24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 					conflict_fcport =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 					    qla2x00_find_fcport_by_wwpn(vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 						e->port_name, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 					if (conflict_fcport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 						ql_dbg(ql_dbg_disc + ql_dbg_verbose,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 						    vha, 0x20e5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 						    "%s %d %8phC post del sess\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 						    __func__, __LINE__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 						    conflict_fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 						qlt_schedule_sess_for_deletion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 							(conflict_fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 				 * FW already picked this loop id for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 				 * another fcport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 				if (fcport->loop_id == loop_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 					fcport->loop_id = FC_NO_LOOP_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 			qla24xx_fcport_handle_login(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 		case ISP_CFG_N:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 			qla2x00_set_fcport_disc_state(fcport, DSC_DELETED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 			if (time_after_eq(jiffies, fcport->dm_login_expire)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 				if (fcport->n2n_link_reset_cnt < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 					fcport->n2n_link_reset_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 					/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 					 * remote port is not sending PLOGI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 					 * Reset link to kick start his state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 					 * machine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 					 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 					set_bit(N2N_LINK_RESET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 					    &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 					if (fcport->n2n_chip_reset < 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 						ql_log(ql_log_info, vha, 0x705d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 						    "Chip reset to bring laser down");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 						set_bit(ISP_ABORT_NEEDED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 						    &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 						fcport->n2n_chip_reset++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 					} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 						ql_log(ql_log_info, vha, 0x705d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 						    "Remote port %8ph is not coming back\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 						    fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 						fcport->scan_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 				qla2xxx_wake_dpc(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 				 * report port suppose to do PLOGI. Give him
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 				 * more time. FW will catch it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 				set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 		case ISP_CFG_NL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 			qla24xx_fcport_handle_login(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) } /* gnl_event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) static void qla24xx_async_gnl_sp_done(srb_t *sp, int res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	struct scsi_qla_host *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	struct fc_port *fcport = NULL, *tf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	u16 i, n = 0, loop_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	struct event_arg ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	struct get_name_list_extended *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	u64 wwn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	struct list_head h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	ql_dbg(ql_dbg_disc, vha, 0x20e7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	    "Async done-%s res %x mb[1]=%x mb[2]=%x \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	    sp->name, res, sp->u.iocb_cmd.u.mbx.in_mb[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	    sp->u.iocb_cmd.u.mbx.in_mb[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	sp->fcport->flags &= ~(FCF_ASYNC_SENT|FCF_ASYNC_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	memset(&ea, 0, sizeof(ea));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	ea.sp = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	ea.rc = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	if (sp->u.iocb_cmd.u.mbx.in_mb[1] >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	    sizeof(struct get_name_list_extended)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 		n = sp->u.iocb_cmd.u.mbx.in_mb[1] /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 		    sizeof(struct get_name_list_extended);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 		ea.data[0] = sp->u.iocb_cmd.u.mbx.in_mb[1]; /* amnt xfered */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	for (i = 0; i < n; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 		e = &vha->gnl.l[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 		loop_id = le16_to_cpu(e->nport_handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 		/* mask out reserve bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 		loop_id = (loop_id & 0x7fff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 		set_bit(loop_id, vha->hw->loop_id_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 		wwn = wwn_to_u64(e->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 		ql_dbg(ql_dbg_disc, vha, 0x20e8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 		    "%s %8phC %02x:%02x:%02x CLS %x/%x lid %x \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 		    __func__, &wwn, e->port_id[2], e->port_id[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 		    e->port_id[0], e->current_login_state, e->last_login_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 		    (loop_id & 0x7fff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	INIT_LIST_HEAD(&h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	fcport = tf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	if (!list_empty(&vha->gnl.fcports))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		list_splice_init(&vha->gnl.fcports, &h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	list_for_each_entry_safe(fcport, tf, &h, gnl_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 		spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 		list_del_init(&fcport->gnl_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 		fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 		spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 		ea.fcport = fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 		qla24xx_handle_gnl_done_event(vha, &ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	/* create new fcport if fw has knowledge of new sessions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	for (i = 0; i < n; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 		port_id_t id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 		u64 wwnn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 		e = &vha->gnl.l[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 		wwn = wwn_to_u64(e->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 		found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 		list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 			if (!memcmp((u8 *)&wwn, fcport->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 			    WWN_SIZE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 				found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 			}
^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) 		id.b.domain = e->port_id[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 		id.b.area = e->port_id[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 		id.b.al_pa = e->port_id[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 		id.b.rsvd_1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 		if (!found && wwn && !IS_SW_RESV_ADDR(id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 			ql_dbg(ql_dbg_disc, vha, 0x2065,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 			    "%s %d %8phC %06x post new sess\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 			    __func__, __LINE__, (u8 *)&wwn, id.b24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 			wwnn = wwn_to_u64(e->node_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 			qla24xx_post_newsess_work(vha, &id, (u8 *)&wwn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 			    (u8 *)&wwnn, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	vha->gnl.sent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	if (!list_empty(&vha->gnl.fcports)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 		/* retrigger gnl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 		list_for_each_entry_safe(fcport, tf, &vha->gnl.fcports,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 		    gnl_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 			list_del_init(&fcport->gnl_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 			fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 			if (qla24xx_post_gnl_work(vha, fcport) == QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	srb_t *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	struct srb_iocb *mbx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	int rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	u16 *mb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	ql_dbg(ql_dbg_disc, vha, 0x20d9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	    "Async-gnlist WWPN %8phC \n", fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	fcport->flags |= FCF_ASYNC_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	qla2x00_set_fcport_disc_state(fcport, DSC_GNL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	fcport->last_rscn_gen = fcport->rscn_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	fcport->last_login_gen = fcport->login_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	list_add_tail(&fcport->gnl_entry, &vha->gnl.fcports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	if (vha->gnl.sent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 		spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 		return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	vha->gnl.sent = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	sp->type = SRB_MB_IOCB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	sp->name = "gnlist";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	sp->gen1 = fcport->rscn_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	sp->gen2 = fcport->login_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	mbx = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	mbx->timeout = qla2x00_async_iocb_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha)+2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	mb = sp->u.iocb_cmd.u.mbx.out_mb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	mb[0] = MBC_PORT_NODE_NAME_LIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	mb[1] = BIT_2 | BIT_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	mb[2] = MSW(vha->gnl.ldma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	mb[3] = LSW(vha->gnl.ldma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	mb[6] = MSW(MSD(vha->gnl.ldma));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	mb[7] = LSW(MSD(vha->gnl.ldma));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	mb[8] = vha->gnl.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	mb[9] = vha->vp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	sp->done = qla24xx_async_gnl_sp_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 	ql_dbg(ql_dbg_disc, vha, 0x20da,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	    "Async-%s - OUT WWPN %8phC hndl %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	    sp->name, fcport->port_name, sp->handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	rval = qla2x00_start_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	if (rval != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) done_free_sp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	fcport->flags &= ~(FCF_ASYNC_ACTIVE | FCF_ASYNC_SENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) int qla24xx_post_gnl_work(struct scsi_qla_host *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	struct qla_work_evt *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	e = qla2x00_alloc_work(vha, QLA_EVT_GNL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	if (!e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	e->u.fcport.fcport = fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	fcport->flags |= FCF_ASYNC_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	return qla2x00_post_work(vha, e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) static void qla24xx_async_gpdb_sp_done(srb_t *sp, int res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	struct scsi_qla_host *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 	fc_port_t *fcport = sp->fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	u16 *mb = sp->u.iocb_cmd.u.mbx.in_mb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	struct event_arg ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	ql_dbg(ql_dbg_disc, vha, 0x20db,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	    "Async done-%s res %x, WWPN %8phC mb[1]=%x mb[2]=%x \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	    sp->name, res, fcport->port_name, mb[1], mb[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	if (res == QLA_FUNCTION_TIMEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	memset(&ea, 0, sizeof(ea));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	ea.fcport = fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	ea.sp = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	qla24xx_handle_gpdb_event(vha, &ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	dma_pool_free(ha->s_dma_pool, sp->u.iocb_cmd.u.mbx.in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 		sp->u.iocb_cmd.u.mbx.in_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) static int qla24xx_post_prli_work(struct scsi_qla_host *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	struct qla_work_evt *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	if (vha->host->active_mode == MODE_TARGET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	e = qla2x00_alloc_work(vha, QLA_EVT_PRLI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	if (!e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	e->u.fcport.fcport = fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 	return qla2x00_post_work(vha, e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) static void qla2x00_async_prli_sp_done(srb_t *sp, int res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	struct scsi_qla_host *vha = sp->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 	struct srb_iocb *lio = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 	struct event_arg ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 	ql_dbg(ql_dbg_disc, vha, 0x2129,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	    "%s %8phC res %d \n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	    sp->fcport->port_name, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	sp->fcport->flags &= ~FCF_ASYNC_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	if (!test_bit(UNLOADING, &vha->dpc_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 		memset(&ea, 0, sizeof(ea));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 		ea.fcport = sp->fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 		ea.data[0] = lio->u.logio.data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 		ea.data[1] = lio->u.logio.data[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 		ea.iop[0] = lio->u.logio.iop[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 		ea.iop[1] = lio->u.logio.iop[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 		ea.sp = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 		qla24xx_handle_prli_done_event(vha, &ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) qla24xx_async_prli(struct scsi_qla_host *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 	srb_t *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	struct srb_iocb *lio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	int rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	if (!vha->flags.online) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 		ql_dbg(ql_dbg_disc, vha, 0xffff, "%s %d %8phC exit\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 		    __func__, __LINE__, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 	    fcport->fw_login_state == DSC_LS_PRLI_PEND) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 	    qla_dual_mode_enabled(vha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 		ql_dbg(ql_dbg_disc, vha, 0xffff, "%s %d %8phC exit\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 		    __func__, __LINE__, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	fcport->flags |= FCF_ASYNC_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	fcport->logout_completed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	sp->type = SRB_PRLI_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	sp->name = "prli";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 	lio = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 	lio->timeout = qla2x00_async_iocb_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	sp->done = qla2x00_async_prli_sp_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	lio->u.logio.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 	if (NVME_TARGET(vha->hw, fcport))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 		lio->u.logio.flags |= SRB_LOGIN_NVME_PRLI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	ql_dbg(ql_dbg_disc, vha, 0x211b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	    "Async-prli - %8phC hdl=%x, loopid=%x portid=%06x retries=%d fc4type %x priority %x %s.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	    fcport->port_name, sp->handle, fcport->loop_id, fcport->d_id.b24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	    fcport->login_retry, fcport->fc4_type, vha->hw->fc4_type_priority,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 	    NVME_TARGET(vha->hw, fcport) ? "nvme" : "fcp");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 	rval = qla2x00_start_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 		fcport->flags |= FCF_LOGIN_NEEDED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 		set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) done_free_sp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 	fcport->flags &= ~FCF_ASYNC_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) int qla24xx_post_gpdb_work(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 	struct qla_work_evt *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	e = qla2x00_alloc_work(vha, QLA_EVT_GPDB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 	if (!e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 	e->u.fcport.fcport = fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 	e->u.fcport.opt = opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 	fcport->flags |= FCF_ASYNC_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 	return qla2x00_post_work(vha, e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) int qla24xx_async_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 	srb_t *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	struct srb_iocb *mbx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 	int rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	u16 *mb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	dma_addr_t pd_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	struct port_database_24xx *pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	if (IS_SESSION_DELETED(fcport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 		ql_log(ql_log_warn, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 		       "%s: %8phC is being delete - not sending command.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 		       __func__, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 		fcport->flags &= ~FCF_ASYNC_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 	if (!vha->flags.online || fcport->flags & FCF_ASYNC_SENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 		ql_log(ql_log_warn, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 		    "%s: %8phC online %d flags %x - not sending command.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 		    __func__, fcport->port_name, vha->flags.online, fcport->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 	if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	qla2x00_set_fcport_disc_state(fcport, DSC_GPDB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	fcport->flags |= FCF_ASYNC_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	sp->type = SRB_MB_IOCB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	sp->name = "gpdb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	sp->gen1 = fcport->rscn_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 	sp->gen2 = fcport->login_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	mbx = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	mbx->timeout = qla2x00_async_iocb_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	pd = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	if (pd == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 		ql_log(ql_log_warn, vha, 0xd043,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 		    "Failed to allocate port database structure.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 	mb = sp->u.iocb_cmd.u.mbx.out_mb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 	mb[0] = MBC_GET_PORT_DATABASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 	mb[1] = fcport->loop_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	mb[2] = MSW(pd_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 	mb[3] = LSW(pd_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 	mb[6] = MSW(MSD(pd_dma));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	mb[7] = LSW(MSD(pd_dma));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 	mb[9] = vha->vp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 	mb[10] = opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 	mbx->u.mbx.in = pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 	mbx->u.mbx.in_dma = pd_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 	sp->done = qla24xx_async_gpdb_sp_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	ql_dbg(ql_dbg_disc, vha, 0x20dc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 	    "Async-%s %8phC hndl %x opt %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 	    sp->name, fcport->port_name, sp->handle, opt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 	rval = qla2x00_start_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 	if (rval != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) done_free_sp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	if (pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 		dma_pool_free(ha->s_dma_pool, pd, pd_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 	fcport->flags &= ~FCF_ASYNC_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 	fcport->flags &= ~FCF_ASYNC_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	qla24xx_post_gpdb_work(vha, fcport, opt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) void __qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 	spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 	ea->fcport->login_gen++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 	ea->fcport->deleted = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 	ea->fcport->logout_on_delete = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 	if (!ea->fcport->login_succ && !IS_SW_RESV_ADDR(ea->fcport->d_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 		vha->fcport_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 		ea->fcport->login_succ = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 		spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 		qla24xx_sched_upd_fcport(ea->fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 		spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	} else if (ea->fcport->login_succ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 		 * We have an existing session. A late RSCN delivery
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 		 * must have triggered the session to be re-validate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 		 * Session is still valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 		ql_dbg(ql_dbg_disc, vha, 0x20d6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 		    "%s %d %8phC session revalidate success\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 		    __func__, __LINE__, ea->fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 		qla2x00_set_fcport_disc_state(ea->fcport, DSC_LOGIN_COMPLETE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 	spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 	fc_port_t *fcport = ea->fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 	struct port_database_24xx *pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 	struct srb *sp = ea->sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	uint8_t	ls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 	pd = (struct port_database_24xx *)sp->u.iocb_cmd.u.mbx.in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 	fcport->flags &= ~FCF_ASYNC_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 	ql_dbg(ql_dbg_disc, vha, 0x20d2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 	    "%s %8phC DS %d LS %d fc4_type %x rc %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 	    fcport->port_name, fcport->disc_state, pd->current_login_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 	    fcport->fc4_type, ea->rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 	if (fcport->disc_state == DSC_DELETE_PEND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 	if (NVME_TARGET(vha->hw, fcport))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 		ls = pd->current_login_state >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 		ls = pd->current_login_state & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 	if (ea->sp->gen2 != fcport->login_gen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 		/* target side must have changed it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 		ql_dbg(ql_dbg_disc, vha, 0x20d3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 		    "%s %8phC generation changed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 		    __func__, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 	} else if (ea->sp->gen1 != fcport->rscn_gen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 		qla_rscn_replay(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 		qlt_schedule_sess_for_deletion(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 	switch (ls) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 	case PDS_PRLI_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 		__qla24xx_parse_gpdb(vha, fcport, pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 	case PDS_PLOGI_PENDING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 	case PDS_PLOGI_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 	case PDS_PRLI_PENDING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 	case PDS_PRLI2_PENDING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 		/* Set discovery state back to GNL to Relogin attempt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 		if (qla_dual_mode_enabled(vha) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 		    qla_ini_mode_enabled(vha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 			qla2x00_set_fcport_disc_state(fcport, DSC_GNL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 			set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 	case PDS_LOGO_PENDING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 	case PDS_PORT_UNAVAILABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 		ql_dbg(ql_dbg_disc, vha, 0x20d5, "%s %d %8phC post del sess\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 		    __func__, __LINE__, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 		qlt_schedule_sess_for_deletion(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 	__qla24xx_handle_gpdb_event(vha, ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) } /* gpdb event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) static void qla_chk_n2n_b4_login(struct scsi_qla_host *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 	u8 login = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 	ql_dbg(ql_dbg_disc, vha, 0x307b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 	    "%s %8phC DS %d LS %d lid %d retries=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 	    __func__, fcport->port_name, fcport->disc_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 	    fcport->fw_login_state, fcport->loop_id, fcport->login_retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 	if (qla_tgt_mode_enabled(vha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 	if (qla_dual_mode_enabled(vha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 		if (N2N_TOPO(vha->hw)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 			u64 mywwn, wwn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 			mywwn = wwn_to_u64(vha->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 			wwn = wwn_to_u64(fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 			if (mywwn > wwn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 				login = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 			else if ((fcport->fw_login_state == DSC_LS_PLOGI_COMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 			    && time_after_eq(jiffies,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 				    fcport->plogi_nack_done_deadline))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 				login = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 			login = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 		/* initiator mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 		login = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 	if (login && fcport->login_retry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 		fcport->login_retry--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 		if (fcport->loop_id == FC_NO_LOOP_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 			fcport->fw_login_state = DSC_LS_PORT_UNAVAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 			rc = qla2x00_find_new_loop_id(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 			if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 				ql_dbg(ql_dbg_disc, vha, 0x20e6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 				    "%s %d %8phC post del sess - out of loopid\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 				    __func__, __LINE__, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 				fcport->scan_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 				qlt_schedule_sess_for_deletion(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 				return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 		ql_dbg(ql_dbg_disc, vha, 0x20bf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 		    "%s %d %8phC post login\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 		    __func__, __LINE__, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 		qla2x00_post_async_login_work(vha, fcport, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 	u16 data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 	u64 wwn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 	u16 sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	ql_dbg(ql_dbg_disc, vha, 0x20d8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 	    "%s %8phC DS %d LS %d P %d fl %x confl %p rscn %d|%d login %d lid %d scan %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 	    __func__, fcport->port_name, fcport->disc_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 	    fcport->fw_login_state, fcport->login_pause, fcport->flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 	    fcport->conflict, fcport->last_rscn_gen, fcport->rscn_gen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	    fcport->login_gen, fcport->loop_id, fcport->scan_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 	if (fcport->scan_state != QLA_FCPORT_FOUND ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 	    fcport->disc_state == DSC_DELETE_PEND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 	if ((fcport->loop_id != FC_NO_LOOP_ID) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	    qla_dual_mode_enabled(vha) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 	    ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 	     (fcport->fw_login_state == DSC_LS_PRLI_PEND)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 	if (fcport->fw_login_state == DSC_LS_PLOGI_COMP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 	    !N2N_TOPO(vha->hw)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 		if (time_before_eq(jiffies, fcport->plogi_nack_done_deadline)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 			set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 	/* Target won't initiate port login if fabric is present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 	if (vha->host->active_mode == MODE_TARGET && !N2N_TOPO(vha->hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	if (fcport->flags & (FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 		set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 	switch (fcport->disc_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 	case DSC_DELETED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 		wwn = wwn_to_u64(fcport->node_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 		switch (vha->hw->current_topology) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 		case ISP_CFG_N:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 			if (fcport_is_smaller(fcport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 				/* this adapter is bigger */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 				if (fcport->login_retry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 					if (fcport->loop_id == FC_NO_LOOP_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 						qla2x00_find_new_loop_id(vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 						    fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 						fcport->fw_login_state =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 						    DSC_LS_PORT_UNAVAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 					fcport->login_retry--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 					qla_post_els_plogi_work(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 					ql_log(ql_log_info, vha, 0x705d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 					    "Unable to reach remote port %8phC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 					    fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 				qla24xx_post_gnl_work(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 			if (wwn == 0)    {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 				ql_dbg(ql_dbg_disc, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 				    "%s %d %8phC post GNNID\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 				    __func__, __LINE__, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 				qla24xx_post_gnnid_work(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 			} else if (fcport->loop_id == FC_NO_LOOP_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 				ql_dbg(ql_dbg_disc, vha, 0x20bd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 				    "%s %d %8phC post gnl\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 				    __func__, __LINE__, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 				qla24xx_post_gnl_work(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 				qla_chk_n2n_b4_login(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 	case DSC_GNL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 		switch (vha->hw->current_topology) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 		case ISP_CFG_N:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 			if ((fcport->current_login_state & 0xf) == 0x6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 				ql_dbg(ql_dbg_disc, vha, 0x2118,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 				    "%s %d %8phC post GPDB work\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 				    __func__, __LINE__, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 				fcport->chip_reset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 					vha->hw->base_qpair->chip_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 				qla24xx_post_gpdb_work(vha, fcport, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 			}  else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 				ql_dbg(ql_dbg_disc, vha, 0x2118,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 				    "%s %d %8phC post %s PRLI\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 				    __func__, __LINE__, fcport->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 				    NVME_TARGET(vha->hw, fcport) ? "NVME" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 				    "FC");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 				qla24xx_post_prli_work(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 			if (fcport->login_pause) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 				ql_dbg(ql_dbg_disc, vha, 0x20d8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 				    "%s %d %8phC exit\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 				    __func__, __LINE__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 				    fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 				fcport->last_rscn_gen = fcport->rscn_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 				fcport->last_login_gen = fcport->login_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 				set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 			qla_chk_n2n_b4_login(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 	case DSC_LOGIN_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 		if (N2N_TOPO(vha->hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 			qla_chk_n2n_b4_login(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 			qlt_schedule_sess_for_deletion(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 	case DSC_LOGIN_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 		/* recheck login state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 		data[0] = data[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 		qla2x00_post_async_adisc_work(vha, fcport, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 	case DSC_LOGIN_PEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 		if (fcport->fw_login_state == DSC_LS_PLOGI_COMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 			qla24xx_post_prli_work(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 	case DSC_UPD_FCPORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 		sec =  jiffies_to_msecs(jiffies -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 		    fcport->jiffies_at_registration)/1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 		if (fcport->sec_since_registration < sec && sec &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 		    !(sec % 60)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 			fcport->sec_since_registration = sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 			ql_dbg(ql_dbg_disc, fcport->vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 			    "%s %8phC - Slow Rport registration(%d Sec)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 			    __func__, fcport->port_name, sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 		if (fcport->next_disc_state != DSC_DELETE_PEND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 			fcport->next_disc_state = DSC_ADISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 		set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) int qla24xx_post_newsess_work(struct scsi_qla_host *vha, port_id_t *id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710)     u8 *port_name, u8 *node_name, void *pla, u8 fc4_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 	struct qla_work_evt *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 	e = qla2x00_alloc_work(vha, QLA_EVT_NEW_SESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 	if (!e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 	e->u.new_sess.id = *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 	e->u.new_sess.pla = pla;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 	e->u.new_sess.fc4_type = fc4_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 	memcpy(e->u.new_sess.port_name, port_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 	if (node_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 		memcpy(e->u.new_sess.node_name, node_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 	return qla2x00_post_work(vha, e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 	fc_port_t *fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 	switch (ea->id.b.rsvd_1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 	case RSCN_PORT_ADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 		fcport = qla2x00_find_fcport_by_nportid(vha, &ea->id, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 		if (fcport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 			if (fcport->flags & FCF_FCP2_DEVICE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 				ql_dbg(ql_dbg_disc, vha, 0x2115,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 				       "Delaying session delete for FCP2 portid=%06x %8phC ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 					fcport->d_id.b24, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 				return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 			fcport->scan_needed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 			fcport->rscn_gen++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 	case RSCN_AREA_ADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 		list_for_each_entry(fcport, &vha->vp_fcports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 			if (fcport->flags & FCF_FCP2_DEVICE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 			if ((ea->id.b24 & 0xffff00) == (fcport->d_id.b24 & 0xffff00)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 				fcport->scan_needed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 				fcport->rscn_gen++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 	case RSCN_DOM_ADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 		list_for_each_entry(fcport, &vha->vp_fcports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 			if (fcport->flags & FCF_FCP2_DEVICE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 			if ((ea->id.b24 & 0xff0000) == (fcport->d_id.b24 & 0xff0000)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 				fcport->scan_needed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 				fcport->rscn_gen++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 	case RSCN_FAB_ADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 		list_for_each_entry(fcport, &vha->vp_fcports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 			if (fcport->flags & FCF_FCP2_DEVICE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 			fcport->scan_needed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 			fcport->rscn_gen++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 	spin_lock_irqsave(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 	if (vha->scan.scan_flags == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 		ql_dbg(ql_dbg_disc, vha, 0xffff, "%s: schedule\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 		vha->scan.scan_flags |= SF_QUEUED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 		schedule_delayed_work(&vha->scan.scan_work, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 	spin_unlock_irqrestore(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) void qla24xx_handle_relogin_event(scsi_qla_host_t *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 	struct event_arg *ea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 	fc_port_t *fcport = ea->fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 	if (test_bit(UNLOADING, &vha->dpc_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 	ql_dbg(ql_dbg_disc, vha, 0x2102,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 	    "%s %8phC DS %d LS %d P %d del %d cnfl %p rscn %d|%d login %d|%d fl %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 	    __func__, fcport->port_name, fcport->disc_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 	    fcport->fw_login_state, fcport->login_pause,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 	    fcport->deleted, fcport->conflict,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 	    fcport->last_rscn_gen, fcport->rscn_gen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 	    fcport->last_login_gen, fcport->login_gen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 	    fcport->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 	if (fcport->last_rscn_gen != fcport->rscn_gen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 		ql_dbg(ql_dbg_disc, vha, 0x20e9, "%s %d %8phC post gnl\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 		    __func__, __LINE__, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 		qla24xx_post_gnl_work(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 	qla24xx_fcport_handle_login(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) void qla_handle_els_plogi_done(scsi_qla_host_t *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 				      struct event_arg *ea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 	/* for pure Target Mode, PRLI will not be initiated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 	if (vha->host->active_mode == MODE_TARGET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 	ql_dbg(ql_dbg_disc, vha, 0x2118,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 	    "%s %d %8phC post PRLI\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 	    __func__, __LINE__, ea->fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 	qla24xx_post_prli_work(vha, ea->fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831)  * RSCN(s) came in for this fcport, but the RSCN(s) was not able
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)  * to be consumed by the fcport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) void qla_rscn_replay(fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 	struct event_arg ea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 	switch (fcport->disc_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 	case DSC_DELETE_PEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 	if (fcport->scan_needed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 		memset(&ea, 0, sizeof(ea));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 		ea.id = fcport->d_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 		ea.id.b.rsvd_1 = RSCN_PORT_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 		qla2x00_handle_rscn(fcport->vha, &ea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) qla2x00_tmf_iocb_timeout(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 	srb_t *sp = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 	struct srb_iocb *tmf = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 	int rc, h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 	rc = qla24xx_async_abort_cmd(sp, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 	if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 		spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 		for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 			if (sp->qpair->req->outstanding_cmds[h] == sp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 				sp->qpair->req->outstanding_cmds[h] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 		spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 		tmf->u.tmf.comp_status = cpu_to_le16(CS_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 		tmf->u.tmf.data = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 		complete(&tmf->u.tmf.comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) static void qla2x00_tmf_sp_done(srb_t *sp, int res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 	struct srb_iocb *tmf = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 	complete(&tmf->u.tmf.comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 	uint32_t tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 	struct scsi_qla_host *vha = fcport->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 	struct srb_iocb *tm_iocb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 	srb_t *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 	int rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 	if (!sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 	tm_iocb = &sp->u.iocb_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 	sp->type = SRB_TM_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 	sp->name = "tmf";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 	tm_iocb->timeout = qla2x00_tmf_iocb_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 	init_completion(&tm_iocb->u.tmf.comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 	qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 	tm_iocb->u.tmf.flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 	tm_iocb->u.tmf.lun = lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 	tm_iocb->u.tmf.data = tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 	sp->done = qla2x00_tmf_sp_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 	ql_dbg(ql_dbg_taskm, vha, 0x802f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 	    "Async-tmf hdl=%x loop-id=%x portid=%02x%02x%02x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 	    sp->handle, fcport->loop_id, fcport->d_id.b.domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 	    fcport->d_id.b.area, fcport->d_id.b.al_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 	rval = qla2x00_start_sp(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 	if (rval != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 		goto done_free_sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 	wait_for_completion(&tm_iocb->u.tmf.comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 	rval = tm_iocb->u.tmf.data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 		ql_log(ql_log_warn, vha, 0x8030,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 		    "TM IOCB failed (%x).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 	if (!test_bit(UNLOADING, &vha->dpc_flags) && !IS_QLAFX00(vha->hw)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 		flags = tm_iocb->u.tmf.flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 		lun = (uint16_t)tm_iocb->u.tmf.lun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 		/* Issue Marker IOCB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 		qla2x00_marker(vha, vha->hw->base_qpair,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 		    fcport->loop_id, lun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 		    flags == TCF_LUN_RESET ? MK_SYNC_ID_LUN : MK_SYNC_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) done_free_sp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 	sp->free(sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 	fcport->flags &= ~FCF_ASYNC_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) qla24xx_async_abort_command(srb_t *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 	unsigned long   flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 	uint32_t	handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 	fc_port_t	*fcport = sp->fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 	struct qla_qpair *qpair = sp->qpair;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 	struct scsi_qla_host *vha = fcport->vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 	struct req_que *req = qpair->req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 	spin_lock_irqsave(qpair->qp_lock_ptr, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 	for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 		if (req->outstanding_cmds[handle] == sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 	spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 	if (handle == req->num_outstanding_cmds) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 		/* Command not found. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 	if (sp->type == SRB_FXIOCB_DCMD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 		return qlafx00_fx_disc(vha, &vha->hw->mr.fcport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 		    FXDISC_ABORT_IOCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 	return qla24xx_async_abort_cmd(sp, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 	WARN_ONCE(!qla2xxx_is_valid_mbs(ea->data[0]), "mbs: %#x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 		  ea->data[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 	switch (ea->data[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 	case MBS_COMMAND_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 		ql_dbg(ql_dbg_disc, vha, 0x2118,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 		    "%s %d %8phC post gpdb\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 		    __func__, __LINE__, ea->fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 		ea->fcport->chip_reset = vha->hw->base_qpair->chip_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 		ea->fcport->logout_on_delete = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 		ea->fcport->nvme_prli_service_param = ea->iop[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 		if (ea->iop[0] & NVME_PRLI_SP_FIRST_BURST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 			ea->fcport->nvme_first_burst_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 			    (ea->iop[1] & 0xffff) * 512;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 			ea->fcport->nvme_first_burst_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 		qla24xx_post_gpdb_work(vha, ea->fcport, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 		if ((ea->iop[0] == LSC_SCODE_ELS_REJECT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 		    (ea->iop[1] == 0x50000)) {   /* reson 5=busy expl:0x0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 			set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 			ea->fcport->fw_login_state = DSC_LS_PLOGI_COMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 		ql_dbg(ql_dbg_disc, vha, 0x2118,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 		       "%s %d %8phC priority %s, fc4type %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 		       __func__, __LINE__, ea->fcport->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 		       vha->hw->fc4_type_priority == FC4_PRIORITY_FCP ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 		       "FCP" : "NVMe", ea->fcport->fc4_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 		if (N2N_TOPO(vha->hw)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 			if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 				ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 				ea->fcport->fc4_type |= FS_FC4TYPE_FCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 				ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 				ea->fcport->fc4_type |= FS_FC4TYPE_NVME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 			if (ea->fcport->n2n_link_reset_cnt < 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 				ea->fcport->n2n_link_reset_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 				vha->relogin_jif = jiffies + 2 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 				 * PRLI failed. Reset link to kick start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 				 * state machine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 				set_bit(N2N_LINK_RESET, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 				ql_log(ql_log_warn, vha, 0x2119,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 				       "%s %d %8phC Unable to reconnect\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 				       __func__, __LINE__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 				       ea->fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 			 * switch connect. login failed. Take connection down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 			 * and allow relogin to retrigger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 			if (NVME_FCP_TARGET(ea->fcport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 				ql_dbg(ql_dbg_disc, vha, 0x2118,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 				       "%s %d %8phC post %s prli\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 				       __func__, __LINE__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 				       ea->fcport->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 				       (ea->fcport->fc4_type & FS_FC4TYPE_NVME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 				       ? "NVMe" : "FCP");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 				if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 					ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 					ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 			ea->fcport->flags &= ~FCF_ASYNC_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 			ea->fcport->keep_nport_handle = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 			ea->fcport->logout_on_delete = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) 			qlt_schedule_sess_for_deletion(ea->fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) 	port_id_t cid;	/* conflict Nport id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 	u16 lid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 	struct fc_port *conflict_fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 	struct fc_port *fcport = ea->fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) 	ql_dbg(ql_dbg_disc, vha, 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 	    "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d data %x|%x iop %x|%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 	    __func__, fcport->port_name, fcport->disc_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 	    fcport->fw_login_state, ea->rc, ea->sp->gen2, fcport->login_gen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 	    ea->sp->gen1, fcport->rscn_gen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 	    ea->data[0], ea->data[1], ea->iop[0], ea->iop[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 	if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 	    (fcport->fw_login_state == DSC_LS_PRLI_PEND)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 		ql_dbg(ql_dbg_disc, vha, 0x20ea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 		    "%s %d %8phC Remote is trying to login\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 		    __func__, __LINE__, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 	if ((fcport->disc_state == DSC_DELETE_PEND) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 	    (fcport->disc_state == DSC_DELETED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 		set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 	if (ea->sp->gen2 != fcport->login_gen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 		/* target side must have changed it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 		ql_dbg(ql_dbg_disc, vha, 0x20d3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 		    "%s %8phC generation changed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 		    __func__, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 		set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 	} else if (ea->sp->gen1 != fcport->rscn_gen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 		ql_dbg(ql_dbg_disc, vha, 0x20d3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 		    "%s %8phC RSCN generation changed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 		    __func__, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 		qla_rscn_replay(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 		qlt_schedule_sess_for_deletion(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 	WARN_ONCE(!qla2xxx_is_valid_mbs(ea->data[0]), "mbs: %#x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 		  ea->data[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 	switch (ea->data[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 	case MBS_COMMAND_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) 		 * Driver must validate login state - If PRLI not complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 		 * force a relogin attempt via implicit LOGO, PLOGI, and PRLI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 		 * requests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 		if (NVME_TARGET(vha->hw, ea->fcport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) 			ql_dbg(ql_dbg_disc, vha, 0x2117,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 				"%s %d %8phC post prli\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 				__func__, __LINE__, ea->fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 			qla24xx_post_prli_work(vha, ea->fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 			ql_dbg(ql_dbg_disc, vha, 0x20ea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 			    "%s %d %8phC LoopID 0x%x in use with %06x. post gpdb\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 			    __func__, __LINE__, ea->fcport->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 			    ea->fcport->loop_id, ea->fcport->d_id.b24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 			set_bit(ea->fcport->loop_id, vha->hw->loop_id_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 			spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) 			ea->fcport->chip_reset = vha->hw->base_qpair->chip_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 			ea->fcport->logout_on_delete = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 			ea->fcport->send_els_logo = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) 			ea->fcport->fw_login_state = DSC_LS_PRLI_COMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 			spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 			qla24xx_post_gpdb_work(vha, ea->fcport, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 	case MBS_COMMAND_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 		ql_dbg(ql_dbg_disc, vha, 0x20eb, "%s %d %8phC cmd error %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 		    __func__, __LINE__, ea->fcport->port_name, ea->data[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 		qlt_schedule_sess_for_deletion(ea->fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 	case MBS_LOOP_ID_USED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 		/* data[1] = IO PARAM 1 = nport ID  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 		cid.b.domain = (ea->iop[1] >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 		cid.b.area   = (ea->iop[1] >>  8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 		cid.b.al_pa  = ea->iop[1] & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 		cid.b.rsvd_1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 		ql_dbg(ql_dbg_disc, vha, 0x20ec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 		    "%s %d %8phC lid %#x in use with pid %06x post gnl\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 		    __func__, __LINE__, ea->fcport->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 		    ea->fcport->loop_id, cid.b24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 		set_bit(ea->fcport->loop_id, vha->hw->loop_id_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 		ea->fcport->loop_id = FC_NO_LOOP_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 		qla24xx_post_gnl_work(vha, ea->fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 	case MBS_PORT_ID_USED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) 		lid = ea->iop[1] & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 		qlt_find_sess_invalidate_other(vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 		    wwn_to_u64(ea->fcport->port_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 		    ea->fcport->d_id, lid, &conflict_fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 		if (conflict_fcport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 			 * Another fcport share the same loop_id/nport id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 			 * Conflict fcport needs to finish cleanup before this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 			 * fcport can proceed to login.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 			conflict_fcport->conflict = ea->fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 			ea->fcport->login_pause = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 			ql_dbg(ql_dbg_disc, vha, 0x20ed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 			    "%s %d %8phC NPortId %06x inuse with loopid 0x%x. post gidpn\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 			    __func__, __LINE__, ea->fcport->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 			    ea->fcport->d_id.b24, lid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 			ql_dbg(ql_dbg_disc, vha, 0x20ed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 			    "%s %d %8phC NPortId %06x inuse with loopid 0x%x. sched delete\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 			    __func__, __LINE__, ea->fcport->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 			    ea->fcport->d_id.b24, lid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 			qla2x00_clear_loop_id(ea->fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 			set_bit(lid, vha->hw->loop_id_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 			ea->fcport->loop_id = lid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) 			ea->fcport->keep_nport_handle = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 			ea->fcport->logout_on_delete = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 			qlt_schedule_sess_for_deletion(ea->fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) /*                QLogic ISP2x00 Hardware Support Functions.                */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) qla83xx_nic_core_fw_load(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 	int rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 	uint32_t idc_major_ver, idc_minor_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 	uint16_t config[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 	qla83xx_idc_lock(vha, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 	/* SV: TODO: Assign initialization timeout from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 	 * flash-info / other param
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 	ha->fcoe_dev_init_timeout = QLA83XX_IDC_INITIALIZATION_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 	ha->fcoe_reset_timeout = QLA83XX_IDC_RESET_ACK_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 	/* Set our fcoe function presence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 	if (__qla83xx_set_drv_presence(vha) != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 		ql_dbg(ql_dbg_p3p, vha, 0xb077,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 		    "Error while setting DRV-Presence.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 		rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) 	/* Decide the reset ownership */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) 	qla83xx_reset_ownership(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) 	 * On first protocol driver load:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 	 * Init-Owner: Set IDC-Major-Version and Clear IDC-Lock-Recovery
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 	 * register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 	 * Others: Check compatibility with current IDC Major version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 	qla83xx_rd_reg(vha, QLA83XX_IDC_MAJOR_VERSION, &idc_major_ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 	if (ha->flags.nic_core_reset_owner) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 		/* Set IDC Major version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 		idc_major_ver = QLA83XX_SUPP_IDC_MAJOR_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 		qla83xx_wr_reg(vha, QLA83XX_IDC_MAJOR_VERSION, idc_major_ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 		/* Clearing IDC-Lock-Recovery register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 		qla83xx_wr_reg(vha, QLA83XX_IDC_LOCK_RECOVERY, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 	} else if (idc_major_ver != QLA83XX_SUPP_IDC_MAJOR_VERSION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 		 * Clear further IDC participation if we are not compatible with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 		 * the current IDC Major Version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 		ql_log(ql_log_warn, vha, 0xb07d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 		    "Failing load, idc_major_ver=%d, expected_major_ver=%d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 		    idc_major_ver, QLA83XX_SUPP_IDC_MAJOR_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 		__qla83xx_clear_drv_presence(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 		rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 	/* Each function sets its supported Minor version. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 	qla83xx_rd_reg(vha, QLA83XX_IDC_MINOR_VERSION, &idc_minor_ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 	idc_minor_ver |= (QLA83XX_SUPP_IDC_MINOR_VERSION << (ha->portnum * 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 	qla83xx_wr_reg(vha, QLA83XX_IDC_MINOR_VERSION, idc_minor_ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 	if (ha->flags.nic_core_reset_owner) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 		memset(config, 0, sizeof(config));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 		if (!qla81xx_get_port_config(vha, config))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 			qla83xx_wr_reg(vha, QLA83XX_IDC_DEV_STATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 			    QLA8XXX_DEV_READY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 	rval = qla83xx_idc_state_handler(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 	qla83xx_idc_unlock(vha, 0);
^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_initialize_adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) *      Initialize board.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) * Input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) *      ha = adapter block pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) *      0 = success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) qla2x00_initialize_adapter(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 	int	rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 	struct req_que *req = ha->req_q_map[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 	memset(&vha->qla_stats, 0, sizeof(vha->qla_stats));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 	memset(&vha->fc_host_stat, 0, sizeof(vha->fc_host_stat));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 	/* Clear adapter flags. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 	vha->flags.online = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 	ha->flags.chip_reset_done = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 	vha->flags.reset_active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 	ha->flags.pci_channel_io_perm_failure = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 	ha->flags.eeh_busy = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 	vha->qla_stats.jiffies_at_last_reset = get_jiffies_64();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 	atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 	atomic_set(&vha->loop_state, LOOP_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 	vha->device_flags = DFLG_NO_CABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 	vha->dpc_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 	vha->flags.management_server_logged_in = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 	vha->marker_needed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 	ha->isp_abort_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 	ha->beacon_blink_led = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 	set_bit(0, ha->req_qid_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 	set_bit(0, ha->rsp_qid_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 	ql_dbg(ql_dbg_init, vha, 0x0040,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 	    "Configuring PCI space...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 	rval = ha->isp_ops->pci_config(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 	if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 		ql_log(ql_log_warn, vha, 0x0044,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 		    "Unable to configure PCI space.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 		return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 	ha->isp_ops->reset_chip(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 	/* Check for secure flash support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 	if (IS_QLA28XX(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 		if (rd_reg_word(&reg->mailbox12) & BIT_0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 			ha->flags.secure_adapter = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 		ql_log(ql_log_info, vha, 0xffff, "Secure Adapter: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 		    (ha->flags.secure_adapter) ? "Yes" : "No");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 	rval = qla2xxx_get_flash_info(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 	if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 		ql_log(ql_log_fatal, vha, 0x004f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 		    "Unable to validate FLASH data.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 	if (IS_QLA8044(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 		qla8044_read_reset_template(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 		/* NOTE: If ql2xdontresethba==1, set IDC_CTRL DONTRESET_BIT0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 		 * If DONRESET_BIT0 is set, drivers should not set dev_state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 		 * to NEED_RESET. But if NEED_RESET is set, drivers should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 		 * should honor the reset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 		if (ql2xdontresethba == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 			qla8044_set_idc_dontreset(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 	ha->isp_ops->get_flash_version(vha, req->ring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 	ql_dbg(ql_dbg_init, vha, 0x0061,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 	    "Configure NVRAM parameters...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 	/* Let priority default to FCP, can be overridden by nvram_config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 	ha->fc4_type_priority = FC4_PRIORITY_FCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 	ha->isp_ops->nvram_config(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 	if (ha->fc4_type_priority != FC4_PRIORITY_FCP &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 	    ha->fc4_type_priority != FC4_PRIORITY_NVME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 		ha->fc4_type_priority = FC4_PRIORITY_FCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 	ql_log(ql_log_info, vha, 0xffff, "FC4 priority set to %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 	       ha->fc4_type_priority == FC4_PRIORITY_FCP ? "FCP" : "NVMe");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 	if (ha->flags.disable_serdes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 		/* Mask HBA via NVRAM settings? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 		ql_log(ql_log_info, vha, 0x0077,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 		    "Masking HBA WWPN %8phN (via NVRAM).\n", vha->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 	ql_dbg(ql_dbg_init, vha, 0x0078,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 	    "Verifying loaded RISC code...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 	/* If smartsan enabled then require fdmi and rdp enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 	if (ql2xsmartsan) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 		ql2xfdmienable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 		ql2xrdpenable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 	if (qla2x00_isp_firmware(vha) != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 		rval = ha->isp_ops->chip_diag(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 		if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 			return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 		rval = qla2x00_setup_chip(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) 		if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 			return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 	if (IS_QLA84XX(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 		ha->cs84xx = qla84xx_get_chip(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 		if (!ha->cs84xx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) 			ql_log(ql_log_warn, vha, 0x00d0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 			    "Unable to configure ISP84XX.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) 			return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 	if (qla_ini_mode_enabled(vha) || qla_dual_mode_enabled(vha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 		rval = qla2x00_init_rings(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 	/* No point in continuing if firmware initialization failed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 	if (rval != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 	ha->flags.chip_reset_done = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 	if (rval == QLA_SUCCESS && IS_QLA84XX(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 		/* Issue verify 84xx FW IOCB to complete 84xx initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 		rval = qla84xx_init_chip(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 		if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 			ql_log(ql_log_warn, vha, 0x00d4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 			    "Unable to initialize ISP84XX.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 			qla84xx_put_chip(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 	/* Load the NIC Core f/w if we are the first protocol driver. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 	if (IS_QLA8031(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 		rval = qla83xx_nic_core_fw_load(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 		if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 			ql_log(ql_log_warn, vha, 0x0124,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 			    "Error in initializing NIC Core f/w.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 	if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 		qla24xx_read_fcp_prio_cfg(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 	if (IS_P3P_TYPE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) 		qla82xx_set_driver_version(vha, QLA2XXX_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 		qla25xx_set_driver_version(vha, QLA2XXX_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440)  * qla2100_pci_config() - Setup ISP21xx PCI configuration registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) qla2100_pci_config(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 	uint16_t w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 	pci_set_master(ha->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 	pci_try_set_mwi(ha->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 	pci_read_config_word(ha->pdev, PCI_COMMAND, &w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 	w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 	pci_write_config_word(ha->pdev, PCI_COMMAND, w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 	pci_disable_rom(ha->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 	/* Get PCI bus information. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 	spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 	ha->pci_attr = rd_reg_word(&reg->ctrl_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 	return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471)  * qla2300_pci_config() - Setup ISP23xx PCI configuration registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) qla2300_pci_config(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 	uint16_t	w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 	unsigned long   flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 	uint32_t	cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 	pci_set_master(ha->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 	pci_try_set_mwi(ha->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 	pci_read_config_word(ha->pdev, PCI_COMMAND, &w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 	w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 	if (IS_QLA2322(ha) || IS_QLA6322(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 		w &= ~PCI_COMMAND_INTX_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 	pci_write_config_word(ha->pdev, PCI_COMMAND, w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 	 * If this is a 2300 card and not 2312, reset the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 	 * COMMAND_INVALIDATE due to a bug in the 2300. Unfortunately,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 	 * the 2310 also reports itself as a 2300 so we need to get the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 	 * fb revision level -- a 6 indicates it really is a 2300 and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 	 * not a 2310.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 	if (IS_QLA2300(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 		spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 		/* Pause RISC. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 		wrt_reg_word(&reg->hccr, HCCR_PAUSE_RISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 		for (cnt = 0; cnt < 30000; cnt++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 			if ((rd_reg_word(&reg->hccr) & HCCR_RISC_PAUSE) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 			udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 		/* Select FPM registers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 		wrt_reg_word(&reg->ctrl_status, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 		rd_reg_word(&reg->ctrl_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 		/* Get the fb rev level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 		ha->fb_rev = RD_FB_CMD_REG(ha, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 		if (ha->fb_rev == FPM_2300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 			pci_clear_mwi(ha->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 		/* Deselect FPM registers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 		wrt_reg_word(&reg->ctrl_status, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 		rd_reg_word(&reg->ctrl_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 		/* Release RISC module. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 		wrt_reg_word(&reg->hccr, HCCR_RELEASE_RISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 		for (cnt = 0; cnt < 30000; cnt++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 			if ((rd_reg_word(&reg->hccr) & HCCR_RISC_PAUSE) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 			udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 	pci_write_config_byte(ha->pdev, PCI_LATENCY_TIMER, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 	pci_disable_rom(ha->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 	/* Get PCI bus information. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 	spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 	ha->pci_attr = rd_reg_word(&reg->ctrl_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 	return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553)  * qla24xx_pci_config() - Setup ISP24xx PCI configuration registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) qla24xx_pci_config(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 	uint16_t w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 	unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 	pci_set_master(ha->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 	pci_try_set_mwi(ha->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 	pci_read_config_word(ha->pdev, PCI_COMMAND, &w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 	w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 	w &= ~PCI_COMMAND_INTX_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 	pci_write_config_word(ha->pdev, PCI_COMMAND, w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 	pci_write_config_byte(ha->pdev, PCI_LATENCY_TIMER, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) 	/* PCI-X -- adjust Maximum Memory Read Byte Count (2048). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 	if (pci_find_capability(ha->pdev, PCI_CAP_ID_PCIX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 		pcix_set_mmrbc(ha->pdev, 2048);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 	/* PCIe -- adjust Maximum Read Request Size (2048). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 	if (pci_is_pcie(ha->pdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 		pcie_set_readrq(ha->pdev, 4096);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 	pci_disable_rom(ha->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 	ha->chip_revision = ha->pdev->revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 	/* Get PCI bus information. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 	spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 	ha->pci_attr = rd_reg_dword(&reg->ctrl_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) 	return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597)  * qla25xx_pci_config() - Setup ISP25xx PCI configuration registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) qla25xx_pci_config(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) 	uint16_t w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 	pci_set_master(ha->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 	pci_try_set_mwi(ha->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 	pci_read_config_word(ha->pdev, PCI_COMMAND, &w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 	w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 	w &= ~PCI_COMMAND_INTX_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) 	pci_write_config_word(ha->pdev, PCI_COMMAND, w);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 	/* PCIe -- adjust Maximum Read Request Size (2048). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 	if (pci_is_pcie(ha->pdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 		pcie_set_readrq(ha->pdev, 4096);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) 	pci_disable_rom(ha->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) 	ha->chip_revision = ha->pdev->revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) 	return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) }
^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)  * qla2x00_isp_firmware() - Choose firmware image.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) qla2x00_isp_firmware(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) 	int  rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 	uint16_t loop_id, topo, sw_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 	uint8_t domain, area, al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) 	/* Assume loading risc code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) 	rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) 	if (ha->flags.disable_risc_code_load) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) 		ql_log(ql_log_info, vha, 0x0079, "RISC CODE NOT loaded.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) 		/* Verify checksum of loaded RISC code. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 		rval = qla2x00_verify_checksum(vha, ha->fw_srisc_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 		if (rval == QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) 			/* And, verify we are not in ROM code. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) 			rval = qla2x00_get_adapter_id(vha, &loop_id, &al_pa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) 			    &area, &domain, &topo, &sw_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 	if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 		ql_dbg(ql_dbg_init, vha, 0x007a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 		    "**** Load RISC code ****.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664)  * qla2x00_reset_chip() - Reset ISP chip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) qla2x00_reset_chip(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 	unsigned long   flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 	uint32_t	cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 	uint16_t	cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 	int rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 	if (unlikely(pci_channel_offline(ha->pdev)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 	ha->isp_ops->disable_intrs(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 	spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 	/* Turn off master enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 	cmd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 	pci_read_config_word(ha->pdev, PCI_COMMAND, &cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 	cmd &= ~PCI_COMMAND_MASTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 	pci_write_config_word(ha->pdev, PCI_COMMAND, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 	if (!IS_QLA2100(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) 		/* Pause RISC. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 		wrt_reg_word(&reg->hccr, HCCR_PAUSE_RISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 		if (IS_QLA2200(ha) || IS_QLA2300(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) 			for (cnt = 0; cnt < 30000; cnt++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 				if ((rd_reg_word(&reg->hccr) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) 				    HCCR_RISC_PAUSE) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) 				udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) 			rd_reg_word(&reg->hccr);	/* PCI Posting. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 			udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 		/* Select FPM registers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 		wrt_reg_word(&reg->ctrl_status, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) 		rd_reg_word(&reg->ctrl_status);		/* PCI Posting. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) 		/* FPM Soft Reset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 		wrt_reg_word(&reg->fpm_diag_config, 0x100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) 		rd_reg_word(&reg->fpm_diag_config);	/* PCI Posting. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) 		/* Toggle Fpm Reset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) 		if (!IS_QLA2200(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) 			wrt_reg_word(&reg->fpm_diag_config, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 			rd_reg_word(&reg->fpm_diag_config); /* PCI Posting. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) 		/* Select frame buffer registers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) 		wrt_reg_word(&reg->ctrl_status, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 		rd_reg_word(&reg->ctrl_status);		/* PCI Posting. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) 		/* Reset frame buffer FIFOs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) 		if (IS_QLA2200(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) 			WRT_FB_CMD_REG(ha, reg, 0xa000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) 			RD_FB_CMD_REG(ha, reg);		/* PCI Posting. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) 			WRT_FB_CMD_REG(ha, reg, 0x00fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) 			/* Read back fb_cmd until zero or 3 seconds max */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) 			for (cnt = 0; cnt < 3000; cnt++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) 				if ((RD_FB_CMD_REG(ha, reg) & 0xff) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) 				udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) 		/* Select RISC module registers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) 		wrt_reg_word(&reg->ctrl_status, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) 		rd_reg_word(&reg->ctrl_status);		/* PCI Posting. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) 		/* Reset RISC processor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) 		wrt_reg_word(&reg->hccr, HCCR_RESET_RISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) 		rd_reg_word(&reg->hccr);		/* PCI Posting. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 		/* Release RISC processor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) 		wrt_reg_word(&reg->hccr, HCCR_RELEASE_RISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 		rd_reg_word(&reg->hccr);		/* PCI Posting. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) 	wrt_reg_word(&reg->hccr, HCCR_CLR_RISC_INT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) 	wrt_reg_word(&reg->hccr, HCCR_CLR_HOST_INT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 	/* Reset ISP chip. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 	wrt_reg_word(&reg->ctrl_status, CSR_ISP_SOFT_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 	/* Wait for RISC to recover from reset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 	if (IS_QLA2100(ha) || IS_QLA2200(ha) || IS_QLA2300(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 		 * It is necessary to for a delay here since the card doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) 		 * respond to PCI reads during a reset. On some architectures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) 		 * this will result in an MCA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 		udelay(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 		for (cnt = 30000; cnt; cnt--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 			if ((rd_reg_word(&reg->ctrl_status) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) 			    CSR_ISP_SOFT_RESET) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) 			udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) 		udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) 	/* Reset RISC processor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 	wrt_reg_word(&reg->hccr, HCCR_RESET_RISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 	wrt_reg_word(&reg->semaphore, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 	/* Release RISC processor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 	wrt_reg_word(&reg->hccr, HCCR_RELEASE_RISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 	rd_reg_word(&reg->hccr);			/* PCI Posting. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 	if (IS_QLA2100(ha) || IS_QLA2200(ha) || IS_QLA2300(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 		for (cnt = 0; cnt < 30000; cnt++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 			if (RD_MAILBOX_REG(ha, reg, 0) != MBS_BUSY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) 			udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) 		udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) 	/* Turn on master enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) 	cmd |= PCI_COMMAND_MASTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) 	pci_write_config_word(ha->pdev, PCI_COMMAND, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) 	/* Disable RISC pause on FPM parity error. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) 	if (!IS_QLA2100(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) 		wrt_reg_word(&reg->hccr, HCCR_DISABLE_PARITY_PAUSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) 		rd_reg_word(&reg->hccr);		/* PCI Posting. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) 	return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811)  * qla81xx_reset_mpi() - Reset's MPI FW via Write MPI Register MBC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) qla81xx_reset_mpi(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 	uint16_t mb[4] = {0x1010, 0, 1, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 	if (!IS_QLA81XX(vha->hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 		return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 	return qla81xx_write_mpi_register(vha, mb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828)  * qla24xx_reset_risc() - Perform full reset of ISP24xx RISC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) qla24xx_reset_risc(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 	unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) 	uint32_t cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 	uint16_t wd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) 	static int abts_cnt; /* ISP abort retry counts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) 	int rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 	spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 	/* Reset RISC. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 	wrt_reg_dword(&reg->ctrl_status, CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 	for (cnt = 0; cnt < 30000; cnt++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) 		if ((rd_reg_dword(&reg->ctrl_status) & CSRX_DMA_ACTIVE) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 		udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 	if (!(rd_reg_dword(&reg->ctrl_status) & CSRX_DMA_ACTIVE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) 		set_bit(DMA_SHUTDOWN_CMPL, &ha->fw_dump_cap_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) 	ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x017e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) 	    "HCCR: 0x%x, Control Status %x, DMA active status:0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 	    rd_reg_dword(&reg->hccr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) 	    rd_reg_dword(&reg->ctrl_status),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 	    (rd_reg_dword(&reg->ctrl_status) & CSRX_DMA_ACTIVE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) 	wrt_reg_dword(&reg->ctrl_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) 	    CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) 	pci_read_config_word(ha->pdev, PCI_COMMAND, &wd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) 	udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) 	/* Wait for firmware to complete NVRAM accesses. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 	rd_reg_word(&reg->mailbox0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) 	for (cnt = 10000; rd_reg_word(&reg->mailbox0) != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 	    rval == QLA_SUCCESS; cnt--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) 		barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) 		if (cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 			udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 			rval = QLA_FUNCTION_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 	if (rval == QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 		set_bit(ISP_MBX_RDY, &ha->fw_dump_cap_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 	ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x017f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) 	    "HCCR: 0x%x, MailBox0 Status 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 	    rd_reg_dword(&reg->hccr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) 	    rd_reg_word(&reg->mailbox0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) 	/* Wait for soft-reset to complete. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 	rd_reg_dword(&reg->ctrl_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) 	for (cnt = 0; cnt < 60; cnt++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) 		barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) 		if ((rd_reg_dword(&reg->ctrl_status) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 		    CSRX_ISP_SOFT_RESET) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 		udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 	if (!(rd_reg_dword(&reg->ctrl_status) & CSRX_ISP_SOFT_RESET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 		set_bit(ISP_SOFT_RESET_CMPL, &ha->fw_dump_cap_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 	ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x015d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 	    "HCCR: 0x%x, Soft Reset status: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 	    rd_reg_dword(&reg->hccr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 	    rd_reg_dword(&reg->ctrl_status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 	/* If required, do an MPI FW reset now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 	if (test_and_clear_bit(MPI_RESET_NEEDED, &vha->dpc_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 		if (qla81xx_reset_mpi(vha) != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 			if (++abts_cnt < 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 				set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) 				set_bit(MPI_RESET_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) 				 * We exhausted the ISP abort retries. We have to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) 				 * set the board offline.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 				abts_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) 				vha->flags.online = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) 	wrt_reg_dword(&reg->hccr, HCCRX_SET_RISC_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) 	rd_reg_dword(&reg->hccr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) 	wrt_reg_dword(&reg->hccr, HCCRX_REL_RISC_PAUSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 	rd_reg_dword(&reg->hccr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 	wrt_reg_dword(&reg->hccr, HCCRX_CLR_RISC_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) 	rd_reg_dword(&reg->hccr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) 	rd_reg_word(&reg->mailbox0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 	for (cnt = 60; rd_reg_word(&reg->mailbox0) != 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 	    rval == QLA_SUCCESS; cnt--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 		barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) 		if (cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) 			udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) 			rval = QLA_FUNCTION_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) 	if (rval == QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) 		set_bit(RISC_RDY_AFT_RESET, &ha->fw_dump_cap_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) 	ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x015e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) 	    "Host Risc 0x%x, mailbox0 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) 	    rd_reg_dword(&reg->hccr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) 	     rd_reg_word(&reg->mailbox0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) 	ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x015f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) 	    "Driver in %s mode\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) 	    IS_NOPOLLING_TYPE(ha) ? "Interrupt" : "Polling");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) 	if (IS_NOPOLLING_TYPE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) 		ha->isp_ops->enable_intrs(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) qla25xx_read_risc_sema_reg(scsi_qla_host_t *vha, uint32_t *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) 	struct device_reg_24xx __iomem *reg = &vha->hw->iobase->isp24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) 	wrt_reg_dword(&reg->iobase_addr, RISC_REGISTER_BASE_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) 	*data = rd_reg_dword(&reg->iobase_window + RISC_REGISTER_WINDOW_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) qla25xx_write_risc_sema_reg(scsi_qla_host_t *vha, uint32_t data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) 	struct device_reg_24xx __iomem *reg = &vha->hw->iobase->isp24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) 	wrt_reg_dword(&reg->iobase_addr, RISC_REGISTER_BASE_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) 	wrt_reg_dword(&reg->iobase_window + RISC_REGISTER_WINDOW_OFFSET, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) qla25xx_manipulate_risc_semaphore(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) 	uint32_t wd32 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) 	uint delta_msec = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) 	uint elapsed_msec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) 	uint timeout_msec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) 	ulong n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) 	if (vha->hw->pdev->subsystem_device != 0x0175 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) 	    vha->hw->pdev->subsystem_device != 0x0240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) 	wrt_reg_dword(&vha->hw->iobase->isp24.hccr, HCCRX_SET_RISC_PAUSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) 	udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) attempt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) 	timeout_msec = TIMEOUT_SEMAPHORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) 	n = timeout_msec / delta_msec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) 	while (n--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) 		qla25xx_write_risc_sema_reg(vha, RISC_SEMAPHORE_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) 		qla25xx_read_risc_sema_reg(vha, &wd32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) 		if (wd32 & RISC_SEMAPHORE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) 		msleep(delta_msec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) 		elapsed_msec += delta_msec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) 		if (elapsed_msec > TIMEOUT_TOTAL_ELAPSED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) 			goto force;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) 	if (!(wd32 & RISC_SEMAPHORE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) 		goto force;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) 	if (!(wd32 & RISC_SEMAPHORE_FORCE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) 		goto acquired;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) 	qla25xx_write_risc_sema_reg(vha, RISC_SEMAPHORE_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) 	timeout_msec = TIMEOUT_SEMAPHORE_FORCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) 	n = timeout_msec / delta_msec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) 	while (n--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) 		qla25xx_read_risc_sema_reg(vha, &wd32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) 		if (!(wd32 & RISC_SEMAPHORE_FORCE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) 		msleep(delta_msec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) 		elapsed_msec += delta_msec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) 		if (elapsed_msec > TIMEOUT_TOTAL_ELAPSED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) 			goto force;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) 	if (wd32 & RISC_SEMAPHORE_FORCE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) 		qla25xx_write_risc_sema_reg(vha, RISC_SEMAPHORE_FORCE_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) 	goto attempt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) force:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) 	qla25xx_write_risc_sema_reg(vha, RISC_SEMAPHORE_FORCE_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) acquired:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042)  * qla24xx_reset_chip() - Reset ISP24xx chip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) qla24xx_reset_chip(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) 	int rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) 	if (pci_channel_offline(ha->pdev) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) 	    ha->flags.pci_channel_io_perm_failure) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) 	ha->isp_ops->disable_intrs(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) 	qla25xx_manipulate_risc_semaphore(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) 	/* Perform RISC reset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) 	rval = qla24xx_reset_risc(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069)  * qla2x00_chip_diag() - Test chip for proper operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) qla2x00_chip_diag(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) 	int		rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) 	unsigned long	flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) 	uint16_t	data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) 	uint32_t	cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) 	uint16_t	mb[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) 	struct req_que *req = ha->req_q_map[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) 	/* Assume a failed state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) 	rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) 	ql_dbg(ql_dbg_init, vha, 0x007b, "Testing device at %p.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) 	       &reg->flash_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) 	spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) 	/* Reset ISP chip. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) 	wrt_reg_word(&reg->ctrl_status, CSR_ISP_SOFT_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) 	 * We need to have a delay here since the card will not respond while
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) 	 * in reset causing an MCA on some architectures.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) 	udelay(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) 	data = qla2x00_debounce_register(&reg->ctrl_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) 	for (cnt = 6000000 ; cnt && (data & CSR_ISP_SOFT_RESET); cnt--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) 		udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) 		data = rd_reg_word(&reg->ctrl_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) 		barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) 	if (!cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) 		goto chip_diag_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) 	ql_dbg(ql_dbg_init, vha, 0x007c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) 	    "Reset register cleared by chip reset.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) 	/* Reset RISC processor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) 	wrt_reg_word(&reg->hccr, HCCR_RESET_RISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) 	wrt_reg_word(&reg->hccr, HCCR_RELEASE_RISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) 	/* Workaround for QLA2312 PCI parity error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) 	if (IS_QLA2100(ha) || IS_QLA2200(ha) || IS_QLA2300(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) 		data = qla2x00_debounce_register(MAILBOX_REG(ha, reg, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) 		for (cnt = 6000000; cnt && (data == MBS_BUSY); cnt--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) 			udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) 			data = RD_MAILBOX_REG(ha, reg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) 			barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) 		udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) 	if (!cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) 		goto chip_diag_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) 	/* Check product ID of chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) 	ql_dbg(ql_dbg_init, vha, 0x007d, "Checking product ID of chip.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) 	mb[1] = RD_MAILBOX_REG(ha, reg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) 	mb[2] = RD_MAILBOX_REG(ha, reg, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) 	mb[3] = RD_MAILBOX_REG(ha, reg, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) 	mb[4] = qla2x00_debounce_register(MAILBOX_REG(ha, reg, 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) 	if (mb[1] != PROD_ID_1 || (mb[2] != PROD_ID_2 && mb[2] != PROD_ID_2a) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) 	    mb[3] != PROD_ID_3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) 		ql_log(ql_log_warn, vha, 0x0062,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) 		    "Wrong product ID = 0x%x,0x%x,0x%x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) 		    mb[1], mb[2], mb[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) 		goto chip_diag_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) 	ha->product_id[0] = mb[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) 	ha->product_id[1] = mb[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) 	ha->product_id[2] = mb[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) 	ha->product_id[3] = mb[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) 	/* Adjust fw RISC transfer size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) 	if (req->length > 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) 		ha->fw_transfer_size = REQUEST_ENTRY_SIZE * 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) 		ha->fw_transfer_size = REQUEST_ENTRY_SIZE *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) 		    req->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) 	if (IS_QLA2200(ha) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) 	    RD_MAILBOX_REG(ha, reg, 7) == QLA2200A_RISC_ROM_VER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) 		/* Limit firmware transfer size with a 2200A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) 		ql_dbg(ql_dbg_init, vha, 0x007e, "Found QLA2200A Chip.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) 		ha->device_type |= DT_ISP2200A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) 		ha->fw_transfer_size = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) 	/* Wrap Incoming Mailboxes Test. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) 	ql_dbg(ql_dbg_init, vha, 0x007f, "Checking mailboxes.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) 	rval = qla2x00_mbx_reg_test(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) 	if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) 		ql_log(ql_log_warn, vha, 0x0080,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) 		    "Failed mailbox send register test.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) 		/* Flag a successful rval */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) 		rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) 	spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) chip_diag_failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) 	if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) 		ql_log(ql_log_info, vha, 0x0081,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) 		    "Chip diagnostics **** FAILED ****.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193)  * qla24xx_chip_diag() - Test ISP24xx for proper operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) qla24xx_chip_diag(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) 	struct req_que *req = ha->req_q_map[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) 	if (IS_P3P_TYPE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) 		return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) 	ha->fw_transfer_size = REQUEST_ENTRY_SIZE * req->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) 	rval = qla2x00_mbx_reg_test(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) 	if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) 		ql_log(ql_log_warn, vha, 0x0082,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) 		    "Failed mailbox send register test.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) 		/* Flag a successful rval */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) 		rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) qla2x00_init_fce_trace(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) 	dma_addr_t tc_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) 	void *tc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) 	if (!IS_FWI2_CAPABLE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) 	if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) 	    !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) 	if (ha->fce) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) 		ql_dbg(ql_dbg_init, vha, 0x00bd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) 		       "%s: FCE Mem is already allocated.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) 		       __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) 	/* Allocate memory for Fibre Channel Event Buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) 	tc = dma_alloc_coherent(&ha->pdev->dev, FCE_SIZE, &tc_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) 				GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) 	if (!tc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) 		ql_log(ql_log_warn, vha, 0x00be,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) 		       "Unable to allocate (%d KB) for FCE.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) 		       FCE_SIZE / 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) 	rval = qla2x00_enable_fce_trace(vha, tc_dma, FCE_NUM_BUFFERS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) 					ha->fce_mb, &ha->fce_bufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) 	if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) 		ql_log(ql_log_warn, vha, 0x00bf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) 		       "Unable to initialize FCE (%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) 		dma_free_coherent(&ha->pdev->dev, FCE_SIZE, tc, tc_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) 	ql_dbg(ql_dbg_init, vha, 0x00c0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) 	       "Allocated (%d KB) for FCE...\n", FCE_SIZE / 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) 	ha->flags.fce_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) 	ha->fce_dma = tc_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) 	ha->fce = tc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) qla2x00_init_eft_trace(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) 	dma_addr_t tc_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) 	void *tc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) 	if (!IS_FWI2_CAPABLE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) 	if (ha->eft) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) 		ql_dbg(ql_dbg_init, vha, 0x00bd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) 		    "%s: EFT Mem is already allocated.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) 		    __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) 	/* Allocate memory for Extended Trace Buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) 	tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) 				GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) 	if (!tc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) 		ql_log(ql_log_warn, vha, 0x00c1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) 		       "Unable to allocate (%d KB) for EFT.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) 		       EFT_SIZE / 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) 		return;
^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) 	rval = qla2x00_enable_eft_trace(vha, tc_dma, EFT_NUM_BUFFERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) 	if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) 		ql_log(ql_log_warn, vha, 0x00c2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) 		       "Unable to initialize EFT (%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) 		dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc, tc_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) 	ql_dbg(ql_dbg_init, vha, 0x00c3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) 	       "Allocated (%d KB) EFT ...\n", EFT_SIZE / 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) 	ha->eft_dma = tc_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) 	ha->eft = tc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) qla2x00_alloc_offload_mem(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) 	qla2x00_init_fce_trace(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) 	qla2x00_init_eft_trace(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) 	uint32_t dump_size, fixed_size, mem_size, req_q_size, rsp_q_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) 	    eft_size, fce_size, mq_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) 	struct req_que *req = ha->req_q_map[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) 	struct rsp_que *rsp = ha->rsp_q_map[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) 	struct qla2xxx_fw_dump *fw_dump;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) 	if (ha->fw_dump) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) 		ql_dbg(ql_dbg_init, vha, 0x00bd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) 		    "Firmware dump already allocated.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) 	ha->fw_dumped = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) 	ha->fw_dump_cap_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) 	dump_size = fixed_size = mem_size = eft_size = fce_size = mq_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) 	req_q_size = rsp_q_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) 	if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) 		fixed_size = sizeof(struct qla2100_fw_dump);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) 	} else if (IS_QLA23XX(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) 		fixed_size = offsetof(struct qla2300_fw_dump, data_ram);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) 		mem_size = (ha->fw_memory_size - 0x11000 + 1) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) 		    sizeof(uint16_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) 	} else if (IS_FWI2_CAPABLE(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) 		if (IS_QLA83XX(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) 			fixed_size = offsetof(struct qla83xx_fw_dump, ext_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) 		else if (IS_QLA81XX(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) 			fixed_size = offsetof(struct qla81xx_fw_dump, ext_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) 		else if (IS_QLA25XX(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) 			fixed_size = offsetof(struct qla25xx_fw_dump, ext_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) 			fixed_size = offsetof(struct qla24xx_fw_dump, ext_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) 		mem_size = (ha->fw_memory_size - 0x100000 + 1) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) 		    sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) 		if (ha->mqenable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) 			if (!IS_QLA83XX(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) 				mq_size = sizeof(struct qla2xxx_mq_chain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) 			 * Allocate maximum buffer size for all queues - Q0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) 			 * Resizing must be done at end-of-dump processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) 			mq_size += (ha->max_req_queues - 1) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) 			    (req->length * sizeof(request_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) 			mq_size += (ha->max_rsp_queues - 1) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) 			    (rsp->length * sizeof(response_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) 		if (ha->tgt.atio_ring)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) 			mq_size += ha->tgt.atio_q_length * sizeof(request_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) 		qla2x00_init_fce_trace(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) 		if (ha->fce)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) 			fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) 		qla2x00_init_eft_trace(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) 		if (ha->eft)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) 			eft_size = EFT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) 	if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) 		struct fwdt *fwdt = ha->fwdt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) 		uint j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) 		for (j = 0; j < 2; j++, fwdt++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) 			if (!fwdt->template) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) 				ql_dbg(ql_dbg_init, vha, 0x00ba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) 				    "-> fwdt%u no template\n", j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) 			ql_dbg(ql_dbg_init, vha, 0x00fa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) 			    "-> fwdt%u calculating fwdump size...\n", j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) 			fwdt->dump_size = qla27xx_fwdt_calculate_dump_size(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) 			    vha, fwdt->template);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) 			ql_dbg(ql_dbg_init, vha, 0x00fa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) 			    "-> fwdt%u calculated fwdump size = %#lx bytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) 			    j, fwdt->dump_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) 			dump_size += fwdt->dump_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) 		/* Add space for spare MPI fw dump. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) 		dump_size += ha->fwdt[1].dump_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) 		req_q_size = req->length * sizeof(request_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) 		rsp_q_size = rsp->length * sizeof(response_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) 		dump_size = offsetof(struct qla2xxx_fw_dump, isp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) 		dump_size += fixed_size + mem_size + req_q_size + rsp_q_size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) 			+ eft_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) 		ha->chain_offset = dump_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) 		dump_size += mq_size + fce_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) 		if (ha->exchoffld_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) 			dump_size += sizeof(struct qla2xxx_offld_chain) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) 				ha->exchoffld_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) 		if (ha->exlogin_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) 			dump_size += sizeof(struct qla2xxx_offld_chain) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) 				ha->exlogin_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) 	if (!ha->fw_dump_len || dump_size > ha->fw_dump_alloc_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) 		ql_dbg(ql_dbg_init, vha, 0x00c5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) 		    "%s dump_size %d fw_dump_len %d fw_dump_alloc_len %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) 		    __func__, dump_size, ha->fw_dump_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) 		    ha->fw_dump_alloc_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) 		fw_dump = vmalloc(dump_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) 		if (!fw_dump) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) 			ql_log(ql_log_warn, vha, 0x00c4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) 			    "Unable to allocate (%d KB) for firmware dump.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) 			    dump_size / 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) 			mutex_lock(&ha->optrom_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) 			if (ha->fw_dumped) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) 				memcpy(fw_dump, ha->fw_dump, ha->fw_dump_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) 				vfree(ha->fw_dump);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) 				ha->fw_dump = fw_dump;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) 				ha->fw_dump_alloc_len =  dump_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) 				ql_dbg(ql_dbg_init, vha, 0x00c5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) 				    "Re-Allocated (%d KB) and save firmware dump.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) 				    dump_size / 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) 				if (ha->fw_dump)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) 					vfree(ha->fw_dump);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) 				ha->fw_dump = fw_dump;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) 				ha->fw_dump_len = ha->fw_dump_alloc_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) 				    dump_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) 				ql_dbg(ql_dbg_init, vha, 0x00c5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) 				    "Allocated (%d KB) for firmware dump.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) 				    dump_size / 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) 				if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) 					ha->mpi_fw_dump = (char *)fw_dump +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) 						ha->fwdt[1].dump_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) 					mutex_unlock(&ha->optrom_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) 					return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) 				ha->fw_dump->signature[0] = 'Q';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) 				ha->fw_dump->signature[1] = 'L';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) 				ha->fw_dump->signature[2] = 'G';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) 				ha->fw_dump->signature[3] = 'C';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) 				ha->fw_dump->version = htonl(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) 				ha->fw_dump->fixed_size = htonl(fixed_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) 				ha->fw_dump->mem_size = htonl(mem_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) 				ha->fw_dump->req_q_size = htonl(req_q_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) 				ha->fw_dump->rsp_q_size = htonl(rsp_q_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) 				ha->fw_dump->eft_size = htonl(eft_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) 				ha->fw_dump->eft_addr_l =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) 				    htonl(LSD(ha->eft_dma));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) 				ha->fw_dump->eft_addr_h =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) 				    htonl(MSD(ha->eft_dma));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) 				ha->fw_dump->header_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) 					htonl(offsetof
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) 					    (struct qla2xxx_fw_dump, isp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) 			mutex_unlock(&ha->optrom_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) qla81xx_mpi_sync(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) #define MPS_MASK	0xe0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) 	uint16_t dc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) 	uint32_t dw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) 	if (!IS_QLA81XX(vha->hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) 		return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) 	rval = qla2x00_write_ram_word(vha, 0x7c00, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) 		ql_log(ql_log_warn, vha, 0x0105,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) 		    "Unable to acquire semaphore.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) 	pci_read_config_word(vha->hw->pdev, 0x54, &dc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) 	rval = qla2x00_read_ram_word(vha, 0x7a15, &dw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) 		ql_log(ql_log_warn, vha, 0x0067, "Unable to read sync.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) 		goto done_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) 	dc &= MPS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) 	if (dc == (dw & MPS_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) 		goto done_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) 	dw &= ~MPS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) 	dw |= dc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) 	rval = qla2x00_write_ram_word(vha, 0x7a15, dw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) 		ql_log(ql_log_warn, vha, 0x0114, "Unable to gain sync.\n");
^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) done_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) 	rval = qla2x00_write_ram_word(vha, 0x7c00, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) 		ql_log(ql_log_warn, vha, 0x006d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) 		    "Unable to release semaphore.\n");
^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) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) qla2x00_alloc_outstanding_cmds(struct qla_hw_data *ha, struct req_que *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) 	/* Don't try to reallocate the array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) 	if (req->outstanding_cmds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) 		return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) 	if (!IS_FWI2_CAPABLE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) 		req->num_outstanding_cmds = DEFAULT_OUTSTANDING_COMMANDS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) 		if (ha->cur_fw_xcb_count <= ha->cur_fw_iocb_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) 			req->num_outstanding_cmds = ha->cur_fw_xcb_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) 			req->num_outstanding_cmds = ha->cur_fw_iocb_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) 	req->outstanding_cmds = kcalloc(req->num_outstanding_cmds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) 					sizeof(srb_t *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) 					GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) 	if (!req->outstanding_cmds) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) 		 * Try to allocate a minimal size just so we can get through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) 		 * initialization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) 		req->num_outstanding_cmds = MIN_OUTSTANDING_COMMANDS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) 		req->outstanding_cmds = kcalloc(req->num_outstanding_cmds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) 						sizeof(srb_t *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) 						GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) 		if (!req->outstanding_cmds) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) 			ql_log(ql_log_fatal, NULL, 0x0126,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) 			    "Failed to allocate memory for "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) 			    "outstanding_cmds for req_que %p.\n", req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) 			req->num_outstanding_cmds = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) 			return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) 	return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) #define PRINT_FIELD(_field, _flag, _str) {		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) 	if (a0->_field & _flag) {\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) 		if (p) {\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) 			strcat(ptr, "|");\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) 			ptr++;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) 			leftover--;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) 		} \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) 		len = snprintf(ptr, leftover, "%s", _str);	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) 		p = 1;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) 		leftover -= len;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) 		ptr += len; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) 	} \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) static void qla2xxx_print_sfp_info(struct scsi_qla_host *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) #define STR_LEN 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) 	struct sff_8247_a0 *a0 = (struct sff_8247_a0 *)vha->hw->sfp_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) 	u8 str[STR_LEN], *ptr, p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) 	int leftover, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) 	memset(str, 0, STR_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) 	snprintf(str, SFF_VEN_NAME_LEN+1, a0->vendor_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) 	ql_dbg(ql_dbg_init, vha, 0x015a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) 	    "SFP MFG Name: %s\n", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) 	memset(str, 0, STR_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) 	snprintf(str, SFF_PART_NAME_LEN+1, a0->vendor_pn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) 	ql_dbg(ql_dbg_init, vha, 0x015c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) 	    "SFP Part Name: %s\n", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) 	/* media */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) 	memset(str, 0, STR_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) 	ptr = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) 	leftover = STR_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) 	p = len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) 	PRINT_FIELD(fc_med_cc9, FC_MED_TW, "Twin AX");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) 	PRINT_FIELD(fc_med_cc9, FC_MED_TP, "Twisted Pair");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) 	PRINT_FIELD(fc_med_cc9, FC_MED_MI, "Min Coax");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) 	PRINT_FIELD(fc_med_cc9, FC_MED_TV, "Video Coax");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) 	PRINT_FIELD(fc_med_cc9, FC_MED_M6, "MultiMode 62.5um");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) 	PRINT_FIELD(fc_med_cc9, FC_MED_M5, "MultiMode 50um");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) 	PRINT_FIELD(fc_med_cc9, FC_MED_SM, "SingleMode");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) 	ql_dbg(ql_dbg_init, vha, 0x0160,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) 	    "SFP Media: %s\n", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) 	/* link length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) 	memset(str, 0, STR_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) 	ptr = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) 	leftover = STR_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) 	p = len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) 	PRINT_FIELD(fc_ll_cc7, FC_LL_VL, "Very Long");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) 	PRINT_FIELD(fc_ll_cc7, FC_LL_S, "Short");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) 	PRINT_FIELD(fc_ll_cc7, FC_LL_I, "Intermediate");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) 	PRINT_FIELD(fc_ll_cc7, FC_LL_L, "Long");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) 	PRINT_FIELD(fc_ll_cc7, FC_LL_M, "Medium");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) 	ql_dbg(ql_dbg_init, vha, 0x0196,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) 	    "SFP Link Length: %s\n", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) 	memset(str, 0, STR_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) 	ptr = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) 	leftover = STR_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) 	p = len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) 	PRINT_FIELD(fc_ll_cc7, FC_LL_SA, "Short Wave (SA)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) 	PRINT_FIELD(fc_ll_cc7, FC_LL_LC, "Long Wave(LC)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) 	PRINT_FIELD(fc_tec_cc8, FC_TEC_SN, "Short Wave (SN)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) 	PRINT_FIELD(fc_tec_cc8, FC_TEC_SL, "Short Wave (SL)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) 	PRINT_FIELD(fc_tec_cc8, FC_TEC_LL, "Long Wave (LL)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) 	ql_dbg(ql_dbg_init, vha, 0x016e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) 	    "SFP FC Link Tech: %s\n", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) 	if (a0->length_km)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) 		ql_dbg(ql_dbg_init, vha, 0x016f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) 		    "SFP Distant: %d km\n", a0->length_km);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) 	if (a0->length_100m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) 		ql_dbg(ql_dbg_init, vha, 0x0170,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) 		    "SFP Distant: %d m\n", a0->length_100m*100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) 	if (a0->length_50um_10m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) 		ql_dbg(ql_dbg_init, vha, 0x0189,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) 		    "SFP Distant (WL=50um): %d m\n", a0->length_50um_10m * 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) 	if (a0->length_62um_10m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) 		ql_dbg(ql_dbg_init, vha, 0x018a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) 		  "SFP Distant (WL=62.5um): %d m\n", a0->length_62um_10m * 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) 	if (a0->length_om4_10m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) 		ql_dbg(ql_dbg_init, vha, 0x0194,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) 		    "SFP Distant (OM4): %d m\n", a0->length_om4_10m * 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) 	if (a0->length_om3_10m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) 		ql_dbg(ql_dbg_init, vha, 0x0195,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) 		    "SFP Distant (OM3): %d m\n", a0->length_om3_10m * 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668)  * qla24xx_detect_sfp()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670)  * @vha: adapter state pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672)  * @return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673)  *	0 -- Configure firmware to use short-range settings -- normal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674)  *	     buffer-to-buffer credits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676)  *	1 -- Configure firmware to use long-range settings -- extra
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677)  *	     buffer-to-buffer credits should be allocated with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678)  *	     ha->lr_distance containing distance settings from NVRAM or SFP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679)  *	     (if supported).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) qla24xx_detect_sfp(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) 	int rc, used_nvram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) 	struct sff_8247_a0 *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) 	struct nvram_81xx *nv = ha->nvram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) #define LR_DISTANCE_UNKNOWN	2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) 	static const char * const types[] = { "Short", "Long" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) 	static const char * const lengths[] = { "(10km)", "(5km)", "" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) 	u8 ll = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) 	/* Seed with NVRAM settings. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) 	used_nvram = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) 	ha->flags.lr_detected = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) 	if (IS_BPM_RANGE_CAPABLE(ha) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) 	    (nv->enhanced_features & NEF_LR_DIST_ENABLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) 		used_nvram = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) 		ha->flags.lr_detected = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) 		ha->lr_distance =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) 		    (nv->enhanced_features >> LR_DIST_NV_POS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) 		     & LR_DIST_NV_MASK;
^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) 	if (!IS_BPM_ENABLED(vha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) 	/* Determine SR/LR capabilities of SFP/Transceiver. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) 	rc = qla2x00_read_sfp_dev(vha, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) 	used_nvram = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) 	a = (struct sff_8247_a0 *)vha->hw->sfp_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) 	qla2xxx_print_sfp_info(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) 	ha->flags.lr_detected = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) 	ll = a->fc_ll_cc7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) 	if (ll & FC_LL_VL || ll & FC_LL_L) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) 		/* Long range, track length. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) 		ha->flags.lr_detected = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) 		if (a->length_km > 5 || a->length_100m > 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) 			ha->lr_distance = LR_DISTANCE_10K;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) 			ha->lr_distance = LR_DISTANCE_5K;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) 	ql_dbg(ql_dbg_async, vha, 0x507b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) 	    "SFP detect: %s-Range SFP %s (nvr=%x ll=%x lr=%x lrd=%x).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) 	    types[ha->flags.lr_detected],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) 	    ha->flags.lr_detected ? lengths[ha->lr_distance] :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) 	       lengths[LR_DISTANCE_UNKNOWN],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) 	    used_nvram, ll, ha->flags.lr_detected, ha->lr_distance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) 	return ha->flags.lr_detected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) void qla_init_iocb_limit(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) 	u16 i, num_qps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) 	u32 limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) 	num_qps = ha->num_qpairs + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) 	limit = (ha->orig_fw_iocb_count * QLA_IOCB_PCT_LIMIT) / 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) 	ha->base_qpair->fwres.iocbs_total = ha->orig_fw_iocb_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) 	ha->base_qpair->fwres.iocbs_limit = limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) 	ha->base_qpair->fwres.iocbs_qp_limit = limit / num_qps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) 	ha->base_qpair->fwres.iocbs_used = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) 	for (i = 0; i < ha->max_qpairs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) 		if (ha->queue_pair_map[i])  {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) 			ha->queue_pair_map[i]->fwres.iocbs_total =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) 				ha->orig_fw_iocb_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) 			ha->queue_pair_map[i]->fwres.iocbs_limit = limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) 			ha->queue_pair_map[i]->fwres.iocbs_qp_limit =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) 				limit / num_qps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) 			ha->queue_pair_map[i]->fwres.iocbs_used = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764)  * qla2x00_setup_chip() - Load and start RISC firmware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) qla2x00_setup_chip(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) 	uint32_t srisc_address = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) 	uint16_t fw_major_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) 	int done_once = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) 	if (IS_P3P_TYPE(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) 		rval = ha->isp_ops->load_risc(vha, &srisc_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) 		if (rval == QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) 			qla2x00_stop_firmware(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) 			goto enable_82xx_npiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) 			goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) 	if (!IS_FWI2_CAPABLE(ha) && !IS_QLA2100(ha) && !IS_QLA2200(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) 		/* Disable SRAM, Instruction RAM and GP RAM parity.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) 		spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) 		wrt_reg_word(&reg->hccr, (HCCR_ENABLE_PARITY + 0x0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) 		rd_reg_word(&reg->hccr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
^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) 	qla81xx_mpi_sync(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) execute_fw_with_lr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) 	/* Load firmware sequences */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) 	rval = ha->isp_ops->load_risc(vha, &srisc_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) 	if (rval == QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) 		ql_dbg(ql_dbg_init, vha, 0x00c9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) 		    "Verifying Checksum of loaded RISC code.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) 		rval = qla2x00_verify_checksum(vha, srisc_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) 		if (rval == QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) 			/* Start firmware execution. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) 			ql_dbg(ql_dbg_init, vha, 0x00ca,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) 			    "Starting firmware.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) 			if (ql2xexlogins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) 				ha->flags.exlogins_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) 			if (qla_is_exch_offld_enabled(vha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) 				ha->flags.exchoffld_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) 			rval = qla2x00_execute_fw(vha, srisc_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) 			/* Retrieve firmware information. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) 			if (rval == QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) 				/* Enable BPM support? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) 				if (!done_once++ && qla24xx_detect_sfp(vha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) 					ql_dbg(ql_dbg_init, vha, 0x00ca,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) 					    "Re-starting firmware -- BPM.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) 					/* Best-effort - re-init. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) 					ha->isp_ops->reset_chip(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) 					ha->isp_ops->chip_diag(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) 					goto execute_fw_with_lr;
^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) 				if (IS_ZIO_THRESHOLD_CAPABLE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) 					qla27xx_set_zio_threshold(vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) 					    ha->last_zio_threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) 				rval = qla2x00_set_exlogins_buffer(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) 				if (rval != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) 					goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) 				rval = qla2x00_set_exchoffld_buffer(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) 				if (rval != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) 					goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) enable_82xx_npiv:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) 				fw_major_version = ha->fw_major_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) 				if (IS_P3P_TYPE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) 					qla82xx_check_md_needed(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) 					rval = qla2x00_get_fw_version(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) 				if (rval != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) 					goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) 				ha->flags.npiv_supported = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) 				if (IS_QLA2XXX_MIDTYPE(ha) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) 					 (ha->fw_attributes & BIT_2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) 					ha->flags.npiv_supported = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) 					if ((!ha->max_npiv_vports) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) 					    ((ha->max_npiv_vports + 1) %
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) 					    MIN_MULTI_ID_FABRIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) 						ha->max_npiv_vports =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) 						    MIN_MULTI_ID_FABRIC - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) 				qla2x00_get_resource_cnts(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) 				qla_init_iocb_limit(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) 				 * Allocate the array of outstanding commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) 				 * now that we know the firmware resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) 				rval = qla2x00_alloc_outstanding_cmds(ha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) 				    vha->req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) 				if (rval != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) 					goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) 				if (!fw_major_version && !(IS_P3P_TYPE(ha)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) 					qla2x00_alloc_offload_mem(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) 				if (ql2xallocfwdump && !(IS_P3P_TYPE(ha)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) 					qla2x00_alloc_fw_dump(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) 				goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) 			ql_log(ql_log_fatal, vha, 0x00cd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) 			    "ISP Firmware failed checksum.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) 			goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) 		/* Enable PUREX PASSTHRU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) 		if (ql2xrdpenable || ha->flags.scm_supported_f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) 			qla25xx_set_els_cmds_supported(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) 		goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) 	if (!IS_FWI2_CAPABLE(ha) && !IS_QLA2100(ha) && !IS_QLA2200(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) 		/* Enable proper parity. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) 		spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) 		if (IS_QLA2300(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) 			/* SRAM parity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) 			wrt_reg_word(&reg->hccr, HCCR_ENABLE_PARITY + 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) 			/* SRAM, Instruction RAM and GP RAM parity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) 			wrt_reg_word(&reg->hccr, HCCR_ENABLE_PARITY + 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) 		rd_reg_word(&reg->hccr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) 	if (IS_QLA27XX(ha) || IS_QLA28XX(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) 		ha->flags.fac_supported = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) 	else if (rval == QLA_SUCCESS && IS_FAC_REQUIRED(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) 		uint32_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) 		rval = qla81xx_fac_get_sector_size(vha, &size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) 		if (rval == QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) 			ha->flags.fac_supported = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) 			ha->fdt_block_size = size << 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) 			ql_log(ql_log_warn, vha, 0x00ce,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) 			    "Unsupported FAC firmware (%d.%02d.%02d).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) 			    ha->fw_major_version, ha->fw_minor_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) 			    ha->fw_subminor_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) 			if (IS_QLA83XX(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) 				ha->flags.fac_supported = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) 				rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) 	if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) 		ql_log(ql_log_fatal, vha, 0x00cf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) 		    "Setup chip ****FAILED****.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938)  * qla2x00_init_response_q_entries() - Initializes response queue entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939)  * @rsp: response queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941)  * Beginning of request ring has initialization control block already built
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942)  * by nvram config routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) qla2x00_init_response_q_entries(struct rsp_que *rsp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) 	uint16_t cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) 	response_t *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) 	rsp->ring_ptr = rsp->ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) 	rsp->ring_index    = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) 	rsp->status_srb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) 	pkt = rsp->ring_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) 	for (cnt = 0; cnt < rsp->length; cnt++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) 		pkt->signature = RESPONSE_PROCESSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) 		pkt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963)  * qla2x00_update_fw_options() - Read and process firmware options.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) qla2x00_update_fw_options(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) 	uint16_t swing, emphasis, tx_sens, rx_sens;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) 	memset(ha->fw_options, 0, sizeof(ha->fw_options));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) 	qla2x00_get_fw_options(vha, ha->fw_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) 	if (IS_QLA2100(ha) || IS_QLA2200(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) 	/* Serial Link options. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) 	ql_dbg(ql_dbg_init + ql_dbg_buffer, vha, 0x0115,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) 	    "Serial link options.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) 	ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x0109,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) 	    ha->fw_seriallink_options, sizeof(ha->fw_seriallink_options));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) 	ha->fw_options[1] &= ~FO1_SET_EMPHASIS_SWING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) 	if (ha->fw_seriallink_options[3] & BIT_2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) 		ha->fw_options[1] |= FO1_SET_EMPHASIS_SWING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) 		/*  1G settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) 		swing = ha->fw_seriallink_options[2] & (BIT_2 | BIT_1 | BIT_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) 		emphasis = (ha->fw_seriallink_options[2] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) 		    (BIT_4 | BIT_3)) >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) 		tx_sens = ha->fw_seriallink_options[0] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) 		    (BIT_3 | BIT_2 | BIT_1 | BIT_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) 		rx_sens = (ha->fw_seriallink_options[0] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) 		    (BIT_7 | BIT_6 | BIT_5 | BIT_4)) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) 		ha->fw_options[10] = (emphasis << 14) | (swing << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) 		if (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA6312(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) 			if (rx_sens == 0x0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) 				rx_sens = 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) 			ha->fw_options[10] |= (tx_sens << 4) | rx_sens;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) 		} else if (IS_QLA2322(ha) || IS_QLA6322(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) 			ha->fw_options[10] |= BIT_5 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) 			    ((rx_sens & (BIT_1 | BIT_0)) << 2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) 			    (tx_sens & (BIT_1 | BIT_0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) 		/*  2G settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) 		swing = (ha->fw_seriallink_options[2] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) 		    (BIT_7 | BIT_6 | BIT_5)) >> 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) 		emphasis = ha->fw_seriallink_options[3] & (BIT_1 | BIT_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) 		tx_sens = ha->fw_seriallink_options[1] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) 		    (BIT_3 | BIT_2 | BIT_1 | BIT_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) 		rx_sens = (ha->fw_seriallink_options[1] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) 		    (BIT_7 | BIT_6 | BIT_5 | BIT_4)) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) 		ha->fw_options[11] = (emphasis << 14) | (swing << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) 		if (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA6312(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) 			if (rx_sens == 0x0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) 				rx_sens = 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) 			ha->fw_options[11] |= (tx_sens << 4) | rx_sens;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) 		} else if (IS_QLA2322(ha) || IS_QLA6322(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) 			ha->fw_options[11] |= BIT_5 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) 			    ((rx_sens & (BIT_1 | BIT_0)) << 2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) 			    (tx_sens & (BIT_1 | BIT_0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) 	/* FCP2 options. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) 	/*  Return command IOCBs without waiting for an ABTS to complete. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) 	ha->fw_options[3] |= BIT_13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) 	/* LED scheme. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) 	if (ha->flags.enable_led_scheme)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) 		ha->fw_options[2] |= BIT_12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) 	/* Detect ISP6312. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) 	if (IS_QLA6312(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) 		ha->fw_options[2] |= BIT_13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) 	/* Set Retry FLOGI in case of P2P connection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) 	if (ha->operating_mode == P2P) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) 		ha->fw_options[2] |= BIT_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) 		ql_dbg(ql_dbg_disc, vha, 0x2100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) 		    "(%s): Setting FLOGI retry BIT in fw_options[2]: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) 			__func__, ha->fw_options[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) 	/* Update firmware options. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) 	qla2x00_set_fw_options(vha, ha->fw_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) qla24xx_update_fw_options(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) 	if (IS_P3P_TYPE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) 	/*  Hold status IOCBs until ABTS response received. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) 	if (ql2xfwholdabts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) 		ha->fw_options[3] |= BIT_12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) 	/* Set Retry FLOGI in case of P2P connection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) 	if (ha->operating_mode == P2P) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) 		ha->fw_options[2] |= BIT_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) 		ql_dbg(ql_dbg_disc, vha, 0x2101,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) 		    "(%s): Setting FLOGI retry BIT in fw_options[2]: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) 			__func__, ha->fw_options[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) 	/* Move PUREX, ABTS RX & RIDA to ATIOQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) 	if (ql2xmvasynctoatio &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) 	    (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) 		if (qla_tgt_mode_enabled(vha) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) 		    qla_dual_mode_enabled(vha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) 			ha->fw_options[2] |= BIT_11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) 			ha->fw_options[2] &= ~BIT_11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) 	if (IS_QLA25XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) 	    IS_QLA28XX(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) 		 * Tell FW to track each exchange to prevent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) 		 * driver from using stale exchange.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) 		if (qla_tgt_mode_enabled(vha) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) 		    qla_dual_mode_enabled(vha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) 			ha->fw_options[2] |= BIT_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) 			ha->fw_options[2] &= ~BIT_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) 		/* Reserve 1/2 of emergency exchanges for ELS.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) 		if (qla2xuseresexchforels)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) 			ha->fw_options[2] |= BIT_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) 			ha->fw_options[2] &= ~BIT_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) 	if (ql2xrdpenable || ha->flags.scm_supported_f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) 		ha->fw_options[1] |= ADD_FO1_ENABLE_PUREX_IOCB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) 	/* Enable Async 8130/8131 events -- transceiver insertion/removal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) 	if (IS_BPM_RANGE_CAPABLE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) 		ha->fw_options[3] |= BIT_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) 	ql_dbg(ql_dbg_init, vha, 0x00e8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) 	    "%s, add FW options 1-3 = 0x%04x 0x%04x 0x%04x mode %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) 	    __func__, ha->fw_options[1], ha->fw_options[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) 	    ha->fw_options[3], vha->host->active_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) 	if (ha->fw_options[1] || ha->fw_options[2] || ha->fw_options[3])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) 		qla2x00_set_fw_options(vha, ha->fw_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) 	/* Update Serial Link options. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) 	if ((le16_to_cpu(ha->fw_seriallink_options24[0]) & BIT_0) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) 	rval = qla2x00_set_serdes_params(vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) 	    le16_to_cpu(ha->fw_seriallink_options24[1]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) 	    le16_to_cpu(ha->fw_seriallink_options24[2]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) 	    le16_to_cpu(ha->fw_seriallink_options24[3]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) 		ql_log(ql_log_warn, vha, 0x0104,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) 		    "Unable to update Serial Link options (%x).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) qla2x00_config_rings(struct scsi_qla_host *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) 	struct req_que *req = ha->req_q_map[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) 	struct rsp_que *rsp = ha->rsp_q_map[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) 	/* Setup ring parameters in initialization control block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) 	ha->init_cb->request_q_outpointer = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) 	ha->init_cb->response_q_inpointer = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) 	ha->init_cb->request_q_length = cpu_to_le16(req->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) 	ha->init_cb->response_q_length = cpu_to_le16(rsp->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) 	put_unaligned_le64(req->dma, &ha->init_cb->request_q_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) 	put_unaligned_le64(rsp->dma, &ha->init_cb->response_q_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) 	wrt_reg_word(ISP_REQ_Q_IN(ha, reg), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) 	wrt_reg_word(ISP_REQ_Q_OUT(ha, reg), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) 	wrt_reg_word(ISP_RSP_Q_IN(ha, reg), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) 	wrt_reg_word(ISP_RSP_Q_OUT(ha, reg), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) 	rd_reg_word(ISP_RSP_Q_OUT(ha, reg));		/* PCI Posting. */
^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) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) qla24xx_config_rings(struct scsi_qla_host *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) 	device_reg_t *reg = ISP_QUE_REG(ha, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) 	struct device_reg_2xxx __iomem *ioreg = &ha->iobase->isp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) 	struct qla_msix_entry *msix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) 	struct init_cb_24xx *icb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) 	uint16_t rid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) 	struct req_que *req = ha->req_q_map[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) 	struct rsp_que *rsp = ha->rsp_q_map[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) 	/* Setup ring parameters in initialization control block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) 	icb = (struct init_cb_24xx *)ha->init_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) 	icb->request_q_outpointer = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) 	icb->response_q_inpointer = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) 	icb->request_q_length = cpu_to_le16(req->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) 	icb->response_q_length = cpu_to_le16(rsp->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) 	put_unaligned_le64(req->dma, &icb->request_q_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) 	put_unaligned_le64(rsp->dma, &icb->response_q_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) 	/* Setup ATIO queue dma pointers for target mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) 	icb->atio_q_inpointer = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) 	icb->atio_q_length = cpu_to_le16(ha->tgt.atio_q_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) 	put_unaligned_le64(ha->tgt.atio_dma, &icb->atio_q_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) 	if (IS_SHADOW_REG_CAPABLE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) 		icb->firmware_options_2 |= cpu_to_le32(BIT_30|BIT_29);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) 	if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) 	    IS_QLA28XX(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) 		icb->qos = cpu_to_le16(QLA_DEFAULT_QUE_QOS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) 		icb->rid = cpu_to_le16(rid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) 		if (ha->flags.msix_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) 			msix = &ha->msix_entries[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) 			ql_dbg(ql_dbg_init, vha, 0x0019,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) 			    "Registering vector 0x%x for base que.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) 			    msix->entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) 			icb->msix = cpu_to_le16(msix->entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) 		/* Use alternate PCI bus number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) 		if (MSB(rid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) 			icb->firmware_options_2 |= cpu_to_le32(BIT_19);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) 		/* Use alternate PCI devfn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) 		if (LSB(rid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) 			icb->firmware_options_2 |= cpu_to_le32(BIT_18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) 		/* Use Disable MSIX Handshake mode for capable adapters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) 		if ((ha->fw_attributes & BIT_6) && (IS_MSIX_NACK_CAPABLE(ha)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) 		    (ha->flags.msix_enabled)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) 			icb->firmware_options_2 &= cpu_to_le32(~BIT_22);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) 			ha->flags.disable_msix_handshake = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) 			ql_dbg(ql_dbg_init, vha, 0x00fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) 			    "MSIX Handshake Disable Mode turned on.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) 			icb->firmware_options_2 |= cpu_to_le32(BIT_22);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) 		icb->firmware_options_2 |= cpu_to_le32(BIT_23);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) 		wrt_reg_dword(&reg->isp25mq.req_q_in, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) 		wrt_reg_dword(&reg->isp25mq.req_q_out, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) 		wrt_reg_dword(&reg->isp25mq.rsp_q_in, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) 		wrt_reg_dword(&reg->isp25mq.rsp_q_out, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) 		wrt_reg_dword(&reg->isp24.req_q_in, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) 		wrt_reg_dword(&reg->isp24.req_q_out, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) 		wrt_reg_dword(&reg->isp24.rsp_q_in, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) 		wrt_reg_dword(&reg->isp24.rsp_q_out, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) 	qlt_24xx_config_rings(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) 	/* If the user has configured the speed, set it here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) 	if (ha->set_data_rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) 		ql_dbg(ql_dbg_init, vha, 0x00fd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) 		    "Speed set by user : %s Gbps \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) 		    qla2x00_get_link_speed_str(ha, ha->set_data_rate));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) 		icb->firmware_options_3 = cpu_to_le32(ha->set_data_rate << 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) 	/* PCI posting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) 	rd_reg_word(&ioreg->hccr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238)  * qla2x00_init_rings() - Initializes firmware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241)  * Beginning of request ring has initialization control block already built
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242)  * by nvram config routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) qla2x00_init_rings(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) 	int	rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) 	unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) 	int cnt, que;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) 	struct req_que *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) 	struct rsp_que *rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) 	struct mid_init_cb_24xx *mid_init_cb =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) 	    (struct mid_init_cb_24xx *) ha->init_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) 	spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) 	/* Clear outstanding commands array. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) 	for (que = 0; que < ha->max_req_queues; que++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) 		req = ha->req_q_map[que];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) 		if (!req || !test_bit(que, ha->req_qid_map))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) 		req->out_ptr = (uint16_t *)(req->ring + req->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) 		*req->out_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) 		for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) 			req->outstanding_cmds[cnt] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) 		req->current_outstanding_cmd = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) 		/* Initialize firmware. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) 		req->ring_ptr  = req->ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) 		req->ring_index    = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) 		req->cnt      = req->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) 	for (que = 0; que < ha->max_rsp_queues; que++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) 		rsp = ha->rsp_q_map[que];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) 		if (!rsp || !test_bit(que, ha->rsp_qid_map))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) 		rsp->in_ptr = (uint16_t *)(rsp->ring + rsp->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) 		*rsp->in_ptr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) 		/* Initialize response queue entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) 		if (IS_QLAFX00(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) 			qlafx00_init_response_q_entries(rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) 			qla2x00_init_response_q_entries(rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) 	ha->tgt.atio_ring_ptr = ha->tgt.atio_ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) 	ha->tgt.atio_ring_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) 	/* Initialize ATIO queue entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) 	qlt_init_atio_q_entries(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) 	ha->isp_ops->config_rings(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) 	ql_dbg(ql_dbg_init, vha, 0x00d1, "Issue init firmware.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) 	if (IS_QLAFX00(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) 		rval = qlafx00_init_firmware(vha, ha->init_cb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) 		goto next_check;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) 	/* Update any ISP specific firmware options before initialization. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) 	ha->isp_ops->update_fw_options(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) 	if (ha->flags.npiv_supported) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) 		if (ha->operating_mode == LOOP && !IS_CNA_CAPABLE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) 			ha->max_npiv_vports = MIN_MULTI_ID_FABRIC - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) 		mid_init_cb->count = cpu_to_le16(ha->max_npiv_vports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) 	if (IS_FWI2_CAPABLE(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) 		mid_init_cb->options = cpu_to_le16(BIT_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) 		mid_init_cb->init_cb.execution_throttle =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) 		    cpu_to_le16(ha->cur_fw_xcb_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) 		ha->flags.dport_enabled =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321) 			(le32_to_cpu(mid_init_cb->init_cb.firmware_options_1) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) 			 BIT_7) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) 		ql_dbg(ql_dbg_init, vha, 0x0191, "DPORT Support: %s.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) 		    (ha->flags.dport_enabled) ? "enabled" : "disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) 		/* FA-WWPN Status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) 		ha->flags.fawwpn_enabled =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) 			(le32_to_cpu(mid_init_cb->init_cb.firmware_options_1) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) 			 BIT_6) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) 		ql_dbg(ql_dbg_init, vha, 0x00bc, "FA-WWPN Support: %s.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) 		    (ha->flags.fawwpn_enabled) ? "enabled" : "disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) 	rval = qla2x00_init_firmware(vha, ha->init_cb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) next_check:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) 	if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) 		ql_log(ql_log_fatal, vha, 0x00d2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) 		    "Init Firmware **** FAILED ****.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339) 		ql_dbg(ql_dbg_init, vha, 0x00d3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) 		    "Init Firmware -- success.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) 		QLA_FW_STARTED(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) 		vha->u_ql2xexchoffld = vha->u_ql2xiniexchg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349)  * qla2x00_fw_ready() - Waits for firmware ready.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352)  * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) qla2x00_fw_ready(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) 	int		rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) 	unsigned long	wtime, mtime, cs84xx_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) 	uint16_t	min_wait;	/* Minimum wait time if loop is down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) 	uint16_t	wait_time;	/* Wait time if loop is coming ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) 	uint16_t	state[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) 	if (IS_QLAFX00(vha->hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) 		return qlafx00_fw_ready(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) 	rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) 	/* Time to wait for loop down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) 	if (IS_P3P_TYPE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) 		min_wait = 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) 		min_wait = 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) 	 * Firmware should take at most one RATOV to login, plus 5 seconds for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) 	 * our own processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) 	if ((wait_time = (ha->retry_count*ha->login_timeout) + 5) < min_wait) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) 		wait_time = min_wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) 	/* Min wait time if loop down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) 	mtime = jiffies + (min_wait * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) 	/* wait time before firmware ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) 	wtime = jiffies + (wait_time * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) 	/* Wait for ISP to finish LIP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) 	if (!vha->flags.init_done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) 		ql_log(ql_log_info, vha, 0x801e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) 		    "Waiting for LIP to complete.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) 		memset(state, -1, sizeof(state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) 		rval = qla2x00_get_firmware_state(vha, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) 		if (rval == QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) 			if (state[0] < FSTATE_LOSS_OF_SYNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) 				vha->device_flags &= ~DFLG_NO_CABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) 			if (IS_QLA84XX(ha) && state[0] != FSTATE_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) 				ql_dbg(ql_dbg_taskm, vha, 0x801f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) 				    "fw_state=%x 84xx=%x.\n", state[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) 				    state[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) 				if ((state[2] & FSTATE_LOGGED_IN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) 				     (state[2] & FSTATE_WAITING_FOR_VERIFY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) 					ql_dbg(ql_dbg_taskm, vha, 0x8028,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) 					    "Sending verify iocb.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) 					cs84xx_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) 					rval = qla84xx_init_chip(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) 					if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) 						ql_log(ql_log_warn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414) 						    vha, 0x8007,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) 						    "Init chip failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) 						break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) 					/* Add time taken to initialize. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) 					cs84xx_time = jiffies - cs84xx_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) 					wtime += cs84xx_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) 					mtime += cs84xx_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) 					ql_dbg(ql_dbg_taskm, vha, 0x8008,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) 					    "Increasing wait time by %ld. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) 					    "New time %ld.\n", cs84xx_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) 					    wtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) 			} else if (state[0] == FSTATE_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) 				ql_dbg(ql_dbg_taskm, vha, 0x8037,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) 				    "F/W Ready - OK.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) 				qla2x00_get_retry_cnt(vha, &ha->retry_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) 				    &ha->login_timeout, &ha->r_a_tov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) 				rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) 			rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) 			if (atomic_read(&vha->loop_down_timer) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) 			    state[0] != FSTATE_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) 				/* Loop down. Timeout on min_wait for states
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) 				 * other than Wait for Login.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) 				if (time_after_eq(jiffies, mtime)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) 					ql_log(ql_log_info, vha, 0x8038,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) 					    "Cable is unplugged...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) 					vha->device_flags |= DFLG_NO_CABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) 			/* Mailbox cmd failed. Timeout on min_wait. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) 			if (time_after_eq(jiffies, mtime) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) 				ha->flags.isp82xx_fw_hung)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) 		if (time_after_eq(jiffies, wtime))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) 		/* Delay for a while */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) 		msleep(500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) 	} while (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) 	ql_dbg(ql_dbg_taskm, vha, 0x803a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) 	    "fw_state=%x (%x, %x, %x, %x %x) curr time=%lx.\n", state[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) 	    state[1], state[2], state[3], state[4], state[5], jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) 	if (rval && !(vha->device_flags & DFLG_NO_CABLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) 		ql_log(ql_log_warn, vha, 0x803b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) 		    "Firmware ready **** FAILED ****.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) *  qla2x00_configure_hba
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) *      Setup adapter context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484) * Input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) *      ha = adapter state pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) *      0 = success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) * Context:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) *      Kernel context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494) qla2x00_configure_hba(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) 	int       rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) 	uint16_t      loop_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) 	uint16_t      topo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) 	uint16_t      sw_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) 	uint8_t       al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) 	uint8_t       area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) 	uint8_t       domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503) 	char		connect_type[22];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) 	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506) 	port_id_t id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) 	/* Get host addresses. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) 	rval = qla2x00_get_adapter_id(vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) 	    &loop_id, &al_pa, &area, &domain, &topo, &sw_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) 		if (LOOP_TRANSITION(vha) || atomic_read(&ha->loop_down_timer) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) 		    IS_CNA_CAPABLE(ha) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) 		    (rval == QLA_COMMAND_ERROR && loop_id == 0x7)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) 			ql_dbg(ql_dbg_disc, vha, 0x2008,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) 			    "Loop is in a transition state.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) 			ql_log(ql_log_warn, vha, 0x2009,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) 			    "Unable to get host loop ID.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) 			if (IS_FWI2_CAPABLE(ha) && (vha == base_vha) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) 			    (rval == QLA_COMMAND_ERROR && loop_id == 0x1b)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) 				ql_log(ql_log_warn, vha, 0x1151,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) 				    "Doing link init.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) 				if (qla24xx_link_initialize(vha) == QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) 					return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) 			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) 		return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) 	if (topo == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) 		ql_log(ql_log_info, vha, 0x200a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) 		    "Cannot get topology - retrying.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) 		return (QLA_FUNCTION_FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) 	vha->loop_id = loop_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) 	/* initialize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) 	ha->min_external_loopid = SNS_FIRST_LOOP_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) 	ha->operating_mode = LOOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) 	ha->switch_cap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) 	switch (topo) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) 		ql_dbg(ql_dbg_disc, vha, 0x200b, "HBA in NL topology.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) 		ha->current_topology = ISP_CFG_NL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) 		strcpy(connect_type, "(Loop)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) 		ql_dbg(ql_dbg_disc, vha, 0x200c, "HBA in FL topology.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) 		ha->switch_cap = sw_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) 		ha->current_topology = ISP_CFG_FL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) 		strcpy(connect_type, "(FL_Port)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) 	case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) 		ql_dbg(ql_dbg_disc, vha, 0x200d, "HBA in N P2P topology.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) 		ha->operating_mode = P2P;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) 		ha->current_topology = ISP_CFG_N;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) 		strcpy(connect_type, "(N_Port-to-N_Port)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) 	case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) 		ql_dbg(ql_dbg_disc, vha, 0x200e, "HBA in F P2P topology.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) 		ha->switch_cap = sw_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) 		ha->operating_mode = P2P;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) 		ha->current_topology = ISP_CFG_F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) 		strcpy(connect_type, "(F_Port)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) 		ql_dbg(ql_dbg_disc, vha, 0x200f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) 		    "HBA in unknown topology %x, using NL.\n", topo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) 		ha->current_topology = ISP_CFG_NL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) 		strcpy(connect_type, "(Loop)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) 	/* Save Host port and loop ID. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584) 	/* byte order - Big Endian */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) 	id.b.domain = domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) 	id.b.area = area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) 	id.b.al_pa = al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) 	id.b.rsvd_1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) 	spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) 	if (!(topo == 2 && ha->flags.n2n_bigger))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) 		qlt_update_host_map(vha, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) 	if (!vha->flags.init_done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) 		ql_log(ql_log_info, vha, 0x2010,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) 		    "Topology - %s, Host Loop address 0x%x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) 		    connect_type, vha->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) 	return(rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) qla2x00_set_model_info(scsi_qla_host_t *vha, uint8_t *model, size_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) 		       const char *def)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) 	char *st, *en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) 	uint16_t index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) 	uint64_t zero[2] = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610) 	int use_tbl = !IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611) 	    !IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) 	if (len > sizeof(zero))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614) 		len = sizeof(zero);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) 	if (memcmp(model, &zero, len) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616) 		memcpy(ha->model_number, model, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) 		st = en = ha->model_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) 		en += len - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619) 		while (en > st) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620) 			if (*en != 0x20 && *en != 0x00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622) 			*en-- = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) 		index = (ha->pdev->subsystem_device & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) 		if (use_tbl &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627) 		    ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) 		    index < QLA_MODEL_NAMES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629) 			strlcpy(ha->model_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) 			    qla2x00_model_name[index * 2 + 1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) 			    sizeof(ha->model_desc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) 		index = (ha->pdev->subsystem_device & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) 		if (use_tbl &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) 		    ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636) 		    index < QLA_MODEL_NAMES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) 			strlcpy(ha->model_number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) 				qla2x00_model_name[index * 2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639) 				sizeof(ha->model_number));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640) 			strlcpy(ha->model_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) 			    qla2x00_model_name[index * 2 + 1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) 			    sizeof(ha->model_desc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644) 			strlcpy(ha->model_number, def,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) 				sizeof(ha->model_number));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) 	if (IS_FWI2_CAPABLE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) 		qla2xxx_get_vpd_field(vha, "\x82", ha->model_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) 		    sizeof(ha->model_desc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) /* On sparc systems, obtain port and node WWN from firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654)  * properties.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) static void qla2xxx_nvram_wwn_from_ofw(scsi_qla_host_t *vha, nvram_t *nv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658) #ifdef CONFIG_SPARC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) 	struct pci_dev *pdev = ha->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) 	struct device_node *dp = pci_device_to_OF_node(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) 	const u8 *val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663) 	int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665) 	val = of_get_property(dp, "port-wwn", &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666) 	if (val && len >= WWN_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667) 		memcpy(nv->port_name, val, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669) 	val = of_get_property(dp, "node-wwn", &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670) 	if (val && len >= WWN_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671) 		memcpy(nv->node_name, val, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676) * NVRAM configuration for ISP 2xxx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678) * Input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679) *      ha                = adapter block pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681) * Output:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682) *      initialization control block in response_ring
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683) *      host adapters parameters in host adapter block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686) *      0 = success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689) qla2x00_nvram_config(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691) 	int             rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692) 	uint8_t         chksum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693) 	uint16_t        cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694) 	uint8_t         *dptr1, *dptr2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) 	init_cb_t       *icb = ha->init_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697) 	nvram_t         *nv = ha->nvram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698) 	uint8_t         *ptr = ha->nvram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699) 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701) 	rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703) 	/* Determine NVRAM starting address. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) 	ha->nvram_size = sizeof(*nv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705) 	ha->nvram_base = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706) 	if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA2300(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) 		if ((rd_reg_word(&reg->ctrl_status) >> 14) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708) 			ha->nvram_base = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710) 	/* Get NVRAM data and calculate checksum. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711) 	ha->isp_ops->read_nvram(vha, ptr, ha->nvram_base, ha->nvram_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712) 	for (cnt = 0, chksum = 0; cnt < ha->nvram_size; cnt++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713) 		chksum += *ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) 	ql_dbg(ql_dbg_init + ql_dbg_buffer, vha, 0x010f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) 	    "Contents of NVRAM.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717) 	ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x0110,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718) 	    nv, ha->nvram_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) 	/* Bad NVRAM data, set defaults parameters. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721) 	if (chksum || memcmp("ISP ", nv->id, sizeof(nv->id)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722) 	    nv->nvram_version < 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) 		/* Reset NVRAM data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) 		ql_log(ql_log_warn, vha, 0x0064,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725) 		    "Inconsistent NVRAM detected: checksum=%#x id=%.4s version=%#x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726) 		    chksum, nv->id, nv->nvram_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) 		ql_log(ql_log_warn, vha, 0x0065,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728) 		    "Falling back to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) 		    "functioning (yet invalid -- WWPN) defaults.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) 		 * Set default initialization control block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734) 		memset(nv, 0, ha->nvram_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735) 		nv->parameter_block_version = ICB_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737) 		if (IS_QLA23XX(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738) 			nv->firmware_options[0] = BIT_2 | BIT_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) 			nv->firmware_options[1] = BIT_7 | BIT_5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740) 			nv->add_firmware_options[0] = BIT_5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) 			nv->add_firmware_options[1] = BIT_5 | BIT_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) 			nv->frame_payload_size = cpu_to_le16(2048);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743) 			nv->special_options[1] = BIT_7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) 		} else if (IS_QLA2200(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745) 			nv->firmware_options[0] = BIT_2 | BIT_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746) 			nv->firmware_options[1] = BIT_7 | BIT_5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747) 			nv->add_firmware_options[0] = BIT_5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) 			nv->add_firmware_options[1] = BIT_5 | BIT_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) 			nv->frame_payload_size = cpu_to_le16(1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750) 		} else if (IS_QLA2100(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751) 			nv->firmware_options[0] = BIT_3 | BIT_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) 			nv->firmware_options[1] = BIT_5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753) 			nv->frame_payload_size = cpu_to_le16(1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) 		nv->max_iocb_allocation = cpu_to_le16(256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757) 		nv->execution_throttle = cpu_to_le16(16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) 		nv->retry_count = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) 		nv->retry_delay = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761) 		nv->port_name[0] = 33;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762) 		nv->port_name[3] = 224;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763) 		nv->port_name[4] = 139;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765) 		qla2xxx_nvram_wwn_from_ofw(vha, nv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767) 		nv->login_timeout = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770) 		 * Set default host adapter parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772) 		nv->host_p[1] = BIT_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773) 		nv->reset_delay = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774) 		nv->port_down_retry_count = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775) 		nv->max_luns_per_target = cpu_to_le16(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776) 		nv->link_down_timeout = 60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778) 		rval = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) 	/* Reset Initialization control block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) 	memset(icb, 0, ha->init_cb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785) 	 * Setup driver NVRAM options.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787) 	nv->firmware_options[0] |= (BIT_6 | BIT_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788) 	nv->firmware_options[0] &= ~(BIT_5 | BIT_4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789) 	nv->firmware_options[1] |= (BIT_5 | BIT_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790) 	nv->firmware_options[1] &= ~BIT_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792) 	if (IS_QLA23XX(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793) 		nv->firmware_options[0] |= BIT_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794) 		nv->firmware_options[0] &= ~BIT_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795) 		nv->special_options[0] &= ~BIT_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796) 		nv->add_firmware_options[1] |= BIT_5 | BIT_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798) 		if (IS_QLA2300(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) 			if (ha->fb_rev == FPM_2310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800) 				strcpy(ha->model_number, "QLA2310");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802) 				strcpy(ha->model_number, "QLA2300");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) 			qla2x00_set_model_info(vha, nv->model_number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806) 			    sizeof(nv->model_number), "QLA23xx");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808) 	} else if (IS_QLA2200(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) 		nv->firmware_options[0] |= BIT_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) 		 * 'Point-to-point preferred, else loop' is not a safe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812) 		 * connection mode setting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814) 		if ((nv->add_firmware_options[0] & (BIT_6 | BIT_5 | BIT_4)) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815) 		    (BIT_5 | BIT_4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816) 			/* Force 'loop preferred, else point-to-point'. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817) 			nv->add_firmware_options[0] &= ~(BIT_6 | BIT_5 | BIT_4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818) 			nv->add_firmware_options[0] |= BIT_5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820) 		strcpy(ha->model_number, "QLA22xx");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821) 	} else /*if (IS_QLA2100(ha))*/ {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822) 		strcpy(ha->model_number, "QLA2100");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) 	 * Copy over NVRAM RISC parameter block to initialization control block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828) 	dptr1 = (uint8_t *)icb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829) 	dptr2 = (uint8_t *)&nv->parameter_block_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830) 	cnt = (uint8_t *)&icb->request_q_outpointer - (uint8_t *)&icb->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) 	while (cnt--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832) 		*dptr1++ = *dptr2++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834) 	/* Copy 2nd half. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835) 	dptr1 = (uint8_t *)icb->add_firmware_options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836) 	cnt = (uint8_t *)icb->reserved_3 - (uint8_t *)icb->add_firmware_options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837) 	while (cnt--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) 		*dptr1++ = *dptr2++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) 	ha->frame_payload_size = le16_to_cpu(icb->frame_payload_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840) 	/* Use alternate WWN? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) 	if (nv->host_p[1] & BIT_7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842) 		memcpy(icb->node_name, nv->alternate_node_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843) 		memcpy(icb->port_name, nv->alternate_port_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846) 	/* Prepare nodename */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) 	if ((icb->firmware_options[1] & BIT_6) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849) 		 * Firmware will apply the following mask if the nodename was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850) 		 * not provided.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852) 		memcpy(icb->node_name, icb->port_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853) 		icb->node_name[0] &= 0xF0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857) 	 * Set host adapter parameters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) 	 * BIT_7 in the host-parameters section allows for modification to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862) 	 * internal driver logging.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864) 	if (nv->host_p[0] & BIT_7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) 		ql2xextended_error_logging = QL_DBG_DEFAULT1_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866) 	ha->flags.disable_risc_code_load = ((nv->host_p[0] & BIT_4) ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867) 	/* Always load RISC code on non ISP2[12]00 chips. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868) 	if (!IS_QLA2100(ha) && !IS_QLA2200(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) 		ha->flags.disable_risc_code_load = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870) 	ha->flags.enable_lip_reset = ((nv->host_p[1] & BIT_1) ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871) 	ha->flags.enable_lip_full_login = ((nv->host_p[1] & BIT_2) ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872) 	ha->flags.enable_target_reset = ((nv->host_p[1] & BIT_3) ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873) 	ha->flags.enable_led_scheme = (nv->special_options[1] & BIT_4) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874) 	ha->flags.disable_serdes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876) 	ha->operating_mode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877) 	    (icb->add_firmware_options[0] & (BIT_6 | BIT_5 | BIT_4)) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879) 	memcpy(ha->fw_seriallink_options, nv->seriallink_options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) 	    sizeof(ha->fw_seriallink_options));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882) 	/* save HBA serial number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883) 	ha->serial0 = icb->port_name[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884) 	ha->serial1 = icb->port_name[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885) 	ha->serial2 = icb->port_name[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886) 	memcpy(vha->node_name, icb->node_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) 	memcpy(vha->port_name, icb->port_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889) 	icb->execution_throttle = cpu_to_le16(0xFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891) 	ha->retry_count = nv->retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893) 	/* Set minimum login_timeout to 4 seconds. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894) 	if (nv->login_timeout != ql2xlogintimeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895) 		nv->login_timeout = ql2xlogintimeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896) 	if (nv->login_timeout < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) 		nv->login_timeout = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898) 	ha->login_timeout = nv->login_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900) 	/* Set minimum RATOV to 100 tenths of a second. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901) 	ha->r_a_tov = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903) 	ha->loop_reset_delay = nv->reset_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905) 	/* Link Down Timeout = 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907) 	 * 	When Port Down timer expires we will start returning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908) 	 *	I/O's to OS with "DID_NO_CONNECT".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910) 	 * Link Down Timeout != 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912) 	 *	 The driver waits for the link to come up after link down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) 	 *	 before returning I/Os to OS with "DID_NO_CONNECT".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915) 	if (nv->link_down_timeout == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916) 		ha->loop_down_abort_time =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917) 		    (LOOP_DOWN_TIME - LOOP_DOWN_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919) 		ha->link_down_timeout =	 nv->link_down_timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920) 		ha->loop_down_abort_time =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921) 		    (LOOP_DOWN_TIME - ha->link_down_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4924) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4925) 	 * Need enough time to try and get the port back.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4926) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4927) 	ha->port_down_retry_count = nv->port_down_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4928) 	if (qlport_down_retry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4929) 		ha->port_down_retry_count = qlport_down_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4930) 	/* Set login_retry_count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4931) 	ha->login_retry_count  = nv->retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4932) 	if (ha->port_down_retry_count == nv->port_down_retry_count &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4933) 	    ha->port_down_retry_count > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4934) 		ha->login_retry_count = ha->port_down_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4935) 	else if (ha->port_down_retry_count > (int)ha->login_retry_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4936) 		ha->login_retry_count = ha->port_down_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4937) 	if (ql2xloginretrycount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4938) 		ha->login_retry_count = ql2xloginretrycount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4940) 	icb->lun_enables = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4941) 	icb->command_resource_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4942) 	icb->immediate_notify_resource_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4943) 	icb->timeout = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4945) 	if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4946) 		/* Enable RIO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4947) 		icb->firmware_options[0] &= ~BIT_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4948) 		icb->add_firmware_options[0] &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4949) 		    ~(BIT_3 | BIT_2 | BIT_1 | BIT_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4950) 		icb->add_firmware_options[0] |= BIT_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4951) 		icb->response_accumulation_timer = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4952) 		icb->interrupt_delay_timer = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4954) 		vha->flags.process_response_queue = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4955) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4956) 		/* Enable ZIO. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4957) 		if (!vha->flags.init_done) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4958) 			ha->zio_mode = icb->add_firmware_options[0] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4959) 			    (BIT_3 | BIT_2 | BIT_1 | BIT_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4960) 			ha->zio_timer = icb->interrupt_delay_timer ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4961) 			    icb->interrupt_delay_timer : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4962) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4963) 		icb->add_firmware_options[0] &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4964) 		    ~(BIT_3 | BIT_2 | BIT_1 | BIT_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4965) 		vha->flags.process_response_queue = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4966) 		if (ha->zio_mode != QLA_ZIO_DISABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4967) 			ha->zio_mode = QLA_ZIO_MODE_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4969) 			ql_log(ql_log_info, vha, 0x0068,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4970) 			    "ZIO mode %d enabled; timer delay (%d us).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4971) 			    ha->zio_mode, ha->zio_timer * 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4973) 			icb->add_firmware_options[0] |= (uint8_t)ha->zio_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4974) 			icb->interrupt_delay_timer = (uint8_t)ha->zio_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4975) 			vha->flags.process_response_queue = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4976) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4977) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4979) 	if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4980) 		ql_log(ql_log_warn, vha, 0x0069,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4981) 		    "NVRAM configuration failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4982) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4983) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4986) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4987) qla2x00_rport_del(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4988) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4989) 	fc_port_t *fcport = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4990) 	struct fc_rport *rport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4991) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4993) 	spin_lock_irqsave(fcport->vha->host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4994) 	rport = fcport->drport ? fcport->drport : fcport->rport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4995) 	fcport->drport = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4996) 	spin_unlock_irqrestore(fcport->vha->host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4997) 	if (rport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4998) 		ql_dbg(ql_dbg_disc, fcport->vha, 0x210b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4999) 		    "%s %8phN. rport %p roles %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5000) 		    __func__, fcport->port_name, rport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5001) 		    rport->roles);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5003) 		fc_remote_port_delete(rport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5004) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5007) void qla2x00_set_fcport_state(fc_port_t *fcport, int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5008) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5009) 	int old_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5011) 	old_state = atomic_read(&fcport->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5012) 	atomic_set(&fcport->state, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5014) 	/* Don't print state transitions during initial allocation of fcport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5015) 	if (old_state && old_state != state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5016) 		ql_dbg(ql_dbg_disc, fcport->vha, 0x207d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5017) 		       "FCPort %8phC state transitioned from %s to %s - portid=%02x%02x%02x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5018) 		       fcport->port_name, port_state_str[old_state],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5019) 		       port_state_str[state], fcport->d_id.b.domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5020) 		       fcport->d_id.b.area, fcport->d_id.b.al_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5021) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5024) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5025)  * qla2x00_alloc_fcport() - Allocate a generic fcport.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5026)  * @vha: HA context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5027)  * @flags: allocation flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5028)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5029)  * Returns a pointer to the allocated fcport, or NULL, if none available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5030)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5031) fc_port_t *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5032) qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5034) 	fc_port_t *fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5036) 	fcport = kzalloc(sizeof(fc_port_t), flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5037) 	if (!fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5038) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5040) 	fcport->ct_desc.ct_sns = dma_alloc_coherent(&vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5041) 		sizeof(struct ct_sns_pkt), &fcport->ct_desc.ct_sns_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5042) 		flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5043) 	if (!fcport->ct_desc.ct_sns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5044) 		ql_log(ql_log_warn, vha, 0xd049,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5045) 		    "Failed to allocate ct_sns request.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5046) 		kfree(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5047) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5048) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5050) 	/* Setup fcport template structure. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5051) 	fcport->vha = vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5052) 	fcport->port_type = FCT_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5053) 	fcport->loop_id = FC_NO_LOOP_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5054) 	qla2x00_set_fcport_state(fcport, FCS_UNCONFIGURED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5055) 	fcport->supported_classes = FC_COS_UNSPECIFIED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5056) 	fcport->fp_speed = PORT_SPEED_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5058) 	fcport->disc_state = DSC_DELETED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5059) 	fcport->fw_login_state = DSC_LS_PORT_UNAVAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5060) 	fcport->deleted = QLA_SESS_DELETED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5061) 	fcport->login_retry = vha->hw->login_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5062) 	fcport->chip_reset = vha->hw->base_qpair->chip_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5063) 	fcport->logout_on_delete = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5065) 	if (!fcport->ct_desc.ct_sns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5066) 		ql_log(ql_log_warn, vha, 0xd049,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5067) 		    "Failed to allocate ct_sns request.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5068) 		kfree(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5069) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5070) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5072) 	INIT_WORK(&fcport->del_work, qla24xx_delete_sess_fn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5073) 	INIT_WORK(&fcport->free_work, qlt_free_session_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5074) 	INIT_WORK(&fcport->reg_work, qla_register_fcport_fn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5075) 	INIT_LIST_HEAD(&fcport->gnl_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5076) 	INIT_LIST_HEAD(&fcport->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5078) 	return fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5081) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5082) qla2x00_free_fcport(fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5083) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5084) 	if (fcport->ct_desc.ct_sns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5085) 		dma_free_coherent(&fcport->vha->hw->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5086) 			sizeof(struct ct_sns_pkt), fcport->ct_desc.ct_sns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5087) 			fcport->ct_desc.ct_sns_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5089) 		fcport->ct_desc.ct_sns = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5090) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5091) 	list_del(&fcport->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5092) 	qla2x00_clear_loop_id(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5093) 	kfree(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5096) static void qla_get_login_template(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5097) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5098) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5099) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5100) 	u32 *bp, sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5101) 	__be32 *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5103) 	memset(ha->init_cb, 0, ha->init_cb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5104) 	sz = min_t(int, sizeof(struct fc_els_flogi), ha->init_cb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5105) 	rval = qla24xx_get_port_login_templ(vha, ha->init_cb_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5106) 					    ha->init_cb, sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5107) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5108) 		ql_dbg(ql_dbg_init, vha, 0x00d1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5109) 		       "PLOGI ELS param read fail.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5110) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5111) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5112) 	q = (__be32 *)&ha->plogi_els_payld.fl_csp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5114) 	bp = (uint32_t *)ha->init_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5115) 	cpu_to_be32_array(q, bp, sz / 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5116) 	ha->flags.plogi_template_valid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5119) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5120)  * qla2x00_configure_loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5121)  *      Updates Fibre Channel Device Database with what is actually on loop.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5122)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5123)  * Input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5124)  *      ha                = adapter block pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5125)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5126)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5127)  *      0 = success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5128)  *      1 = error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5129)  *      2 = database was full and device was not configured.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5130)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5131) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5132) qla2x00_configure_loop(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5134) 	int  rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5135) 	unsigned long flags, save_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5136) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5138) 	rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5140) 	/* Get Initiator ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5141) 	if (test_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5142) 		rval = qla2x00_configure_hba(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5143) 		if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5144) 			ql_dbg(ql_dbg_disc, vha, 0x2013,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5145) 			    "Unable to configure HBA.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5146) 			return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5147) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5148) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5150) 	save_flags = flags = vha->dpc_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5151) 	ql_dbg(ql_dbg_disc, vha, 0x2014,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5152) 	    "Configure loop -- dpc flags = 0x%lx.\n", flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5154) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5155) 	 * If we have both an RSCN and PORT UPDATE pending then handle them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5156) 	 * both at the same time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5157) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5158) 	clear_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5159) 	clear_bit(RSCN_UPDATE, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5161) 	qla2x00_get_data_rate(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5162) 	qla_get_login_template(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5164) 	/* Determine what we need to do */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5165) 	if ((ha->current_topology == ISP_CFG_FL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5166) 	    ha->current_topology == ISP_CFG_F) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5167) 	    (test_bit(LOCAL_LOOP_UPDATE, &flags))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5169) 		set_bit(RSCN_UPDATE, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5170) 		clear_bit(LOCAL_LOOP_UPDATE, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5172) 	} else if (ha->current_topology == ISP_CFG_NL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5173) 		   ha->current_topology == ISP_CFG_N) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5174) 		clear_bit(RSCN_UPDATE, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5175) 		set_bit(LOCAL_LOOP_UPDATE, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5176) 	} else if (!vha->flags.online ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5177) 	    (test_bit(ABORT_ISP_ACTIVE, &flags))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5178) 		set_bit(RSCN_UPDATE, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5179) 		set_bit(LOCAL_LOOP_UPDATE, &flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5180) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5182) 	if (test_bit(LOCAL_LOOP_UPDATE, &flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5183) 		if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5184) 			ql_dbg(ql_dbg_disc, vha, 0x2015,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5185) 			    "Loop resync needed, failing.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5186) 			rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5187) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5188) 			rval = qla2x00_configure_local_loop(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5189) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5191) 	if (rval == QLA_SUCCESS && test_bit(RSCN_UPDATE, &flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5192) 		if (LOOP_TRANSITION(vha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5193) 			ql_dbg(ql_dbg_disc, vha, 0x2099,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5194) 			    "Needs RSCN update and loop transition.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5195) 			rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5196) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5197) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5198) 			rval = qla2x00_configure_fabric(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5199) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5201) 	if (rval == QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5202) 		if (atomic_read(&vha->loop_down_timer) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5203) 		    test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5204) 			rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5205) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5206) 			atomic_set(&vha->loop_state, LOOP_READY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5207) 			ql_dbg(ql_dbg_disc, vha, 0x2069,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5208) 			    "LOOP READY.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5209) 			ha->flags.fw_init_done = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5211) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5212) 			 * Process any ATIO queue entries that came in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5213) 			 * while we weren't online.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5214) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5215) 			if (qla_tgt_mode_enabled(vha) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5216) 			    qla_dual_mode_enabled(vha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5217) 				spin_lock_irqsave(&ha->tgt.atio_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5218) 				qlt_24xx_process_atio_queue(vha, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5219) 				spin_unlock_irqrestore(&ha->tgt.atio_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5220) 				    flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5221) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5222) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5223) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5225) 	if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5226) 		ql_dbg(ql_dbg_disc, vha, 0x206a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5227) 		    "%s *** FAILED ***.\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5228) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5229) 		ql_dbg(ql_dbg_disc, vha, 0x206b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5230) 		    "%s: exiting normally.\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5231) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5233) 	/* Restore state if a resync event occurred during processing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5234) 	if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5235) 		if (test_bit(LOCAL_LOOP_UPDATE, &save_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5236) 			set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5237) 		if (test_bit(RSCN_UPDATE, &save_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5238) 			set_bit(RSCN_UPDATE, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5239) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5240) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5242) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5245) static int qla2x00_configure_n2n_loop(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5247) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5248) 	fc_port_t *fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5250) 	if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5251) 		set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5253) 	list_for_each_entry(fcport, &vha->vp_fcports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5254) 		if (fcport->n2n_flag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5255) 			qla24xx_fcport_handle_login(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5256) 			return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5257) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5258) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5260) 	spin_lock_irqsave(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5261) 	vha->scan.scan_retry++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5262) 	spin_unlock_irqrestore(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5264) 	if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5265) 		set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5266) 		set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5267) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5268) 	return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5271) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5272)  * qla2x00_configure_local_loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5273)  *	Updates Fibre Channel Device Database with local loop devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5274)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5275)  * Input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5276)  *	ha = adapter block pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5277)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5278)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5279)  *	0 = success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5280)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5281) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5282) qla2x00_configure_local_loop(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5284) 	int		rval, rval2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5285) 	int		found_devs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5286) 	int		found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5287) 	fc_port_t	*fcport, *new_fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5288) 	uint16_t	index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5289) 	uint16_t	entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5290) 	struct gid_list_info *gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5291) 	uint16_t	loop_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5292) 	uint8_t		domain, area, al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5293) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5294) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5296) 	/* Inititae N2N login. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5297) 	if (N2N_TOPO(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5298) 		return qla2x00_configure_n2n_loop(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5300) 	found_devs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5301) 	new_fcport = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5302) 	entries = MAX_FIBRE_DEVICES_LOOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5304) 	/* Get list of logged in devices. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5305) 	memset(ha->gid_list, 0, qla2x00_gid_list_size(ha));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5306) 	rval = qla2x00_get_id_list(vha, ha->gid_list, ha->gid_list_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5307) 	    &entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5308) 	if (rval != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5309) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5311) 	ql_dbg(ql_dbg_disc, vha, 0x2011,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5312) 	    "Entries in ID list (%d).\n", entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5313) 	ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2075,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5314) 	    ha->gid_list, entries * sizeof(*ha->gid_list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5316) 	if (entries == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5317) 		spin_lock_irqsave(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5318) 		vha->scan.scan_retry++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5319) 		spin_unlock_irqrestore(&vha->work_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5321) 		if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5322) 			set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5323) 			set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5324) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5325) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5326) 		vha->scan.scan_retry = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5327) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5329) 	list_for_each_entry(fcport, &vha->vp_fcports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5330) 		fcport->scan_state = QLA_FCPORT_SCAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5331) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5333) 	/* Allocate temporary fcport for any new fcports discovered. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5334) 	new_fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5335) 	if (new_fcport == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5336) 		ql_log(ql_log_warn, vha, 0x2012,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5337) 		    "Memory allocation failed for fcport.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5338) 		rval = QLA_MEMORY_ALLOC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5339) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5340) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5341) 	new_fcport->flags &= ~FCF_FABRIC_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5343) 	/* Add devices to port list. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5344) 	gid = ha->gid_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5345) 	for (index = 0; index < entries; index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5346) 		domain = gid->domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5347) 		area = gid->area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5348) 		al_pa = gid->al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5349) 		if (IS_QLA2100(ha) || IS_QLA2200(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5350) 			loop_id = gid->loop_id_2100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5351) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5352) 			loop_id = le16_to_cpu(gid->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5353) 		gid = (void *)gid + ha->gid_list_info_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5355) 		/* Bypass reserved domain fields. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5356) 		if ((domain & 0xf0) == 0xf0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5357) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5359) 		/* Bypass if not same domain and area of adapter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5360) 		if (area && domain && ((area != vha->d_id.b.area) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5361) 		    (domain != vha->d_id.b.domain)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5362) 		    (ha->current_topology == ISP_CFG_NL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5363) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5366) 		/* Bypass invalid local loop ID. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5367) 		if (loop_id > LAST_LOCAL_LOOP_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5368) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5370) 		memset(new_fcport->port_name, 0, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5372) 		/* Fill in member data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5373) 		new_fcport->d_id.b.domain = domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5374) 		new_fcport->d_id.b.area = area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5375) 		new_fcport->d_id.b.al_pa = al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5376) 		new_fcport->loop_id = loop_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5377) 		new_fcport->scan_state = QLA_FCPORT_FOUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5379) 		rval2 = qla2x00_get_port_database(vha, new_fcport, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5380) 		if (rval2 != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5381) 			ql_dbg(ql_dbg_disc, vha, 0x2097,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5382) 			    "Failed to retrieve fcport information "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5383) 			    "-- get_port_database=%x, loop_id=0x%04x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5384) 			    rval2, new_fcport->loop_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5385) 			/* Skip retry if N2N */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5386) 			if (ha->current_topology != ISP_CFG_N) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5387) 				ql_dbg(ql_dbg_disc, vha, 0x2105,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5388) 				    "Scheduling resync.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5389) 				set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5390) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5391) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5392) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5394) 		spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5395) 		/* Check for matching device in port list. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5396) 		found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5397) 		fcport = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5398) 		list_for_each_entry(fcport, &vha->vp_fcports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5399) 			if (memcmp(new_fcport->port_name, fcport->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5400) 			    WWN_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5401) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5403) 			fcport->flags &= ~FCF_FABRIC_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5404) 			fcport->loop_id = new_fcport->loop_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5405) 			fcport->port_type = new_fcport->port_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5406) 			fcport->d_id.b24 = new_fcport->d_id.b24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5407) 			memcpy(fcport->node_name, new_fcport->node_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5408) 			    WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5409) 			fcport->scan_state = QLA_FCPORT_FOUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5410) 			if (fcport->login_retry == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5411) 				fcport->login_retry = vha->hw->login_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5412) 				ql_dbg(ql_dbg_disc, vha, 0x2135,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5413) 				    "Port login retry %8phN, lid 0x%04x retry cnt=%d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5414) 				    fcport->port_name, fcport->loop_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5415) 				    fcport->login_retry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5416) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5417) 			found++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5418) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5419) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5421) 		if (!found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5422) 			/* New device, add to fcports list. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5423) 			list_add_tail(&new_fcport->list, &vha->vp_fcports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5425) 			/* Allocate a new replacement fcport. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5426) 			fcport = new_fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5428) 			spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5430) 			new_fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5432) 			if (new_fcport == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5433) 				ql_log(ql_log_warn, vha, 0xd031,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5434) 				    "Failed to allocate memory for fcport.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5435) 				rval = QLA_MEMORY_ALLOC_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5436) 				goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5437) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5438) 			spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5439) 			new_fcport->flags &= ~FCF_FABRIC_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5440) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5442) 		spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5444) 		/* Base iIDMA settings on HBA port speed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5445) 		fcport->fp_speed = ha->link_data_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5447) 		found_devs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5448) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5450) 	list_for_each_entry(fcport, &vha->vp_fcports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5451) 		if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5452) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5454) 		if (fcport->scan_state == QLA_FCPORT_SCAN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5455) 			if ((qla_dual_mode_enabled(vha) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5456) 			    qla_ini_mode_enabled(vha)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5457) 			    atomic_read(&fcport->state) == FCS_ONLINE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5458) 				qla2x00_mark_device_lost(vha, fcport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5459) 					ql2xplogiabsentdevice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5460) 				if (fcport->loop_id != FC_NO_LOOP_ID &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5461) 				    (fcport->flags & FCF_FCP2_DEVICE) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5462) 				    fcport->port_type != FCT_INITIATOR &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5463) 				    fcport->port_type != FCT_BROADCAST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5464) 					ql_dbg(ql_dbg_disc, vha, 0x20f0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5465) 					    "%s %d %8phC post del sess\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5466) 					    __func__, __LINE__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5467) 					    fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5469) 					qlt_schedule_sess_for_deletion(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5470) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5471) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5472) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5473) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5475) 		if (fcport->scan_state == QLA_FCPORT_FOUND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5476) 			qla24xx_fcport_handle_login(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5477) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5479) 	qla2x00_free_fcport(new_fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5481) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5483) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5484) 	ql_dbg(ql_dbg_disc, vha, 0x2098,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5485) 	       "Configure local loop error exit: rval=%x.\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5486) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5489) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5490) qla2x00_iidma_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5492) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5493) 	uint16_t mb[MAILBOX_REGISTER_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5494) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5496) 	if (!IS_IIDMA_CAPABLE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5497) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5499) 	if (atomic_read(&fcport->state) != FCS_ONLINE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5500) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5502) 	if (fcport->fp_speed == PORT_SPEED_UNKNOWN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5503) 	    fcport->fp_speed > ha->link_data_rate ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5504) 	    !ha->flags.gpsc_supported)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5505) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5507) 	rval = qla2x00_set_idma_speed(vha, fcport->loop_id, fcport->fp_speed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5508) 	    mb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5509) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5510) 		ql_dbg(ql_dbg_disc, vha, 0x2004,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5511) 		    "Unable to adjust iIDMA %8phN -- %04x %x %04x %04x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5512) 		    fcport->port_name, rval, fcport->fp_speed, mb[0], mb[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5513) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5514) 		ql_dbg(ql_dbg_disc, vha, 0x2005,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5515) 		    "iIDMA adjusted to %s GB/s (%X) on %8phN.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5516) 		    qla2x00_get_link_speed_str(ha, fcport->fp_speed),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5517) 		    fcport->fp_speed, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5518) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5521) void qla_do_iidma_work(struct scsi_qla_host *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5523) 	qla2x00_iidma_fcport(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5524) 	qla24xx_update_fcport_fcp_prio(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5527) int qla_post_iidma_work(struct scsi_qla_host *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5529) 	struct qla_work_evt *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5531) 	e = qla2x00_alloc_work(vha, QLA_EVT_IIDMA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5532) 	if (!e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5533) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5535) 	e->u.fcport.fcport = fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5536) 	return qla2x00_post_work(vha, e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5539) /* qla2x00_reg_remote_port is reserved for Initiator Mode only.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5540) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5541) qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5543) 	struct fc_rport_identifiers rport_ids;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5544) 	struct fc_rport *rport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5545) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5547) 	if (atomic_read(&fcport->state) == FCS_ONLINE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5548) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5550) 	qla2x00_set_fcport_state(fcport, FCS_ONLINE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5552) 	rport_ids.node_name = wwn_to_u64(fcport->node_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5553) 	rport_ids.port_name = wwn_to_u64(fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5554) 	rport_ids.port_id = fcport->d_id.b.domain << 16 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5555) 	    fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5556) 	rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5557) 	fcport->rport = rport = fc_remote_port_add(vha->host, 0, &rport_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5558) 	if (!rport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5559) 		ql_log(ql_log_warn, vha, 0x2006,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5560) 		    "Unable to allocate fc remote port.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5561) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5562) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5564) 	spin_lock_irqsave(fcport->vha->host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5565) 	*((fc_port_t **)rport->dd_data) = fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5566) 	spin_unlock_irqrestore(fcport->vha->host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5568) 	rport->supported_classes = fcport->supported_classes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5570) 	rport_ids.roles = FC_PORT_ROLE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5571) 	if (fcport->port_type == FCT_INITIATOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5572) 		rport_ids.roles |= FC_PORT_ROLE_FCP_INITIATOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5573) 	if (fcport->port_type == FCT_TARGET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5574) 		rport_ids.roles |= FC_PORT_ROLE_FCP_TARGET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5575) 	if (fcport->port_type & FCT_NVME_INITIATOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5576) 		rport_ids.roles |= FC_PORT_ROLE_NVME_INITIATOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5577) 	if (fcport->port_type & FCT_NVME_TARGET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5578) 		rport_ids.roles |= FC_PORT_ROLE_NVME_TARGET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5579) 	if (fcport->port_type & FCT_NVME_DISCOVERY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5580) 		rport_ids.roles |= FC_PORT_ROLE_NVME_DISCOVERY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5582) 	ql_dbg(ql_dbg_disc, vha, 0x20ee,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5583) 	    "%s %8phN. rport %p is %s mode\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5584) 	    __func__, fcport->port_name, rport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5585) 	    (fcport->port_type == FCT_TARGET) ? "tgt" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5586) 	    ((fcport->port_type & FCT_NVME) ? "nvme" : "ini"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5588) 	fc_remote_port_rolechg(rport, rport_ids.roles);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5591) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5592)  * qla2x00_update_fcport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5593)  *	Updates device on list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5594)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5595)  * Input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5596)  *	ha = adapter block pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5597)  *	fcport = port structure pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5598)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5599)  * Return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5600)  *	0  - Success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5601)  *  BIT_0 - error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5602)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5603)  * Context:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5604)  *	Kernel context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5605)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5606) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5607) qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5609) 	if (IS_SW_RESV_ADDR(fcport->d_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5610) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5612) 	ql_dbg(ql_dbg_disc, vha, 0x20ef, "%s %8phC\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5613) 	    __func__, fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5615) 	qla2x00_set_fcport_disc_state(fcport, DSC_UPD_FCPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5616) 	fcport->login_retry = vha->hw->login_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5617) 	fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5618) 	fcport->deleted = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5619) 	if (vha->hw->current_topology == ISP_CFG_NL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5620) 		fcport->logout_on_delete = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5621) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5622) 		fcport->logout_on_delete = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5623) 	fcport->n2n_chip_reset = fcport->n2n_link_reset_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5625) 	switch (vha->hw->current_topology) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5626) 	case ISP_CFG_N:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5627) 	case ISP_CFG_NL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5628) 		fcport->keep_nport_handle = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5629) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5630) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5631) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5632) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5634) 	qla2x00_iidma_fcport(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5636) 	qla2x00_dfs_create_rport(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5638) 	if (NVME_TARGET(vha->hw, fcport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5639) 		qla_nvme_register_remote(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5640) 		qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_COMPLETE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5641) 		qla2x00_set_fcport_state(fcport, FCS_ONLINE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5642) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5643) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5645) 	qla24xx_update_fcport_fcp_prio(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5647) 	switch (vha->host->active_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5648) 	case MODE_INITIATOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5649) 		qla2x00_reg_remote_port(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5650) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5651) 	case MODE_TARGET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5652) 		qla2x00_set_fcport_state(fcport, FCS_ONLINE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5653) 		if (!vha->vha_tgt.qla_tgt->tgt_stop &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5654) 			!vha->vha_tgt.qla_tgt->tgt_stopped)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5655) 			qlt_fc_port_added(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5656) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5657) 	case MODE_DUAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5658) 		qla2x00_reg_remote_port(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5659) 		if (!vha->vha_tgt.qla_tgt->tgt_stop &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5660) 			!vha->vha_tgt.qla_tgt->tgt_stopped)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5661) 			qlt_fc_port_added(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5662) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5663) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5664) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5665) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5667) 	if (IS_IIDMA_CAPABLE(vha->hw) && vha->hw->flags.gpsc_supported) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5668) 		if (fcport->id_changed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5669) 			fcport->id_changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5670) 			ql_dbg(ql_dbg_disc, vha, 0x20d7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5671) 			    "%s %d %8phC post gfpnid fcp_cnt %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5672) 			    __func__, __LINE__, fcport->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5673) 			    vha->fcport_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5674) 			qla24xx_post_gfpnid_work(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5675) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5676) 			ql_dbg(ql_dbg_disc, vha, 0x20d7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5677) 			    "%s %d %8phC post gpsc fcp_cnt %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5678) 			    __func__, __LINE__, fcport->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5679) 			    vha->fcport_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5680) 			qla24xx_post_gpsc_work(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5681) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5682) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5684) 	qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_COMPLETE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5687) void qla_register_fcport_fn(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5689) 	fc_port_t *fcport = container_of(work, struct fc_port, reg_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5690) 	u32 rscn_gen = fcport->rscn_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5691) 	u16 data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5693) 	if (IS_SW_RESV_ADDR(fcport->d_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5694) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5696) 	qla2x00_update_fcport(fcport->vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5698) 	if (rscn_gen != fcport->rscn_gen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5699) 		/* RSCN(s) came in while registration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5700) 		switch (fcport->next_disc_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5701) 		case DSC_DELETE_PEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5702) 			qlt_schedule_sess_for_deletion(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5703) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5704) 		case DSC_ADISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5705) 			data[0] = data[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5706) 			qla2x00_post_async_adisc_work(fcport->vha, fcport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5707) 			    data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5708) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5709) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5710) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5711) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5712) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5715) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5716)  * qla2x00_configure_fabric
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5717)  *      Setup SNS devices with loop ID's.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5718)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5719)  * Input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5720)  *      ha = adapter block pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5721)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5722)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5723)  *      0 = success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5724)  *      BIT_0 = error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5725)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5726) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5727) qla2x00_configure_fabric(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5729) 	int	rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5730) 	fc_port_t	*fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5731) 	uint16_t	mb[MAILBOX_REGISTER_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5732) 	uint16_t	loop_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5733) 	LIST_HEAD(new_fcports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5734) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5735) 	int		discovery_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5737) 	/* If FL port exists, then SNS is present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5738) 	if (IS_FWI2_CAPABLE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5739) 		loop_id = NPH_F_PORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5740) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5741) 		loop_id = SNS_FL_PORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5742) 	rval = qla2x00_get_port_name(vha, loop_id, vha->fabric_node_name, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5743) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5744) 		ql_dbg(ql_dbg_disc, vha, 0x20a0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5745) 		    "MBX_GET_PORT_NAME failed, No FL Port.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5747) 		vha->device_flags &= ~SWITCH_FOUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5748) 		return (QLA_SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5749) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5750) 	vha->device_flags |= SWITCH_FOUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5752) 	rval = qla2x00_get_port_name(vha, loop_id, vha->fabric_port_name, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5753) 	if (rval != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5754) 		ql_dbg(ql_dbg_disc, vha, 0x20ff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5755) 		    "Failed to get Fabric Port Name\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5757) 	if (qla_tgt_mode_enabled(vha) || qla_dual_mode_enabled(vha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5758) 		rval = qla2x00_send_change_request(vha, 0x3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5759) 		if (rval != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5760) 			ql_log(ql_log_warn, vha, 0x121,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5761) 			    "Failed to enable receiving of RSCN requests: 0x%x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5762) 			    rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5763) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5765) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5766) 		qla2x00_mgmt_svr_login(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5768) 		/* Ensure we are logged into the SNS. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5769) 		loop_id = NPH_SNS_LID(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5770) 		rval = ha->isp_ops->fabric_login(vha, loop_id, 0xff, 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5771) 		    0xfc, mb, BIT_1|BIT_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5772) 		if (rval != QLA_SUCCESS || mb[0] != MBS_COMMAND_COMPLETE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5773) 			ql_dbg(ql_dbg_disc, vha, 0x20a1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5774) 			    "Failed SNS login: loop_id=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[6]=%x mb[7]=%x (%x).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5775) 			    loop_id, mb[0], mb[1], mb[2], mb[6], mb[7], rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5776) 			set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5777) 			return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5778) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5780) 		/* FDMI support. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5781) 		if (ql2xfdmienable &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5782) 		    test_and_clear_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5783) 			qla2x00_fdmi_register(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5785) 		if (test_and_clear_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5786) 			if (qla2x00_rft_id(vha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5787) 				/* EMPTY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5788) 				ql_dbg(ql_dbg_disc, vha, 0x20a2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5789) 				    "Register FC-4 TYPE failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5790) 				if (test_bit(LOOP_RESYNC_NEEDED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5791) 				    &vha->dpc_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5792) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5793) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5794) 			if (qla2x00_rff_id(vha, FC4_TYPE_FCP_SCSI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5795) 				/* EMPTY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5796) 				ql_dbg(ql_dbg_disc, vha, 0x209a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5797) 				    "Register FC-4 Features failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5798) 				if (test_bit(LOOP_RESYNC_NEEDED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5799) 				    &vha->dpc_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5800) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5801) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5802) 			if (vha->flags.nvme_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5803) 				if (qla2x00_rff_id(vha, FC_TYPE_NVME)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5804) 					ql_dbg(ql_dbg_disc, vha, 0x2049,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5805) 					    "Register NVME FC Type Features failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5806) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5807) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5808) 			if (qla2x00_rnn_id(vha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5809) 				/* EMPTY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5810) 				ql_dbg(ql_dbg_disc, vha, 0x2104,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5811) 				    "Register Node Name failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5812) 				if (test_bit(LOOP_RESYNC_NEEDED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5813) 				    &vha->dpc_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5814) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5815) 			} else if (qla2x00_rsnn_nn(vha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5816) 				/* EMPTY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5817) 				ql_dbg(ql_dbg_disc, vha, 0x209b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5818) 				    "Register Symbolic Node Name failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5819) 				if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5820) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5821) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5822) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5825) 		/* Mark the time right before querying FW for connected ports.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5826) 		 * This process is long, asynchronous and by the time it's done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5827) 		 * collected information might not be accurate anymore. E.g.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5828) 		 * disconnected port might have re-connected and a brand new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5829) 		 * session has been created. In this case session's generation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5830) 		 * will be newer than discovery_gen. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5831) 		qlt_do_generation_tick(vha, &discovery_gen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5833) 		if (USE_ASYNC_SCAN(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5834) 			rval = qla24xx_async_gpnft(vha, FC4_TYPE_FCP_SCSI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5835) 			    NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5836) 			if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5837) 				set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5838) 		} else  {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5839) 			list_for_each_entry(fcport, &vha->vp_fcports, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5840) 				fcport->scan_state = QLA_FCPORT_SCAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5842) 			rval = qla2x00_find_all_fabric_devs(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5843) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5844) 		if (rval != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5845) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5846) 	} while (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5848) 	if (!vha->nvme_local_port && vha->flags.nvme_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5849) 		qla_nvme_register_hba(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5851) 	if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5852) 		ql_dbg(ql_dbg_disc, vha, 0x2068,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5853) 		    "Configure fabric error exit rval=%d.\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5855) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5858) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5859)  * qla2x00_find_all_fabric_devs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5860)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5861)  * Input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5862)  *	ha = adapter block pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5863)  *	dev = database device entry pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5864)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5865)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5866)  *	0 = success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5867)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5868)  * Context:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5869)  *	Kernel context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5870)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5871) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5872) qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5873) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5874) 	int		rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5875) 	uint16_t	loop_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5876) 	fc_port_t	*fcport, *new_fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5877) 	int		found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5879) 	sw_info_t	*swl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5880) 	int		swl_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5881) 	int		first_dev, last_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5882) 	port_id_t	wrap = {}, nxt_d_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5883) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5884) 	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5885) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5887) 	rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5889) 	/* Try GID_PT to get device list, else GAN. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5890) 	if (!ha->swl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5891) 		ha->swl = kcalloc(ha->max_fibre_devices, sizeof(sw_info_t),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5892) 		    GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5893) 	swl = ha->swl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5894) 	if (!swl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5895) 		/*EMPTY*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5896) 		ql_dbg(ql_dbg_disc, vha, 0x209c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5897) 		    "GID_PT allocations failed, fallback on GA_NXT.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5898) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5899) 		memset(swl, 0, ha->max_fibre_devices * sizeof(sw_info_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5900) 		if (qla2x00_gid_pt(vha, swl) != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5901) 			swl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5902) 			if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5903) 				return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5904) 		} else if (qla2x00_gpn_id(vha, swl) != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5905) 			swl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5906) 			if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5907) 				return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5908) 		} else if (qla2x00_gnn_id(vha, swl) != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5909) 			swl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5910) 			if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5911) 				return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5912) 		} else if (qla2x00_gfpn_id(vha, swl) != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5913) 			swl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5914) 			if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5915) 				return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5916) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5918) 		/* If other queries succeeded probe for FC-4 type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5919) 		if (swl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5920) 			qla2x00_gff_id(vha, swl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5921) 			if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5922) 				return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5923) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5924) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5925) 	swl_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5927) 	/* Allocate temporary fcport for any new fcports discovered. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5928) 	new_fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5929) 	if (new_fcport == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5930) 		ql_log(ql_log_warn, vha, 0x209d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5931) 		    "Failed to allocate memory for fcport.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5932) 		return (QLA_MEMORY_ALLOC_FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5933) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5934) 	new_fcport->flags |= (FCF_FABRIC_DEVICE | FCF_LOGIN_NEEDED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5935) 	/* Set start port ID scan at adapter ID. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5936) 	first_dev = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5937) 	last_dev = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5939) 	/* Starting free loop ID. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5940) 	loop_id = ha->min_external_loopid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5941) 	for (; loop_id <= ha->max_loop_id; loop_id++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5942) 		if (qla2x00_is_reserved_id(vha, loop_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5943) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5945) 		if (ha->current_topology == ISP_CFG_FL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5946) 		    (atomic_read(&vha->loop_down_timer) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5947) 		     LOOP_TRANSITION(vha))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5948) 			atomic_set(&vha->loop_down_timer, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5949) 			set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5950) 			set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5951) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5952) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5954) 		if (swl != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5955) 			if (last_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5956) 				wrap.b24 = new_fcport->d_id.b24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5957) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5958) 				new_fcport->d_id.b24 = swl[swl_idx].d_id.b24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5959) 				memcpy(new_fcport->node_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5960) 				    swl[swl_idx].node_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5961) 				memcpy(new_fcport->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5962) 				    swl[swl_idx].port_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5963) 				memcpy(new_fcport->fabric_port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5964) 				    swl[swl_idx].fabric_port_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5965) 				new_fcport->fp_speed = swl[swl_idx].fp_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5966) 				new_fcport->fc4_type = swl[swl_idx].fc4_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5968) 				new_fcport->nvme_flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5969) 				if (vha->flags.nvme_enabled &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5970) 				    swl[swl_idx].fc4_type & FS_FC4TYPE_NVME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5971) 					ql_log(ql_log_info, vha, 0x2131,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5972) 					    "FOUND: NVME port %8phC as FC Type 28h\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5973) 					    new_fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5974) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5976) 				if (swl[swl_idx].d_id.b.rsvd_1 != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5977) 					last_dev = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5978) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5979) 				swl_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5980) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5981) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5982) 			/* Send GA_NXT to the switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5983) 			rval = qla2x00_ga_nxt(vha, new_fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5984) 			if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5985) 				ql_log(ql_log_warn, vha, 0x209e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5986) 				    "SNS scan failed -- assuming "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5987) 				    "zero-entry result.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5988) 				rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5989) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5990) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5991) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5993) 		/* If wrap on switch device list, exit. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5994) 		if (first_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5995) 			wrap.b24 = new_fcport->d_id.b24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5996) 			first_dev = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5997) 		} else if (new_fcport->d_id.b24 == wrap.b24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5998) 			ql_dbg(ql_dbg_disc, vha, 0x209f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5999) 			    "Device wrap (%02x%02x%02x).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6000) 			    new_fcport->d_id.b.domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6001) 			    new_fcport->d_id.b.area,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6002) 			    new_fcport->d_id.b.al_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6003) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6004) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6005) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6006) 		/* Bypass if same physical adapter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6007) 		if (new_fcport->d_id.b24 == base_vha->d_id.b24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6008) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6010) 		/* Bypass virtual ports of the same host. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6011) 		if (qla2x00_is_a_vp_did(vha, new_fcport->d_id.b24))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6012) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6014) 		/* Bypass if same domain and area of adapter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6015) 		if (((new_fcport->d_id.b24 & 0xffff00) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6016) 		    (vha->d_id.b24 & 0xffff00)) && ha->current_topology ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6017) 			ISP_CFG_FL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6018) 			    continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6020) 		/* Bypass reserved domain fields. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6021) 		if ((new_fcport->d_id.b.domain & 0xf0) == 0xf0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6022) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6024) 		/* Bypass ports whose FCP-4 type is not FCP_SCSI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6025) 		if (ql2xgffidenable &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6026) 		    (!(new_fcport->fc4_type & FS_FC4TYPE_FCP) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6027) 		    new_fcport->fc4_type != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6028) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6030) 		spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6032) 		/* Locate matching device in database. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6033) 		found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6034) 		list_for_each_entry(fcport, &vha->vp_fcports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6035) 			if (memcmp(new_fcport->port_name, fcport->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6036) 			    WWN_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6037) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6039) 			fcport->scan_state = QLA_FCPORT_FOUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6041) 			found++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6043) 			/* Update port state. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6044) 			memcpy(fcport->fabric_port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6045) 			    new_fcport->fabric_port_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6046) 			fcport->fp_speed = new_fcport->fp_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6048) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6049) 			 * If address the same and state FCS_ONLINE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6050) 			 * (or in target mode), nothing changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6051) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6052) 			if (fcport->d_id.b24 == new_fcport->d_id.b24 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6053) 			    (atomic_read(&fcport->state) == FCS_ONLINE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6054) 			     (vha->host->active_mode == MODE_TARGET))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6055) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6056) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6058) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6059) 			 * If device was not a fabric device before.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6060) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6061) 			if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6062) 				fcport->d_id.b24 = new_fcport->d_id.b24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6063) 				qla2x00_clear_loop_id(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6064) 				fcport->flags |= (FCF_FABRIC_DEVICE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6065) 				    FCF_LOGIN_NEEDED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6066) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6067) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6069) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6070) 			 * Port ID changed or device was marked to be updated;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6071) 			 * Log it out if still logged in and mark it for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6072) 			 * relogin later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6073) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6074) 			if (qla_tgt_mode_enabled(base_vha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6075) 				ql_dbg(ql_dbg_tgt_mgt, vha, 0xf080,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6076) 					 "port changed FC ID, %8phC"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6077) 					 " old %x:%x:%x (loop_id 0x%04x)-> new %x:%x:%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6078) 					 fcport->port_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6079) 					 fcport->d_id.b.domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6080) 					 fcport->d_id.b.area,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6081) 					 fcport->d_id.b.al_pa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6082) 					 fcport->loop_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6083) 					 new_fcport->d_id.b.domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6084) 					 new_fcport->d_id.b.area,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6085) 					 new_fcport->d_id.b.al_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6086) 				fcport->d_id.b24 = new_fcport->d_id.b24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6087) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6088) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6089) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6090) 			fcport->d_id.b24 = new_fcport->d_id.b24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6091) 			fcport->flags |= FCF_LOGIN_NEEDED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6092) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6093) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6095) 		if (found && NVME_TARGET(vha->hw, fcport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6096) 			if (fcport->disc_state == DSC_DELETE_PEND) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6097) 				qla2x00_set_fcport_disc_state(fcport, DSC_GNL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6098) 				vha->fcport_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6099) 				fcport->login_succ = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6100) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6101) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6103) 		if (found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6104) 			spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6105) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6106) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6107) 		/* If device was not in our fcports list, then add it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6108) 		new_fcport->scan_state = QLA_FCPORT_FOUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6109) 		list_add_tail(&new_fcport->list, &vha->vp_fcports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6111) 		spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6114) 		/* Allocate a new replacement fcport. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6115) 		nxt_d_id.b24 = new_fcport->d_id.b24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6116) 		new_fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6117) 		if (new_fcport == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6118) 			ql_log(ql_log_warn, vha, 0xd032,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6119) 			    "Memory allocation failed for fcport.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6120) 			return (QLA_MEMORY_ALLOC_FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6121) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6122) 		new_fcport->flags |= (FCF_FABRIC_DEVICE | FCF_LOGIN_NEEDED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6123) 		new_fcport->d_id.b24 = nxt_d_id.b24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6124) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6126) 	qla2x00_free_fcport(new_fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6128) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6129) 	 * Logout all previous fabric dev marked lost, except FCP2 devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6130) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6131) 	list_for_each_entry(fcport, &vha->vp_fcports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6132) 		if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6133) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6135) 		if ((fcport->flags & FCF_FABRIC_DEVICE) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6136) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6138) 		if (fcport->scan_state == QLA_FCPORT_SCAN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6139) 			if ((qla_dual_mode_enabled(vha) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6140) 			    qla_ini_mode_enabled(vha)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6141) 			    atomic_read(&fcport->state) == FCS_ONLINE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6142) 				qla2x00_mark_device_lost(vha, fcport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6143) 					ql2xplogiabsentdevice);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6144) 				if (fcport->loop_id != FC_NO_LOOP_ID &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6145) 				    (fcport->flags & FCF_FCP2_DEVICE) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6146) 				    fcport->port_type != FCT_INITIATOR &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6147) 				    fcport->port_type != FCT_BROADCAST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6148) 					ql_dbg(ql_dbg_disc, vha, 0x20f0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6149) 					    "%s %d %8phC post del sess\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6150) 					    __func__, __LINE__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6151) 					    fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6152) 					qlt_schedule_sess_for_deletion(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6153) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6154) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6155) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6156) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6158) 		if (fcport->scan_state == QLA_FCPORT_FOUND &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6159) 		    (fcport->flags & FCF_LOGIN_NEEDED) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6160) 			qla24xx_fcport_handle_login(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6161) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6162) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6165) /* FW does not set aside Loop id for MGMT Server/FFFFFAh */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6166) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6167) qla2x00_reserve_mgmt_server_loop_id(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6169) 	int loop_id = FC_NO_LOOP_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6170) 	int lid = NPH_MGMT_SERVER - vha->vp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6171) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6172) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6174) 	if (vha->vp_idx == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6175) 		set_bit(NPH_MGMT_SERVER, ha->loop_id_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6176) 		return NPH_MGMT_SERVER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6177) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6179) 	/* pick id from high and work down to low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6180) 	spin_lock_irqsave(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6181) 	for (; lid > 0; lid--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6182) 		if (!test_bit(lid, vha->hw->loop_id_map)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6183) 			set_bit(lid, vha->hw->loop_id_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6184) 			loop_id = lid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6185) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6186) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6187) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6188) 	spin_unlock_irqrestore(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6190) 	return loop_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6193) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6194)  * qla2x00_fabric_login
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6195)  *	Issue fabric login command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6196)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6197)  * Input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6198)  *	ha = adapter block pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6199)  *	device = pointer to FC device type structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6200)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6201)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6202)  *      0 - Login successfully
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6203)  *      1 - Login failed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6204)  *      2 - Initiator device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6205)  *      3 - Fatal error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6206)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6207) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6208) qla2x00_fabric_login(scsi_qla_host_t *vha, fc_port_t *fcport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6209)     uint16_t *next_loopid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6211) 	int	rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6212) 	int	retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6213) 	uint16_t tmp_loopid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6214) 	uint16_t mb[MAILBOX_REGISTER_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6215) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6217) 	retry = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6218) 	tmp_loopid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6220) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6221) 		ql_dbg(ql_dbg_disc, vha, 0x2000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6222) 		    "Trying Fabric Login w/loop id 0x%04x for port "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6223) 		    "%02x%02x%02x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6224) 		    fcport->loop_id, fcport->d_id.b.domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6225) 		    fcport->d_id.b.area, fcport->d_id.b.al_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6227) 		/* Login fcport on switch. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6228) 		rval = ha->isp_ops->fabric_login(vha, fcport->loop_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6229) 		    fcport->d_id.b.domain, fcport->d_id.b.area,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6230) 		    fcport->d_id.b.al_pa, mb, BIT_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6231) 		if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6232) 			return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6233) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6234) 		if (mb[0] == MBS_PORT_ID_USED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6235) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6236) 			 * Device has another loop ID.  The firmware team
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6237) 			 * recommends the driver perform an implicit login with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6238) 			 * the specified ID again. The ID we just used is save
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6239) 			 * here so we return with an ID that can be tried by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6240) 			 * the next login.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6241) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6242) 			retry++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6243) 			tmp_loopid = fcport->loop_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6244) 			fcport->loop_id = mb[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6246) 			ql_dbg(ql_dbg_disc, vha, 0x2001,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6247) 			    "Fabric Login: port in use - next loop "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6248) 			    "id=0x%04x, port id= %02x%02x%02x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6249) 			    fcport->loop_id, fcport->d_id.b.domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6250) 			    fcport->d_id.b.area, fcport->d_id.b.al_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6252) 		} else if (mb[0] == MBS_COMMAND_COMPLETE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6253) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6254) 			 * Login succeeded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6255) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6256) 			if (retry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6257) 				/* A retry occurred before. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6258) 				*next_loopid = tmp_loopid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6259) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6260) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6261) 				 * No retry occurred before. Just increment the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6262) 				 * ID value for next login.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6263) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6264) 				*next_loopid = (fcport->loop_id + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6265) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6267) 			if (mb[1] & BIT_0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6268) 				fcport->port_type = FCT_INITIATOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6269) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6270) 				fcport->port_type = FCT_TARGET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6271) 				if (mb[1] & BIT_1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6272) 					fcport->flags |= FCF_FCP2_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6273) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6274) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6276) 			if (mb[10] & BIT_0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6277) 				fcport->supported_classes |= FC_COS_CLASS2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6278) 			if (mb[10] & BIT_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6279) 				fcport->supported_classes |= FC_COS_CLASS3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6281) 			if (IS_FWI2_CAPABLE(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6282) 				if (mb[10] & BIT_7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6283) 					fcport->flags |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6284) 					    FCF_CONF_COMP_SUPPORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6285) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6287) 			rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6288) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6289) 		} else if (mb[0] == MBS_LOOP_ID_USED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6290) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6291) 			 * Loop ID already used, try next loop ID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6292) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6293) 			fcport->loop_id++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6294) 			rval = qla2x00_find_new_loop_id(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6295) 			if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6296) 				/* Ran out of loop IDs to use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6297) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6298) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6299) 		} else if (mb[0] == MBS_COMMAND_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6300) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6301) 			 * Firmware possibly timed out during login. If NO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6302) 			 * retries are left to do then the device is declared
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6303) 			 * dead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6304) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6305) 			*next_loopid = fcport->loop_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6306) 			ha->isp_ops->fabric_logout(vha, fcport->loop_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6307) 			    fcport->d_id.b.domain, fcport->d_id.b.area,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6308) 			    fcport->d_id.b.al_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6309) 			qla2x00_mark_device_lost(vha, fcport, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6311) 			rval = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6312) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6313) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6314) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6315) 			 * unrecoverable / not handled error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6316) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6317) 			ql_dbg(ql_dbg_disc, vha, 0x2002,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6318) 			    "Failed=%x port_id=%02x%02x%02x loop_id=%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6319) 			    "jiffies=%lx.\n", mb[0], fcport->d_id.b.domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6320) 			    fcport->d_id.b.area, fcport->d_id.b.al_pa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6321) 			    fcport->loop_id, jiffies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6323) 			*next_loopid = fcport->loop_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6324) 			ha->isp_ops->fabric_logout(vha, fcport->loop_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6325) 			    fcport->d_id.b.domain, fcport->d_id.b.area,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6326) 			    fcport->d_id.b.al_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6327) 			qla2x00_clear_loop_id(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6328) 			fcport->login_retry = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6330) 			rval = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6331) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6332) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6333) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6335) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6338) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6339)  * qla2x00_local_device_login
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6340)  *	Issue local device login command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6341)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6342)  * Input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6343)  *	ha = adapter block pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6344)  *	loop_id = loop id of device to login to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6345)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6346)  * Returns (Where's the #define!!!!):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6347)  *      0 - Login successfully
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6348)  *      1 - Login failed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6349)  *      3 - Fatal error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6350)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6351) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6352) qla2x00_local_device_login(scsi_qla_host_t *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6354) 	int		rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6355) 	uint16_t	mb[MAILBOX_REGISTER_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6357) 	memset(mb, 0, sizeof(mb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6358) 	rval = qla2x00_login_local_device(vha, fcport, mb, BIT_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6359) 	if (rval == QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6360) 		/* Interrogate mailbox registers for any errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6361) 		if (mb[0] == MBS_COMMAND_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6362) 			rval = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6363) 		else if (mb[0] == MBS_COMMAND_PARAMETER_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6364) 			/* device not in PCB table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6365) 			rval = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6366) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6368) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6371) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6372)  *  qla2x00_loop_resync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6373)  *      Resync with fibre channel devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6374)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6375)  * Input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6376)  *      ha = adapter block pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6377)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6378)  * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6379)  *      0 = success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6380)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6381) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6382) qla2x00_loop_resync(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6384) 	int rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6385) 	uint32_t wait_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6387) 	clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6388) 	if (vha->flags.online) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6389) 		if (!(rval = qla2x00_fw_ready(vha))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6390) 			/* Wait at most MAX_TARGET RSCNs for a stable link. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6391) 			wait_time = 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6392) 			do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6393) 				if (!IS_QLAFX00(vha->hw)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6394) 					/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6395) 					 * Issue a marker after FW becomes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6396) 					 * ready.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6397) 					 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6398) 					qla2x00_marker(vha, vha->hw->base_qpair,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6399) 					    0, 0, MK_SYNC_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6400) 					vha->marker_needed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6401) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6403) 				/* Remap devices on Loop. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6404) 				clear_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6406) 				if (IS_QLAFX00(vha->hw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6407) 					qlafx00_configure_devices(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6408) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6409) 					qla2x00_configure_loop(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6411) 				wait_time--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6412) 			} while (!atomic_read(&vha->loop_down_timer) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6413) 				!(test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6414) 				&& wait_time && (test_bit(LOOP_RESYNC_NEEDED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6415) 				&vha->dpc_flags)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6416) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6417) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6419) 	if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6420) 		return (QLA_FUNCTION_FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6422) 	if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6423) 		ql_dbg(ql_dbg_disc, vha, 0x206c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6424) 		    "%s *** FAILED ***.\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6426) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6429) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6430) * qla2x00_perform_loop_resync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6431) * Description: This function will set the appropriate flags and call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6432) *              qla2x00_loop_resync. If successful loop will be resynced
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6433) * Arguments : scsi_qla_host_t pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6434) * returm    : Success or Failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6435) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6437) int qla2x00_perform_loop_resync(scsi_qla_host_t *ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6439) 	int32_t rval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6441) 	if (!test_and_set_bit(LOOP_RESYNC_ACTIVE, &ha->dpc_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6442) 		/*Configure the flags so that resync happens properly*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6443) 		atomic_set(&ha->loop_down_timer, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6444) 		if (!(ha->device_flags & DFLG_NO_CABLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6445) 			atomic_set(&ha->loop_state, LOOP_UP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6446) 			set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6447) 			set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6448) 			set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6450) 			rval = qla2x00_loop_resync(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6451) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6452) 			atomic_set(&ha->loop_state, LOOP_DEAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6454) 		clear_bit(LOOP_RESYNC_ACTIVE, &ha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6455) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6457) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6460) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6461) qla2x00_update_fcports(scsi_qla_host_t *base_vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6463) 	fc_port_t *fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6464) 	struct scsi_qla_host *vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6465) 	struct qla_hw_data *ha = base_vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6466) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6468) 	spin_lock_irqsave(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6469) 	/* Go with deferred removal of rport references. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6470) 	list_for_each_entry(vha, &base_vha->hw->vp_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6471) 		atomic_inc(&vha->vref_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6472) 		list_for_each_entry(fcport, &vha->vp_fcports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6473) 			if (fcport->drport &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6474) 			    atomic_read(&fcport->state) != FCS_UNCONFIGURED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6475) 				spin_unlock_irqrestore(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6476) 				qla2x00_rport_del(fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6478) 				spin_lock_irqsave(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6479) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6480) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6481) 		atomic_dec(&vha->vref_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6482) 		wake_up(&vha->vref_waitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6483) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6484) 	spin_unlock_irqrestore(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6487) /* Assumes idc_lock always held on entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6488) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6489) qla83xx_reset_ownership(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6491) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6492) 	uint32_t drv_presence, drv_presence_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6493) 	uint32_t dev_part_info1, dev_part_info2, class_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6494) 	uint32_t class_type_mask = 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6495) 	uint16_t fcoe_other_function = 0xffff, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6497) 	if (IS_QLA8044(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6498) 		drv_presence = qla8044_rd_direct(vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6499) 		    QLA8044_CRB_DRV_ACTIVE_INDEX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6500) 		dev_part_info1 = qla8044_rd_direct(vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6501) 		    QLA8044_CRB_DEV_PART_INFO_INDEX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6502) 		dev_part_info2 = qla8044_rd_direct(vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6503) 		    QLA8044_CRB_DEV_PART_INFO2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6504) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6505) 		qla83xx_rd_reg(vha, QLA83XX_IDC_DRV_PRESENCE, &drv_presence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6506) 		qla83xx_rd_reg(vha, QLA83XX_DEV_PARTINFO1, &dev_part_info1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6507) 		qla83xx_rd_reg(vha, QLA83XX_DEV_PARTINFO2, &dev_part_info2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6508) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6509) 	for (i = 0; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6510) 		class_type = ((dev_part_info1 >> (i * 4)) & class_type_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6511) 		if ((class_type == QLA83XX_CLASS_TYPE_FCOE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6512) 		    (i != ha->portnum)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6513) 			fcoe_other_function = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6514) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6515) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6516) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6517) 	if (fcoe_other_function == 0xffff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6518) 		for (i = 0; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6519) 			class_type = ((dev_part_info2 >> (i * 4)) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6520) 			    class_type_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6521) 			if ((class_type == QLA83XX_CLASS_TYPE_FCOE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6522) 			    ((i + 8) != ha->portnum)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6523) 				fcoe_other_function = i + 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6524) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6525) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6526) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6527) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6528) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6529) 	 * Prepare drv-presence mask based on fcoe functions present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6530) 	 * However consider only valid physical fcoe function numbers (0-15).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6531) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6532) 	drv_presence_mask = ~((1 << (ha->portnum)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6533) 			((fcoe_other_function == 0xffff) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6534) 			 0 : (1 << (fcoe_other_function))));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6536) 	/* We are the reset owner iff:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6537) 	 *    - No other protocol drivers present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6538) 	 *    - This is the lowest among fcoe functions. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6539) 	if (!(drv_presence & drv_presence_mask) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6540) 			(ha->portnum < fcoe_other_function)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6541) 		ql_dbg(ql_dbg_p3p, vha, 0xb07f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6542) 		    "This host is Reset owner.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6543) 		ha->flags.nic_core_reset_owner = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6544) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6547) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6548) __qla83xx_set_drv_ack(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6550) 	int rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6551) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6552) 	uint32_t drv_ack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6554) 	rval = qla83xx_rd_reg(vha, QLA83XX_IDC_DRIVER_ACK, &drv_ack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6555) 	if (rval == QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6556) 		drv_ack |= (1 << ha->portnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6557) 		rval = qla83xx_wr_reg(vha, QLA83XX_IDC_DRIVER_ACK, drv_ack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6558) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6560) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6563) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6564) __qla83xx_clear_drv_ack(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6566) 	int rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6567) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6568) 	uint32_t drv_ack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6570) 	rval = qla83xx_rd_reg(vha, QLA83XX_IDC_DRIVER_ACK, &drv_ack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6571) 	if (rval == QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6572) 		drv_ack &= ~(1 << ha->portnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6573) 		rval = qla83xx_wr_reg(vha, QLA83XX_IDC_DRIVER_ACK, drv_ack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6574) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6576) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6579) static const char *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6580) qla83xx_dev_state_to_string(uint32_t dev_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6581) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6582) 	switch (dev_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6583) 	case QLA8XXX_DEV_COLD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6584) 		return "COLD/RE-INIT";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6585) 	case QLA8XXX_DEV_INITIALIZING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6586) 		return "INITIALIZING";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6587) 	case QLA8XXX_DEV_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6588) 		return "READY";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6589) 	case QLA8XXX_DEV_NEED_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6590) 		return "NEED RESET";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6591) 	case QLA8XXX_DEV_NEED_QUIESCENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6592) 		return "NEED QUIESCENT";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6593) 	case QLA8XXX_DEV_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6594) 		return "FAILED";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6595) 	case QLA8XXX_DEV_QUIESCENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6596) 		return "QUIESCENT";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6597) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6598) 		return "Unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6599) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6602) /* Assumes idc-lock always held on entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6603) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6604) qla83xx_idc_audit(scsi_qla_host_t *vha, int audit_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6605) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6606) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6607) 	uint32_t idc_audit_reg = 0, duration_secs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6609) 	switch (audit_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6610) 	case IDC_AUDIT_TIMESTAMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6611) 		ha->idc_audit_ts = (jiffies_to_msecs(jiffies) / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6612) 		idc_audit_reg = (ha->portnum) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6613) 		    (IDC_AUDIT_TIMESTAMP << 7) | (ha->idc_audit_ts << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6614) 		qla83xx_wr_reg(vha, QLA83XX_IDC_AUDIT, idc_audit_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6615) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6617) 	case IDC_AUDIT_COMPLETION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6618) 		duration_secs = ((jiffies_to_msecs(jiffies) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6619) 		    jiffies_to_msecs(ha->idc_audit_ts)) / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6620) 		idc_audit_reg = (ha->portnum) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6621) 		    (IDC_AUDIT_COMPLETION << 7) | (duration_secs << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6622) 		qla83xx_wr_reg(vha, QLA83XX_IDC_AUDIT, idc_audit_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6623) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6625) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6626) 		ql_log(ql_log_warn, vha, 0xb078,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6627) 		    "Invalid audit type specified.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6628) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6629) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6632) /* Assumes idc_lock always held on entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6633) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6634) qla83xx_initiating_reset(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6636) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6637) 	uint32_t  idc_control, dev_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6639) 	__qla83xx_get_idc_control(vha, &idc_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6640) 	if ((idc_control & QLA83XX_IDC_RESET_DISABLED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6641) 		ql_log(ql_log_info, vha, 0xb080,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6642) 		    "NIC Core reset has been disabled. idc-control=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6643) 		    idc_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6644) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6645) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6647) 	/* Set NEED-RESET iff in READY state and we are the reset-owner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6648) 	qla83xx_rd_reg(vha, QLA83XX_IDC_DEV_STATE, &dev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6649) 	if (ha->flags.nic_core_reset_owner && dev_state == QLA8XXX_DEV_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6650) 		qla83xx_wr_reg(vha, QLA83XX_IDC_DEV_STATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6651) 		    QLA8XXX_DEV_NEED_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6652) 		ql_log(ql_log_info, vha, 0xb056, "HW State: NEED RESET.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6653) 		qla83xx_idc_audit(vha, IDC_AUDIT_TIMESTAMP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6654) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6655) 		const char *state = qla83xx_dev_state_to_string(dev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6657) 		ql_log(ql_log_info, vha, 0xb057, "HW State: %s.\n", state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6659) 		/* SV: XXX: Is timeout required here? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6660) 		/* Wait for IDC state change READY -> NEED_RESET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6661) 		while (dev_state == QLA8XXX_DEV_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6662) 			qla83xx_idc_unlock(vha, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6663) 			msleep(200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6664) 			qla83xx_idc_lock(vha, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6665) 			qla83xx_rd_reg(vha, QLA83XX_IDC_DEV_STATE, &dev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6666) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6667) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6669) 	/* Send IDC ack by writing to drv-ack register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6670) 	__qla83xx_set_drv_ack(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6672) 	return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6675) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6676) __qla83xx_set_idc_control(scsi_qla_host_t *vha, uint32_t idc_control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6677) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6678) 	return qla83xx_wr_reg(vha, QLA83XX_IDC_CONTROL, idc_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6681) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6682) __qla83xx_get_idc_control(scsi_qla_host_t *vha, uint32_t *idc_control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6684) 	return qla83xx_rd_reg(vha, QLA83XX_IDC_CONTROL, idc_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6687) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6688) qla83xx_check_driver_presence(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6689) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6690) 	uint32_t drv_presence = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6691) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6693) 	qla83xx_rd_reg(vha, QLA83XX_IDC_DRV_PRESENCE, &drv_presence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6694) 	if (drv_presence & (1 << ha->portnum))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6695) 		return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6696) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6697) 		return QLA_TEST_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6700) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6701) qla83xx_nic_core_reset(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6703) 	int rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6704) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6706) 	ql_dbg(ql_dbg_p3p, vha, 0xb058,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6707) 	    "Entered  %s().\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6709) 	if (vha->device_flags & DFLG_DEV_FAILED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6710) 		ql_log(ql_log_warn, vha, 0xb059,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6711) 		    "Device in unrecoverable FAILED state.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6712) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6713) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6715) 	qla83xx_idc_lock(vha, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6717) 	if (qla83xx_check_driver_presence(vha) != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6718) 		ql_log(ql_log_warn, vha, 0xb05a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6719) 		    "Function=0x%x has been removed from IDC participation.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6720) 		    ha->portnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6721) 		rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6722) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6723) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6725) 	qla83xx_reset_ownership(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6727) 	rval = qla83xx_initiating_reset(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6729) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6730) 	 * Perform reset if we are the reset-owner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6731) 	 * else wait till IDC state changes to READY/FAILED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6732) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6733) 	if (rval == QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6734) 		rval = qla83xx_idc_state_handler(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6736) 		if (rval == QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6737) 			ha->flags.nic_core_hung = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6738) 		__qla83xx_clear_drv_ack(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6739) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6741) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6742) 	qla83xx_idc_unlock(vha, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6744) 	ql_dbg(ql_dbg_p3p, vha, 0xb05b, "Exiting %s.\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6746) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6749) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6750) qla2xxx_mctp_dump(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6751) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6752) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6753) 	int rval = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6755) 	if (!IS_MCTP_CAPABLE(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6756) 		/* This message can be removed from the final version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6757) 		ql_log(ql_log_info, vha, 0x506d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6758) 		    "This board is not MCTP capable\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6759) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6760) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6762) 	if (!ha->mctp_dump) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6763) 		ha->mctp_dump = dma_alloc_coherent(&ha->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6764) 		    MCTP_DUMP_SIZE, &ha->mctp_dump_dma, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6766) 		if (!ha->mctp_dump) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6767) 			ql_log(ql_log_warn, vha, 0x506e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6768) 			    "Failed to allocate memory for mctp dump\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6769) 			return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6770) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6771) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6773) #define MCTP_DUMP_STR_ADDR	0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6774) 	rval = qla2x00_dump_mctp_data(vha, ha->mctp_dump_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6775) 	    MCTP_DUMP_STR_ADDR, MCTP_DUMP_SIZE/4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6776) 	if (rval != QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6777) 		ql_log(ql_log_warn, vha, 0x506f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6778) 		    "Failed to capture mctp dump\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6779) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6780) 		ql_log(ql_log_info, vha, 0x5070,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6781) 		    "Mctp dump capture for host (%ld/%p).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6782) 		    vha->host_no, ha->mctp_dump);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6783) 		ha->mctp_dumped = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6784) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6786) 	if (!ha->flags.nic_core_reset_hdlr_active && !ha->portnum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6787) 		ha->flags.nic_core_reset_hdlr_active = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6788) 		rval = qla83xx_restart_nic_firmware(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6789) 		if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6790) 			/* NIC Core reset failed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6791) 			ql_log(ql_log_warn, vha, 0x5071,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6792) 			    "Failed to restart nic firmware\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6793) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6794) 			ql_dbg(ql_dbg_p3p, vha, 0xb084,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6795) 			    "Restarted NIC firmware successfully.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6796) 		ha->flags.nic_core_reset_hdlr_active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6797) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6799) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6803) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6804) * qla2x00_quiesce_io
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6805) * Description: This function will block the new I/Os
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6806) *              Its not aborting any I/Os as context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6807) *              is not destroyed during quiescence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6808) * Arguments: scsi_qla_host_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6809) * return   : void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6810) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6811) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6812) qla2x00_quiesce_io(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6813) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6814) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6815) 	struct scsi_qla_host *vp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6817) 	ql_dbg(ql_dbg_dpc, vha, 0x401d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6818) 	    "Quiescing I/O - ha=%p.\n", ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6820) 	atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6821) 	if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6822) 		atomic_set(&vha->loop_state, LOOP_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6823) 		qla2x00_mark_all_devices_lost(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6824) 		list_for_each_entry(vp, &ha->vp_list, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6825) 			qla2x00_mark_all_devices_lost(vp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6826) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6827) 		if (!atomic_read(&vha->loop_down_timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6828) 			atomic_set(&vha->loop_down_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6829) 					LOOP_DOWN_TIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6830) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6831) 	/* Wait for pending cmds to complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6832) 	WARN_ON_ONCE(qla2x00_eh_wait_for_pending_commands(vha, 0, 0, WAIT_HOST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6833) 		     != QLA_SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6836) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6837) qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6838) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6839) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6840) 	struct scsi_qla_host *vp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6841) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6842) 	fc_port_t *fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6843) 	u16 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6845) 	/* For ISP82XX, driver waits for completion of the commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6846) 	 * online flag should be set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6847) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6848) 	if (!(IS_P3P_TYPE(ha)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6849) 		vha->flags.online = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6850) 	ha->flags.chip_reset_done = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6851) 	clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6852) 	vha->qla_stats.total_isp_aborts++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6854) 	ql_log(ql_log_info, vha, 0x00af,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6855) 	    "Performing ISP error recovery - ha=%p.\n", ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6857) 	ha->flags.purge_mbox = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6858) 	/* For ISP82XX, reset_chip is just disabling interrupts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6859) 	 * Driver waits for the completion of the commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6860) 	 * the interrupts need to be enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6861) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6862) 	if (!(IS_P3P_TYPE(ha)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6863) 		ha->isp_ops->reset_chip(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6865) 	ha->link_data_rate = PORT_SPEED_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6866) 	SAVE_TOPO(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6867) 	ha->flags.rida_fmt2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6868) 	ha->flags.n2n_ae = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6869) 	ha->flags.lip_ae = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6870) 	ha->current_topology = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6871) 	QLA_FW_STOPPED(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6872) 	ha->flags.fw_init_done = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6873) 	ha->chip_reset++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6874) 	ha->base_qpair->chip_reset = ha->chip_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6875) 	for (i = 0; i < ha->max_qpairs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6876) 		if (ha->queue_pair_map[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6877) 			ha->queue_pair_map[i]->chip_reset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6878) 				ha->base_qpair->chip_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6879) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6881) 	/* purge MBox commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6882) 	if (atomic_read(&ha->num_pend_mbx_stage3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6883) 		clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6884) 		complete(&ha->mbx_intr_comp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6885) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6887) 	i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6888) 	while (atomic_read(&ha->num_pend_mbx_stage3) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6889) 	    atomic_read(&ha->num_pend_mbx_stage2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6890) 	    atomic_read(&ha->num_pend_mbx_stage1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6891) 		msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6892) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6893) 		if (i > 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6894) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6895) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6896) 	ha->flags.purge_mbox = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6898) 	atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6899) 	if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6900) 		atomic_set(&vha->loop_state, LOOP_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6901) 		qla2x00_mark_all_devices_lost(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6903) 		spin_lock_irqsave(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6904) 		list_for_each_entry(vp, &ha->vp_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6905) 			atomic_inc(&vp->vref_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6906) 			spin_unlock_irqrestore(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6908) 			qla2x00_mark_all_devices_lost(vp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6910) 			spin_lock_irqsave(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6911) 			atomic_dec(&vp->vref_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6912) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6913) 		spin_unlock_irqrestore(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6914) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6915) 		if (!atomic_read(&vha->loop_down_timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6916) 			atomic_set(&vha->loop_down_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6917) 			    LOOP_DOWN_TIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6918) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6920) 	/* Clear all async request states across all VPs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6921) 	list_for_each_entry(fcport, &vha->vp_fcports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6922) 		fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6923) 		fcport->scan_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6924) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6925) 	spin_lock_irqsave(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6926) 	list_for_each_entry(vp, &ha->vp_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6927) 		atomic_inc(&vp->vref_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6928) 		spin_unlock_irqrestore(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6930) 		list_for_each_entry(fcport, &vp->vp_fcports, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6931) 			fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6933) 		spin_lock_irqsave(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6934) 		atomic_dec(&vp->vref_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6935) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6936) 	spin_unlock_irqrestore(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6938) 	if (!ha->flags.eeh_busy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6939) 		/* Make sure for ISP 82XX IO DMA is complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6940) 		if (IS_P3P_TYPE(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6941) 			qla82xx_chip_reset_cleanup(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6942) 			ql_log(ql_log_info, vha, 0x00b4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6943) 			    "Done chip reset cleanup.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6945) 			/* Done waiting for pending commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6946) 			 * Reset the online flag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6947) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6948) 			vha->flags.online = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6949) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6951) 		/* Requeue all commands in outstanding command list. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6952) 		qla2x00_abort_all_cmds(vha, DID_RESET << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6953) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6954) 	/* memory barrier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6955) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6958) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6959) *  qla2x00_abort_isp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6960) *      Resets ISP and aborts all outstanding commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6961) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6962) * Input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6963) *      ha           = adapter block pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6964) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6965) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6966) *      0 = success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6967) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6968) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6969) qla2x00_abort_isp(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6970) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6971) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6972) 	uint8_t        status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6973) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6974) 	struct scsi_qla_host *vp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6975) 	struct req_que *req = ha->req_q_map[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6976) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6978) 	if (vha->flags.online) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6979) 		qla2x00_abort_isp_cleanup(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6981) 		if (test_and_clear_bit(ISP_ABORT_TO_ROM, &vha->dpc_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6982) 			ha->flags.chip_reset_done = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6983) 			vha->flags.online = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6984) 			status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6985) 			clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6986) 			return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6987) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6989) 		if (IS_QLA8031(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6990) 			ql_dbg(ql_dbg_p3p, vha, 0xb05c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6991) 			    "Clearing fcoe driver presence.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6992) 			if (qla83xx_clear_drv_presence(vha) != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6993) 				ql_dbg(ql_dbg_p3p, vha, 0xb073,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6994) 				    "Error while clearing DRV-Presence.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6995) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6997) 		if (unlikely(pci_channel_offline(ha->pdev) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6998) 		    ha->flags.pci_channel_io_perm_failure)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6999) 			clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7000) 			status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7001) 			return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7002) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7003) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7004) 		switch (vha->qlini_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7005) 		case QLA2XXX_INI_MODE_DISABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7006) 			if (!qla_tgt_mode_enabled(vha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7007) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7008) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7009) 		case QLA2XXX_INI_MODE_DUAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7010) 			if (!qla_dual_mode_enabled(vha) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7011) 			    !qla_ini_mode_enabled(vha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7012) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7013) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7014) 		case QLA2XXX_INI_MODE_ENABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7015) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7016) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7017) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7019) 		ha->isp_ops->get_flash_version(vha, req->ring);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7021) 		ha->isp_ops->nvram_config(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7023) 		if (!qla2x00_restart_isp(vha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7024) 			clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7026) 			if (!atomic_read(&vha->loop_down_timer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7027) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7028) 				 * Issue marker command only when we are going
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7029) 				 * to start the I/O .
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7030) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7031) 				vha->marker_needed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7032) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7034) 			vha->flags.online = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7036) 			ha->isp_ops->enable_intrs(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7038) 			ha->isp_abort_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7039) 			clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7041) 			if (IS_QLA81XX(ha) || IS_QLA8031(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7042) 				qla2x00_get_fw_version(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7043) 			if (ha->fce) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7044) 				ha->flags.fce_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7045) 				memset(ha->fce, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7046) 				    fce_calc_size(ha->fce_bufs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7047) 				rval = qla2x00_enable_fce_trace(vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7048) 				    ha->fce_dma, ha->fce_bufs, ha->fce_mb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7049) 				    &ha->fce_bufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7050) 				if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7051) 					ql_log(ql_log_warn, vha, 0x8033,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7052) 					    "Unable to reinitialize FCE "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7053) 					    "(%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7054) 					ha->flags.fce_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7055) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7056) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7058) 			if (ha->eft) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7059) 				memset(ha->eft, 0, EFT_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7060) 				rval = qla2x00_enable_eft_trace(vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7061) 				    ha->eft_dma, EFT_NUM_BUFFERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7062) 				if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7063) 					ql_log(ql_log_warn, vha, 0x8034,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7064) 					    "Unable to reinitialize EFT "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7065) 					    "(%d).\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7066) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7067) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7068) 		} else {	/* failed the ISP abort */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7069) 			vha->flags.online = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7070) 			if (test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7071) 				if (ha->isp_abort_cnt == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7072) 					ql_log(ql_log_fatal, vha, 0x8035,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7073) 					    "ISP error recover failed - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7074) 					    "board disabled.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7075) 					/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7076) 					 * The next call disables the board
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7077) 					 * completely.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7078) 					 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7079) 					qla2x00_abort_isp_cleanup(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7080) 					vha->flags.online = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7081) 					clear_bit(ISP_ABORT_RETRY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7082) 					    &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7083) 					status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7084) 				} else { /* schedule another ISP abort */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7085) 					ha->isp_abort_cnt--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7086) 					ql_dbg(ql_dbg_taskm, vha, 0x8020,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7087) 					    "ISP abort - retry remaining %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7088) 					    ha->isp_abort_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7089) 					status = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7090) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7091) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7092) 				ha->isp_abort_cnt = MAX_RETRIES_OF_ISP_ABORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7093) 				ql_dbg(ql_dbg_taskm, vha, 0x8021,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7094) 				    "ISP error recovery - retrying (%d) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7095) 				    "more times.\n", ha->isp_abort_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7096) 				set_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7097) 				status = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7098) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7099) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7101) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7103) 	if (!status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7104) 		ql_dbg(ql_dbg_taskm, vha, 0x8022, "%s succeeded.\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7105) 		qla2x00_configure_hba(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7106) 		spin_lock_irqsave(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7107) 		list_for_each_entry(vp, &ha->vp_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7108) 			if (vp->vp_idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7109) 				atomic_inc(&vp->vref_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7110) 				spin_unlock_irqrestore(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7112) 				qla2x00_vp_abort_isp(vp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7114) 				spin_lock_irqsave(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7115) 				atomic_dec(&vp->vref_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7116) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7117) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7118) 		spin_unlock_irqrestore(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7120) 		if (IS_QLA8031(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7121) 			ql_dbg(ql_dbg_p3p, vha, 0xb05d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7122) 			    "Setting back fcoe driver presence.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7123) 			if (qla83xx_set_drv_presence(vha) != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7124) 				ql_dbg(ql_dbg_p3p, vha, 0xb074,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7125) 				    "Error while setting DRV-Presence.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7126) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7127) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7128) 		ql_log(ql_log_warn, vha, 0x8023, "%s **** FAILED ****.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7129) 		       __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7130) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7132) 	return(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7135) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7136) *  qla2x00_restart_isp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7137) *      restarts the ISP after a reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7138) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7139) * Input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7140) *      ha = adapter block pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7141) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7142) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7143) *      0 = success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7144) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7145) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7146) qla2x00_restart_isp(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7148) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7149) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7151) 	/* If firmware needs to be loaded */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7152) 	if (qla2x00_isp_firmware(vha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7153) 		vha->flags.online = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7154) 		status = ha->isp_ops->chip_diag(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7155) 		if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7156) 			return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7157) 		status = qla2x00_setup_chip(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7158) 		if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7159) 			return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7160) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7162) 	status = qla2x00_init_rings(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7163) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7164) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7166) 	clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7167) 	ha->flags.chip_reset_done = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7169) 	/* Initialize the queues in use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7170) 	qla25xx_init_queues(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7172) 	status = qla2x00_fw_ready(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7173) 	if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7174) 		/* if no cable then assume it's good */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7175) 		return vha->device_flags & DFLG_NO_CABLE ? 0 : status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7176) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7178) 	/* Issue a marker after FW becomes ready. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7179) 	qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7180) 	set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7182) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7185) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7186) qla25xx_init_queues(struct qla_hw_data *ha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7188) 	struct rsp_que *rsp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7189) 	struct req_que *req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7190) 	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7191) 	int ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7192) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7194) 	for (i = 1; i < ha->max_rsp_queues; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7195) 		rsp = ha->rsp_q_map[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7196) 		if (rsp && test_bit(i, ha->rsp_qid_map)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7197) 			rsp->options &= ~BIT_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7198) 			ret = qla25xx_init_rsp_que(base_vha, rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7199) 			if (ret != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7200) 				ql_dbg(ql_dbg_init, base_vha, 0x00ff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7201) 				    "%s Rsp que: %d init failed.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7202) 				    __func__, rsp->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7203) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7204) 				ql_dbg(ql_dbg_init, base_vha, 0x0100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7205) 				    "%s Rsp que: %d inited.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7206) 				    __func__, rsp->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7207) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7208) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7209) 	for (i = 1; i < ha->max_req_queues; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7210) 		req = ha->req_q_map[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7211) 		if (req && test_bit(i, ha->req_qid_map)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7212) 			/* Clear outstanding commands array. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7213) 			req->options &= ~BIT_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7214) 			ret = qla25xx_init_req_que(base_vha, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7215) 			if (ret != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7216) 				ql_dbg(ql_dbg_init, base_vha, 0x0101,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7217) 				    "%s Req que: %d init failed.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7218) 				    __func__, req->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7219) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7220) 				ql_dbg(ql_dbg_init, base_vha, 0x0102,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7221) 				    "%s Req que: %d inited.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7222) 				    __func__, req->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7223) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7224) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7225) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7228) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7229) * qla2x00_reset_adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7230) *      Reset adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7231) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7232) * Input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7233) *      ha = adapter block pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7234) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7235) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7236) qla2x00_reset_adapter(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7238) 	unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7239) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7240) 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7242) 	vha->flags.online = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7243) 	ha->isp_ops->disable_intrs(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7245) 	spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7246) 	wrt_reg_word(&reg->hccr, HCCR_RESET_RISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7247) 	rd_reg_word(&reg->hccr);			/* PCI Posting. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7248) 	wrt_reg_word(&reg->hccr, HCCR_RELEASE_RISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7249) 	rd_reg_word(&reg->hccr);			/* PCI Posting. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7250) 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7252) 	return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7255) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7256) qla24xx_reset_adapter(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7258) 	unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7259) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7260) 	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7262) 	if (IS_P3P_TYPE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7263) 		return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7265) 	vha->flags.online = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7266) 	ha->isp_ops->disable_intrs(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7268) 	spin_lock_irqsave(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7269) 	wrt_reg_dword(&reg->hccr, HCCRX_SET_RISC_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7270) 	rd_reg_dword(&reg->hccr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7271) 	wrt_reg_dword(&reg->hccr, HCCRX_REL_RISC_PAUSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7272) 	rd_reg_dword(&reg->hccr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7273) 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7275) 	if (IS_NOPOLLING_TYPE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7276) 		ha->isp_ops->enable_intrs(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7278) 	return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7281) /* On sparc systems, obtain port and node WWN from firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7282)  * properties.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7283)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7284) static void qla24xx_nvram_wwn_from_ofw(scsi_qla_host_t *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7285) 	struct nvram_24xx *nv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7287) #ifdef CONFIG_SPARC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7288) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7289) 	struct pci_dev *pdev = ha->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7290) 	struct device_node *dp = pci_device_to_OF_node(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7291) 	const u8 *val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7292) 	int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7294) 	val = of_get_property(dp, "port-wwn", &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7295) 	if (val && len >= WWN_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7296) 		memcpy(nv->port_name, val, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7298) 	val = of_get_property(dp, "node-wwn", &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7299) 	if (val && len >= WWN_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7300) 		memcpy(nv->node_name, val, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7301) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7304) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7305) qla24xx_nvram_config(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7307) 	int   rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7308) 	struct init_cb_24xx *icb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7309) 	struct nvram_24xx *nv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7310) 	__le32 *dptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7311) 	uint8_t  *dptr1, *dptr2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7312) 	uint32_t chksum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7313) 	uint16_t cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7314) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7316) 	rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7317) 	icb = (struct init_cb_24xx *)ha->init_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7318) 	nv = ha->nvram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7320) 	/* Determine NVRAM starting address. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7321) 	if (ha->port_no == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7322) 		ha->nvram_base = FA_NVRAM_FUNC0_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7323) 		ha->vpd_base = FA_NVRAM_VPD0_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7324) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7325) 		ha->nvram_base = FA_NVRAM_FUNC1_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7326) 		ha->vpd_base = FA_NVRAM_VPD1_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7327) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7329) 	ha->nvram_size = sizeof(*nv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7330) 	ha->vpd_size = FA_NVRAM_VPD_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7332) 	/* Get VPD data into cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7333) 	ha->vpd = ha->nvram + VPD_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7334) 	ha->isp_ops->read_nvram(vha, ha->vpd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7335) 	    ha->nvram_base - FA_NVRAM_FUNC0_ADDR, FA_NVRAM_VPD_SIZE * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7337) 	/* Get NVRAM data into cache and calculate checksum. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7338) 	dptr = (__force __le32 *)nv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7339) 	ha->isp_ops->read_nvram(vha, dptr, ha->nvram_base, ha->nvram_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7340) 	for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++, dptr++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7341) 		chksum += le32_to_cpu(*dptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7343) 	ql_dbg(ql_dbg_init + ql_dbg_buffer, vha, 0x006a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7344) 	    "Contents of NVRAM\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7345) 	ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x010d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7346) 	    nv, ha->nvram_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7348) 	/* Bad NVRAM data, set defaults parameters. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7349) 	if (chksum || memcmp("ISP ", nv->id, sizeof(nv->id)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7350) 	    le16_to_cpu(nv->nvram_version) < ICB_VERSION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7351) 		/* Reset NVRAM data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7352) 		ql_log(ql_log_warn, vha, 0x006b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7353) 		    "Inconsistent NVRAM checksum=%#x id=%.4s version=%#x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7354) 		    chksum, nv->id, nv->nvram_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7355) 		ql_dump_buffer(ql_dbg_init, vha, 0x006b, nv, sizeof(*nv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7356) 		ql_log(ql_log_warn, vha, 0x006c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7357) 		    "Falling back to functioning (yet invalid -- WWPN) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7358) 		    "defaults.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7360) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7361) 		 * Set default initialization control block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7362) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7363) 		memset(nv, 0, ha->nvram_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7364) 		nv->nvram_version = cpu_to_le16(ICB_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7365) 		nv->version = cpu_to_le16(ICB_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7366) 		nv->frame_payload_size = cpu_to_le16(2048);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7367) 		nv->execution_throttle = cpu_to_le16(0xFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7368) 		nv->exchange_count = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7369) 		nv->hard_address = cpu_to_le16(124);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7370) 		nv->port_name[0] = 0x21;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7371) 		nv->port_name[1] = 0x00 + ha->port_no + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7372) 		nv->port_name[2] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7373) 		nv->port_name[3] = 0xe0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7374) 		nv->port_name[4] = 0x8b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7375) 		nv->port_name[5] = 0x1c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7376) 		nv->port_name[6] = 0x55;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7377) 		nv->port_name[7] = 0x86;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7378) 		nv->node_name[0] = 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7379) 		nv->node_name[1] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7380) 		nv->node_name[2] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7381) 		nv->node_name[3] = 0xe0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7382) 		nv->node_name[4] = 0x8b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7383) 		nv->node_name[5] = 0x1c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7384) 		nv->node_name[6] = 0x55;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7385) 		nv->node_name[7] = 0x86;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7386) 		qla24xx_nvram_wwn_from_ofw(vha, nv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7387) 		nv->login_retry_count = cpu_to_le16(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7388) 		nv->interrupt_delay_timer = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7389) 		nv->login_timeout = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7390) 		nv->firmware_options_1 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7391) 		    cpu_to_le32(BIT_14|BIT_13|BIT_2|BIT_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7392) 		nv->firmware_options_2 = cpu_to_le32(2 << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7393) 		nv->firmware_options_2 |= cpu_to_le32(BIT_12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7394) 		nv->firmware_options_3 = cpu_to_le32(2 << 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7395) 		nv->host_p = cpu_to_le32(BIT_11|BIT_10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7396) 		nv->efi_parameters = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7397) 		nv->reset_delay = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7398) 		nv->max_luns_per_target = cpu_to_le16(128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7399) 		nv->port_down_retry_count = cpu_to_le16(30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7400) 		nv->link_down_timeout = cpu_to_le16(30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7402) 		rval = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7403) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7405) 	if (qla_tgt_mode_enabled(vha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7406) 		/* Don't enable full login after initial LIP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7407) 		nv->firmware_options_1 &= cpu_to_le32(~BIT_13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7408) 		/* Don't enable LIP full login for initiator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7409) 		nv->host_p &= cpu_to_le32(~BIT_10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7410) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7412) 	qlt_24xx_config_nvram_stage1(vha, nv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7414) 	/* Reset Initialization control block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7415) 	memset(icb, 0, ha->init_cb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7417) 	/* Copy 1st segment. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7418) 	dptr1 = (uint8_t *)icb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7419) 	dptr2 = (uint8_t *)&nv->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7420) 	cnt = (uint8_t *)&icb->response_q_inpointer - (uint8_t *)&icb->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7421) 	while (cnt--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7422) 		*dptr1++ = *dptr2++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7424) 	icb->login_retry_count = nv->login_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7425) 	icb->link_down_on_nos = nv->link_down_on_nos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7427) 	/* Copy 2nd segment. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7428) 	dptr1 = (uint8_t *)&icb->interrupt_delay_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7429) 	dptr2 = (uint8_t *)&nv->interrupt_delay_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7430) 	cnt = (uint8_t *)&icb->reserved_3 -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7431) 	    (uint8_t *)&icb->interrupt_delay_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7432) 	while (cnt--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7433) 		*dptr1++ = *dptr2++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7434) 	ha->frame_payload_size = le16_to_cpu(icb->frame_payload_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7435) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7436) 	 * Setup driver NVRAM options.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7437) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7438) 	qla2x00_set_model_info(vha, nv->model_name, sizeof(nv->model_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7439) 	    "QLA2462");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7441) 	qlt_24xx_config_nvram_stage2(vha, icb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7443) 	if (nv->host_p & cpu_to_le32(BIT_15)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7444) 		/* Use alternate WWN? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7445) 		memcpy(icb->node_name, nv->alternate_node_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7446) 		memcpy(icb->port_name, nv->alternate_port_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7447) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7449) 	/* Prepare nodename */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7450) 	if ((icb->firmware_options_1 & cpu_to_le32(BIT_14)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7451) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7452) 		 * Firmware will apply the following mask if the nodename was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7453) 		 * not provided.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7454) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7455) 		memcpy(icb->node_name, icb->port_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7456) 		icb->node_name[0] &= 0xF0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7457) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7459) 	/* Set host adapter parameters. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7460) 	ha->flags.disable_risc_code_load = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7461) 	ha->flags.enable_lip_reset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7462) 	ha->flags.enable_lip_full_login =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7463) 	    le32_to_cpu(nv->host_p) & BIT_10 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7464) 	ha->flags.enable_target_reset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7465) 	    le32_to_cpu(nv->host_p) & BIT_11 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7466) 	ha->flags.enable_led_scheme = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7467) 	ha->flags.disable_serdes = le32_to_cpu(nv->host_p) & BIT_5 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7469) 	ha->operating_mode = (le32_to_cpu(icb->firmware_options_2) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7470) 	    (BIT_6 | BIT_5 | BIT_4)) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7472) 	memcpy(ha->fw_seriallink_options24, nv->seriallink_options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7473) 	    sizeof(ha->fw_seriallink_options24));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7475) 	/* save HBA serial number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7476) 	ha->serial0 = icb->port_name[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7477) 	ha->serial1 = icb->port_name[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7478) 	ha->serial2 = icb->port_name[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7479) 	memcpy(vha->node_name, icb->node_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7480) 	memcpy(vha->port_name, icb->port_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7482) 	icb->execution_throttle = cpu_to_le16(0xFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7484) 	ha->retry_count = le16_to_cpu(nv->login_retry_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7486) 	/* Set minimum login_timeout to 4 seconds. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7487) 	if (le16_to_cpu(nv->login_timeout) < ql2xlogintimeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7488) 		nv->login_timeout = cpu_to_le16(ql2xlogintimeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7489) 	if (le16_to_cpu(nv->login_timeout) < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7490) 		nv->login_timeout = cpu_to_le16(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7491) 	ha->login_timeout = le16_to_cpu(nv->login_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7493) 	/* Set minimum RATOV to 100 tenths of a second. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7494) 	ha->r_a_tov = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7496) 	ha->loop_reset_delay = nv->reset_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7498) 	/* Link Down Timeout = 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7499) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7500) 	 * 	When Port Down timer expires we will start returning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7501) 	 *	I/O's to OS with "DID_NO_CONNECT".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7502) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7503) 	 * Link Down Timeout != 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7504) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7505) 	 *	 The driver waits for the link to come up after link down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7506) 	 *	 before returning I/Os to OS with "DID_NO_CONNECT".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7507) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7508) 	if (le16_to_cpu(nv->link_down_timeout) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7509) 		ha->loop_down_abort_time =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7510) 		    (LOOP_DOWN_TIME - LOOP_DOWN_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7511) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7512) 		ha->link_down_timeout =	le16_to_cpu(nv->link_down_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7513) 		ha->loop_down_abort_time =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7514) 		    (LOOP_DOWN_TIME - ha->link_down_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7515) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7517) 	/* Need enough time to try and get the port back. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7518) 	ha->port_down_retry_count = le16_to_cpu(nv->port_down_retry_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7519) 	if (qlport_down_retry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7520) 		ha->port_down_retry_count = qlport_down_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7522) 	/* Set login_retry_count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7523) 	ha->login_retry_count  = le16_to_cpu(nv->login_retry_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7524) 	if (ha->port_down_retry_count ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7525) 	    le16_to_cpu(nv->port_down_retry_count) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7526) 	    ha->port_down_retry_count > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7527) 		ha->login_retry_count = ha->port_down_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7528) 	else if (ha->port_down_retry_count > (int)ha->login_retry_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7529) 		ha->login_retry_count = ha->port_down_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7530) 	if (ql2xloginretrycount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7531) 		ha->login_retry_count = ql2xloginretrycount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7533) 	/* N2N: driver will initiate Login instead of FW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7534) 	icb->firmware_options_3 |= cpu_to_le32(BIT_8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7536) 	/* Enable ZIO. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7537) 	if (!vha->flags.init_done) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7538) 		ha->zio_mode = le32_to_cpu(icb->firmware_options_2) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7539) 		    (BIT_3 | BIT_2 | BIT_1 | BIT_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7540) 		ha->zio_timer = le16_to_cpu(icb->interrupt_delay_timer) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7541) 		    le16_to_cpu(icb->interrupt_delay_timer) : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7542) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7543) 	icb->firmware_options_2 &= cpu_to_le32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7544) 	    ~(BIT_3 | BIT_2 | BIT_1 | BIT_0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7545) 	if (ha->zio_mode != QLA_ZIO_DISABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7546) 		ha->zio_mode = QLA_ZIO_MODE_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7548) 		ql_log(ql_log_info, vha, 0x006f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7549) 		    "ZIO mode %d enabled; timer delay (%d us).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7550) 		    ha->zio_mode, ha->zio_timer * 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7552) 		icb->firmware_options_2 |= cpu_to_le32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7553) 		    (uint32_t)ha->zio_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7554) 		icb->interrupt_delay_timer = cpu_to_le16(ha->zio_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7555) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7557) 	if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7558) 		ql_log(ql_log_warn, vha, 0x0070,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7559) 		    "NVRAM configuration failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7560) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7561) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7564) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7565) qla27xx_print_image(struct scsi_qla_host *vha, char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7566)     struct qla27xx_image_status *image_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7568) 	ql_dbg(ql_dbg_init, vha, 0x018b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7569) 	    "%s %s: mask=%#02x gen=%#04x ver=%u.%u map=%#01x sum=%#08x sig=%#08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7570) 	    name, "status",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7571) 	    image_status->image_status_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7572) 	    le16_to_cpu(image_status->generation),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7573) 	    image_status->ver_major,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7574) 	    image_status->ver_minor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7575) 	    image_status->bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7576) 	    le32_to_cpu(image_status->checksum),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7577) 	    le32_to_cpu(image_status->signature));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7580) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7581) qla28xx_check_aux_image_status_signature(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7582)     struct qla27xx_image_status *image_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7584) 	ulong signature = le32_to_cpu(image_status->signature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7586) 	return signature != QLA28XX_AUX_IMG_STATUS_SIGN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7589) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7590) qla27xx_check_image_status_signature(struct qla27xx_image_status *image_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7592) 	ulong signature = le32_to_cpu(image_status->signature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7594) 	return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7595) 	    signature != QLA27XX_IMG_STATUS_SIGN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7596) 	    signature != QLA28XX_IMG_STATUS_SIGN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7599) static ulong
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7600) qla27xx_image_status_checksum(struct qla27xx_image_status *image_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7602) 	__le32 *p = (__force __le32 *)image_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7603) 	uint n = sizeof(*image_status) / sizeof(*p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7604) 	uint32_t sum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7606) 	for ( ; n--; p++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7607) 		sum += le32_to_cpup(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7609) 	return sum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7612) static inline uint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7613) qla28xx_component_bitmask(struct qla27xx_image_status *aux, uint bitmask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7615) 	return aux->bitmap & bitmask ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7616) 	    QLA27XX_SECONDARY_IMAGE : QLA27XX_PRIMARY_IMAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7619) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7620) qla28xx_component_status(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7621)     struct active_regions *active_regions, struct qla27xx_image_status *aux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7623) 	active_regions->aux.board_config =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7624) 	    qla28xx_component_bitmask(aux, QLA28XX_AUX_IMG_BOARD_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7626) 	active_regions->aux.vpd_nvram =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7627) 	    qla28xx_component_bitmask(aux, QLA28XX_AUX_IMG_VPD_NVRAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7629) 	active_regions->aux.npiv_config_0_1 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7630) 	    qla28xx_component_bitmask(aux, QLA28XX_AUX_IMG_NPIV_CONFIG_0_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7632) 	active_regions->aux.npiv_config_2_3 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7633) 	    qla28xx_component_bitmask(aux, QLA28XX_AUX_IMG_NPIV_CONFIG_2_3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7636) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7637) qla27xx_compare_image_generation(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7638)     struct qla27xx_image_status *pri_image_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7639)     struct qla27xx_image_status *sec_image_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7641) 	/* calculate generation delta as uint16 (this accounts for wrap) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7642) 	int16_t delta =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7643) 	    le16_to_cpu(pri_image_status->generation) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7644) 	    le16_to_cpu(sec_image_status->generation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7646) 	ql_dbg(ql_dbg_init, NULL, 0x0180, "generation delta = %d\n", delta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7648) 	return delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7651) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7652) qla28xx_get_aux_images(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7653) 	struct scsi_qla_host *vha, struct active_regions *active_regions)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7655) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7656) 	struct qla27xx_image_status pri_aux_image_status, sec_aux_image_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7657) 	bool valid_pri_image = false, valid_sec_image = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7658) 	bool active_pri_image = false, active_sec_image = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7660) 	if (!ha->flt_region_aux_img_status_pri) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7661) 		ql_dbg(ql_dbg_init, vha, 0x018a, "Primary aux image not addressed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7662) 		goto check_sec_image;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7663) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7665) 	qla24xx_read_flash_data(vha, (uint32_t *)&pri_aux_image_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7666) 	    ha->flt_region_aux_img_status_pri,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7667) 	    sizeof(pri_aux_image_status) >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7668) 	qla27xx_print_image(vha, "Primary aux image", &pri_aux_image_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7670) 	if (qla28xx_check_aux_image_status_signature(&pri_aux_image_status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7671) 		ql_dbg(ql_dbg_init, vha, 0x018b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7672) 		    "Primary aux image signature (%#x) not valid\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7673) 		    le32_to_cpu(pri_aux_image_status.signature));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7674) 		goto check_sec_image;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7675) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7677) 	if (qla27xx_image_status_checksum(&pri_aux_image_status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7678) 		ql_dbg(ql_dbg_init, vha, 0x018c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7679) 		    "Primary aux image checksum failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7680) 		goto check_sec_image;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7681) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7683) 	valid_pri_image = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7685) 	if (pri_aux_image_status.image_status_mask & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7686) 		ql_dbg(ql_dbg_init, vha, 0x018d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7687) 		    "Primary aux image is active\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7688) 		active_pri_image = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7689) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7691) check_sec_image:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7692) 	if (!ha->flt_region_aux_img_status_sec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7693) 		ql_dbg(ql_dbg_init, vha, 0x018a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7694) 		    "Secondary aux image not addressed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7695) 		goto check_valid_image;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7696) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7698) 	qla24xx_read_flash_data(vha, (uint32_t *)&sec_aux_image_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7699) 	    ha->flt_region_aux_img_status_sec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7700) 	    sizeof(sec_aux_image_status) >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7701) 	qla27xx_print_image(vha, "Secondary aux image", &sec_aux_image_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7703) 	if (qla28xx_check_aux_image_status_signature(&sec_aux_image_status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7704) 		ql_dbg(ql_dbg_init, vha, 0x018b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7705) 		    "Secondary aux image signature (%#x) not valid\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7706) 		    le32_to_cpu(sec_aux_image_status.signature));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7707) 		goto check_valid_image;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7708) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7710) 	if (qla27xx_image_status_checksum(&sec_aux_image_status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7711) 		ql_dbg(ql_dbg_init, vha, 0x018c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7712) 		    "Secondary aux image checksum failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7713) 		goto check_valid_image;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7714) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7716) 	valid_sec_image = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7718) 	if (sec_aux_image_status.image_status_mask & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7719) 		ql_dbg(ql_dbg_init, vha, 0x018d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7720) 		    "Secondary aux image is active\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7721) 		active_sec_image = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7722) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7724) check_valid_image:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7725) 	if (valid_pri_image && active_pri_image &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7726) 	    valid_sec_image && active_sec_image) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7727) 		if (qla27xx_compare_image_generation(&pri_aux_image_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7728) 		    &sec_aux_image_status) >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7729) 			qla28xx_component_status(active_regions,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7730) 			    &pri_aux_image_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7731) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7732) 			qla28xx_component_status(active_regions,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7733) 			    &sec_aux_image_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7734) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7735) 	} else if (valid_pri_image && active_pri_image) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7736) 		qla28xx_component_status(active_regions, &pri_aux_image_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7737) 	} else if (valid_sec_image && active_sec_image) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7738) 		qla28xx_component_status(active_regions, &sec_aux_image_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7739) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7741) 	ql_dbg(ql_dbg_init, vha, 0x018f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7742) 	    "aux images active: BCFG=%u VPD/NVR=%u NPIV0/1=%u NPIV2/3=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7743) 	    active_regions->aux.board_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7744) 	    active_regions->aux.vpd_nvram,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7745) 	    active_regions->aux.npiv_config_0_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7746) 	    active_regions->aux.npiv_config_2_3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7749) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7750) qla27xx_get_active_image(struct scsi_qla_host *vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7751)     struct active_regions *active_regions)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7752) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7753) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7754) 	struct qla27xx_image_status pri_image_status, sec_image_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7755) 	bool valid_pri_image = false, valid_sec_image = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7756) 	bool active_pri_image = false, active_sec_image = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7758) 	if (!ha->flt_region_img_status_pri) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7759) 		ql_dbg(ql_dbg_init, vha, 0x018a, "Primary image not addressed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7760) 		goto check_sec_image;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7761) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7763) 	if (qla24xx_read_flash_data(vha, (uint32_t *)&pri_image_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7764) 	    ha->flt_region_img_status_pri, sizeof(pri_image_status) >> 2) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7765) 	    QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7766) 		WARN_ON_ONCE(true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7767) 		goto check_sec_image;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7768) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7769) 	qla27xx_print_image(vha, "Primary image", &pri_image_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7771) 	if (qla27xx_check_image_status_signature(&pri_image_status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7772) 		ql_dbg(ql_dbg_init, vha, 0x018b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7773) 		    "Primary image signature (%#x) not valid\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7774) 		    le32_to_cpu(pri_image_status.signature));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7775) 		goto check_sec_image;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7776) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7778) 	if (qla27xx_image_status_checksum(&pri_image_status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7779) 		ql_dbg(ql_dbg_init, vha, 0x018c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7780) 		    "Primary image checksum failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7781) 		goto check_sec_image;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7782) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7784) 	valid_pri_image = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7786) 	if (pri_image_status.image_status_mask & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7787) 		ql_dbg(ql_dbg_init, vha, 0x018d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7788) 		    "Primary image is active\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7789) 		active_pri_image = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7790) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7792) check_sec_image:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7793) 	if (!ha->flt_region_img_status_sec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7794) 		ql_dbg(ql_dbg_init, vha, 0x018a, "Secondary image not addressed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7795) 		goto check_valid_image;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7796) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7798) 	qla24xx_read_flash_data(vha, (uint32_t *)(&sec_image_status),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7799) 	    ha->flt_region_img_status_sec, sizeof(sec_image_status) >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7800) 	qla27xx_print_image(vha, "Secondary image", &sec_image_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7802) 	if (qla27xx_check_image_status_signature(&sec_image_status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7803) 		ql_dbg(ql_dbg_init, vha, 0x018b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7804) 		    "Secondary image signature (%#x) not valid\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7805) 		    le32_to_cpu(sec_image_status.signature));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7806) 		goto check_valid_image;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7807) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7809) 	if (qla27xx_image_status_checksum(&sec_image_status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7810) 		ql_dbg(ql_dbg_init, vha, 0x018c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7811) 		    "Secondary image checksum failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7812) 		goto check_valid_image;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7813) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7815) 	valid_sec_image = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7817) 	if (sec_image_status.image_status_mask & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7818) 		ql_dbg(ql_dbg_init, vha, 0x018d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7819) 		    "Secondary image is active\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7820) 		active_sec_image = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7821) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7823) check_valid_image:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7824) 	if (valid_pri_image && active_pri_image)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7825) 		active_regions->global = QLA27XX_PRIMARY_IMAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7827) 	if (valid_sec_image && active_sec_image) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7828) 		if (!active_regions->global ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7829) 		    qla27xx_compare_image_generation(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7830) 			&pri_image_status, &sec_image_status) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7831) 			active_regions->global = QLA27XX_SECONDARY_IMAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7832) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7833) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7835) 	ql_dbg(ql_dbg_init, vha, 0x018f, "active image %s (%u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7836) 	    active_regions->global == QLA27XX_DEFAULT_IMAGE ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7837) 		"default (boot/fw)" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7838) 	    active_regions->global == QLA27XX_PRIMARY_IMAGE ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7839) 		"primary" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7840) 	    active_regions->global == QLA27XX_SECONDARY_IMAGE ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7841) 		"secondary" : "invalid",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7842) 	    active_regions->global);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7845) bool qla24xx_risc_firmware_invalid(uint32_t *dword)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7846) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7847) 	return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7848) 	    !(dword[4] | dword[5] | dword[6] | dword[7]) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7849) 	    !(~dword[4] | ~dword[5] | ~dword[6] | ~dword[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7852) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7853) qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7854)     uint32_t faddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7855) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7856) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7857) 	uint templates, segments, fragment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7858) 	ulong i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7859) 	uint j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7860) 	ulong dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7861) 	uint32_t *dcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7862) 	uint32_t risc_addr, risc_size, risc_attr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7863) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7864) 	struct req_que *req = ha->req_q_map[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7865) 	struct fwdt *fwdt = ha->fwdt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7867) 	ql_dbg(ql_dbg_init, vha, 0x008b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7868) 	    "FW: Loading firmware from flash (%x).\n", faddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7870) 	dcode = (uint32_t *)req->ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7871) 	qla24xx_read_flash_data(vha, dcode, faddr, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7872) 	if (qla24xx_risc_firmware_invalid(dcode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7873) 		ql_log(ql_log_fatal, vha, 0x008c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7874) 		    "Unable to verify the integrity of flash firmware "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7875) 		    "image.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7876) 		ql_log(ql_log_fatal, vha, 0x008d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7877) 		    "Firmware data: %08x %08x %08x %08x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7878) 		    dcode[0], dcode[1], dcode[2], dcode[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7880) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7881) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7883) 	dcode = (uint32_t *)req->ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7884) 	*srisc_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7885) 	segments = FA_RISC_CODE_SEGMENTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7886) 	for (j = 0; j < segments; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7887) 		ql_dbg(ql_dbg_init, vha, 0x008d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7888) 		    "-> Loading segment %u...\n", j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7889) 		qla24xx_read_flash_data(vha, dcode, faddr, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7890) 		risc_addr = be32_to_cpu((__force __be32)dcode[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7891) 		risc_size = be32_to_cpu((__force __be32)dcode[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7892) 		if (!*srisc_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7893) 			*srisc_addr = risc_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7894) 			risc_attr = be32_to_cpu((__force __be32)dcode[9]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7895) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7897) 		dlen = ha->fw_transfer_size >> 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7898) 		for (fragment = 0; risc_size; fragment++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7899) 			if (dlen > risc_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7900) 				dlen = risc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7902) 			ql_dbg(ql_dbg_init, vha, 0x008e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7903) 			    "-> Loading fragment %u: %#x <- %#x (%#lx dwords)...\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7904) 			    fragment, risc_addr, faddr, dlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7905) 			qla24xx_read_flash_data(vha, dcode, faddr, dlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7906) 			for (i = 0; i < dlen; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7907) 				dcode[i] = swab32(dcode[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7909) 			rval = qla2x00_load_ram(vha, req->dma, risc_addr, dlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7910) 			if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7911) 				ql_log(ql_log_fatal, vha, 0x008f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7912) 				    "-> Failed load firmware fragment %u.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7913) 				    fragment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7914) 				return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7915) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7917) 			faddr += dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7918) 			risc_addr += dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7919) 			risc_size -= dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7920) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7921) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7923) 	if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7924) 		return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7926) 	templates = (risc_attr & BIT_9) ? 2 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7927) 	ql_dbg(ql_dbg_init, vha, 0x0160, "-> templates = %u\n", templates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7928) 	for (j = 0; j < templates; j++, fwdt++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7929) 		if (fwdt->template)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7930) 			vfree(fwdt->template);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7931) 		fwdt->template = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7932) 		fwdt->length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7934) 		dcode = (uint32_t *)req->ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7935) 		qla24xx_read_flash_data(vha, dcode, faddr, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7936) 		risc_size = be32_to_cpu((__force __be32)dcode[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7937) 		ql_dbg(ql_dbg_init, vha, 0x0161,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7938) 		    "-> fwdt%u template array at %#x (%#x dwords)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7939) 		    j, faddr, risc_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7940) 		if (!risc_size || !~risc_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7941) 			ql_dbg(ql_dbg_init, vha, 0x0162,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7942) 			    "-> fwdt%u failed to read array\n", j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7943) 			goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7944) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7946) 		/* skip header and ignore checksum */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7947) 		faddr += 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7948) 		risc_size -= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7950) 		ql_dbg(ql_dbg_init, vha, 0x0163,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7951) 		    "-> fwdt%u template allocate template %#x words...\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7952) 		    j, risc_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7953) 		fwdt->template = vmalloc(risc_size * sizeof(*dcode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7954) 		if (!fwdt->template) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7955) 			ql_log(ql_log_warn, vha, 0x0164,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7956) 			    "-> fwdt%u failed allocate template.\n", j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7957) 			goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7958) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7960) 		dcode = fwdt->template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7961) 		qla24xx_read_flash_data(vha, dcode, faddr, risc_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7963) 		if (!qla27xx_fwdt_template_valid(dcode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7964) 			ql_log(ql_log_warn, vha, 0x0165,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7965) 			    "-> fwdt%u failed template validate\n", j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7966) 			goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7967) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7969) 		dlen = qla27xx_fwdt_template_size(dcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7970) 		ql_dbg(ql_dbg_init, vha, 0x0166,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7971) 		    "-> fwdt%u template size %#lx bytes (%#lx words)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7972) 		    j, dlen, dlen / sizeof(*dcode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7973) 		if (dlen > risc_size * sizeof(*dcode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7974) 			ql_log(ql_log_warn, vha, 0x0167,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7975) 			    "-> fwdt%u template exceeds array (%-lu bytes)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7976) 			    j, dlen - risc_size * sizeof(*dcode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7977) 			goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7978) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7980) 		fwdt->length = dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7981) 		ql_dbg(ql_dbg_init, vha, 0x0168,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7982) 		    "-> fwdt%u loaded template ok\n", j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7984) 		faddr += risc_size + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7985) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7987) 	return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7989) failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7990) 	if (fwdt->template)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7991) 		vfree(fwdt->template);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7992) 	fwdt->template = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7993) 	fwdt->length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7995) 	return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7998) #define QLA_FW_URL "http://ldriver.qlogic.com/firmware/"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8000) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8001) qla2x00_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8002) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8003) 	int	rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8004) 	int	i, fragment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8005) 	uint16_t *wcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8006) 	__be16	 *fwcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8007) 	uint32_t risc_addr, risc_size, fwclen, wlen, *seg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8008) 	struct fw_blob *blob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8009) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8010) 	struct req_que *req = ha->req_q_map[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8012) 	/* Load firmware blob. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8013) 	blob = qla2x00_request_firmware(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8014) 	if (!blob) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8015) 		ql_log(ql_log_info, vha, 0x0083,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8016) 		    "Firmware image unavailable.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8017) 		ql_log(ql_log_info, vha, 0x0084,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8018) 		    "Firmware images can be retrieved from: "QLA_FW_URL ".\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8019) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8020) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8022) 	rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8024) 	wcode = (uint16_t *)req->ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8025) 	*srisc_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8026) 	fwcode = (__force __be16 *)blob->fw->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8027) 	fwclen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8029) 	/* Validate firmware image by checking version. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8030) 	if (blob->fw->size < 8 * sizeof(uint16_t)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8031) 		ql_log(ql_log_fatal, vha, 0x0085,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8032) 		    "Unable to verify integrity of firmware image (%zd).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8033) 		    blob->fw->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8034) 		goto fail_fw_integrity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8035) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8036) 	for (i = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8037) 		wcode[i] = be16_to_cpu(fwcode[i + 4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8038) 	if ((wcode[0] == 0xffff && wcode[1] == 0xffff && wcode[2] == 0xffff &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8039) 	    wcode[3] == 0xffff) || (wcode[0] == 0 && wcode[1] == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8040) 		wcode[2] == 0 && wcode[3] == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8041) 		ql_log(ql_log_fatal, vha, 0x0086,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8042) 		    "Unable to verify integrity of firmware image.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8043) 		ql_log(ql_log_fatal, vha, 0x0087,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8044) 		    "Firmware data: %04x %04x %04x %04x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8045) 		    wcode[0], wcode[1], wcode[2], wcode[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8046) 		goto fail_fw_integrity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8047) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8049) 	seg = blob->segs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8050) 	while (*seg && rval == QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8051) 		risc_addr = *seg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8052) 		*srisc_addr = *srisc_addr == 0 ? *seg : *srisc_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8053) 		risc_size = be16_to_cpu(fwcode[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8055) 		/* Validate firmware image size. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8056) 		fwclen += risc_size * sizeof(uint16_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8057) 		if (blob->fw->size < fwclen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8058) 			ql_log(ql_log_fatal, vha, 0x0088,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8059) 			    "Unable to verify integrity of firmware image "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8060) 			    "(%zd).\n", blob->fw->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8061) 			goto fail_fw_integrity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8062) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8064) 		fragment = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8065) 		while (risc_size > 0 && rval == QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8066) 			wlen = (uint16_t)(ha->fw_transfer_size >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8067) 			if (wlen > risc_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8068) 				wlen = risc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8069) 			ql_dbg(ql_dbg_init, vha, 0x0089,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8070) 			    "Loading risc segment@ risc addr %x number of "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8071) 			    "words 0x%x.\n", risc_addr, wlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8073) 			for (i = 0; i < wlen; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8074) 				wcode[i] = swab16((__force u32)fwcode[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8076) 			rval = qla2x00_load_ram(vha, req->dma, risc_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8077) 			    wlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8078) 			if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8079) 				ql_log(ql_log_fatal, vha, 0x008a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8080) 				    "Failed to load segment %d of firmware.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8081) 				    fragment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8082) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8083) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8085) 			fwcode += wlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8086) 			risc_addr += wlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8087) 			risc_size -= wlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8088) 			fragment++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8089) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8091) 		/* Next segment. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8092) 		seg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8093) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8094) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8096) fail_fw_integrity:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8097) 	return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8100) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8101) qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8103) 	int	rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8104) 	uint templates, segments, fragment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8105) 	uint32_t *dcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8106) 	ulong dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8107) 	uint32_t risc_addr, risc_size, risc_attr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8108) 	ulong i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8109) 	uint j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8110) 	struct fw_blob *blob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8111) 	__be32 *fwcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8112) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8113) 	struct req_que *req = ha->req_q_map[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8114) 	struct fwdt *fwdt = ha->fwdt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8116) 	ql_dbg(ql_dbg_init, vha, 0x0090,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8117) 	    "-> FW: Loading via request-firmware.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8119) 	blob = qla2x00_request_firmware(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8120) 	if (!blob) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8121) 		ql_log(ql_log_warn, vha, 0x0092,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8122) 		    "-> Firmware file not found.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8124) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8125) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8127) 	fwcode = (__force __be32 *)blob->fw->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8128) 	dcode = (__force uint32_t *)fwcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8129) 	if (qla24xx_risc_firmware_invalid(dcode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8130) 		ql_log(ql_log_fatal, vha, 0x0093,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8131) 		    "Unable to verify integrity of firmware image (%zd).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8132) 		    blob->fw->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8133) 		ql_log(ql_log_fatal, vha, 0x0095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8134) 		    "Firmware data: %08x %08x %08x %08x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8135) 		    dcode[0], dcode[1], dcode[2], dcode[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8136) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8137) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8139) 	dcode = (uint32_t *)req->ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8140) 	*srisc_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8141) 	segments = FA_RISC_CODE_SEGMENTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8142) 	for (j = 0; j < segments; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8143) 		ql_dbg(ql_dbg_init, vha, 0x0096,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8144) 		    "-> Loading segment %u...\n", j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8145) 		risc_addr = be32_to_cpu(fwcode[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8146) 		risc_size = be32_to_cpu(fwcode[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8148) 		if (!*srisc_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8149) 			*srisc_addr = risc_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8150) 			risc_attr = be32_to_cpu(fwcode[9]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8151) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8153) 		dlen = ha->fw_transfer_size >> 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8154) 		for (fragment = 0; risc_size; fragment++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8155) 			if (dlen > risc_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8156) 				dlen = risc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8158) 			ql_dbg(ql_dbg_init, vha, 0x0097,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8159) 			    "-> Loading fragment %u: %#x <- %#x (%#lx words)...\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8160) 			    fragment, risc_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8161) 			    (uint32_t)(fwcode - (typeof(fwcode))blob->fw->data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8162) 			    dlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8164) 			for (i = 0; i < dlen; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8165) 				dcode[i] = swab32((__force u32)fwcode[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8167) 			rval = qla2x00_load_ram(vha, req->dma, risc_addr, dlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8168) 			if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8169) 				ql_log(ql_log_fatal, vha, 0x0098,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8170) 				    "-> Failed load firmware fragment %u.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8171) 				    fragment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8172) 				return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8173) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8175) 			fwcode += dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8176) 			risc_addr += dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8177) 			risc_size -= dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8178) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8179) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8181) 	if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8182) 		return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8184) 	templates = (risc_attr & BIT_9) ? 2 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8185) 	ql_dbg(ql_dbg_init, vha, 0x0170, "-> templates = %u\n", templates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8186) 	for (j = 0; j < templates; j++, fwdt++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8187) 		if (fwdt->template)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8188) 			vfree(fwdt->template);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8189) 		fwdt->template = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8190) 		fwdt->length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8192) 		risc_size = be32_to_cpu(fwcode[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8193) 		ql_dbg(ql_dbg_init, vha, 0x0171,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8194) 		    "-> fwdt%u template array at %#x (%#x dwords)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8195) 		    j, (uint32_t)((void *)fwcode - (void *)blob->fw->data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8196) 		    risc_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8197) 		if (!risc_size || !~risc_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8198) 			ql_dbg(ql_dbg_init, vha, 0x0172,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8199) 			    "-> fwdt%u failed to read array\n", j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8200) 			goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8201) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8203) 		/* skip header and ignore checksum */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8204) 		fwcode += 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8205) 		risc_size -= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8207) 		ql_dbg(ql_dbg_init, vha, 0x0173,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8208) 		    "-> fwdt%u template allocate template %#x words...\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8209) 		    j, risc_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8210) 		fwdt->template = vmalloc(risc_size * sizeof(*dcode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8211) 		if (!fwdt->template) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8212) 			ql_log(ql_log_warn, vha, 0x0174,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8213) 			    "-> fwdt%u failed allocate template.\n", j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8214) 			goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8215) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8217) 		dcode = fwdt->template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8218) 		for (i = 0; i < risc_size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8219) 			dcode[i] = (__force u32)fwcode[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8221) 		if (!qla27xx_fwdt_template_valid(dcode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8222) 			ql_log(ql_log_warn, vha, 0x0175,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8223) 			    "-> fwdt%u failed template validate\n", j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8224) 			goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8225) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8227) 		dlen = qla27xx_fwdt_template_size(dcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8228) 		ql_dbg(ql_dbg_init, vha, 0x0176,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8229) 		    "-> fwdt%u template size %#lx bytes (%#lx words)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8230) 		    j, dlen, dlen / sizeof(*dcode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8231) 		if (dlen > risc_size * sizeof(*dcode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8232) 			ql_log(ql_log_warn, vha, 0x0177,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8233) 			    "-> fwdt%u template exceeds array (%-lu bytes)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8234) 			    j, dlen - risc_size * sizeof(*dcode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8235) 			goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8236) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8238) 		fwdt->length = dlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8239) 		ql_dbg(ql_dbg_init, vha, 0x0178,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8240) 		    "-> fwdt%u loaded template ok\n", j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8242) 		fwcode += risc_size + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8243) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8245) 	return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8247) failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8248) 	if (fwdt->template)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8249) 		vfree(fwdt->template);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8250) 	fwdt->template = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8251) 	fwdt->length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8253) 	return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8256) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8257) qla24xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8259) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8261) 	if (ql2xfwloadbin == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8262) 		return qla81xx_load_risc(vha, srisc_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8264) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8265) 	 * FW Load priority:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8266) 	 * 1) Firmware via request-firmware interface (.bin file).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8267) 	 * 2) Firmware residing in flash.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8268) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8269) 	rval = qla24xx_load_risc_blob(vha, srisc_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8270) 	if (rval == QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8271) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8273) 	return qla24xx_load_risc_flash(vha, srisc_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8274) 	    vha->hw->flt_region_fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8277) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8278) qla81xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8280) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8281) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8282) 	struct active_regions active_regions = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8284) 	if (ql2xfwloadbin == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8285) 		goto try_blob_fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8287) 	/* FW Load priority:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8288) 	 * 1) Firmware residing in flash.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8289) 	 * 2) Firmware via request-firmware interface (.bin file).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8290) 	 * 3) Golden-Firmware residing in flash -- (limited operation).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8291) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8293) 	if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8294) 		goto try_primary_fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8296) 	qla27xx_get_active_image(vha, &active_regions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8298) 	if (active_regions.global != QLA27XX_SECONDARY_IMAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8299) 		goto try_primary_fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8301) 	ql_dbg(ql_dbg_init, vha, 0x008b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8302) 	    "Loading secondary firmware image.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8303) 	rval = qla24xx_load_risc_flash(vha, srisc_addr, ha->flt_region_fw_sec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8304) 	if (!rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8305) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8307) try_primary_fw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8308) 	ql_dbg(ql_dbg_init, vha, 0x008b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8309) 	    "Loading primary firmware image.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8310) 	rval = qla24xx_load_risc_flash(vha, srisc_addr, ha->flt_region_fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8311) 	if (!rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8312) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8314) try_blob_fw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8315) 	rval = qla24xx_load_risc_blob(vha, srisc_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8316) 	if (!rval || !ha->flt_region_gold_fw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8317) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8319) 	ql_log(ql_log_info, vha, 0x0099,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8320) 	    "Attempting to fallback to golden firmware.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8321) 	rval = qla24xx_load_risc_flash(vha, srisc_addr, ha->flt_region_gold_fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8322) 	if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8323) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8325) 	ql_log(ql_log_info, vha, 0x009a, "Need firmware flash update.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8326) 	ha->flags.running_gold_fw = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8327) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8330) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8331) qla2x00_try_to_stop_firmware(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8333) 	int ret, retries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8334) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8336) 	if (ha->flags.pci_channel_io_perm_failure)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8337) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8338) 	if (!IS_FWI2_CAPABLE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8339) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8340) 	if (!ha->fw_major_version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8341) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8342) 	if (!ha->flags.fw_started)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8343) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8345) 	ret = qla2x00_stop_firmware(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8346) 	for (retries = 5; ret != QLA_SUCCESS && ret != QLA_FUNCTION_TIMEOUT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8347) 	    ret != QLA_INVALID_COMMAND && retries ; retries--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8348) 		ha->isp_ops->reset_chip(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8349) 		if (ha->isp_ops->chip_diag(vha) != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8350) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8351) 		if (qla2x00_setup_chip(vha) != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8352) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8353) 		ql_log(ql_log_info, vha, 0x8015,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8354) 		    "Attempting retry of stop-firmware command.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8355) 		ret = qla2x00_stop_firmware(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8356) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8358) 	QLA_FW_STOPPED(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8359) 	ha->flags.fw_init_done = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8362) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8363) qla24xx_configure_vhba(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8365) 	int rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8366) 	int rval2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8367) 	uint16_t mb[MAILBOX_REGISTER_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8368) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8369) 	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8371) 	if (!vha->vp_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8372) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8374) 	rval = qla2x00_fw_ready(base_vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8376) 	if (rval == QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8377) 		clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8378) 		qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8379) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8381) 	vha->flags.management_server_logged_in = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8383) 	/* Login to SNS first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8384) 	rval2 = ha->isp_ops->fabric_login(vha, NPH_SNS, 0xff, 0xff, 0xfc, mb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8385) 	    BIT_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8386) 	if (rval2 != QLA_SUCCESS || mb[0] != MBS_COMMAND_COMPLETE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8387) 		if (rval2 == QLA_MEMORY_ALLOC_FAILED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8388) 			ql_dbg(ql_dbg_init, vha, 0x0120,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8389) 			    "Failed SNS login: loop_id=%x, rval2=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8390) 			    NPH_SNS, rval2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8391) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8392) 			ql_dbg(ql_dbg_init, vha, 0x0103,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8393) 			    "Failed SNS login: loop_id=%x mb[0]=%x mb[1]=%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8394) 			    "mb[2]=%x mb[6]=%x mb[7]=%x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8395) 			    NPH_SNS, mb[0], mb[1], mb[2], mb[6], mb[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8396) 		return (QLA_FUNCTION_FAILED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8397) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8399) 	atomic_set(&vha->loop_down_timer, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8400) 	atomic_set(&vha->loop_state, LOOP_UP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8401) 	set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8402) 	set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8403) 	rval = qla2x00_loop_resync(base_vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8405) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8408) /* 84XX Support **************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8410) static LIST_HEAD(qla_cs84xx_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8411) static DEFINE_MUTEX(qla_cs84xx_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8413) static struct qla_chip_state_84xx *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8414) qla84xx_get_chip(struct scsi_qla_host *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8416) 	struct qla_chip_state_84xx *cs84xx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8417) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8419) 	mutex_lock(&qla_cs84xx_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8421) 	/* Find any shared 84xx chip. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8422) 	list_for_each_entry(cs84xx, &qla_cs84xx_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8423) 		if (cs84xx->bus == ha->pdev->bus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8424) 			kref_get(&cs84xx->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8425) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8426) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8427) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8429) 	cs84xx = kzalloc(sizeof(*cs84xx), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8430) 	if (!cs84xx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8431) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8433) 	kref_init(&cs84xx->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8434) 	spin_lock_init(&cs84xx->access_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8435) 	mutex_init(&cs84xx->fw_update_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8436) 	cs84xx->bus = ha->pdev->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8438) 	list_add_tail(&cs84xx->list, &qla_cs84xx_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8439) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8440) 	mutex_unlock(&qla_cs84xx_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8441) 	return cs84xx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8444) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8445) __qla84xx_chip_release(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8447) 	struct qla_chip_state_84xx *cs84xx =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8448) 	    container_of(kref, struct qla_chip_state_84xx, kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8450) 	mutex_lock(&qla_cs84xx_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8451) 	list_del(&cs84xx->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8452) 	mutex_unlock(&qla_cs84xx_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8453) 	kfree(cs84xx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8456) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8457) qla84xx_put_chip(struct scsi_qla_host *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8459) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8461) 	if (ha->cs84xx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8462) 		kref_put(&ha->cs84xx->kref, __qla84xx_chip_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8465) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8466) qla84xx_init_chip(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8468) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8469) 	uint16_t status[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8470) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8472) 	mutex_lock(&ha->cs84xx->fw_update_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8474) 	rval = qla84xx_verify_chip(vha, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8476) 	mutex_unlock(&ha->cs84xx->fw_update_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8478) 	return rval != QLA_SUCCESS || status[0] ? QLA_FUNCTION_FAILED :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8479) 	    QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8482) /* 81XX Support **************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8484) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8485) qla81xx_nvram_config(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8487) 	int   rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8488) 	struct init_cb_81xx *icb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8489) 	struct nvram_81xx *nv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8490) 	__le32 *dptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8491) 	uint8_t  *dptr1, *dptr2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8492) 	uint32_t chksum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8493) 	uint16_t cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8494) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8495) 	uint32_t faddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8496) 	struct active_regions active_regions = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8498) 	rval = QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8499) 	icb = (struct init_cb_81xx *)ha->init_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8500) 	nv = ha->nvram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8502) 	/* Determine NVRAM starting address. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8503) 	ha->nvram_size = sizeof(*nv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8504) 	ha->vpd_size = FA_NVRAM_VPD_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8505) 	if (IS_P3P_TYPE(ha) || IS_QLA8031(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8506) 		ha->vpd_size = FA_VPD_SIZE_82XX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8508) 	if (IS_QLA28XX(ha) || IS_QLA27XX(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8509) 		qla28xx_get_aux_images(vha, &active_regions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8511) 	/* Get VPD data into cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8512) 	ha->vpd = ha->nvram + VPD_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8514) 	faddr = ha->flt_region_vpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8515) 	if (IS_QLA28XX(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8516) 		if (active_regions.aux.vpd_nvram == QLA27XX_SECONDARY_IMAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8517) 			faddr = ha->flt_region_vpd_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8518) 		ql_dbg(ql_dbg_init, vha, 0x0110,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8519) 		    "Loading %s nvram image.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8520) 		    active_regions.aux.vpd_nvram == QLA27XX_PRIMARY_IMAGE ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8521) 		    "primary" : "secondary");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8522) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8523) 	ha->isp_ops->read_optrom(vha, ha->vpd, faddr << 2, ha->vpd_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8525) 	/* Get NVRAM data into cache and calculate checksum. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8526) 	faddr = ha->flt_region_nvram;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8527) 	if (IS_QLA28XX(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8528) 		if (active_regions.aux.vpd_nvram == QLA27XX_SECONDARY_IMAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8529) 			faddr = ha->flt_region_nvram_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8530) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8531) 	ql_dbg(ql_dbg_init, vha, 0x0110,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8532) 	    "Loading %s nvram image.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8533) 	    active_regions.aux.vpd_nvram == QLA27XX_PRIMARY_IMAGE ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8534) 	    "primary" : "secondary");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8535) 	ha->isp_ops->read_optrom(vha, ha->nvram, faddr << 2, ha->nvram_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8537) 	dptr = (__force __le32 *)nv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8538) 	for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++, dptr++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8539) 		chksum += le32_to_cpu(*dptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8541) 	ql_dbg(ql_dbg_init + ql_dbg_buffer, vha, 0x0111,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8542) 	    "Contents of NVRAM:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8543) 	ql_dump_buffer(ql_dbg_init + ql_dbg_buffer, vha, 0x0112,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8544) 	    nv, ha->nvram_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8546) 	/* Bad NVRAM data, set defaults parameters. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8547) 	if (chksum || memcmp("ISP ", nv->id, sizeof(nv->id)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8548) 	    le16_to_cpu(nv->nvram_version) < ICB_VERSION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8549) 		/* Reset NVRAM data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8550) 		ql_log(ql_log_info, vha, 0x0073,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8551) 		    "Inconsistent NVRAM checksum=%#x id=%.4s version=%#x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8552) 		    chksum, nv->id, le16_to_cpu(nv->nvram_version));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8553) 		ql_dump_buffer(ql_dbg_init, vha, 0x0073, nv, sizeof(*nv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8554) 		ql_log(ql_log_info, vha, 0x0074,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8555) 		    "Falling back to functioning (yet invalid -- WWPN) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8556) 		    "defaults.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8558) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8559) 		 * Set default initialization control block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8560) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8561) 		memset(nv, 0, ha->nvram_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8562) 		nv->nvram_version = cpu_to_le16(ICB_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8563) 		nv->version = cpu_to_le16(ICB_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8564) 		nv->frame_payload_size = cpu_to_le16(2048);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8565) 		nv->execution_throttle = cpu_to_le16(0xFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8566) 		nv->exchange_count = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8567) 		nv->port_name[0] = 0x21;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8568) 		nv->port_name[1] = 0x00 + ha->port_no + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8569) 		nv->port_name[2] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8570) 		nv->port_name[3] = 0xe0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8571) 		nv->port_name[4] = 0x8b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8572) 		nv->port_name[5] = 0x1c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8573) 		nv->port_name[6] = 0x55;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8574) 		nv->port_name[7] = 0x86;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8575) 		nv->node_name[0] = 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8576) 		nv->node_name[1] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8577) 		nv->node_name[2] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8578) 		nv->node_name[3] = 0xe0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8579) 		nv->node_name[4] = 0x8b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8580) 		nv->node_name[5] = 0x1c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8581) 		nv->node_name[6] = 0x55;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8582) 		nv->node_name[7] = 0x86;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8583) 		nv->login_retry_count = cpu_to_le16(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8584) 		nv->interrupt_delay_timer = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8585) 		nv->login_timeout = cpu_to_le16(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8586) 		nv->firmware_options_1 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8587) 		    cpu_to_le32(BIT_14|BIT_13|BIT_2|BIT_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8588) 		nv->firmware_options_2 = cpu_to_le32(2 << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8589) 		nv->firmware_options_2 |= cpu_to_le32(BIT_12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8590) 		nv->firmware_options_3 = cpu_to_le32(2 << 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8591) 		nv->host_p = cpu_to_le32(BIT_11|BIT_10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8592) 		nv->efi_parameters = cpu_to_le32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8593) 		nv->reset_delay = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8594) 		nv->max_luns_per_target = cpu_to_le16(128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8595) 		nv->port_down_retry_count = cpu_to_le16(30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8596) 		nv->link_down_timeout = cpu_to_le16(180);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8597) 		nv->enode_mac[0] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8598) 		nv->enode_mac[1] = 0xC0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8599) 		nv->enode_mac[2] = 0xDD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8600) 		nv->enode_mac[3] = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8601) 		nv->enode_mac[4] = 0x05;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8602) 		nv->enode_mac[5] = 0x06 + ha->port_no + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8604) 		rval = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8605) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8607) 	if (IS_T10_PI_CAPABLE(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8608) 		nv->frame_payload_size &= cpu_to_le16(~7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8610) 	qlt_81xx_config_nvram_stage1(vha, nv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8612) 	/* Reset Initialization control block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8613) 	memset(icb, 0, ha->init_cb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8615) 	/* Copy 1st segment. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8616) 	dptr1 = (uint8_t *)icb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8617) 	dptr2 = (uint8_t *)&nv->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8618) 	cnt = (uint8_t *)&icb->response_q_inpointer - (uint8_t *)&icb->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8619) 	while (cnt--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8620) 		*dptr1++ = *dptr2++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8622) 	icb->login_retry_count = nv->login_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8624) 	/* Copy 2nd segment. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8625) 	dptr1 = (uint8_t *)&icb->interrupt_delay_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8626) 	dptr2 = (uint8_t *)&nv->interrupt_delay_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8627) 	cnt = (uint8_t *)&icb->reserved_5 -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8628) 	    (uint8_t *)&icb->interrupt_delay_timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8629) 	while (cnt--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8630) 		*dptr1++ = *dptr2++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8632) 	memcpy(icb->enode_mac, nv->enode_mac, sizeof(icb->enode_mac));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8633) 	/* Some boards (with valid NVRAMs) still have NULL enode_mac!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8634) 	if (!memcmp(icb->enode_mac, "\0\0\0\0\0\0", sizeof(icb->enode_mac))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8635) 		icb->enode_mac[0] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8636) 		icb->enode_mac[1] = 0xC0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8637) 		icb->enode_mac[2] = 0xDD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8638) 		icb->enode_mac[3] = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8639) 		icb->enode_mac[4] = 0x05;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8640) 		icb->enode_mac[5] = 0x06 + ha->port_no + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8641) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8643) 	/* Use extended-initialization control block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8644) 	memcpy(ha->ex_init_cb, &nv->ex_version, sizeof(*ha->ex_init_cb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8645) 	ha->frame_payload_size = le16_to_cpu(icb->frame_payload_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8646) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8647) 	 * Setup driver NVRAM options.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8648) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8649) 	qla2x00_set_model_info(vha, nv->model_name, sizeof(nv->model_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8650) 	    "QLE8XXX");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8652) 	qlt_81xx_config_nvram_stage2(vha, icb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8654) 	/* Use alternate WWN? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8655) 	if (nv->host_p & cpu_to_le32(BIT_15)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8656) 		memcpy(icb->node_name, nv->alternate_node_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8657) 		memcpy(icb->port_name, nv->alternate_port_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8658) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8660) 	/* Prepare nodename */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8661) 	if ((icb->firmware_options_1 & cpu_to_le32(BIT_14)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8662) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8663) 		 * Firmware will apply the following mask if the nodename was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8664) 		 * not provided.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8665) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8666) 		memcpy(icb->node_name, icb->port_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8667) 		icb->node_name[0] &= 0xF0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8668) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8670) 	if (IS_QLA28XX(ha) || IS_QLA27XX(ha)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8671) 		if ((nv->enhanced_features & BIT_7) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8672) 			ha->flags.scm_supported_a = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8673) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8675) 	/* Set host adapter parameters. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8676) 	ha->flags.disable_risc_code_load = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8677) 	ha->flags.enable_lip_reset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8678) 	ha->flags.enable_lip_full_login =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8679) 	    le32_to_cpu(nv->host_p) & BIT_10 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8680) 	ha->flags.enable_target_reset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8681) 	    le32_to_cpu(nv->host_p) & BIT_11 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8682) 	ha->flags.enable_led_scheme = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8683) 	ha->flags.disable_serdes = le32_to_cpu(nv->host_p) & BIT_5 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8685) 	ha->operating_mode = (le32_to_cpu(icb->firmware_options_2) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8686) 	    (BIT_6 | BIT_5 | BIT_4)) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8688) 	/* save HBA serial number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8689) 	ha->serial0 = icb->port_name[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8690) 	ha->serial1 = icb->port_name[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8691) 	ha->serial2 = icb->port_name[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8692) 	memcpy(vha->node_name, icb->node_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8693) 	memcpy(vha->port_name, icb->port_name, WWN_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8695) 	icb->execution_throttle = cpu_to_le16(0xFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8697) 	ha->retry_count = le16_to_cpu(nv->login_retry_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8699) 	/* Set minimum login_timeout to 4 seconds. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8700) 	if (le16_to_cpu(nv->login_timeout) < ql2xlogintimeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8701) 		nv->login_timeout = cpu_to_le16(ql2xlogintimeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8702) 	if (le16_to_cpu(nv->login_timeout) < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8703) 		nv->login_timeout = cpu_to_le16(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8704) 	ha->login_timeout = le16_to_cpu(nv->login_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8706) 	/* Set minimum RATOV to 100 tenths of a second. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8707) 	ha->r_a_tov = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8709) 	ha->loop_reset_delay = nv->reset_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8711) 	/* Link Down Timeout = 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8712) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8713) 	 *	When Port Down timer expires we will start returning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8714) 	 *	I/O's to OS with "DID_NO_CONNECT".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8715) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8716) 	 * Link Down Timeout != 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8717) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8718) 	 *	 The driver waits for the link to come up after link down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8719) 	 *	 before returning I/Os to OS with "DID_NO_CONNECT".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8720) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8721) 	if (le16_to_cpu(nv->link_down_timeout) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8722) 		ha->loop_down_abort_time =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8723) 		    (LOOP_DOWN_TIME - LOOP_DOWN_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8724) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8725) 		ha->link_down_timeout =	le16_to_cpu(nv->link_down_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8726) 		ha->loop_down_abort_time =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8727) 		    (LOOP_DOWN_TIME - ha->link_down_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8728) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8730) 	/* Need enough time to try and get the port back. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8731) 	ha->port_down_retry_count = le16_to_cpu(nv->port_down_retry_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8732) 	if (qlport_down_retry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8733) 		ha->port_down_retry_count = qlport_down_retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8735) 	/* Set login_retry_count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8736) 	ha->login_retry_count  = le16_to_cpu(nv->login_retry_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8737) 	if (ha->port_down_retry_count ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8738) 	    le16_to_cpu(nv->port_down_retry_count) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8739) 	    ha->port_down_retry_count > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8740) 		ha->login_retry_count = ha->port_down_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8741) 	else if (ha->port_down_retry_count > (int)ha->login_retry_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8742) 		ha->login_retry_count = ha->port_down_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8743) 	if (ql2xloginretrycount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8744) 		ha->login_retry_count = ql2xloginretrycount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8746) 	/* if not running MSI-X we need handshaking on interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8747) 	if (!vha->hw->flags.msix_enabled &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8748) 	    (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8749) 		icb->firmware_options_2 |= cpu_to_le32(BIT_22);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8751) 	/* Enable ZIO. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8752) 	if (!vha->flags.init_done) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8753) 		ha->zio_mode = le32_to_cpu(icb->firmware_options_2) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8754) 		    (BIT_3 | BIT_2 | BIT_1 | BIT_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8755) 		ha->zio_timer = le16_to_cpu(icb->interrupt_delay_timer) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8756) 		    le16_to_cpu(icb->interrupt_delay_timer) : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8757) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8758) 	icb->firmware_options_2 &= cpu_to_le32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8759) 	    ~(BIT_3 | BIT_2 | BIT_1 | BIT_0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8760) 	vha->flags.process_response_queue = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8761) 	if (ha->zio_mode != QLA_ZIO_DISABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8762) 		ha->zio_mode = QLA_ZIO_MODE_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8764) 		ql_log(ql_log_info, vha, 0x0075,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8765) 		    "ZIO mode %d enabled; timer delay (%d us).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8766) 		    ha->zio_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8767) 		    ha->zio_timer * 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8769) 		icb->firmware_options_2 |= cpu_to_le32(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8770) 		    (uint32_t)ha->zio_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8771) 		icb->interrupt_delay_timer = cpu_to_le16(ha->zio_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8772) 		vha->flags.process_response_queue = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8773) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8775) 	 /* enable RIDA Format2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8776) 	icb->firmware_options_3 |= cpu_to_le32(BIT_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8778) 	/* N2N: driver will initiate Login instead of FW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8779) 	icb->firmware_options_3 |= cpu_to_le32(BIT_8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8781) 	/* Determine NVMe/FCP priority for target ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8782) 	ha->fc4_type_priority = qla2xxx_get_fc4_priority(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8784) 	if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8785) 		ql_log(ql_log_warn, vha, 0x0076,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8786) 		    "NVRAM configuration failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8787) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8788) 	return (rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8791) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8792) qla82xx_restart_isp(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8794) 	int status, rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8795) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8796) 	struct scsi_qla_host *vp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8797) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8799) 	status = qla2x00_init_rings(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8800) 	if (!status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8801) 		clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8802) 		ha->flags.chip_reset_done = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8804) 		status = qla2x00_fw_ready(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8805) 		if (!status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8806) 			/* Issue a marker after FW becomes ready. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8807) 			qla2x00_marker(vha, ha->base_qpair, 0, 0, MK_SYNC_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8808) 			vha->flags.online = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8809) 			set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8810) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8812) 		/* if no cable then assume it's good */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8813) 		if ((vha->device_flags & DFLG_NO_CABLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8814) 			status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8815) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8817) 	if (!status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8818) 		clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8820) 		if (!atomic_read(&vha->loop_down_timer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8821) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8822) 			 * Issue marker command only when we are going
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8823) 			 * to start the I/O .
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8824) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8825) 			vha->marker_needed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8826) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8828) 		ha->isp_ops->enable_intrs(ha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8830) 		ha->isp_abort_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8831) 		clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8833) 		/* Update the firmware version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8834) 		status = qla82xx_check_md_needed(vha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8836) 		if (ha->fce) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8837) 			ha->flags.fce_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8838) 			memset(ha->fce, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8839) 			    fce_calc_size(ha->fce_bufs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8840) 			rval = qla2x00_enable_fce_trace(vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8841) 			    ha->fce_dma, ha->fce_bufs, ha->fce_mb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8842) 			    &ha->fce_bufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8843) 			if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8844) 				ql_log(ql_log_warn, vha, 0x8001,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8845) 				    "Unable to reinitialize FCE (%d).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8846) 				    rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8847) 				ha->flags.fce_enabled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8848) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8849) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8851) 		if (ha->eft) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8852) 			memset(ha->eft, 0, EFT_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8853) 			rval = qla2x00_enable_eft_trace(vha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8854) 			    ha->eft_dma, EFT_NUM_BUFFERS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8855) 			if (rval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8856) 				ql_log(ql_log_warn, vha, 0x8010,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8857) 				    "Unable to reinitialize EFT (%d).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8858) 				    rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8859) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8860) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8861) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8863) 	if (!status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8864) 		ql_dbg(ql_dbg_taskm, vha, 0x8011,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8865) 		    "qla82xx_restart_isp succeeded.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8867) 		spin_lock_irqsave(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8868) 		list_for_each_entry(vp, &ha->vp_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8869) 			if (vp->vp_idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8870) 				atomic_inc(&vp->vref_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8871) 				spin_unlock_irqrestore(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8873) 				qla2x00_vp_abort_isp(vp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8875) 				spin_lock_irqsave(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8876) 				atomic_dec(&vp->vref_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8877) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8878) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8879) 		spin_unlock_irqrestore(&ha->vport_slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8881) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8882) 		ql_log(ql_log_warn, vha, 0x8016,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8883) 		    "qla82xx_restart_isp **** FAILED ****.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8884) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8886) 	return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8889) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8890)  * qla24xx_get_fcp_prio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8891)  *	Gets the fcp cmd priority value for the logged in port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8892)  *	Looks for a match of the port descriptors within
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8893)  *	each of the fcp prio config entries. If a match is found,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8894)  *	the tag (priority) value is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8895)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8896)  * Input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8897)  *	vha = scsi host structure pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8898)  *	fcport = port structure pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8899)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8900)  * Return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8901)  *	non-zero (if found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8902)  *	-1 (if not found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8903)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8904)  * Context:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8905)  * 	Kernel context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8906)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8907) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8908) qla24xx_get_fcp_prio(scsi_qla_host_t *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8909) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8910) 	int i, entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8911) 	uint8_t pid_match, wwn_match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8912) 	int priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8913) 	uint32_t pid1, pid2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8914) 	uint64_t wwn1, wwn2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8915) 	struct qla_fcp_prio_entry *pri_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8916) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8918) 	if (!ha->fcp_prio_cfg || !ha->flags.fcp_prio_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8919) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8921) 	priority = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8922) 	entries = ha->fcp_prio_cfg->num_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8923) 	pri_entry = &ha->fcp_prio_cfg->entry[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8925) 	for (i = 0; i < entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8926) 		pid_match = wwn_match = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8928) 		if (!(pri_entry->flags & FCP_PRIO_ENTRY_VALID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8929) 			pri_entry++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8930) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8931) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8933) 		/* check source pid for a match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8934) 		if (pri_entry->flags & FCP_PRIO_ENTRY_SPID_VALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8935) 			pid1 = pri_entry->src_pid & INVALID_PORT_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8936) 			pid2 = vha->d_id.b24 & INVALID_PORT_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8937) 			if (pid1 == INVALID_PORT_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8938) 				pid_match++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8939) 			else if (pid1 == pid2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8940) 				pid_match++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8941) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8943) 		/* check destination pid for a match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8944) 		if (pri_entry->flags & FCP_PRIO_ENTRY_DPID_VALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8945) 			pid1 = pri_entry->dst_pid & INVALID_PORT_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8946) 			pid2 = fcport->d_id.b24 & INVALID_PORT_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8947) 			if (pid1 == INVALID_PORT_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8948) 				pid_match++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8949) 			else if (pid1 == pid2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8950) 				pid_match++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8951) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8953) 		/* check source WWN for a match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8954) 		if (pri_entry->flags & FCP_PRIO_ENTRY_SWWN_VALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8955) 			wwn1 = wwn_to_u64(vha->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8956) 			wwn2 = wwn_to_u64(pri_entry->src_wwpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8957) 			if (wwn2 == (uint64_t)-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8958) 				wwn_match++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8959) 			else if (wwn1 == wwn2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8960) 				wwn_match++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8961) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8963) 		/* check destination WWN for a match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8964) 		if (pri_entry->flags & FCP_PRIO_ENTRY_DWWN_VALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8965) 			wwn1 = wwn_to_u64(fcport->port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8966) 			wwn2 = wwn_to_u64(pri_entry->dst_wwpn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8967) 			if (wwn2 == (uint64_t)-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8968) 				wwn_match++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8969) 			else if (wwn1 == wwn2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8970) 				wwn_match++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8971) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8973) 		if (pid_match == 2 || wwn_match == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8974) 			/* Found a matching entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8975) 			if (pri_entry->flags & FCP_PRIO_ENTRY_TAG_VALID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8976) 				priority = pri_entry->tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8977) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8978) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8980) 		pri_entry++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8981) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8983) 	return priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8986) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8987)  * qla24xx_update_fcport_fcp_prio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8988)  *	Activates fcp priority for the logged in fc port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8989)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8990)  * Input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8991)  *	vha = scsi host structure pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8992)  *	fcp = port structure pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8993)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8994)  * Return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8995)  *	QLA_SUCCESS or QLA_FUNCTION_FAILED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8996)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8997)  * Context:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8998)  *	Kernel context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8999)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9000) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9001) qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *vha, fc_port_t *fcport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9002) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9003) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9004) 	int priority;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9005) 	uint16_t mb[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9007) 	if (fcport->port_type != FCT_TARGET ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9008) 	    fcport->loop_id == FC_NO_LOOP_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9009) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9011) 	priority = qla24xx_get_fcp_prio(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9012) 	if (priority < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9013) 		return QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9015) 	if (IS_P3P_TYPE(vha->hw)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9016) 		fcport->fcp_prio = priority & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9017) 		return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9018) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9020) 	ret = qla24xx_set_fcp_prio(vha, fcport->loop_id, priority, mb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9021) 	if (ret == QLA_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9022) 		if (fcport->fcp_prio != priority)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9023) 			ql_dbg(ql_dbg_user, vha, 0x709e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9024) 			    "Updated FCP_CMND priority - value=%d loop_id=%d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9025) 			    "port_id=%02x%02x%02x.\n", priority,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9026) 			    fcport->loop_id, fcport->d_id.b.domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9027) 			    fcport->d_id.b.area, fcport->d_id.b.al_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9028) 		fcport->fcp_prio = priority & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9029) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9030) 		ql_dbg(ql_dbg_user, vha, 0x704f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9031) 		    "Unable to update FCP_CMND priority - ret=0x%x for "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9032) 		    "loop_id=%d port_id=%02x%02x%02x.\n", ret, fcport->loop_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9033) 		    fcport->d_id.b.domain, fcport->d_id.b.area,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9034) 		    fcport->d_id.b.al_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9035) 	return  ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9038) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9039)  * qla24xx_update_all_fcp_prio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9040)  *	Activates fcp priority for all the logged in ports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9041)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9042)  * Input:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9043)  *	ha = adapter block pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9044)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9045)  * Return:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9046)  *	QLA_SUCCESS or QLA_FUNCTION_FAILED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9047)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9048)  * Context:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9049)  *	Kernel context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9050)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9051) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9052) qla24xx_update_all_fcp_prio(scsi_qla_host_t *vha)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9054) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9055) 	fc_port_t *fcport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9057) 	ret = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9058) 	/* We need to set priority for all logged in ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9059) 	list_for_each_entry(fcport, &vha->vp_fcports, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9060) 		ret = qla24xx_update_fcport_fcp_prio(vha, fcport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9062) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9065) struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9066) 	int vp_idx, bool startqp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9067) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9068) 	int rsp_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9069) 	int  req_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9070) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9071) 	struct qla_hw_data *ha = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9072) 	uint16_t qpair_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9073) 	struct qla_qpair *qpair = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9074) 	struct qla_msix_entry *msix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9076) 	if (!(ha->fw_attributes & BIT_6) || !ha->flags.msix_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9077) 		ql_log(ql_log_warn, vha, 0x00181,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9078) 		    "FW/Driver is not multi-queue capable.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9079) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9080) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9081) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9082) 	if (ql2xmqsupport || ql2xnvmeenable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9083) 		qpair = kzalloc(sizeof(struct qla_qpair), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9084) 		if (qpair == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9085) 			ql_log(ql_log_warn, vha, 0x0182,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9086) 			    "Failed to allocate memory for queue pair.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9087) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9088) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9089) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9090) 		qpair->hw = vha->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9091) 		qpair->vha = vha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9092) 		qpair->qp_lock_ptr = &qpair->qp_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9093) 		spin_lock_init(&qpair->qp_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9094) 		qpair->use_shadow_reg = IS_SHADOW_REG_CAPABLE(ha) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9096) 		/* Assign available que pair id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9097) 		mutex_lock(&ha->mq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9098) 		qpair_id = find_first_zero_bit(ha->qpair_qid_map, ha->max_qpairs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9099) 		if (ha->num_qpairs >= ha->max_qpairs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9100) 			mutex_unlock(&ha->mq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9101) 			ql_log(ql_log_warn, vha, 0x0183,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9102) 			    "No resources to create additional q pair.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9103) 			goto fail_qid_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9104) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9105) 		ha->num_qpairs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9106) 		set_bit(qpair_id, ha->qpair_qid_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9107) 		ha->queue_pair_map[qpair_id] = qpair;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9108) 		qpair->id = qpair_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9109) 		qpair->vp_idx = vp_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9110) 		qpair->fw_started = ha->flags.fw_started;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9111) 		INIT_LIST_HEAD(&qpair->hints_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9112) 		qpair->chip_reset = ha->base_qpair->chip_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9113) 		qpair->enable_class_2 = ha->base_qpair->enable_class_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9114) 		qpair->enable_explicit_conf =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9115) 		    ha->base_qpair->enable_explicit_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9117) 		for (i = 0; i < ha->msix_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9118) 			msix = &ha->msix_entries[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9119) 			if (msix->in_use)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9120) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9121) 			qpair->msix = msix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9122) 			ql_dbg(ql_dbg_multiq, vha, 0xc00f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9123) 			    "Vector %x selected for qpair\n", msix->vector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9124) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9125) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9126) 		if (!qpair->msix) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9127) 			ql_log(ql_log_warn, vha, 0x0184,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9128) 			    "Out of MSI-X vectors!.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9129) 			goto fail_msix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9130) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9132) 		qpair->msix->in_use = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9133) 		list_add_tail(&qpair->qp_list_elem, &vha->qp_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9134) 		qpair->pdev = ha->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9135) 		if (IS_QLA27XX(ha) || IS_QLA83XX(ha) || IS_QLA28XX(ha))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9136) 			qpair->reqq_start_iocbs = qla_83xx_start_iocbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9138) 		mutex_unlock(&ha->mq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9140) 		/* Create response queue first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9141) 		rsp_id = qla25xx_create_rsp_que(ha, 0, 0, 0, qpair, startqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9142) 		if (!rsp_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9143) 			ql_log(ql_log_warn, vha, 0x0185,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9144) 			    "Failed to create response queue.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9145) 			goto fail_rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9146) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9148) 		qpair->rsp = ha->rsp_q_map[rsp_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9150) 		/* Create request queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9151) 		req_id = qla25xx_create_req_que(ha, 0, vp_idx, 0, rsp_id, qos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9152) 		    startqp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9153) 		if (!req_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9154) 			ql_log(ql_log_warn, vha, 0x0186,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9155) 			    "Failed to create request queue.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9156) 			goto fail_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9157) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9159) 		qpair->req = ha->req_q_map[req_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9160) 		qpair->rsp->req = qpair->req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9161) 		qpair->rsp->qpair = qpair;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9162) 		/* init qpair to this cpu. Will adjust at run time. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9163) 		qla_cpu_update(qpair, raw_smp_processor_id());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9165) 		if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9166) 			if (ha->fw_attributes & BIT_4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9167) 				qpair->difdix_supported = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9168) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9170) 		qpair->srb_mempool = mempool_create_slab_pool(SRB_MIN_REQ, srb_cachep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9171) 		if (!qpair->srb_mempool) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9172) 			ql_log(ql_log_warn, vha, 0xd036,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9173) 			    "Failed to create srb mempool for qpair %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9174) 			    qpair->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9175) 			goto fail_mempool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9176) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9178) 		/* Mark as online */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9179) 		qpair->online = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9181) 		if (!vha->flags.qpairs_available)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9182) 			vha->flags.qpairs_available = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9184) 		ql_dbg(ql_dbg_multiq, vha, 0xc00d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9185) 		    "Request/Response queue pair created, id %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9186) 		    qpair->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9187) 		ql_dbg(ql_dbg_init, vha, 0x0187,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9188) 		    "Request/Response queue pair created, id %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9189) 		    qpair->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9190) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9191) 	return qpair;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9193) fail_mempool:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9194) fail_req:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9195) 	qla25xx_delete_rsp_que(vha, qpair->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9196) fail_rsp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9197) 	mutex_lock(&ha->mq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9198) 	qpair->msix->in_use = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9199) 	list_del(&qpair->qp_list_elem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9200) 	if (list_empty(&vha->qp_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9201) 		vha->flags.qpairs_available = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9202) fail_msix:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9203) 	ha->queue_pair_map[qpair_id] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9204) 	clear_bit(qpair_id, ha->qpair_qid_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9205) 	ha->num_qpairs--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9206) 	mutex_unlock(&ha->mq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9207) fail_qid_map:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9208) 	kfree(qpair);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9209) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9212) int qla2xxx_delete_qpair(struct scsi_qla_host *vha, struct qla_qpair *qpair)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9214) 	int ret = QLA_FUNCTION_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9215) 	struct qla_hw_data *ha = qpair->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9217) 	qpair->delete_in_progress = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9219) 	ret = qla25xx_delete_req_que(vha, qpair->req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9220) 	if (ret != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9221) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9223) 	ret = qla25xx_delete_rsp_que(vha, qpair->rsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9224) 	if (ret != QLA_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9225) 		goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9227) 	mutex_lock(&ha->mq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9228) 	ha->queue_pair_map[qpair->id] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9229) 	clear_bit(qpair->id, ha->qpair_qid_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9230) 	ha->num_qpairs--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9231) 	list_del(&qpair->qp_list_elem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9232) 	if (list_empty(&vha->qp_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9233) 		vha->flags.qpairs_available = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9234) 		vha->flags.qpairs_req_created = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9235) 		vha->flags.qpairs_rsp_created = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9236) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9237) 	mempool_destroy(qpair->srb_mempool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9238) 	kfree(qpair);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9239) 	mutex_unlock(&ha->mq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9241) 	return QLA_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9242) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9243) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9244) }