brintos

brintos / linux-shallow public Read only

0
0
Text · 71.4 KiB · 75125d2 Raw
2459 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * QLogic iSCSI HBA Driver4 * Copyright (c)  2003-2013 QLogic Corporation5 */6 7#include <linux/ctype.h>8#include "ql4_def.h"9#include "ql4_glbl.h"10#include "ql4_dbg.h"11#include "ql4_inline.h"12#include "ql4_version.h"13 14void qla4xxx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd,15			    int in_count)16{17	int i;18 19	/* Load all mailbox registers, except mailbox 0. */20	for (i = 1; i < in_count; i++)21		writel(mbx_cmd[i], &ha->reg->mailbox[i]);22 23	/* Wakeup firmware  */24	writel(mbx_cmd[0], &ha->reg->mailbox[0]);25	readl(&ha->reg->mailbox[0]);26	writel(set_rmask(CSR_INTR_RISC), &ha->reg->ctrl_status);27	readl(&ha->reg->ctrl_status);28}29 30void qla4xxx_process_mbox_intr(struct scsi_qla_host *ha, int out_count)31{32	int intr_status;33 34	intr_status = readl(&ha->reg->ctrl_status);35	if (intr_status & INTR_PENDING) {36		/*37		 * Service the interrupt.38		 * The ISR will save the mailbox status registers39		 * to a temporary storage location in the adapter structure.40		 */41		ha->mbox_status_count = out_count;42		ha->isp_ops->interrupt_service_routine(ha, intr_status);43	}44}45 46/**47 * qla4xxx_is_intr_poll_mode - Are we allowed to poll for interrupts?48 * @ha: Pointer to host adapter structure.49 * returns: 1=polling mode, 0=non-polling mode50 **/51static int qla4xxx_is_intr_poll_mode(struct scsi_qla_host *ha)52{53	int rval = 1;54 55	if (is_qla8032(ha) || is_qla8042(ha)) {56		if (test_bit(AF_IRQ_ATTACHED, &ha->flags) &&57		    test_bit(AF_83XX_MBOX_INTR_ON, &ha->flags))58			rval = 0;59	} else {60		if (test_bit(AF_IRQ_ATTACHED, &ha->flags) &&61		    test_bit(AF_INTERRUPTS_ON, &ha->flags) &&62		    test_bit(AF_ONLINE, &ha->flags) &&63		    !test_bit(AF_HA_REMOVAL, &ha->flags))64			rval = 0;65	}66 67	return rval;68}69 70/**71 * qla4xxx_mailbox_command - issues mailbox commands72 * @ha: Pointer to host adapter structure.73 * @inCount: number of mailbox registers to load.74 * @outCount: number of mailbox registers to return.75 * @mbx_cmd: data pointer for mailbox in registers.76 * @mbx_sts: data pointer for mailbox out registers.77 *78 * This routine issue mailbox commands and waits for completion.79 * If outCount is 0, this routine completes successfully WITHOUT waiting80 * for the mailbox command to complete.81 **/82int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,83			    uint8_t outCount, uint32_t *mbx_cmd,84			    uint32_t *mbx_sts)85{86	int status = QLA_ERROR;87	uint8_t i;88	u_long wait_count;89	unsigned long flags = 0;90	uint32_t dev_state;91 92	/* Make sure that pointers are valid */93	if (!mbx_cmd || !mbx_sts) {94		DEBUG2(printk("scsi%ld: %s: Invalid mbx_cmd or mbx_sts "95			      "pointer\n", ha->host_no, __func__));96		return status;97	}98 99	if (is_qla40XX(ha)) {100		if (test_bit(AF_HA_REMOVAL, &ha->flags)) {101			DEBUG2(ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: "102					  "prematurely completing mbx cmd as "103					  "adapter removal detected\n",104					  ha->host_no, __func__));105			return status;106		}107	}108 109	if ((is_aer_supported(ha)) &&110	    (test_bit(AF_PCI_CHANNEL_IO_PERM_FAILURE, &ha->flags))) {111		DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Perm failure on EEH, "112		    "timeout MBX Exiting.\n", ha->host_no, __func__));113		return status;114	}115 116	/* Mailbox code active */117	wait_count = MBOX_TOV * 100;118 119	while (wait_count--) {120		mutex_lock(&ha->mbox_sem);121		if (!test_bit(AF_MBOX_COMMAND, &ha->flags)) {122			set_bit(AF_MBOX_COMMAND, &ha->flags);123			mutex_unlock(&ha->mbox_sem);124			break;125		}126		mutex_unlock(&ha->mbox_sem);127		if (!wait_count) {128			DEBUG2(printk("scsi%ld: %s: mbox_sem failed\n",129				ha->host_no, __func__));130			return status;131		}132		msleep(10);133	}134 135	if (is_qla80XX(ha)) {136		if (test_bit(AF_FW_RECOVERY, &ha->flags)) {137			DEBUG2(ql4_printk(KERN_WARNING, ha,138					  "scsi%ld: %s: prematurely completing mbx cmd as firmware recovery detected\n",139					  ha->host_no, __func__));140			goto mbox_exit;141		}142		/* Do not send any mbx cmd if h/w is in failed state*/143		ha->isp_ops->idc_lock(ha);144		dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);145		ha->isp_ops->idc_unlock(ha);146		if (dev_state == QLA8XXX_DEV_FAILED) {147			ql4_printk(KERN_WARNING, ha,148				   "scsi%ld: %s: H/W is in failed state, do not send any mailbox commands\n",149				   ha->host_no, __func__);150			goto mbox_exit;151		}152	}153 154	spin_lock_irqsave(&ha->hardware_lock, flags);155 156	ha->mbox_status_count = outCount;157	for (i = 0; i < outCount; i++)158		ha->mbox_status[i] = 0;159 160	/* Queue the mailbox command to the firmware */161	ha->isp_ops->queue_mailbox_command(ha, mbx_cmd, inCount);162 163	spin_unlock_irqrestore(&ha->hardware_lock, flags);164 165	/* Wait for completion */166 167	/*168	 * If we don't want status, don't wait for the mailbox command to169	 * complete.  For example, MBOX_CMD_RESET_FW doesn't return status,170	 * you must poll the inbound Interrupt Mask for completion.171	 */172	if (outCount == 0) {173		status = QLA_SUCCESS;174		goto mbox_exit;175	}176 177	/*178	 * Wait for completion: Poll or completion queue179	 */180	if (qla4xxx_is_intr_poll_mode(ha)) {181		/* Poll for command to complete */182		wait_count = jiffies + MBOX_TOV * HZ;183		while (test_bit(AF_MBOX_COMMAND_DONE, &ha->flags) == 0) {184			if (time_after_eq(jiffies, wait_count))185				break;186			/*187			 * Service the interrupt.188			 * The ISR will save the mailbox status registers189			 * to a temporary storage location in the adapter190			 * structure.191			 */192			spin_lock_irqsave(&ha->hardware_lock, flags);193			ha->isp_ops->process_mailbox_interrupt(ha, outCount);194			spin_unlock_irqrestore(&ha->hardware_lock, flags);195			msleep(10);196		}197	} else {198		/* Do not poll for completion. Use completion queue */199		set_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags);200		wait_for_completion_timeout(&ha->mbx_intr_comp, MBOX_TOV * HZ);201		clear_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags);202	}203 204	/* Check for mailbox timeout. */205	if (!test_bit(AF_MBOX_COMMAND_DONE, &ha->flags)) {206		if (is_qla80XX(ha) &&207		    test_bit(AF_FW_RECOVERY, &ha->flags)) {208			DEBUG2(ql4_printk(KERN_INFO, ha,209			    "scsi%ld: %s: prematurely completing mbx cmd as "210			    "firmware recovery detected\n",211			    ha->host_no, __func__));212			goto mbox_exit;213		}214		ql4_printk(KERN_WARNING, ha, "scsi%ld: Mailbox Cmd 0x%08X timed out, Scheduling Adapter Reset\n",215			   ha->host_no, mbx_cmd[0]);216		ha->mailbox_timeout_count++;217		mbx_sts[0] = (-1);218		set_bit(DPC_RESET_HA, &ha->dpc_flags);219		if (is_qla8022(ha)) {220			ql4_printk(KERN_INFO, ha,221				   "disabling pause transmit on port 0 & 1.\n");222			qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98,223					CRB_NIU_XG_PAUSE_CTL_P0 |224					CRB_NIU_XG_PAUSE_CTL_P1);225		} else if (is_qla8032(ha) || is_qla8042(ha)) {226			ql4_printk(KERN_INFO, ha, " %s: disabling pause transmit on port 0 & 1.\n",227				   __func__);228			qla4_83xx_disable_pause(ha);229		}230		goto mbox_exit;231	}232 233	/*234	 * Copy the mailbox out registers to the caller's mailbox in/out235	 * structure.236	 */237	spin_lock_irqsave(&ha->hardware_lock, flags);238	for (i = 0; i < outCount; i++)239		mbx_sts[i] = ha->mbox_status[i];240 241	/* Set return status and error flags (if applicable). */242	switch (ha->mbox_status[0]) {243	case MBOX_STS_COMMAND_COMPLETE:244		status = QLA_SUCCESS;245		break;246 247	case MBOX_STS_INTERMEDIATE_COMPLETION:248		status = QLA_SUCCESS;249		break;250 251	case MBOX_STS_BUSY:252		ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: Cmd = %08X, ISP BUSY\n",253			   ha->host_no, __func__, mbx_cmd[0]);254		ha->mailbox_timeout_count++;255		break;256 257	default:258		ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: FAILED, MBOX CMD = %08X, MBOX STS = %08X %08X %08X %08X %08X %08X %08X %08X\n",259			   ha->host_no, __func__, mbx_cmd[0], mbx_sts[0],260			   mbx_sts[1], mbx_sts[2], mbx_sts[3], mbx_sts[4],261			   mbx_sts[5], mbx_sts[6], mbx_sts[7]);262		break;263	}264	spin_unlock_irqrestore(&ha->hardware_lock, flags);265 266mbox_exit:267	mutex_lock(&ha->mbox_sem);268	clear_bit(AF_MBOX_COMMAND, &ha->flags);269	mutex_unlock(&ha->mbox_sem);270	clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags);271 272	return status;273}274 275/**276 * qla4xxx_get_minidump_template - Get the firmware template277 * @ha: Pointer to host adapter structure.278 * @phys_addr: dma address for template279 *280 * Obtain the minidump template from firmware during initialization281 * as it may not be available when minidump is desired.282 **/283int qla4xxx_get_minidump_template(struct scsi_qla_host *ha,284				  dma_addr_t phys_addr)285{286	uint32_t mbox_cmd[MBOX_REG_COUNT];287	uint32_t mbox_sts[MBOX_REG_COUNT];288	int status;289 290	memset(&mbox_cmd, 0, sizeof(mbox_cmd));291	memset(&mbox_sts, 0, sizeof(mbox_sts));292 293	mbox_cmd[0] = MBOX_CMD_MINIDUMP;294	mbox_cmd[1] = MINIDUMP_GET_TMPLT_SUBCOMMAND;295	mbox_cmd[2] = LSDW(phys_addr);296	mbox_cmd[3] = MSDW(phys_addr);297	mbox_cmd[4] = ha->fw_dump_tmplt_size;298	mbox_cmd[5] = 0;299 300	status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0],301					 &mbox_sts[0]);302	if (status != QLA_SUCCESS) {303		DEBUG2(ql4_printk(KERN_INFO, ha,304				  "scsi%ld: %s: Cmd = %08X, mbx[0] = 0x%04x, mbx[1] = 0x%04x\n",305				  ha->host_no, __func__, mbox_cmd[0],306				  mbox_sts[0], mbox_sts[1]));307	}308	return status;309}310 311/**312 * qla4xxx_req_template_size - Get minidump template size from firmware.313 * @ha: Pointer to host adapter structure.314 **/315int qla4xxx_req_template_size(struct scsi_qla_host *ha)316{317	uint32_t mbox_cmd[MBOX_REG_COUNT];318	uint32_t mbox_sts[MBOX_REG_COUNT];319	int status;320 321	memset(&mbox_cmd, 0, sizeof(mbox_cmd));322	memset(&mbox_sts, 0, sizeof(mbox_sts));323 324	mbox_cmd[0] = MBOX_CMD_MINIDUMP;325	mbox_cmd[1] = MINIDUMP_GET_SIZE_SUBCOMMAND;326 327	status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 8, &mbox_cmd[0],328					 &mbox_sts[0]);329	if (status == QLA_SUCCESS) {330		ha->fw_dump_tmplt_size = mbox_sts[1];331		DEBUG2(ql4_printk(KERN_INFO, ha,332				  "%s: sts[0]=0x%04x, template  size=0x%04x, size_cm_02=0x%04x, size_cm_04=0x%04x, size_cm_08=0x%04x, size_cm_10=0x%04x, size_cm_FF=0x%04x, version=0x%04x\n",333				  __func__, mbox_sts[0], mbox_sts[1],334				  mbox_sts[2], mbox_sts[3], mbox_sts[4],335				  mbox_sts[5], mbox_sts[6], mbox_sts[7]));336		if (ha->fw_dump_tmplt_size == 0)337			status = QLA_ERROR;338	} else {339		ql4_printk(KERN_WARNING, ha,340			   "%s: Error sts[0]=0x%04x, mbx[1]=0x%04x\n",341			   __func__, mbox_sts[0], mbox_sts[1]);342		status = QLA_ERROR;343	}344 345	return status;346}347 348void qla4xxx_mailbox_premature_completion(struct scsi_qla_host *ha)349{350	set_bit(AF_FW_RECOVERY, &ha->flags);351	ql4_printk(KERN_INFO, ha, "scsi%ld: %s: set FW RECOVERY!\n",352	    ha->host_no, __func__);353 354	if (test_bit(AF_MBOX_COMMAND, &ha->flags)) {355		if (test_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags)) {356			complete(&ha->mbx_intr_comp);357			ql4_printk(KERN_INFO, ha, "scsi%ld: %s: Due to fw "358			    "recovery, doing premature completion of "359			    "mbx cmd\n", ha->host_no, __func__);360 361		} else {362			set_bit(AF_MBOX_COMMAND_DONE, &ha->flags);363			ql4_printk(KERN_INFO, ha, "scsi%ld: %s: Due to fw "364			    "recovery, doing premature completion of "365			    "polling mbx cmd\n", ha->host_no, __func__);366		}367	}368}369 370static uint8_t371qla4xxx_set_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,372		 uint32_t *mbox_sts, dma_addr_t init_fw_cb_dma)373{374	memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT);375	memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT);376 377	if (is_qla8022(ha))378		qla4_82xx_wr_32(ha, ha->nx_db_wr_ptr, 0);379 380	mbox_cmd[0] = MBOX_CMD_INITIALIZE_FIRMWARE;381	mbox_cmd[1] = 0;382	mbox_cmd[2] = LSDW(init_fw_cb_dma);383	mbox_cmd[3] = MSDW(init_fw_cb_dma);384	mbox_cmd[4] = sizeof(struct addr_ctrl_blk);385 386	if (qla4xxx_mailbox_command(ha, 6, 6, mbox_cmd, mbox_sts) !=387	    QLA_SUCCESS) {388		DEBUG2(printk(KERN_WARNING "scsi%ld: %s: "389			      "MBOX_CMD_INITIALIZE_FIRMWARE"390			      " failed w/ status %04X\n",391			      ha->host_no, __func__, mbox_sts[0]));392		return QLA_ERROR;393	}394	return QLA_SUCCESS;395}396 397uint8_t398qla4xxx_get_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,399		 uint32_t *mbox_sts, dma_addr_t init_fw_cb_dma)400{401	memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT);402	memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT);403	mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK;404	mbox_cmd[2] = LSDW(init_fw_cb_dma);405	mbox_cmd[3] = MSDW(init_fw_cb_dma);406	mbox_cmd[4] = sizeof(struct addr_ctrl_blk);407 408	if (qla4xxx_mailbox_command(ha, 5, 5, mbox_cmd, mbox_sts) !=409	    QLA_SUCCESS) {410		DEBUG2(printk(KERN_WARNING "scsi%ld: %s: "411			      "MBOX_CMD_GET_INIT_FW_CTRL_BLOCK"412			      " failed w/ status %04X\n",413			      ha->host_no, __func__, mbox_sts[0]));414		return QLA_ERROR;415	}416	return QLA_SUCCESS;417}418 419uint8_t qla4xxx_set_ipaddr_state(uint8_t fw_ipaddr_state)420{421	uint8_t ipaddr_state;422 423	switch (fw_ipaddr_state) {424	case IP_ADDRSTATE_UNCONFIGURED:425		ipaddr_state = ISCSI_IPDDRESS_STATE_UNCONFIGURED;426		break;427	case IP_ADDRSTATE_INVALID:428		ipaddr_state = ISCSI_IPDDRESS_STATE_INVALID;429		break;430	case IP_ADDRSTATE_ACQUIRING:431		ipaddr_state = ISCSI_IPDDRESS_STATE_ACQUIRING;432		break;433	case IP_ADDRSTATE_TENTATIVE:434		ipaddr_state = ISCSI_IPDDRESS_STATE_TENTATIVE;435		break;436	case IP_ADDRSTATE_DEPRICATED:437		ipaddr_state = ISCSI_IPDDRESS_STATE_DEPRECATED;438		break;439	case IP_ADDRSTATE_PREFERRED:440		ipaddr_state = ISCSI_IPDDRESS_STATE_VALID;441		break;442	case IP_ADDRSTATE_DISABLING:443		ipaddr_state = ISCSI_IPDDRESS_STATE_DISABLING;444		break;445	default:446		ipaddr_state = ISCSI_IPDDRESS_STATE_UNCONFIGURED;447	}448	return ipaddr_state;449}450 451static void452qla4xxx_update_local_ip(struct scsi_qla_host *ha,453			struct addr_ctrl_blk *init_fw_cb)454{455	ha->ip_config.tcp_options = le16_to_cpu(init_fw_cb->ipv4_tcp_opts);456	ha->ip_config.ipv4_options = le16_to_cpu(init_fw_cb->ipv4_ip_opts);457	ha->ip_config.ipv4_addr_state =458			qla4xxx_set_ipaddr_state(init_fw_cb->ipv4_addr_state);459	ha->ip_config.eth_mtu_size =460				le16_to_cpu(init_fw_cb->eth_mtu_size);461	ha->ip_config.ipv4_port = le16_to_cpu(init_fw_cb->ipv4_port);462 463	if (ha->acb_version == ACB_SUPPORTED) {464		ha->ip_config.ipv6_options = le16_to_cpu(init_fw_cb->ipv6_opts);465		ha->ip_config.ipv6_addl_options =466				le16_to_cpu(init_fw_cb->ipv6_addtl_opts);467		ha->ip_config.ipv6_tcp_options =468				le16_to_cpu(init_fw_cb->ipv6_tcp_opts);469	}470 471	/* Save IPv4 Address Info */472	memcpy(ha->ip_config.ip_address, init_fw_cb->ipv4_addr,473	       min(sizeof(ha->ip_config.ip_address),474		   sizeof(init_fw_cb->ipv4_addr)));475	memcpy(ha->ip_config.subnet_mask, init_fw_cb->ipv4_subnet,476	       min(sizeof(ha->ip_config.subnet_mask),477		   sizeof(init_fw_cb->ipv4_subnet)));478	memcpy(ha->ip_config.gateway, init_fw_cb->ipv4_gw_addr,479	       min(sizeof(ha->ip_config.gateway),480		   sizeof(init_fw_cb->ipv4_gw_addr)));481 482	ha->ip_config.ipv4_vlan_tag = be16_to_cpu(init_fw_cb->ipv4_vlan_tag);483	ha->ip_config.control = init_fw_cb->control;484	ha->ip_config.tcp_wsf = init_fw_cb->ipv4_tcp_wsf;485	ha->ip_config.ipv4_tos = init_fw_cb->ipv4_tos;486	ha->ip_config.ipv4_cache_id = init_fw_cb->ipv4_cacheid;487	ha->ip_config.ipv4_alt_cid_len = init_fw_cb->ipv4_dhcp_alt_cid_len;488	memcpy(ha->ip_config.ipv4_alt_cid, init_fw_cb->ipv4_dhcp_alt_cid,489	       min(sizeof(ha->ip_config.ipv4_alt_cid),490		   sizeof(init_fw_cb->ipv4_dhcp_alt_cid)));491	ha->ip_config.ipv4_vid_len = init_fw_cb->ipv4_dhcp_vid_len;492	memcpy(ha->ip_config.ipv4_vid, init_fw_cb->ipv4_dhcp_vid,493	       min(sizeof(ha->ip_config.ipv4_vid),494		   sizeof(init_fw_cb->ipv4_dhcp_vid)));495	ha->ip_config.ipv4_ttl = init_fw_cb->ipv4_ttl;496	ha->ip_config.def_timeout = le16_to_cpu(init_fw_cb->def_timeout);497	ha->ip_config.abort_timer = init_fw_cb->abort_timer;498	ha->ip_config.iscsi_options = le16_to_cpu(init_fw_cb->iscsi_opts);499	ha->ip_config.iscsi_max_pdu_size =500				le16_to_cpu(init_fw_cb->iscsi_max_pdu_size);501	ha->ip_config.iscsi_first_burst_len =502				le16_to_cpu(init_fw_cb->iscsi_fburst_len);503	ha->ip_config.iscsi_max_outstnd_r2t =504				le16_to_cpu(init_fw_cb->iscsi_max_outstnd_r2t);505	ha->ip_config.iscsi_max_burst_len =506				le16_to_cpu(init_fw_cb->iscsi_max_burst_len);507	memcpy(ha->ip_config.iscsi_name, init_fw_cb->iscsi_name,508	       min(sizeof(ha->ip_config.iscsi_name),509		   sizeof(init_fw_cb->iscsi_name)));510 511	if (is_ipv6_enabled(ha)) {512		/* Save IPv6 Address */513		ha->ip_config.ipv6_link_local_state =514		  qla4xxx_set_ipaddr_state(init_fw_cb->ipv6_lnk_lcl_addr_state);515		ha->ip_config.ipv6_addr0_state =516			qla4xxx_set_ipaddr_state(init_fw_cb->ipv6_addr0_state);517		ha->ip_config.ipv6_addr1_state =518			qla4xxx_set_ipaddr_state(init_fw_cb->ipv6_addr1_state);519 520		switch (le16_to_cpu(init_fw_cb->ipv6_dflt_rtr_state)) {521		case IPV6_RTRSTATE_UNKNOWN:522			ha->ip_config.ipv6_default_router_state =523						ISCSI_ROUTER_STATE_UNKNOWN;524			break;525		case IPV6_RTRSTATE_MANUAL:526			ha->ip_config.ipv6_default_router_state =527						ISCSI_ROUTER_STATE_MANUAL;528			break;529		case IPV6_RTRSTATE_ADVERTISED:530			ha->ip_config.ipv6_default_router_state =531						ISCSI_ROUTER_STATE_ADVERTISED;532			break;533		case IPV6_RTRSTATE_STALE:534			ha->ip_config.ipv6_default_router_state =535						ISCSI_ROUTER_STATE_STALE;536			break;537		default:538			ha->ip_config.ipv6_default_router_state =539						ISCSI_ROUTER_STATE_UNKNOWN;540		}541 542		ha->ip_config.ipv6_link_local_addr.in6_u.u6_addr8[0] = 0xFE;543		ha->ip_config.ipv6_link_local_addr.in6_u.u6_addr8[1] = 0x80;544 545		memcpy(&ha->ip_config.ipv6_link_local_addr.in6_u.u6_addr8[8],546		       init_fw_cb->ipv6_if_id,547		       min(sizeof(ha->ip_config.ipv6_link_local_addr)/2,548			   sizeof(init_fw_cb->ipv6_if_id)));549		memcpy(&ha->ip_config.ipv6_addr0, init_fw_cb->ipv6_addr0,550		       min(sizeof(ha->ip_config.ipv6_addr0),551			   sizeof(init_fw_cb->ipv6_addr0)));552		memcpy(&ha->ip_config.ipv6_addr1, init_fw_cb->ipv6_addr1,553		       min(sizeof(ha->ip_config.ipv6_addr1),554			   sizeof(init_fw_cb->ipv6_addr1)));555		memcpy(&ha->ip_config.ipv6_default_router_addr,556		       init_fw_cb->ipv6_dflt_rtr_addr,557		       min(sizeof(ha->ip_config.ipv6_default_router_addr),558			   sizeof(init_fw_cb->ipv6_dflt_rtr_addr)));559		ha->ip_config.ipv6_vlan_tag =560				be16_to_cpu(init_fw_cb->ipv6_vlan_tag);561		ha->ip_config.ipv6_port = le16_to_cpu(init_fw_cb->ipv6_port);562		ha->ip_config.ipv6_cache_id = init_fw_cb->ipv6_cache_id;563		ha->ip_config.ipv6_flow_lbl =564				le16_to_cpu(init_fw_cb->ipv6_flow_lbl);565		ha->ip_config.ipv6_traffic_class =566				init_fw_cb->ipv6_traffic_class;567		ha->ip_config.ipv6_hop_limit = init_fw_cb->ipv6_hop_limit;568		ha->ip_config.ipv6_nd_reach_time =569				le32_to_cpu(init_fw_cb->ipv6_nd_reach_time);570		ha->ip_config.ipv6_nd_rexmit_timer =571				le32_to_cpu(init_fw_cb->ipv6_nd_rexmit_timer);572		ha->ip_config.ipv6_nd_stale_timeout =573				le32_to_cpu(init_fw_cb->ipv6_nd_stale_timeout);574		ha->ip_config.ipv6_dup_addr_detect_count =575					init_fw_cb->ipv6_dup_addr_detect_count;576		ha->ip_config.ipv6_gw_advrt_mtu =577				le32_to_cpu(init_fw_cb->ipv6_gw_advrt_mtu);578		ha->ip_config.ipv6_tcp_wsf = init_fw_cb->ipv6_tcp_wsf;579	}580}581 582uint8_t583qla4xxx_update_local_ifcb(struct scsi_qla_host *ha,584			  uint32_t *mbox_cmd,585			  uint32_t *mbox_sts,586			  struct addr_ctrl_blk  *init_fw_cb,587			  dma_addr_t init_fw_cb_dma)588{589	if (qla4xxx_get_ifcb(ha, mbox_cmd, mbox_sts, init_fw_cb_dma)590	    != QLA_SUCCESS) {591		DEBUG2(printk(KERN_WARNING592			      "scsi%ld: %s: Failed to get init_fw_ctrl_blk\n",593			      ha->host_no, __func__));594		return QLA_ERROR;595	}596 597	DEBUG2(qla4xxx_dump_buffer(init_fw_cb, sizeof(struct addr_ctrl_blk)));598 599	/* Save some info in adapter structure. */600	ha->acb_version = init_fw_cb->acb_version;601	ha->firmware_options = le16_to_cpu(init_fw_cb->fw_options);602	ha->heartbeat_interval = init_fw_cb->hb_interval;603	memcpy(ha->name_string, init_fw_cb->iscsi_name,604		min(sizeof(ha->name_string),605		sizeof(init_fw_cb->iscsi_name)));606	ha->def_timeout = le16_to_cpu(init_fw_cb->def_timeout);607	/*memcpy(ha->alias, init_fw_cb->Alias,608	       min(sizeof(ha->alias), sizeof(init_fw_cb->Alias)));*/609 610	qla4xxx_update_local_ip(ha, init_fw_cb);611 612	return QLA_SUCCESS;613}614 615/**616 * qla4xxx_initialize_fw_cb - initializes firmware control block.617 * @ha: Pointer to host adapter structure.618 **/619int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha)620{621	struct addr_ctrl_blk *init_fw_cb;622	dma_addr_t init_fw_cb_dma;623	uint32_t mbox_cmd[MBOX_REG_COUNT];624	uint32_t mbox_sts[MBOX_REG_COUNT];625	int status = QLA_ERROR;626 627	init_fw_cb = dma_alloc_coherent(&ha->pdev->dev,628					sizeof(struct addr_ctrl_blk),629					&init_fw_cb_dma, GFP_KERNEL);630	if (init_fw_cb == NULL) {631		DEBUG2(printk("scsi%ld: %s: Unable to alloc init_cb\n",632			      ha->host_no, __func__));633		goto exit_init_fw_cb_no_free;634	}635 636	/* Get Initialize Firmware Control Block. */637	memset(&mbox_cmd, 0, sizeof(mbox_cmd));638	memset(&mbox_sts, 0, sizeof(mbox_sts));639 640	if (qla4xxx_get_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma) !=641	    QLA_SUCCESS) {642		goto exit_init_fw_cb;643	}644 645	/* Fill in the request and response queue information. */646	init_fw_cb->rqq_consumer_idx = cpu_to_le16(ha->request_out);647	init_fw_cb->compq_producer_idx = cpu_to_le16(ha->response_in);648	init_fw_cb->rqq_len = cpu_to_le16(REQUEST_QUEUE_DEPTH);649	init_fw_cb->compq_len = cpu_to_le16(RESPONSE_QUEUE_DEPTH);650	init_fw_cb->rqq_addr_lo = cpu_to_le32(LSDW(ha->request_dma));651	init_fw_cb->rqq_addr_hi = cpu_to_le32(MSDW(ha->request_dma));652	init_fw_cb->compq_addr_lo = cpu_to_le32(LSDW(ha->response_dma));653	init_fw_cb->compq_addr_hi = cpu_to_le32(MSDW(ha->response_dma));654	init_fw_cb->shdwreg_addr_lo = cpu_to_le32(LSDW(ha->shadow_regs_dma));655	init_fw_cb->shdwreg_addr_hi = cpu_to_le32(MSDW(ha->shadow_regs_dma));656 657	/* Set up required options. */658	init_fw_cb->fw_options |=659		cpu_to_le16(FWOPT_SESSION_MODE |660			    FWOPT_INITIATOR_MODE);661 662	if (is_qla80XX(ha))663		init_fw_cb->fw_options |=664		    cpu_to_le16(FWOPT_ENABLE_CRBDB);665 666	init_fw_cb->fw_options &= cpu_to_le16(~FWOPT_TARGET_MODE);667 668	init_fw_cb->add_fw_options = 0;669	init_fw_cb->add_fw_options |=670			cpu_to_le16(ADFWOPT_SERIALIZE_TASK_MGMT);671	init_fw_cb->add_fw_options |=672			cpu_to_le16(ADFWOPT_AUTOCONN_DISABLE);673 674	if (qla4xxx_set_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma)675		!= QLA_SUCCESS) {676		DEBUG2(printk(KERN_WARNING677			      "scsi%ld: %s: Failed to set init_fw_ctrl_blk\n",678			      ha->host_no, __func__));679		goto exit_init_fw_cb;680	}681 682	if (qla4xxx_update_local_ifcb(ha, &mbox_cmd[0], &mbox_sts[0],683		init_fw_cb, init_fw_cb_dma) != QLA_SUCCESS) {684		DEBUG2(printk("scsi%ld: %s: Failed to update local ifcb\n",685				ha->host_no, __func__));686		goto exit_init_fw_cb;687	}688	status = QLA_SUCCESS;689 690exit_init_fw_cb:691	dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk),692				init_fw_cb, init_fw_cb_dma);693exit_init_fw_cb_no_free:694	return status;695}696 697/**698 * qla4xxx_get_dhcp_ip_address - gets HBA ip address via DHCP699 * @ha: Pointer to host adapter structure.700 **/701int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host * ha)702{703	struct addr_ctrl_blk *init_fw_cb;704	dma_addr_t init_fw_cb_dma;705	uint32_t mbox_cmd[MBOX_REG_COUNT];706	uint32_t mbox_sts[MBOX_REG_COUNT];707 708	init_fw_cb = dma_alloc_coherent(&ha->pdev->dev,709					sizeof(struct addr_ctrl_blk),710					&init_fw_cb_dma, GFP_KERNEL);711	if (init_fw_cb == NULL) {712		printk("scsi%ld: %s: Unable to alloc init_cb\n", ha->host_no,713		       __func__);714		return QLA_ERROR;715	}716 717	/* Get Initialize Firmware Control Block. */718	if (qla4xxx_get_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma) !=719	    QLA_SUCCESS) {720		DEBUG2(printk("scsi%ld: %s: Failed to get init_fw_ctrl_blk\n",721			      ha->host_no, __func__));722		dma_free_coherent(&ha->pdev->dev,723				  sizeof(struct addr_ctrl_blk),724				  init_fw_cb, init_fw_cb_dma);725		return QLA_ERROR;726	}727 728	/* Save IP Address. */729	qla4xxx_update_local_ip(ha, init_fw_cb);730	dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk),731				init_fw_cb, init_fw_cb_dma);732 733	return QLA_SUCCESS;734}735 736/**737 * qla4xxx_get_firmware_state - gets firmware state of HBA738 * @ha: Pointer to host adapter structure.739 **/740int qla4xxx_get_firmware_state(struct scsi_qla_host * ha)741{742	uint32_t mbox_cmd[MBOX_REG_COUNT];743	uint32_t mbox_sts[MBOX_REG_COUNT];744 745	/* Get firmware version */746	memset(&mbox_cmd, 0, sizeof(mbox_cmd));747	memset(&mbox_sts, 0, sizeof(mbox_sts));748 749	mbox_cmd[0] = MBOX_CMD_GET_FW_STATE;750 751	if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 4, &mbox_cmd[0], &mbox_sts[0]) !=752	    QLA_SUCCESS) {753		DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATE failed w/ "754			      "status %04X\n", ha->host_no, __func__,755			      mbox_sts[0]));756		return QLA_ERROR;757	}758	ha->firmware_state = mbox_sts[1];759	ha->board_id = mbox_sts[2];760	ha->addl_fw_state = mbox_sts[3];761	DEBUG2(printk("scsi%ld: %s firmware_state=0x%x\n",762		      ha->host_no, __func__, ha->firmware_state);)763 764	return QLA_SUCCESS;765}766 767/**768 * qla4xxx_get_firmware_status - retrieves firmware status769 * @ha: Pointer to host adapter structure.770 **/771int qla4xxx_get_firmware_status(struct scsi_qla_host * ha)772{773	uint32_t mbox_cmd[MBOX_REG_COUNT];774	uint32_t mbox_sts[MBOX_REG_COUNT];775 776	/* Get firmware version */777	memset(&mbox_cmd, 0, sizeof(mbox_cmd));778	memset(&mbox_sts, 0, sizeof(mbox_sts));779 780	mbox_cmd[0] = MBOX_CMD_GET_FW_STATUS;781 782	if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 3, &mbox_cmd[0], &mbox_sts[0]) !=783	    QLA_SUCCESS) {784		DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATUS failed w/ "785			      "status %04X\n", ha->host_no, __func__,786			      mbox_sts[0]));787		return QLA_ERROR;788	}789 790	/* High-water mark of IOCBs */791	ha->iocb_hiwat = mbox_sts[2];792	DEBUG2(ql4_printk(KERN_INFO, ha,793			  "%s: firmware IOCBs available = %d\n", __func__,794			  ha->iocb_hiwat));795 796	if (ha->iocb_hiwat > IOCB_HIWAT_CUSHION)797		ha->iocb_hiwat -= IOCB_HIWAT_CUSHION;798 799	/* Ideally, we should not enter this code, as the # of firmware800	 * IOCBs is hard-coded in the firmware. We set a default801	 * iocb_hiwat here just in case */802	if (ha->iocb_hiwat == 0) {803		ha->iocb_hiwat = REQUEST_QUEUE_DEPTH / 4;804		DEBUG2(ql4_printk(KERN_WARNING, ha,805				  "%s: Setting IOCB's to = %d\n", __func__,806				  ha->iocb_hiwat));807	}808 809	return QLA_SUCCESS;810}811 812/*813 * qla4xxx_get_fwddb_entry - retrieves firmware ddb entry814 * @ha: Pointer to host adapter structure.815 * @fw_ddb_index: Firmware's device database index816 * @fw_ddb_entry: Pointer to firmware's device database entry structure817 * @num_valid_ddb_entries: Pointer to number of valid ddb entries818 * @next_ddb_index: Pointer to next valid device database index819 * @fw_ddb_device_state: Pointer to device state820 **/821int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha,822			    uint16_t fw_ddb_index,823			    struct dev_db_entry *fw_ddb_entry,824			    dma_addr_t fw_ddb_entry_dma,825			    uint32_t *num_valid_ddb_entries,826			    uint32_t *next_ddb_index,827			    uint32_t *fw_ddb_device_state,828			    uint32_t *conn_err_detail,829			    uint16_t *tcp_source_port_num,830			    uint16_t *connection_id)831{832	int status = QLA_ERROR;833	uint16_t options;834	uint32_t mbox_cmd[MBOX_REG_COUNT];835	uint32_t mbox_sts[MBOX_REG_COUNT];836 837	/* Make sure the device index is valid */838	if (fw_ddb_index >= MAX_DDB_ENTRIES) {839		DEBUG2(printk("scsi%ld: %s: ddb [%d] out of range.\n",840			      ha->host_no, __func__, fw_ddb_index));841		goto exit_get_fwddb;842	}843	memset(&mbox_cmd, 0, sizeof(mbox_cmd));844	memset(&mbox_sts, 0, sizeof(mbox_sts));845	if (fw_ddb_entry)846		memset(fw_ddb_entry, 0, sizeof(struct dev_db_entry));847 848	mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY;849	mbox_cmd[1] = (uint32_t) fw_ddb_index;850	mbox_cmd[2] = LSDW(fw_ddb_entry_dma);851	mbox_cmd[3] = MSDW(fw_ddb_entry_dma);852	mbox_cmd[4] = sizeof(struct dev_db_entry);853 854	if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 7, &mbox_cmd[0], &mbox_sts[0]) ==855	    QLA_ERROR) {856		DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_DATABASE_ENTRY failed"857			      " with status 0x%04X\n", ha->host_no, __func__,858			      mbox_sts[0]));859		goto exit_get_fwddb;860	}861	if (fw_ddb_index != mbox_sts[1]) {862		DEBUG2(printk("scsi%ld: %s: ddb mismatch [%d] != [%d].\n",863			      ha->host_no, __func__, fw_ddb_index,864			      mbox_sts[1]));865		goto exit_get_fwddb;866	}867	if (fw_ddb_entry) {868		options = le16_to_cpu(fw_ddb_entry->options);869		if (options & DDB_OPT_IPV6_DEVICE) {870			ql4_printk(KERN_INFO, ha, "%s: DDB[%d] MB0 %04x Tot %d "871				"Next %d State %04x ConnErr %08x %pI6 "872				":%04d \"%s\"\n", __func__, fw_ddb_index,873				mbox_sts[0], mbox_sts[2], mbox_sts[3],874				mbox_sts[4], mbox_sts[5],875				fw_ddb_entry->ip_addr,876				le16_to_cpu(fw_ddb_entry->port),877				fw_ddb_entry->iscsi_name);878		} else {879			ql4_printk(KERN_INFO, ha, "%s: DDB[%d] MB0 %04x Tot %d "880				"Next %d State %04x ConnErr %08x %pI4 "881				":%04d \"%s\"\n", __func__, fw_ddb_index,882				mbox_sts[0], mbox_sts[2], mbox_sts[3],883				mbox_sts[4], mbox_sts[5],884				fw_ddb_entry->ip_addr,885				le16_to_cpu(fw_ddb_entry->port),886				fw_ddb_entry->iscsi_name);887		}888	}889	if (num_valid_ddb_entries)890		*num_valid_ddb_entries = mbox_sts[2];891	if (next_ddb_index)892		*next_ddb_index = mbox_sts[3];893	if (fw_ddb_device_state)894		*fw_ddb_device_state = mbox_sts[4];895 896	/*897	 * RA: This mailbox has been changed to pass connection error and898	 * details.  Its true for ISP4010 as per Version E - Not sure when it899	 * was changed.	 Get the time2wait from the fw_dd_entry field :900	 * default_time2wait which we call it as minTime2Wait DEV_DB_ENTRY901	 * struct.902	 */903	if (conn_err_detail)904		*conn_err_detail = mbox_sts[5];905	if (tcp_source_port_num)906		*tcp_source_port_num = (uint16_t) (mbox_sts[6] >> 16);907	if (connection_id)908		*connection_id = (uint16_t) mbox_sts[6] & 0x00FF;909	status = QLA_SUCCESS;910 911exit_get_fwddb:912	return status;913}914 915int qla4xxx_conn_open(struct scsi_qla_host *ha, uint16_t fw_ddb_index)916{917	uint32_t mbox_cmd[MBOX_REG_COUNT];918	uint32_t mbox_sts[MBOX_REG_COUNT];919	int status;920 921	memset(&mbox_cmd, 0, sizeof(mbox_cmd));922	memset(&mbox_sts, 0, sizeof(mbox_sts));923 924	mbox_cmd[0] = MBOX_CMD_CONN_OPEN;925	mbox_cmd[1] = fw_ddb_index;926 927	status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0],928					 &mbox_sts[0]);929	DEBUG2(ql4_printk(KERN_INFO, ha,930			  "%s: status = %d mbx0 = 0x%x mbx1 = 0x%x\n",931			  __func__, status, mbox_sts[0], mbox_sts[1]));932	return status;933}934 935/**936 * qla4xxx_set_ddb_entry - sets a ddb entry.937 * @ha: Pointer to host adapter structure.938 * @fw_ddb_index: Firmware's device database index939 * @fw_ddb_entry_dma: dma address of ddb entry940 * @mbx_sts: mailbox 0 to be returned or NULL941 *942 * This routine initializes or updates the adapter's device database943 * entry for the specified device.944 **/945int qla4xxx_set_ddb_entry(struct scsi_qla_host * ha, uint16_t fw_ddb_index,946			  dma_addr_t fw_ddb_entry_dma, uint32_t *mbx_sts)947{948	uint32_t mbox_cmd[MBOX_REG_COUNT];949	uint32_t mbox_sts[MBOX_REG_COUNT];950	int status;951 952	/* Do not wait for completion. The firmware will send us an953	 * ASTS_DATABASE_CHANGED (0x8014) to notify us of the login status.954	 */955	memset(&mbox_cmd, 0, sizeof(mbox_cmd));956	memset(&mbox_sts, 0, sizeof(mbox_sts));957 958	mbox_cmd[0] = MBOX_CMD_SET_DATABASE_ENTRY;959	mbox_cmd[1] = (uint32_t) fw_ddb_index;960	mbox_cmd[2] = LSDW(fw_ddb_entry_dma);961	mbox_cmd[3] = MSDW(fw_ddb_entry_dma);962	mbox_cmd[4] = sizeof(struct dev_db_entry);963 964	status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0],965					 &mbox_sts[0]);966	if (mbx_sts)967		*mbx_sts = mbox_sts[0];968	DEBUG2(printk("scsi%ld: %s: status=%d mbx0=0x%x mbx4=0x%x\n",969	    ha->host_no, __func__, status, mbox_sts[0], mbox_sts[4]);)970 971	return status;972}973 974int qla4xxx_session_logout_ddb(struct scsi_qla_host *ha,975			       struct ddb_entry *ddb_entry, int options)976{977	int status;978	uint32_t mbox_cmd[MBOX_REG_COUNT];979	uint32_t mbox_sts[MBOX_REG_COUNT];980 981	memset(&mbox_cmd, 0, sizeof(mbox_cmd));982	memset(&mbox_sts, 0, sizeof(mbox_sts));983 984	mbox_cmd[0] = MBOX_CMD_CONN_CLOSE_SESS_LOGOUT;985	mbox_cmd[1] = ddb_entry->fw_ddb_index;986	mbox_cmd[3] = options;987 988	status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0],989					 &mbox_sts[0]);990	if (status != QLA_SUCCESS) {991		DEBUG2(ql4_printk(KERN_INFO, ha,992				  "%s: MBOX_CMD_CONN_CLOSE_SESS_LOGOUT "993				  "failed sts %04X %04X", __func__,994				  mbox_sts[0], mbox_sts[1]));995		if ((mbox_sts[0] == MBOX_STS_COMMAND_ERROR) &&996		    (mbox_sts[1] == DDB_NOT_LOGGED_IN)) {997			set_bit(DDB_CONN_CLOSE_FAILURE, &ddb_entry->flags);998		}999	}1000 1001	return status;1002}1003 1004/**1005 * qla4xxx_get_crash_record - retrieves crash record.1006 * @ha: Pointer to host adapter structure.1007 *1008 * This routine retrieves a crash record from the QLA4010 after an 8002h aen.1009 **/1010void qla4xxx_get_crash_record(struct scsi_qla_host * ha)1011{1012	uint32_t mbox_cmd[MBOX_REG_COUNT];1013	uint32_t mbox_sts[MBOX_REG_COUNT];1014	struct crash_record *crash_record = NULL;1015	dma_addr_t crash_record_dma = 0;1016	uint32_t crash_record_size = 0;1017 1018	memset(&mbox_cmd, 0, sizeof(mbox_cmd));1019	memset(&mbox_sts, 0, sizeof(mbox_cmd));1020 1021	/* Get size of crash record. */1022	mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD;1023 1024	if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=1025	    QLA_SUCCESS) {1026		DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve size!\n",1027			      ha->host_no, __func__));1028		goto exit_get_crash_record;1029	}1030	crash_record_size = mbox_sts[4];1031	if (crash_record_size == 0) {1032		DEBUG2(printk("scsi%ld: %s: ERROR: Crash record size is 0!\n",1033			      ha->host_no, __func__));1034		goto exit_get_crash_record;1035	}1036 1037	/* Alloc Memory for Crash Record. */1038	crash_record = dma_alloc_coherent(&ha->pdev->dev, crash_record_size,1039					  &crash_record_dma, GFP_KERNEL);1040	if (crash_record == NULL)1041		goto exit_get_crash_record;1042 1043	/* Get Crash Record. */1044	memset(&mbox_cmd, 0, sizeof(mbox_cmd));1045	memset(&mbox_sts, 0, sizeof(mbox_cmd));1046 1047	mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD;1048	mbox_cmd[2] = LSDW(crash_record_dma);1049	mbox_cmd[3] = MSDW(crash_record_dma);1050	mbox_cmd[4] = crash_record_size;1051 1052	if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=1053	    QLA_SUCCESS)1054		goto exit_get_crash_record;1055 1056	/* Dump Crash Record. */1057 1058exit_get_crash_record:1059	if (crash_record)1060		dma_free_coherent(&ha->pdev->dev, crash_record_size,1061				  crash_record, crash_record_dma);1062}1063 1064/**1065 * qla4xxx_get_conn_event_log - retrieves connection event log1066 * @ha: Pointer to host adapter structure.1067 **/1068void qla4xxx_get_conn_event_log(struct scsi_qla_host * ha)1069{1070	uint32_t mbox_cmd[MBOX_REG_COUNT];1071	uint32_t mbox_sts[MBOX_REG_COUNT];1072	struct conn_event_log_entry *event_log = NULL;1073	dma_addr_t event_log_dma = 0;1074	uint32_t event_log_size = 0;1075	uint32_t num_valid_entries;1076	uint32_t      oldest_entry = 0;1077	uint32_t	max_event_log_entries;1078	uint8_t		i;1079 1080	memset(&mbox_cmd, 0, sizeof(mbox_cmd));1081	memset(&mbox_sts, 0, sizeof(mbox_cmd));1082 1083	/* Get size of crash record. */1084	mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG;1085 1086	if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=1087	    QLA_SUCCESS)1088		goto exit_get_event_log;1089 1090	event_log_size = mbox_sts[4];1091	if (event_log_size == 0)1092		goto exit_get_event_log;1093 1094	/* Alloc Memory for Crash Record. */1095	event_log = dma_alloc_coherent(&ha->pdev->dev, event_log_size,1096				       &event_log_dma, GFP_KERNEL);1097	if (event_log == NULL)1098		goto exit_get_event_log;1099 1100	/* Get Crash Record. */1101	memset(&mbox_cmd, 0, sizeof(mbox_cmd));1102	memset(&mbox_sts, 0, sizeof(mbox_cmd));1103 1104	mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG;1105	mbox_cmd[2] = LSDW(event_log_dma);1106	mbox_cmd[3] = MSDW(event_log_dma);1107 1108	if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=1109	    QLA_SUCCESS) {1110		DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve event "1111			      "log!\n", ha->host_no, __func__));1112		goto exit_get_event_log;1113	}1114 1115	/* Dump Event Log. */1116	num_valid_entries = mbox_sts[1];1117 1118	max_event_log_entries = event_log_size /1119		sizeof(struct conn_event_log_entry);1120 1121	if (num_valid_entries > max_event_log_entries)1122		oldest_entry = num_valid_entries % max_event_log_entries;1123 1124	DEBUG3(printk("scsi%ld: Connection Event Log Dump (%d entries):\n",1125		      ha->host_no, num_valid_entries));1126 1127	if (ql4xextended_error_logging == 3) {1128		if (oldest_entry == 0) {1129			/* Circular Buffer has not wrapped around */1130			for (i=0; i < num_valid_entries; i++) {1131				qla4xxx_dump_buffer((uint8_t *)event_log+1132						    (i*sizeof(*event_log)),1133						    sizeof(*event_log));1134			}1135		}1136		else {1137			/* Circular Buffer has wrapped around -1138			 * display accordingly*/1139			for (i=oldest_entry; i < max_event_log_entries; i++) {1140				qla4xxx_dump_buffer((uint8_t *)event_log+1141						    (i*sizeof(*event_log)),1142						    sizeof(*event_log));1143			}1144			for (i=0; i < oldest_entry; i++) {1145				qla4xxx_dump_buffer((uint8_t *)event_log+1146						    (i*sizeof(*event_log)),1147						    sizeof(*event_log));1148			}1149		}1150	}1151 1152exit_get_event_log:1153	if (event_log)1154		dma_free_coherent(&ha->pdev->dev, event_log_size, event_log,1155				  event_log_dma);1156}1157 1158/**1159 * qla4xxx_abort_task - issues Abort Task1160 * @ha: Pointer to host adapter structure.1161 * @srb: Pointer to srb entry1162 *1163 * This routine performs a LUN RESET on the specified target/lun.1164 * The caller must ensure that the ddb_entry and lun_entry pointers1165 * are valid before calling this routine.1166 **/1167int qla4xxx_abort_task(struct scsi_qla_host *ha, struct srb *srb)1168{1169	uint32_t mbox_cmd[MBOX_REG_COUNT];1170	uint32_t mbox_sts[MBOX_REG_COUNT];1171	struct scsi_cmnd *cmd = srb->cmd;1172	int status = QLA_SUCCESS;1173	unsigned long flags = 0;1174	uint32_t index;1175 1176	/*1177	 * Send abort task command to ISP, so that the ISP will return1178	 * request with ABORT status1179	 */1180	memset(&mbox_cmd, 0, sizeof(mbox_cmd));1181	memset(&mbox_sts, 0, sizeof(mbox_sts));1182 1183	spin_lock_irqsave(&ha->hardware_lock, flags);1184	index = (unsigned long)(unsigned char *)cmd->host_scribble;1185	spin_unlock_irqrestore(&ha->hardware_lock, flags);1186 1187	/* Firmware already posted completion on response queue */1188	if (index == MAX_SRBS)1189		return status;1190 1191	mbox_cmd[0] = MBOX_CMD_ABORT_TASK;1192	mbox_cmd[1] = srb->ddb->fw_ddb_index;1193	mbox_cmd[2] = index;1194	/* Immediate Command Enable */1195	mbox_cmd[5] = 0x01;1196 1197	qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0],1198	    &mbox_sts[0]);1199	if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE) {1200		status = QLA_ERROR;1201 1202		DEBUG2(printk(KERN_WARNING "scsi%ld:%d:%llu: abort task FAILED: "1203		    "mbx0=%04X, mb1=%04X, mb2=%04X, mb3=%04X, mb4=%04X\n",1204		    ha->host_no, cmd->device->id, cmd->device->lun, mbox_sts[0],1205		    mbox_sts[1], mbox_sts[2], mbox_sts[3], mbox_sts[4]));1206	}1207 1208	return status;1209}1210 1211/**1212 * qla4xxx_reset_lun - issues LUN Reset1213 * @ha: Pointer to host adapter structure.1214 * @ddb_entry: Pointer to device database entry1215 * @lun: lun number1216 *1217 * This routine performs a LUN RESET on the specified target/lun.1218 * The caller must ensure that the ddb_entry and lun_entry pointers1219 * are valid before calling this routine.1220 **/1221int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry,1222		      uint64_t lun)1223{1224	uint32_t mbox_cmd[MBOX_REG_COUNT];1225	uint32_t mbox_sts[MBOX_REG_COUNT];1226	uint32_t scsi_lun[2];1227	int status = QLA_SUCCESS;1228 1229	DEBUG2(printk("scsi%ld:%d:%llu: lun reset issued\n", ha->host_no,1230		      ddb_entry->fw_ddb_index, lun));1231 1232	/*1233	 * Send lun reset command to ISP, so that the ISP will return all1234	 * outstanding requests with RESET status1235	 */1236	memset(&mbox_cmd, 0, sizeof(mbox_cmd));1237	memset(&mbox_sts, 0, sizeof(mbox_sts));1238	int_to_scsilun(lun, (struct scsi_lun *) scsi_lun);1239 1240	mbox_cmd[0] = MBOX_CMD_LUN_RESET;1241	mbox_cmd[1] = ddb_entry->fw_ddb_index;1242	/* FW expects LUN bytes 0-3 in Incoming Mailbox 21243	 * (LUN byte 0 is LSByte, byte 3 is MSByte) */1244	mbox_cmd[2] = cpu_to_le32(scsi_lun[0]);1245	/* FW expects LUN bytes 4-7 in Incoming Mailbox 31246	 * (LUN byte 4 is LSByte, byte 7 is MSByte) */1247	mbox_cmd[3] = cpu_to_le32(scsi_lun[1]);1248	mbox_cmd[5] = 0x01;	/* Immediate Command Enable */1249 1250	qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]);1251	if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE &&1252	    mbox_sts[0] != MBOX_STS_COMMAND_ERROR)1253		status = QLA_ERROR;1254 1255	return status;1256}1257 1258/**1259 * qla4xxx_reset_target - issues target Reset1260 * @ha: Pointer to host adapter structure.1261 * @ddb_entry: Pointer to device database entry1262 *1263 * This routine performs a TARGET RESET on the specified target.1264 * The caller must ensure that the ddb_entry pointers1265 * are valid before calling this routine.1266 **/1267int qla4xxx_reset_target(struct scsi_qla_host *ha,1268			 struct ddb_entry *ddb_entry)1269{1270	uint32_t mbox_cmd[MBOX_REG_COUNT];1271	uint32_t mbox_sts[MBOX_REG_COUNT];1272	int status = QLA_SUCCESS;1273 1274	DEBUG2(printk("scsi%ld:%d: target reset issued\n", ha->host_no,1275		      ddb_entry->fw_ddb_index));1276 1277	/*1278	 * Send target reset command to ISP, so that the ISP will return all1279	 * outstanding requests with RESET status1280	 */1281	memset(&mbox_cmd, 0, sizeof(mbox_cmd));1282	memset(&mbox_sts, 0, sizeof(mbox_sts));1283 1284	mbox_cmd[0] = MBOX_CMD_TARGET_WARM_RESET;1285	mbox_cmd[1] = ddb_entry->fw_ddb_index;1286	mbox_cmd[5] = 0x01;	/* Immediate Command Enable */1287 1288	qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0],1289				&mbox_sts[0]);1290	if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE &&1291	    mbox_sts[0] != MBOX_STS_COMMAND_ERROR)1292		status = QLA_ERROR;1293 1294	return status;1295}1296 1297int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr,1298		      uint32_t offset, uint32_t len)1299{1300	uint32_t mbox_cmd[MBOX_REG_COUNT];1301	uint32_t mbox_sts[MBOX_REG_COUNT];1302 1303	memset(&mbox_cmd, 0, sizeof(mbox_cmd));1304	memset(&mbox_sts, 0, sizeof(mbox_sts));1305 1306	mbox_cmd[0] = MBOX_CMD_READ_FLASH;1307	mbox_cmd[1] = LSDW(dma_addr);1308	mbox_cmd[2] = MSDW(dma_addr);1309	mbox_cmd[3] = offset;1310	mbox_cmd[4] = len;1311 1312	if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0], &mbox_sts[0]) !=1313	    QLA_SUCCESS) {1314		DEBUG2(printk("scsi%ld: %s: MBOX_CMD_READ_FLASH, failed w/ "1315		    "status %04X %04X, offset %08x, len %08x\n", ha->host_no,1316		    __func__, mbox_sts[0], mbox_sts[1], offset, len));1317		return QLA_ERROR;1318	}1319	return QLA_SUCCESS;1320}1321 1322/**1323 * qla4xxx_about_firmware - gets FW, iscsi draft and boot loader version1324 * @ha: Pointer to host adapter structure.1325 *1326 * Retrieves the FW version, iSCSI draft version & bootloader version of HBA.1327 * Mailboxes 2 & 3 may hold an address for data. Make sure that we write 0 to1328 * those mailboxes, if unused.1329 **/1330int qla4xxx_about_firmware(struct scsi_qla_host *ha)1331{1332	struct about_fw_info *about_fw = NULL;1333	dma_addr_t about_fw_dma;1334	uint32_t mbox_cmd[MBOX_REG_COUNT];1335	uint32_t mbox_sts[MBOX_REG_COUNT];1336	int status = QLA_ERROR;1337 1338	about_fw = dma_alloc_coherent(&ha->pdev->dev,1339				      sizeof(struct about_fw_info),1340				      &about_fw_dma, GFP_KERNEL);1341	if (!about_fw) {1342		DEBUG2(ql4_printk(KERN_ERR, ha, "%s: Unable to alloc memory "1343				  "for about_fw\n", __func__));1344		return status;1345	}1346 1347	memset(&mbox_cmd, 0, sizeof(mbox_cmd));1348	memset(&mbox_sts, 0, sizeof(mbox_sts));1349 1350	mbox_cmd[0] = MBOX_CMD_ABOUT_FW;1351	mbox_cmd[2] = LSDW(about_fw_dma);1352	mbox_cmd[3] = MSDW(about_fw_dma);1353	mbox_cmd[4] = sizeof(struct about_fw_info);1354 1355	status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, MBOX_REG_COUNT,1356					 &mbox_cmd[0], &mbox_sts[0]);1357	if (status != QLA_SUCCESS) {1358		DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_ABOUT_FW "1359				  "failed w/ status %04X\n", __func__,1360				  mbox_sts[0]));1361		goto exit_about_fw;1362	}1363 1364	/* Save version information. */1365	ha->fw_info.fw_major = le16_to_cpu(about_fw->fw_major);1366	ha->fw_info.fw_minor = le16_to_cpu(about_fw->fw_minor);1367	ha->fw_info.fw_patch = le16_to_cpu(about_fw->fw_patch);1368	ha->fw_info.fw_build = le16_to_cpu(about_fw->fw_build);1369	memcpy(ha->fw_info.fw_build_date, about_fw->fw_build_date,1370	       sizeof(about_fw->fw_build_date));1371	memcpy(ha->fw_info.fw_build_time, about_fw->fw_build_time,1372	       sizeof(about_fw->fw_build_time));1373	strcpy((char *)ha->fw_info.fw_build_user,1374	       skip_spaces((char *)about_fw->fw_build_user));1375	ha->fw_info.fw_load_source = le16_to_cpu(about_fw->fw_load_source);1376	ha->fw_info.iscsi_major = le16_to_cpu(about_fw->iscsi_major);1377	ha->fw_info.iscsi_minor = le16_to_cpu(about_fw->iscsi_minor);1378	ha->fw_info.bootload_major = le16_to_cpu(about_fw->bootload_major);1379	ha->fw_info.bootload_minor = le16_to_cpu(about_fw->bootload_minor);1380	ha->fw_info.bootload_patch = le16_to_cpu(about_fw->bootload_patch);1381	ha->fw_info.bootload_build = le16_to_cpu(about_fw->bootload_build);1382	strcpy((char *)ha->fw_info.extended_timestamp,1383	       skip_spaces((char *)about_fw->extended_timestamp));1384 1385	ha->fw_uptime_secs = le32_to_cpu(mbox_sts[5]);1386	ha->fw_uptime_msecs = le32_to_cpu(mbox_sts[6]);1387	status = QLA_SUCCESS;1388 1389exit_about_fw:1390	dma_free_coherent(&ha->pdev->dev, sizeof(struct about_fw_info),1391			  about_fw, about_fw_dma);1392	return status;1393}1394 1395int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, uint32_t options,1396			    dma_addr_t dma_addr)1397{1398	uint32_t mbox_cmd[MBOX_REG_COUNT];1399	uint32_t mbox_sts[MBOX_REG_COUNT];1400 1401	memset(&mbox_cmd, 0, sizeof(mbox_cmd));1402	memset(&mbox_sts, 0, sizeof(mbox_sts));1403 1404	mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY_DEFAULTS;1405	mbox_cmd[1] = options;1406	mbox_cmd[2] = LSDW(dma_addr);1407	mbox_cmd[3] = MSDW(dma_addr);1408 1409	if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) !=1410	    QLA_SUCCESS) {1411		DEBUG2(printk("scsi%ld: %s: failed status %04X\n",1412		     ha->host_no, __func__, mbox_sts[0]));1413		return QLA_ERROR;1414	}1415	return QLA_SUCCESS;1416}1417 1418int qla4xxx_req_ddb_entry(struct scsi_qla_host *ha, uint32_t ddb_index,1419			  uint32_t *mbx_sts)1420{1421	int status;1422	uint32_t mbox_cmd[MBOX_REG_COUNT];1423	uint32_t mbox_sts[MBOX_REG_COUNT];1424 1425	memset(&mbox_cmd, 0, sizeof(mbox_cmd));1426	memset(&mbox_sts, 0, sizeof(mbox_sts));1427 1428	mbox_cmd[0] = MBOX_CMD_REQUEST_DATABASE_ENTRY;1429	mbox_cmd[1] = ddb_index;1430 1431	status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0],1432					 &mbox_sts[0]);1433	if (status != QLA_SUCCESS) {1434		DEBUG2(ql4_printk(KERN_ERR, ha, "%s: failed status %04X\n",1435				   __func__, mbox_sts[0]));1436	}1437 1438	*mbx_sts = mbox_sts[0];1439	return status;1440}1441 1442int qla4xxx_clear_ddb_entry(struct scsi_qla_host *ha, uint32_t ddb_index)1443{1444	int status;1445	uint32_t mbox_cmd[MBOX_REG_COUNT];1446	uint32_t mbox_sts[MBOX_REG_COUNT];1447 1448	memset(&mbox_cmd, 0, sizeof(mbox_cmd));1449	memset(&mbox_sts, 0, sizeof(mbox_sts));1450 1451	mbox_cmd[0] = MBOX_CMD_CLEAR_DATABASE_ENTRY;1452	mbox_cmd[1] = ddb_index;1453 1454	status = qla4xxx_mailbox_command(ha, 2, 1, &mbox_cmd[0],1455					 &mbox_sts[0]);1456	if (status != QLA_SUCCESS) {1457		DEBUG2(ql4_printk(KERN_ERR, ha, "%s: failed status %04X\n",1458				   __func__, mbox_sts[0]));1459	}1460 1461	return status;1462}1463 1464int qla4xxx_set_flash(struct scsi_qla_host *ha, dma_addr_t dma_addr,1465		      uint32_t offset, uint32_t length, uint32_t options)1466{1467	uint32_t mbox_cmd[MBOX_REG_COUNT];1468	uint32_t mbox_sts[MBOX_REG_COUNT];1469	int status = QLA_SUCCESS;1470 1471	memset(&mbox_cmd, 0, sizeof(mbox_cmd));1472	memset(&mbox_sts, 0, sizeof(mbox_sts));1473 1474	mbox_cmd[0] = MBOX_CMD_WRITE_FLASH;1475	mbox_cmd[1] = LSDW(dma_addr);1476	mbox_cmd[2] = MSDW(dma_addr);1477	mbox_cmd[3] = offset;1478	mbox_cmd[4] = length;1479	mbox_cmd[5] = options;1480 1481	status = qla4xxx_mailbox_command(ha, 6, 2, &mbox_cmd[0], &mbox_sts[0]);1482	if (status != QLA_SUCCESS) {1483		DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_WRITE_FLASH "1484				  "failed w/ status %04X, mbx1 %04X\n",1485				  __func__, mbox_sts[0], mbox_sts[1]));1486	}1487	return status;1488}1489 1490int qla4xxx_bootdb_by_index(struct scsi_qla_host *ha,1491			    struct dev_db_entry *fw_ddb_entry,1492			    dma_addr_t fw_ddb_entry_dma, uint16_t ddb_index)1493{1494	uint32_t dev_db_start_offset = FLASH_OFFSET_DB_INFO;1495	uint32_t dev_db_end_offset;1496	int status = QLA_ERROR;1497 1498	memset(fw_ddb_entry, 0, sizeof(*fw_ddb_entry));1499 1500	dev_db_start_offset += (ddb_index * sizeof(*fw_ddb_entry));1501	dev_db_end_offset = FLASH_OFFSET_DB_END;1502 1503	if (dev_db_start_offset > dev_db_end_offset) {1504		DEBUG2(ql4_printk(KERN_ERR, ha,1505				  "%s:Invalid DDB index %d", __func__,1506				  ddb_index));1507		goto exit_bootdb_failed;1508	}1509 1510	if (qla4xxx_get_flash(ha, fw_ddb_entry_dma, dev_db_start_offset,1511			      sizeof(*fw_ddb_entry)) != QLA_SUCCESS) {1512		ql4_printk(KERN_ERR, ha, "scsi%ld: %s: Get Flash"1513			   "failed\n", ha->host_no, __func__);1514		goto exit_bootdb_failed;1515	}1516 1517	if (fw_ddb_entry->cookie == DDB_VALID_COOKIE)1518		status = QLA_SUCCESS;1519 1520exit_bootdb_failed:1521	return status;1522}1523 1524int qla4xxx_flashdb_by_index(struct scsi_qla_host *ha,1525			     struct dev_db_entry *fw_ddb_entry,1526			     dma_addr_t fw_ddb_entry_dma, uint16_t ddb_index)1527{1528	uint32_t dev_db_start_offset;1529	uint32_t dev_db_end_offset;1530	int status = QLA_ERROR;1531 1532	memset(fw_ddb_entry, 0, sizeof(*fw_ddb_entry));1533 1534	if (is_qla40XX(ha)) {1535		dev_db_start_offset = FLASH_OFFSET_DB_INFO;1536		dev_db_end_offset = FLASH_OFFSET_DB_END;1537	} else {1538		dev_db_start_offset = FLASH_RAW_ACCESS_ADDR +1539				      (ha->hw.flt_region_ddb << 2);1540		/* flt_ddb_size is DDB table size for both ports1541		 * so divide it by 2 to calculate the offset for second port1542		 */1543		if (ha->port_num == 1)1544			dev_db_start_offset += (ha->hw.flt_ddb_size / 2);1545 1546		dev_db_end_offset = dev_db_start_offset +1547				    (ha->hw.flt_ddb_size / 2);1548	}1549 1550	dev_db_start_offset += (ddb_index * sizeof(*fw_ddb_entry));1551 1552	if (dev_db_start_offset > dev_db_end_offset) {1553		DEBUG2(ql4_printk(KERN_ERR, ha,1554				  "%s:Invalid DDB index %d", __func__,1555				  ddb_index));1556		goto exit_fdb_failed;1557	}1558 1559	if (qla4xxx_get_flash(ha, fw_ddb_entry_dma, dev_db_start_offset,1560			      sizeof(*fw_ddb_entry)) != QLA_SUCCESS) {1561		ql4_printk(KERN_ERR, ha, "scsi%ld: %s: Get Flash failed\n",1562			   ha->host_no, __func__);1563		goto exit_fdb_failed;1564	}1565 1566	if (fw_ddb_entry->cookie == DDB_VALID_COOKIE)1567		status = QLA_SUCCESS;1568 1569exit_fdb_failed:1570	return status;1571}1572 1573int qla4xxx_get_chap(struct scsi_qla_host *ha, char *username, char *password,1574		     uint16_t idx)1575{1576	int ret = 0;1577	int rval = QLA_ERROR;1578	uint32_t offset = 0, chap_size;1579	struct ql4_chap_table *chap_table;1580	dma_addr_t chap_dma;1581 1582	chap_table = dma_pool_zalloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma);1583	if (chap_table == NULL)1584		return -ENOMEM;1585 1586	chap_size = sizeof(struct ql4_chap_table);1587 1588	if (is_qla40XX(ha))1589		offset = FLASH_CHAP_OFFSET | (idx * chap_size);1590	else {1591		offset = FLASH_RAW_ACCESS_ADDR + (ha->hw.flt_region_chap << 2);1592		/* flt_chap_size is CHAP table size for both ports1593		 * so divide it by 2 to calculate the offset for second port1594		 */1595		if (ha->port_num == 1)1596			offset += (ha->hw.flt_chap_size / 2);1597		offset += (idx * chap_size);1598	}1599 1600	rval = qla4xxx_get_flash(ha, chap_dma, offset, chap_size);1601	if (rval != QLA_SUCCESS) {1602		ret = -EINVAL;1603		goto exit_get_chap;1604	}1605 1606	DEBUG2(ql4_printk(KERN_INFO, ha, "Chap Cookie: x%x\n",1607		__le16_to_cpu(chap_table->cookie)));1608 1609	if (__le16_to_cpu(chap_table->cookie) != CHAP_VALID_COOKIE) {1610		ql4_printk(KERN_ERR, ha, "No valid chap entry found\n");1611		goto exit_get_chap;1612	}1613 1614	strscpy(password, chap_table->secret, QL4_CHAP_MAX_SECRET_LEN);1615	strscpy(username, chap_table->name, QL4_CHAP_MAX_NAME_LEN);1616	chap_table->cookie = cpu_to_le16(CHAP_VALID_COOKIE);1617 1618exit_get_chap:1619	dma_pool_free(ha->chap_dma_pool, chap_table, chap_dma);1620	return ret;1621}1622 1623/**1624 * qla4xxx_set_chap - Make a chap entry at the given index1625 * @ha: pointer to adapter structure1626 * @username: CHAP username to set1627 * @password: CHAP password to set1628 * @idx: CHAP index at which to make the entry1629 * @bidi: type of chap entry (chap_in or chap_out)1630 *1631 * Create chap entry at the given index with the information provided.1632 *1633 * Note: Caller should acquire the chap lock before getting here.1634 **/1635int qla4xxx_set_chap(struct scsi_qla_host *ha, char *username, char *password,1636		     uint16_t idx, int bidi)1637{1638	int ret = 0;1639	int rval = QLA_ERROR;1640	uint32_t offset = 0;1641	struct ql4_chap_table *chap_table;1642	uint32_t chap_size = 0;1643	dma_addr_t chap_dma;1644	ssize_t secret_len;1645 1646	chap_table = dma_pool_zalloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma);1647	if (chap_table == NULL) {1648		ret =  -ENOMEM;1649		goto exit_set_chap;1650	}1651 1652	if (bidi)1653		chap_table->flags |= BIT_6; /* peer */1654	else1655		chap_table->flags |= BIT_7; /* local */1656 1657	secret_len = strscpy(chap_table->secret, password,1658			     sizeof(chap_table->secret));1659	if (secret_len < MIN_CHAP_SECRET_LEN)1660		goto cleanup_chap_table;1661	chap_table->secret_len = (uint8_t)secret_len;1662	strscpy(chap_table->name, username, sizeof(chap_table->name));1663	chap_table->cookie = cpu_to_le16(CHAP_VALID_COOKIE);1664 1665	if (is_qla40XX(ha)) {1666		chap_size = MAX_CHAP_ENTRIES_40XX * sizeof(*chap_table);1667		offset = FLASH_CHAP_OFFSET;1668	} else { /* Single region contains CHAP info for both ports which is1669		  * divided into half for each port.1670		  */1671		chap_size = ha->hw.flt_chap_size / 2;1672		offset = FLASH_RAW_ACCESS_ADDR + (ha->hw.flt_region_chap << 2);1673		if (ha->port_num == 1)1674			offset += chap_size;1675	}1676 1677	offset += (idx * sizeof(struct ql4_chap_table));1678	rval = qla4xxx_set_flash(ha, chap_dma, offset,1679				sizeof(struct ql4_chap_table),1680				FLASH_OPT_RMW_COMMIT);1681 1682	if (rval == QLA_SUCCESS && ha->chap_list) {1683		/* Update ha chap_list cache */1684		memcpy((struct ql4_chap_table *)ha->chap_list + idx,1685		       chap_table, sizeof(struct ql4_chap_table));1686	}1687 1688cleanup_chap_table:1689	dma_pool_free(ha->chap_dma_pool, chap_table, chap_dma);1690	if (rval != QLA_SUCCESS)1691		ret =  -EINVAL;1692 1693exit_set_chap:1694	return ret;1695}1696 1697 1698int qla4xxx_get_uni_chap_at_index(struct scsi_qla_host *ha, char *username,1699				  char *password, uint16_t chap_index)1700{1701	int rval = QLA_ERROR;1702	struct ql4_chap_table *chap_table = NULL;1703	int max_chap_entries;1704 1705	if (!ha->chap_list) {1706		ql4_printk(KERN_ERR, ha, "Do not have CHAP table cache\n");1707		rval = QLA_ERROR;1708		goto exit_uni_chap;1709	}1710 1711	if (!username || !password) {1712		ql4_printk(KERN_ERR, ha, "No memory for username & secret\n");1713		rval = QLA_ERROR;1714		goto exit_uni_chap;1715	}1716 1717	if (is_qla80XX(ha))1718		max_chap_entries = (ha->hw.flt_chap_size / 2) /1719				   sizeof(struct ql4_chap_table);1720	else1721		max_chap_entries = MAX_CHAP_ENTRIES_40XX;1722 1723	if (chap_index > max_chap_entries) {1724		ql4_printk(KERN_ERR, ha, "Invalid Chap index\n");1725		rval = QLA_ERROR;1726		goto exit_uni_chap;1727	}1728 1729	mutex_lock(&ha->chap_sem);1730	chap_table = (struct ql4_chap_table *)ha->chap_list + chap_index;1731	if (chap_table->cookie != cpu_to_le16(CHAP_VALID_COOKIE)) {1732		rval = QLA_ERROR;1733		goto exit_unlock_uni_chap;1734	}1735 1736	if (!(chap_table->flags & BIT_7)) {1737		ql4_printk(KERN_ERR, ha, "Unidirectional entry not set\n");1738		rval = QLA_ERROR;1739		goto exit_unlock_uni_chap;1740	}1741 1742	strscpy(password, chap_table->secret, MAX_CHAP_SECRET_LEN);1743	strscpy(username, chap_table->name, MAX_CHAP_NAME_LEN);1744 1745	rval = QLA_SUCCESS;1746 1747exit_unlock_uni_chap:1748	mutex_unlock(&ha->chap_sem);1749exit_uni_chap:1750	return rval;1751}1752 1753/**1754 * qla4xxx_get_chap_index - Get chap index given username and secret1755 * @ha: pointer to adapter structure1756 * @username: CHAP username to be searched1757 * @password: CHAP password to be searched1758 * @bidi: Is this a BIDI CHAP1759 * @chap_index: CHAP index to be returned1760 *1761 * Match the username and password in the chap_list, return the index if a1762 * match is found. If a match is not found then add the entry in FLASH and1763 * return the index at which entry is written in the FLASH.1764 **/1765int qla4xxx_get_chap_index(struct scsi_qla_host *ha, char *username,1766			   char *password, int bidi, uint16_t *chap_index)1767{1768	int i, rval;1769	int free_index = -1;1770	int found_index = 0;1771	int max_chap_entries = 0;1772	struct ql4_chap_table *chap_table;1773 1774	if (is_qla80XX(ha))1775		max_chap_entries = (ha->hw.flt_chap_size / 2) /1776						sizeof(struct ql4_chap_table);1777	else1778		max_chap_entries = MAX_CHAP_ENTRIES_40XX;1779 1780	if (!ha->chap_list) {1781		ql4_printk(KERN_ERR, ha, "Do not have CHAP table cache\n");1782		return QLA_ERROR;1783	}1784 1785	if (!username || !password) {1786		ql4_printk(KERN_ERR, ha, "Do not have username and psw\n");1787		return QLA_ERROR;1788	}1789 1790	mutex_lock(&ha->chap_sem);1791	for (i = 0; i < max_chap_entries; i++) {1792		chap_table = (struct ql4_chap_table *)ha->chap_list + i;1793		if (chap_table->cookie !=1794		    cpu_to_le16(CHAP_VALID_COOKIE)) {1795			if (i > MAX_RESRV_CHAP_IDX && free_index == -1)1796				free_index = i;1797			continue;1798		}1799		if (bidi) {1800			if (chap_table->flags & BIT_7)1801				continue;1802		} else {1803			if (chap_table->flags & BIT_6)1804				continue;1805		}1806		if (!strncmp(chap_table->secret, password,1807			     MAX_CHAP_SECRET_LEN) &&1808		    !strncmp(chap_table->name, username,1809			     MAX_CHAP_NAME_LEN)) {1810			*chap_index = i;1811			found_index = 1;1812			break;1813		}1814	}1815 1816	/* If chap entry is not present and a free index is available then1817	 * write the entry in flash1818	 */1819	if (!found_index && free_index != -1) {1820		rval = qla4xxx_set_chap(ha, username, password,1821					free_index, bidi);1822		if (!rval) {1823			*chap_index = free_index;1824			found_index = 1;1825		}1826	}1827 1828	mutex_unlock(&ha->chap_sem);1829 1830	if (found_index)1831		return QLA_SUCCESS;1832	return QLA_ERROR;1833}1834 1835int qla4xxx_conn_close_sess_logout(struct scsi_qla_host *ha,1836				   uint16_t fw_ddb_index,1837				   uint16_t connection_id,1838				   uint16_t option)1839{1840	uint32_t mbox_cmd[MBOX_REG_COUNT];1841	uint32_t mbox_sts[MBOX_REG_COUNT];1842	int status = QLA_SUCCESS;1843 1844	memset(&mbox_cmd, 0, sizeof(mbox_cmd));1845	memset(&mbox_sts, 0, sizeof(mbox_sts));1846 1847	mbox_cmd[0] = MBOX_CMD_CONN_CLOSE_SESS_LOGOUT;1848	mbox_cmd[1] = fw_ddb_index;1849	mbox_cmd[2] = connection_id;1850	mbox_cmd[3] = option;1851 1852	status = qla4xxx_mailbox_command(ha, 4, 2, &mbox_cmd[0], &mbox_sts[0]);1853	if (status != QLA_SUCCESS) {1854		DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_CONN_CLOSE "1855				  "option %04x failed w/ status %04X %04X\n",1856				  __func__, option, mbox_sts[0], mbox_sts[1]));1857	}1858	return status;1859}1860 1861/**1862 * qla4_84xx_extend_idc_tmo - Extend IDC Timeout.1863 * @ha: Pointer to host adapter structure.1864 * @ext_tmo: idc timeout value1865 *1866 * Requests firmware to extend the idc timeout value.1867 **/1868static int qla4_84xx_extend_idc_tmo(struct scsi_qla_host *ha, uint32_t ext_tmo)1869{1870	uint32_t mbox_cmd[MBOX_REG_COUNT];1871	uint32_t mbox_sts[MBOX_REG_COUNT];1872	int status;1873 1874	memset(&mbox_cmd, 0, sizeof(mbox_cmd));1875	memset(&mbox_sts, 0, sizeof(mbox_sts));1876	ext_tmo &= 0xf;1877 1878	mbox_cmd[0] = MBOX_CMD_IDC_TIME_EXTEND;1879	mbox_cmd[1] = ((ha->idc_info.request_desc & 0xfffff0ff) |1880		       (ext_tmo << 8));		/* new timeout */1881	mbox_cmd[2] = ha->idc_info.info1;1882	mbox_cmd[3] = ha->idc_info.info2;1883	mbox_cmd[4] = ha->idc_info.info3;1884 1885	status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, MBOX_REG_COUNT,1886					 mbox_cmd, mbox_sts);1887	if (status != QLA_SUCCESS) {1888		DEBUG2(ql4_printk(KERN_INFO, ha,1889				  "scsi%ld: %s: failed status %04X\n",1890				  ha->host_no, __func__, mbox_sts[0]));1891		return QLA_ERROR;1892	} else {1893		ql4_printk(KERN_INFO, ha, "%s: IDC timeout extended by %d secs\n",1894			   __func__, ext_tmo);1895	}1896 1897	return QLA_SUCCESS;1898}1899 1900int qla4xxx_disable_acb(struct scsi_qla_host *ha)1901{1902	uint32_t mbox_cmd[MBOX_REG_COUNT];1903	uint32_t mbox_sts[MBOX_REG_COUNT];1904	int status = QLA_SUCCESS;1905 1906	memset(&mbox_cmd, 0, sizeof(mbox_cmd));1907	memset(&mbox_sts, 0, sizeof(mbox_sts));1908 1909	mbox_cmd[0] = MBOX_CMD_DISABLE_ACB;1910 1911	status = qla4xxx_mailbox_command(ha, 8, 5, &mbox_cmd[0], &mbox_sts[0]);1912	if (status != QLA_SUCCESS) {1913		DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_DISABLE_ACB "1914				  "failed w/ status %04X %04X %04X", __func__,1915				  mbox_sts[0], mbox_sts[1], mbox_sts[2]));1916	} else {1917		if (is_qla8042(ha) &&1918		    test_bit(DPC_POST_IDC_ACK, &ha->dpc_flags) &&1919		    (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE)) {1920			/*1921			 * Disable ACB mailbox command takes time to complete1922			 * based on the total number of targets connected.1923			 * For 512 targets, it took approximately 5 secs to1924			 * complete. Setting the timeout value to 8, with the 31925			 * secs buffer.1926			 */1927			qla4_84xx_extend_idc_tmo(ha, IDC_EXTEND_TOV);1928			if (!wait_for_completion_timeout(&ha->disable_acb_comp,1929							 IDC_EXTEND_TOV * HZ)) {1930				ql4_printk(KERN_WARNING, ha, "%s: Disable ACB Completion not received\n",1931					   __func__);1932			}1933		}1934	}1935	return status;1936}1937 1938int qla4xxx_get_acb(struct scsi_qla_host *ha, dma_addr_t acb_dma,1939		    uint32_t acb_type, uint32_t len)1940{1941	uint32_t mbox_cmd[MBOX_REG_COUNT];1942	uint32_t mbox_sts[MBOX_REG_COUNT];1943	int status = QLA_SUCCESS;1944 1945	memset(&mbox_cmd, 0, sizeof(mbox_cmd));1946	memset(&mbox_sts, 0, sizeof(mbox_sts));1947 1948	mbox_cmd[0] = MBOX_CMD_GET_ACB;1949	mbox_cmd[1] = acb_type;1950	mbox_cmd[2] = LSDW(acb_dma);1951	mbox_cmd[3] = MSDW(acb_dma);1952	mbox_cmd[4] = len;1953 1954	status = qla4xxx_mailbox_command(ha, 5, 5, &mbox_cmd[0], &mbox_sts[0]);1955	if (status != QLA_SUCCESS) {1956		DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_GET_ACB "1957				  "failed w/ status %04X\n", __func__,1958				  mbox_sts[0]));1959	}1960	return status;1961}1962 1963int qla4xxx_set_acb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,1964		    uint32_t *mbox_sts, dma_addr_t acb_dma)1965{1966	int status = QLA_SUCCESS;1967 1968	memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT);1969	memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT);1970	mbox_cmd[0] = MBOX_CMD_SET_ACB;1971	mbox_cmd[1] = 0; /* Primary ACB */1972	mbox_cmd[2] = LSDW(acb_dma);1973	mbox_cmd[3] = MSDW(acb_dma);1974	mbox_cmd[4] = sizeof(struct addr_ctrl_blk);1975 1976	status = qla4xxx_mailbox_command(ha, 5, 5, &mbox_cmd[0], &mbox_sts[0]);1977	if (status != QLA_SUCCESS) {1978		DEBUG2(ql4_printk(KERN_WARNING, ha,  "%s: MBOX_CMD_SET_ACB "1979				  "failed w/ status %04X\n", __func__,1980				  mbox_sts[0]));1981	}1982	return status;1983}1984 1985int qla4xxx_set_param_ddbentry(struct scsi_qla_host *ha,1986			       struct ddb_entry *ddb_entry,1987			       struct iscsi_cls_conn *cls_conn,1988			       uint32_t *mbx_sts)1989{1990	struct dev_db_entry *fw_ddb_entry;1991	struct iscsi_conn *conn;1992	struct iscsi_session *sess;1993	struct qla_conn *qla_conn;1994	struct sockaddr *dst_addr;1995	dma_addr_t fw_ddb_entry_dma;1996	int status = QLA_SUCCESS;1997	int rval = 0;1998	struct sockaddr_in *addr;1999	struct sockaddr_in6 *addr6;2000	char *ip;2001	uint16_t iscsi_opts = 0;2002	uint32_t options = 0;2003	uint16_t idx, *ptid;2004 2005	fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),2006					  &fw_ddb_entry_dma, GFP_KERNEL);2007	if (!fw_ddb_entry) {2008		DEBUG2(ql4_printk(KERN_ERR, ha,2009				  "%s: Unable to allocate dma buffer.\n",2010				  __func__));2011		rval = -ENOMEM;2012		goto exit_set_param_no_free;2013	}2014 2015	conn = cls_conn->dd_data;2016	qla_conn = conn->dd_data;2017	sess = conn->session;2018	dst_addr = (struct sockaddr *)&qla_conn->qla_ep->dst_addr;2019 2020	if (dst_addr->sa_family == AF_INET6)2021		options |= IPV6_DEFAULT_DDB_ENTRY;2022 2023	status = qla4xxx_get_default_ddb(ha, options, fw_ddb_entry_dma);2024	if (status == QLA_ERROR) {2025		rval = -EINVAL;2026		goto exit_set_param;2027	}2028 2029	ptid = (uint16_t *)&fw_ddb_entry->isid[1];2030	*ptid = cpu_to_le16((uint16_t)ddb_entry->sess->target_id);2031 2032	DEBUG2(ql4_printk(KERN_INFO, ha, "ISID [%pmR]\n", fw_ddb_entry->isid));2033 2034	iscsi_opts = le16_to_cpu(fw_ddb_entry->iscsi_options);2035	memset(fw_ddb_entry->iscsi_alias, 0, sizeof(fw_ddb_entry->iscsi_alias));2036 2037	memset(fw_ddb_entry->iscsi_name, 0, sizeof(fw_ddb_entry->iscsi_name));2038 2039	if (sess->targetname != NULL) {2040		memcpy(fw_ddb_entry->iscsi_name, sess->targetname,2041		       min(strlen(sess->targetname),2042		       sizeof(fw_ddb_entry->iscsi_name)));2043	}2044 2045	memset(fw_ddb_entry->ip_addr, 0, sizeof(fw_ddb_entry->ip_addr));2046	memset(fw_ddb_entry->tgt_addr, 0, sizeof(fw_ddb_entry->tgt_addr));2047 2048	fw_ddb_entry->options =  DDB_OPT_TARGET | DDB_OPT_AUTO_SENDTGTS_DISABLE;2049 2050	if (dst_addr->sa_family == AF_INET) {2051		addr = (struct sockaddr_in *)dst_addr;2052		ip = (char *)&addr->sin_addr;2053		memcpy(fw_ddb_entry->ip_addr, ip, IP_ADDR_LEN);2054		fw_ddb_entry->port = cpu_to_le16(ntohs(addr->sin_port));2055		DEBUG2(ql4_printk(KERN_INFO, ha,2056				  "%s: Destination Address [%pI4]: index [%d]\n",2057				   __func__, fw_ddb_entry->ip_addr,2058				  ddb_entry->fw_ddb_index));2059	} else if (dst_addr->sa_family == AF_INET6) {2060		addr6 = (struct sockaddr_in6 *)dst_addr;2061		ip = (char *)&addr6->sin6_addr;2062		memcpy(fw_ddb_entry->ip_addr, ip, IPv6_ADDR_LEN);2063		fw_ddb_entry->port = cpu_to_le16(ntohs(addr6->sin6_port));2064		fw_ddb_entry->options |= DDB_OPT_IPV6_DEVICE;2065		DEBUG2(ql4_printk(KERN_INFO, ha,2066				  "%s: Destination Address [%pI6]: index [%d]\n",2067				   __func__, fw_ddb_entry->ip_addr,2068				  ddb_entry->fw_ddb_index));2069	} else {2070		ql4_printk(KERN_ERR, ha,2071			   "%s: Failed to get IP Address\n",2072			   __func__);2073		rval = -EINVAL;2074		goto exit_set_param;2075	}2076 2077	/* CHAP */2078	if (sess->username != NULL && sess->password != NULL) {2079		if (strlen(sess->username) && strlen(sess->password)) {2080			iscsi_opts |= BIT_7;2081 2082			rval = qla4xxx_get_chap_index(ha, sess->username,2083						sess->password,2084						LOCAL_CHAP, &idx);2085			if (rval)2086				goto exit_set_param;2087 2088			fw_ddb_entry->chap_tbl_idx = cpu_to_le16(idx);2089		}2090	}2091 2092	if (sess->username_in != NULL && sess->password_in != NULL) {2093		/* Check if BIDI CHAP */2094		if (strlen(sess->username_in) && strlen(sess->password_in)) {2095			iscsi_opts |= BIT_4;2096 2097			rval = qla4xxx_get_chap_index(ha, sess->username_in,2098						      sess->password_in,2099						      BIDI_CHAP, &idx);2100			if (rval)2101				goto exit_set_param;2102		}2103	}2104 2105	if (sess->initial_r2t_en)2106		iscsi_opts |= BIT_10;2107 2108	if (sess->imm_data_en)2109		iscsi_opts |= BIT_11;2110 2111	fw_ddb_entry->iscsi_options = cpu_to_le16(iscsi_opts);2112 2113	if (conn->max_recv_dlength)2114		fw_ddb_entry->iscsi_max_rcv_data_seg_len =2115		  cpu_to_le16((conn->max_recv_dlength / BYTE_UNITS));2116 2117	if (sess->max_r2t)2118		fw_ddb_entry->iscsi_max_outsnd_r2t = cpu_to_le16(sess->max_r2t);2119 2120	if (sess->first_burst)2121		fw_ddb_entry->iscsi_first_burst_len =2122		       cpu_to_le16((sess->first_burst / BYTE_UNITS));2123 2124	if (sess->max_burst)2125		fw_ddb_entry->iscsi_max_burst_len =2126			cpu_to_le16((sess->max_burst / BYTE_UNITS));2127 2128	if (sess->time2wait)2129		fw_ddb_entry->iscsi_def_time2wait =2130			cpu_to_le16(sess->time2wait);2131 2132	if (sess->time2retain)2133		fw_ddb_entry->iscsi_def_time2retain =2134			cpu_to_le16(sess->time2retain);2135 2136	status = qla4xxx_set_ddb_entry(ha, ddb_entry->fw_ddb_index,2137				       fw_ddb_entry_dma, mbx_sts);2138 2139	if (status != QLA_SUCCESS)2140		rval = -EINVAL;2141exit_set_param:2142	dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),2143			  fw_ddb_entry, fw_ddb_entry_dma);2144exit_set_param_no_free:2145	return rval;2146}2147 2148int qla4xxx_get_mgmt_data(struct scsi_qla_host *ha, uint16_t fw_ddb_index,2149			  uint16_t stats_size, dma_addr_t stats_dma)2150{2151	int status = QLA_SUCCESS;2152	uint32_t mbox_cmd[MBOX_REG_COUNT];2153	uint32_t mbox_sts[MBOX_REG_COUNT];2154 2155	memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT);2156	memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT);2157	mbox_cmd[0] = MBOX_CMD_GET_MANAGEMENT_DATA;2158	mbox_cmd[1] = fw_ddb_index;2159	mbox_cmd[2] = LSDW(stats_dma);2160	mbox_cmd[3] = MSDW(stats_dma);2161	mbox_cmd[4] = stats_size;2162 2163	status = qla4xxx_mailbox_command(ha, 5, 1, &mbox_cmd[0], &mbox_sts[0]);2164	if (status != QLA_SUCCESS) {2165		DEBUG2(ql4_printk(KERN_WARNING, ha,2166				  "%s: MBOX_CMD_GET_MANAGEMENT_DATA "2167				  "failed w/ status %04X\n", __func__,2168				  mbox_sts[0]));2169	}2170	return status;2171}2172 2173int qla4xxx_get_ip_state(struct scsi_qla_host *ha, uint32_t acb_idx,2174			 uint32_t ip_idx, uint32_t *sts)2175{2176	uint32_t mbox_cmd[MBOX_REG_COUNT];2177	uint32_t mbox_sts[MBOX_REG_COUNT];2178	int status = QLA_SUCCESS;2179 2180	memset(&mbox_cmd, 0, sizeof(mbox_cmd));2181	memset(&mbox_sts, 0, sizeof(mbox_sts));2182	mbox_cmd[0] = MBOX_CMD_GET_IP_ADDR_STATE;2183	mbox_cmd[1] = acb_idx;2184	mbox_cmd[2] = ip_idx;2185 2186	status = qla4xxx_mailbox_command(ha, 3, 8, &mbox_cmd[0], &mbox_sts[0]);2187	if (status != QLA_SUCCESS) {2188		DEBUG2(ql4_printk(KERN_WARNING, ha,  "%s: "2189				  "MBOX_CMD_GET_IP_ADDR_STATE failed w/ "2190				  "status %04X\n", __func__, mbox_sts[0]));2191	}2192	memcpy(sts, mbox_sts, sizeof(mbox_sts));2193	return status;2194}2195 2196int qla4xxx_get_nvram(struct scsi_qla_host *ha, dma_addr_t nvram_dma,2197		      uint32_t offset, uint32_t size)2198{2199	int status = QLA_SUCCESS;2200	uint32_t mbox_cmd[MBOX_REG_COUNT];2201	uint32_t mbox_sts[MBOX_REG_COUNT];2202 2203	memset(&mbox_cmd, 0, sizeof(mbox_cmd));2204	memset(&mbox_sts, 0, sizeof(mbox_sts));2205 2206	mbox_cmd[0] = MBOX_CMD_GET_NVRAM;2207	mbox_cmd[1] = LSDW(nvram_dma);2208	mbox_cmd[2] = MSDW(nvram_dma);2209	mbox_cmd[3] = offset;2210	mbox_cmd[4] = size;2211 2212	status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0],2213					 &mbox_sts[0]);2214	if (status != QLA_SUCCESS) {2215		DEBUG2(ql4_printk(KERN_ERR, ha, "scsi%ld: %s: failed "2216				  "status %04X\n", ha->host_no, __func__,2217				  mbox_sts[0]));2218	}2219	return status;2220}2221 2222int qla4xxx_set_nvram(struct scsi_qla_host *ha, dma_addr_t nvram_dma,2223		      uint32_t offset, uint32_t size)2224{2225	int status = QLA_SUCCESS;2226	uint32_t mbox_cmd[MBOX_REG_COUNT];2227	uint32_t mbox_sts[MBOX_REG_COUNT];2228 2229	memset(&mbox_cmd, 0, sizeof(mbox_cmd));2230	memset(&mbox_sts, 0, sizeof(mbox_sts));2231 2232	mbox_cmd[0] = MBOX_CMD_SET_NVRAM;2233	mbox_cmd[1] = LSDW(nvram_dma);2234	mbox_cmd[2] = MSDW(nvram_dma);2235	mbox_cmd[3] = offset;2236	mbox_cmd[4] = size;2237 2238	status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0],2239					 &mbox_sts[0]);2240	if (status != QLA_SUCCESS) {2241		DEBUG2(ql4_printk(KERN_ERR, ha, "scsi%ld: %s: failed "2242				  "status %04X\n", ha->host_no, __func__,2243				  mbox_sts[0]));2244	}2245	return status;2246}2247 2248int qla4xxx_restore_factory_defaults(struct scsi_qla_host *ha,2249				     uint32_t region, uint32_t field0,2250				     uint32_t field1)2251{2252	int status = QLA_SUCCESS;2253	uint32_t mbox_cmd[MBOX_REG_COUNT];2254	uint32_t mbox_sts[MBOX_REG_COUNT];2255 2256	memset(&mbox_cmd, 0, sizeof(mbox_cmd));2257	memset(&mbox_sts, 0, sizeof(mbox_sts));2258 2259	mbox_cmd[0] = MBOX_CMD_RESTORE_FACTORY_DEFAULTS;2260	mbox_cmd[3] = region;2261	mbox_cmd[4] = field0;2262	mbox_cmd[5] = field1;2263 2264	status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 3, &mbox_cmd[0],2265					 &mbox_sts[0]);2266	if (status != QLA_SUCCESS) {2267		DEBUG2(ql4_printk(KERN_ERR, ha, "scsi%ld: %s: failed "2268				  "status %04X\n", ha->host_no, __func__,2269				  mbox_sts[0]));2270	}2271	return status;2272}2273 2274/**2275 * qla4_8xxx_set_param - set driver version in firmware.2276 * @ha: Pointer to host adapter structure.2277 * @param: Parameter to set i.e driver version2278 **/2279int qla4_8xxx_set_param(struct scsi_qla_host *ha, int param)2280{2281	uint32_t mbox_cmd[MBOX_REG_COUNT];2282	uint32_t mbox_sts[MBOX_REG_COUNT];2283	uint32_t status;2284 2285	memset(&mbox_cmd, 0, sizeof(mbox_cmd));2286	memset(&mbox_sts, 0, sizeof(mbox_sts));2287 2288	mbox_cmd[0] = MBOX_CMD_SET_PARAM;2289	if (param == SET_DRVR_VERSION) {2290		mbox_cmd[1] = SET_DRVR_VERSION;2291		strscpy((char *)&mbox_cmd[2], QLA4XXX_DRIVER_VERSION,2292			MAX_DRVR_VER_LEN);2293	} else {2294		ql4_printk(KERN_ERR, ha, "%s: invalid parameter 0x%x\n",2295			   __func__, param);2296		status = QLA_ERROR;2297		goto exit_set_param;2298	}2299 2300	status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, mbox_cmd,2301					 mbox_sts);2302	if (status == QLA_ERROR)2303		ql4_printk(KERN_ERR, ha, "%s: failed status %04X\n",2304			   __func__, mbox_sts[0]);2305 2306exit_set_param:2307	return status;2308}2309 2310/**2311 * qla4_83xx_post_idc_ack - post IDC ACK2312 * @ha: Pointer to host adapter structure.2313 *2314 * Posts IDC ACK for IDC Request Notification AEN.2315 **/2316int qla4_83xx_post_idc_ack(struct scsi_qla_host *ha)2317{2318	uint32_t mbox_cmd[MBOX_REG_COUNT];2319	uint32_t mbox_sts[MBOX_REG_COUNT];2320	int status;2321 2322	memset(&mbox_cmd, 0, sizeof(mbox_cmd));2323	memset(&mbox_sts, 0, sizeof(mbox_sts));2324 2325	mbox_cmd[0] = MBOX_CMD_IDC_ACK;2326	mbox_cmd[1] = ha->idc_info.request_desc;2327	mbox_cmd[2] = ha->idc_info.info1;2328	mbox_cmd[3] = ha->idc_info.info2;2329	mbox_cmd[4] = ha->idc_info.info3;2330 2331	status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, MBOX_REG_COUNT,2332					 mbox_cmd, mbox_sts);2333	if (status == QLA_ERROR)2334		ql4_printk(KERN_ERR, ha, "%s: failed status %04X\n", __func__,2335			   mbox_sts[0]);2336	else2337	       ql4_printk(KERN_INFO, ha, "%s: IDC ACK posted\n", __func__);2338 2339	return status;2340}2341 2342int qla4_84xx_config_acb(struct scsi_qla_host *ha, int acb_config)2343{2344	uint32_t mbox_cmd[MBOX_REG_COUNT];2345	uint32_t mbox_sts[MBOX_REG_COUNT];2346	struct addr_ctrl_blk *acb = NULL;2347	uint32_t acb_len = sizeof(struct addr_ctrl_blk);2348	int rval = QLA_SUCCESS;2349	dma_addr_t acb_dma;2350 2351	acb = dma_alloc_coherent(&ha->pdev->dev,2352				 sizeof(struct addr_ctrl_blk),2353				 &acb_dma, GFP_KERNEL);2354	if (!acb) {2355		ql4_printk(KERN_ERR, ha, "%s: Unable to alloc acb\n", __func__);2356		rval = QLA_ERROR;2357		goto exit_config_acb;2358	}2359	memset(acb, 0, acb_len);2360 2361	switch (acb_config) {2362	case ACB_CONFIG_DISABLE:2363		rval = qla4xxx_get_acb(ha, acb_dma, 0, acb_len);2364		if (rval != QLA_SUCCESS)2365			goto exit_free_acb;2366 2367		rval = qla4xxx_disable_acb(ha);2368		if (rval != QLA_SUCCESS)2369			goto exit_free_acb;2370 2371		if (!ha->saved_acb)2372			ha->saved_acb = kzalloc(acb_len, GFP_KERNEL);2373 2374		if (!ha->saved_acb) {2375			ql4_printk(KERN_ERR, ha, "%s: Unable to alloc acb\n",2376				   __func__);2377			rval = QLA_ERROR;2378			goto exit_free_acb;2379		}2380		memcpy(ha->saved_acb, acb, acb_len);2381		break;2382	case ACB_CONFIG_SET:2383 2384		if (!ha->saved_acb) {2385			ql4_printk(KERN_ERR, ha, "%s: Can't set ACB, Saved ACB not available\n",2386				   __func__);2387			rval = QLA_ERROR;2388			goto exit_free_acb;2389		}2390 2391		memcpy(acb, ha->saved_acb, acb_len);2392 2393		rval = qla4xxx_set_acb(ha, &mbox_cmd[0], &mbox_sts[0], acb_dma);2394		if (rval != QLA_SUCCESS)2395			goto exit_free_acb;2396 2397		break;2398	default:2399		ql4_printk(KERN_ERR, ha, "%s: Invalid ACB Configuration\n",2400			   __func__);2401	}2402 2403exit_free_acb:2404	dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk), acb,2405			  acb_dma);2406exit_config_acb:2407	if ((acb_config == ACB_CONFIG_SET) && ha->saved_acb) {2408		kfree(ha->saved_acb);2409		ha->saved_acb = NULL;2410	}2411	DEBUG2(ql4_printk(KERN_INFO, ha,2412			  "%s %s\n", __func__,2413			  rval == QLA_SUCCESS ? "SUCCEEDED" : "FAILED"));2414	return rval;2415}2416 2417int qla4_83xx_get_port_config(struct scsi_qla_host *ha, uint32_t *config)2418{2419	uint32_t mbox_cmd[MBOX_REG_COUNT];2420	uint32_t mbox_sts[MBOX_REG_COUNT];2421	int status;2422 2423	memset(&mbox_cmd, 0, sizeof(mbox_cmd));2424	memset(&mbox_sts, 0, sizeof(mbox_sts));2425 2426	mbox_cmd[0] = MBOX_CMD_GET_PORT_CONFIG;2427 2428	status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, MBOX_REG_COUNT,2429					 mbox_cmd, mbox_sts);2430	if (status == QLA_SUCCESS)2431		*config = mbox_sts[1];2432	else2433		ql4_printk(KERN_ERR, ha, "%s: failed status %04X\n", __func__,2434			   mbox_sts[0]);2435 2436	return status;2437}2438 2439int qla4_83xx_set_port_config(struct scsi_qla_host *ha, uint32_t *config)2440{2441	uint32_t mbox_cmd[MBOX_REG_COUNT];2442	uint32_t mbox_sts[MBOX_REG_COUNT];2443	int status;2444 2445	memset(&mbox_cmd, 0, sizeof(mbox_cmd));2446	memset(&mbox_sts, 0, sizeof(mbox_sts));2447 2448	mbox_cmd[0] = MBOX_CMD_SET_PORT_CONFIG;2449	mbox_cmd[1] = *config;2450 2451	status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, MBOX_REG_COUNT,2452				mbox_cmd, mbox_sts);2453	if (status != QLA_SUCCESS)2454		ql4_printk(KERN_ERR, ha, "%s: failed status %04X\n", __func__,2455			   mbox_sts[0]);2456 2457	return status;2458}2459