1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2010 QLogic Corporation.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*
28  * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
29  *
30  * ***********************************************************************
31  * *									**
32  * *				NOTICE					**
33  * *		COPYRIGHT (C) 1996-2010 QLOGIC CORPORATION		**
34  * *			ALL RIGHTS RESERVED				**
35  * *									**
36  * ***********************************************************************
37  *
38  */
39 
40 #include <ql_apps.h>
41 #include <ql_api.h>
42 #include <ql_debug.h>
43 #include <ql_mbx.h>
44 #include <ql_nx.h>
45 
46 /*
47  *  Local Function Prototypes.
48  */
49 static void *ql_8021_pci_base_offsetfset(ql_adapter_state_t *, uint64_t);
50 static void ql_crb_addr_transform_setup(ql_adapter_state_t *);
51 static void ql_8021_pci_set_crbwindow_2M(ql_adapter_state_t *, uint64_t *);
52 static void ql_8021_wr_32(ql_adapter_state_t *, uint64_t, uint32_t);
53 static void ql_8021_rd_32(ql_adapter_state_t *, uint64_t, uint32_t *);
54 static int ql_8021_crb_win_lock(ql_adapter_state_t *);
55 static void ql_8021_crb_win_unlock(ql_adapter_state_t *);
56 static int ql_8021_pci_get_crb_addr_2M(ql_adapter_state_t *, uint64_t *);
57 static uint32_t ql_8021_pci_mem_bound_check(ql_adapter_state_t *, uint64_t,
58     uint32_t);
59 static uint64_t ql_8021_pci_set_window(ql_adapter_state_t *, uint64_t);
60 static int ql_8021_pci_is_same_window(ql_adapter_state_t *, uint64_t);
61 static int ql_8021_pci_mem_read_direct(ql_adapter_state_t *, uint64_t, void *,
62     uint32_t);
63 static int ql_8021_pci_mem_write_direct(ql_adapter_state_t *, uint64_t, void *,
64     uint32_t);
65 static int ql_8021_pci_mem_read_2M(ql_adapter_state_t *, uint64_t, void *,
66     uint32_t);
67 static int ql_8021_pci_mem_write_2M(ql_adapter_state_t *, uint64_t, void *,
68     uint32_t);
69 static uint32_t ql_8021_decode_crb_addr(ql_adapter_state_t *, uint32_t);
70 static int ql_8021_rom_lock(ql_adapter_state_t *);
71 static void ql_8021_rom_unlock(ql_adapter_state_t *);
72 static int ql_8021_wait_rom_done(ql_adapter_state_t *);
73 static int ql_8021_wait_flash_done(ql_adapter_state_t *);
74 static int ql_8021_do_rom_fast_read(ql_adapter_state_t *, uint32_t, uint32_t *);
75 static int ql_8021_rom_fast_read(ql_adapter_state_t *, uint32_t, uint32_t *);
76 static int ql_8021_do_rom_write(ql_adapter_state_t *, uint32_t, uint32_t);
77 static int ql_8021_do_rom_erase(ql_adapter_state_t *, uint32_t);
78 static int ql_8021_phantom_init(ql_adapter_state_t *);
79 static int ql_8021_pinit_from_rom(ql_adapter_state_t *);
80 static int ql_8021_load_from_flash(ql_adapter_state_t *);
81 static int ql_8021_load_firmware(ql_adapter_state_t *);
82 static int ql_8021_reset_hw(ql_adapter_state_t *, int);
83 static int ql_8021_init_p3p(ql_adapter_state_t *);
84 static int ql_8021_hw_lock(ql_adapter_state_t *, uint32_t);
85 static void ql_8021_hw_unlock(ql_adapter_state_t *);
86 static void ql_8021_need_reset_handler(ql_adapter_state_t *);
87 
88 /*
89  * Local Data.
90  */
91 static uint32_t	crb_addr_xform[MAX_CRB_XFORM];
92 static int	crb_table_initialized = 0;
93 static int	pci_set_window_warning_count = 0;
94 
95 static struct legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;
96 
97 static crb_128M_2M_block_map_t crb_128M_2M_map[64] = {
98 	{{{0, 0,	 0,	 0}}},			/* 0: PCI */
99 	{{{1, 0x0100000, 0x0102000, 0x120000},		/* 1: PCIE */
100 	    {1, 0x0110000, 0x0120000, 0x130000},
101 	    {1, 0x0120000, 0x0122000, 0x124000},
102 	    {1, 0x0130000, 0x0132000, 0x126000},
103 	    {1, 0x0140000, 0x0142000, 0x128000},
104 	    {1, 0x0150000, 0x0152000, 0x12a000},
105 	    {1, 0x0160000, 0x0170000, 0x110000},
106 	    {1, 0x0170000, 0x0172000, 0x12e000},
107 	    {0, 0x0000000, 0x0000000, 0x000000},
108 	    {0, 0x0000000, 0x0000000, 0x000000},
109 	    {0, 0x0000000, 0x0000000, 0x000000},
110 	    {0, 0x0000000, 0x0000000, 0x000000},
111 	    {0, 0x0000000, 0x0000000, 0x000000},
112 	    {0, 0x0000000, 0x0000000, 0x000000},
113 	    {1, 0x01e0000, 0x01e0800, 0x122000},
114 	    {0, 0x0000000, 0x0000000, 0x000000}}},
115 	{{{1, 0x0200000, 0x0210000, 0x180000}}},	/* 2: MN */
116 	{{{0, 0,	 0,	 0}}},			/* 3: */
117 	{{{1, 0x0400000, 0x0401000, 0x169000}}},	/* 4: P2NR1 */
118 	{{{1, 0x0500000, 0x0510000, 0x140000}}},	/* 5: SRE   */
119 	{{{1, 0x0600000, 0x0610000, 0x1c0000}}},	/* 6: NIU   */
120 	{{{1, 0x0700000, 0x0704000, 0x1b8000}}},	/* 7: QM    */
121 	{{{1, 0x0800000, 0x0802000, 0x170000},  	/* 8: SQM0  */
122 	    {0, 0x0000000, 0x0000000, 0x000000},
123 	    {0, 0x0000000, 0x0000000, 0x000000},
124 	    {0, 0x0000000, 0x0000000, 0x000000},
125 	    {0, 0x0000000, 0x0000000, 0x000000},
126 	    {0, 0x0000000, 0x0000000, 0x000000},
127 	    {0, 0x0000000, 0x0000000, 0x000000},
128 	    {0, 0x0000000, 0x0000000, 0x000000},
129 	    {0, 0x0000000, 0x0000000, 0x000000},
130 	    {0, 0x0000000, 0x0000000, 0x000000},
131 	    {0, 0x0000000, 0x0000000, 0x000000},
132 	    {0, 0x0000000, 0x0000000, 0x000000},
133 	    {0, 0x0000000, 0x0000000, 0x000000},
134 	    {0, 0x0000000, 0x0000000, 0x000000},
135 	    {0, 0x0000000, 0x0000000, 0x000000},
136 	    {1, 0x08f0000, 0x08f2000, 0x172000}}},
137 	{{{1, 0x0900000, 0x0902000, 0x174000},		/* 9: SQM1 */
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 	    {0, 0x0000000, 0x0000000, 0x000000},
150 	    {0, 0x0000000, 0x0000000, 0x000000},
151 	    {0, 0x0000000, 0x0000000, 0x000000},
152 	    {1, 0x09f0000, 0x09f2000, 0x176000}}},
153 	{{{0, 0x0a00000, 0x0a02000, 0x178000},		/* 10: SQM2 */
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 	    {0, 0x0000000, 0x0000000, 0x000000},
166 	    {0, 0x0000000, 0x0000000, 0x000000},
167 	    {0, 0x0000000, 0x0000000, 0x000000},
168 	    {1, 0x0af0000, 0x0af2000, 0x17a000}}},
169 	{{{0, 0x0b00000, 0x0b02000, 0x17c000},		/* 11: SQM3 */
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 	    {0, 0x0000000, 0x0000000, 0x000000},
182 	    {0, 0x0000000, 0x0000000, 0x000000},
183 	    {0, 0x0000000, 0x0000000, 0x000000},
184 	    {1, 0x0bf0000, 0x0bf2000, 0x17e000}}},
185 	{{{1, 0x0c00000, 0x0c04000, 0x1d4000}}},	/* 12: I2Q */
186 	{{{1, 0x0d00000, 0x0d04000, 0x1a4000}}},	/* 13: TMR */
187 	{{{1, 0x0e00000, 0x0e04000, 0x1a0000}}},	/* 14: ROMUSB */
188 	{{{1, 0x0f00000, 0x0f01000, 0x164000}}},	/* 15: PEG4 */
189 	{{{0, 0x1000000, 0x1004000, 0x1a8000}}},	/* 16: XDMA */
190 	{{{1, 0x1100000, 0x1101000, 0x160000}}},	/* 17: PEG0 */
191 	{{{1, 0x1200000, 0x1201000, 0x161000}}},	/* 18: PEG1 */
192 	{{{1, 0x1300000, 0x1301000, 0x162000}}},	/* 19: PEG2 */
193 	{{{1, 0x1400000, 0x1401000, 0x163000}}},	/* 20: PEG3 */
194 	{{{1, 0x1500000, 0x1501000, 0x165000}}},	/* 21: P2ND */
195 	{{{1, 0x1600000, 0x1601000, 0x166000}}},	/* 22: P2NI */
196 	{{{0, 0,	 0,	 0}}},			/* 23: */
197 	{{{0, 0,	 0,	 0}}},			/* 24: */
198 	{{{0, 0,	 0,	 0}}},			/* 25: */
199 	{{{0, 0,	 0,	 0}}},			/* 26: */
200 	{{{0, 0,	 0,	 0}}},			/* 27: */
201 	{{{0, 0,	 0,	 0}}},			/* 28: */
202 	{{{1, 0x1d00000, 0x1d10000, 0x190000}}},	/* 29: MS */
203 	{{{1, 0x1e00000, 0x1e01000, 0x16a000}}},	/* 30: P2NR2 */
204 	{{{1, 0x1f00000, 0x1f10000, 0x150000}}},	/* 31: EPG */
205 	{{{0}}},					/* 32: PCI */
206 	{{{1, 0x2100000, 0x2102000, 0x120000},		/* 33: PCIE */
207 	    {1, 0x2110000, 0x2120000, 0x130000},
208 	    {1, 0x2120000, 0x2122000, 0x124000},
209 	    {1, 0x2130000, 0x2132000, 0x126000},
210 	    {1, 0x2140000, 0x2142000, 0x128000},
211 	    {1, 0x2150000, 0x2152000, 0x12a000},
212 	    {1, 0x2160000, 0x2170000, 0x110000},
213 	    {1, 0x2170000, 0x2172000, 0x12e000},
214 	    {0, 0x0000000, 0x0000000, 0x000000},
215 	    {0, 0x0000000, 0x0000000, 0x000000},
216 	    {0, 0x0000000, 0x0000000, 0x000000},
217 	    {0, 0x0000000, 0x0000000, 0x000000},
218 	    {0, 0x0000000, 0x0000000, 0x000000},
219 	    {0, 0x0000000, 0x0000000, 0x000000},
220 	    {0, 0x0000000, 0x0000000, 0x000000},
221 	    {0, 0x0000000, 0x0000000, 0x000000}}},
222 	{{{1, 0x2200000, 0x2204000, 0x1b0000}}},	/* 34: CAM */
223 	{{{0}}},					/* 35: */
224 	{{{0}}},					/* 36: */
225 	{{{0}}},					/* 37: */
226 	{{{0}}},					/* 38: */
227 	{{{0}}},					/* 39: */
228 	{{{1, 0x2800000, 0x2804000, 0x1a4000}}},	/* 40: TMR */
229 	{{{1, 0x2900000, 0x2901000, 0x16b000}}},	/* 41: P2NR3 */
230 	{{{1, 0x2a00000, 0x2a00400, 0x1ac400}}},	/* 42: RPMX1 */
231 	{{{1, 0x2b00000, 0x2b00400, 0x1ac800}}},	/* 43: RPMX2 */
232 	{{{1, 0x2c00000, 0x2c00400, 0x1acc00}}},	/* 44: RPMX3 */
233 	{{{1, 0x2d00000, 0x2d00400, 0x1ad000}}},	/* 45: RPMX4 */
234 	{{{1, 0x2e00000, 0x2e00400, 0x1ad400}}},	/* 46: RPMX5 */
235 	{{{1, 0x2f00000, 0x2f00400, 0x1ad800}}},	/* 47: RPMX6 */
236 	{{{1, 0x3000000, 0x3000400, 0x1adc00}}},	/* 48: RPMX7 */
237 	{{{0, 0x3100000, 0x3104000, 0x1a8000}}},	/* 49: XDMA */
238 	{{{1, 0x3200000, 0x3204000, 0x1d4000}}},	/* 50: I2Q */
239 	{{{1, 0x3300000, 0x3304000, 0x1a0000}}},	/* 51: ROMUSB */
240 	{{{0}}},					/* 52: */
241 	{{{1, 0x3500000, 0x3500400, 0x1ac000}}},	/* 53: RPMX0 */
242 	{{{1, 0x3600000, 0x3600400, 0x1ae000}}},	/* 54: RPMX8 */
243 	{{{1, 0x3700000, 0x3700400, 0x1ae400}}},	/* 55: RPMX9 */
244 	{{{1, 0x3800000, 0x3804000, 0x1d0000}}},	/* 56: OCM0 */
245 	{{{1, 0x3900000, 0x3904000, 0x1b4000}}},	/* 57: CRYPTO */
246 	{{{1, 0x3a00000, 0x3a04000, 0x1d8000}}},	/* 58: SMB */
247 	{{{0}}},					/* 59: I2C0 */
248 	{{{0}}},					/* 60: I2C1 */
249 	{{{1, 0x3d00000, 0x3d04000, 0x1dc000}}},	/* 61: LPC */
250 	{{{1, 0x3e00000, 0x3e01000, 0x167000}}},	/* 62: P2NC */
251 	{{{1, 0x3f00000, 0x3f01000, 0x168000}}}		/* 63: P2NR0 */
252 };
253 
254 /*
255  * top 12 bits of crb internal address (hub, agent)
256  */
257 static uint32_t crb_hub_agt[64] = {
258 	0,
259 	UNM_HW_CRB_HUB_AGT_ADR_PS,
260 	UNM_HW_CRB_HUB_AGT_ADR_MN,
261 	UNM_HW_CRB_HUB_AGT_ADR_MS,
262 	0,
263 	UNM_HW_CRB_HUB_AGT_ADR_SRE,
264 	UNM_HW_CRB_HUB_AGT_ADR_NIU,
265 	UNM_HW_CRB_HUB_AGT_ADR_QMN,
266 	UNM_HW_CRB_HUB_AGT_ADR_SQN0,
267 	UNM_HW_CRB_HUB_AGT_ADR_SQN1,
268 	UNM_HW_CRB_HUB_AGT_ADR_SQN2,
269 	UNM_HW_CRB_HUB_AGT_ADR_SQN3,
270 	UNM_HW_CRB_HUB_AGT_ADR_I2Q,
271 	UNM_HW_CRB_HUB_AGT_ADR_TIMR,
272 	UNM_HW_CRB_HUB_AGT_ADR_ROMUSB,
273 	UNM_HW_CRB_HUB_AGT_ADR_PGN4,
274 	UNM_HW_CRB_HUB_AGT_ADR_XDMA,
275 	UNM_HW_CRB_HUB_AGT_ADR_PGN0,
276 	UNM_HW_CRB_HUB_AGT_ADR_PGN1,
277 	UNM_HW_CRB_HUB_AGT_ADR_PGN2,
278 	UNM_HW_CRB_HUB_AGT_ADR_PGN3,
279 	UNM_HW_CRB_HUB_AGT_ADR_PGND,
280 	UNM_HW_CRB_HUB_AGT_ADR_PGNI,
281 	UNM_HW_CRB_HUB_AGT_ADR_PGS0,
282 	UNM_HW_CRB_HUB_AGT_ADR_PGS1,
283 	UNM_HW_CRB_HUB_AGT_ADR_PGS2,
284 	UNM_HW_CRB_HUB_AGT_ADR_PGS3,
285 	0,
286 	UNM_HW_CRB_HUB_AGT_ADR_PGSI,
287 	UNM_HW_CRB_HUB_AGT_ADR_SN,
288 	0,
289 	UNM_HW_CRB_HUB_AGT_ADR_EG,
290 	0,
291 	UNM_HW_CRB_HUB_AGT_ADR_PS,
292 	UNM_HW_CRB_HUB_AGT_ADR_CAM,
293 	0,
294 	0,
295 	0,
296 	0,
297 	0,
298 	UNM_HW_CRB_HUB_AGT_ADR_TIMR,
299 	0,
300 	UNM_HW_CRB_HUB_AGT_ADR_RPMX1,
301 	UNM_HW_CRB_HUB_AGT_ADR_RPMX2,
302 	UNM_HW_CRB_HUB_AGT_ADR_RPMX3,
303 	UNM_HW_CRB_HUB_AGT_ADR_RPMX4,
304 	UNM_HW_CRB_HUB_AGT_ADR_RPMX5,
305 	UNM_HW_CRB_HUB_AGT_ADR_RPMX6,
306 	UNM_HW_CRB_HUB_AGT_ADR_RPMX7,
307 	UNM_HW_CRB_HUB_AGT_ADR_XDMA,
308 	UNM_HW_CRB_HUB_AGT_ADR_I2Q,
309 	UNM_HW_CRB_HUB_AGT_ADR_ROMUSB,
310 	0,
311 	UNM_HW_CRB_HUB_AGT_ADR_RPMX0,
312 	UNM_HW_CRB_HUB_AGT_ADR_RPMX8,
313 	UNM_HW_CRB_HUB_AGT_ADR_RPMX9,
314 	UNM_HW_CRB_HUB_AGT_ADR_OCM0,
315 	0,
316 	UNM_HW_CRB_HUB_AGT_ADR_SMB,
317 	UNM_HW_CRB_HUB_AGT_ADR_I2C0,
318 	UNM_HW_CRB_HUB_AGT_ADR_I2C1,
319 	0,
320 	UNM_HW_CRB_HUB_AGT_ADR_PGNC,
321 	0,
322 };
323 
324 static void *
325 ql_8021_pci_base_offsetfset(ql_adapter_state_t *ha, uint64_t off)
326 {
327 	if ((off < ha->first_page_group_end) &&
328 	    (off >= ha->first_page_group_start)) {
329 		return ((void *)(ha->nx_pcibase + off));
330 	}
331 
332 	return (NULL);
333 }
334 
335 /* ARGSUSED */
336 static void
337 ql_crb_addr_transform_setup(ql_adapter_state_t *ha)
338 {
339 	crb_addr_transform(XDMA);
340 	crb_addr_transform(TIMR);
341 	crb_addr_transform(SRE);
342 	crb_addr_transform(SQN3);
343 	crb_addr_transform(SQN2);
344 	crb_addr_transform(SQN1);
345 	crb_addr_transform(SQN0);
346 	crb_addr_transform(SQS3);
347 	crb_addr_transform(SQS2);
348 	crb_addr_transform(SQS1);
349 	crb_addr_transform(SQS0);
350 	crb_addr_transform(RPMX7);
351 	crb_addr_transform(RPMX6);
352 	crb_addr_transform(RPMX5);
353 	crb_addr_transform(RPMX4);
354 	crb_addr_transform(RPMX3);
355 	crb_addr_transform(RPMX2);
356 	crb_addr_transform(RPMX1);
357 	crb_addr_transform(RPMX0);
358 	crb_addr_transform(ROMUSB);
359 	crb_addr_transform(SN);
360 	crb_addr_transform(QMN);
361 	crb_addr_transform(QMS);
362 	crb_addr_transform(PGNI);
363 	crb_addr_transform(PGND);
364 	crb_addr_transform(PGN3);
365 	crb_addr_transform(PGN2);
366 	crb_addr_transform(PGN1);
367 	crb_addr_transform(PGN0);
368 	crb_addr_transform(PGSI);
369 	crb_addr_transform(PGSD);
370 	crb_addr_transform(PGS3);
371 	crb_addr_transform(PGS2);
372 	crb_addr_transform(PGS1);
373 	crb_addr_transform(PGS0);
374 	crb_addr_transform(PS);
375 	crb_addr_transform(PH);
376 	crb_addr_transform(NIU);
377 	crb_addr_transform(I2Q);
378 	crb_addr_transform(EG);
379 	crb_addr_transform(MN);
380 	crb_addr_transform(MS);
381 	crb_addr_transform(CAS2);
382 	crb_addr_transform(CAS1);
383 	crb_addr_transform(CAS0);
384 	crb_addr_transform(CAM);
385 	crb_addr_transform(C2C1);
386 	crb_addr_transform(C2C0);
387 	crb_addr_transform(SMB);
388 	crb_addr_transform(OCM0);
389 	/*
390 	 * Used only in P3 just define it for P2 also.
391 	 */
392 	crb_addr_transform(I2C0);
393 
394 	crb_table_initialized = 1;
395 }
396 
397 /*
398  * In: 'off' is offset from CRB space in 128M pci map
399  * Out: 'off' is 2M pci map addr
400  * side effect: lock crb window
401  */
402 static void
403 ql_8021_pci_set_crbwindow_2M(ql_adapter_state_t *ha, uint64_t *off)
404 {
405 	uint32_t	win_read;
406 
407 	ha->crb_win = (uint32_t)CRB_HI(*off);
408 	WRT_REG_DWORD(ha, CRB_WINDOW_2M + ha->nx_pcibase, ha->crb_win);
409 
410 	/*
411 	 * Read back value to make sure write has gone through before trying
412 	 * to use it.
413 	 */
414 	win_read = RD_REG_DWORD(ha, CRB_WINDOW_2M + ha->nx_pcibase);
415 	if (win_read != ha->crb_win) {
416 		EL(ha, "Written crbwin (0x%x) != Read crbwin (0x%x), "
417 		    "off=0x%llx\n", ha->crb_win, win_read, *off);
418 	}
419 	*off = (*off & MASK(16)) + CRB_INDIRECT_2M + (uintptr_t)ha->nx_pcibase;
420 }
421 
422 static void
423 ql_8021_wr_32(ql_adapter_state_t *ha, uint64_t off, uint32_t data)
424 {
425 	int	rv;
426 
427 	rv = ql_8021_pci_get_crb_addr_2M(ha, &off);
428 	if (rv == -1) {
429 		cmn_err(CE_PANIC, "ql_8021_wr_32, ql_8021_pci_get_crb_addr_"
430 		    "2M=-1\n");
431 	}
432 	if (rv == 1) {
433 		(void) ql_8021_crb_win_lock(ha);
434 		ql_8021_pci_set_crbwindow_2M(ha, &off);
435 	}
436 
437 	WRT_REG_DWORD(ha, (uintptr_t)off, data);
438 
439 	if (rv == 1) {
440 		ql_8021_crb_win_unlock(ha);
441 	}
442 }
443 
444 static void
445 ql_8021_rd_32(ql_adapter_state_t *ha, uint64_t off, uint32_t *data)
446 {
447 	int		rv;
448 	uint32_t	n;
449 
450 	rv = ql_8021_pci_get_crb_addr_2M(ha, &off);
451 	if (rv == -1) {
452 		cmn_err(CE_PANIC, "ql_8021_rd_32, ql_8021_pci_get_crb_addr_"
453 		    "2M=-1\n");
454 	}
455 
456 	if (rv == 1) {
457 		(void) ql_8021_crb_win_lock(ha);
458 		ql_8021_pci_set_crbwindow_2M(ha, &off);
459 	}
460 	n = RD_REG_DWORD(ha, (uintptr_t)off);
461 
462 	if (data != NULL) {
463 		*data = n;
464 	}
465 
466 	if (rv == 1) {
467 		ql_8021_crb_win_unlock(ha);
468 	}
469 }
470 
471 static int
472 ql_8021_crb_win_lock(ql_adapter_state_t *ha)
473 {
474 	uint32_t	done = 0, timeout = 0;
475 
476 	while (!done) {
477 		/* acquire semaphore3 from PCI HW block */
478 		ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM7_LOCK), &done);
479 		if (done == 1) {
480 			break;
481 		}
482 		if (timeout >= CRB_WIN_LOCK_TIMEOUT) {
483 			EL(ha, "timeout\n");
484 			return (-1);
485 		}
486 		timeout++;
487 
488 		/* Yield CPU */
489 		delay(1);
490 	}
491 	ql_8021_wr_32(ha, UNM_CRB_WIN_LOCK_ID, ha->function_number);
492 
493 	return (0);
494 }
495 
496 static void
497 ql_8021_crb_win_unlock(ql_adapter_state_t *ha)
498 {
499 	ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM7_UNLOCK), NULL);
500 }
501 
502 static int
503 ql_8021_pci_get_crb_addr_2M(ql_adapter_state_t *ha, uint64_t *off)
504 {
505 	crb_128M_2M_sub_block_map_t	*m;
506 
507 	if (*off >= UNM_CRB_MAX) {
508 		EL(ha, "%llx >= %llx\n", *off, UNM_CRB_MAX);
509 		return (-1);
510 	}
511 
512 	if (*off >= UNM_PCI_CAMQM && (*off < UNM_PCI_CAMQM_2M_END)) {
513 		*off = (*off - UNM_PCI_CAMQM) + UNM_PCI_CAMQM_2M_BASE +
514 		    (uintptr_t)ha->nx_pcibase;
515 		return (0);
516 	}
517 
518 	if (*off < UNM_PCI_CRBSPACE) {
519 		EL(ha, "%llx < %llx\n", *off, UNM_PCI_CRBSPACE);
520 		return (-1);
521 	}
522 
523 	*off -= UNM_PCI_CRBSPACE;
524 	/*
525 	 * Try direct map
526 	 */
527 
528 	m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)];
529 
530 	if (m->valid && ((uint64_t)m->start_128M <= *off) &&
531 	    ((uint64_t)m->end_128M > *off)) {
532 		*off = (uint64_t)(*off + m->start_2M - m->start_128M +
533 		    (uintptr_t)ha->nx_pcibase);
534 		return (0);
535 	}
536 
537 	/*
538 	 * Not in direct map, use crb window
539 	 */
540 	return (1);
541 }
542 
543 /*
544  * check memory access boundary.
545  * used by test agent. support ddr access only for now
546  */
547 /* ARGSUSED */
548 static uint32_t
549 ql_8021_pci_mem_bound_check(ql_adapter_state_t *ha, uint64_t addr,
550     uint32_t size)
551 {
552 	/*LINTED suspicious 0 comparison*/
553 	if (!QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET,
554 	    UNM_ADDR_DDR_NET_MAX) ||
555 	    /*LINTED suspicious 0 comparison*/
556 	    !QL_8021_ADDR_IN_RANGE(addr + size - 1, UNM_ADDR_DDR_NET,
557 	    UNM_ADDR_DDR_NET_MAX) ||
558 	    ((size != 1) && (size != 2) && (size != 4) && (size != 8))) {
559 		return (0);
560 	}
561 
562 	return (1);
563 }
564 
565 static uint64_t
566 ql_8021_pci_set_window(ql_adapter_state_t *ha, uint64_t addr)
567 {
568 	uint32_t	window, win_read;
569 
570 	/*LINTED suspicious 0 comparison*/
571 	if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET,
572 	    UNM_ADDR_DDR_NET_MAX)) {
573 		/* DDR network side */
574 		window = (uint32_t)MN_WIN(addr);
575 		ha->ddr_mn_window = window;
576 		ql_8021_wr_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE, window);
577 		ql_8021_rd_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE,
578 		    &win_read);
579 		if ((win_read << 17) != window) {
580 			EL(ha, "Warning, Written MNwin (0x%x) != Read MNwin "
581 			    "(0x%x)\n", window, win_read);
582 		}
583 		addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_DDR_NET;
584 	} else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_OCM0,
585 	    UNM_ADDR_OCM0_MAX)) {
586 		uint32_t	temp1;
587 
588 		if ((addr & 0x00ff800) == 0xff800) {
589 			/* if bits 19:18&17:11 are on */
590 			EL(ha, "QM access not handled\n");
591 			addr = -1UL;
592 		}
593 
594 		window = (uint32_t)OCM_WIN(addr);
595 		ha->ddr_mn_window = window;
596 		ql_8021_wr_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE, window);
597 		ql_8021_rd_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE,
598 		    &win_read);
599 		temp1 = ((window & 0x1FF) << 7) |
600 		    ((window & 0x0FFFE0000) >> 17);
601 		if (win_read != temp1) {
602 			EL(ha, "Written OCMwin (0x%x) != Read OCMwin (0x%x)\n",
603 			    temp1, win_read);
604 		}
605 		addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_OCM0_2M;
606 	} else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET,
607 	    NX_P3_ADDR_QDR_NET_MAX)) {
608 		/* QDR network side */
609 		window = (uint32_t)MS_WIN(addr);
610 		ha->qdr_sn_window = window;
611 		ql_8021_wr_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE, window);
612 		ql_8021_rd_32(ha, ha->mn_win_crb | UNM_PCI_CRBSPACE,
613 		    &win_read);
614 		if (win_read != window) {
615 			EL(ha, "Written MSwin (0x%x) != Read MSwin (0x%x)\n",
616 			    window, win_read);
617 		}
618 		addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_QDR_NET;
619 	} else {
620 		/*
621 		 * peg gdb frequently accesses memory that doesn't exist,
622 		 * this limits the chit chat so debugging isn't slowed down.
623 		 */
624 		if ((pci_set_window_warning_count++ < 8) ||
625 		    (pci_set_window_warning_count % 64 == 0)) {
626 			EL(ha, "Unknown address range\n");
627 		}
628 		addr = -1UL;
629 	}
630 
631 	return (addr);
632 }
633 
634 /* check if address is in the same windows as the previous access */
635 static int
636 ql_8021_pci_is_same_window(ql_adapter_state_t *ha, uint64_t addr)
637 {
638 	uint32_t	window;
639 	uint64_t	qdr_max;
640 
641 	qdr_max = NX_P3_ADDR_QDR_NET_MAX;
642 
643 	/*LINTED suspicious 0 comparison*/
644 	if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET,
645 	    UNM_ADDR_DDR_NET_MAX)) {
646 		/* DDR network side */
647 		EL(ha, "DDR network side\n");
648 		return (0);	/* MN access can not come here */
649 	} else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_OCM0,
650 	    UNM_ADDR_OCM0_MAX)) {
651 		return (1);
652 	} else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_OCM1,
653 	    UNM_ADDR_OCM1_MAX)) {
654 		return (1);
655 	} else if (QL_8021_ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET, qdr_max)) {
656 		/* QDR network side */
657 		window = (uint32_t)(((addr - UNM_ADDR_QDR_NET) >> 22) & 0x3f);
658 		if (ha->qdr_sn_window == window) {
659 			return (1);
660 		}
661 	}
662 
663 	return (0);
664 }
665 
666 static int
667 ql_8021_pci_mem_read_direct(ql_adapter_state_t *ha, uint64_t off, void *data,
668     uint32_t size)
669 {
670 	void		*addr;
671 	int		ret = 0;
672 	uint64_t	start;
673 
674 	/*
675 	 * If attempting to access unknown address or straddle hw windows,
676 	 * do not access.
677 	 */
678 	if (((start = ql_8021_pci_set_window(ha, off)) == -1UL) ||
679 	    (ql_8021_pci_is_same_window(ha, off + size - 1) == 0)) {
680 		EL(ha, "out of bound pci memory access. offset is 0x%llx\n",
681 		    off);
682 		return (-1);
683 	}
684 
685 	addr = ql_8021_pci_base_offsetfset(ha, start);
686 	if (!addr) {
687 		addr = (void *)((uint8_t *)ha->nx_pcibase + start);
688 	}
689 
690 	switch (size) {
691 	case 1:
692 		*(uint8_t  *)data = RD_REG_BYTE(ha, addr);
693 		break;
694 	case 2:
695 		*(uint16_t  *)data = RD_REG_WORD(ha, addr);
696 		break;
697 	case 4:
698 		*(uint32_t  *)data = RD_REG_DWORD(ha, addr);
699 		break;
700 	case 8:
701 		*(uint64_t  *)data = RD_REG_DDWORD(ha, addr);
702 		break;
703 	default:
704 		EL(ha, "invalid size=%x\n", size);
705 		ret = -1;
706 		break;
707 	}
708 
709 	return (ret);
710 }
711 
712 static int
713 ql_8021_pci_mem_write_direct(ql_adapter_state_t *ha, uint64_t off, void *data,
714     uint32_t size)
715 {
716 	void		*addr;
717 	int		ret = 0;
718 	uint64_t	start;
719 
720 	/*
721 	 * If attempting to access unknown address or straddle hw windows,
722 	 * do not access.
723 	 */
724 	if (((start = ql_8021_pci_set_window(ha, off)) == -1UL) ||
725 	    (ql_8021_pci_is_same_window(ha, off + size -1) == 0)) {
726 		EL(ha, "out of bound pci memory access. offset is 0x%llx\n",
727 		    off);
728 		return (-1);
729 	}
730 
731 	addr = ql_8021_pci_base_offsetfset(ha, start);
732 	if (!addr) {
733 		addr = (void *)((uint8_t *)ha->nx_pcibase + start);
734 	}
735 
736 	switch (size) {
737 	case 1:
738 		WRT_REG_BYTE(ha, addr, *(uint8_t *)data);
739 		break;
740 	case 2:
741 		WRT_REG_WORD(ha, addr, *(uint16_t *)data);
742 		break;
743 	case 4:
744 		WRT_REG_DWORD(ha, addr, *(uint32_t *)data);
745 		break;
746 	case 8:
747 		WRT_REG_DDWORD(ha, addr, *(uint64_t *)data);
748 		break;
749 	default:
750 		EL(ha, "invalid size=%x\n", size);
751 		ret = -1;
752 		break;
753 	}
754 
755 	return (ret);
756 }
757 
758 static int
759 ql_8021_pci_mem_read_2M(ql_adapter_state_t *ha, uint64_t off, void *data,
760     uint32_t size)
761 {
762 	int		j = 0;
763 	uint32_t	i, temp, sz[2], loop, shift_amount;
764 	uint64_t	start, end, k;
765 	uint64_t	off8, off0[2], val, mem_crb, word[2] = {0, 0};
766 
767 	/*
768 	 * If not MN, go check for MS or invalid.
769 	 */
770 
771 	if (off >= UNM_ADDR_QDR_NET && off <= NX_P3_ADDR_QDR_NET_MAX) {
772 		mem_crb = UNM_CRB_QDR_NET;
773 	} else {
774 		mem_crb = UNM_CRB_DDR_NET;
775 		if (ql_8021_pci_mem_bound_check(ha, off, size) == 0) {
776 			return (ql_8021_pci_mem_read_direct(ha, off, data,
777 			    size));
778 		}
779 	}
780 
781 	if (NX_IS_REVISION_P3PLUS(ha->rev_id)) {
782 		off8 = off & 0xfffffff0;
783 		off0[0] = off & 0xf;
784 		sz[0] = (uint32_t)(((uint64_t)size < (16 - off0[0])) ? size :
785 		    (16 - off0[0]));
786 		shift_amount = 4;
787 	} else {
788 		off8 = off & 0xfffffff8;
789 		off0[0] = off & 0x7;
790 		sz[0] = (uint32_t)(((uint64_t)size < (8 - off0[0])) ? size :
791 		    (8 - off0[0]));
792 		shift_amount = 3;
793 	}
794 	loop = (uint32_t)(((off0[0] + size - 1) >> shift_amount) + 1);
795 	off0[1] = 0;
796 	sz[1] = size - sz[0];
797 
798 	/*
799 	 * don't lock here - write_wx gets the lock if each time
800 	 * write_lock_irqsave(&adapter->adapter_lock, flags);
801 	 * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
802 	 */
803 
804 	for (i = 0; i < loop; i++) {
805 		temp = (uint32_t)(off8 + (i << shift_amount));
806 		ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);
807 		temp = 0;
808 		ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_HI, temp);
809 		temp = MIU_TA_CTL_ENABLE;
810 		ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
811 		temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;
812 		ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
813 
814 		for (j = 0; j < MAX_CTL_CHECK; j++) {
815 			ql_8021_rd_32(ha, mem_crb + MIU_TEST_AGT_CTRL, &temp);
816 			if ((temp & MIU_TA_CTL_BUSY) == 0) {
817 				break;
818 			}
819 		}
820 
821 		if (j >= MAX_CTL_CHECK) {
822 			EL(ha, "failed to read through agent\n");
823 			break;
824 		}
825 
826 		start = off0[i] >> 2;
827 		end = (off0[i] + sz[i] - 1) >> 2;
828 		for (k = start; k <= end; k++) {
829 			ql_8021_rd_32(ha, mem_crb + MIU_TEST_AGT_RDDATA(k),
830 			    &temp);
831 			word[i] |= ((uint64_t)temp << (32 * (k & 1)));
832 		}
833 	}
834 
835 	/*
836 	 * netxen_nic_pci_change_crbwindow_128M(adapter, 1);
837 	 * write_unlock_irqrestore(&adapter->adapter_lock, flags);
838 	 */
839 
840 	if (j >= MAX_CTL_CHECK) {
841 		return (-1);
842 	}
843 
844 	if ((off0[0] & 7) == 0) {
845 		val = word[0];
846 	} else {
847 		val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
848 		    ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
849 	}
850 
851 	switch (size) {
852 	case 1:
853 		*(uint8_t *)data = (uint8_t)val;
854 		break;
855 	case 2:
856 		*(uint16_t *)data = (uint16_t)val;
857 		break;
858 	case 4:
859 		*(uint32_t *)data = (uint32_t)val;
860 		break;
861 	case 8:
862 		*(uint64_t *)data = val;
863 		break;
864 	}
865 
866 	return (0);
867 }
868 
869 static int
870 ql_8021_pci_mem_write_2M(ql_adapter_state_t *ha, uint64_t off, void *data,
871     uint32_t size)
872 {
873 	int		j, ret = 0;
874 	uint32_t	i, temp, loop, sz[2];
875 	uint32_t	scale, shift_amount, p3p, startword;
876 	uint64_t	off8, off0, mem_crb, tmpw, word[2] = {0, 0};
877 
878 	/*
879 	 * If not MN, go check for MS or invalid.
880 	 */
881 	if (off >= UNM_ADDR_QDR_NET && off <= NX_P3_ADDR_QDR_NET_MAX) {
882 		mem_crb = UNM_CRB_QDR_NET;
883 	} else {
884 		mem_crb = UNM_CRB_DDR_NET;
885 		if (ql_8021_pci_mem_bound_check(ha, off, size) == 0) {
886 			return (ql_8021_pci_mem_write_direct(ha, off, data,
887 			    size));
888 		}
889 	}
890 
891 	off0 = off & 0x7;
892 	sz[0] = (uint32_t)(((uint64_t)size < (8 - off0)) ? size : (8 - off0));
893 	sz[1] = size - sz[0];
894 
895 	if (NX_IS_REVISION_P3PLUS(ha->rev_id)) {
896 		off8 = off & 0xfffffff0;
897 		loop = (uint32_t)((((off & 0xf) + size - 1) >> 4) + 1);
898 		shift_amount = 4;
899 		scale = 2;
900 		p3p = 1;
901 		startword = (uint32_t)((off & 0xf) / 8);
902 	} else {
903 		off8 = off & 0xfffffff8;
904 		loop = (uint32_t)(((off0 + size - 1) >> 3) + 1);
905 		shift_amount = 3;
906 		scale = 1;
907 		p3p = 0;
908 		startword = 0;
909 	}
910 
911 	if (p3p || (size != 8) || (off0 != 0)) {
912 		for (i = 0; i < loop; i++) {
913 			if (ql_8021_pci_mem_read_2M(ha, off8 +
914 			    (i << shift_amount), &word[i * scale], 8)) {
915 				EL(ha, "8021_pci_mem_read_2M != 0\n");
916 				return (-1);
917 			}
918 		}
919 	}
920 
921 	switch (size) {
922 	case 1:
923 		tmpw = (uint64_t)(*((uint8_t *)data));
924 		break;
925 	case 2:
926 		tmpw = (uint64_t)(*((uint16_t *)data));
927 		break;
928 	case 4:
929 		tmpw = (uint64_t)(*((uint32_t *)data));
930 		break;
931 	case 8:
932 	default:
933 		tmpw = *((uint64_t *)data);
934 		break;
935 	}
936 
937 	if (p3p) {
938 		if (sz[0] == 8) {
939 			word[startword] = tmpw;
940 		} else {
941 			word[startword] &= ~((~(~0ULL << (sz[0] * 8))) <<
942 			    (off0 * 8));
943 			word[startword] |= tmpw << (off0 * 8);
944 		}
945 		if (sz[1] != 0) {
946 			word[startword+1] &= ~(~0ULL << (sz[1] * 8));
947 			word[startword+1] |= tmpw >> (sz[0] * 8);
948 		}
949 	} else {
950 		word[startword] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
951 		word[startword] |= tmpw << (off0 * 8);
952 
953 		if (loop == 2) {
954 			word[1] &= ~(~0ULL << (sz[1] * 8));
955 			word[1] |= tmpw >> (sz[0] * 8);
956 		}
957 	}
958 
959 	/*
960 	 * don't lock here - write_wx gets the lock if each time
961 	 * write_lock_irqsave(&adapter->adapter_lock, flags);
962 	 * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
963 	 */
964 
965 	for (i = 0; i < loop; i++) {
966 		temp = (uint32_t)(off8 + (i << shift_amount));
967 		ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);
968 		temp = 0;
969 		ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_ADDR_HI, temp);
970 		temp = (uint32_t)(word[i * scale] & 0xffffffff);
971 		ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_WRDATA_LO, temp);
972 		temp = (uint32_t)((word[i * scale] >> 32) & 0xffffffff);
973 		ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_WRDATA_HI, temp);
974 		if (p3p) {
975 			temp = (uint32_t)(word[i * scale + 1] & 0xffffffff);
976 			ql_8021_wr_32(ha,
977 			    mem_crb + MIU_TEST_AGT_WRDATA_UPPER_LO, temp);
978 			temp = (uint32_t)((word[i * scale + 1] >> 32) &
979 			    0xffffffff);
980 			ql_8021_wr_32(ha,
981 			    mem_crb + MIU_TEST_AGT_WRDATA_UPPER_HI, temp);
982 		}
983 		temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
984 		ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
985 		temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
986 		ql_8021_wr_32(ha, mem_crb + MIU_TEST_AGT_CTRL, temp);
987 
988 		for (j = 0; j < MAX_CTL_CHECK; j++) {
989 			ql_8021_rd_32(ha, mem_crb + MIU_TEST_AGT_CTRL, &temp);
990 			if ((temp & MIU_TA_CTL_BUSY) == 0)
991 				break;
992 		}
993 
994 		if (j >= MAX_CTL_CHECK) {
995 			EL(ha, "failed to write through agent\n");
996 			ret = -1;
997 			break;
998 		}
999 	}
1000 
1001 	return (ret);
1002 }
1003 
1004 static uint32_t
1005 ql_8021_decode_crb_addr(ql_adapter_state_t *ha, uint32_t addr)
1006 {
1007 	int		i;
1008 	uint32_t	base_addr, offset, pci_base;
1009 
1010 	if (!crb_table_initialized) {
1011 		ql_crb_addr_transform_setup(ha);
1012 	}
1013 
1014 	pci_base = ADDR_ERROR;
1015 	base_addr = addr & 0xfff00000;
1016 	offset = addr & 0x000fffff;
1017 
1018 	for (i = 0; i < MAX_CRB_XFORM; i++) {
1019 		if (crb_addr_xform[i] == base_addr) {
1020 			pci_base = i << 20;
1021 			break;
1022 		}
1023 	}
1024 	if (pci_base == ADDR_ERROR) {
1025 		return (pci_base);
1026 	} else {
1027 		return (pci_base + offset);
1028 	}
1029 }
1030 
1031 static int
1032 ql_8021_hw_lock(ql_adapter_state_t *ha, uint32_t timer)
1033 {
1034 	uint32_t	done = 0, timeout = 0;
1035 
1036 	while (!done) {
1037 		/* acquire semaphore5 from PCI HW block */
1038 		ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM5_LOCK), &done);
1039 		if (done == 1) {
1040 			break;
1041 		}
1042 		if (timeout >= timer) {
1043 			EL(ha, "timeout\n");
1044 			return (-1);
1045 		}
1046 		timeout++;
1047 
1048 		/*
1049 		 * Yield CPU
1050 		 */
1051 		delay(1);
1052 	}
1053 
1054 	return (0);
1055 }
1056 
1057 static void
1058 ql_8021_hw_unlock(ql_adapter_state_t *ha)
1059 {
1060 	ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM5_UNLOCK), NULL);
1061 }
1062 
1063 static int
1064 ql_8021_rom_lock(ql_adapter_state_t *ha)
1065 {
1066 	uint32_t	done = 0, timeout = 0;
1067 
1068 	while (!done) {
1069 		/* acquire semaphore2 from PCI HW block */
1070 		ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM2_LOCK), &done);
1071 		if (done == 1) {
1072 			break;
1073 		}
1074 		if (timeout >= ROM_LOCK_TIMEOUT) {
1075 			EL(ha, "timeout\n");
1076 			return (-1);
1077 		}
1078 		timeout++;
1079 
1080 		/*
1081 		 * Yield CPU
1082 		 */
1083 		delay(1);
1084 	}
1085 	ql_8021_wr_32(ha, UNM_ROM_LOCK_ID, ROM_LOCK_DRIVER);
1086 
1087 	return (0);
1088 }
1089 
1090 static void
1091 ql_8021_rom_unlock(ql_adapter_state_t *ha)
1092 {
1093 	ql_8021_rd_32(ha, UNM_PCIE_REG(PCIE_SEM2_UNLOCK), NULL);
1094 }
1095 
1096 static int
1097 ql_8021_wait_rom_done(ql_adapter_state_t *ha)
1098 {
1099 	uint32_t	timeout = 0, done = 0;
1100 
1101 	while (done == 0) {
1102 		ql_8021_rd_32(ha, UNM_ROMUSB_GLB_STATUS, &done);
1103 		done &= 2;
1104 		timeout++;
1105 		if (timeout >= ROM_MAX_TIMEOUT) {
1106 			EL(ha, "Timeout reached waiting for rom done\n");
1107 			return (-1);
1108 		}
1109 	}
1110 
1111 	return (0);
1112 }
1113 
1114 static int
1115 ql_8021_wait_flash_done(ql_adapter_state_t *ha)
1116 {
1117 	clock_t		timer;
1118 	uint32_t	status;
1119 
1120 	for (timer = 30 * drv_usectohz(1000000); timer; timer--) {
1121 		ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1122 		ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1123 		    UNM_ROMUSB_ROM_RDSR_INSTR);
1124 		if (ql_8021_wait_rom_done(ha)) {
1125 			EL(ha, "Error waiting for rom done2\n");
1126 			return (-1);
1127 		}
1128 
1129 		/* Get status. */
1130 		ql_8021_rd_32(ha, UNM_ROMUSB_ROM_RDATA, &status);
1131 		if (!(status & BIT_0)) {
1132 			return (0);
1133 		}
1134 		delay(1);
1135 	}
1136 
1137 	EL(ha, "timeout status=%x\n", status);
1138 	return (-1);
1139 }
1140 
1141 static int
1142 ql_8021_do_rom_fast_read(ql_adapter_state_t *ha, uint32_t addr, uint32_t *valp)
1143 {
1144 	ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ADDRESS, addr);
1145 	ql_8021_wr_32(ha, UNM_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
1146 	ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 3);
1147 	ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1148 	    UNM_ROMUSB_ROM_FAST_RD_INSTR);
1149 	if (ql_8021_wait_rom_done(ha)) {
1150 		EL(ha, "Error waiting for rom done\n");
1151 		return (-1);
1152 	}
1153 	/* reset abyte_cnt and dummy_byte_cnt */
1154 	ql_8021_wr_32(ha, UNM_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
1155 	drv_usecwait(10);
1156 	ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1157 
1158 	ql_8021_rd_32(ha, UNM_ROMUSB_ROM_RDATA, valp);
1159 
1160 	return (0);
1161 }
1162 
1163 int
1164 ql_8021_rom_fast_read(ql_adapter_state_t *ha, uint32_t addr, uint32_t *valp)
1165 {
1166 	int	ret, loops = 0;
1167 
1168 	while ((ql_8021_rom_lock(ha) != 0) && (loops < 50000)) {
1169 		drv_usecwait(100);
1170 		loops++;
1171 	}
1172 	if (loops >= 50000) {
1173 		EL(ha, "rom_lock failed\n");
1174 		return (-1);
1175 	}
1176 	ret = ql_8021_do_rom_fast_read(ha, addr, valp);
1177 	ql_8021_rom_unlock(ha);
1178 
1179 	return (ret);
1180 }
1181 
1182 static int
1183 ql_8021_do_rom_write(ql_adapter_state_t *ha, uint32_t addr, uint32_t data)
1184 {
1185 	ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1186 	ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1187 	    UNM_ROMUSB_ROM_WREN_INSTR);
1188 	if (ql_8021_wait_rom_done(ha)) {
1189 		EL(ha, "Error waiting for rom done\n");
1190 		return (-1);
1191 	}
1192 
1193 	ql_8021_wr_32(ha, UNM_ROMUSB_ROM_WDATA, data);
1194 	ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ADDRESS, addr);
1195 	ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 3);
1196 	ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1197 	    UNM_ROMUSB_ROM_PP_INSTR);
1198 	if (ql_8021_wait_rom_done(ha)) {
1199 		EL(ha, "Error waiting for rom done1\n");
1200 		return (-1);
1201 	}
1202 
1203 	if (ql_8021_wait_flash_done(ha)) {
1204 		EL(ha, "Error waiting for flash done\n");
1205 		return (-1);
1206 	}
1207 
1208 	return (0);
1209 }
1210 
1211 static int
1212 ql_8021_do_rom_erase(ql_adapter_state_t *ha, uint32_t addr)
1213 {
1214 	ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1215 	ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1216 	    UNM_ROMUSB_ROM_WREN_INSTR);
1217 	if (ql_8021_wait_rom_done(ha)) {
1218 		EL(ha, "Error waiting for rom done\n");
1219 		return (-1);
1220 	}
1221 
1222 	ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ADDRESS, addr);
1223 	ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 3);
1224 	ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1225 	    UNM_ROMUSB_ROM_SE_INSTR);
1226 	if (ql_8021_wait_rom_done(ha)) {
1227 		EL(ha, "Error waiting for rom done1\n");
1228 		return (-1);
1229 	}
1230 
1231 	if (ql_8021_wait_flash_done(ha)) {
1232 		EL(ha, "Error waiting for flash done\n");
1233 		return (-1);
1234 	}
1235 
1236 	return (0);
1237 }
1238 
1239 int
1240 ql_8021_rom_read(ql_adapter_state_t *ha, uint32_t addr, uint32_t *bp)
1241 {
1242 	int	ret;
1243 
1244 	ret = ql_8021_rom_fast_read(ha, addr << 2, bp) == 0 ? QL_SUCCESS :
1245 	    QL_FUNCTION_FAILED;
1246 
1247 	return (ret);
1248 }
1249 
1250 int
1251 ql_8021_rom_write(ql_adapter_state_t *ha, uint32_t addr, uint32_t data)
1252 {
1253 	int	ret, loops = 0;
1254 
1255 	while ((ql_8021_rom_lock(ha) != 0) && (loops < 50000)) {
1256 		drv_usecwait(100);
1257 		loops++;
1258 	}
1259 	if (loops >= 50000) {
1260 		EL(ha, "rom_lock failed\n");
1261 		ret = QL_FUNCTION_TIMEOUT;
1262 	} else {
1263 		ret = ql_8021_do_rom_write(ha, addr << 2, data) == 0 ?
1264 		    QL_SUCCESS : QL_FUNCTION_FAILED;
1265 		ql_8021_rom_unlock(ha);
1266 	}
1267 
1268 	return (ret);
1269 }
1270 
1271 int
1272 ql_8021_rom_erase(ql_adapter_state_t *ha, uint32_t addr)
1273 {
1274 	int	ret, loops = 0;
1275 
1276 	while ((ql_8021_rom_lock(ha) != 0) && (loops < 50000)) {
1277 		drv_usecwait(100);
1278 		loops++;
1279 	}
1280 	if (loops >= 50000) {
1281 		EL(ha, "rom_lock failed\n");
1282 		ret = QL_FUNCTION_TIMEOUT;
1283 	} else {
1284 		ret = ql_8021_do_rom_erase(ha, addr << 2) == 0 ? QL_SUCCESS :
1285 		    QL_FUNCTION_FAILED;
1286 		ql_8021_rom_unlock(ha);
1287 	}
1288 
1289 	return (ret);
1290 }
1291 
1292 int
1293 ql_8021_rom_wrsr(ql_adapter_state_t *ha, uint32_t data)
1294 {
1295 	int	ret = QL_SUCCESS, loops = 0;
1296 
1297 	while ((ql_8021_rom_lock(ha) != 0) && (loops < 50000)) {
1298 		drv_usecwait(100);
1299 		loops++;
1300 	}
1301 	if (loops >= 50000) {
1302 		EL(ha, "rom_lock failed\n");
1303 		ret = QL_FUNCTION_TIMEOUT;
1304 	} else {
1305 		ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1306 		ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1307 		    UNM_ROMUSB_ROM_WREN_INSTR);
1308 		if (ql_8021_wait_rom_done(ha)) {
1309 			EL(ha, "Error waiting for rom done\n");
1310 			ret = QL_FUNCTION_FAILED;
1311 		} else {
1312 			ql_8021_wr_32(ha, UNM_ROMUSB_ROM_WDATA, data);
1313 			ql_8021_wr_32(ha, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
1314 			ql_8021_wr_32(ha, UNM_ROMUSB_ROM_INSTR_OPCODE,
1315 			    UNM_ROMUSB_ROM_WRSR_INSTR);
1316 			if (ql_8021_wait_rom_done(ha)) {
1317 				EL(ha, "Error waiting for rom done1\n");
1318 				ret = QL_FUNCTION_FAILED;
1319 			} else if (ql_8021_wait_flash_done(ha)) {
1320 				EL(ha, "Error waiting for flash done\n");
1321 				ret = QL_FUNCTION_FAILED;
1322 			}
1323 		}
1324 		ql_8021_rom_unlock(ha);
1325 	}
1326 
1327 	return (ret);
1328 }
1329 
1330 static int
1331 ql_8021_phantom_init(ql_adapter_state_t *ha)
1332 {
1333 	uint32_t	val = 0, err = 0;
1334 	int		retries = 60;
1335 
1336 	do {
1337 		ql_8021_rd_32(ha, CRB_CMDPEG_STATE, &val);
1338 
1339 		switch (val) {
1340 		case PHAN_INITIALIZE_COMPLETE:
1341 		case PHAN_INITIALIZE_ACK:
1342 			EL(ha, "success=%xh\n", val);
1343 			return (0);
1344 		case PHAN_INITIALIZE_FAILED:
1345 			EL(ha, "PHAN_INITIALIZE_FAILED\n");
1346 			err = 1;
1347 			break;
1348 		default:
1349 			break;
1350 		}
1351 
1352 		if (err) {
1353 			break;
1354 		}
1355 		/* 500 msec wait */
1356 		delay(50);
1357 
1358 	} while (--retries);
1359 
1360 	if (!err) {
1361 		ql_8021_wr_32(ha, CRB_CMDPEG_STATE, PHAN_INITIALIZE_FAILED);
1362 	}
1363 
1364 	EL(ha, "firmware init failed=%x\n", val);
1365 	return (-1);
1366 }
1367 
1368 static int
1369 ql_8021_pinit_from_rom(ql_adapter_state_t *ha)
1370 {
1371 	int			init_delay = 0;
1372 	struct crb_addr_pair	*buf;
1373 	uint32_t		offset, off, i, n, addr, val;
1374 
1375 	/* Grab the lock so that no one can read flash when we reset the chip */
1376 	(void) ql_8021_rom_lock(ha);
1377 	ql_8021_wr_32(ha, UNM_ROMUSB_GLB_SW_RESET, 0xffffffff);
1378 	/* Just in case it was held when we reset the chip */
1379 	ql_8021_rom_unlock(ha);
1380 
1381 	if (ql_8021_rom_fast_read(ha, 0, &n) != 0 || n != 0xcafecafe ||
1382 	    ql_8021_rom_fast_read(ha, 4, &n) != 0) {
1383 		EL(ha, "ERROR Reading crb_init area: n: %08x\n", n);
1384 		return (-1);
1385 	}
1386 	offset = n & 0xffff;
1387 	n = (n >> 16) & 0xffff;
1388 	if (n >= 1024) {
1389 		EL(ha, "n=0x%x Error! NetXen card flash not initialized\n", n);
1390 		return (-1);
1391 	}
1392 
1393 	buf = kmem_zalloc(n * sizeof (struct crb_addr_pair), KM_SLEEP);
1394 	if (buf == NULL) {
1395 		EL(ha, "Unable to zalloc memory\n");
1396 		return (-1);
1397 	}
1398 
1399 	for (i = 0; i < n; i++) {
1400 		if (ql_8021_rom_fast_read(ha, 8 * i + 4 * offset, &val) != 0 ||
1401 		    ql_8021_rom_fast_read(ha, 8 * i + 4 * offset + 4, &addr) !=
1402 		    0) {
1403 			kmem_free(buf, n * sizeof (struct crb_addr_pair));
1404 			EL(ha, "ql_8021_rom_fast_read != 0 to zalloc memory\n");
1405 			return (-1);
1406 		}
1407 
1408 		buf[i].addr = addr;
1409 		buf[i].data = val;
1410 	}
1411 
1412 	for (i = 0; i < n; i++) {
1413 		off = ql_8021_decode_crb_addr(ha, buf[i].addr);
1414 		if (off == ADDR_ERROR) {
1415 			EL(ha, "Err: Unknown addr: 0x%lx\n", buf[i].addr);
1416 			continue;
1417 		}
1418 		off += UNM_PCI_CRBSPACE;
1419 
1420 		if (off & 1) {
1421 			continue;
1422 		}
1423 
1424 		/* skipping cold reboot MAGIC */
1425 		if (off == UNM_RAM_COLD_BOOT) {
1426 			continue;
1427 		}
1428 		if (off == (UNM_CRB_I2C0 + 0x1c)) {
1429 			continue;
1430 		}
1431 		/* do not reset PCI */
1432 		if (off == (ROMUSB_GLB + 0xbc)) {
1433 			continue;
1434 		}
1435 		if (off == (ROMUSB_GLB + 0xa8)) {
1436 			continue;
1437 		}
1438 		if (off == (ROMUSB_GLB + 0xc8)) {	/* core clock */
1439 			continue;
1440 		}
1441 		if (off == (ROMUSB_GLB + 0x24)) {	/* MN clock */
1442 			continue;
1443 		}
1444 		if (off == (ROMUSB_GLB + 0x1c)) {	/* MS clock */
1445 			continue;
1446 		}
1447 		if ((off & 0x0ff00000) == UNM_CRB_DDR_NET) {
1448 			continue;
1449 		}
1450 		if (off == (UNM_CRB_PEG_NET_1 + 0x18) &&
1451 		    !NX_IS_REVISION_P3PLUS(ha->rev_id)) {
1452 			buf[i].data = 0x1020;
1453 		}
1454 		/* skip the function enable register */
1455 		if (off == UNM_PCIE_REG(PCIE_SETUP_FUNCTION)) {
1456 			continue;
1457 		}
1458 		if (off == UNM_PCIE_REG(PCIE_SETUP_FUNCTION2)) {
1459 			continue;
1460 		}
1461 		if ((off & 0x0ff00000) == UNM_CRB_SMB) {
1462 			continue;
1463 		}
1464 
1465 		/* After writing this register, HW needs time for CRB */
1466 		/* to quiet down (else crb_window returns 0xffffffff) */
1467 		init_delay = 1;
1468 		if (off == UNM_ROMUSB_GLB_SW_RESET) {
1469 			init_delay = 100;	/* Sleep 1000 msecs */
1470 		}
1471 
1472 		ql_8021_wr_32(ha, off, buf[i].data);
1473 
1474 		delay(init_delay);
1475 	}
1476 	kmem_free(buf, n * sizeof (struct crb_addr_pair));
1477 
1478 	/* disable_peg_cache_all */
1479 
1480 	/* p2dn replyCount */
1481 	ql_8021_wr_32(ha, UNM_CRB_PEG_NET_D + 0xec, 0x1e);
1482 	/* disable_peg_cache 0 */
1483 	ql_8021_wr_32(ha, UNM_CRB_PEG_NET_D + 0x4c, 8);
1484 	/* disable_peg_cache 1 */
1485 	ql_8021_wr_32(ha, UNM_CRB_PEG_NET_I + 0x4c, 8);
1486 
1487 	/* peg_clr_all */
1488 	/* peg_clr 0 */
1489 	ql_8021_wr_32(ha, UNM_CRB_PEG_NET_0 + 0x8, 0);
1490 	ql_8021_wr_32(ha, UNM_CRB_PEG_NET_0 + 0xc, 0);
1491 	/* peg_clr 1 */
1492 	ql_8021_wr_32(ha, UNM_CRB_PEG_NET_1 + 0x8, 0);
1493 	ql_8021_wr_32(ha, UNM_CRB_PEG_NET_1 + 0xc, 0);
1494 	/* peg_clr 2 */
1495 	ql_8021_wr_32(ha, UNM_CRB_PEG_NET_2 + 0x8, 0);
1496 	ql_8021_wr_32(ha, UNM_CRB_PEG_NET_2 + 0xc, 0);
1497 	/* peg_clr 3 */
1498 	ql_8021_wr_32(ha, UNM_CRB_PEG_NET_3 + 0x8, 0);
1499 	ql_8021_wr_32(ha, UNM_CRB_PEG_NET_3 + 0xc, 0);
1500 
1501 	return (0);
1502 }
1503 
1504 static int
1505 ql_8021_load_from_flash(ql_adapter_state_t *ha)
1506 {
1507 	int		i;
1508 	uint32_t	flashaddr, memaddr;
1509 	uint32_t	high, low, size;
1510 	uint64_t	data;
1511 
1512 	size = ha->bootloader_size / 2;
1513 	flashaddr = ha->bootloader_addr << 2;
1514 	memaddr = BOOTLD_START;
1515 
1516 	for (i = 0; i < size; i++) {
1517 		if ((ql_8021_rom_fast_read(ha, flashaddr, &low)) ||
1518 		    (ql_8021_rom_fast_read(ha, flashaddr + 4, &high))) {
1519 			EL(ha, "ql_8021_rom_fast_read != 0\n");
1520 			return (-1);
1521 		}
1522 		data = ((uint64_t)high << 32) | low;
1523 		(void) ql_8021_pci_mem_write_2M(ha, memaddr, &data, 8);
1524 		flashaddr += 8;
1525 		memaddr += 8;
1526 	}
1527 
1528 	size = ha->flash_fw_size / 2;
1529 	flashaddr = ha->flash_fw_addr << 2;
1530 	memaddr = IMAGE_START;
1531 
1532 	for (i = 0; i < size; i++) {
1533 		if ((ql_8021_rom_fast_read(ha, flashaddr, &low)) ||
1534 		    (ql_8021_rom_fast_read(ha, flashaddr + 4, &high))) {
1535 			EL(ha, "ql_8021_rom_fast_read3 != 0\n");
1536 			return (-1);
1537 		}
1538 		data = ((uint64_t)high << 32) | low;
1539 		(void) ql_8021_pci_mem_write_2M(ha, memaddr, &data, 8);
1540 		flashaddr += 8;
1541 		memaddr += 8;
1542 	}
1543 
1544 	return (0);
1545 }
1546 
1547 static int
1548 ql_8021_load_firmware(ql_adapter_state_t *ha)
1549 {
1550 	uint64_t	data;
1551 	uint32_t	i, flashaddr, size;
1552 	uint8_t		*bp, n, *dp;
1553 
1554 	bp = (uint8_t *)(ha->risc_fw[0].code);
1555 	dp = (uint8_t *)&size;
1556 	for (n = 0; n < 4; n++) {
1557 		dp[n] = *bp++;
1558 	}
1559 	LITTLE_ENDIAN_32(&size);
1560 	EL(ha, "signature=%x\n", size);
1561 
1562 	size = (IMAGE_START - BOOTLD_START) / 8;
1563 
1564 	bp = (uint8_t *)(ha->risc_fw[0].code + BOOTLD_START);
1565 	flashaddr = BOOTLD_START;
1566 
1567 	dp = (uint8_t *)&data;
1568 	for (i = 0; i < size; i++) {
1569 		for (n = 0; n < 8; n++) {
1570 			dp[n] = *bp++;
1571 		}
1572 		LITTLE_ENDIAN_64(&data);
1573 		(void) ql_8021_pci_mem_write_2M(ha, flashaddr, &data, 8);
1574 		flashaddr += 8;
1575 	}
1576 
1577 	bp = (uint8_t *)(ha->risc_fw[0].code + FW_SIZE_OFFSET);
1578 	dp = (uint8_t *)&size;
1579 	for (n = 0; n < 4; n++) {
1580 		dp[n] = *bp++;
1581 	}
1582 	LITTLE_ENDIAN_32(&size);
1583 	EL(ha, "IMAGE_START size=%llx\n", size);
1584 	size = (size + 7) / 8;
1585 
1586 	bp = (uint8_t *)(ha->risc_fw[0].code + IMAGE_START);
1587 	flashaddr = IMAGE_START;
1588 
1589 	dp = (uint8_t *)&data;
1590 	for (i = 0; i < size; i++) {
1591 		for (n = 0; n < 8; n++) {
1592 			dp[n] = *bp++;
1593 		}
1594 		LITTLE_ENDIAN_64(&data);
1595 		(void) ql_8021_pci_mem_write_2M(ha, flashaddr, &data, 8);
1596 		flashaddr += 8;
1597 	}
1598 
1599 	return (0);
1600 }
1601 
1602 static int
1603 ql_8021_init_p3p(ql_adapter_state_t *ha)
1604 {
1605 	uint32_t	data;
1606 
1607 	/* ??? */
1608 	ql_8021_wr_32(ha, UNM_PORT_MODE_ADDR, UNM_PORT_MODE_AUTO_NEG);
1609 	delay(drv_usectohz(1000000));
1610 
1611 	/* CAM RAM Cold Boot Register */
1612 	ql_8021_rd_32(ha, UNM_RAM_COLD_BOOT, &data);
1613 	if (data == 0x55555555) {
1614 		ql_8021_rd_32(ha, UNM_ROMUSB_GLB_SW_RESET, &data);
1615 		if (data != 0x80000f) {
1616 			EL(ha, "CRB_UNM_GLB_SW_RST=%x exit\n", data);
1617 			return (-1);
1618 		}
1619 		ql_8021_wr_32(ha, UNM_RAM_COLD_BOOT, 0);
1620 	}
1621 	ql_8021_rd_32(ha, UNM_ROMUSB_GLB_PEGTUNE_DONE, &data);
1622 	data |= 1;
1623 	ql_8021_wr_32(ha, UNM_ROMUSB_GLB_PEGTUNE_DONE, data);
1624 
1625 	/*
1626 	 * ???
1627 	 * data = ha->pci_bus_addr | BIT_31;
1628 	 * ql_8021_wr_32(ha, UNM_BUS_DEV_NO, data);
1629 	 */
1630 
1631 	return (0);
1632 }
1633 
1634 /* ARGSUSED */
1635 void
1636 ql_8021_reset_chip(ql_adapter_state_t *ha)
1637 {
1638 	/*
1639 	 * Disable interrupts does not work on a per function bases
1640 	 * leave them enabled
1641 	 */
1642 	ql_8021_enable_intrs(ha);
1643 
1644 	ADAPTER_STATE_LOCK(ha);
1645 	ha->flags |= INTERRUPTS_ENABLED;
1646 	ADAPTER_STATE_UNLOCK(ha);
1647 
1648 	(void) ql_stop_firmware(ha);
1649 }
1650 
1651 static int
1652 ql_8021_reset_hw(ql_adapter_state_t *ha, int type)
1653 {
1654 	int		ret;
1655 	uint32_t	rst;
1656 
1657 	/* scrub dma mask expansion register */
1658 	ql_8021_wr_32(ha, CRB_DMA_SHIFT, 0x55555555);
1659 
1660 	/* Overwrite stale initialization register values */
1661 	ql_8021_wr_32(ha, CRB_CMDPEG_STATE, 0);
1662 	ql_8021_wr_32(ha, CRB_RCVPEG_STATE, 0);
1663 	ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS1, 0);
1664 	ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS2, 0);
1665 
1666 	(void) ql_8021_pinit_from_rom(ha);
1667 	delay(1);
1668 
1669 	/* Bring QM and CAMRAM out of reset */
1670 	ql_8021_rd_32(ha, UNM_ROMUSB_GLB_SW_RESET, &rst);
1671 	rst &= ~((1 << 28) | (1 << 24));
1672 	ql_8021_wr_32(ha, UNM_ROMUSB_GLB_SW_RESET, rst);
1673 
1674 	switch (type) {
1675 	case 0:
1676 		ret = ql_8021_init_p3p(ha);
1677 		break;
1678 	case 1:
1679 		ret = ql_8021_load_from_flash(ha);
1680 		break;
1681 	case 2:
1682 		ret = ql_8021_load_firmware(ha);
1683 		break;
1684 	}
1685 	delay(1);
1686 
1687 	ql_8021_wr_32(ha, UNM_CRB_PEG_NET_0 + 0x18, 0x1020);
1688 	ql_8021_wr_32(ha, UNM_ROMUSB_GLB_SW_RESET, 0x80001e);
1689 
1690 	if (ret) {
1691 		EL(ha, "type=%d, ret=%d\n", type, ret);
1692 	} else {
1693 		ret = ql_8021_phantom_init(ha);
1694 	}
1695 	return (ret);
1696 }
1697 
1698 int
1699 ql_8021_load_risc(ql_adapter_state_t *ha)
1700 {
1701 	int		rv = 0;
1702 	static int	ql_8021_fw_loaded = 0;
1703 
1704 	GLOBAL_HW_LOCK();
1705 	if (!ql_8021_fw_loaded) {
1706 		if (ha->risc_fw[0].code) {
1707 			EL(ha, "from driver\n");
1708 			rv = ql_8021_reset_hw(ha, 2);
1709 		} else {
1710 			/*
1711 			 * BIOS method
1712 			 * ql_8021_reset_hw(ha, 0)
1713 			 */
1714 			EL(ha, "from flash\n");
1715 			rv = ql_8021_reset_hw(ha, 1);
1716 		}
1717 		if (rv == 0) {
1718 			ql_8021_fw_loaded = 1;
1719 
1720 			ql_8021_wr_32(ha, CRB_DMA_SHIFT, 0x55555555);
1721 			ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS1, 0x0);
1722 			ql_8021_wr_32(ha, UNM_PEG_HALT_STATUS2, 0x0);
1723 
1724 			GLOBAL_HW_UNLOCK();
1725 
1726 			ADAPTER_STATE_LOCK(ha);
1727 			ha->flags &= ~INTERRUPTS_ENABLED;
1728 			ADAPTER_STATE_UNLOCK(ha);
1729 
1730 			(void) ql_8021_enable_intrs(ha);
1731 
1732 			ADAPTER_STATE_LOCK(ha);
1733 			ha->flags |= INTERRUPTS_ENABLED;
1734 			ADAPTER_STATE_UNLOCK(ha);
1735 		} else {
1736 			GLOBAL_HW_UNLOCK();
1737 		}
1738 	} else {
1739 		GLOBAL_HW_UNLOCK();
1740 		EL(ha, "Firmware loaded by other function\n");
1741 	}
1742 
1743 	if (rv == 0) {
1744 		ql_8021_rd_32(ha, UNM_FW_VERSION_MAJOR, &ha->fw_major_version);
1745 		ql_8021_rd_32(ha, UNM_FW_VERSION_MINOR, &ha->fw_minor_version);
1746 		ql_8021_rd_32(ha, UNM_FW_VERSION_SUB, &ha->fw_subminor_version);
1747 		EL(ha, "fw v%d.%02d.%02d\n", ha->fw_major_version,
1748 		    ha->fw_minor_version, ha->fw_subminor_version);
1749 	} else {
1750 		EL(ha, "status = -1\n");
1751 		return (QL_FUNCTION_FAILED);
1752 	}
1753 
1754 	return (QL_SUCCESS);
1755 }
1756 
1757 void
1758 ql_8021_clr_hw_intr(ql_adapter_state_t *ha)
1759 {
1760 	ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xffffffff);
1761 	ql_8021_rd_32(ha, ISR_INT_VECTOR, NULL);
1762 	ql_8021_rd_32(ha, ISR_INT_VECTOR, NULL);
1763 }
1764 
1765 void
1766 ql_8021_clr_fw_intr(ql_adapter_state_t *ha)
1767 {
1768 	WRT32_IO_REG(ha, nx_risc_int, 0);
1769 	ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xfbff);
1770 }
1771 
1772 void
1773 ql_8021_enable_intrs(ql_adapter_state_t *ha)
1774 {
1775 	GLOBAL_HW_LOCK();
1776 	ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);
1777 	GLOBAL_HW_UNLOCK();
1778 	(void) ql_toggle_interrupt(ha, 1);
1779 }
1780 
1781 void
1782 ql_8021_disable_intrs(ql_adapter_state_t *ha)
1783 {
1784 	(void) ql_toggle_interrupt(ha, 0);
1785 	GLOBAL_HW_LOCK();
1786 	ql_8021_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0x0400);
1787 	GLOBAL_HW_UNLOCK();
1788 }
1789 
1790 void
1791 ql_8021_update_crb_int_ptr(ql_adapter_state_t *ha)
1792 {
1793 	struct legacy_intr_set	*nx_legacy_intr;
1794 
1795 	ha->qdr_sn_window = (uint32_t)-1;
1796 	ha->ddr_mn_window = (uint32_t)-1;
1797 	nx_legacy_intr = &legacy_intr[ha->function_number];
1798 
1799 	ha->nx_legacy_intr.int_vec_bit = nx_legacy_intr->int_vec_bit;
1800 	ha->nx_legacy_intr.tgt_status_reg = nx_legacy_intr->tgt_status_reg;
1801 	ha->nx_legacy_intr.tgt_mask_reg = nx_legacy_intr->tgt_mask_reg;
1802 	ha->nx_legacy_intr.pci_int_reg = nx_legacy_intr->pci_int_reg;
1803 }
1804 
1805 void
1806 ql_8021_set_drv_active(ql_adapter_state_t *ha)
1807 {
1808 	uint32_t	val;
1809 
1810 	if (ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT)) {
1811 		return;
1812 	}
1813 
1814 	ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &val);
1815 	if (val == 0xffffffff) {
1816 		val = (1 << (ha->function_number * 4));
1817 	} else {
1818 		val |= (1 << (ha->function_number * 4));
1819 	}
1820 	ql_8021_wr_32(ha, CRB_DRV_ACTIVE, val);
1821 
1822 	ql_8021_hw_unlock(ha);
1823 }
1824 
1825 void
1826 ql_8021_clr_drv_active(ql_adapter_state_t *ha)
1827 {
1828 	uint32_t	val;
1829 
1830 	if (ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT)) {
1831 		return;
1832 	}
1833 
1834 	ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &val);
1835 	val &= ~(1 << (ha->function_number * 4));
1836 	ql_8021_wr_32(ha, CRB_DRV_ACTIVE, val);
1837 
1838 	ql_8021_hw_unlock(ha);
1839 }
1840 
1841 static void
1842 ql_8021_need_reset_handler(ql_adapter_state_t *ha)
1843 {
1844 	uint32_t	drv_state, drv_active;
1845 	clock_t		timer;
1846 
1847 	(void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1848 
1849 	ql_8021_rd_32(ha, CRB_DRV_STATE, &drv_state);
1850 	drv_state |= (1 << (ha->function_number * 4));
1851 	ql_8021_wr_32(ha, CRB_DRV_STATE, drv_state);
1852 
1853 	ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &drv_active);
1854 
1855 	ql_8021_hw_unlock(ha);
1856 
1857 	for (timer = 30; timer && drv_state != drv_active; timer--) {
1858 		delay(100);
1859 
1860 		(void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1861 		ql_8021_rd_32(ha, CRB_DRV_STATE, &drv_state);
1862 		ql_8021_rd_32(ha, CRB_DRV_ACTIVE, &drv_active);
1863 		ql_8021_hw_unlock(ha);
1864 	}
1865 }
1866 
1867 uint32_t
1868 ql_8021_idc_handler(ql_adapter_state_t *ha)
1869 {
1870 	uint32_t	dev_state, drv_state, rval;
1871 	clock_t		timer;
1872 	ql_mbx_data_t	mr;
1873 	boolean_t	stalled = B_FALSE, lock = B_FALSE;
1874 
1875 	/* wait for 30 seconds for device to go ready */
1876 	timer = 30;
1877 	while (timer) {
1878 		if (lock == B_FALSE) {
1879 			(void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1880 			lock = B_TRUE;
1881 		}
1882 		ql_8021_rd_32(ha, CRB_DEV_STATE, &dev_state);
1883 
1884 		switch (dev_state) {
1885 		case 0xffffffff:
1886 		case NX_DEV_COLD:
1887 			EL(ha, "dev_state=NX_DEV_COLD\n");
1888 			rval = NX_DEV_COLD;
1889 			ql_8021_wr_32(ha, CRB_DEV_STATE, NX_DEV_INITIALIZING);
1890 			ql_8021_wr_32(ha, CRB_DRV_IDC_VERSION, NX_IDC_VERSION);
1891 			(void) ql_8021_hw_unlock(ha);
1892 			if (ql_get_fw_version(ha, &mr, 2) == QL_SUCCESS &&
1893 			    (mr.mb[1] | mr.mb[2] | mr.mb[3])) {
1894 				ql_8021_rd_32(ha, UNM_FW_VERSION_MAJOR,
1895 				    &ha->fw_major_version);
1896 				ql_8021_rd_32(ha, UNM_FW_VERSION_MINOR,
1897 				    &ha->fw_minor_version);
1898 				ql_8021_rd_32(ha, UNM_FW_VERSION_SUB,
1899 				    &ha->fw_subminor_version);
1900 				rval = NX_DEV_READY;
1901 			} else if (ql_8021_load_risc(ha) == QL_SUCCESS) {
1902 				rval = NX_DEV_READY;
1903 			}
1904 			(void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1905 			ql_8021_wr_32(ha, CRB_DEV_STATE, rval);
1906 			break;
1907 		case NX_DEV_READY:
1908 			rval = NX_DEV_READY;
1909 			timer = 0;
1910 			break;
1911 		case NX_DEV_FAILED:
1912 			EL(ha, "dev_state=NX_DEV_FAILED\n");
1913 			rval = NX_DEV_FAILED;
1914 			timer = 0;
1915 			break;
1916 
1917 		case NX_DEV_NEED_RESET:
1918 			EL(ha, "dev_state=NX_DEV_NEED_RESET\n");
1919 			rval = NX_DEV_NEED_RESET;
1920 			(void) ql_8021_hw_unlock(ha);
1921 			lock = B_FALSE;
1922 			if (ql_stall_driver(ha, 0) == QL_SUCCESS) {
1923 				stalled = B_TRUE;
1924 				ql_8021_need_reset_handler(ha);
1925 			}
1926 			break;
1927 
1928 		case NX_DEV_NEED_QUIESCENT:
1929 			EL(ha, "dev_state=NX_DEV_NEED_QUIESCENT\n");
1930 			(void) ql_8021_hw_unlock(ha);
1931 			lock = B_FALSE;
1932 			rval = ql_stall_driver(ha, 0);
1933 			if (rval == QL_SUCCESS) {
1934 				stalled = B_TRUE;
1935 				(void) ql_8021_hw_lock(ha, IDC_LOCK_TIMEOUT);
1936 				lock = B_TRUE;
1937 				ql_8021_rd_32(ha, CRB_DRV_STATE, &drv_state);
1938 				drv_state |=
1939 				    (2 << (ha->function_number * 4));
1940 				ql_8021_wr_32(ha, CRB_DRV_STATE, drv_state);
1941 			}
1942 			break;
1943 
1944 		case NX_DEV_INITIALIZING:
1945 			EL(ha, "dev_state=NX_DEV_INITIALIZING\n");
1946 			break;
1947 		case NX_DEV_QUIESCENT:
1948 			EL(ha, "dev_state=NX_DEV_QUIESCENT\n");
1949 			break;
1950 		default:
1951 			EL(ha, "dev_state=%x, default\n", dev_state);
1952 			break;
1953 		}
1954 		if (lock == B_TRUE) {
1955 			(void) ql_8021_hw_unlock(ha);
1956 			lock = B_FALSE;
1957 		}
1958 
1959 		if (timer) {
1960 			delay(100);
1961 			timer--;
1962 		}
1963 	}
1964 
1965 	if (stalled) {
1966 		ql_restart_driver(ha);
1967 	}
1968 	return (rval);
1969 }
1970