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