brintos

brintos / linux-shallow public Read only

0
0
Text · 114.7 KiB · 6dfb70e Raw
4478 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * QLogic Fibre Channel HBA Driver4 * Copyright (c)  2003-2014 QLogic Corporation5 */6#include "qla_def.h"7#include <linux/delay.h>8#include <linux/io-64-nonatomic-lo-hi.h>9#include <linux/pci.h>10#include <linux/ratelimit.h>11#include <linux/vmalloc.h>12#include <scsi/scsi_tcq.h>13 14#define MASK(n)			((1ULL<<(n))-1)15#define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | \16	((addr >> 25) & 0x3ff))17#define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) | \18	((addr >> 25) & 0x3ff))19#define MS_WIN(addr) (addr & 0x0ffc0000)20#define QLA82XX_PCI_MN_2M   (0)21#define QLA82XX_PCI_MS_2M   (0x80000)22#define QLA82XX_PCI_OCM0_2M (0xc0000)23#define VALID_OCM_ADDR(addr) (((addr) & 0x3f800) != 0x3f800)24#define GET_MEM_OFFS_2M(addr) (addr & MASK(18))25#define BLOCK_PROTECT_BITS 0x0F26 27/* CRB window related */28#define CRB_BLK(off)	((off >> 20) & 0x3f)29#define CRB_SUBBLK(off)	((off >> 16) & 0xf)30#define CRB_WINDOW_2M	(0x130060)31#define QLA82XX_PCI_CAMQM_2M_END	(0x04800800UL)32#define CRB_HI(off)	((qla82xx_crb_hub_agt[CRB_BLK(off)] << 20) | \33			((off) & 0xf0000))34#define QLA82XX_PCI_CAMQM_2M_BASE	(0x000ff800UL)35#define CRB_INDIRECT_2M	(0x1e0000UL)36 37#define MAX_CRB_XFORM 6038static unsigned long crb_addr_xform[MAX_CRB_XFORM];39static int qla82xx_crb_table_initialized;40 41#define qla82xx_crb_addr_transform(name) \42	(crb_addr_xform[QLA82XX_HW_PX_MAP_CRB_##name] = \43	QLA82XX_HW_CRB_HUB_AGT_ADR_##name << 20)44 45const int MD_MIU_TEST_AGT_RDDATA[] = {46	0x410000A8, 0x410000AC,47	0x410000B8, 0x410000BC48};49 50static void qla82xx_crb_addr_transform_setup(void)51{52	qla82xx_crb_addr_transform(XDMA);53	qla82xx_crb_addr_transform(TIMR);54	qla82xx_crb_addr_transform(SRE);55	qla82xx_crb_addr_transform(SQN3);56	qla82xx_crb_addr_transform(SQN2);57	qla82xx_crb_addr_transform(SQN1);58	qla82xx_crb_addr_transform(SQN0);59	qla82xx_crb_addr_transform(SQS3);60	qla82xx_crb_addr_transform(SQS2);61	qla82xx_crb_addr_transform(SQS1);62	qla82xx_crb_addr_transform(SQS0);63	qla82xx_crb_addr_transform(RPMX7);64	qla82xx_crb_addr_transform(RPMX6);65	qla82xx_crb_addr_transform(RPMX5);66	qla82xx_crb_addr_transform(RPMX4);67	qla82xx_crb_addr_transform(RPMX3);68	qla82xx_crb_addr_transform(RPMX2);69	qla82xx_crb_addr_transform(RPMX1);70	qla82xx_crb_addr_transform(RPMX0);71	qla82xx_crb_addr_transform(ROMUSB);72	qla82xx_crb_addr_transform(SN);73	qla82xx_crb_addr_transform(QMN);74	qla82xx_crb_addr_transform(QMS);75	qla82xx_crb_addr_transform(PGNI);76	qla82xx_crb_addr_transform(PGND);77	qla82xx_crb_addr_transform(PGN3);78	qla82xx_crb_addr_transform(PGN2);79	qla82xx_crb_addr_transform(PGN1);80	qla82xx_crb_addr_transform(PGN0);81	qla82xx_crb_addr_transform(PGSI);82	qla82xx_crb_addr_transform(PGSD);83	qla82xx_crb_addr_transform(PGS3);84	qla82xx_crb_addr_transform(PGS2);85	qla82xx_crb_addr_transform(PGS1);86	qla82xx_crb_addr_transform(PGS0);87	qla82xx_crb_addr_transform(PS);88	qla82xx_crb_addr_transform(PH);89	qla82xx_crb_addr_transform(NIU);90	qla82xx_crb_addr_transform(I2Q);91	qla82xx_crb_addr_transform(EG);92	qla82xx_crb_addr_transform(MN);93	qla82xx_crb_addr_transform(MS);94	qla82xx_crb_addr_transform(CAS2);95	qla82xx_crb_addr_transform(CAS1);96	qla82xx_crb_addr_transform(CAS0);97	qla82xx_crb_addr_transform(CAM);98	qla82xx_crb_addr_transform(C2C1);99	qla82xx_crb_addr_transform(C2C0);100	qla82xx_crb_addr_transform(SMB);101	qla82xx_crb_addr_transform(OCM0);102	/*103	 * Used only in P3 just define it for P2 also.104	 */105	qla82xx_crb_addr_transform(I2C0);106 107	qla82xx_crb_table_initialized = 1;108}109 110static struct crb_128M_2M_block_map crb_128M_2M_map[64] = {111	{{{0, 0,         0,         0} } },112	{{{1, 0x0100000, 0x0102000, 0x120000},113	{1, 0x0110000, 0x0120000, 0x130000},114	{1, 0x0120000, 0x0122000, 0x124000},115	{1, 0x0130000, 0x0132000, 0x126000},116	{1, 0x0140000, 0x0142000, 0x128000},117	{1, 0x0150000, 0x0152000, 0x12a000},118	{1, 0x0160000, 0x0170000, 0x110000},119	{1, 0x0170000, 0x0172000, 0x12e000},120	{0, 0x0000000, 0x0000000, 0x000000},121	{0, 0x0000000, 0x0000000, 0x000000},122	{0, 0x0000000, 0x0000000, 0x000000},123	{0, 0x0000000, 0x0000000, 0x000000},124	{0, 0x0000000, 0x0000000, 0x000000},125	{0, 0x0000000, 0x0000000, 0x000000},126	{1, 0x01e0000, 0x01e0800, 0x122000},127	{0, 0x0000000, 0x0000000, 0x000000} } } ,128	{{{1, 0x0200000, 0x0210000, 0x180000} } },129	{{{0, 0,         0,         0} } },130	{{{1, 0x0400000, 0x0401000, 0x169000} } },131	{{{1, 0x0500000, 0x0510000, 0x140000} } },132	{{{1, 0x0600000, 0x0610000, 0x1c0000} } },133	{{{1, 0x0700000, 0x0704000, 0x1b8000} } },134	{{{1, 0x0800000, 0x0802000, 0x170000},135	{0, 0x0000000, 0x0000000, 0x000000},136	{0, 0x0000000, 0x0000000, 0x000000},137	{0, 0x0000000, 0x0000000, 0x000000},138	{0, 0x0000000, 0x0000000, 0x000000},139	{0, 0x0000000, 0x0000000, 0x000000},140	{0, 0x0000000, 0x0000000, 0x000000},141	{0, 0x0000000, 0x0000000, 0x000000},142	{0, 0x0000000, 0x0000000, 0x000000},143	{0, 0x0000000, 0x0000000, 0x000000},144	{0, 0x0000000, 0x0000000, 0x000000},145	{0, 0x0000000, 0x0000000, 0x000000},146	{0, 0x0000000, 0x0000000, 0x000000},147	{0, 0x0000000, 0x0000000, 0x000000},148	{0, 0x0000000, 0x0000000, 0x000000},149	{1, 0x08f0000, 0x08f2000, 0x172000} } },150	{{{1, 0x0900000, 0x0902000, 0x174000},151	{0, 0x0000000, 0x0000000, 0x000000},152	{0, 0x0000000, 0x0000000, 0x000000},153	{0, 0x0000000, 0x0000000, 0x000000},154	{0, 0x0000000, 0x0000000, 0x000000},155	{0, 0x0000000, 0x0000000, 0x000000},156	{0, 0x0000000, 0x0000000, 0x000000},157	{0, 0x0000000, 0x0000000, 0x000000},158	{0, 0x0000000, 0x0000000, 0x000000},159	{0, 0x0000000, 0x0000000, 0x000000},160	{0, 0x0000000, 0x0000000, 0x000000},161	{0, 0x0000000, 0x0000000, 0x000000},162	{0, 0x0000000, 0x0000000, 0x000000},163	{0, 0x0000000, 0x0000000, 0x000000},164	{0, 0x0000000, 0x0000000, 0x000000},165	{1, 0x09f0000, 0x09f2000, 0x176000} } },166	{{{0, 0x0a00000, 0x0a02000, 0x178000},167	{0, 0x0000000, 0x0000000, 0x000000},168	{0, 0x0000000, 0x0000000, 0x000000},169	{0, 0x0000000, 0x0000000, 0x000000},170	{0, 0x0000000, 0x0000000, 0x000000},171	{0, 0x0000000, 0x0000000, 0x000000},172	{0, 0x0000000, 0x0000000, 0x000000},173	{0, 0x0000000, 0x0000000, 0x000000},174	{0, 0x0000000, 0x0000000, 0x000000},175	{0, 0x0000000, 0x0000000, 0x000000},176	{0, 0x0000000, 0x0000000, 0x000000},177	{0, 0x0000000, 0x0000000, 0x000000},178	{0, 0x0000000, 0x0000000, 0x000000},179	{0, 0x0000000, 0x0000000, 0x000000},180	{0, 0x0000000, 0x0000000, 0x000000},181	{1, 0x0af0000, 0x0af2000, 0x17a000} } },182	{{{0, 0x0b00000, 0x0b02000, 0x17c000},183	{0, 0x0000000, 0x0000000, 0x000000},184	{0, 0x0000000, 0x0000000, 0x000000},185	{0, 0x0000000, 0x0000000, 0x000000},186	{0, 0x0000000, 0x0000000, 0x000000},187	{0, 0x0000000, 0x0000000, 0x000000},188	{0, 0x0000000, 0x0000000, 0x000000},189	{0, 0x0000000, 0x0000000, 0x000000},190	{0, 0x0000000, 0x0000000, 0x000000},191	{0, 0x0000000, 0x0000000, 0x000000},192	{0, 0x0000000, 0x0000000, 0x000000},193	{0, 0x0000000, 0x0000000, 0x000000},194	{0, 0x0000000, 0x0000000, 0x000000},195	{0, 0x0000000, 0x0000000, 0x000000},196	{0, 0x0000000, 0x0000000, 0x000000},197	{1, 0x0bf0000, 0x0bf2000, 0x17e000} } },198	{{{1, 0x0c00000, 0x0c04000, 0x1d4000} } },199	{{{1, 0x0d00000, 0x0d04000, 0x1a4000} } },200	{{{1, 0x0e00000, 0x0e04000, 0x1a0000} } },201	{{{1, 0x0f00000, 0x0f01000, 0x164000} } },202	{{{0, 0x1000000, 0x1004000, 0x1a8000} } },203	{{{1, 0x1100000, 0x1101000, 0x160000} } },204	{{{1, 0x1200000, 0x1201000, 0x161000} } },205	{{{1, 0x1300000, 0x1301000, 0x162000} } },206	{{{1, 0x1400000, 0x1401000, 0x163000} } },207	{{{1, 0x1500000, 0x1501000, 0x165000} } },208	{{{1, 0x1600000, 0x1601000, 0x166000} } },209	{{{0, 0,         0,         0} } },210	{{{0, 0,         0,         0} } },211	{{{0, 0,         0,         0} } },212	{{{0, 0,         0,         0} } },213	{{{0, 0,         0,         0} } },214	{{{0, 0,         0,         0} } },215	{{{1, 0x1d00000, 0x1d10000, 0x190000} } },216	{{{1, 0x1e00000, 0x1e01000, 0x16a000} } },217	{{{1, 0x1f00000, 0x1f10000, 0x150000} } },218	{{{0} } },219	{{{1, 0x2100000, 0x2102000, 0x120000},220	{1, 0x2110000, 0x2120000, 0x130000},221	{1, 0x2120000, 0x2122000, 0x124000},222	{1, 0x2130000, 0x2132000, 0x126000},223	{1, 0x2140000, 0x2142000, 0x128000},224	{1, 0x2150000, 0x2152000, 0x12a000},225	{1, 0x2160000, 0x2170000, 0x110000},226	{1, 0x2170000, 0x2172000, 0x12e000},227	{0, 0x0000000, 0x0000000, 0x000000},228	{0, 0x0000000, 0x0000000, 0x000000},229	{0, 0x0000000, 0x0000000, 0x000000},230	{0, 0x0000000, 0x0000000, 0x000000},231	{0, 0x0000000, 0x0000000, 0x000000},232	{0, 0x0000000, 0x0000000, 0x000000},233	{0, 0x0000000, 0x0000000, 0x000000},234	{0, 0x0000000, 0x0000000, 0x000000} } },235	{{{1, 0x2200000, 0x2204000, 0x1b0000} } },236	{{{0} } },237	{{{0} } },238	{{{0} } },239	{{{0} } },240	{{{0} } },241	{{{1, 0x2800000, 0x2804000, 0x1a4000} } },242	{{{1, 0x2900000, 0x2901000, 0x16b000} } },243	{{{1, 0x2a00000, 0x2a00400, 0x1ac400} } },244	{{{1, 0x2b00000, 0x2b00400, 0x1ac800} } },245	{{{1, 0x2c00000, 0x2c00400, 0x1acc00} } },246	{{{1, 0x2d00000, 0x2d00400, 0x1ad000} } },247	{{{1, 0x2e00000, 0x2e00400, 0x1ad400} } },248	{{{1, 0x2f00000, 0x2f00400, 0x1ad800} } },249	{{{1, 0x3000000, 0x3000400, 0x1adc00} } },250	{{{0, 0x3100000, 0x3104000, 0x1a8000} } },251	{{{1, 0x3200000, 0x3204000, 0x1d4000} } },252	{{{1, 0x3300000, 0x3304000, 0x1a0000} } },253	{{{0} } },254	{{{1, 0x3500000, 0x3500400, 0x1ac000} } },255	{{{1, 0x3600000, 0x3600400, 0x1ae000} } },256	{{{1, 0x3700000, 0x3700400, 0x1ae400} } },257	{{{1, 0x3800000, 0x3804000, 0x1d0000} } },258	{{{1, 0x3900000, 0x3904000, 0x1b4000} } },259	{{{1, 0x3a00000, 0x3a04000, 0x1d8000} } },260	{{{0} } },261	{{{0} } },262	{{{1, 0x3d00000, 0x3d04000, 0x1dc000} } },263	{{{1, 0x3e00000, 0x3e01000, 0x167000} } },264	{{{1, 0x3f00000, 0x3f01000, 0x168000} } }265};266 267/*268 * top 12 bits of crb internal address (hub, agent)269 */270static unsigned qla82xx_crb_hub_agt[64] = {271	0,272	QLA82XX_HW_CRB_HUB_AGT_ADR_PS,273	QLA82XX_HW_CRB_HUB_AGT_ADR_MN,274	QLA82XX_HW_CRB_HUB_AGT_ADR_MS,275	0,276	QLA82XX_HW_CRB_HUB_AGT_ADR_SRE,277	QLA82XX_HW_CRB_HUB_AGT_ADR_NIU,278	QLA82XX_HW_CRB_HUB_AGT_ADR_QMN,279	QLA82XX_HW_CRB_HUB_AGT_ADR_SQN0,280	QLA82XX_HW_CRB_HUB_AGT_ADR_SQN1,281	QLA82XX_HW_CRB_HUB_AGT_ADR_SQN2,282	QLA82XX_HW_CRB_HUB_AGT_ADR_SQN3,283	QLA82XX_HW_CRB_HUB_AGT_ADR_I2Q,284	QLA82XX_HW_CRB_HUB_AGT_ADR_TIMR,285	QLA82XX_HW_CRB_HUB_AGT_ADR_ROMUSB,286	QLA82XX_HW_CRB_HUB_AGT_ADR_PGN4,287	QLA82XX_HW_CRB_HUB_AGT_ADR_XDMA,288	QLA82XX_HW_CRB_HUB_AGT_ADR_PGN0,289	QLA82XX_HW_CRB_HUB_AGT_ADR_PGN1,290	QLA82XX_HW_CRB_HUB_AGT_ADR_PGN2,291	QLA82XX_HW_CRB_HUB_AGT_ADR_PGN3,292	QLA82XX_HW_CRB_HUB_AGT_ADR_PGND,293	QLA82XX_HW_CRB_HUB_AGT_ADR_PGNI,294	QLA82XX_HW_CRB_HUB_AGT_ADR_PGS0,295	QLA82XX_HW_CRB_HUB_AGT_ADR_PGS1,296	QLA82XX_HW_CRB_HUB_AGT_ADR_PGS2,297	QLA82XX_HW_CRB_HUB_AGT_ADR_PGS3,298	0,299	QLA82XX_HW_CRB_HUB_AGT_ADR_PGSI,300	QLA82XX_HW_CRB_HUB_AGT_ADR_SN,301	0,302	QLA82XX_HW_CRB_HUB_AGT_ADR_EG,303	0,304	QLA82XX_HW_CRB_HUB_AGT_ADR_PS,305	QLA82XX_HW_CRB_HUB_AGT_ADR_CAM,306	0,307	0,308	0,309	0,310	0,311	QLA82XX_HW_CRB_HUB_AGT_ADR_TIMR,312	0,313	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX1,314	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX2,315	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX3,316	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX4,317	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX5,318	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX6,319	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX7,320	QLA82XX_HW_CRB_HUB_AGT_ADR_XDMA,321	QLA82XX_HW_CRB_HUB_AGT_ADR_I2Q,322	QLA82XX_HW_CRB_HUB_AGT_ADR_ROMUSB,323	0,324	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX0,325	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX8,326	QLA82XX_HW_CRB_HUB_AGT_ADR_RPMX9,327	QLA82XX_HW_CRB_HUB_AGT_ADR_OCM0,328	0,329	QLA82XX_HW_CRB_HUB_AGT_ADR_SMB,330	QLA82XX_HW_CRB_HUB_AGT_ADR_I2C0,331	QLA82XX_HW_CRB_HUB_AGT_ADR_I2C1,332	0,333	QLA82XX_HW_CRB_HUB_AGT_ADR_PGNC,334	0,335};336 337/* Device states */338static const char *const q_dev_state[] = {339	[QLA8XXX_DEV_UNKNOWN]		= "Unknown",340	[QLA8XXX_DEV_COLD]		= "Cold/Re-init",341	[QLA8XXX_DEV_INITIALIZING]	= "Initializing",342	[QLA8XXX_DEV_READY]		= "Ready",343	[QLA8XXX_DEV_NEED_RESET]	= "Need Reset",344	[QLA8XXX_DEV_NEED_QUIESCENT]	= "Need Quiescent",345	[QLA8XXX_DEV_FAILED]		= "Failed",346	[QLA8XXX_DEV_QUIESCENT]		= "Quiescent",347};348 349const char *qdev_state(uint32_t dev_state)350{351	return (dev_state < MAX_STATES) ? q_dev_state[dev_state] : "Unknown";352}353 354/*355 * In: 'off_in' is offset from CRB space in 128M pci map356 * Out: 'off_out' is 2M pci map addr357 * side effect: lock crb window358 */359static void360qla82xx_pci_set_crbwindow_2M(struct qla_hw_data *ha, ulong off_in,361			     void __iomem **off_out)362{363	u32 win_read;364	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);365 366	ha->crb_win = CRB_HI(off_in);367	writel(ha->crb_win, CRB_WINDOW_2M + ha->nx_pcibase);368 369	/* Read back value to make sure write has gone through before trying370	 * to use it.371	 */372	win_read = rd_reg_dword(CRB_WINDOW_2M + ha->nx_pcibase);373	if (win_read != ha->crb_win) {374		ql_dbg(ql_dbg_p3p, vha, 0xb000,375		    "%s: Written crbwin (0x%x) "376		    "!= Read crbwin (0x%x), off=0x%lx.\n",377		    __func__, ha->crb_win, win_read, off_in);378	}379	*off_out = (off_in & MASK(16)) + CRB_INDIRECT_2M + ha->nx_pcibase;380}381 382static int383qla82xx_pci_get_crb_addr_2M(struct qla_hw_data *ha, ulong off_in,384			    void __iomem **off_out)385{386	struct crb_128M_2M_sub_block_map *m;387 388	if (off_in >= QLA82XX_CRB_MAX)389		return -1;390 391	if (off_in >= QLA82XX_PCI_CAMQM && off_in < QLA82XX_PCI_CAMQM_2M_END) {392		*off_out = (off_in - QLA82XX_PCI_CAMQM) +393		    QLA82XX_PCI_CAMQM_2M_BASE + ha->nx_pcibase;394		return 0;395	}396 397	if (off_in < QLA82XX_PCI_CRBSPACE)398		return -1;399 400	off_in -= QLA82XX_PCI_CRBSPACE;401 402	/* Try direct map */403	m = &crb_128M_2M_map[CRB_BLK(off_in)].sub_block[CRB_SUBBLK(off_in)];404 405	if (m->valid && (m->start_128M <= off_in) && (m->end_128M > off_in)) {406		*off_out = off_in + m->start_2M - m->start_128M + ha->nx_pcibase;407		return 0;408	}409	/* Not in direct map, use crb window */410	*off_out = (void __iomem *)off_in;411	return 1;412}413 414#define CRB_WIN_LOCK_TIMEOUT 100000000415static int qla82xx_crb_win_lock(struct qla_hw_data *ha)416{417	int done = 0, timeout = 0;418 419	while (!done) {420		/* acquire semaphore3 from PCI HW block */421		done = qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM7_LOCK));422		if (done == 1)423			break;424		if (timeout >= CRB_WIN_LOCK_TIMEOUT)425			return -1;426		timeout++;427	}428	qla82xx_wr_32(ha, QLA82XX_CRB_WIN_LOCK_ID, ha->portnum);429	return 0;430}431 432int433qla82xx_wr_32(struct qla_hw_data *ha, ulong off_in, u32 data)434{435	void __iomem *off;436	unsigned long flags = 0;437	int rv;438 439	rv = qla82xx_pci_get_crb_addr_2M(ha, off_in, &off);440 441	BUG_ON(rv == -1);442 443	if (rv == 1) {444#ifndef __CHECKER__445		write_lock_irqsave(&ha->hw_lock, flags);446#endif447		qla82xx_crb_win_lock(ha);448		qla82xx_pci_set_crbwindow_2M(ha, off_in, &off);449	}450 451	writel(data, (void __iomem *)off);452 453	if (rv == 1) {454		qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM7_UNLOCK));455#ifndef __CHECKER__456		write_unlock_irqrestore(&ha->hw_lock, flags);457#endif458	}459	return 0;460}461 462int463qla82xx_rd_32(struct qla_hw_data *ha, ulong off_in)464{465	void __iomem *off;466	unsigned long flags = 0;467	int rv;468	u32 data;469 470	rv = qla82xx_pci_get_crb_addr_2M(ha, off_in, &off);471 472	BUG_ON(rv == -1);473 474	if (rv == 1) {475#ifndef __CHECKER__476		write_lock_irqsave(&ha->hw_lock, flags);477#endif478		qla82xx_crb_win_lock(ha);479		qla82xx_pci_set_crbwindow_2M(ha, off_in, &off);480	}481	data = rd_reg_dword(off);482 483	if (rv == 1) {484		qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM7_UNLOCK));485#ifndef __CHECKER__486		write_unlock_irqrestore(&ha->hw_lock, flags);487#endif488	}489	return data;490}491 492/*493 * Context: task, might sleep494 */495int qla82xx_idc_lock(struct qla_hw_data *ha)496{497	const int delay_ms = 100, timeout_ms = 2000;498	int done, total = 0;499 500	might_sleep();501 502	while (true) {503		/* acquire semaphore5 from PCI HW block */504		done = qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM5_LOCK));505		if (done == 1)506			break;507		if (WARN_ON_ONCE(total >= timeout_ms))508			return -1;509 510		total += delay_ms;511		msleep(delay_ms);512	}513 514	return 0;515}516 517void qla82xx_idc_unlock(struct qla_hw_data *ha)518{519	qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM5_UNLOCK));520}521 522/*523 * check memory access boundary.524 * used by test agent. support ddr access only for now525 */526static unsigned long527qla82xx_pci_mem_bound_check(struct qla_hw_data *ha,528	unsigned long long addr, int size)529{530	if (!addr_in_range(addr, QLA82XX_ADDR_DDR_NET,531		QLA82XX_ADDR_DDR_NET_MAX) ||532		!addr_in_range(addr + size - 1, QLA82XX_ADDR_DDR_NET,533		QLA82XX_ADDR_DDR_NET_MAX) ||534		((size != 1) && (size != 2) && (size != 4) && (size != 8)))535			return 0;536	else537		return 1;538}539 540static int qla82xx_pci_set_window_warning_count;541 542static unsigned long543qla82xx_pci_set_window(struct qla_hw_data *ha, unsigned long long addr)544{545	int window;546	u32 win_read;547	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);548 549	if (addr_in_range(addr, QLA82XX_ADDR_DDR_NET,550		QLA82XX_ADDR_DDR_NET_MAX)) {551		/* DDR network side */552		window = MN_WIN(addr);553		ha->ddr_mn_window = window;554		qla82xx_wr_32(ha,555			ha->mn_win_crb | QLA82XX_PCI_CRBSPACE, window);556		win_read = qla82xx_rd_32(ha,557			ha->mn_win_crb | QLA82XX_PCI_CRBSPACE);558		if ((win_read << 17) != window) {559			ql_dbg(ql_dbg_p3p, vha, 0xb003,560			    "%s: Written MNwin (0x%x) != Read MNwin (0x%x).\n",561			    __func__, window, win_read);562		}563		addr = GET_MEM_OFFS_2M(addr) + QLA82XX_PCI_DDR_NET;564	} else if (addr_in_range(addr, QLA82XX_ADDR_OCM0,565		QLA82XX_ADDR_OCM0_MAX)) {566		unsigned int temp1;567 568		if ((addr & 0x00ff800) == 0xff800) {569			ql_log(ql_log_warn, vha, 0xb004,570			    "%s: QM access not handled.\n", __func__);571			addr = -1UL;572		}573		window = OCM_WIN(addr);574		ha->ddr_mn_window = window;575		qla82xx_wr_32(ha,576			ha->mn_win_crb | QLA82XX_PCI_CRBSPACE, window);577		win_read = qla82xx_rd_32(ha,578			ha->mn_win_crb | QLA82XX_PCI_CRBSPACE);579		temp1 = ((window & 0x1FF) << 7) |580		    ((window & 0x0FFFE0000) >> 17);581		if (win_read != temp1) {582			ql_log(ql_log_warn, vha, 0xb005,583			    "%s: Written OCMwin (0x%x) != Read OCMwin (0x%x).\n",584			    __func__, temp1, win_read);585		}586		addr = GET_MEM_OFFS_2M(addr) + QLA82XX_PCI_OCM0_2M;587 588	} else if (addr_in_range(addr, QLA82XX_ADDR_QDR_NET,589		QLA82XX_P3_ADDR_QDR_NET_MAX)) {590		/* QDR network side */591		window = MS_WIN(addr);592		ha->qdr_sn_window = window;593		qla82xx_wr_32(ha,594			ha->ms_win_crb | QLA82XX_PCI_CRBSPACE, window);595		win_read = qla82xx_rd_32(ha,596			ha->ms_win_crb | QLA82XX_PCI_CRBSPACE);597		if (win_read != window) {598			ql_log(ql_log_warn, vha, 0xb006,599			    "%s: Written MSwin (0x%x) != Read MSwin (0x%x).\n",600			    __func__, window, win_read);601		}602		addr = GET_MEM_OFFS_2M(addr) + QLA82XX_PCI_QDR_NET;603	} else {604		/*605		 * peg gdb frequently accesses memory that doesn't exist,606		 * this limits the chit chat so debugging isn't slowed down.607		 */608		if ((qla82xx_pci_set_window_warning_count++ < 8) ||609		    (qla82xx_pci_set_window_warning_count%64 == 0)) {610			ql_log(ql_log_warn, vha, 0xb007,611			    "%s: Warning:%s Unknown address range!.\n",612			    __func__, QLA2XXX_DRIVER_NAME);613		}614		addr = -1UL;615	}616	return addr;617}618 619/* check if address is in the same windows as the previous access */620static int qla82xx_pci_is_same_window(struct qla_hw_data *ha,621	unsigned long long addr)622{623	int			window;624	unsigned long long	qdr_max;625 626	qdr_max = QLA82XX_P3_ADDR_QDR_NET_MAX;627 628	/* DDR network side */629	if (addr_in_range(addr, QLA82XX_ADDR_DDR_NET,630		QLA82XX_ADDR_DDR_NET_MAX))631		BUG();632	else if (addr_in_range(addr, QLA82XX_ADDR_OCM0,633		QLA82XX_ADDR_OCM0_MAX))634		return 1;635	else if (addr_in_range(addr, QLA82XX_ADDR_OCM1,636		QLA82XX_ADDR_OCM1_MAX))637		return 1;638	else if (addr_in_range(addr, QLA82XX_ADDR_QDR_NET, qdr_max)) {639		/* QDR network side */640		window = ((addr - QLA82XX_ADDR_QDR_NET) >> 22) & 0x3f;641		if (ha->qdr_sn_window == window)642			return 1;643	}644	return 0;645}646 647static int qla82xx_pci_mem_read_direct(struct qla_hw_data *ha,648	u64 off, void *data, int size)649{650	unsigned long   flags;651	void __iomem *addr = NULL;652	int             ret = 0;653	u64             start;654	uint8_t __iomem  *mem_ptr = NULL;655	unsigned long   mem_base;656	unsigned long   mem_page;657	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);658 659	write_lock_irqsave(&ha->hw_lock, flags);660 661	/*662	 * If attempting to access unknown address or straddle hw windows,663	 * do not access.664	 */665	start = qla82xx_pci_set_window(ha, off);666	if ((start == -1UL) ||667		(qla82xx_pci_is_same_window(ha, off + size - 1) == 0)) {668		write_unlock_irqrestore(&ha->hw_lock, flags);669		ql_log(ql_log_fatal, vha, 0xb008,670		    "%s out of bound pci memory "671		    "access, offset is 0x%llx.\n",672		    QLA2XXX_DRIVER_NAME, off);673		return -1;674	}675 676	write_unlock_irqrestore(&ha->hw_lock, flags);677	mem_base = pci_resource_start(ha->pdev, 0);678	mem_page = start & PAGE_MASK;679	/* Map two pages whenever user tries to access addresses in two680	* consecutive pages.681	*/682	if (mem_page != ((start + size - 1) & PAGE_MASK))683		mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2);684	else685		mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);686	if (mem_ptr == NULL) {687		*(u8  *)data = 0;688		return -1;689	}690	addr = mem_ptr;691	addr += start & (PAGE_SIZE - 1);692	write_lock_irqsave(&ha->hw_lock, flags);693 694	switch (size) {695	case 1:696		*(u8  *)data = readb(addr);697		break;698	case 2:699		*(u16 *)data = readw(addr);700		break;701	case 4:702		*(u32 *)data = readl(addr);703		break;704	case 8:705		*(u64 *)data = readq(addr);706		break;707	default:708		ret = -1;709		break;710	}711	write_unlock_irqrestore(&ha->hw_lock, flags);712 713	if (mem_ptr)714		iounmap(mem_ptr);715	return ret;716}717 718static int719qla82xx_pci_mem_write_direct(struct qla_hw_data *ha,720	u64 off, void *data, int size)721{722	unsigned long   flags;723	void  __iomem *addr = NULL;724	int             ret = 0;725	u64             start;726	uint8_t __iomem *mem_ptr = NULL;727	unsigned long   mem_base;728	unsigned long   mem_page;729	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);730 731	write_lock_irqsave(&ha->hw_lock, flags);732 733	/*734	 * If attempting to access unknown address or straddle hw windows,735	 * do not access.736	 */737	start = qla82xx_pci_set_window(ha, off);738	if ((start == -1UL) ||739		(qla82xx_pci_is_same_window(ha, off + size - 1) == 0)) {740		write_unlock_irqrestore(&ha->hw_lock, flags);741		ql_log(ql_log_fatal, vha, 0xb009,742		    "%s out of bound memory "743		    "access, offset is 0x%llx.\n",744		    QLA2XXX_DRIVER_NAME, off);745		return -1;746	}747 748	write_unlock_irqrestore(&ha->hw_lock, flags);749	mem_base = pci_resource_start(ha->pdev, 0);750	mem_page = start & PAGE_MASK;751	/* Map two pages whenever user tries to access addresses in two752	 * consecutive pages.753	 */754	if (mem_page != ((start + size - 1) & PAGE_MASK))755		mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE*2);756	else757		mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);758	if (mem_ptr == NULL)759		return -1;760 761	addr = mem_ptr;762	addr += start & (PAGE_SIZE - 1);763	write_lock_irqsave(&ha->hw_lock, flags);764 765	switch (size) {766	case 1:767		writeb(*(u8  *)data, addr);768		break;769	case 2:770		writew(*(u16 *)data, addr);771		break;772	case 4:773		writel(*(u32 *)data, addr);774		break;775	case 8:776		writeq(*(u64 *)data, addr);777		break;778	default:779		ret = -1;780		break;781	}782	write_unlock_irqrestore(&ha->hw_lock, flags);783	if (mem_ptr)784		iounmap(mem_ptr);785	return ret;786}787 788#define MTU_FUDGE_FACTOR 100789static unsigned long790qla82xx_decode_crb_addr(unsigned long addr)791{792	int i;793	unsigned long base_addr, offset, pci_base;794 795	if (!qla82xx_crb_table_initialized)796		qla82xx_crb_addr_transform_setup();797 798	pci_base = ADDR_ERROR;799	base_addr = addr & 0xfff00000;800	offset = addr & 0x000fffff;801 802	for (i = 0; i < MAX_CRB_XFORM; i++) {803		if (crb_addr_xform[i] == base_addr) {804			pci_base = i << 20;805			break;806		}807	}808	if (pci_base == ADDR_ERROR)809		return pci_base;810	return pci_base + offset;811}812 813static long rom_max_timeout = 100;814static long qla82xx_rom_lock_timeout = 100;815 816static int817qla82xx_rom_lock(struct qla_hw_data *ha)818{819	int done = 0, timeout = 0;820	uint32_t lock_owner = 0;821	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);822 823	while (!done) {824		/* acquire semaphore2 from PCI HW block */825		done = qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_LOCK));826		if (done == 1)827			break;828		if (timeout >= qla82xx_rom_lock_timeout) {829			lock_owner = qla82xx_rd_32(ha, QLA82XX_ROM_LOCK_ID);830			ql_dbg(ql_dbg_p3p, vha, 0xb157,831			    "%s: Simultaneous flash access by following ports, active port = %d: accessing port = %d",832			    __func__, ha->portnum, lock_owner);833			return -1;834		}835		timeout++;836	}837	qla82xx_wr_32(ha, QLA82XX_ROM_LOCK_ID, ha->portnum);838	return 0;839}840 841static void842qla82xx_rom_unlock(struct qla_hw_data *ha)843{844	qla82xx_wr_32(ha, QLA82XX_ROM_LOCK_ID, 0xffffffff);845	qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_UNLOCK));846}847 848static int849qla82xx_wait_rom_busy(struct qla_hw_data *ha)850{851	long timeout = 0;852	long done = 0 ;853	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);854 855	while (done == 0) {856		done = qla82xx_rd_32(ha, QLA82XX_ROMUSB_GLB_STATUS);857		done &= 4;858		timeout++;859		if (timeout >= rom_max_timeout) {860			ql_dbg(ql_dbg_p3p, vha, 0xb00a,861			    "%s: Timeout reached waiting for rom busy.\n",862			    QLA2XXX_DRIVER_NAME);863			return -1;864		}865	}866	return 0;867}868 869static int870qla82xx_wait_rom_done(struct qla_hw_data *ha)871{872	long timeout = 0;873	long done = 0 ;874	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);875 876	while (done == 0) {877		done = qla82xx_rd_32(ha, QLA82XX_ROMUSB_GLB_STATUS);878		done &= 2;879		timeout++;880		if (timeout >= rom_max_timeout) {881			ql_dbg(ql_dbg_p3p, vha, 0xb00b,882			    "%s: Timeout reached waiting for rom done.\n",883			    QLA2XXX_DRIVER_NAME);884			return -1;885		}886	}887	return 0;888}889 890static int891qla82xx_md_rw_32(struct qla_hw_data *ha, uint32_t off, u32 data, uint8_t flag)892{893	uint32_t  off_value, rval = 0;894 895	wrt_reg_dword(CRB_WINDOW_2M + ha->nx_pcibase, off & 0xFFFF0000);896 897	/* Read back value to make sure write has gone through */898	rd_reg_dword(CRB_WINDOW_2M + ha->nx_pcibase);899	off_value  = (off & 0x0000FFFF);900 901	if (flag)902		wrt_reg_dword(off_value + CRB_INDIRECT_2M + ha->nx_pcibase,903			      data);904	else905		rval = rd_reg_dword(off_value + CRB_INDIRECT_2M +906				    ha->nx_pcibase);907 908	return rval;909}910 911static int912qla82xx_do_rom_fast_read(struct qla_hw_data *ha, int addr, int *valp)913{914	/* Dword reads to flash. */915	qla82xx_md_rw_32(ha, MD_DIRECT_ROM_WINDOW, (addr & 0xFFFF0000), 1);916	*valp = qla82xx_md_rw_32(ha, MD_DIRECT_ROM_READ_BASE +917	    (addr & 0x0000FFFF), 0, 0);918 919	return 0;920}921 922static int923qla82xx_rom_fast_read(struct qla_hw_data *ha, int addr, int *valp)924{925	int ret, loops = 0;926	uint32_t lock_owner = 0;927	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);928 929	while ((qla82xx_rom_lock(ha) != 0) && (loops < 50000)) {930		udelay(100);931		schedule();932		loops++;933	}934	if (loops >= 50000) {935		lock_owner = qla82xx_rd_32(ha, QLA82XX_ROM_LOCK_ID);936		ql_log(ql_log_fatal, vha, 0x00b9,937		    "Failed to acquire SEM2 lock, Lock Owner %u.\n",938		    lock_owner);939		return -1;940	}941	ret = qla82xx_do_rom_fast_read(ha, addr, valp);942	qla82xx_rom_unlock(ha);943	return ret;944}945 946static int947qla82xx_read_status_reg(struct qla_hw_data *ha, uint32_t *val)948{949	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);950 951	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, M25P_INSTR_RDSR);952	qla82xx_wait_rom_busy(ha);953	if (qla82xx_wait_rom_done(ha)) {954		ql_log(ql_log_warn, vha, 0xb00c,955		    "Error waiting for rom done.\n");956		return -1;957	}958	*val = qla82xx_rd_32(ha, QLA82XX_ROMUSB_ROM_RDATA);959	return 0;960}961 962static int963qla82xx_flash_wait_write_finish(struct qla_hw_data *ha)964{965	uint32_t val = 0;966	int i, ret;967	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);968 969	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ABYTE_CNT, 0);970	for (i = 0; i < 50000; i++) {971		ret = qla82xx_read_status_reg(ha, &val);972		if (ret < 0 || (val & 1) == 0)973			return ret;974		udelay(10);975		cond_resched();976	}977	ql_log(ql_log_warn, vha, 0xb00d,978	       "Timeout reached waiting for write finish.\n");979	return -1;980}981 982static int983qla82xx_flash_set_write_enable(struct qla_hw_data *ha)984{985	uint32_t val;986 987	qla82xx_wait_rom_busy(ha);988	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ABYTE_CNT, 0);989	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, M25P_INSTR_WREN);990	qla82xx_wait_rom_busy(ha);991	if (qla82xx_wait_rom_done(ha))992		return -1;993	if (qla82xx_read_status_reg(ha, &val) != 0)994		return -1;995	if ((val & 2) != 2)996		return -1;997	return 0;998}999 1000static int1001qla82xx_write_status_reg(struct qla_hw_data *ha, uint32_t val)1002{1003	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);1004 1005	if (qla82xx_flash_set_write_enable(ha))1006		return -1;1007	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_WDATA, val);1008	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, 0x1);1009	if (qla82xx_wait_rom_done(ha)) {1010		ql_log(ql_log_warn, vha, 0xb00e,1011		    "Error waiting for rom done.\n");1012		return -1;1013	}1014	return qla82xx_flash_wait_write_finish(ha);1015}1016 1017static int1018qla82xx_write_disable_flash(struct qla_hw_data *ha)1019{1020	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);1021 1022	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, M25P_INSTR_WRDI);1023	if (qla82xx_wait_rom_done(ha)) {1024		ql_log(ql_log_warn, vha, 0xb00f,1025		    "Error waiting for rom done.\n");1026		return -1;1027	}1028	return 0;1029}1030 1031static int1032ql82xx_rom_lock_d(struct qla_hw_data *ha)1033{1034	int loops = 0;1035	uint32_t lock_owner = 0;1036	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);1037 1038	while ((qla82xx_rom_lock(ha) != 0) && (loops < 50000)) {1039		udelay(100);1040		cond_resched();1041		loops++;1042	}1043	if (loops >= 50000) {1044		lock_owner = qla82xx_rd_32(ha, QLA82XX_ROM_LOCK_ID);1045		ql_log(ql_log_warn, vha, 0xb010,1046		    "ROM lock failed, Lock Owner %u.\n", lock_owner);1047		return -1;1048	}1049	return 0;1050}1051 1052static int1053qla82xx_write_flash_dword(struct qla_hw_data *ha, uint32_t flashaddr,1054	uint32_t data)1055{1056	int ret = 0;1057	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);1058 1059	ret = ql82xx_rom_lock_d(ha);1060	if (ret < 0) {1061		ql_log(ql_log_warn, vha, 0xb011,1062		    "ROM lock failed.\n");1063		return ret;1064	}1065 1066	ret = qla82xx_flash_set_write_enable(ha);1067	if (ret < 0)1068		goto done_write;1069 1070	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_WDATA, data);1071	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ADDRESS, flashaddr);1072	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ABYTE_CNT, 3);1073	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, M25P_INSTR_PP);1074	qla82xx_wait_rom_busy(ha);1075	if (qla82xx_wait_rom_done(ha)) {1076		ql_log(ql_log_warn, vha, 0xb012,1077		    "Error waiting for rom done.\n");1078		ret = -1;1079		goto done_write;1080	}1081 1082	ret = qla82xx_flash_wait_write_finish(ha);1083 1084done_write:1085	qla82xx_rom_unlock(ha);1086	return ret;1087}1088 1089/* This routine does CRB initialize sequence1090 *  to put the ISP into operational state1091 */1092static int1093qla82xx_pinit_from_rom(scsi_qla_host_t *vha)1094{1095	int addr, val;1096	int i ;1097	struct crb_addr_pair *buf;1098	unsigned long off;1099	unsigned offset, n;1100	struct qla_hw_data *ha = vha->hw;1101 1102	struct crb_addr_pair {1103		long addr;1104		long data;1105	};1106 1107	/* Halt all the individual PEGs and other blocks of the ISP */1108	qla82xx_rom_lock(ha);1109 1110	/* disable all I2Q */1111	qla82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x10, 0x0);1112	qla82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x14, 0x0);1113	qla82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x18, 0x0);1114	qla82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x1c, 0x0);1115	qla82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x20, 0x0);1116	qla82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x24, 0x0);1117 1118	/* disable all niu interrupts */1119	qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x40, 0xff);1120	/* disable xge rx/tx */1121	qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x70000, 0x00);1122	/* disable xg1 rx/tx */1123	qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x80000, 0x00);1124	/* disable sideband mac */1125	qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x90000, 0x00);1126	/* disable ap0 mac */1127	qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0xa0000, 0x00);1128	/* disable ap1 mac */1129	qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0xb0000, 0x00);1130 1131	/* halt sre */1132	val = qla82xx_rd_32(ha, QLA82XX_CRB_SRE + 0x1000);1133	qla82xx_wr_32(ha, QLA82XX_CRB_SRE + 0x1000, val & (~(0x1)));1134 1135	/* halt epg */1136	qla82xx_wr_32(ha, QLA82XX_CRB_EPG + 0x1300, 0x1);1137 1138	/* halt timers */1139	qla82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x0, 0x0);1140	qla82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x8, 0x0);1141	qla82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x10, 0x0);1142	qla82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x18, 0x0);1143	qla82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x100, 0x0);1144	qla82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x200, 0x0);1145 1146	/* halt pegs */1147	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_0 + 0x3c, 1);1148	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_1 + 0x3c, 1);1149	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_2 + 0x3c, 1);1150	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_3 + 0x3c, 1);1151	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_4 + 0x3c, 1);1152	msleep(20);1153 1154	/* big hammer */1155	if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))1156		/* don't reset CAM block on reset */1157		qla82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xfeffffff);1158	else1159		qla82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xffffffff);1160	qla82xx_rom_unlock(ha);1161 1162	/* Read the signature value from the flash.1163	 * Offset 0: Contain signature (0xcafecafe)1164	 * Offset 4: Offset and number of addr/value pairs1165	 * that present in CRB initialize sequence1166	 */1167	n = 0;1168	if (qla82xx_rom_fast_read(ha, 0, &n) != 0 || n != 0xcafecafeUL ||1169	    qla82xx_rom_fast_read(ha, 4, &n) != 0) {1170		ql_log(ql_log_fatal, vha, 0x006e,1171		    "Error Reading crb_init area: n: %08x.\n", n);1172		return -1;1173	}1174 1175	/* Offset in flash = lower 16 bits1176	 * Number of entries = upper 16 bits1177	 */1178	offset = n & 0xffffU;1179	n = (n >> 16) & 0xffffU;1180 1181	/* number of addr/value pair should not exceed 1024 entries */1182	if (n  >= 1024) {1183		ql_log(ql_log_fatal, vha, 0x0071,1184		    "Card flash not initialized:n=0x%x.\n", n);1185		return -1;1186	}1187 1188	ql_log(ql_log_info, vha, 0x0072,1189	    "%d CRB init values found in ROM.\n", n);1190 1191	buf = kmalloc_array(n, sizeof(struct crb_addr_pair), GFP_KERNEL);1192	if (buf == NULL) {1193		ql_log(ql_log_fatal, vha, 0x010c,1194		    "Unable to allocate memory.\n");1195		return -ENOMEM;1196	}1197 1198	for (i = 0; i < n; i++) {1199		if (qla82xx_rom_fast_read(ha, 8*i + 4*offset, &val) != 0 ||1200		    qla82xx_rom_fast_read(ha, 8*i + 4*offset + 4, &addr) != 0) {1201			kfree(buf);1202			return -1;1203		}1204 1205		buf[i].addr = addr;1206		buf[i].data = val;1207	}1208 1209	for (i = 0; i < n; i++) {1210		/* Translate internal CRB initialization1211		 * address to PCI bus address1212		 */1213		off = qla82xx_decode_crb_addr((unsigned long)buf[i].addr) +1214		    QLA82XX_PCI_CRBSPACE;1215		/* Not all CRB  addr/value pair to be written,1216		 * some of them are skipped1217		 */1218 1219		/* skipping cold reboot MAGIC */1220		if (off == QLA82XX_CAM_RAM(0x1fc))1221			continue;1222 1223		/* do not reset PCI */1224		if (off == (ROMUSB_GLB + 0xbc))1225			continue;1226 1227		/* skip core clock, so that firmware can increase the clock */1228		if (off == (ROMUSB_GLB + 0xc8))1229			continue;1230 1231		/* skip the function enable register */1232		if (off == QLA82XX_PCIE_REG(PCIE_SETUP_FUNCTION))1233			continue;1234 1235		if (off == QLA82XX_PCIE_REG(PCIE_SETUP_FUNCTION2))1236			continue;1237 1238		if ((off & 0x0ff00000) == QLA82XX_CRB_SMB)1239			continue;1240 1241		if ((off & 0x0ff00000) == QLA82XX_CRB_DDR_NET)1242			continue;1243 1244		if (off == ADDR_ERROR) {1245			ql_log(ql_log_fatal, vha, 0x0116,1246			    "Unknown addr: 0x%08lx.\n", buf[i].addr);1247			continue;1248		}1249 1250		qla82xx_wr_32(ha, off, buf[i].data);1251 1252		/* ISP requires much bigger delay to settle down,1253		 * else crb_window returns 0xffffffff1254		 */1255		if (off == QLA82XX_ROMUSB_GLB_SW_RESET)1256			msleep(1000);1257 1258		/* ISP requires millisec delay between1259		 * successive CRB register updation1260		 */1261		msleep(1);1262	}1263 1264	kfree(buf);1265 1266	/* Resetting the data and instruction cache */1267	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_D+0xec, 0x1e);1268	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_D+0x4c, 8);1269	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_I+0x4c, 8);1270 1271	/* Clear all protocol processing engines */1272	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_0+0x8, 0);1273	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_0+0xc, 0);1274	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_1+0x8, 0);1275	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_1+0xc, 0);1276	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_2+0x8, 0);1277	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_2+0xc, 0);1278	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_3+0x8, 0);1279	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_3+0xc, 0);1280	return 0;1281}1282 1283static int1284qla82xx_pci_mem_write_2M(struct qla_hw_data *ha,1285		u64 off, void *data, int size)1286{1287	int i, j, ret = 0, loop, sz[2], off0;1288	int scale, shift_amount, startword;1289	uint32_t temp;1290	uint64_t off8, mem_crb, tmpw, word[2] = {0, 0};1291 1292	/*1293	 * If not MN, go check for MS or invalid.1294	 */1295	if (off >= QLA82XX_ADDR_QDR_NET && off <= QLA82XX_P3_ADDR_QDR_NET_MAX)1296		mem_crb = QLA82XX_CRB_QDR_NET;1297	else {1298		mem_crb = QLA82XX_CRB_DDR_NET;1299		if (qla82xx_pci_mem_bound_check(ha, off, size) == 0)1300			return qla82xx_pci_mem_write_direct(ha,1301			    off, data, size);1302	}1303 1304	off0 = off & 0x7;1305	sz[0] = (size < (8 - off0)) ? size : (8 - off0);1306	sz[1] = size - sz[0];1307 1308	off8 = off & 0xfffffff0;1309	loop = (((off & 0xf) + size - 1) >> 4) + 1;1310	shift_amount = 4;1311	scale = 2;1312	startword = (off & 0xf)/8;1313 1314	for (i = 0; i < loop; i++) {1315		if (qla82xx_pci_mem_read_2M(ha, off8 +1316		    (i << shift_amount), &word[i * scale], 8))1317			return -1;1318	}1319 1320	switch (size) {1321	case 1:1322		tmpw = *((uint8_t *)data);1323		break;1324	case 2:1325		tmpw = *((uint16_t *)data);1326		break;1327	case 4:1328		tmpw = *((uint32_t *)data);1329		break;1330	case 8:1331	default:1332		tmpw = *((uint64_t *)data);1333		break;1334	}1335 1336	if (sz[0] == 8) {1337		word[startword] = tmpw;1338	} else {1339		word[startword] &=1340			~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));1341		word[startword] |= tmpw << (off0 * 8);1342	}1343	if (sz[1] != 0) {1344		word[startword+1] &= ~(~0ULL << (sz[1] * 8));1345		word[startword+1] |= tmpw >> (sz[0] * 8);1346	}1347 1348	for (i = 0; i < loop; i++) {1349		temp = off8 + (i << shift_amount);1350		qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_ADDR_LO, temp);1351		temp = 0;1352		qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_ADDR_HI, temp);1353		temp = word[i * scale] & 0xffffffff;1354		qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_WRDATA_LO, temp);1355		temp = (word[i * scale] >> 32) & 0xffffffff;1356		qla82xx_wr_32(ha, mem_crb+MIU_TEST_AGT_WRDATA_HI, temp);1357		temp = word[i*scale + 1] & 0xffffffff;1358		qla82xx_wr_32(ha, mem_crb +1359		    MIU_TEST_AGT_WRDATA_UPPER_LO, temp);1360		temp = (word[i*scale + 1] >> 32) & 0xffffffff;1361		qla82xx_wr_32(ha, mem_crb +1362		    MIU_TEST_AGT_WRDATA_UPPER_HI, temp);1363 1364		temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;1365		qla82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);1366		temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;1367		qla82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);1368 1369		for (j = 0; j < MAX_CTL_CHECK; j++) {1370			temp = qla82xx_rd_32(ha, mem_crb + MIU_TEST_AGT_CTRL);1371			if ((temp & MIU_TA_CTL_BUSY) == 0)1372				break;1373		}1374 1375		if (j >= MAX_CTL_CHECK) {1376			if (printk_ratelimit())1377				dev_err(&ha->pdev->dev,1378				    "failed to write through agent.\n");1379			ret = -1;1380			break;1381		}1382	}1383 1384	return ret;1385}1386 1387static int1388qla82xx_fw_load_from_flash(struct qla_hw_data *ha)1389{1390	int  i;1391	long size = 0;1392	long flashaddr = ha->flt_region_bootload << 2;1393	long memaddr = BOOTLD_START;1394	u64 data;1395	u32 high, low;1396 1397	size = (IMAGE_START - BOOTLD_START) / 8;1398 1399	for (i = 0; i < size; i++) {1400		if ((qla82xx_rom_fast_read(ha, flashaddr, (int *)&low)) ||1401		    (qla82xx_rom_fast_read(ha, flashaddr + 4, (int *)&high))) {1402			return -1;1403		}1404		data = ((u64)high << 32) | low ;1405		qla82xx_pci_mem_write_2M(ha, memaddr, &data, 8);1406		flashaddr += 8;1407		memaddr += 8;1408 1409		if (i % 0x1000 == 0)1410			msleep(1);1411	}1412	udelay(100);1413	read_lock(&ha->hw_lock);1414	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_0 + 0x18, 0x1020);1415	qla82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0x80001e);1416	read_unlock(&ha->hw_lock);1417	return 0;1418}1419 1420int1421qla82xx_pci_mem_read_2M(struct qla_hw_data *ha,1422		u64 off, void *data, int size)1423{1424	int i, j = 0, k, start, end, loop, sz[2], off0[2];1425	int	      shift_amount;1426	uint32_t      temp;1427	uint64_t      off8, val, mem_crb, word[2] = {0, 0};1428 1429	/*1430	 * If not MN, go check for MS or invalid.1431	 */1432 1433	if (off >= QLA82XX_ADDR_QDR_NET && off <= QLA82XX_P3_ADDR_QDR_NET_MAX)1434		mem_crb = QLA82XX_CRB_QDR_NET;1435	else {1436		mem_crb = QLA82XX_CRB_DDR_NET;1437		if (qla82xx_pci_mem_bound_check(ha, off, size) == 0)1438			return qla82xx_pci_mem_read_direct(ha,1439			    off, data, size);1440	}1441 1442	off8 = off & 0xfffffff0;1443	off0[0] = off & 0xf;1444	sz[0] = (size < (16 - off0[0])) ? size : (16 - off0[0]);1445	shift_amount = 4;1446	loop = ((off0[0] + size - 1) >> shift_amount) + 1;1447	off0[1] = 0;1448	sz[1] = size - sz[0];1449 1450	for (i = 0; i < loop; i++) {1451		temp = off8 + (i << shift_amount);1452		qla82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);1453		temp = 0;1454		qla82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_HI, temp);1455		temp = MIU_TA_CTL_ENABLE;1456		qla82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);1457		temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;1458		qla82xx_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);1459 1460		for (j = 0; j < MAX_CTL_CHECK; j++) {1461			temp = qla82xx_rd_32(ha, mem_crb + MIU_TEST_AGT_CTRL);1462			if ((temp & MIU_TA_CTL_BUSY) == 0)1463				break;1464		}1465 1466		if (j >= MAX_CTL_CHECK) {1467			if (printk_ratelimit())1468				dev_err(&ha->pdev->dev,1469				    "failed to read through agent.\n");1470			break;1471		}1472 1473		start = off0[i] >> 2;1474		end   = (off0[i] + sz[i] - 1) >> 2;1475		for (k = start; k <= end; k++) {1476			temp = qla82xx_rd_32(ha,1477					mem_crb + MIU_TEST_AGT_RDDATA(k));1478			word[i] |= ((uint64_t)temp << (32 * (k & 1)));1479		}1480	}1481 1482	if (j >= MAX_CTL_CHECK)1483		return -1;1484 1485	if ((off0[0] & 7) == 0) {1486		val = word[0];1487	} else {1488		val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |1489			((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));1490	}1491 1492	switch (size) {1493	case 1:1494		*(uint8_t  *)data = val;1495		break;1496	case 2:1497		*(uint16_t *)data = val;1498		break;1499	case 4:1500		*(uint32_t *)data = val;1501		break;1502	case 8:1503		*(uint64_t *)data = val;1504		break;1505	}1506	return 0;1507}1508 1509 1510static struct qla82xx_uri_table_desc *1511qla82xx_get_table_desc(const u8 *unirom, int section)1512{1513	uint32_t i;1514	struct qla82xx_uri_table_desc *directory =1515		(struct qla82xx_uri_table_desc *)&unirom[0];1516	uint32_t offset;1517	uint32_t tab_type;1518	uint32_t entries = le32_to_cpu(directory->num_entries);1519 1520	for (i = 0; i < entries; i++) {1521		offset = le32_to_cpu(directory->findex) +1522		    (i * le32_to_cpu(directory->entry_size));1523		tab_type = get_unaligned_le32((u32 *)&unirom[offset] + 8);1524 1525		if (tab_type == section)1526			return (struct qla82xx_uri_table_desc *)&unirom[offset];1527	}1528 1529	return NULL;1530}1531 1532static struct qla82xx_uri_data_desc *1533qla82xx_get_data_desc(struct qla_hw_data *ha,1534	u32 section, u32 idx_offset)1535{1536	const u8 *unirom = ha->hablob->fw->data;1537	int idx = get_unaligned_le32((u32 *)&unirom[ha->file_prd_off] +1538				     idx_offset);1539	struct qla82xx_uri_table_desc *tab_desc = NULL;1540	uint32_t offset;1541 1542	tab_desc = qla82xx_get_table_desc(unirom, section);1543	if (!tab_desc)1544		return NULL;1545 1546	offset = le32_to_cpu(tab_desc->findex) +1547	    (le32_to_cpu(tab_desc->entry_size) * idx);1548 1549	return (struct qla82xx_uri_data_desc *)&unirom[offset];1550}1551 1552static u8 *1553qla82xx_get_bootld_offset(struct qla_hw_data *ha)1554{1555	u32 offset = BOOTLD_START;1556	struct qla82xx_uri_data_desc *uri_desc = NULL;1557 1558	if (ha->fw_type == QLA82XX_UNIFIED_ROMIMAGE) {1559		uri_desc = qla82xx_get_data_desc(ha,1560		    QLA82XX_URI_DIR_SECT_BOOTLD, QLA82XX_URI_BOOTLD_IDX_OFF);1561		if (uri_desc)1562			offset = le32_to_cpu(uri_desc->findex);1563	}1564 1565	return (u8 *)&ha->hablob->fw->data[offset];1566}1567 1568static u32 qla82xx_get_fw_size(struct qla_hw_data *ha)1569{1570	struct qla82xx_uri_data_desc *uri_desc = NULL;1571 1572	if (ha->fw_type == QLA82XX_UNIFIED_ROMIMAGE) {1573		uri_desc =  qla82xx_get_data_desc(ha, QLA82XX_URI_DIR_SECT_FW,1574		    QLA82XX_URI_FIRMWARE_IDX_OFF);1575		if (uri_desc)1576			return le32_to_cpu(uri_desc->size);1577	}1578 1579	return get_unaligned_le32(&ha->hablob->fw->data[FW_SIZE_OFFSET]);1580}1581 1582static u8 *1583qla82xx_get_fw_offs(struct qla_hw_data *ha)1584{1585	u32 offset = IMAGE_START;1586	struct qla82xx_uri_data_desc *uri_desc = NULL;1587 1588	if (ha->fw_type == QLA82XX_UNIFIED_ROMIMAGE) {1589		uri_desc = qla82xx_get_data_desc(ha, QLA82XX_URI_DIR_SECT_FW,1590			QLA82XX_URI_FIRMWARE_IDX_OFF);1591		if (uri_desc)1592			offset = le32_to_cpu(uri_desc->findex);1593	}1594 1595	return (u8 *)&ha->hablob->fw->data[offset];1596}1597 1598/* PCI related functions */1599int qla82xx_pci_region_offset(struct pci_dev *pdev, int region)1600{1601	unsigned long val = 0;1602	u32 control;1603 1604	switch (region) {1605	case 0:1606		val = 0;1607		break;1608	case 1:1609		pci_read_config_dword(pdev, QLA82XX_PCI_REG_MSIX_TBL, &control);1610		val = control + QLA82XX_MSIX_TBL_SPACE;1611		break;1612	}1613	return val;1614}1615 1616 1617int1618qla82xx_iospace_config(struct qla_hw_data *ha)1619{1620	uint32_t len = 0;1621 1622	if (pci_request_regions(ha->pdev, QLA2XXX_DRIVER_NAME)) {1623		ql_log_pci(ql_log_fatal, ha->pdev, 0x000c,1624		    "Failed to reserver selected regions.\n");1625		goto iospace_error_exit;1626	}1627 1628	/* Use MMIO operations for all accesses. */1629	if (!(pci_resource_flags(ha->pdev, 0) & IORESOURCE_MEM)) {1630		ql_log_pci(ql_log_fatal, ha->pdev, 0x000d,1631		    "Region #0 not an MMIO resource, aborting.\n");1632		goto iospace_error_exit;1633	}1634 1635	len = pci_resource_len(ha->pdev, 0);1636	ha->nx_pcibase = ioremap(pci_resource_start(ha->pdev, 0), len);1637	if (!ha->nx_pcibase) {1638		ql_log_pci(ql_log_fatal, ha->pdev, 0x000e,1639		    "Cannot remap pcibase MMIO, aborting.\n");1640		goto iospace_error_exit;1641	}1642 1643	/* Mapping of IO base pointer */1644	if (IS_QLA8044(ha)) {1645		ha->iobase = ha->nx_pcibase;1646	} else if (IS_QLA82XX(ha)) {1647		ha->iobase = ha->nx_pcibase + 0xbc000 + (ha->pdev->devfn << 11);1648	}1649 1650	if (!ql2xdbwr) {1651		ha->nxdb_wr_ptr = ioremap((pci_resource_start(ha->pdev, 4) +1652		    (ha->pdev->devfn << 12)), 4);1653		if (!ha->nxdb_wr_ptr) {1654			ql_log_pci(ql_log_fatal, ha->pdev, 0x000f,1655			    "Cannot remap MMIO, aborting.\n");1656			goto iospace_error_exit;1657		}1658 1659		/* Mapping of IO base pointer,1660		 * door bell read and write pointer1661		 */1662		ha->nxdb_rd_ptr = ha->nx_pcibase + (512 * 1024) +1663		    (ha->pdev->devfn * 8);1664	} else {1665		ha->nxdb_wr_ptr = (void __iomem *)(ha->pdev->devfn == 6 ?1666			QLA82XX_CAMRAM_DB1 :1667			QLA82XX_CAMRAM_DB2);1668	}1669 1670	ha->max_req_queues = ha->max_rsp_queues = 1;1671	ha->msix_count = ha->max_rsp_queues + 1;1672	ql_dbg_pci(ql_dbg_multiq, ha->pdev, 0xc006,1673	    "nx_pci_base=%p iobase=%p "1674	    "max_req_queues=%d msix_count=%d.\n",1675	    ha->nx_pcibase, ha->iobase,1676	    ha->max_req_queues, ha->msix_count);1677	ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0010,1678	    "nx_pci_base=%p iobase=%p "1679	    "max_req_queues=%d msix_count=%d.\n",1680	    ha->nx_pcibase, ha->iobase,1681	    ha->max_req_queues, ha->msix_count);1682	return 0;1683 1684iospace_error_exit:1685	return -ENOMEM;1686}1687 1688/* GS related functions */1689 1690/* Initialization related functions */1691 1692/**1693 * qla82xx_pci_config() - Setup ISP82xx PCI configuration registers.1694 * @vha: HA context1695 *1696 * Returns 0 on success.1697*/1698int1699qla82xx_pci_config(scsi_qla_host_t *vha)1700{1701	struct qla_hw_data *ha = vha->hw;1702	int ret;1703 1704	pci_set_master(ha->pdev);1705	ret = pci_set_mwi(ha->pdev);1706	ha->chip_revision = ha->pdev->revision;1707	ql_dbg(ql_dbg_init, vha, 0x0043,1708	    "Chip revision:%d; pci_set_mwi() returned %d.\n",1709	    ha->chip_revision, ret);1710	return 0;1711}1712 1713/**1714 * qla82xx_reset_chip() - Setup ISP82xx PCI configuration registers.1715 * @vha: HA context1716 *1717 * Returns 0 on success.1718 */1719int1720qla82xx_reset_chip(scsi_qla_host_t *vha)1721{1722	struct qla_hw_data *ha = vha->hw;1723 1724	ha->isp_ops->disable_intrs(ha);1725 1726	return QLA_SUCCESS;1727}1728 1729void qla82xx_config_rings(struct scsi_qla_host *vha)1730{1731	struct qla_hw_data *ha = vha->hw;1732	struct device_reg_82xx __iomem *reg = &ha->iobase->isp82;1733	struct init_cb_81xx *icb;1734	struct req_que *req = ha->req_q_map[0];1735	struct rsp_que *rsp = ha->rsp_q_map[0];1736 1737	/* Setup ring parameters in initialization control block. */1738	icb = (struct init_cb_81xx *)ha->init_cb;1739	icb->request_q_outpointer = cpu_to_le16(0);1740	icb->response_q_inpointer = cpu_to_le16(0);1741	icb->request_q_length = cpu_to_le16(req->length);1742	icb->response_q_length = cpu_to_le16(rsp->length);1743	put_unaligned_le64(req->dma, &icb->request_q_address);1744	put_unaligned_le64(rsp->dma, &icb->response_q_address);1745 1746	wrt_reg_dword(&reg->req_q_out[0], 0);1747	wrt_reg_dword(&reg->rsp_q_in[0], 0);1748	wrt_reg_dword(&reg->rsp_q_out[0], 0);1749}1750 1751static int1752qla82xx_fw_load_from_blob(struct qla_hw_data *ha)1753{1754	u64 *ptr64;1755	u32 i, flashaddr, size;1756	__le64 data;1757 1758	size = (IMAGE_START - BOOTLD_START) / 8;1759 1760	ptr64 = (u64 *)qla82xx_get_bootld_offset(ha);1761	flashaddr = BOOTLD_START;1762 1763	for (i = 0; i < size; i++) {1764		data = cpu_to_le64(ptr64[i]);1765		if (qla82xx_pci_mem_write_2M(ha, flashaddr, &data, 8))1766			return -EIO;1767		flashaddr += 8;1768	}1769 1770	flashaddr = FLASH_ADDR_START;1771	size = qla82xx_get_fw_size(ha) / 8;1772	ptr64 = (u64 *)qla82xx_get_fw_offs(ha);1773 1774	for (i = 0; i < size; i++) {1775		data = cpu_to_le64(ptr64[i]);1776 1777		if (qla82xx_pci_mem_write_2M(ha, flashaddr, &data, 8))1778			return -EIO;1779		flashaddr += 8;1780	}1781	udelay(100);1782 1783	/* Write a magic value to CAMRAM register1784	 * at a specified offset to indicate1785	 * that all data is written and1786	 * ready for firmware to initialize.1787	 */1788	qla82xx_wr_32(ha, QLA82XX_CAM_RAM(0x1fc), QLA82XX_BDINFO_MAGIC);1789 1790	read_lock(&ha->hw_lock);1791	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_0 + 0x18, 0x1020);1792	qla82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0x80001e);1793	read_unlock(&ha->hw_lock);1794	return 0;1795}1796 1797static int1798qla82xx_set_product_offset(struct qla_hw_data *ha)1799{1800	struct qla82xx_uri_table_desc *ptab_desc = NULL;1801	const uint8_t *unirom = ha->hablob->fw->data;1802	uint32_t i;1803	uint32_t entries;1804	uint32_t flags, file_chiprev, offset;1805	uint8_t chiprev = ha->chip_revision;1806	/* Hardcoding mn_present flag for P3P */1807	int mn_present = 0;1808	uint32_t flagbit;1809 1810	ptab_desc = qla82xx_get_table_desc(unirom,1811		 QLA82XX_URI_DIR_SECT_PRODUCT_TBL);1812	if (!ptab_desc)1813		return -1;1814 1815	entries = le32_to_cpu(ptab_desc->num_entries);1816 1817	for (i = 0; i < entries; i++) {1818		offset = le32_to_cpu(ptab_desc->findex) +1819			(i * le32_to_cpu(ptab_desc->entry_size));1820		flags = le32_to_cpu(*((__le32 *)&unirom[offset] +1821			QLA82XX_URI_FLAGS_OFF));1822		file_chiprev = le32_to_cpu(*((__le32 *)&unirom[offset] +1823			QLA82XX_URI_CHIP_REV_OFF));1824 1825		flagbit = mn_present ? 1 : 2;1826 1827		if ((chiprev == file_chiprev) && ((1ULL << flagbit) & flags)) {1828			ha->file_prd_off = offset;1829			return 0;1830		}1831	}1832	return -1;1833}1834 1835static int1836qla82xx_validate_firmware_blob(scsi_qla_host_t *vha, uint8_t fw_type)1837{1838	uint32_t val;1839	uint32_t min_size;1840	struct qla_hw_data *ha = vha->hw;1841	const struct firmware *fw = ha->hablob->fw;1842 1843	ha->fw_type = fw_type;1844 1845	if (fw_type == QLA82XX_UNIFIED_ROMIMAGE) {1846		if (qla82xx_set_product_offset(ha))1847			return -EINVAL;1848 1849		min_size = QLA82XX_URI_FW_MIN_SIZE;1850	} else {1851		val = get_unaligned_le32(&fw->data[QLA82XX_FW_MAGIC_OFFSET]);1852		if (val != QLA82XX_BDINFO_MAGIC)1853			return -EINVAL;1854 1855		min_size = QLA82XX_FW_MIN_SIZE;1856	}1857 1858	if (fw->size < min_size)1859		return -EINVAL;1860	return 0;1861}1862 1863static int1864qla82xx_check_cmdpeg_state(struct qla_hw_data *ha)1865{1866	u32 val = 0;1867	int retries = 60;1868	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);1869 1870	do {1871		read_lock(&ha->hw_lock);1872		val = qla82xx_rd_32(ha, CRB_CMDPEG_STATE);1873		read_unlock(&ha->hw_lock);1874 1875		switch (val) {1876		case PHAN_INITIALIZE_COMPLETE:1877		case PHAN_INITIALIZE_ACK:1878			return QLA_SUCCESS;1879		case PHAN_INITIALIZE_FAILED:1880			break;1881		default:1882			break;1883		}1884		ql_log(ql_log_info, vha, 0x00a8,1885		    "CRB_CMDPEG_STATE: 0x%x and retries:0x%x.\n",1886		    val, retries);1887 1888		msleep(500);1889 1890	} while (--retries);1891 1892	ql_log(ql_log_fatal, vha, 0x00a9,1893	    "Cmd Peg initialization failed: 0x%x.\n", val);1894 1895	val = qla82xx_rd_32(ha, QLA82XX_ROMUSB_GLB_PEGTUNE_DONE);1896	read_lock(&ha->hw_lock);1897	qla82xx_wr_32(ha, CRB_CMDPEG_STATE, PHAN_INITIALIZE_FAILED);1898	read_unlock(&ha->hw_lock);1899	return QLA_FUNCTION_FAILED;1900}1901 1902static int1903qla82xx_check_rcvpeg_state(struct qla_hw_data *ha)1904{1905	u32 val = 0;1906	int retries = 60;1907	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);1908 1909	do {1910		read_lock(&ha->hw_lock);1911		val = qla82xx_rd_32(ha, CRB_RCVPEG_STATE);1912		read_unlock(&ha->hw_lock);1913 1914		switch (val) {1915		case PHAN_INITIALIZE_COMPLETE:1916		case PHAN_INITIALIZE_ACK:1917			return QLA_SUCCESS;1918		case PHAN_INITIALIZE_FAILED:1919			break;1920		default:1921			break;1922		}1923		ql_log(ql_log_info, vha, 0x00ab,1924		    "CRB_RCVPEG_STATE: 0x%x and retries: 0x%x.\n",1925		    val, retries);1926 1927		msleep(500);1928 1929	} while (--retries);1930 1931	ql_log(ql_log_fatal, vha, 0x00ac,1932	    "Rcv Peg initialization failed: 0x%x.\n", val);1933	read_lock(&ha->hw_lock);1934	qla82xx_wr_32(ha, CRB_RCVPEG_STATE, PHAN_INITIALIZE_FAILED);1935	read_unlock(&ha->hw_lock);1936	return QLA_FUNCTION_FAILED;1937}1938 1939/* ISR related functions */1940static struct qla82xx_legacy_intr_set legacy_intr[] =1941	QLA82XX_LEGACY_INTR_CONFIG;1942 1943/*1944 * qla82xx_mbx_completion() - Process mailbox command completions.1945 * @ha: SCSI driver HA context1946 * @mb0: Mailbox0 register1947 */1948void1949qla82xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0)1950{1951	uint16_t	cnt;1952	__le16 __iomem *wptr;1953	struct qla_hw_data *ha = vha->hw;1954	struct device_reg_82xx __iomem *reg = &ha->iobase->isp82;1955 1956	wptr = &reg->mailbox_out[1];1957 1958	/* Load return mailbox registers. */1959	ha->flags.mbox_int = 1;1960	ha->mailbox_out[0] = mb0;1961 1962	for (cnt = 1; cnt < ha->mbx_count; cnt++) {1963		ha->mailbox_out[cnt] = rd_reg_word(wptr);1964		wptr++;1965	}1966 1967	if (!ha->mcp)1968		ql_dbg(ql_dbg_async, vha, 0x5053,1969		    "MBX pointer ERROR.\n");1970}1971 1972/**1973 * qla82xx_intr_handler() - Process interrupts for the ISP23xx and ISP63xx.1974 * @irq: interrupt number1975 * @dev_id: SCSI driver HA context1976 *1977 * Called by system whenever the host adapter generates an interrupt.1978 *1979 * Returns handled flag.1980 */1981irqreturn_t1982qla82xx_intr_handler(int irq, void *dev_id)1983{1984	scsi_qla_host_t	*vha;1985	struct qla_hw_data *ha;1986	struct rsp_que *rsp;1987	struct device_reg_82xx __iomem *reg;1988	int status = 0, status1 = 0;1989	unsigned long	flags;1990	unsigned long	iter;1991	uint32_t	stat = 0;1992	uint16_t	mb[8];1993 1994	rsp = (struct rsp_que *) dev_id;1995	if (!rsp) {1996		ql_log(ql_log_info, NULL, 0xb053,1997		    "%s: NULL response queue pointer.\n", __func__);1998		return IRQ_NONE;1999	}2000	ha = rsp->hw;2001 2002	if (!ha->flags.msi_enabled) {2003		status = qla82xx_rd_32(ha, ISR_INT_VECTOR);2004		if (!(status & ha->nx_legacy_intr.int_vec_bit))2005			return IRQ_NONE;2006 2007		status1 = qla82xx_rd_32(ha, ISR_INT_STATE_REG);2008		if (!ISR_IS_LEGACY_INTR_TRIGGERED(status1))2009			return IRQ_NONE;2010	}2011 2012	/* clear the interrupt */2013	qla82xx_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xffffffff);2014 2015	/* read twice to ensure write is flushed */2016	qla82xx_rd_32(ha, ISR_INT_VECTOR);2017	qla82xx_rd_32(ha, ISR_INT_VECTOR);2018 2019	reg = &ha->iobase->isp82;2020 2021	spin_lock_irqsave(&ha->hardware_lock, flags);2022	vha = pci_get_drvdata(ha->pdev);2023	for (iter = 1; iter--; ) {2024 2025		if (rd_reg_dword(&reg->host_int)) {2026			stat = rd_reg_dword(&reg->host_status);2027 2028			switch (stat & 0xff) {2029			case 0x1:2030			case 0x2:2031			case 0x10:2032			case 0x11:2033				qla82xx_mbx_completion(vha, MSW(stat));2034				status |= MBX_INTERRUPT;2035				break;2036			case 0x12:2037				mb[0] = MSW(stat);2038				mb[1] = rd_reg_word(&reg->mailbox_out[1]);2039				mb[2] = rd_reg_word(&reg->mailbox_out[2]);2040				mb[3] = rd_reg_word(&reg->mailbox_out[3]);2041				qla2x00_async_event(vha, rsp, mb);2042				break;2043			case 0x13:2044				qla24xx_process_response_queue(vha, rsp);2045				break;2046			default:2047				ql_dbg(ql_dbg_async, vha, 0x5054,2048				    "Unrecognized interrupt type (%d).\n",2049				    stat & 0xff);2050				break;2051			}2052		}2053		wrt_reg_dword(&reg->host_int, 0);2054	}2055 2056	qla2x00_handle_mbx_completion(ha, status);2057	spin_unlock_irqrestore(&ha->hardware_lock, flags);2058 2059	if (!ha->flags.msi_enabled)2060		qla82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);2061 2062	return IRQ_HANDLED;2063}2064 2065irqreturn_t2066qla82xx_msix_default(int irq, void *dev_id)2067{2068	scsi_qla_host_t	*vha;2069	struct qla_hw_data *ha;2070	struct rsp_que *rsp;2071	struct device_reg_82xx __iomem *reg;2072	int status = 0;2073	unsigned long flags;2074	uint32_t stat = 0;2075	uint32_t host_int = 0;2076	uint16_t mb[8];2077 2078	rsp = (struct rsp_que *) dev_id;2079	if (!rsp) {2080		printk(KERN_INFO2081			"%s(): NULL response queue pointer.\n", __func__);2082		return IRQ_NONE;2083	}2084	ha = rsp->hw;2085 2086	reg = &ha->iobase->isp82;2087 2088	spin_lock_irqsave(&ha->hardware_lock, flags);2089	vha = pci_get_drvdata(ha->pdev);2090	do {2091		host_int = rd_reg_dword(&reg->host_int);2092		if (qla2x00_check_reg32_for_disconnect(vha, host_int))2093			break;2094		if (host_int) {2095			stat = rd_reg_dword(&reg->host_status);2096 2097			switch (stat & 0xff) {2098			case 0x1:2099			case 0x2:2100			case 0x10:2101			case 0x11:2102				qla82xx_mbx_completion(vha, MSW(stat));2103				status |= MBX_INTERRUPT;2104				break;2105			case 0x12:2106				mb[0] = MSW(stat);2107				mb[1] = rd_reg_word(&reg->mailbox_out[1]);2108				mb[2] = rd_reg_word(&reg->mailbox_out[2]);2109				mb[3] = rd_reg_word(&reg->mailbox_out[3]);2110				qla2x00_async_event(vha, rsp, mb);2111				break;2112			case 0x13:2113				qla24xx_process_response_queue(vha, rsp);2114				break;2115			default:2116				ql_dbg(ql_dbg_async, vha, 0x5041,2117				    "Unrecognized interrupt type (%d).\n",2118				    stat & 0xff);2119				break;2120			}2121		}2122		wrt_reg_dword(&reg->host_int, 0);2123	} while (0);2124 2125	qla2x00_handle_mbx_completion(ha, status);2126	spin_unlock_irqrestore(&ha->hardware_lock, flags);2127 2128	return IRQ_HANDLED;2129}2130 2131irqreturn_t2132qla82xx_msix_rsp_q(int irq, void *dev_id)2133{2134	scsi_qla_host_t	*vha;2135	struct qla_hw_data *ha;2136	struct rsp_que *rsp;2137	struct device_reg_82xx __iomem *reg;2138	unsigned long flags;2139	uint32_t host_int = 0;2140 2141	rsp = (struct rsp_que *) dev_id;2142	if (!rsp) {2143		printk(KERN_INFO2144			"%s(): NULL response queue pointer.\n", __func__);2145		return IRQ_NONE;2146	}2147 2148	ha = rsp->hw;2149	reg = &ha->iobase->isp82;2150	spin_lock_irqsave(&ha->hardware_lock, flags);2151	vha = pci_get_drvdata(ha->pdev);2152	host_int = rd_reg_dword(&reg->host_int);2153	if (qla2x00_check_reg32_for_disconnect(vha, host_int))2154		goto out;2155	qla24xx_process_response_queue(vha, rsp);2156	wrt_reg_dword(&reg->host_int, 0);2157out:2158	spin_unlock_irqrestore(&ha->hardware_lock, flags);2159	return IRQ_HANDLED;2160}2161 2162void2163qla82xx_poll(int irq, void *dev_id)2164{2165	scsi_qla_host_t	*vha;2166	struct qla_hw_data *ha;2167	struct rsp_que *rsp;2168	struct device_reg_82xx __iomem *reg;2169	uint32_t stat;2170	uint32_t host_int = 0;2171	uint16_t mb[8];2172	unsigned long flags;2173 2174	rsp = (struct rsp_que *) dev_id;2175	if (!rsp) {2176		printk(KERN_INFO2177			"%s(): NULL response queue pointer.\n", __func__);2178		return;2179	}2180	ha = rsp->hw;2181 2182	reg = &ha->iobase->isp82;2183	spin_lock_irqsave(&ha->hardware_lock, flags);2184	vha = pci_get_drvdata(ha->pdev);2185 2186	host_int = rd_reg_dword(&reg->host_int);2187	if (qla2x00_check_reg32_for_disconnect(vha, host_int))2188		goto out;2189	if (host_int) {2190		stat = rd_reg_dword(&reg->host_status);2191		switch (stat & 0xff) {2192		case 0x1:2193		case 0x2:2194		case 0x10:2195		case 0x11:2196			qla82xx_mbx_completion(vha, MSW(stat));2197			break;2198		case 0x12:2199			mb[0] = MSW(stat);2200			mb[1] = rd_reg_word(&reg->mailbox_out[1]);2201			mb[2] = rd_reg_word(&reg->mailbox_out[2]);2202			mb[3] = rd_reg_word(&reg->mailbox_out[3]);2203			qla2x00_async_event(vha, rsp, mb);2204			break;2205		case 0x13:2206			qla24xx_process_response_queue(vha, rsp);2207			break;2208		default:2209			ql_dbg(ql_dbg_p3p, vha, 0xb013,2210			    "Unrecognized interrupt type (%d).\n",2211			    stat * 0xff);2212			break;2213		}2214		wrt_reg_dword(&reg->host_int, 0);2215	}2216out:2217	spin_unlock_irqrestore(&ha->hardware_lock, flags);2218}2219 2220void2221qla82xx_enable_intrs(struct qla_hw_data *ha)2222{2223	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);2224 2225	qla82xx_mbx_intr_enable(vha);2226	spin_lock_irq(&ha->hardware_lock);2227	if (IS_QLA8044(ha))2228		qla8044_wr_reg(ha, LEG_INTR_MASK_OFFSET, 0);2229	else2230		qla82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);2231	spin_unlock_irq(&ha->hardware_lock);2232	ha->interrupts_on = 1;2233}2234 2235void2236qla82xx_disable_intrs(struct qla_hw_data *ha)2237{2238	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);2239 2240	if (ha->interrupts_on)2241		qla82xx_mbx_intr_disable(vha);2242 2243	spin_lock_irq(&ha->hardware_lock);2244	if (IS_QLA8044(ha))2245		qla8044_wr_reg(ha, LEG_INTR_MASK_OFFSET, 1);2246	else2247		qla82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0x0400);2248	spin_unlock_irq(&ha->hardware_lock);2249	ha->interrupts_on = 0;2250}2251 2252void qla82xx_init_flags(struct qla_hw_data *ha)2253{2254	struct qla82xx_legacy_intr_set *nx_legacy_intr;2255 2256	/* ISP 8021 initializations */2257	rwlock_init(&ha->hw_lock);2258	ha->qdr_sn_window = -1;2259	ha->ddr_mn_window = -1;2260	ha->curr_window = 255;2261	ha->portnum = PCI_FUNC(ha->pdev->devfn);2262	nx_legacy_intr = &legacy_intr[ha->portnum];2263	ha->nx_legacy_intr.int_vec_bit = nx_legacy_intr->int_vec_bit;2264	ha->nx_legacy_intr.tgt_status_reg = nx_legacy_intr->tgt_status_reg;2265	ha->nx_legacy_intr.tgt_mask_reg = nx_legacy_intr->tgt_mask_reg;2266	ha->nx_legacy_intr.pci_int_reg = nx_legacy_intr->pci_int_reg;2267}2268 2269static inline void2270qla82xx_set_idc_version(scsi_qla_host_t *vha)2271{2272	int idc_ver;2273	uint32_t drv_active;2274	struct qla_hw_data *ha = vha->hw;2275 2276	drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);2277	if (drv_active == (QLA82XX_DRV_ACTIVE << (ha->portnum * 4))) {2278		qla82xx_wr_32(ha, QLA82XX_CRB_DRV_IDC_VERSION,2279		    QLA82XX_IDC_VERSION);2280		ql_log(ql_log_info, vha, 0xb082,2281		    "IDC version updated to %d\n", QLA82XX_IDC_VERSION);2282	} else {2283		idc_ver = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_IDC_VERSION);2284		if (idc_ver != QLA82XX_IDC_VERSION)2285			ql_log(ql_log_info, vha, 0xb083,2286			    "qla2xxx driver IDC version %d is not compatible "2287			    "with IDC version %d of the other drivers\n",2288			    QLA82XX_IDC_VERSION, idc_ver);2289	}2290}2291 2292inline void2293qla82xx_set_drv_active(scsi_qla_host_t *vha)2294{2295	uint32_t drv_active;2296	struct qla_hw_data *ha = vha->hw;2297 2298	drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);2299 2300	/* If reset value is all FF's, initialize DRV_ACTIVE */2301	if (drv_active == 0xffffffff) {2302		qla82xx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE,2303			QLA82XX_DRV_NOT_ACTIVE);2304		drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);2305	}2306	drv_active |= (QLA82XX_DRV_ACTIVE << (ha->portnum * 4));2307	qla82xx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE, drv_active);2308}2309 2310inline void2311qla82xx_clear_drv_active(struct qla_hw_data *ha)2312{2313	uint32_t drv_active;2314 2315	drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);2316	drv_active &= ~(QLA82XX_DRV_ACTIVE << (ha->portnum * 4));2317	qla82xx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE, drv_active);2318}2319 2320static inline int2321qla82xx_need_reset(struct qla_hw_data *ha)2322{2323	uint32_t drv_state;2324	int rval;2325 2326	if (ha->flags.nic_core_reset_owner)2327		return 1;2328	else {2329		drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);2330		rval = drv_state & (QLA82XX_DRVST_RST_RDY << (ha->portnum * 4));2331		return rval;2332	}2333}2334 2335static inline void2336qla82xx_set_rst_ready(struct qla_hw_data *ha)2337{2338	uint32_t drv_state;2339	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);2340 2341	drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);2342 2343	/* If reset value is all FF's, initialize DRV_STATE */2344	if (drv_state == 0xffffffff) {2345		qla82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, QLA82XX_DRVST_NOT_RDY);2346		drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);2347	}2348	drv_state |= (QLA82XX_DRVST_RST_RDY << (ha->portnum * 4));2349	ql_dbg(ql_dbg_init, vha, 0x00bb,2350	    "drv_state = 0x%08x.\n", drv_state);2351	qla82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, drv_state);2352}2353 2354static inline void2355qla82xx_clear_rst_ready(struct qla_hw_data *ha)2356{2357	uint32_t drv_state;2358 2359	drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);2360	drv_state &= ~(QLA82XX_DRVST_RST_RDY << (ha->portnum * 4));2361	qla82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, drv_state);2362}2363 2364static inline void2365qla82xx_set_qsnt_ready(struct qla_hw_data *ha)2366{2367	uint32_t qsnt_state;2368 2369	qsnt_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);2370	qsnt_state |= (QLA82XX_DRVST_QSNT_RDY << (ha->portnum * 4));2371	qla82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, qsnt_state);2372}2373 2374void2375qla82xx_clear_qsnt_ready(scsi_qla_host_t *vha)2376{2377	struct qla_hw_data *ha = vha->hw;2378	uint32_t qsnt_state;2379 2380	qsnt_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);2381	qsnt_state &= ~(QLA82XX_DRVST_QSNT_RDY << (ha->portnum * 4));2382	qla82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, qsnt_state);2383}2384 2385static int2386qla82xx_load_fw(scsi_qla_host_t *vha)2387{2388	int rst;2389	struct fw_blob *blob;2390	struct qla_hw_data *ha = vha->hw;2391 2392	if (qla82xx_pinit_from_rom(vha) != QLA_SUCCESS) {2393		ql_log(ql_log_fatal, vha, 0x009f,2394		    "Error during CRB initialization.\n");2395		return QLA_FUNCTION_FAILED;2396	}2397	udelay(500);2398 2399	/* Bring QM and CAMRAM out of reset */2400	rst = qla82xx_rd_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET);2401	rst &= ~((1 << 28) | (1 << 24));2402	qla82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, rst);2403 2404	/*2405	 * FW Load priority:2406	 * 1) Operational firmware residing in flash.2407	 * 2) Firmware via request-firmware interface (.bin file).2408	 */2409	if (ql2xfwloadbin == 2)2410		goto try_blob_fw;2411 2412	ql_log(ql_log_info, vha, 0x00a0,2413	    "Attempting to load firmware from flash.\n");2414 2415	if (qla82xx_fw_load_from_flash(ha) == QLA_SUCCESS) {2416		ql_log(ql_log_info, vha, 0x00a1,2417		    "Firmware loaded successfully from flash.\n");2418		return QLA_SUCCESS;2419	} else {2420		ql_log(ql_log_warn, vha, 0x0108,2421		    "Firmware load from flash failed.\n");2422	}2423 2424try_blob_fw:2425	ql_log(ql_log_info, vha, 0x00a2,2426	    "Attempting to load firmware from blob.\n");2427 2428	/* Load firmware blob. */2429	blob = ha->hablob = qla2x00_request_firmware(vha);2430	if (!blob) {2431		ql_log(ql_log_fatal, vha, 0x00a3,2432		    "Firmware image not present.\n");2433		goto fw_load_failed;2434	}2435 2436	/* Validating firmware blob */2437	if (qla82xx_validate_firmware_blob(vha,2438		QLA82XX_FLASH_ROMIMAGE)) {2439		/* Fallback to URI format */2440		if (qla82xx_validate_firmware_blob(vha,2441			QLA82XX_UNIFIED_ROMIMAGE)) {2442			ql_log(ql_log_fatal, vha, 0x00a4,2443			    "No valid firmware image found.\n");2444			return QLA_FUNCTION_FAILED;2445		}2446	}2447 2448	if (qla82xx_fw_load_from_blob(ha) == QLA_SUCCESS) {2449		ql_log(ql_log_info, vha, 0x00a5,2450		    "Firmware loaded successfully from binary blob.\n");2451		return QLA_SUCCESS;2452	}2453 2454	ql_log(ql_log_fatal, vha, 0x00a6,2455	       "Firmware load failed for binary blob.\n");2456	blob->fw = NULL;2457	blob = NULL;2458 2459fw_load_failed:2460	return QLA_FUNCTION_FAILED;2461}2462 2463int2464qla82xx_start_firmware(scsi_qla_host_t *vha)2465{2466	uint16_t      lnk;2467	struct qla_hw_data *ha = vha->hw;2468 2469	/* scrub dma mask expansion register */2470	qla82xx_wr_32(ha, CRB_DMA_SHIFT, QLA82XX_DMA_SHIFT_VALUE);2471 2472	/* Put both the PEG CMD and RCV PEG to default state2473	 * of 0 before resetting the hardware2474	 */2475	qla82xx_wr_32(ha, CRB_CMDPEG_STATE, 0);2476	qla82xx_wr_32(ha, CRB_RCVPEG_STATE, 0);2477 2478	/* Overwrite stale initialization register values */2479	qla82xx_wr_32(ha, QLA82XX_PEG_HALT_STATUS1, 0);2480	qla82xx_wr_32(ha, QLA82XX_PEG_HALT_STATUS2, 0);2481 2482	if (qla82xx_load_fw(vha) != QLA_SUCCESS) {2483		ql_log(ql_log_fatal, vha, 0x00a7,2484		    "Error trying to start fw.\n");2485		return QLA_FUNCTION_FAILED;2486	}2487 2488	/* Handshake with the card before we register the devices. */2489	if (qla82xx_check_cmdpeg_state(ha) != QLA_SUCCESS) {2490		ql_log(ql_log_fatal, vha, 0x00aa,2491		    "Error during card handshake.\n");2492		return QLA_FUNCTION_FAILED;2493	}2494 2495	/* Negotiated Link width */2496	pcie_capability_read_word(ha->pdev, PCI_EXP_LNKSTA, &lnk);2497	ha->link_width = (lnk >> 4) & 0x3f;2498 2499	/* Synchronize with Receive peg */2500	return qla82xx_check_rcvpeg_state(ha);2501}2502 2503static __le32 *2504qla82xx_read_flash_data(scsi_qla_host_t *vha, __le32 *dwptr, uint32_t faddr,2505	uint32_t length)2506{2507	uint32_t i;2508	uint32_t val;2509	struct qla_hw_data *ha = vha->hw;2510 2511	/* Dword reads to flash. */2512	for (i = 0; i < length/4; i++, faddr += 4) {2513		if (qla82xx_rom_fast_read(ha, faddr, &val)) {2514			ql_log(ql_log_warn, vha, 0x0106,2515			    "Do ROM fast read failed.\n");2516			goto done_read;2517		}2518		dwptr[i] = cpu_to_le32(val);2519	}2520done_read:2521	return dwptr;2522}2523 2524static int2525qla82xx_unprotect_flash(struct qla_hw_data *ha)2526{2527	int ret;2528	uint32_t val;2529	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);2530 2531	ret = ql82xx_rom_lock_d(ha);2532	if (ret < 0) {2533		ql_log(ql_log_warn, vha, 0xb014,2534		    "ROM Lock failed.\n");2535		return ret;2536	}2537 2538	ret = qla82xx_read_status_reg(ha, &val);2539	if (ret < 0)2540		goto done_unprotect;2541 2542	val &= ~(BLOCK_PROTECT_BITS << 2);2543	ret = qla82xx_write_status_reg(ha, val);2544	if (ret < 0) {2545		val |= (BLOCK_PROTECT_BITS << 2);2546		qla82xx_write_status_reg(ha, val);2547	}2548 2549	if (qla82xx_write_disable_flash(ha) != 0)2550		ql_log(ql_log_warn, vha, 0xb015,2551		    "Write disable failed.\n");2552 2553done_unprotect:2554	qla82xx_rom_unlock(ha);2555	return ret;2556}2557 2558static int2559qla82xx_protect_flash(struct qla_hw_data *ha)2560{2561	int ret;2562	uint32_t val;2563	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);2564 2565	ret = ql82xx_rom_lock_d(ha);2566	if (ret < 0) {2567		ql_log(ql_log_warn, vha, 0xb016,2568		    "ROM Lock failed.\n");2569		return ret;2570	}2571 2572	ret = qla82xx_read_status_reg(ha, &val);2573	if (ret < 0)2574		goto done_protect;2575 2576	val |= (BLOCK_PROTECT_BITS << 2);2577	/* LOCK all sectors */2578	ret = qla82xx_write_status_reg(ha, val);2579	if (ret < 0)2580		ql_log(ql_log_warn, vha, 0xb017,2581		    "Write status register failed.\n");2582 2583	if (qla82xx_write_disable_flash(ha) != 0)2584		ql_log(ql_log_warn, vha, 0xb018,2585		    "Write disable failed.\n");2586done_protect:2587	qla82xx_rom_unlock(ha);2588	return ret;2589}2590 2591static int2592qla82xx_erase_sector(struct qla_hw_data *ha, int addr)2593{2594	int ret = 0;2595	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);2596 2597	ret = ql82xx_rom_lock_d(ha);2598	if (ret < 0) {2599		ql_log(ql_log_warn, vha, 0xb019,2600		    "ROM Lock failed.\n");2601		return ret;2602	}2603 2604	qla82xx_flash_set_write_enable(ha);2605	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ADDRESS, addr);2606	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_ABYTE_CNT, 3);2607	qla82xx_wr_32(ha, QLA82XX_ROMUSB_ROM_INSTR_OPCODE, M25P_INSTR_SE);2608 2609	if (qla82xx_wait_rom_done(ha)) {2610		ql_log(ql_log_warn, vha, 0xb01a,2611		    "Error waiting for rom done.\n");2612		ret = -1;2613		goto done;2614	}2615	ret = qla82xx_flash_wait_write_finish(ha);2616done:2617	qla82xx_rom_unlock(ha);2618	return ret;2619}2620 2621/*2622 * Address and length are byte address2623 */2624void *2625qla82xx_read_optrom_data(struct scsi_qla_host *vha, void *buf,2626	uint32_t offset, uint32_t length)2627{2628	scsi_block_requests(vha->host);2629	qla82xx_read_flash_data(vha, buf, offset, length);2630	scsi_unblock_requests(vha->host);2631	return buf;2632}2633 2634static int2635qla82xx_write_flash_data(struct scsi_qla_host *vha, __le32 *dwptr,2636	uint32_t faddr, uint32_t dwords)2637{2638	int ret;2639	uint32_t liter;2640	uint32_t rest_addr;2641	dma_addr_t optrom_dma;2642	void *optrom = NULL;2643	int page_mode = 0;2644	struct qla_hw_data *ha = vha->hw;2645 2646	ret = -1;2647 2648	/* Prepare burst-capable write on supported ISPs. */2649	if (page_mode && !(faddr & 0xfff) &&2650	    dwords > OPTROM_BURST_DWORDS) {2651		optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE,2652		    &optrom_dma, GFP_KERNEL);2653		if (!optrom) {2654			ql_log(ql_log_warn, vha, 0xb01b,2655			    "Unable to allocate memory "2656			    "for optrom burst write (%x KB).\n",2657			    OPTROM_BURST_SIZE / 1024);2658		}2659	}2660 2661	rest_addr = ha->fdt_block_size - 1;2662 2663	ret = qla82xx_unprotect_flash(ha);2664	if (ret) {2665		ql_log(ql_log_warn, vha, 0xb01c,2666		    "Unable to unprotect flash for update.\n");2667		goto write_done;2668	}2669 2670	for (liter = 0; liter < dwords; liter++, faddr += 4, dwptr++) {2671		/* Are we at the beginning of a sector? */2672		if ((faddr & rest_addr) == 0) {2673 2674			ret = qla82xx_erase_sector(ha, faddr);2675			if (ret) {2676				ql_log(ql_log_warn, vha, 0xb01d,2677				    "Unable to erase sector: address=%x.\n",2678				    faddr);2679				break;2680			}2681		}2682 2683		/* Go with burst-write. */2684		if (optrom && (liter + OPTROM_BURST_DWORDS) <= dwords) {2685			/* Copy data to DMA'ble buffer. */2686			memcpy(optrom, dwptr, OPTROM_BURST_SIZE);2687 2688			ret = qla2x00_load_ram(vha, optrom_dma,2689			    (ha->flash_data_off | faddr),2690			    OPTROM_BURST_DWORDS);2691			if (ret != QLA_SUCCESS) {2692				ql_log(ql_log_warn, vha, 0xb01e,2693				    "Unable to burst-write optrom segment "2694				    "(%x/%x/%llx).\n", ret,2695				    (ha->flash_data_off | faddr),2696				    (unsigned long long)optrom_dma);2697				ql_log(ql_log_warn, vha, 0xb01f,2698				    "Reverting to slow-write.\n");2699 2700				dma_free_coherent(&ha->pdev->dev,2701				    OPTROM_BURST_SIZE, optrom, optrom_dma);2702				optrom = NULL;2703			} else {2704				liter += OPTROM_BURST_DWORDS - 1;2705				faddr += OPTROM_BURST_DWORDS - 1;2706				dwptr += OPTROM_BURST_DWORDS - 1;2707				continue;2708			}2709		}2710 2711		ret = qla82xx_write_flash_dword(ha, faddr,2712						le32_to_cpu(*dwptr));2713		if (ret) {2714			ql_dbg(ql_dbg_p3p, vha, 0xb020,2715			    "Unable to program flash address=%x data=%x.\n",2716			    faddr, *dwptr);2717			break;2718		}2719	}2720 2721	ret = qla82xx_protect_flash(ha);2722	if (ret)2723		ql_log(ql_log_warn, vha, 0xb021,2724		    "Unable to protect flash after update.\n");2725write_done:2726	if (optrom)2727		dma_free_coherent(&ha->pdev->dev,2728		    OPTROM_BURST_SIZE, optrom, optrom_dma);2729	return ret;2730}2731 2732int2733qla82xx_write_optrom_data(struct scsi_qla_host *vha, void *buf,2734	uint32_t offset, uint32_t length)2735{2736	int rval;2737 2738	/* Suspend HBA. */2739	scsi_block_requests(vha->host);2740	rval = qla82xx_write_flash_data(vha, buf, offset, length >> 2);2741	scsi_unblock_requests(vha->host);2742 2743	/* Convert return ISP82xx to generic */2744	if (rval)2745		rval = QLA_FUNCTION_FAILED;2746	else2747		rval = QLA_SUCCESS;2748	return rval;2749}2750 2751void2752qla82xx_start_iocbs(scsi_qla_host_t *vha)2753{2754	struct qla_hw_data *ha = vha->hw;2755	struct req_que *req = ha->req_q_map[0];2756	uint32_t dbval;2757 2758	/* Adjust ring index. */2759	req->ring_index++;2760	if (req->ring_index == req->length) {2761		req->ring_index = 0;2762		req->ring_ptr = req->ring;2763	} else2764		req->ring_ptr++;2765 2766	dbval = 0x04 | (ha->portnum << 5);2767 2768	dbval = dbval | (req->id << 8) | (req->ring_index << 16);2769	if (ql2xdbwr)2770		qla82xx_wr_32(ha, (unsigned long)ha->nxdb_wr_ptr, dbval);2771	else {2772		wrt_reg_dword(ha->nxdb_wr_ptr, dbval);2773		wmb();2774		while (rd_reg_dword(ha->nxdb_rd_ptr) != dbval) {2775			wrt_reg_dword(ha->nxdb_wr_ptr, dbval);2776			wmb();2777		}2778	}2779}2780 2781static void2782qla82xx_rom_lock_recovery(struct qla_hw_data *ha)2783{2784	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);2785	uint32_t lock_owner = 0;2786 2787	if (qla82xx_rom_lock(ha)) {2788		lock_owner = qla82xx_rd_32(ha, QLA82XX_ROM_LOCK_ID);2789		/* Someone else is holding the lock. */2790		ql_log(ql_log_info, vha, 0xb022,2791		    "Resetting rom_lock, Lock Owner %u.\n", lock_owner);2792	}2793	/*2794	 * Either we got the lock, or someone2795	 * else died while holding it.2796	 * In either case, unlock.2797	 */2798	qla82xx_rom_unlock(ha);2799}2800 2801/*2802 * qla82xx_device_bootstrap2803 *    Initialize device, set DEV_READY, start fw2804 *2805 * Note:2806 *      IDC lock must be held upon entry2807 *2808 * Return:2809 *    Success : 02810 *    Failed  : 12811 */2812static int2813qla82xx_device_bootstrap(scsi_qla_host_t *vha)2814{2815	int rval = QLA_SUCCESS;2816	int i;2817	uint32_t old_count, count;2818	struct qla_hw_data *ha = vha->hw;2819	int need_reset = 0;2820 2821	need_reset = qla82xx_need_reset(ha);2822 2823	if (need_reset) {2824		/* We are trying to perform a recovery here. */2825		if (ha->flags.isp82xx_fw_hung)2826			qla82xx_rom_lock_recovery(ha);2827	} else  {2828		old_count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);2829		for (i = 0; i < 10; i++) {2830			msleep(200);2831			count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);2832			if (count != old_count) {2833				rval = QLA_SUCCESS;2834				goto dev_ready;2835			}2836		}2837		qla82xx_rom_lock_recovery(ha);2838	}2839 2840	/* set to DEV_INITIALIZING */2841	ql_log(ql_log_info, vha, 0x009e,2842	    "HW State: INITIALIZING.\n");2843	qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA8XXX_DEV_INITIALIZING);2844 2845	qla82xx_idc_unlock(ha);2846	rval = qla82xx_start_firmware(vha);2847	qla82xx_idc_lock(ha);2848 2849	if (rval != QLA_SUCCESS) {2850		ql_log(ql_log_fatal, vha, 0x00ad,2851		    "HW State: FAILED.\n");2852		qla82xx_clear_drv_active(ha);2853		qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA8XXX_DEV_FAILED);2854		return rval;2855	}2856 2857dev_ready:2858	ql_log(ql_log_info, vha, 0x00ae,2859	    "HW State: READY.\n");2860	qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA8XXX_DEV_READY);2861 2862	return QLA_SUCCESS;2863}2864 2865/*2866* qla82xx_need_qsnt_handler2867*    Code to start quiescence sequence2868*2869* Note:2870*      IDC lock must be held upon entry2871*2872* Return: void2873*/2874 2875static void2876qla82xx_need_qsnt_handler(scsi_qla_host_t *vha)2877{2878	struct qla_hw_data *ha = vha->hw;2879	uint32_t dev_state, drv_state, drv_active;2880	unsigned long reset_timeout;2881 2882	if (vha->flags.online) {2883		/*Block any further I/O and wait for pending cmnds to complete*/2884		qla2x00_quiesce_io(vha);2885	}2886 2887	/* Set the quiescence ready bit */2888	qla82xx_set_qsnt_ready(ha);2889 2890	/*wait for 30 secs for other functions to ack */2891	reset_timeout = jiffies + (30 * HZ);2892 2893	drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);2894	drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);2895	/* Its 2 that is written when qsnt is acked, moving one bit */2896	drv_active = drv_active << 0x01;2897 2898	while (drv_state != drv_active) {2899 2900		if (time_after_eq(jiffies, reset_timeout)) {2901			/* quiescence timeout, other functions didn't ack2902			 * changing the state to DEV_READY2903			 */2904			ql_log(ql_log_info, vha, 0xb023,2905			    "%s : QUIESCENT TIMEOUT DRV_ACTIVE:%d "2906			    "DRV_STATE:%d.\n", QLA2XXX_DRIVER_NAME,2907			    drv_active, drv_state);2908			qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,2909			    QLA8XXX_DEV_READY);2910			ql_log(ql_log_info, vha, 0xb025,2911			    "HW State: DEV_READY.\n");2912			qla82xx_idc_unlock(ha);2913			qla2x00_perform_loop_resync(vha);2914			qla82xx_idc_lock(ha);2915 2916			qla82xx_clear_qsnt_ready(vha);2917			return;2918		}2919 2920		qla82xx_idc_unlock(ha);2921		msleep(1000);2922		qla82xx_idc_lock(ha);2923 2924		drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);2925		drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);2926		drv_active = drv_active << 0x01;2927	}2928	dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);2929	/* everyone acked so set the state to DEV_QUIESCENCE */2930	if (dev_state == QLA8XXX_DEV_NEED_QUIESCENT) {2931		ql_log(ql_log_info, vha, 0xb026,2932		    "HW State: DEV_QUIESCENT.\n");2933		qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA8XXX_DEV_QUIESCENT);2934	}2935}2936 2937/*2938* qla82xx_wait_for_state_change2939*    Wait for device state to change from given current state2940*2941* Note:2942*     IDC lock must not be held upon entry2943*2944* Return:2945*    Changed device state.2946*/2947uint32_t2948qla82xx_wait_for_state_change(scsi_qla_host_t *vha, uint32_t curr_state)2949{2950	struct qla_hw_data *ha = vha->hw;2951	uint32_t dev_state;2952 2953	do {2954		msleep(1000);2955		qla82xx_idc_lock(ha);2956		dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);2957		qla82xx_idc_unlock(ha);2958	} while (dev_state == curr_state);2959 2960	return dev_state;2961}2962 2963void2964qla8xxx_dev_failed_handler(scsi_qla_host_t *vha)2965{2966	struct qla_hw_data *ha = vha->hw;2967 2968	/* Disable the board */2969	ql_log(ql_log_fatal, vha, 0x00b8,2970	    "Disabling the board.\n");2971 2972	if (IS_QLA82XX(ha)) {2973		qla82xx_clear_drv_active(ha);2974		qla82xx_idc_unlock(ha);2975	} else if (IS_QLA8044(ha)) {2976		qla8044_clear_drv_active(ha);2977		qla8044_idc_unlock(ha);2978	}2979 2980	/* Set DEV_FAILED flag to disable timer */2981	vha->device_flags |= DFLG_DEV_FAILED;2982	qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16);2983	qla2x00_mark_all_devices_lost(vha);2984	vha->flags.online = 0;2985	vha->flags.init_done = 0;2986}2987 2988/*2989 * qla82xx_need_reset_handler2990 *    Code to start reset sequence2991 *2992 * Note:2993 *      IDC lock must be held upon entry2994 *2995 * Return:2996 *    Success : 02997 *    Failed  : 12998 */2999static void3000qla82xx_need_reset_handler(scsi_qla_host_t *vha)3001{3002	uint32_t dev_state, drv_state, drv_active;3003	uint32_t active_mask = 0;3004	unsigned long reset_timeout;3005	struct qla_hw_data *ha = vha->hw;3006	struct req_que *req = ha->req_q_map[0];3007 3008	if (vha->flags.online) {3009		qla82xx_idc_unlock(ha);3010		qla2x00_abort_isp_cleanup(vha);3011		ha->isp_ops->get_flash_version(vha, req->ring);3012		ha->isp_ops->nvram_config(vha);3013		qla82xx_idc_lock(ha);3014	}3015 3016	drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);3017	if (!ha->flags.nic_core_reset_owner) {3018		ql_dbg(ql_dbg_p3p, vha, 0xb028,3019		    "reset_acknowledged by 0x%x\n", ha->portnum);3020		qla82xx_set_rst_ready(ha);3021	} else {3022		active_mask = ~(QLA82XX_DRV_ACTIVE << (ha->portnum * 4));3023		drv_active &= active_mask;3024		ql_dbg(ql_dbg_p3p, vha, 0xb029,3025		    "active_mask: 0x%08x\n", active_mask);3026	}3027 3028	/* wait for 10 seconds for reset ack from all functions */3029	reset_timeout = jiffies + (ha->fcoe_reset_timeout * HZ);3030 3031	drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);3032	drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);3033	dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);3034 3035	ql_dbg(ql_dbg_p3p, vha, 0xb02a,3036	    "drv_state: 0x%08x, drv_active: 0x%08x, "3037	    "dev_state: 0x%08x, active_mask: 0x%08x\n",3038	    drv_state, drv_active, dev_state, active_mask);3039 3040	while (drv_state != drv_active &&3041	    dev_state != QLA8XXX_DEV_INITIALIZING) {3042		if (time_after_eq(jiffies, reset_timeout)) {3043			ql_log(ql_log_warn, vha, 0x00b5,3044			    "Reset timeout.\n");3045			break;3046		}3047		qla82xx_idc_unlock(ha);3048		msleep(1000);3049		qla82xx_idc_lock(ha);3050		drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);3051		drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);3052		if (ha->flags.nic_core_reset_owner)3053			drv_active &= active_mask;3054		dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);3055	}3056 3057	ql_dbg(ql_dbg_p3p, vha, 0xb02b,3058	    "drv_state: 0x%08x, drv_active: 0x%08x, "3059	    "dev_state: 0x%08x, active_mask: 0x%08x\n",3060	    drv_state, drv_active, dev_state, active_mask);3061 3062	ql_log(ql_log_info, vha, 0x00b6,3063	    "Device state is 0x%x = %s.\n",3064	    dev_state, qdev_state(dev_state));3065 3066	/* Force to DEV_COLD unless someone else is starting a reset */3067	if (dev_state != QLA8XXX_DEV_INITIALIZING &&3068	    dev_state != QLA8XXX_DEV_COLD) {3069		ql_log(ql_log_info, vha, 0x00b7,3070		    "HW State: COLD/RE-INIT.\n");3071		qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA8XXX_DEV_COLD);3072		qla82xx_set_rst_ready(ha);3073		if (ql2xmdenable) {3074			if (qla82xx_md_collect(vha))3075				ql_log(ql_log_warn, vha, 0xb02c,3076				    "Minidump not collected.\n");3077		} else3078			ql_log(ql_log_warn, vha, 0xb04f,3079			    "Minidump disabled.\n");3080	}3081}3082 3083int3084qla82xx_check_md_needed(scsi_qla_host_t *vha)3085{3086	struct qla_hw_data *ha = vha->hw;3087	uint16_t fw_major_version, fw_minor_version, fw_subminor_version;3088	int rval = QLA_SUCCESS;3089 3090	fw_major_version = ha->fw_major_version;3091	fw_minor_version = ha->fw_minor_version;3092	fw_subminor_version = ha->fw_subminor_version;3093 3094	rval = qla2x00_get_fw_version(vha);3095	if (rval != QLA_SUCCESS)3096		return rval;3097 3098	if (ql2xmdenable) {3099		if (!ha->fw_dumped) {3100			if ((fw_major_version != ha->fw_major_version ||3101			    fw_minor_version != ha->fw_minor_version ||3102			    fw_subminor_version != ha->fw_subminor_version) ||3103			    (ha->prev_minidump_failed)) {3104				ql_dbg(ql_dbg_p3p, vha, 0xb02d,3105				    "Firmware version differs Previous version: %d:%d:%d - New version: %d:%d:%d, prev_minidump_failed: %d.\n",3106				    fw_major_version, fw_minor_version,3107				    fw_subminor_version,3108				    ha->fw_major_version,3109				    ha->fw_minor_version,3110				    ha->fw_subminor_version,3111				    ha->prev_minidump_failed);3112				/* Release MiniDump resources */3113				qla82xx_md_free(vha);3114				/* ALlocate MiniDump resources */3115				qla82xx_md_prep(vha);3116			}3117		} else3118			ql_log(ql_log_info, vha, 0xb02e,3119			    "Firmware dump available to retrieve\n");3120	}3121	return rval;3122}3123 3124 3125static int3126qla82xx_check_fw_alive(scsi_qla_host_t *vha)3127{3128	uint32_t fw_heartbeat_counter;3129	int status = 0;3130 3131	fw_heartbeat_counter = qla82xx_rd_32(vha->hw,3132		QLA82XX_PEG_ALIVE_COUNTER);3133	/* all 0xff, assume AER/EEH in progress, ignore */3134	if (fw_heartbeat_counter == 0xffffffff) {3135		ql_dbg(ql_dbg_timer, vha, 0x6003,3136		    "FW heartbeat counter is 0xffffffff, "3137		    "returning status=%d.\n", status);3138		return status;3139	}3140	if (vha->fw_heartbeat_counter == fw_heartbeat_counter) {3141		vha->seconds_since_last_heartbeat++;3142		/* FW not alive after 2 seconds */3143		if (vha->seconds_since_last_heartbeat == 2) {3144			vha->seconds_since_last_heartbeat = 0;3145			status = 1;3146		}3147	} else3148		vha->seconds_since_last_heartbeat = 0;3149	vha->fw_heartbeat_counter = fw_heartbeat_counter;3150	if (status)3151		ql_dbg(ql_dbg_timer, vha, 0x6004,3152		    "Returning status=%d.\n", status);3153	return status;3154}3155 3156/*3157 * qla82xx_device_state_handler3158 *	Main state handler3159 *3160 * Note:3161 *      IDC lock must be held upon entry3162 *3163 * Return:3164 *    Success : 03165 *    Failed  : 13166 */3167int3168qla82xx_device_state_handler(scsi_qla_host_t *vha)3169{3170	uint32_t dev_state;3171	uint32_t old_dev_state;3172	int rval = QLA_SUCCESS;3173	unsigned long dev_init_timeout;3174	struct qla_hw_data *ha = vha->hw;3175	int loopcount = 0;3176 3177	qla82xx_idc_lock(ha);3178	if (!vha->flags.init_done) {3179		qla82xx_set_drv_active(vha);3180		qla82xx_set_idc_version(vha);3181	}3182 3183	dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);3184	old_dev_state = dev_state;3185	ql_log(ql_log_info, vha, 0x009b,3186	    "Device state is 0x%x = %s.\n",3187	    dev_state, qdev_state(dev_state));3188 3189	/* wait for 30 seconds for device to go ready */3190	dev_init_timeout = jiffies + (ha->fcoe_dev_init_timeout * HZ);3191 3192	while (1) {3193 3194		if (time_after_eq(jiffies, dev_init_timeout)) {3195			ql_log(ql_log_fatal, vha, 0x009c,3196			    "Device init failed.\n");3197			rval = QLA_FUNCTION_FAILED;3198			break;3199		}3200		dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);3201		if (old_dev_state != dev_state) {3202			loopcount = 0;3203			old_dev_state = dev_state;3204		}3205		if (loopcount < 5) {3206			ql_log(ql_log_info, vha, 0x009d,3207			    "Device state is 0x%x = %s.\n",3208			    dev_state, qdev_state(dev_state));3209		}3210 3211		switch (dev_state) {3212		case QLA8XXX_DEV_READY:3213			ha->flags.nic_core_reset_owner = 0;3214			goto rel_lock;3215		case QLA8XXX_DEV_COLD:3216			rval = qla82xx_device_bootstrap(vha);3217			break;3218		case QLA8XXX_DEV_INITIALIZING:3219			qla82xx_idc_unlock(ha);3220			msleep(1000);3221			qla82xx_idc_lock(ha);3222			break;3223		case QLA8XXX_DEV_NEED_RESET:3224			if (!ql2xdontresethba)3225				qla82xx_need_reset_handler(vha);3226			else {3227				qla82xx_idc_unlock(ha);3228				msleep(1000);3229				qla82xx_idc_lock(ha);3230			}3231			dev_init_timeout = jiffies +3232			    (ha->fcoe_dev_init_timeout * HZ);3233			break;3234		case QLA8XXX_DEV_NEED_QUIESCENT:3235			qla82xx_need_qsnt_handler(vha);3236			/* Reset timeout value after quiescence handler */3237			dev_init_timeout = jiffies + (ha->fcoe_dev_init_timeout3238							 * HZ);3239			break;3240		case QLA8XXX_DEV_QUIESCENT:3241			/* Owner will exit and other will wait for the state3242			 * to get changed3243			 */3244			if (ha->flags.quiesce_owner)3245				goto rel_lock;3246 3247			qla82xx_idc_unlock(ha);3248			msleep(1000);3249			qla82xx_idc_lock(ha);3250 3251			/* Reset timeout value after quiescence handler */3252			dev_init_timeout = jiffies + (ha->fcoe_dev_init_timeout3253							 * HZ);3254			break;3255		case QLA8XXX_DEV_FAILED:3256			qla8xxx_dev_failed_handler(vha);3257			rval = QLA_FUNCTION_FAILED;3258			goto exit;3259		default:3260			qla82xx_idc_unlock(ha);3261			msleep(1000);3262			qla82xx_idc_lock(ha);3263		}3264		loopcount++;3265	}3266rel_lock:3267	qla82xx_idc_unlock(ha);3268exit:3269	return rval;3270}3271 3272static int qla82xx_check_temp(scsi_qla_host_t *vha)3273{3274	uint32_t temp, temp_state, temp_val;3275	struct qla_hw_data *ha = vha->hw;3276 3277	temp = qla82xx_rd_32(ha, CRB_TEMP_STATE);3278	temp_state = qla82xx_get_temp_state(temp);3279	temp_val = qla82xx_get_temp_val(temp);3280 3281	if (temp_state == QLA82XX_TEMP_PANIC) {3282		ql_log(ql_log_warn, vha, 0x600e,3283		    "Device temperature %d degrees C exceeds "3284		    " maximum allowed. Hardware has been shut down.\n",3285		    temp_val);3286		return 1;3287	} else if (temp_state == QLA82XX_TEMP_WARN) {3288		ql_log(ql_log_warn, vha, 0x600f,3289		    "Device temperature %d degrees C exceeds "3290		    "operating range. Immediate action needed.\n",3291		    temp_val);3292	}3293	return 0;3294}3295 3296int qla82xx_read_temperature(scsi_qla_host_t *vha)3297{3298	uint32_t temp;3299 3300	temp = qla82xx_rd_32(vha->hw, CRB_TEMP_STATE);3301	return qla82xx_get_temp_val(temp);3302}3303 3304void qla82xx_clear_pending_mbx(scsi_qla_host_t *vha)3305{3306	struct qla_hw_data *ha = vha->hw;3307 3308	if (ha->flags.mbox_busy) {3309		ha->flags.mbox_int = 1;3310		ha->flags.mbox_busy = 0;3311		ql_log(ql_log_warn, vha, 0x6010,3312		    "Doing premature completion of mbx command.\n");3313		if (test_and_clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags))3314			complete(&ha->mbx_intr_comp);3315	}3316}3317 3318void qla82xx_watchdog(scsi_qla_host_t *vha)3319{3320	uint32_t dev_state, halt_status;3321	struct qla_hw_data *ha = vha->hw;3322 3323	/* don't poll if reset is going on */3324	if (!ha->flags.nic_core_reset_hdlr_active) {3325		dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);3326		if (qla82xx_check_temp(vha)) {3327			set_bit(ISP_UNRECOVERABLE, &vha->dpc_flags);3328			ha->flags.isp82xx_fw_hung = 1;3329			qla82xx_clear_pending_mbx(vha);3330		} else if (dev_state == QLA8XXX_DEV_NEED_RESET &&3331		    !test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags)) {3332			ql_log(ql_log_warn, vha, 0x6001,3333			    "Adapter reset needed.\n");3334			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);3335		} else if (dev_state == QLA8XXX_DEV_NEED_QUIESCENT &&3336			!test_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags)) {3337			ql_log(ql_log_warn, vha, 0x6002,3338			    "Quiescent needed.\n");3339			set_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags);3340		} else if (dev_state == QLA8XXX_DEV_FAILED &&3341			!test_bit(ISP_UNRECOVERABLE, &vha->dpc_flags) &&3342			vha->flags.online == 1) {3343			ql_log(ql_log_warn, vha, 0xb055,3344			    "Adapter state is failed. Offlining.\n");3345			set_bit(ISP_UNRECOVERABLE, &vha->dpc_flags);3346			ha->flags.isp82xx_fw_hung = 1;3347			qla82xx_clear_pending_mbx(vha);3348		} else {3349			if (qla82xx_check_fw_alive(vha)) {3350				ql_dbg(ql_dbg_timer, vha, 0x6011,3351				    "disabling pause transmit on port 0 & 1.\n");3352				qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98,3353				    CRB_NIU_XG_PAUSE_CTL_P0|CRB_NIU_XG_PAUSE_CTL_P1);3354				halt_status = qla82xx_rd_32(ha,3355				    QLA82XX_PEG_HALT_STATUS1);3356				ql_log(ql_log_info, vha, 0x6005,3357				    "dumping hw/fw registers:.\n "3358				    " PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2: 0x%x,.\n "3359				    " PEG_NET_0_PC: 0x%x, PEG_NET_1_PC: 0x%x,.\n "3360				    " PEG_NET_2_PC: 0x%x, PEG_NET_3_PC: 0x%x,.\n "3361				    " PEG_NET_4_PC: 0x%x.\n", halt_status,3362				    qla82xx_rd_32(ha, QLA82XX_PEG_HALT_STATUS2),3363				    qla82xx_rd_32(ha,3364					    QLA82XX_CRB_PEG_NET_0 + 0x3c),3365				    qla82xx_rd_32(ha,3366					    QLA82XX_CRB_PEG_NET_1 + 0x3c),3367				    qla82xx_rd_32(ha,3368					    QLA82XX_CRB_PEG_NET_2 + 0x3c),3369				    qla82xx_rd_32(ha,3370					    QLA82XX_CRB_PEG_NET_3 + 0x3c),3371				    qla82xx_rd_32(ha,3372					    QLA82XX_CRB_PEG_NET_4 + 0x3c));3373				if (((halt_status & 0x1fffff00) >> 8) == 0x67)3374					ql_log(ql_log_warn, vha, 0xb052,3375					    "Firmware aborted with "3376					    "error code 0x00006700. Device is "3377					    "being reset.\n");3378				if (halt_status & HALT_STATUS_UNRECOVERABLE) {3379					set_bit(ISP_UNRECOVERABLE,3380					    &vha->dpc_flags);3381				} else {3382					ql_log(ql_log_info, vha, 0x6006,3383					    "Detect abort  needed.\n");3384					set_bit(ISP_ABORT_NEEDED,3385					    &vha->dpc_flags);3386				}3387				ha->flags.isp82xx_fw_hung = 1;3388				ql_log(ql_log_warn, vha, 0x6007, "Firmware hung.\n");3389				qla82xx_clear_pending_mbx(vha);3390			}3391		}3392	}3393}3394 3395int qla82xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)3396{3397	int rval = -1;3398	struct qla_hw_data *ha = vha->hw;3399 3400	if (IS_QLA82XX(ha))3401		rval = qla82xx_device_state_handler(vha);3402	else if (IS_QLA8044(ha)) {3403		qla8044_idc_lock(ha);3404		/* Decide the reset ownership */3405		qla83xx_reset_ownership(vha);3406		qla8044_idc_unlock(ha);3407		rval = qla8044_device_state_handler(vha);3408	}3409	return rval;3410}3411 3412void3413qla82xx_set_reset_owner(scsi_qla_host_t *vha)3414{3415	struct qla_hw_data *ha = vha->hw;3416	uint32_t dev_state = 0;3417 3418	if (IS_QLA82XX(ha))3419		dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);3420	else if (IS_QLA8044(ha))3421		dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX);3422 3423	if (dev_state == QLA8XXX_DEV_READY) {3424		ql_log(ql_log_info, vha, 0xb02f,3425		    "HW State: NEED RESET\n");3426		if (IS_QLA82XX(ha)) {3427			qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,3428			    QLA8XXX_DEV_NEED_RESET);3429			ha->flags.nic_core_reset_owner = 1;3430			ql_dbg(ql_dbg_p3p, vha, 0xb030,3431			    "reset_owner is 0x%x\n", ha->portnum);3432		} else if (IS_QLA8044(ha))3433			qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX,3434			    QLA8XXX_DEV_NEED_RESET);3435	} else3436		ql_log(ql_log_info, vha, 0xb031,3437		    "Device state is 0x%x = %s.\n",3438		    dev_state, qdev_state(dev_state));3439}3440 3441/*3442 *  qla82xx_abort_isp3443 *      Resets ISP and aborts all outstanding commands.3444 *3445 * Input:3446 *      ha           = adapter block pointer.3447 *3448 * Returns:3449 *      0 = success3450 */3451int3452qla82xx_abort_isp(scsi_qla_host_t *vha)3453{3454	int rval = -1;3455	struct qla_hw_data *ha = vha->hw;3456 3457	if (vha->device_flags & DFLG_DEV_FAILED) {3458		ql_log(ql_log_warn, vha, 0x8024,3459		    "Device in failed state, exiting.\n");3460		return QLA_SUCCESS;3461	}3462	ha->flags.nic_core_reset_hdlr_active = 1;3463 3464	qla82xx_idc_lock(ha);3465	qla82xx_set_reset_owner(vha);3466	qla82xx_idc_unlock(ha);3467 3468	if (IS_QLA82XX(ha))3469		rval = qla82xx_device_state_handler(vha);3470	else if (IS_QLA8044(ha)) {3471		qla8044_idc_lock(ha);3472		/* Decide the reset ownership */3473		qla83xx_reset_ownership(vha);3474		qla8044_idc_unlock(ha);3475		rval = qla8044_device_state_handler(vha);3476	}3477 3478	qla82xx_idc_lock(ha);3479	qla82xx_clear_rst_ready(ha);3480	qla82xx_idc_unlock(ha);3481 3482	if (rval == QLA_SUCCESS) {3483		ha->flags.isp82xx_fw_hung = 0;3484		ha->flags.nic_core_reset_hdlr_active = 0;3485		qla82xx_restart_isp(vha);3486	}3487 3488	if (rval) {3489		vha->flags.online = 1;3490		if (test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {3491			if (ha->isp_abort_cnt == 0) {3492				ql_log(ql_log_warn, vha, 0x8027,3493				    "ISP error recover failed - board "3494				    "disabled.\n");3495				/*3496				 * The next call disables the board3497				 * completely.3498				 */3499				ha->isp_ops->reset_adapter(vha);3500				vha->flags.online = 0;3501				clear_bit(ISP_ABORT_RETRY,3502				    &vha->dpc_flags);3503				rval = QLA_SUCCESS;3504			} else { /* schedule another ISP abort */3505				ha->isp_abort_cnt--;3506				ql_log(ql_log_warn, vha, 0x8036,3507				    "ISP abort - retry remaining %d.\n",3508				    ha->isp_abort_cnt);3509				rval = QLA_FUNCTION_FAILED;3510			}3511		} else {3512			ha->isp_abort_cnt = MAX_RETRIES_OF_ISP_ABORT;3513			ql_dbg(ql_dbg_taskm, vha, 0x8029,3514			    "ISP error recovery - retrying (%d) more times.\n",3515			    ha->isp_abort_cnt);3516			set_bit(ISP_ABORT_RETRY, &vha->dpc_flags);3517			rval = QLA_FUNCTION_FAILED;3518		}3519	}3520	return rval;3521}3522 3523/*3524 *  qla82xx_fcoe_ctx_reset3525 *      Perform a quick reset and aborts all outstanding commands.3526 *      This will only perform an FCoE context reset and avoids a full blown3527 *      chip reset.3528 *3529 * Input:3530 *      ha = adapter block pointer.3531 *      is_reset_path = flag for identifying the reset path.3532 *3533 * Returns:3534 *      0 = success3535 */3536int qla82xx_fcoe_ctx_reset(scsi_qla_host_t *vha)3537{3538	int rval = QLA_FUNCTION_FAILED;3539 3540	if (vha->flags.online) {3541		/* Abort all outstanding commands, so as to be requeued later */3542		qla2x00_abort_isp_cleanup(vha);3543	}3544 3545	/* Stop currently executing firmware.3546	 * This will destroy existing FCoE context at the F/W end.3547	 */3548	qla2x00_try_to_stop_firmware(vha);3549 3550	/* Restart. Creates a new FCoE context on INIT_FIRMWARE. */3551	rval = qla82xx_restart_isp(vha);3552 3553	return rval;3554}3555 3556/*3557 * qla2x00_wait_for_fcoe_ctx_reset3558 *    Wait till the FCoE context is reset.3559 *3560 * Note:3561 *    Does context switching here.3562 *    Release SPIN_LOCK (if any) before calling this routine.3563 *3564 * Return:3565 *    Success (fcoe_ctx reset is done) : 03566 *    Failed  (fcoe_ctx reset not completed within max loop timout ) : 13567 */3568int qla2x00_wait_for_fcoe_ctx_reset(scsi_qla_host_t *vha)3569{3570	int status = QLA_FUNCTION_FAILED;3571	unsigned long wait_reset;3572 3573	wait_reset = jiffies + (MAX_LOOP_TIMEOUT * HZ);3574	while ((test_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags) ||3575	    test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))3576	    && time_before(jiffies, wait_reset)) {3577 3578		set_current_state(TASK_UNINTERRUPTIBLE);3579		schedule_timeout(HZ);3580 3581		if (!test_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags) &&3582		    !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)) {3583			status = QLA_SUCCESS;3584			break;3585		}3586	}3587	ql_dbg(ql_dbg_p3p, vha, 0xb027,3588	       "%s: status=%d.\n", __func__, status);3589 3590	return status;3591}3592 3593void3594qla82xx_chip_reset_cleanup(scsi_qla_host_t *vha)3595{3596	int i, fw_state = 0;3597	unsigned long flags;3598	struct qla_hw_data *ha = vha->hw;3599 3600	/* Check if 82XX firmware is alive or not3601	 * We may have arrived here from NEED_RESET3602	 * detection only3603	 */3604	if (!ha->flags.isp82xx_fw_hung) {3605		for (i = 0; i < 2; i++) {3606			msleep(1000);3607			if (IS_QLA82XX(ha))3608				fw_state = qla82xx_check_fw_alive(vha);3609			else if (IS_QLA8044(ha))3610				fw_state = qla8044_check_fw_alive(vha);3611			if (fw_state) {3612				ha->flags.isp82xx_fw_hung = 1;3613				qla82xx_clear_pending_mbx(vha);3614				break;3615			}3616		}3617	}3618	ql_dbg(ql_dbg_init, vha, 0x00b0,3619	    "Entered %s fw_hung=%d.\n",3620	    __func__, ha->flags.isp82xx_fw_hung);3621 3622	/* Abort all commands gracefully if fw NOT hung */3623	if (!ha->flags.isp82xx_fw_hung) {3624		int cnt, que;3625		srb_t *sp;3626		struct req_que *req;3627 3628		spin_lock_irqsave(&ha->hardware_lock, flags);3629		for (que = 0; que < ha->max_req_queues; que++) {3630			req = ha->req_q_map[que];3631			if (!req)3632				continue;3633			for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {3634				sp = req->outstanding_cmds[cnt];3635				if (sp) {3636					if ((!sp->u.scmd.crc_ctx ||3637					    (sp->flags &3638						SRB_FCP_CMND_DMA_VALID)) &&3639						!ha->flags.isp82xx_fw_hung) {3640						spin_unlock_irqrestore(3641						    &ha->hardware_lock, flags);3642						if (ha->isp_ops->abort_command(sp)) {3643							ql_log(ql_log_info, vha,3644							    0x00b1,3645							    "mbx abort failed.\n");3646						} else {3647							ql_log(ql_log_info, vha,3648							    0x00b2,3649							    "mbx abort success.\n");3650						}3651						spin_lock_irqsave(&ha->hardware_lock, flags);3652					}3653				}3654			}3655		}3656		spin_unlock_irqrestore(&ha->hardware_lock, flags);3657 3658		/* Wait for pending cmds (physical and virtual) to complete */3659		if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0,3660		    WAIT_HOST) == QLA_SUCCESS) {3661			ql_dbg(ql_dbg_init, vha, 0x00b3,3662			    "Done wait for "3663			    "pending commands.\n");3664		} else {3665			WARN_ON_ONCE(true);3666		}3667	}3668}3669 3670/* Minidump related functions */3671static int3672qla82xx_minidump_process_control(scsi_qla_host_t *vha,3673	qla82xx_md_entry_hdr_t *entry_hdr, __le32 **d_ptr)3674{3675	struct qla_hw_data *ha = vha->hw;3676	struct qla82xx_md_entry_crb *crb_entry;3677	uint32_t read_value, opcode, poll_time;3678	uint32_t addr, index, crb_addr;3679	unsigned long wtime;3680	struct qla82xx_md_template_hdr *tmplt_hdr;3681	uint32_t rval = QLA_SUCCESS;3682	int i;3683 3684	tmplt_hdr = (struct qla82xx_md_template_hdr *)ha->md_tmplt_hdr;3685	crb_entry = (struct qla82xx_md_entry_crb *)entry_hdr;3686	crb_addr = crb_entry->addr;3687 3688	for (i = 0; i < crb_entry->op_count; i++) {3689		opcode = crb_entry->crb_ctrl.opcode;3690		if (opcode & QLA82XX_DBG_OPCODE_WR) {3691			qla82xx_md_rw_32(ha, crb_addr,3692			    crb_entry->value_1, 1);3693			opcode &= ~QLA82XX_DBG_OPCODE_WR;3694		}3695 3696		if (opcode & QLA82XX_DBG_OPCODE_RW) {3697			read_value = qla82xx_md_rw_32(ha, crb_addr, 0, 0);3698			qla82xx_md_rw_32(ha, crb_addr, read_value, 1);3699			opcode &= ~QLA82XX_DBG_OPCODE_RW;3700		}3701 3702		if (opcode & QLA82XX_DBG_OPCODE_AND) {3703			read_value = qla82xx_md_rw_32(ha, crb_addr, 0, 0);3704			read_value &= crb_entry->value_2;3705			opcode &= ~QLA82XX_DBG_OPCODE_AND;3706			if (opcode & QLA82XX_DBG_OPCODE_OR) {3707				read_value |= crb_entry->value_3;3708				opcode &= ~QLA82XX_DBG_OPCODE_OR;3709			}3710			qla82xx_md_rw_32(ha, crb_addr, read_value, 1);3711		}3712 3713		if (opcode & QLA82XX_DBG_OPCODE_OR) {3714			read_value = qla82xx_md_rw_32(ha, crb_addr, 0, 0);3715			read_value |= crb_entry->value_3;3716			qla82xx_md_rw_32(ha, crb_addr, read_value, 1);3717			opcode &= ~QLA82XX_DBG_OPCODE_OR;3718		}3719 3720		if (opcode & QLA82XX_DBG_OPCODE_POLL) {3721			poll_time = crb_entry->crb_strd.poll_timeout;3722			wtime = jiffies + poll_time;3723			read_value = qla82xx_md_rw_32(ha, crb_addr, 0, 0);3724 3725			do {3726				if ((read_value & crb_entry->value_2)3727				    == crb_entry->value_1)3728					break;3729				else if (time_after_eq(jiffies, wtime)) {3730					/* capturing dump failed */3731					rval = QLA_FUNCTION_FAILED;3732					break;3733				} else3734					read_value = qla82xx_md_rw_32(ha,3735					    crb_addr, 0, 0);3736			} while (1);3737			opcode &= ~QLA82XX_DBG_OPCODE_POLL;3738		}3739 3740		if (opcode & QLA82XX_DBG_OPCODE_RDSTATE) {3741			if (crb_entry->crb_strd.state_index_a) {3742				index = crb_entry->crb_strd.state_index_a;3743				addr = tmplt_hdr->saved_state_array[index];3744			} else3745				addr = crb_addr;3746 3747			read_value = qla82xx_md_rw_32(ha, addr, 0, 0);3748			index = crb_entry->crb_ctrl.state_index_v;3749			tmplt_hdr->saved_state_array[index] = read_value;3750			opcode &= ~QLA82XX_DBG_OPCODE_RDSTATE;3751		}3752 3753		if (opcode & QLA82XX_DBG_OPCODE_WRSTATE) {3754			if (crb_entry->crb_strd.state_index_a) {3755				index = crb_entry->crb_strd.state_index_a;3756				addr = tmplt_hdr->saved_state_array[index];3757			} else3758				addr = crb_addr;3759 3760			if (crb_entry->crb_ctrl.state_index_v) {3761				index = crb_entry->crb_ctrl.state_index_v;3762				read_value =3763				    tmplt_hdr->saved_state_array[index];3764			} else3765				read_value = crb_entry->value_1;3766 3767			qla82xx_md_rw_32(ha, addr, read_value, 1);3768			opcode &= ~QLA82XX_DBG_OPCODE_WRSTATE;3769		}3770 3771		if (opcode & QLA82XX_DBG_OPCODE_MDSTATE) {3772			index = crb_entry->crb_ctrl.state_index_v;3773			read_value = tmplt_hdr->saved_state_array[index];3774			read_value <<= crb_entry->crb_ctrl.shl;3775			read_value >>= crb_entry->crb_ctrl.shr;3776			if (crb_entry->value_2)3777				read_value &= crb_entry->value_2;3778			read_value |= crb_entry->value_3;3779			read_value += crb_entry->value_1;3780			tmplt_hdr->saved_state_array[index] = read_value;3781			opcode &= ~QLA82XX_DBG_OPCODE_MDSTATE;3782		}3783		crb_addr += crb_entry->crb_strd.addr_stride;3784	}3785	return rval;3786}3787 3788static void3789qla82xx_minidump_process_rdocm(scsi_qla_host_t *vha,3790	qla82xx_md_entry_hdr_t *entry_hdr, __le32 **d_ptr)3791{3792	struct qla_hw_data *ha = vha->hw;3793	uint32_t r_addr, r_stride, loop_cnt, i, r_value;3794	struct qla82xx_md_entry_rdocm *ocm_hdr;3795	__le32 *data_ptr = *d_ptr;3796 3797	ocm_hdr = (struct qla82xx_md_entry_rdocm *)entry_hdr;3798	r_addr = ocm_hdr->read_addr;3799	r_stride = ocm_hdr->read_addr_stride;3800	loop_cnt = ocm_hdr->op_count;3801 3802	for (i = 0; i < loop_cnt; i++) {3803		r_value = rd_reg_dword(r_addr + ha->nx_pcibase);3804		*data_ptr++ = cpu_to_le32(r_value);3805		r_addr += r_stride;3806	}3807	*d_ptr = data_ptr;3808}3809 3810static void3811qla82xx_minidump_process_rdmux(scsi_qla_host_t *vha,3812	qla82xx_md_entry_hdr_t *entry_hdr, __le32 **d_ptr)3813{3814	struct qla_hw_data *ha = vha->hw;3815	uint32_t r_addr, s_stride, s_addr, s_value, loop_cnt, i, r_value;3816	struct qla82xx_md_entry_mux *mux_hdr;3817	__le32 *data_ptr = *d_ptr;3818 3819	mux_hdr = (struct qla82xx_md_entry_mux *)entry_hdr;3820	r_addr = mux_hdr->read_addr;3821	s_addr = mux_hdr->select_addr;3822	s_stride = mux_hdr->select_value_stride;3823	s_value = mux_hdr->select_value;3824	loop_cnt = mux_hdr->op_count;3825 3826	for (i = 0; i < loop_cnt; i++) {3827		qla82xx_md_rw_32(ha, s_addr, s_value, 1);3828		r_value = qla82xx_md_rw_32(ha, r_addr, 0, 0);3829		*data_ptr++ = cpu_to_le32(s_value);3830		*data_ptr++ = cpu_to_le32(r_value);3831		s_value += s_stride;3832	}3833	*d_ptr = data_ptr;3834}3835 3836static void3837qla82xx_minidump_process_rdcrb(scsi_qla_host_t *vha,3838	qla82xx_md_entry_hdr_t *entry_hdr, __le32 **d_ptr)3839{3840	struct qla_hw_data *ha = vha->hw;3841	uint32_t r_addr, r_stride, loop_cnt, i, r_value;3842	struct qla82xx_md_entry_crb *crb_hdr;3843	__le32 *data_ptr = *d_ptr;3844 3845	crb_hdr = (struct qla82xx_md_entry_crb *)entry_hdr;3846	r_addr = crb_hdr->addr;3847	r_stride = crb_hdr->crb_strd.addr_stride;3848	loop_cnt = crb_hdr->op_count;3849 3850	for (i = 0; i < loop_cnt; i++) {3851		r_value = qla82xx_md_rw_32(ha, r_addr, 0, 0);3852		*data_ptr++ = cpu_to_le32(r_addr);3853		*data_ptr++ = cpu_to_le32(r_value);3854		r_addr += r_stride;3855	}3856	*d_ptr = data_ptr;3857}3858 3859static int3860qla82xx_minidump_process_l2tag(scsi_qla_host_t *vha,3861	qla82xx_md_entry_hdr_t *entry_hdr, __le32 **d_ptr)3862{3863	struct qla_hw_data *ha = vha->hw;3864	uint32_t addr, r_addr, c_addr, t_r_addr;3865	uint32_t i, k, loop_count, t_value, r_cnt, r_value;3866	unsigned long p_wait, w_time, p_mask;3867	uint32_t c_value_w, c_value_r;3868	struct qla82xx_md_entry_cache *cache_hdr;3869	int rval = QLA_FUNCTION_FAILED;3870	__le32 *data_ptr = *d_ptr;3871 3872	cache_hdr = (struct qla82xx_md_entry_cache *)entry_hdr;3873	loop_count = cache_hdr->op_count;3874	r_addr = cache_hdr->read_addr;3875	c_addr = cache_hdr->control_addr;3876	c_value_w = cache_hdr->cache_ctrl.write_value;3877 3878	t_r_addr = cache_hdr->tag_reg_addr;3879	t_value = cache_hdr->addr_ctrl.init_tag_value;3880	r_cnt = cache_hdr->read_ctrl.read_addr_cnt;3881	p_wait = cache_hdr->cache_ctrl.poll_wait;3882	p_mask = cache_hdr->cache_ctrl.poll_mask;3883 3884	for (i = 0; i < loop_count; i++) {3885		qla82xx_md_rw_32(ha, t_r_addr, t_value, 1);3886		if (c_value_w)3887			qla82xx_md_rw_32(ha, c_addr, c_value_w, 1);3888 3889		if (p_mask) {3890			w_time = jiffies + p_wait;3891			do {3892				c_value_r = qla82xx_md_rw_32(ha, c_addr, 0, 0);3893				if ((c_value_r & p_mask) == 0)3894					break;3895				else if (time_after_eq(jiffies, w_time)) {3896					/* capturing dump failed */3897					ql_dbg(ql_dbg_p3p, vha, 0xb032,3898					    "c_value_r: 0x%x, poll_mask: 0x%lx, "3899					    "w_time: 0x%lx\n",3900					    c_value_r, p_mask, w_time);3901					return rval;3902				}3903			} while (1);3904		}3905 3906		addr = r_addr;3907		for (k = 0; k < r_cnt; k++) {3908			r_value = qla82xx_md_rw_32(ha, addr, 0, 0);3909			*data_ptr++ = cpu_to_le32(r_value);3910			addr += cache_hdr->read_ctrl.read_addr_stride;3911		}3912		t_value += cache_hdr->addr_ctrl.tag_value_stride;3913	}3914	*d_ptr = data_ptr;3915	return QLA_SUCCESS;3916}3917 3918static void3919qla82xx_minidump_process_l1cache(scsi_qla_host_t *vha,3920	qla82xx_md_entry_hdr_t *entry_hdr, __le32 **d_ptr)3921{3922	struct qla_hw_data *ha = vha->hw;3923	uint32_t addr, r_addr, c_addr, t_r_addr;3924	uint32_t i, k, loop_count, t_value, r_cnt, r_value;3925	uint32_t c_value_w;3926	struct qla82xx_md_entry_cache *cache_hdr;3927	__le32 *data_ptr = *d_ptr;3928 3929	cache_hdr = (struct qla82xx_md_entry_cache *)entry_hdr;3930	loop_count = cache_hdr->op_count;3931	r_addr = cache_hdr->read_addr;3932	c_addr = cache_hdr->control_addr;3933	c_value_w = cache_hdr->cache_ctrl.write_value;3934 3935	t_r_addr = cache_hdr->tag_reg_addr;3936	t_value = cache_hdr->addr_ctrl.init_tag_value;3937	r_cnt = cache_hdr->read_ctrl.read_addr_cnt;3938 3939	for (i = 0; i < loop_count; i++) {3940		qla82xx_md_rw_32(ha, t_r_addr, t_value, 1);3941		qla82xx_md_rw_32(ha, c_addr, c_value_w, 1);3942		addr = r_addr;3943		for (k = 0; k < r_cnt; k++) {3944			r_value = qla82xx_md_rw_32(ha, addr, 0, 0);3945			*data_ptr++ = cpu_to_le32(r_value);3946			addr += cache_hdr->read_ctrl.read_addr_stride;3947		}3948		t_value += cache_hdr->addr_ctrl.tag_value_stride;3949	}3950	*d_ptr = data_ptr;3951}3952 3953static void3954qla82xx_minidump_process_queue(scsi_qla_host_t *vha,3955	qla82xx_md_entry_hdr_t *entry_hdr, __le32 **d_ptr)3956{3957	struct qla_hw_data *ha = vha->hw;3958	uint32_t s_addr, r_addr;3959	uint32_t r_stride, r_value, r_cnt, qid = 0;3960	uint32_t i, k, loop_cnt;3961	struct qla82xx_md_entry_queue *q_hdr;3962	__le32 *data_ptr = *d_ptr;3963 3964	q_hdr = (struct qla82xx_md_entry_queue *)entry_hdr;3965	s_addr = q_hdr->select_addr;3966	r_cnt = q_hdr->rd_strd.read_addr_cnt;3967	r_stride = q_hdr->rd_strd.read_addr_stride;3968	loop_cnt = q_hdr->op_count;3969 3970	for (i = 0; i < loop_cnt; i++) {3971		qla82xx_md_rw_32(ha, s_addr, qid, 1);3972		r_addr = q_hdr->read_addr;3973		for (k = 0; k < r_cnt; k++) {3974			r_value = qla82xx_md_rw_32(ha, r_addr, 0, 0);3975			*data_ptr++ = cpu_to_le32(r_value);3976			r_addr += r_stride;3977		}3978		qid += q_hdr->q_strd.queue_id_stride;3979	}3980	*d_ptr = data_ptr;3981}3982 3983static void3984qla82xx_minidump_process_rdrom(scsi_qla_host_t *vha,3985	qla82xx_md_entry_hdr_t *entry_hdr, __le32 **d_ptr)3986{3987	struct qla_hw_data *ha = vha->hw;3988	uint32_t r_addr, r_value;3989	uint32_t i, loop_cnt;3990	struct qla82xx_md_entry_rdrom *rom_hdr;3991	__le32 *data_ptr = *d_ptr;3992 3993	rom_hdr = (struct qla82xx_md_entry_rdrom *)entry_hdr;3994	r_addr = rom_hdr->read_addr;3995	loop_cnt = rom_hdr->read_data_size/sizeof(uint32_t);3996 3997	for (i = 0; i < loop_cnt; i++) {3998		qla82xx_md_rw_32(ha, MD_DIRECT_ROM_WINDOW,3999		    (r_addr & 0xFFFF0000), 1);4000		r_value = qla82xx_md_rw_32(ha,4001		    MD_DIRECT_ROM_READ_BASE +4002		    (r_addr & 0x0000FFFF), 0, 0);4003		*data_ptr++ = cpu_to_le32(r_value);4004		r_addr += sizeof(uint32_t);4005	}4006	*d_ptr = data_ptr;4007}4008 4009static int4010qla82xx_minidump_process_rdmem(scsi_qla_host_t *vha,4011	qla82xx_md_entry_hdr_t *entry_hdr, __le32 **d_ptr)4012{4013	struct qla_hw_data *ha = vha->hw;4014	uint32_t r_addr, r_value, r_data;4015	uint32_t i, j, loop_cnt;4016	struct qla82xx_md_entry_rdmem *m_hdr;4017	unsigned long flags;4018	int rval = QLA_FUNCTION_FAILED;4019	__le32 *data_ptr = *d_ptr;4020 4021	m_hdr = (struct qla82xx_md_entry_rdmem *)entry_hdr;4022	r_addr = m_hdr->read_addr;4023	loop_cnt = m_hdr->read_data_size/16;4024 4025	if (r_addr & 0xf) {4026		ql_log(ql_log_warn, vha, 0xb033,4027		    "Read addr 0x%x not 16 bytes aligned\n", r_addr);4028		return rval;4029	}4030 4031	if (m_hdr->read_data_size % 16) {4032		ql_log(ql_log_warn, vha, 0xb034,4033		    "Read data[0x%x] not multiple of 16 bytes\n",4034		    m_hdr->read_data_size);4035		return rval;4036	}4037 4038	ql_dbg(ql_dbg_p3p, vha, 0xb035,4039	    "[%s]: rdmem_addr: 0x%x, read_data_size: 0x%x, loop_cnt: 0x%x\n",4040	    __func__, r_addr, m_hdr->read_data_size, loop_cnt);4041 4042	write_lock_irqsave(&ha->hw_lock, flags);4043	for (i = 0; i < loop_cnt; i++) {4044		qla82xx_md_rw_32(ha, MD_MIU_TEST_AGT_ADDR_LO, r_addr, 1);4045		r_value = 0;4046		qla82xx_md_rw_32(ha, MD_MIU_TEST_AGT_ADDR_HI, r_value, 1);4047		r_value = MIU_TA_CTL_ENABLE;4048		qla82xx_md_rw_32(ha, MD_MIU_TEST_AGT_CTRL, r_value, 1);4049		r_value = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;4050		qla82xx_md_rw_32(ha, MD_MIU_TEST_AGT_CTRL, r_value, 1);4051 4052		for (j = 0; j < MAX_CTL_CHECK; j++) {4053			r_value = qla82xx_md_rw_32(ha,4054			    MD_MIU_TEST_AGT_CTRL, 0, 0);4055			if ((r_value & MIU_TA_CTL_BUSY) == 0)4056				break;4057		}4058 4059		if (j >= MAX_CTL_CHECK) {4060			printk_ratelimited(KERN_ERR4061			    "failed to read through agent\n");4062			write_unlock_irqrestore(&ha->hw_lock, flags);4063			return rval;4064		}4065 4066		for (j = 0; j < 4; j++) {4067			r_data = qla82xx_md_rw_32(ha,4068			    MD_MIU_TEST_AGT_RDDATA[j], 0, 0);4069			*data_ptr++ = cpu_to_le32(r_data);4070		}4071		r_addr += 16;4072	}4073	write_unlock_irqrestore(&ha->hw_lock, flags);4074	*d_ptr = data_ptr;4075	return QLA_SUCCESS;4076}4077 4078int4079qla82xx_validate_template_chksum(scsi_qla_host_t *vha)4080{4081	struct qla_hw_data *ha = vha->hw;4082	uint64_t chksum = 0;4083	uint32_t *d_ptr = (uint32_t *)ha->md_tmplt_hdr;4084	int count = ha->md_template_size/sizeof(uint32_t);4085 4086	while (count-- > 0)4087		chksum += *d_ptr++;4088	while (chksum >> 32)4089		chksum = (chksum & 0xFFFFFFFF) + (chksum >> 32);4090	return ~chksum;4091}4092 4093static void4094qla82xx_mark_entry_skipped(scsi_qla_host_t *vha,4095	qla82xx_md_entry_hdr_t *entry_hdr, int index)4096{4097	entry_hdr->d_ctrl.driver_flags |= QLA82XX_DBG_SKIPPED_FLAG;4098	ql_dbg(ql_dbg_p3p, vha, 0xb036,4099	    "Skipping entry[%d]: "4100	    "ETYPE[0x%x]-ELEVEL[0x%x]\n",4101	    index, entry_hdr->entry_type,4102	    entry_hdr->d_ctrl.entry_capture_mask);4103}4104 4105int4106qla82xx_md_collect(scsi_qla_host_t *vha)4107{4108	struct qla_hw_data *ha = vha->hw;4109	int no_entry_hdr = 0;4110	qla82xx_md_entry_hdr_t *entry_hdr;4111	struct qla82xx_md_template_hdr *tmplt_hdr;4112	__le32 *data_ptr;4113	uint32_t total_data_size = 0, f_capture_mask, data_collected = 0;4114	int i = 0, rval = QLA_FUNCTION_FAILED;4115 4116	tmplt_hdr = (struct qla82xx_md_template_hdr *)ha->md_tmplt_hdr;4117	data_ptr = ha->md_dump;4118 4119	if (ha->fw_dumped) {4120		ql_log(ql_log_warn, vha, 0xb037,4121		    "Firmware has been previously dumped (%p) "4122		    "-- ignoring request.\n", ha->fw_dump);4123		goto md_failed;4124	}4125 4126	ha->fw_dumped = false;4127 4128	if (!ha->md_tmplt_hdr || !ha->md_dump) {4129		ql_log(ql_log_warn, vha, 0xb038,4130		    "Memory not allocated for minidump capture\n");4131		goto md_failed;4132	}4133 4134	if (ha->flags.isp82xx_no_md_cap) {4135		ql_log(ql_log_warn, vha, 0xb054,4136		    "Forced reset from application, "4137		    "ignore minidump capture\n");4138		ha->flags.isp82xx_no_md_cap = 0;4139		goto md_failed;4140	}4141 4142	if (qla82xx_validate_template_chksum(vha)) {4143		ql_log(ql_log_info, vha, 0xb039,4144		    "Template checksum validation error\n");4145		goto md_failed;4146	}4147 4148	no_entry_hdr = tmplt_hdr->num_of_entries;4149	ql_dbg(ql_dbg_p3p, vha, 0xb03a,4150	    "No of entry headers in Template: 0x%x\n", no_entry_hdr);4151 4152	ql_dbg(ql_dbg_p3p, vha, 0xb03b,4153	    "Capture Mask obtained: 0x%x\n", tmplt_hdr->capture_debug_level);4154 4155	f_capture_mask = tmplt_hdr->capture_debug_level & 0xFF;4156 4157	/* Validate whether required debug level is set */4158	if ((f_capture_mask & 0x3) != 0x3) {4159		ql_log(ql_log_warn, vha, 0xb03c,4160		    "Minimum required capture mask[0x%x] level not set\n",4161		    f_capture_mask);4162		goto md_failed;4163	}4164	tmplt_hdr->driver_capture_mask = ql2xmdcapmask;4165 4166	tmplt_hdr->driver_info[0] = vha->host_no;4167	tmplt_hdr->driver_info[1] = (QLA_DRIVER_MAJOR_VER << 24) |4168	    (QLA_DRIVER_MINOR_VER << 16) | (QLA_DRIVER_PATCH_VER << 8) |4169	    QLA_DRIVER_BETA_VER;4170 4171	total_data_size = ha->md_dump_size;4172 4173	ql_dbg(ql_dbg_p3p, vha, 0xb03d,4174	    "Total minidump data_size 0x%x to be captured\n", total_data_size);4175 4176	/* Check whether template obtained is valid */4177	if (tmplt_hdr->entry_type != QLA82XX_TLHDR) {4178		ql_log(ql_log_warn, vha, 0xb04e,4179		    "Bad template header entry type: 0x%x obtained\n",4180		    tmplt_hdr->entry_type);4181		goto md_failed;4182	}4183 4184	entry_hdr = (qla82xx_md_entry_hdr_t *)4185	    (((uint8_t *)ha->md_tmplt_hdr) + tmplt_hdr->first_entry_offset);4186 4187	/* Walk through the entry headers */4188	for (i = 0; i < no_entry_hdr; i++) {4189 4190		if (data_collected > total_data_size) {4191			ql_log(ql_log_warn, vha, 0xb03e,4192			    "More MiniDump data collected: [0x%x]\n",4193			    data_collected);4194			goto md_failed;4195		}4196 4197		if (!(entry_hdr->d_ctrl.entry_capture_mask &4198		    ql2xmdcapmask)) {4199			entry_hdr->d_ctrl.driver_flags |=4200			    QLA82XX_DBG_SKIPPED_FLAG;4201			ql_dbg(ql_dbg_p3p, vha, 0xb03f,4202			    "Skipping entry[%d]: "4203			    "ETYPE[0x%x]-ELEVEL[0x%x]\n",4204			    i, entry_hdr->entry_type,4205			    entry_hdr->d_ctrl.entry_capture_mask);4206			goto skip_nxt_entry;4207		}4208 4209		ql_dbg(ql_dbg_p3p, vha, 0xb040,4210		    "[%s]: data ptr[%d]: %p, entry_hdr: %p\n"4211		    "entry_type: 0x%x, capture_mask: 0x%x\n",4212		    __func__, i, data_ptr, entry_hdr,4213		    entry_hdr->entry_type,4214		    entry_hdr->d_ctrl.entry_capture_mask);4215 4216		ql_dbg(ql_dbg_p3p, vha, 0xb041,4217		    "Data collected: [0x%x], Dump size left:[0x%x]\n",4218		    data_collected, (ha->md_dump_size - data_collected));4219 4220		/* Decode the entry type and take4221		 * required action to capture debug data */4222		switch (entry_hdr->entry_type) {4223		case QLA82XX_RDEND:4224			qla82xx_mark_entry_skipped(vha, entry_hdr, i);4225			break;4226		case QLA82XX_CNTRL:4227			rval = qla82xx_minidump_process_control(vha,4228			    entry_hdr, &data_ptr);4229			if (rval != QLA_SUCCESS) {4230				qla82xx_mark_entry_skipped(vha, entry_hdr, i);4231				goto md_failed;4232			}4233			break;4234		case QLA82XX_RDCRB:4235			qla82xx_minidump_process_rdcrb(vha,4236			    entry_hdr, &data_ptr);4237			break;4238		case QLA82XX_RDMEM:4239			rval = qla82xx_minidump_process_rdmem(vha,4240			    entry_hdr, &data_ptr);4241			if (rval != QLA_SUCCESS) {4242				qla82xx_mark_entry_skipped(vha, entry_hdr, i);4243				goto md_failed;4244			}4245			break;4246		case QLA82XX_BOARD:4247		case QLA82XX_RDROM:4248			qla82xx_minidump_process_rdrom(vha,4249			    entry_hdr, &data_ptr);4250			break;4251		case QLA82XX_L2DTG:4252		case QLA82XX_L2ITG:4253		case QLA82XX_L2DAT:4254		case QLA82XX_L2INS:4255			rval = qla82xx_minidump_process_l2tag(vha,4256			    entry_hdr, &data_ptr);4257			if (rval != QLA_SUCCESS) {4258				qla82xx_mark_entry_skipped(vha, entry_hdr, i);4259				goto md_failed;4260			}4261			break;4262		case QLA82XX_L1DAT:4263		case QLA82XX_L1INS:4264			qla82xx_minidump_process_l1cache(vha,4265			    entry_hdr, &data_ptr);4266			break;4267		case QLA82XX_RDOCM:4268			qla82xx_minidump_process_rdocm(vha,4269			    entry_hdr, &data_ptr);4270			break;4271		case QLA82XX_RDMUX:4272			qla82xx_minidump_process_rdmux(vha,4273			    entry_hdr, &data_ptr);4274			break;4275		case QLA82XX_QUEUE:4276			qla82xx_minidump_process_queue(vha,4277			    entry_hdr, &data_ptr);4278			break;4279		case QLA82XX_RDNOP:4280		default:4281			qla82xx_mark_entry_skipped(vha, entry_hdr, i);4282			break;4283		}4284 4285		ql_dbg(ql_dbg_p3p, vha, 0xb042,4286		    "[%s]: data ptr[%d]: %p\n", __func__, i, data_ptr);4287 4288		data_collected = (uint8_t *)data_ptr -4289		    (uint8_t *)ha->md_dump;4290skip_nxt_entry:4291		entry_hdr = (qla82xx_md_entry_hdr_t *)4292		    (((uint8_t *)entry_hdr) + entry_hdr->entry_size);4293	}4294 4295	if (data_collected != total_data_size) {4296		ql_dbg(ql_dbg_p3p, vha, 0xb043,4297		    "MiniDump data mismatch: Data collected: [0x%x],"4298		    "total_data_size:[0x%x]\n",4299		    data_collected, total_data_size);4300		goto md_failed;4301	}4302 4303	ql_log(ql_log_info, vha, 0xb044,4304	    "Firmware dump saved to temp buffer (%ld/%p %ld/%p).\n",4305	    vha->host_no, ha->md_tmplt_hdr, vha->host_no, ha->md_dump);4306	ha->fw_dumped = true;4307	qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);4308 4309md_failed:4310	return rval;4311}4312 4313int4314qla82xx_md_alloc(scsi_qla_host_t *vha)4315{4316	struct qla_hw_data *ha = vha->hw;4317	int i, k;4318	struct qla82xx_md_template_hdr *tmplt_hdr;4319 4320	tmplt_hdr = (struct qla82xx_md_template_hdr *)ha->md_tmplt_hdr;4321 4322	if (ql2xmdcapmask < 0x3 || ql2xmdcapmask > 0x7F) {4323		ql2xmdcapmask = tmplt_hdr->capture_debug_level & 0xFF;4324		ql_log(ql_log_info, vha, 0xb045,4325		    "Forcing driver capture mask to firmware default capture mask: 0x%x.\n",4326		    ql2xmdcapmask);4327	}4328 4329	for (i = 0x2, k = 1; (i & QLA82XX_DEFAULT_CAP_MASK); i <<= 1, k++) {4330		if (i & ql2xmdcapmask)4331			ha->md_dump_size += tmplt_hdr->capture_size_array[k];4332	}4333 4334	if (ha->md_dump) {4335		ql_log(ql_log_warn, vha, 0xb046,4336		    "Firmware dump previously allocated.\n");4337		return 1;4338	}4339 4340	ha->md_dump = vmalloc(ha->md_dump_size);4341	if (ha->md_dump == NULL) {4342		ql_log(ql_log_warn, vha, 0xb047,4343		    "Unable to allocate memory for Minidump size "4344		    "(0x%x).\n", ha->md_dump_size);4345		return 1;4346	}4347	return 0;4348}4349 4350void4351qla82xx_md_free(scsi_qla_host_t *vha)4352{4353	struct qla_hw_data *ha = vha->hw;4354 4355	/* Release the template header allocated */4356	if (ha->md_tmplt_hdr) {4357		ql_log(ql_log_info, vha, 0xb048,4358		    "Free MiniDump template: %p, size (%d KB)\n",4359		    ha->md_tmplt_hdr, ha->md_template_size / 1024);4360		dma_free_coherent(&ha->pdev->dev, ha->md_template_size,4361		    ha->md_tmplt_hdr, ha->md_tmplt_hdr_dma);4362		ha->md_tmplt_hdr = NULL;4363	}4364 4365	/* Release the template data buffer allocated */4366	if (ha->md_dump) {4367		ql_log(ql_log_info, vha, 0xb049,4368		    "Free MiniDump memory: %p, size (%d KB)\n",4369		    ha->md_dump, ha->md_dump_size / 1024);4370		vfree(ha->md_dump);4371		ha->md_dump_size = 0;4372		ha->md_dump = NULL;4373	}4374}4375 4376void4377qla82xx_md_prep(scsi_qla_host_t *vha)4378{4379	struct qla_hw_data *ha = vha->hw;4380	int rval;4381 4382	/* Get Minidump template size */4383	rval = qla82xx_md_get_template_size(vha);4384	if (rval == QLA_SUCCESS) {4385		ql_log(ql_log_info, vha, 0xb04a,4386		    "MiniDump Template size obtained (%d KB)\n",4387		    ha->md_template_size / 1024);4388 4389		/* Get Minidump template */4390		if (IS_QLA8044(ha))4391			rval = qla8044_md_get_template(vha);4392		else4393			rval = qla82xx_md_get_template(vha);4394 4395		if (rval == QLA_SUCCESS) {4396			ql_dbg(ql_dbg_p3p, vha, 0xb04b,4397			    "MiniDump Template obtained\n");4398 4399			/* Allocate memory for minidump */4400			rval = qla82xx_md_alloc(vha);4401			if (rval == QLA_SUCCESS)4402				ql_log(ql_log_info, vha, 0xb04c,4403				    "MiniDump memory allocated (%d KB)\n",4404				    ha->md_dump_size / 1024);4405			else {4406				ql_log(ql_log_info, vha, 0xb04d,4407				    "Free MiniDump template: %p, size: (%d KB)\n",4408				    ha->md_tmplt_hdr,4409				    ha->md_template_size / 1024);4410				dma_free_coherent(&ha->pdev->dev,4411				    ha->md_template_size,4412				    ha->md_tmplt_hdr, ha->md_tmplt_hdr_dma);4413				ha->md_tmplt_hdr = NULL;4414			}4415 4416		}4417	}4418}4419 4420int4421qla82xx_beacon_on(struct scsi_qla_host *vha)4422{4423 4424	int rval;4425	struct qla_hw_data *ha = vha->hw;4426 4427	qla82xx_idc_lock(ha);4428	rval = qla82xx_mbx_beacon_ctl(vha, 1);4429 4430	if (rval) {4431		ql_log(ql_log_warn, vha, 0xb050,4432		    "mbx set led config failed in %s\n", __func__);4433		goto exit;4434	}4435	ha->beacon_blink_led = 1;4436exit:4437	qla82xx_idc_unlock(ha);4438	return rval;4439}4440 4441int4442qla82xx_beacon_off(struct scsi_qla_host *vha)4443{4444 4445	int rval;4446	struct qla_hw_data *ha = vha->hw;4447 4448	qla82xx_idc_lock(ha);4449	rval = qla82xx_mbx_beacon_ctl(vha, 0);4450 4451	if (rval) {4452		ql_log(ql_log_warn, vha, 0xb051,4453		    "mbx set led config failed in %s\n", __func__);4454		goto exit;4455	}4456	ha->beacon_blink_led = 0;4457exit:4458	qla82xx_idc_unlock(ha);4459	return rval;4460}4461 4462void4463qla82xx_fw_dump(scsi_qla_host_t *vha)4464{4465	struct qla_hw_data *ha = vha->hw;4466 4467	if (!ha->allow_cna_fw_dump)4468		return;4469 4470	scsi_block_requests(vha->host);4471	ha->flags.isp82xx_no_md_cap = 1;4472	qla82xx_idc_lock(ha);4473	qla82xx_set_reset_owner(vha);4474	qla82xx_idc_unlock(ha);4475	qla2x00_wait_for_chip_reset(vha);4476	scsi_unblock_requests(vha->host);4477}4478