xref: /illumos-gate/usr/src/uts/common/io/ntxn/unm_nic_hw.c (revision bf5d9f18edeb77c14df996d367853599bdd43fd1)
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 2008 NetXen, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #include <sys/types.h>
28 #include <sys/conf.h>
29 #include <sys/debug.h>
30 #include <sys/stropts.h>
31 #include <sys/stream.h>
32 #include <sys/strlog.h>
33 #include <sys/kmem.h>
34 #include <sys/stat.h>
35 #include <sys/kstat.h>
36 #include <sys/vtrace.h>
37 #include <sys/dlpi.h>
38 #include <sys/strsun.h>
39 #include <sys/ethernet.h>
40 #include <sys/modctl.h>
41 #include <sys/errno.h>
42 #include <sys/dditypes.h>
43 #include <sys/ddi.h>
44 #include <sys/sunddi.h>
45 #include <sys/sysmacros.h>
46 
47 #include <sys/pci.h>
48 
49 #include "unm_nic.h"
50 #include "unm_nic_hw.h"
51 #include "nic_cmn.h"
52 #include "unm_brdcfg.h"
53 #include "driver_info.h"
54 
55 long unm_niu_gbe_phy_read(struct unm_adapter_s *,
56 		long reg, unm_crbword_t *readval);
57 
58 #define	MASK(n)			((1ULL<<(n))-1)
59 #define	MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff))
60 #define	OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) |	\
61 		((addr >> 25) & 0x3ff)) // 64K?
62 #define	MS_WIN(addr) (addr & 0x0ffc0000)
63 #define	UNM_PCI_MN_2M   (0)
64 #define	UNM_PCI_MS_2M   (0x80000)
65 #define	UNM_PCI_OCM0_2M (0xc0000)
66 #define	VALID_OCM_ADDR(addr) (((addr) & 0x3f800) != 0x3f800)
67 #define	GET_MEM_OFFS_2M(addr) (addr & MASK(18))
68 
69 #define	CRB_BLK(off)	((off >> 20) & 0x3f)
70 #define	CRB_SUBBLK(off)	((off >> 16) & 0xf)
71 #define	CRB_WINDOW_2M	(0x130060)
72 #define	UNM_PCI_CAMQM_2M_END	(0x04800800UL)
73 #define	CRB_HI(off)	((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000))
74 #define	UNM_PCI_CAMQM_2M_BASE	(0x000ff800UL)
75 #define	CRB_INDIRECT_2M	(0x1e0000UL)
76 
77 static crb_128M_2M_block_map_t	crb_128M_2M_map[64] = {
78 	    {{{0, 0, 0, 0}}}, /* 0: PCI */
79 	    {{{1, 0x0100000, 0x0102000, 0x120000}, /* 1: PCIE */
80 	    {1, 0x0110000, 0x0120000, 0x130000},
81 	    {1, 0x0120000, 0x0122000, 0x124000},
82 	    {1, 0x0130000, 0x0132000, 0x126000},
83 	    {1, 0x0140000, 0x0142000, 0x128000},
84 	    {1, 0x0150000, 0x0152000, 0x12a000},
85 	    {1, 0x0160000, 0x0170000, 0x110000},
86 	    {1, 0x0170000, 0x0172000, 0x12e000},
87 	    {0, 0x0000000, 0x0000000, 0x000000},
88 	    {0, 0x0000000, 0x0000000, 0x000000},
89 	    {0, 0x0000000, 0x0000000, 0x000000},
90 	    {0, 0x0000000, 0x0000000, 0x000000},
91 	    {0, 0x0000000, 0x0000000, 0x000000},
92 	    {0, 0x0000000, 0x0000000, 0x000000},
93 	    {1, 0x01e0000, 0x01e0800, 0x122000},
94 	    {0, 0x0000000, 0x0000000, 0x000000}}},
95 	    {{{1, 0x0200000, 0x0210000, 0x180000}}}, /* 2: MN */
96 	    {{{0, 0, 0, 0}}}, /* 3: */
97 	    {{{1, 0x0400000, 0x0401000, 0x169000}}}, /* 4: P2NR1 */
98 	    {{{1, 0x0500000, 0x0510000, 0x140000}}}, /* 5: SRE   */
99 	    {{{1, 0x0600000, 0x0610000, 0x1c0000}}}, /* 6: NIU   */
100 	    {{{1, 0x0700000, 0x0704000, 0x1b8000}}}, /* 7: QM    */
101 	    {{{1, 0x0800000, 0x0802000, 0x170000}, /* 8: SQM0  */
102 	    {0, 0x0000000, 0x0000000, 0x000000},
103 	    {0, 0x0000000, 0x0000000, 0x000000},
104 	    {0, 0x0000000, 0x0000000, 0x000000},
105 	    {0, 0x0000000, 0x0000000, 0x000000},
106 	    {0, 0x0000000, 0x0000000, 0x000000},
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 	    {0, 0x0000000, 0x0000000, 0x000000},
114 	    {0, 0x0000000, 0x0000000, 0x000000},
115 	    {0, 0x0000000, 0x0000000, 0x000000},
116 	    {1, 0x08f0000, 0x08f2000, 0x172000}}},
117 	    {{{1, 0x0900000, 0x0902000, 0x174000}, /* 9: SQM1 */
118 	    {0, 0x0000000, 0x0000000, 0x000000},
119 	    {0, 0x0000000, 0x0000000, 0x000000},
120 	    {0, 0x0000000, 0x0000000, 0x000000},
121 	    {0, 0x0000000, 0x0000000, 0x000000},
122 	    {0, 0x0000000, 0x0000000, 0x000000},
123 	    {0, 0x0000000, 0x0000000, 0x000000},
124 	    {0, 0x0000000, 0x0000000, 0x000000},
125 	    {0, 0x0000000, 0x0000000, 0x000000},
126 	    {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 	    {1, 0x09f0000, 0x09f2000, 0x176000}}},
133 	    {{{0, 0x0a00000, 0x0a02000, 0x178000}, /* 10: SQM2 */
134 	    {0, 0x0000000, 0x0000000, 0x000000},
135 	    {0, 0x0000000, 0x0000000, 0x000000},
136 	    {0, 0x0000000, 0x0000000, 0x000000},
137 	    {0, 0x0000000, 0x0000000, 0x000000},
138 	    {0, 0x0000000, 0x0000000, 0x000000},
139 	    {0, 0x0000000, 0x0000000, 0x000000},
140 	    {0, 0x0000000, 0x0000000, 0x000000},
141 	    {0, 0x0000000, 0x0000000, 0x000000},
142 	    {0, 0x0000000, 0x0000000, 0x000000},
143 	    {0, 0x0000000, 0x0000000, 0x000000},
144 	    {0, 0x0000000, 0x0000000, 0x000000},
145 	    {0, 0x0000000, 0x0000000, 0x000000},
146 	    {0, 0x0000000, 0x0000000, 0x000000},
147 	    {0, 0x0000000, 0x0000000, 0x000000},
148 	    {1, 0x0af0000, 0x0af2000, 0x17a000}}},
149 	    {{{0, 0x0b00000, 0x0b02000, 0x17c000}, /* 11: SQM3 */
150 	    {0, 0x0000000, 0x0000000, 0x000000},
151 	    {0, 0x0000000, 0x0000000, 0x000000},
152 	    {0, 0x0000000, 0x0000000, 0x000000},
153 	    {0, 0x0000000, 0x0000000, 0x000000},
154 	    {0, 0x0000000, 0x0000000, 0x000000},
155 	    {0, 0x0000000, 0x0000000, 0x000000},
156 	    {0, 0x0000000, 0x0000000, 0x000000},
157 	    {0, 0x0000000, 0x0000000, 0x000000},
158 	    {0, 0x0000000, 0x0000000, 0x000000},
159 	    {0, 0x0000000, 0x0000000, 0x000000},
160 	    {0, 0x0000000, 0x0000000, 0x000000},
161 	    {0, 0x0000000, 0x0000000, 0x000000},
162 	    {0, 0x0000000, 0x0000000, 0x000000},
163 	    {0, 0x0000000, 0x0000000, 0x000000},
164 	    {1, 0x0bf0000, 0x0bf2000, 0x17e000}}},
165 	    {{{1, 0x0c00000, 0x0c04000, 0x1d4000}}}, /* 12: I2Q */
166 	    {{{1, 0x0d00000, 0x0d04000, 0x1a4000}}}, /* 13: TMR */
167 	    {{{1, 0x0e00000, 0x0e04000, 0x1a0000}}}, /* 14: ROMUSB */
168 	    {{{1, 0x0f00000, 0x0f01000, 0x164000}}}, /* 15: PEG4 */
169 	    {{{0, 0x1000000, 0x1004000, 0x1a8000}}}, /* 16: XDMA */
170 	    {{{1, 0x1100000, 0x1101000, 0x160000}}}, /* 17: PEG0 */
171 	    {{{1, 0x1200000, 0x1201000, 0x161000}}}, /* 18: PEG1 */
172 	    {{{1, 0x1300000, 0x1301000, 0x162000}}}, /* 19: PEG2 */
173 	    {{{1, 0x1400000, 0x1401000, 0x163000}}}, /* 20: PEG3 */
174 	    {{{1, 0x1500000, 0x1501000, 0x165000}}}, /* 21: P2ND */
175 	    {{{1, 0x1600000, 0x1601000, 0x166000}}}, /* 22: P2NI */
176 	    {{{0, 0, 0, 0}}}, /* 23: */
177 	    {{{0, 0, 0, 0}}}, /* 24: */
178 	    {{{0, 0, 0, 0}}}, /* 25: */
179 	    {{{0, 0, 0, 0}}}, /* 26: */
180 	    {{{0, 0, 0, 0}}}, /* 27: */
181 	    {{{0, 0, 0, 0}}}, /* 28: */
182 	    {{{1, 0x1d00000, 0x1d10000, 0x190000}}}, /* 29: MS */
183 	    {{{1, 0x1e00000, 0x1e01000, 0x16a000}}}, /* 30: P2NR2 */
184 	    {{{1, 0x1f00000, 0x1f10000, 0x150000}}}, /* 31: EPG */
185 	    {{{0}}}, /* 32: PCI */
186 	    {{{1, 0x2100000, 0x2102000, 0x120000}, /* 33: PCIE */
187 	    {1, 0x2110000, 0x2120000, 0x130000},
188 	    {1, 0x2120000, 0x2122000, 0x124000},
189 	    {1, 0x2130000, 0x2132000, 0x126000},
190 	    {1, 0x2140000, 0x2142000, 0x128000},
191 	    {1, 0x2150000, 0x2152000, 0x12a000},
192 	    {1, 0x2160000, 0x2170000, 0x110000},
193 	    {1, 0x2170000, 0x2172000, 0x12e000},
194 	    {0, 0x0000000, 0x0000000, 0x000000},
195 	    {0, 0x0000000, 0x0000000, 0x000000},
196 	    {0, 0x0000000, 0x0000000, 0x000000},
197 	    {0, 0x0000000, 0x0000000, 0x000000},
198 	    {0, 0x0000000, 0x0000000, 0x000000},
199 	    {0, 0x0000000, 0x0000000, 0x000000},
200 	    {0, 0x0000000, 0x0000000, 0x000000},
201 	    {0, 0x0000000, 0x0000000, 0x000000}}},
202 	    {{{1, 0x2200000, 0x2204000, 0x1b0000}}}, /* 34: CAM */
203 	    {{{0}}}, /* 35: */
204 	    {{{0}}}, /* 36: */
205 	    {{{0}}}, /* 37: */
206 	    {{{0}}}, /* 38: */
207 	    {{{0}}}, /* 39: */
208 	    {{{1, 0x2800000, 0x2804000, 0x1a4000}}}, /* 40: TMR */
209 	    {{{1, 0x2900000, 0x2901000, 0x16b000}}}, /* 41: P2NR3 */
210 	    {{{1, 0x2a00000, 0x2a00400, 0x1ac400}}}, /* 42: RPMX1 */
211 	    {{{1, 0x2b00000, 0x2b00400, 0x1ac800}}}, /* 43: RPMX2 */
212 	    {{{1, 0x2c00000, 0x2c00400, 0x1acc00}}}, /* 44: RPMX3 */
213 	    {{{1, 0x2d00000, 0x2d00400, 0x1ad000}}}, /* 45: RPMX4 */
214 	    {{{1, 0x2e00000, 0x2e00400, 0x1ad400}}}, /* 46: RPMX5 */
215 	    {{{1, 0x2f00000, 0x2f00400, 0x1ad800}}}, /* 47: RPMX6 */
216 	    {{{1, 0x3000000, 0x3000400, 0x1adc00}}}, /* 48: RPMX7 */
217 	    {{{0, 0x3100000, 0x3104000, 0x1a8000}}}, /* 49: XDMA */
218 	    {{{1, 0x3200000, 0x3204000, 0x1d4000}}}, /* 50: I2Q */
219 	    {{{1, 0x3300000, 0x3304000, 0x1a0000}}}, /* 51: ROMUSB */
220 	    {{{0}}}, /* 52: */
221 	    {{{1, 0x3500000, 0x3500400, 0x1ac000}}}, /* 53: RPMX0 */
222 	    {{{1, 0x3600000, 0x3600400, 0x1ae000}}}, /* 54: RPMX8 */
223 	    {{{1, 0x3700000, 0x3700400, 0x1ae400}}}, /* 55: RPMX9 */
224 	    {{{1, 0x3800000, 0x3804000, 0x1d0000}}}, /* 56: OCM0 */
225 	    {{{1, 0x3900000, 0x3904000, 0x1b4000}}}, /* 57: CRYPTO */
226 	    {{{1, 0x3a00000, 0x3a04000, 0x1d8000}}}, /* 58: SMB */
227 	    {{{0}}}, /* 59: I2C0 */
228 	    {{{0}}}, /* 60: I2C1 */
229 	    {{{1, 0x3d00000, 0x3d04000, 0x1d8000}}}, /* 61: LPC */
230 	    {{{1, 0x3e00000, 0x3e01000, 0x167000}}}, /* 62: P2NC */
231 	    {{{1, 0x3f00000, 0x3f01000, 0x168000}}} /* 63: P2NR0 */
232 };
233 
234 /*
235  * top 12 bits of crb internal address (hub, agent)
236  */
237 static unsigned crb_hub_agt[64] = {
238 	0,
239 	UNM_HW_CRB_HUB_AGT_ADR_PS,
240 	UNM_HW_CRB_HUB_AGT_ADR_MN,
241 	UNM_HW_CRB_HUB_AGT_ADR_MS,
242 	0,
243 	UNM_HW_CRB_HUB_AGT_ADR_SRE,
244 	UNM_HW_CRB_HUB_AGT_ADR_NIU,
245 	UNM_HW_CRB_HUB_AGT_ADR_QMN,
246 	UNM_HW_CRB_HUB_AGT_ADR_SQN0,
247 	UNM_HW_CRB_HUB_AGT_ADR_SQN1,
248 	UNM_HW_CRB_HUB_AGT_ADR_SQN2,
249 	UNM_HW_CRB_HUB_AGT_ADR_SQN3,
250 	UNM_HW_CRB_HUB_AGT_ADR_I2Q,
251 	UNM_HW_CRB_HUB_AGT_ADR_TIMR,
252 	UNM_HW_CRB_HUB_AGT_ADR_ROMUSB,
253 	UNM_HW_CRB_HUB_AGT_ADR_PGN4,
254 	UNM_HW_CRB_HUB_AGT_ADR_XDMA,
255 	UNM_HW_CRB_HUB_AGT_ADR_PGN0,
256 	UNM_HW_CRB_HUB_AGT_ADR_PGN1,
257 	UNM_HW_CRB_HUB_AGT_ADR_PGN2,
258 	UNM_HW_CRB_HUB_AGT_ADR_PGN3,
259 	UNM_HW_CRB_HUB_AGT_ADR_PGND,
260 	UNM_HW_CRB_HUB_AGT_ADR_PGNI,
261 	UNM_HW_CRB_HUB_AGT_ADR_PGS0,
262 	UNM_HW_CRB_HUB_AGT_ADR_PGS1,
263 	UNM_HW_CRB_HUB_AGT_ADR_PGS2,
264 	UNM_HW_CRB_HUB_AGT_ADR_PGS3,
265 	0,
266 	UNM_HW_CRB_HUB_AGT_ADR_PGSI,
267 	UNM_HW_CRB_HUB_AGT_ADR_SN,
268 	0,
269 	UNM_HW_CRB_HUB_AGT_ADR_EG,
270 	0,
271 	UNM_HW_CRB_HUB_AGT_ADR_PS,
272 	UNM_HW_CRB_HUB_AGT_ADR_CAM,
273 	0,
274 	0,
275 	0,
276 	0,
277 	0,
278 	UNM_HW_CRB_HUB_AGT_ADR_TIMR,
279 	0,
280 	UNM_HW_CRB_HUB_AGT_ADR_RPMX1,
281 	UNM_HW_CRB_HUB_AGT_ADR_RPMX2,
282 	UNM_HW_CRB_HUB_AGT_ADR_RPMX3,
283 	UNM_HW_CRB_HUB_AGT_ADR_RPMX4,
284 	UNM_HW_CRB_HUB_AGT_ADR_RPMX5,
285 	UNM_HW_CRB_HUB_AGT_ADR_RPMX6,
286 	UNM_HW_CRB_HUB_AGT_ADR_RPMX7,
287 	UNM_HW_CRB_HUB_AGT_ADR_XDMA,
288 	UNM_HW_CRB_HUB_AGT_ADR_I2Q,
289 	UNM_HW_CRB_HUB_AGT_ADR_ROMUSB,
290 	0,
291 	UNM_HW_CRB_HUB_AGT_ADR_RPMX0,
292 	UNM_HW_CRB_HUB_AGT_ADR_RPMX8,
293 	UNM_HW_CRB_HUB_AGT_ADR_RPMX9,
294 	UNM_HW_CRB_HUB_AGT_ADR_OCM0,
295 	0,
296 	UNM_HW_CRB_HUB_AGT_ADR_SMB,
297 	UNM_HW_CRB_HUB_AGT_ADR_I2C0,
298 	UNM_HW_CRB_HUB_AGT_ADR_I2C1,
299 	0,
300 	UNM_HW_CRB_HUB_AGT_ADR_PGNC,
301 	0,
302 };
303 
304 #define	CRB_WIN_LOCK_TIMEOUT 100000000
305 
306 static void
307 crb_win_lock(struct unm_adapter_s *adapter)
308 {
309 	int i;
310 	int done = 0, timeout = 0;
311 
312 	while (!done) {
313 		/* acquire semaphore3 from PCI HW block */
314 		adapter->unm_nic_hw_read_wx(adapter,
315 		    UNM_PCIE_REG(PCIE_SEM7_LOCK), &done, 4);
316 		if (done == 1)
317 			break;
318 		if (timeout >= CRB_WIN_LOCK_TIMEOUT) {
319 			cmn_err(CE_WARN, "%s%d: crb_win_lock timed out\n",
320 			    adapter->name, adapter->instance);
321 			return;
322 		}
323 		timeout++;
324 		/*
325 		 *  Yield CPU
326 		 */
327 		for (i = 0; i < 20; i++)
328 			;
329 	}
330 	adapter->unm_crb_writelit_adapter(adapter, UNM_CRB_WIN_LOCK_ID,
331 	    adapter->portnum);
332 }
333 
334 static void
335 crb_win_unlock(struct unm_adapter_s *adapter)
336 {
337 	int	val;
338 
339 	adapter->unm_nic_hw_read_wx(adapter, UNM_PCIE_REG(PCIE_SEM7_UNLOCK),
340 	    &val, 4);
341 }
342 
343 /*
344  * Changes the CRB window to the specified window.
345  */
346 void
347 unm_nic_pci_change_crbwindow_128M(unm_adapter *adapter, uint32_t wndw)
348 {
349 	unm_pcix_crb_window_t	window;
350 	unsigned long			offset;
351 	uint32_t				tmp;
352 
353 	if (adapter->curr_window == wndw) {
354 		return;
355 	}
356 
357 	/*
358 	 * Move the CRB window.
359 	 * We need to write to the "direct access" region of PCI
360 	 * to avoid a race condition where the window register has
361 	 * not been successfully written across CRB before the target
362 	 * register address is received by PCI. The direct region bypasses
363 	 * the CRB bus.
364 	 */
365 	offset = PCI_OFFSET_SECOND_RANGE(adapter,
366 	    UNM_PCIX_PH_REG(PCIE_CRB_WINDOW_REG(adapter->ahw.pci_func)));
367 
368 	*(unm_crbword_t *)&window = 0;
369 	window.addrbit = wndw;
370 	UNM_NIC_PCI_WRITE_32(*(unsigned int *)&window, (void*) (offset));
371 	/* MUST make sure window is set before we forge on... */
372 	while ((tmp = UNM_NIC_PCI_READ_32((void*) offset)) !=
373 	    *(uint32_t *)&window) {
374 		cmn_err(CE_WARN, "%s: %s WARNING: CRB window value not "
375 		    "registered properly: 0x%08x.\n",
376 		    unm_nic_driver_name, __FUNCTION__, tmp);
377 	}
378 
379 	adapter->curr_window = wndw;
380 }
381 
382 
383 /*
384  * Changes the CRB window to the specified window.
385  */
386 /* ARGSUSED */
387 void
388 unm_nic_pci_change_crbwindow_2M(unm_adapter *adapter, uint32_t wndw)
389 {
390 }
391 
392 
393 uint32_t
394 unm_nic_get_crbwindow(unm_adapter *adapter)
395 {
396 	return (adapter->curr_window);
397 }
398 
399 /*
400  * Return -1 if off is not valid,
401  *	 1 if window access is needed. 'off' is set to offset from
402  *	   CRB space in 128M pci map
403  *	 0 if no window access is needed. 'off' is set to 2M addr
404  * In: 'off' is offset from base in 128M pci map
405  */
406 int
407 unm_nic_pci_get_crb_addr_2M(unm_adapter *adapter, u64 *off, int len)
408 {
409 	unsigned long end = *off + len;
410 	crb_128M_2M_sub_block_map_t *m;
411 
412 
413 	if (*off >= UNM_CRB_MAX)
414 		return (-1);
415 
416 	if (*off >= UNM_PCI_CAMQM && (end <= UNM_PCI_CAMQM_2M_END)) {
417 		*off = (*off - UNM_PCI_CAMQM) + UNM_PCI_CAMQM_2M_BASE +
418 		    adapter->ahw.pci_base0;
419 		return (0);
420 	}
421 
422 	if (*off < UNM_PCI_CRBSPACE)
423 		return (-1);
424 
425 	*off -= UNM_PCI_CRBSPACE;
426 	end = *off + len;
427 	/*
428 	 * Try direct map
429 	 */
430 
431 	m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)];
432 
433 	if (m->valid && (m->start_128M <= *off) && (m->end_128M >= end)) {
434 		*off = *off + m->start_2M - m->start_128M +
435 		    adapter->ahw.pci_base0;
436 		return (0);
437 	}
438 
439 	/*
440 	 * Not in direct map, use crb window
441 	 */
442 	return (1);
443 }
444 /*
445  * In: 'off' is offset from CRB space in 128M pci map
446  * Out: 'off' is 2M pci map addr
447  * side effect: lock crb window
448  */
449 static void
450 unm_nic_pci_set_crbwindow_2M(unm_adapter *adapter, u64 *off)
451 {
452 	u32 win_read;
453 
454 	adapter->crb_win = CRB_HI(*off);
455 	UNM_NIC_PCI_WRITE_32(adapter->crb_win, (void *) (CRB_WINDOW_2M +
456 	    adapter->ahw.pci_base0));
457 	/*
458 	 * Read back value to make sure write has gone through before trying
459 	 * to use it.
460 	 */
461 	win_read = UNM_NIC_PCI_READ_32((void *)
462 	    (CRB_WINDOW_2M + adapter->ahw.pci_base0));
463 	if (win_read != adapter->crb_win) {
464 		cmn_err(CE_WARN, "%s: Written crbwin (0x%x) != Read crbwin "
465 		    "(0x%x), off=0x%llx\n", __FUNCTION__, adapter->crb_win,
466 		    win_read, *off);
467 	}
468 	*off = (*off & MASK(16)) + CRB_INDIRECT_2M +
469 	    adapter->ahw.pci_base0;
470 }
471 
472 int
473 unm_nic_hw_write_ioctl_128M(unm_adapter *adapter, u64 off, void *data, int len)
474 {
475 	void		*addr;
476 	u64		offset = off;
477 
478 	if (ADDR_IN_WINDOW1(off)) { // Window 1
479 		addr = CRB_NORMALIZE(adapter, off);
480 		if (!addr) {
481 			offset = CRB_NORMAL(off);
482 			if (adapter->ahw.pci_len0 == 0)
483 				offset -= UNM_PCI_CRBSPACE;
484 			addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 +
485 			    offset);
486 		}
487 		UNM_READ_LOCK(&adapter->adapter_lock);
488 	} else {// Window 0
489 		addr = (void *) (uptr_t)(pci_base_offset(adapter, off));
490 		if (!addr) {
491 			offset = off;
492 			addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 +
493 			    offset);
494 		}
495 		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
496 		unm_nic_pci_change_crbwindow_128M(adapter, 0);
497 	}
498 
499 	switch (len) {
500 		case 1:
501 			UNM_NIC_PCI_WRITE_8 (*(__uint8_t *)data, addr);
502 			break;
503 		case 2:
504 			UNM_NIC_PCI_WRITE_16 (*(__uint16_t *)data, addr);
505 			break;
506 		case 4:
507 			UNM_NIC_PCI_WRITE_32 (*(__uint32_t *)data, addr);
508 			break;
509 		case 8:
510 			UNM_NIC_PCI_WRITE_64 (*(__uint64_t *)data, addr);
511 			break;
512 		default:
513 #if !defined(NDEBUG)
514 		if ((len & 0x7) != 0)
515 			cmn_err(CE_WARN, "%s: %s len(%d) not multiple of 8.\n",
516 			    unm_nic_driver_name, __FUNCTION__, len);
517 #endif
518 		UNM_NIC_HW_BLOCK_WRITE_64(data, addr, (len>>3));
519 		break;
520 	}
521 	if (ADDR_IN_WINDOW1(off)) {// Window 1
522 		UNM_READ_UNLOCK(&adapter->adapter_lock);
523 	} else {// Window 0
524 		unm_nic_pci_change_crbwindow_128M(adapter, 1);
525 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
526 	}
527 
528 	return (0);
529 }
530 
531 /*
532  * Note : 'len' argument should be either 1, 2, 4, or a multiple of 8.
533  */
534 int
535 unm_nic_hw_write_wx_128M(unm_adapter *adapter, u64 off, void *data, int len)
536 {
537 	/*
538 	 * This is modified from _unm_nic_hw_write().
539 	 * unm_nic_hw_write does not exist now.
540 	 */
541 
542 	void *addr;
543 
544 	if (ADDR_IN_WINDOW1(off)) {// Window 1
545 		addr = CRB_NORMALIZE(adapter, off);
546 		UNM_READ_LOCK(&adapter->adapter_lock);
547 	} else {// Window 0
548 		addr = (void *) (uptr_t)(pci_base_offset(adapter, off));
549 		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
550 		unm_nic_pci_change_crbwindow_128M(adapter, 0);
551 	}
552 
553 
554 	if (!addr) {
555 		if (ADDR_IN_WINDOW1(off)) {// Window 1
556 			UNM_READ_UNLOCK(&adapter->adapter_lock);
557 		} else {// Window 0
558 			unm_nic_pci_change_crbwindow_128M(adapter, 1);
559 			UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
560 		}
561 		return (1);
562 	}
563 
564 	switch (len) {
565 		case 1:
566 			UNM_NIC_PCI_WRITE_8 (*(__uint8_t *)data, addr);
567 			break;
568 		case 2:
569 			UNM_NIC_PCI_WRITE_16 (*(__uint16_t *)data, addr);
570 			break;
571 		case 4:
572 			UNM_NIC_PCI_WRITE_32 (*(__uint32_t *)data, addr);
573 			break;
574 		case 8:
575 			UNM_NIC_PCI_WRITE_64 (*(__uint64_t *)data, addr);
576 			break;
577 		default:
578 #if !defined(NDEBUG)
579 			if ((len & 0x7) != 0)
580 				cmn_err(CE_WARN,
581 				    "%s: %s  len(%d) not multiple of 8.\n",
582 				    unm_nic_driver_name, __FUNCTION__, len);
583 #endif
584 			UNM_NIC_HW_BLOCK_WRITE_64(data, addr, (len>>3));
585 			break;
586 	}
587 	if (ADDR_IN_WINDOW1(off)) {// Window 1
588 		UNM_READ_UNLOCK(&adapter->adapter_lock);
589 	} else {// Window 0
590 		unm_nic_pci_change_crbwindow_128M(adapter, 1);
591 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
592 	}
593 
594 	return (0);
595 }
596 
597 /*
598  * Note : only 32-bit writes!
599  */
600 void
601 unm_nic_pci_write_normalize_128M(unm_adapter *adapter, u64 off, u32 data)
602 {
603 	UNM_NIC_PCI_WRITE_32(data, CRB_NORMALIZE(adapter, off));
604 }
605 
606 /*
607  * Note : only 32-bit reads!
608  */
609 u32
610 unm_nic_pci_read_normalize_128M(unm_adapter *adapter, u64 off)
611 {
612 	return (UNM_NIC_PCI_READ_32(CRB_NORMALIZE(adapter, off)));
613 }
614 
615 /*
616  * Note : only 32-bit writes!
617  */
618 int
619 unm_nic_pci_write_immediate_128M(unm_adapter *adapter, u64 off, u32 *data)
620 {
621 	UNM_NIC_PCI_WRITE_32(*data,
622 	    (void *) (uptr_t)(PCI_OFFSET_SECOND_RANGE(adapter, off)));
623 	return (0);
624 }
625 
626 /*
627  * Note : only 32-bit reads!
628  */
629 int
630 unm_nic_pci_read_immediate_128M(unm_adapter *adapter, u64 off, u32 *data)
631 {
632 	*data = UNM_NIC_PCI_READ_32((void *)
633 	    (uptr_t)(pci_base_offset(adapter, off)));
634 	return (0);
635 }
636 
637 /*
638  * Note : only 32-bit writes!
639  */
640 void
641 unm_nic_pci_write_normalize_2M(unm_adapter *adapter, u64 off, u32 data)
642 {
643 	u32 temp = data;
644 
645 	adapter->unm_nic_hw_write_wx(adapter, off, &temp, 4);
646 }
647 
648 /*
649  * Note : only 32-bit reads!
650  */
651 u32
652 unm_nic_pci_read_normalize_2M(unm_adapter *adapter, u64 off)
653 {
654 	u32 temp;
655 
656 	adapter->unm_nic_hw_read_wx(adapter, off, &temp, 4);
657 
658 	return (temp);
659 }
660 
661 /*
662  * Note : only 32-bit writes!
663  */
664 int
665 unm_nic_pci_write_immediate_2M(unm_adapter *adapter, u64 off, u32 *data)
666 {
667 	u32 temp = *data;
668 
669 	adapter->unm_nic_hw_write_wx(adapter, off, &temp, 4);
670 
671 	return (0);
672 }
673 
674 /*
675  * Note : only 32-bit reads!
676  */
677 int
678 unm_nic_pci_read_immediate_2M(unm_adapter *adapter, u64 off, u32 *data)
679 {
680 	u32 temp;
681 
682 	adapter->unm_nic_hw_read_wx(adapter, off, &temp, 4);
683 
684 	*data = temp;
685 
686 	return (0);
687 }
688 
689 /*
690  * write cross hw window boundary is not supported
691  * 'len' should be either 1, 2, 4, or multiple of 8
692  */
693 int
694 unm_nic_hw_write_wx_2M(unm_adapter *adapter, u64 off, void *data, int len)
695 {
696 	int rv;
697 
698 	rv = unm_nic_pci_get_crb_addr_2M(adapter, &off, len);
699 
700 	if (rv == -1) {
701 		cmn_err(CE_PANIC, "%s: invalid offset: 0x%016llx\n",
702 		    __FUNCTION__, off);
703 		return (-1);
704 	}
705 
706 	if (rv == 1) {
707 		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
708 		crb_win_lock(adapter);
709 		unm_nic_pci_set_crbwindow_2M(adapter, &off);
710 	}
711 
712 	switch (len) {
713 	case 1:
714 		UNM_NIC_PCI_WRITE_8(*(__uint8_t *)data, (void *) (uptr_t)off);
715 		break;
716 	case 2:
717 		UNM_NIC_PCI_WRITE_16(*(__uint16_t *)data, (void *) (uptr_t)off);
718 		break;
719 	case 4:
720 		UNM_NIC_PCI_WRITE_32(*(__uint32_t *)data, (void *) (uptr_t)off);
721 		break;
722 	case 8:
723 		UNM_NIC_PCI_WRITE_64(*(__uint64_t *)data, (void *) (uptr_t)off);
724 		break;
725 	default:
726 #if !defined(NDEBUG)
727 		if ((len & 0x7) != 0)
728 			cmn_err(CE_WARN, "%s: %s  len(%d) not multiple of 8.\n",
729 			    unm_nic_driver_name, __FUNCTION__, len);
730 #endif
731 		UNM_NIC_HW_BLOCK_WRITE_64(data, (uptr_t)off, (len>>3));
732 		break;
733 	}
734 	if (rv == 1) {
735 		crb_win_unlock(adapter);
736 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
737 	}
738 
739 	return (0);
740 }
741 
742 int
743 unm_nic_hw_read_ioctl_128M(unm_adapter *adapter, u64 off, void *data, int len)
744 {
745 	void		*addr;
746 	u64		offset;
747 
748 	if (ADDR_IN_WINDOW1(off)) {// Window 1
749 		addr = CRB_NORMALIZE(adapter, off);
750 		if (!addr) {
751 			offset = CRB_NORMAL(off);
752 			if (adapter->ahw.pci_len0 == 0)
753 				offset -= UNM_PCI_CRBSPACE;
754 			addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 +
755 			    offset);
756 		}
757 		UNM_READ_LOCK(&adapter->adapter_lock);
758 	} else {// Window 0
759 		addr = (void *) (uptr_t)(pci_base_offset(adapter, off));
760 		if (!addr) {
761 			offset = off;
762 			addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 +
763 			    offset);
764 		}
765 		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
766 		unm_nic_pci_change_crbwindow_128M(adapter, 0);
767 	}
768 
769 	switch (len) {
770 	case 1:
771 		*(__uint8_t  *)data = UNM_NIC_PCI_READ_8(addr);
772 		break;
773 	case 2:
774 		*(__uint16_t *)data = UNM_NIC_PCI_READ_16(addr);
775 		break;
776 	case 4:
777 		*(__uint32_t *)data = UNM_NIC_PCI_READ_32(addr);
778 		break;
779 	case 8:
780 		*(__uint64_t *)data = UNM_NIC_PCI_READ_64(addr);
781 		break;
782 	default:
783 #if !defined(NDEBUG)
784 		if ((len & 0x7) != 0)
785 			cmn_err(CE_WARN, "%s: %s len(%d) not multiple of 8.\n",
786 			    unm_nic_driver_name, __FUNCTION__, len);
787 #endif
788 		UNM_NIC_HW_BLOCK_READ_64(data, addr, (len>>3));
789 		break;
790 	}
791 
792 	if (ADDR_IN_WINDOW1(off)) {// Window 1
793 		UNM_READ_UNLOCK(&adapter->adapter_lock);
794 	} else {// Window 0
795 		unm_nic_pci_change_crbwindow_128M(adapter, 1);
796 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
797 	}
798 
799 	return (0);
800 }
801 
802 int
803 unm_nic_hw_read_wx_2M(unm_adapter *adapter, u64 off, void *data, int len)
804 {
805 	int rv;
806 
807 	rv = unm_nic_pci_get_crb_addr_2M(adapter, &off, len);
808 
809 	if (rv == -1) {
810 		cmn_err(CE_PANIC, "%s: invalid offset: 0x%016llx\n",
811 		    __FUNCTION__, off);
812 		return (-1);
813 	}
814 
815 	if (rv == 1) {
816 		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
817 		crb_win_lock(adapter);
818 		unm_nic_pci_set_crbwindow_2M(adapter, &off);
819 	}
820 
821 	switch (len) {
822 	case 1:
823 		*(__uint8_t  *)data = UNM_NIC_PCI_READ_8((void *) (uptr_t)off);
824 		break;
825 	case 2:
826 		*(__uint16_t *)data = UNM_NIC_PCI_READ_16((void *) (uptr_t)off);
827 		break;
828 	case 4:
829 		*(__uint32_t *)data = UNM_NIC_PCI_READ_32((void *) (uptr_t)off);
830 		break;
831 	case 8:
832 		*(__uint64_t *)data = UNM_NIC_PCI_READ_64((void *) (uptr_t)off);
833 		break;
834 	default:
835 #if !defined(NDEBUG)
836 		if ((len & 0x7) != 0)
837 			cmn_err(CE_WARN, "%s: %s len(%d) not multiple of 8.\n",
838 			    unm_nic_driver_name, __FUNCTION__, len);
839 #endif
840 		UNM_NIC_HW_BLOCK_READ_64(data, (void *) (uptr_t)off, (len>>3));
841 		break;
842 	}
843 
844 	if (rv == 1) {
845 		crb_win_unlock(adapter);
846 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
847 	}
848 
849 	return (0);
850 }
851 
852 int
853 unm_nic_hw_read_wx_128M(unm_adapter *adapter, u64 off, void *data, int len)
854 {
855 	void *addr;
856 
857 	if (ADDR_IN_WINDOW1(off)) {
858 		// Window 1
859 		addr = CRB_NORMALIZE(adapter, off);
860 		UNM_READ_LOCK(&adapter->adapter_lock);
861 	} else {// Window 0
862 		addr = (void *) (uptr_t)(pci_base_offset(adapter, off));
863 		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
864 		unm_nic_pci_change_crbwindow_128M(adapter, 0);
865 	}
866 
867 	if (!addr) {
868 		if (ADDR_IN_WINDOW1(off)) {// Window 1
869 			UNM_READ_UNLOCK(&adapter->adapter_lock);
870 		} else {// Window 0
871 			unm_nic_pci_change_crbwindow_128M(adapter, 1);
872 			UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
873 		}
874 		return (1);
875 	}
876 
877 	switch (len) {
878 		case 1:
879 			*(__uint8_t  *)data = UNM_NIC_PCI_READ_8(addr);
880 			break;
881 		case 2:
882 			*(__uint16_t *)data = UNM_NIC_PCI_READ_16(addr);
883 			break;
884 		case 4:
885 			*(__uint32_t *)data = UNM_NIC_PCI_READ_32(addr);
886 			break;
887 		case 8:
888 			*(__uint64_t *)data = UNM_NIC_PCI_READ_64(addr);
889 			break;
890 		default:
891 #if !defined(NDEBUG)
892 			if ((len & 0x7) != 0)
893 				cmn_err(CE_WARN,
894 				    "%s: %s len(%d) not multiple of 8.\n",
895 				    unm_nic_driver_name, __FUNCTION__, len);
896 #endif
897 			UNM_NIC_HW_BLOCK_READ_64(data, addr, (len>>3));
898 			break;
899 	}
900 
901 	if (ADDR_IN_WINDOW1(off)) {// Window 1
902 		UNM_READ_UNLOCK(&adapter->adapter_lock);
903 	} else {// Window 0
904 		unm_nic_pci_change_crbwindow_128M(adapter, 1);
905 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
906 	}
907 
908 	return (0);
909 }
910 
911 /*  PCI Windowing for DDR regions.  */
912 #define	ADDR_IN_RANGE(addr, low, high)	    \
913 	(((addr) <= (high)) && ((low) ? ((addr) >= (low)) : 1))
914 
915 /*
916  * check memory access boundary.
917  * used by test agent. support ddr access only for now
918  */
919 /* ARGSUSED */
920 static unsigned long
921 unm_nic_pci_mem_bound_check(struct unm_adapter_s *adapter,
922     unsigned long long addr, int size)
923 {
924 	if (!ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX) ||
925 	    !ADDR_IN_RANGE(addr + size -1, UNM_ADDR_DDR_NET,
926 	    UNM_ADDR_DDR_NET_MAX) || ((size != 1) && (size != 2) &&
927 	    (size != 4) && (size != 8)))
928 		return (0);
929 
930 	return (1);
931 }
932 
933 int unm_pci_set_window_warning_count = 0;
934 
935 unsigned long long
936 unm_nic_pci_set_window_128M(struct unm_adapter_s *adapter,
937     unsigned long long addr)
938 {
939 	int		window;
940 	unsigned long long	qdr_max;
941 
942 	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
943 		qdr_max = NX_P2_ADDR_QDR_NET_MAX;
944 	} else {
945 		qdr_max = NX_P3_ADDR_QDR_NET_MAX;
946 	}
947 
948 	if (ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX)) {
949 		/* DDR network side */
950 		/* MN access should never come here */
951 		cmn_err(CE_PANIC, "%s\n", __FUNCTION__);
952 		addr = -1ULL;
953 	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM0, UNM_ADDR_OCM0_MAX)) {
954 		addr -= UNM_ADDR_OCM0;
955 		addr += UNM_PCI_OCM0;
956 	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM1, UNM_ADDR_OCM1_MAX)) {
957 		addr -= UNM_ADDR_OCM1;
958 		addr += UNM_PCI_OCM1;
959 	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET, qdr_max)) {
960 		/* QDR network side */
961 		addr -= UNM_ADDR_QDR_NET;
962 		window = (addr >> 22) & 0x3f;
963 		if (adapter->ahw.qdr_sn_window != window) {
964 			adapter->ahw.qdr_sn_window = window;
965 			UNM_NIC_PCI_WRITE_32((window << 22),
966 			    (void *) (uptr_t)(PCI_OFFSET_SECOND_RANGE(adapter,
967 			    UNM_PCIX_PH_REG(PCIE_SN_WINDOW_REG(
968 			    adapter->ahw.pci_func)))));
969 			/* MUST make sure window is set before we forge on... */
970 			(void) UNM_NIC_PCI_READ_32((void *)
971 			    (uptr_t)(PCI_OFFSET_SECOND_RANGE(adapter,
972 			    UNM_PCIX_PH_REG(PCIE_SN_WINDOW_REG(
973 			    adapter->ahw.pci_func)))));
974 		}
975 		addr -= (window * 0x400000);
976 		addr += UNM_PCI_QDR_NET;
977 	} else {
978 		/*
979 		 * peg gdb frequently accesses memory that doesn't exist,
980 		 * this limits the chit chat so debugging isn't slowed down.
981 		 */
982 		if ((unm_pci_set_window_warning_count++ < 8) ||
983 		    (unm_pci_set_window_warning_count%64 == 0)) {
984 			cmn_err(CE_WARN, "%s: Warning:unm_nic_pci_set_window() "
985 			    "Unknown address range!\n", unm_nic_driver_name);
986 		}
987 		addr = -1ULL;
988 	}
989 	return (addr);
990 }
991 
992 unsigned long long
993 unm_nic_pci_set_window_2M(struct unm_adapter_s *adapter,
994     unsigned long long addr)
995 {
996 	int window;
997 	u32 win_read;
998 
999 	if (ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX)) {
1000 		/* DDR network side */
1001 		window = MN_WIN(addr);
1002 		adapter->ahw.ddr_mn_window = window;
1003 		adapter->unm_nic_hw_write_wx(adapter, adapter->ahw.mn_win_crb |
1004 		    UNM_PCI_CRBSPACE, &window, 4);
1005 		adapter->unm_nic_hw_read_wx(adapter, adapter->ahw.mn_win_crb |
1006 		    UNM_PCI_CRBSPACE, &win_read, 4);
1007 		if ((win_read << 17) != window) {
1008 			cmn_err(CE_WARN,
1009 			    "%s: Written MNwin (0x%x) != Read MNwin (0x%x)\n",
1010 			    __FUNCTION__, window, win_read);
1011 		}
1012 		addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_DDR_NET;
1013 	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM0, UNM_ADDR_OCM0_MAX)) {
1014 		unsigned int temp1;
1015 // OCM: pci_addr[20:18] == 011 && pci_addr[17:11] != 7f
1016 		if ((addr & 0x00ff800) == 0xff800) {
1017 			// if bits 19:18&17:11 are on
1018 			cmn_err(CE_WARN, "%s: QM access not handled.\n",
1019 			    __FUNCTION__);
1020 			addr = -1ULL;
1021 		}
1022 
1023 		window = OCM_WIN(addr);
1024 		adapter->ahw.ddr_mn_window = window;
1025 		adapter->unm_nic_hw_write_wx(adapter, adapter->ahw.mn_win_crb |
1026 		    UNM_PCI_CRBSPACE, &window, 4);
1027 		adapter->unm_nic_hw_read_wx(adapter, adapter->ahw.mn_win_crb |
1028 		    UNM_PCI_CRBSPACE, &win_read, 4);
1029 		temp1 = ((window & 0x1FF) << 7) |
1030 		    ((window & 0x0FFFE0000) >> 17);
1031 		if (win_read != temp1) {
1032 			cmn_err(CE_WARN,
1033 			    "%s: Written OCMwin(0x%x) != Read OCMwin(0x%x)\n",
1034 			    __FUNCTION__, temp1, win_read);
1035 		}
1036 		addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_OCM0_2M;
1037 
1038 	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET,
1039 	    NX_P3_ADDR_QDR_NET_MAX)) {
1040 		/* QDR network side */
1041 		window = MS_WIN(addr);
1042 		adapter->ahw.qdr_sn_window = window;
1043 		adapter->unm_nic_hw_write_wx(adapter, adapter->ahw.ms_win_crb |
1044 		    UNM_PCI_CRBSPACE, &window, 4);
1045 		adapter->unm_nic_hw_read_wx(adapter, adapter->ahw.ms_win_crb |
1046 		    UNM_PCI_CRBSPACE, &win_read, 4);
1047 		if (win_read != window) {
1048 			cmn_err(CE_WARN,
1049 			    "%s: Written MSwin (0x%x) != Read MSwin (0x%x)\n",
1050 			    __FUNCTION__, window, win_read);
1051 		}
1052 		addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_QDR_NET;
1053 
1054 	} else {
1055 		/*
1056 		 * peg gdb frequently accesses memory that doesn't exist,
1057 		 * this limits the chit chat so debugging isn't slowed down.
1058 		 */
1059 		if ((unm_pci_set_window_warning_count++ < 8) ||
1060 		    (unm_pci_set_window_warning_count%64 == 0)) {
1061 			cmn_err(CE_WARN, "%s%d: %s Unknown address range!\n",
1062 			    adapter->name, adapter->instance, __FUNCTION__);
1063 		}
1064 		addr = -1ULL;
1065 	}
1066 	return (addr);
1067 }
1068 
1069 /* check if address is in the same windows as the previous access */
1070 static unsigned long
1071 unm_nic_pci_is_same_window(struct unm_adapter_s *adapter,
1072     unsigned long long addr)
1073 {
1074 	int			window;
1075 	unsigned long long	qdr_max;
1076 
1077 	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
1078 		qdr_max = NX_P2_ADDR_QDR_NET_MAX;
1079 	} else {
1080 		qdr_max = NX_P3_ADDR_QDR_NET_MAX;
1081 	}
1082 
1083 	if (ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX)) {
1084 		/* DDR network side */
1085 		/* MN access can not come here */
1086 		cmn_err(CE_PANIC, "%s\n", __FUNCTION__);
1087 #if 0
1088 		window = ((addr - UNM_ADDR_DDR_NET) >> 25) & 0x3ff;
1089 		if (adapter->ahw.ddr_mn_window == window) {
1090 			return (1);
1091 		}
1092 #endif
1093 	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM0, UNM_ADDR_OCM0_MAX)) {
1094 		return (1);
1095 	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM1, UNM_ADDR_OCM1_MAX)) {
1096 		return (1);
1097 	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET, qdr_max)) {
1098 		/* QDR network side */
1099 		window = ((addr - UNM_ADDR_QDR_NET) >> 22) & 0x3f;
1100 		if (adapter->ahw.qdr_sn_window == window) {
1101 			return (1);
1102 		}
1103 	}
1104 
1105 	return (0);
1106 }
1107 
1108 static int
1109 unm_nic_pci_mem_read_direct(struct unm_adapter_s *adapter,
1110     u64 off, void *data, int size)
1111 {
1112 	void			*addr;
1113 	int				ret = 0;
1114 	u64				start;
1115 
1116 #if 0
1117 	/*
1118 	 * This check can not be currently executed, since phanmon findq
1119 	 * command breaks this check whereby 8 byte reads are being attempted
1120 	 * on "aligned-by-4" addresses on x86. Reason this works is our version
1121 	 * breaks up the access into 2 consecutive 4 byte writes; on other
1122 	 * architectures, this might require "aligned-by-8" addresses and we
1123 	 * will run into trouble.
1124 	 *
1125 	 * Check alignment for expected sizes of 1, 2, 4, 8. Other size
1126 	 * values will not trigger access.
1127 	 */
1128 	if ((off & (size - 1)) != 0)
1129 		return (-1);
1130 #endif
1131 
1132 	UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1133 
1134 	/*
1135 	 * If attempting to access unknown address or straddle hw windows,
1136 	 * do not access.
1137 	 */
1138 	if (((start = adapter->unm_nic_pci_set_window(adapter, off)) == -1UL) ||
1139 	    (unm_nic_pci_is_same_window(adapter, off + size -1) == 0)) {
1140 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1141 		cmn_err(CE_WARN, "%s out of bound pci memory access. "
1142 		    "offset is 0x%llx\n", unm_nic_driver_name, off);
1143 		return (-1);
1144 	}
1145 
1146 	addr = (void *) (uptr_t)(pci_base_offset(adapter, start));
1147 	if (!addr)
1148 		addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 + start);
1149 
1150 	switch (size) {
1151 		case 1:
1152 			*(__uint8_t  *)data = UNM_NIC_PCI_READ_8(addr);
1153 			break;
1154 		case 2:
1155 			*(__uint16_t *)data = UNM_NIC_PCI_READ_16(addr);
1156 			break;
1157 		case 4:
1158 			*(__uint32_t *)data = UNM_NIC_PCI_READ_32(addr);
1159 			break;
1160 		case 8:
1161 			*(__uint64_t *)data = UNM_NIC_PCI_READ_64(addr);
1162 			break;
1163 		default:
1164 			ret = -1;
1165 			break;
1166 	}
1167 
1168 	UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1169 	return (ret);
1170 }
1171 
1172 static int
1173 unm_nic_pci_mem_write_direct(struct unm_adapter_s *adapter, u64 off,
1174     void *data, int size)
1175 {
1176 	void	*addr;
1177 	int		ret = 0;
1178 	u64		start;
1179 
1180 #if 0
1181 	/*
1182 	 * This check can not be currently executed, since firmware load
1183 	 * breaks this check whereby 8 byte writes are being attempted on
1184 	 * "aligned-by-4" addresses on x86. Reason this works is our version
1185 	 * breaks up the access into 2 consecutive 4 byte writes; on other
1186 	 * architectures, this might require "aligned-by-8" addresses and we
1187 	 * will run into trouble.
1188 	 *
1189 	 * Check alignment for expected sizes of 1, 2, 4, 8. Other size
1190 	 * values will not trigger access.
1191 	 */
1192 	if ((off & (size - 1)) != 0)
1193 		return (-1);
1194 #endif
1195 
1196 	UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1197 
1198 	/*
1199 	 * If attempting to access unknown address or straddle hw windows,
1200 	 * do not access.
1201 	 */
1202 	if (((start = adapter->unm_nic_pci_set_window(adapter, off)) == -1UL) ||
1203 	    (unm_nic_pci_is_same_window(adapter, off + size -1) == 0)) {
1204 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1205 		cmn_err(CE_WARN, "%s out of bound pci memory access. "
1206 		    "offset is 0x%llx\n", unm_nic_driver_name, off);
1207 		return (-1);
1208 	}
1209 
1210 	addr = (void *) (uptr_t)(pci_base_offset(adapter, start));
1211 	if (!addr)
1212 		addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 + start);
1213 
1214 	switch (size) {
1215 		case 1:
1216 			UNM_NIC_PCI_WRITE_8(*(__uint8_t  *)data, addr);
1217 			break;
1218 		case 2:
1219 			UNM_NIC_PCI_WRITE_16(*(__uint16_t *)data, addr);
1220 			break;
1221 		case 4:
1222 			UNM_NIC_PCI_WRITE_32(*(__uint32_t *)data, addr);
1223 			break;
1224 		case 8:
1225 			UNM_NIC_PCI_WRITE_64(*(__uint64_t *)data, addr);
1226 			break;
1227 		default:
1228 			ret = -1;
1229 			break;
1230 	}
1231 	UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1232 	return (ret);
1233 }
1234 
1235 
1236 int
1237 unm_nic_pci_mem_write_128M(struct unm_adapter_s *adapter, u64 off, void *data,
1238     int size)
1239 {
1240 	int		i, j, ret = 0, loop, sz[2], off0;
1241 	__uint32_t		temp;
1242 	__uint64_t		off8, mem_crb, tmpw, word[2] = {0, 0};
1243 #define	MAX_CTL_CHECK   1000
1244 
1245 	/*
1246 	 * If not MN, go check for MS or invalid.
1247 	 */
1248 	if (unm_nic_pci_mem_bound_check(adapter, off, size) == 0)
1249 		return (unm_nic_pci_mem_write_direct(adapter, off, data, size));
1250 
1251 	off8 = off & 0xfffffff8;
1252 	off0 = off & 0x7;
1253 	sz[0] = (size < (8 - off0)) ? size : (8 - off0);
1254 	sz[1] = size - sz[0];
1255 	loop = ((off0 + size - 1) >> 3) + 1;
1256 	/* LINTED: E_FALSE_LOGICAL_EXPR */
1257 	mem_crb = (uptr_t)(pci_base_offset(adapter, UNM_CRB_DDR_NET));
1258 
1259 	if ((size != 8) || (off0 != 0))  {
1260 		for (i = 0; i < loop; i++) {
1261 			if (adapter->unm_nic_pci_mem_read(adapter,
1262 			    off8 + (i << 3), &word[i], 8))
1263 				return (-1);
1264 		}
1265 	}
1266 
1267 	switch (size) {
1268 		case 1:
1269 			tmpw = *((__uint8_t *)data);
1270 			break;
1271 		case 2:
1272 			tmpw = *((__uint16_t *)data);
1273 			break;
1274 		case 4:
1275 			tmpw = *((__uint32_t *)data);
1276 			break;
1277 		case 8:
1278 		default:
1279 			tmpw = *((__uint64_t *)data);
1280 			break;
1281 	}
1282 	word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
1283 	word[0] |= tmpw << (off0 * 8);
1284 
1285 	if (loop == 2) {
1286 		word[1] &= ~(~0ULL << (sz[1] * 8));
1287 		word[1] |= tmpw >> (sz[0] * 8);
1288 	}
1289 
1290 	UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1291 	unm_nic_pci_change_crbwindow_128M(adapter, 0);
1292 
1293 	for (i = 0; i < loop; i++) {
1294 		UNM_NIC_PCI_WRITE_32((__uint32_t)(off8 + (i << 3)),
1295 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_ADDR_LO));
1296 		UNM_NIC_PCI_WRITE_32(0,
1297 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_ADDR_HI));
1298 		UNM_NIC_PCI_WRITE_32(word[i] & 0xffffffff,
1299 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_WRDATA_LO));
1300 		UNM_NIC_PCI_WRITE_32((word[i] >> 32) & 0xffffffff,
1301 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_WRDATA_HI));
1302 		UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
1303 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
1304 		UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_START | MIU_TA_CTL_ENABLE |
1305 		    MIU_TA_CTL_WRITE,
1306 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
1307 
1308 		for (j = 0; j < MAX_CTL_CHECK; j++) {
1309 			temp = UNM_NIC_PCI_READ_32((void *)
1310 			    (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
1311 			if ((temp & MIU_TA_CTL_BUSY) == 0) {
1312 				break;
1313 			}
1314 		}
1315 
1316 		if (j >= MAX_CTL_CHECK) {
1317 			cmn_err(CE_WARN, "%s: %s Fail to write thru agent\n",
1318 			    __FUNCTION__, unm_nic_driver_name);
1319 			ret = -1;
1320 			break;
1321 		}
1322 	}
1323 
1324 	unm_nic_pci_change_crbwindow_128M(adapter, 1);
1325 	UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1326 	return (ret);
1327 }
1328 
1329 int
1330 unm_nic_pci_mem_read_128M(struct unm_adapter_s *adapter, u64 off, void *data,
1331     int size)
1332 {
1333 	int		i, j = 0, k, start, end, loop, sz[2], off0[2];
1334 	__uint32_t		temp;
1335 	__uint64_t		off8, val, mem_crb, word[2] = {0, 0};
1336 #define	MAX_CTL_CHECK   1000
1337 
1338 	/*
1339 	 * If not MN, go check for MS or invalid.
1340 	 */
1341 	if (unm_nic_pci_mem_bound_check(adapter, off, size) == 0)
1342 		return (unm_nic_pci_mem_read_direct(adapter, off, data, size));
1343 
1344 	off8 = off & 0xfffffff8;
1345 	off0[0] = off & 0x7;
1346 	off0[1] = 0;
1347 	sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
1348 	sz[1] = size - sz[0];
1349 	loop = ((off0[0] + size - 1) >> 3) + 1;
1350 	/* LINTED: E_FALSE_LOGICAL_EXPR */
1351 	mem_crb = (uptr_t)(pci_base_offset(adapter, UNM_CRB_DDR_NET));
1352 
1353 	UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1354 	unm_nic_pci_change_crbwindow_128M(adapter, 0);
1355 
1356 	for (i = 0; i < loop; i++) {
1357 		UNM_NIC_PCI_WRITE_32((__uint32_t)(off8 + (i << 3)),
1358 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_ADDR_LO));
1359 		UNM_NIC_PCI_WRITE_32(0,
1360 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_ADDR_HI));
1361 		UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_ENABLE,
1362 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
1363 		UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE,
1364 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
1365 
1366 		for (j = 0; j < MAX_CTL_CHECK; j++) {
1367 			temp = UNM_NIC_PCI_READ_32((void *)
1368 			    (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
1369 			if ((temp & MIU_TA_CTL_BUSY) == 0) {
1370 				break;
1371 			}
1372 		}
1373 
1374 		if (j >= MAX_CTL_CHECK) {
1375 			cmn_err(CE_WARN, "%s: %s Fail to read through agent\n",
1376 			    __FUNCTION__, unm_nic_driver_name);
1377 			break;
1378 		}
1379 
1380 		start = off0[i] >> 2;
1381 		end   = (off0[i] + sz[i] - 1) >> 2;
1382 		word[i] = 0;
1383 		for (k = start; k <= end; k++) {
1384 			word[i] |= ((__uint64_t)UNM_NIC_PCI_READ_32(
1385 			    (void *) (uptr_t)(mem_crb +
1386 			    MIU_TEST_AGT_RDDATA(k))) << (32*k));
1387 		}
1388 	}
1389 
1390 	unm_nic_pci_change_crbwindow_128M(adapter, 1);
1391 	UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1392 
1393 	if (j >= MAX_CTL_CHECK)
1394 		return (-1);
1395 
1396 	if (sz[0] == 8) {
1397 		val = word[0];
1398 	} else {
1399 		val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
1400 		    ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
1401 	}
1402 
1403 	switch (size) {
1404 	case 1:
1405 		*(__uint8_t  *)data = val;
1406 		break;
1407 	case 2:
1408 		*(__uint16_t *)data = val;
1409 		break;
1410 	case 4:
1411 		*(__uint32_t *)data = val;
1412 		break;
1413 	case 8:
1414 		*(__uint64_t *)data = val;
1415 		break;
1416 	}
1417 	return (0);
1418 }
1419 
1420 
1421 
1422 int
1423 unm_nic_pci_mem_write_2M(struct unm_adapter_s *adapter, u64 off, void *data,
1424     int size)
1425 {
1426 	int	i, j, ret = 0, loop, sz[2], off0;
1427 	__uint32_t	temp;
1428 	__uint64_t	off8, mem_crb, tmpw, word[2] = {0, 0};
1429 #define	MAX_CTL_CHECK   1000
1430 
1431 	/*
1432 	 * If not MN, go check for MS or invalid.
1433 	 */
1434 	if (off >= UNM_ADDR_QDR_NET && off <= NX_P3_ADDR_QDR_NET_MAX) {
1435 		mem_crb = UNM_CRB_QDR_NET;
1436 	} else {
1437 		mem_crb = UNM_CRB_DDR_NET;
1438 		if (unm_nic_pci_mem_bound_check(adapter, off, size) == 0)
1439 			return (unm_nic_pci_mem_write_direct(adapter,
1440 			    off, data, size));
1441 	}
1442 
1443 	off8 = off & 0xfffffff8;
1444 	off0 = off & 0x7;
1445 	sz[0] = (size < (8 - off0)) ? size : (8 - off0);
1446 	sz[1] = size - sz[0];
1447 	loop = ((off0 + size - 1) >> 3) + 1;
1448 
1449 	if ((size != 8) || (off0 != 0)) {
1450 		for (i = 0; i < loop; i++) {
1451 			if (adapter->unm_nic_pci_mem_read(adapter,
1452 			    off8 + (i << 3), &word[i], 8))
1453 				return (-1);
1454 		}
1455 	}
1456 
1457 	switch (size) {
1458 		case 1:
1459 			tmpw = *((__uint8_t *)data);
1460 			break;
1461 		case 2:
1462 			tmpw = *((__uint16_t *)data);
1463 			break;
1464 		case 4:
1465 			tmpw = *((__uint32_t *)data);
1466 			break;
1467 		case 8:
1468 		default:
1469 			tmpw = *((__uint64_t *)data);
1470 			break;
1471 	}
1472 
1473 	word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
1474 	word[0] |= tmpw << (off0 * 8);
1475 
1476 	if (loop == 2) {
1477 		word[1] &= ~(~0ULL << (sz[1] * 8));
1478 		word[1] |= tmpw >> (sz[0] * 8);
1479 	}
1480 
1481 // don't lock here - write_wx gets the lock if each time
1482 // UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1483 // unm_nic_pci_change_crbwindow_128M(adapter, 0);
1484 
1485 	for (i = 0; i < loop; i++) {
1486 		temp = off8 + (i << 3);
1487 		adapter->unm_nic_hw_write_wx(adapter,
1488 		    mem_crb+MIU_TEST_AGT_ADDR_LO, &temp, 4);
1489 		temp = 0;
1490 		adapter->unm_nic_hw_write_wx(adapter,
1491 		    mem_crb+MIU_TEST_AGT_ADDR_HI, &temp, 4);
1492 		temp = word[i] & 0xffffffff;
1493 		adapter->unm_nic_hw_write_wx(adapter,
1494 		    mem_crb+MIU_TEST_AGT_WRDATA_LO, &temp, 4);
1495 		temp = (word[i] >> 32) & 0xffffffff;
1496 		adapter->unm_nic_hw_write_wx(adapter,
1497 		    mem_crb+MIU_TEST_AGT_WRDATA_HI, &temp, 4);
1498 		temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
1499 		adapter->unm_nic_hw_write_wx(adapter,
1500 		    mem_crb+MIU_TEST_AGT_CTRL, &temp, 4);
1501 		temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
1502 		adapter->unm_nic_hw_write_wx(adapter,
1503 		    mem_crb+MIU_TEST_AGT_CTRL, &temp, 4);
1504 
1505 		for (j = 0; j < MAX_CTL_CHECK; j++) {
1506 			adapter->unm_nic_hw_read_wx(adapter,
1507 			    mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
1508 			if ((temp & MIU_TA_CTL_BUSY) == 0) {
1509 				break;
1510 			}
1511 		}
1512 
1513 		if (j >= MAX_CTL_CHECK) {
1514 			cmn_err(CE_WARN, "%s: Fail to write through agent\n",
1515 			    unm_nic_driver_name);
1516 			ret = -1;
1517 			break;
1518 		}
1519 	}
1520 
1521 //  unm_nic_pci_change_crbwindow_128M(adapter, 1);
1522 //  UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1523 	return (ret);
1524 }
1525 
1526 int
1527 unm_nic_pci_mem_read_2M(struct unm_adapter_s *adapter, u64 off, void *data,
1528     int size)
1529 {
1530 // unsigned long   flags;
1531 	int		i, j = 0, k, start, end, loop, sz[2], off0[2];
1532 	__uint32_t	temp;
1533 	__uint64_t	off8, val, mem_crb, word[2] = {0, 0};
1534 #define	MAX_CTL_CHECK   1000
1535 
1536 	/*
1537 	 * If not MN, go check for MS or invalid.
1538 	 */
1539 
1540 	if (off >= UNM_ADDR_QDR_NET && off <= NX_P3_ADDR_QDR_NET_MAX) {
1541 		mem_crb = UNM_CRB_QDR_NET;
1542 	} else {
1543 		mem_crb = UNM_CRB_DDR_NET;
1544 		if (unm_nic_pci_mem_bound_check(adapter, off, size) == 0)
1545 			return (unm_nic_pci_mem_read_direct(adapter,
1546 			    off, data, size));
1547 	}
1548 
1549 	off8 = off & 0xfffffff8;
1550 	off0[0] = off & 0x7;
1551 	off0[1] = 0;
1552 	sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
1553 	sz[1] = size - sz[0];
1554 	loop = ((off0[0] + size - 1) >> 3) + 1;
1555 
1556 // don't get lock - write_wx will get it
1557 // UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1558 // unm_nic_pci_change_crbwindow_128M(adapter, 0);
1559 
1560 	for (i = 0; i < loop; i++) {
1561 		temp = off8 + (i << 3);
1562 		adapter->unm_nic_hw_write_wx(adapter,
1563 		    mem_crb + MIU_TEST_AGT_ADDR_LO, &temp, 4);
1564 		temp = 0;
1565 		adapter->unm_nic_hw_write_wx(adapter,
1566 		    mem_crb + MIU_TEST_AGT_ADDR_HI, &temp, 4);
1567 		temp = MIU_TA_CTL_ENABLE;
1568 		adapter->unm_nic_hw_write_wx(adapter,
1569 		    mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
1570 		temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;
1571 		adapter->unm_nic_hw_write_wx(adapter,
1572 		    mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
1573 
1574 		for (j = 0; j < MAX_CTL_CHECK; j++) {
1575 			adapter->unm_nic_hw_read_wx(adapter,
1576 			    mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
1577 			if ((temp & MIU_TA_CTL_BUSY) == 0) {
1578 				break;
1579 			}
1580 		}
1581 
1582 		if (j >= MAX_CTL_CHECK) {
1583 			cmn_err(CE_WARN, "%s: Fail to read through agent\n",
1584 			    unm_nic_driver_name);
1585 			break;
1586 		}
1587 
1588 		start = off0[i] >> 2;
1589 		end   = (off0[i] + sz[i] - 1) >> 2;
1590 		for (k = start; k <= end; k++) {
1591 			adapter->unm_nic_hw_read_wx(adapter,
1592 			    mem_crb + MIU_TEST_AGT_RDDATA(k), &temp, 4);
1593 			word[i] |= ((__uint64_t)temp << (32 * k));
1594 		}
1595 	}
1596 
1597 // unm_nic_pci_change_crbwindow_128M(adapter, 1);
1598 // UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1599 
1600 	if (j >= MAX_CTL_CHECK)
1601 		return (-1);
1602 
1603 	if (sz[0] == 8) {
1604 		val = word[0];
1605 	} else {
1606 		val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
1607 		    ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
1608 	}
1609 
1610 	switch (size) {
1611 		case 1:
1612 			*(__uint8_t  *)data = val;
1613 			break;
1614 		case 2:
1615 			*(__uint16_t *)data = val;
1616 			break;
1617 		case 4:
1618 			*(__uint32_t *)data = val;
1619 			break;
1620 		case 8:
1621 			*(__uint64_t *)data = val;
1622 			break;
1623 	}
1624 	return (0);
1625 }
1626 
1627 int
1628 unm_crb_writelit_adapter_2M(struct unm_adapter_s *adapter, unsigned long off,
1629     int data)
1630 {
1631 	return (unm_nic_hw_write_wx_2M(adapter, off, &data, 4));
1632 }
1633 
1634 int
1635 unm_crb_writelit_adapter_128M(struct unm_adapter_s *adapter, unsigned long off,
1636     int data)
1637 {
1638 	void *addr;
1639 
1640 	if (ADDR_IN_WINDOW1(off)) {
1641 		UNM_READ_LOCK(&adapter->adapter_lock);
1642 		UNM_NIC_PCI_WRITE_32(data, CRB_NORMALIZE(adapter, off));
1643 		UNM_READ_UNLOCK(&adapter->adapter_lock);
1644 	} else {
1645 		// unm_nic_write_w0 (adapter, off, data);
1646 		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1647 		unm_nic_pci_change_crbwindow_128M(adapter, 0);
1648 		addr = (void *) (pci_base_offset(adapter, off));
1649 		UNM_NIC_PCI_WRITE_32(data, addr);
1650 		unm_nic_pci_change_crbwindow_128M(adapter, 1);
1651 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1652 	}
1653 
1654 	return (0);
1655 }
1656 
1657 int
1658 unm_nic_get_board_info(struct unm_adapter_s *adapter)
1659 {
1660 	int	rv = 0;
1661 	unm_board_info_t  *boardinfo;
1662 	int		i;
1663 	int		addr = BRDCFG_START;
1664 	uint32_t	  *ptr32;
1665 	uint32_t	gpioval;
1666 
1667 	boardinfo = &adapter->ahw.boardcfg;
1668 	ptr32 = (uint32_t *)boardinfo;
1669 
1670 	for (i = 0; i < sizeof (unm_board_info_t) / sizeof (uint32_t); i++) {
1671 		if (rom_fast_read(adapter, addr, (int *)ptr32) == -1) {
1672 			return (-1);
1673 		}
1674 		DPRINTF(1, (CE_WARN, "ROM(%d): %x\n", i, *ptr32));
1675 		ptr32++;
1676 		addr += sizeof (uint32_t);
1677 	}
1678 
1679 	if (boardinfo->magic != UNM_BDINFO_MAGIC) {
1680 		DPRINTF(1, (CE_WARN, "%s: ERROR reading board config."
1681 		    " Read %x, expected %x\n", unm_nic_driver_name,
1682 		    boardinfo->magic, UNM_BDINFO_MAGIC));
1683 		rv = -1;
1684 	}
1685 
1686 	if (boardinfo->header_version != UNM_BDINFO_VERSION) {
1687 		DPRINTF(1, (CE_WARN, "%s: Unknown board config version."
1688 		    " Read %x, expected %x\n", unm_nic_driver_name,
1689 		    boardinfo->header_version, UNM_BDINFO_VERSION));
1690 		rv = -1;
1691 	}
1692 
1693 	if (boardinfo->board_type == UNM_BRDTYPE_P3_4_GB_MM) {
1694 		gpioval = UNM_CRB_READ_VAL_ADAPTER(UNM_ROMUSB_GLB_PAD_GPIO_I,
1695 		    adapter);
1696 		if ((gpioval & 0x8000) == 0)
1697 			boardinfo->board_type = UNM_BRDTYPE_P3_10G_TRP;
1698 	}
1699 
1700 	DPRINTF(0, (CE_WARN, "Discovered board type:0x%x  ",
1701 	    boardinfo->board_type));
1702 
1703 	switch ((unm_brdtype_t)boardinfo->board_type) {
1704 	case UNM_BRDTYPE_P2_SB35_4G:
1705 		adapter->ahw.board_type = UNM_NIC_GBE;
1706 		break;
1707 	case UNM_BRDTYPE_P2_SB31_10G:
1708 	case UNM_BRDTYPE_P2_SB31_10G_IMEZ:
1709 	case UNM_BRDTYPE_P2_SB31_10G_HMEZ:
1710 	case UNM_BRDTYPE_P2_SB31_10G_CX4:
1711 	case UNM_BRDTYPE_P3_HMEZ:
1712 	case UNM_BRDTYPE_P3_XG_LOM:
1713 	case UNM_BRDTYPE_P3_10G_CX4:
1714 	case UNM_BRDTYPE_P3_10G_CX4_LP:
1715 	case UNM_BRDTYPE_P3_IMEZ:
1716 	case UNM_BRDTYPE_P3_10G_SFP_PLUS:
1717 	case UNM_BRDTYPE_P3_10G_XFP:
1718 	case UNM_BRDTYPE_P3_10000_BASE_T:
1719 		adapter->ahw.board_type = UNM_NIC_XGBE;
1720 		break;
1721 	case UNM_BRDTYPE_P3_REF_QG:
1722 	case UNM_BRDTYPE_P3_4_GB:
1723 	case UNM_BRDTYPE_P3_4_GB_MM:
1724 		adapter->ahw.board_type = UNM_NIC_GBE;
1725 		break;
1726 	case UNM_BRDTYPE_P1_BD:
1727 	case UNM_BRDTYPE_P1_SB:
1728 	case UNM_BRDTYPE_P1_SMAX:
1729 	case UNM_BRDTYPE_P1_SOCK:
1730 		adapter->ahw.board_type = UNM_NIC_GBE;
1731 		break;
1732 	case UNM_BRDTYPE_P3_10G_TRP:
1733 		if (adapter->portnum < 2)
1734 			adapter->ahw.board_type = UNM_NIC_XGBE;
1735 		else
1736 			adapter->ahw.board_type = UNM_NIC_GBE;
1737 		break;
1738 	default:
1739 		DPRINTF(1, (CE_WARN, "%s: Unknown(%x)\n", unm_nic_driver_name,
1740 		    boardinfo->board_type));
1741 		break;
1742 	}
1743 
1744 	return (rv);
1745 }
1746 
1747 /* NIU access sections */
1748 
1749 int
1750 unm_nic_macaddr_set(struct unm_adapter_s *adapter, __uint8_t *addr)
1751 {
1752 	int		ret = 0, i, retry_count = 10;
1753 	unsigned char		mac_addr[MAX_ADDR_LEN];
1754 
1755 	/* For P3, we should not set MAC in HW any more */
1756 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
1757 		return (0);
1758 
1759 	switch (adapter->ahw.board_type) {
1760 		case UNM_NIC_GBE:
1761 	/*
1762 	 * Flaky Mac address registers on qgig require several writes.
1763 	 */
1764 			for (i = 0; i < retry_count; ++i) {
1765 				if (unm_niu_macaddr_set(adapter, addr) != 0)
1766 					return (-1);
1767 
1768 				(void) unm_niu_macaddr_get(adapter,
1769 				    (unsigned char *)mac_addr);
1770 				if (memcmp(mac_addr, addr, 6) == 0)
1771 					return (0);
1772 			}
1773 			cmn_err(CE_WARN, "%s: Flaky MAC addr registers\n",
1774 			    unm_nic_driver_name);
1775 			break;
1776 
1777 		case UNM_NIC_XGBE:
1778 			ret = unm_niu_xg_macaddr_set(adapter, addr);
1779 			break;
1780 
1781 		default:
1782 			cmn_err(CE_WARN,  "\r\nUnknown board type encountered"
1783 			    " while setting the MAC address.\n");
1784 			return (-1);
1785 	}
1786 	return (ret);
1787 }
1788 
1789 #define	MTU_FUDGE_FACTOR 100
1790 int
1791 unm_nic_set_mtu(struct unm_adapter_s *adapter, int new_mtu)
1792 {
1793 	long		port = adapter->physical_port;
1794 	int			ret = 0;
1795 	u32			port_mode = 0;
1796 
1797 	if (adapter->ahw.revision_id >= NX_P3_A2)
1798 		return (nx_fw_cmd_set_mtu(adapter, new_mtu));
1799 
1800 	new_mtu += MTU_FUDGE_FACTOR; /* so that MAC accepts frames > MTU */
1801 	switch (adapter->ahw.board_type) {
1802 		case UNM_NIC_GBE:
1803 			unm_nic_write_w0(adapter,
1804 			    UNM_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port),
1805 			    new_mtu);
1806 
1807 			break;
1808 
1809 		case UNM_NIC_XGBE:
1810 			adapter->unm_nic_hw_read_wx(adapter, UNM_PORT_MODE_ADDR,
1811 			    &port_mode, 4);
1812 			if (port_mode == UNM_PORT_MODE_802_3_AP) {
1813 				unm_nic_write_w0(adapter,
1814 				    UNM_NIU_AP_MAX_FRAME_SIZE(port), new_mtu);
1815 			} else {
1816 				if (adapter->physical_port == 0) {
1817 					unm_nic_write_w0(adapter,
1818 					    UNM_NIU_XGE_MAX_FRAME_SIZE,
1819 					    new_mtu);
1820 				} else {
1821 					unm_nic_write_w0(adapter,
1822 					    UNM_NIU_XG1_MAX_FRAME_SIZE,
1823 					    new_mtu);
1824 				}
1825 			}
1826 			break;
1827 
1828 		default:
1829 			cmn_err(CE_WARN, "%s: Unknown brdtype\n",
1830 			    unm_nic_driver_name);
1831 	}
1832 
1833 	return (ret);
1834 }
1835 
1836 int
1837 unm_nic_set_promisc_mode(struct unm_adapter_s *adapter)
1838 {
1839 	int		ret;
1840 
1841 	if (adapter->promisc)
1842 		return (0);
1843 
1844 	switch (adapter->ahw.board_type) {
1845 		case UNM_NIC_GBE:
1846 			ret = unm_niu_set_promiscuous_mode(adapter,
1847 			    UNM_NIU_PROMISCOUS_MODE);
1848 			break;
1849 
1850 		case UNM_NIC_XGBE:
1851 			ret = unm_niu_xg_set_promiscuous_mode(adapter,
1852 			    UNM_NIU_PROMISCOUS_MODE);
1853 			break;
1854 
1855 		default:
1856 			cmn_err(CE_WARN, "%s: Unknown brdtype\n",
1857 			    unm_nic_driver_name);
1858 			ret = -1;
1859 			break;
1860 	}
1861 
1862 if (!ret)
1863 	adapter->promisc = 1;
1864 
1865 		return (ret);
1866 }
1867 
1868 int
1869 unm_nic_unset_promisc_mode(struct unm_adapter_s *adapter)
1870 {
1871 	int	ret = 0;
1872 
1873 	/*
1874 	 * P3 does not unset promiscous mode. Why?
1875 	 */
1876 	if (adapter->ahw.revision_id >= NX_P3_A2) {
1877 		return (0);
1878 	}
1879 
1880 	if (!adapter->promisc)
1881 		return (0);
1882 
1883 	switch (adapter->ahw.board_type) {
1884 		case UNM_NIC_GBE:
1885 			ret = unm_niu_set_promiscuous_mode(adapter,
1886 			    UNM_NIU_NON_PROMISCOUS_MODE);
1887 			break;
1888 
1889 		case UNM_NIC_XGBE:
1890 			ret = unm_niu_xg_set_promiscuous_mode(adapter,
1891 			    UNM_NIU_NON_PROMISCOUS_MODE);
1892 			break;
1893 
1894 		default:
1895 			cmn_err(CE_WARN, "%s: Unknown brdtype\n",
1896 			    unm_nic_driver_name);
1897 			ret = -1;
1898 			break;
1899 	}
1900 
1901 	if (!ret)
1902 		adapter->promisc = 0;
1903 
1904 	return (ret);
1905 }
1906 
1907 long
1908 unm_nic_phy_read(unm_adapter *adapter, long reg, __uint32_t *readval)
1909 {
1910 	long	ret = 0;
1911 
1912 	switch (adapter->ahw.board_type) {
1913 	case UNM_NIC_GBE:
1914 		ret = unm_niu_gbe_phy_read(adapter, reg, readval);
1915 		break;
1916 
1917 	case UNM_NIC_XGBE:
1918 		DPRINTF(1, (CE_WARN,
1919 		    "%s: Function %s is not implemented for XG\n",
1920 		    unm_nic_driver_name, __FUNCTION__));
1921 		break;
1922 
1923 	default:
1924 		DPRINTF(1, (CE_WARN, "%s: Unknown board type\n",
1925 		    unm_nic_driver_name));
1926 	}
1927 
1928 	return (ret);
1929 }
1930 
1931 long
1932 unm_nic_init_port(struct unm_adapter_s *adapter)
1933 {
1934 	long	portnum = adapter->physical_port;
1935 	long	ret = 0;
1936 	long	reg = 0;
1937 	u32			port_mode = 0;
1938 
1939 	unm_nic_set_link_parameters(adapter);
1940 
1941 	switch (adapter->ahw.board_type) {
1942 	case UNM_NIC_GBE:
1943 		ret = unm_niu_enable_gbe_port(adapter);
1944 		break;
1945 
1946 	case UNM_NIC_XGBE:
1947 		adapter->unm_nic_hw_read_wx(adapter, UNM_PORT_MODE_ADDR,
1948 		    &port_mode, 4);
1949 		if (port_mode == UNM_PORT_MODE_802_3_AP) {
1950 			ret = unm_niu_enable_gbe_port(adapter);
1951 		} else {
1952 			adapter->unm_crb_writelit_adapter(adapter,
1953 			    UNM_NIU_XGE_CONFIG_0 + (0x10000 * portnum), 0x5);
1954 			UNM_CRB_READ_CHECK_ADAPTER(UNM_NIU_XGE_CONFIG_1 +
1955 			    (0x10000 * portnum), &reg, adapter);
1956 			if (adapter->ahw.revision_id < NX_P3_A2)
1957 				reg = (reg & ~0x2000UL);
1958 			adapter->unm_crb_writelit_adapter(adapter,
1959 			    UNM_NIU_XGE_CONFIG_1 + (0x10000 * portnum), reg);
1960 		}
1961 		break;
1962 
1963 	default:
1964 		DPRINTF(1, (CE_WARN, "%s: Unknown board type\n",
1965 		    unm_nic_driver_name));
1966 	}
1967 
1968 	return (ret);
1969 }
1970 
1971 void
1972 unm_nic_stop_port(struct unm_adapter_s *adapter)
1973 {
1974 
1975 	(void) mac_unregister(adapter->mach);
1976 
1977 	switch (adapter->ahw.board_type) {
1978 	case UNM_NIC_GBE:
1979 		(void) unm_niu_disable_gbe_port(adapter);
1980 		break;
1981 
1982 	case UNM_NIC_XGBE:
1983 		(void) unm_niu_disable_xg_port(adapter);
1984 		break;
1985 
1986 	default:
1987 		DPRINTF(1, (CE_WARN, "%s: Unknown board type\n",
1988 		    unm_nic_driver_name));
1989 	}
1990 }
1991 
1992 void
1993 unm_crb_write_adapter(unsigned long off, void *data,
1994     struct unm_adapter_s *adapter)
1995 {
1996 	(void) adapter->unm_nic_hw_write_wx(adapter, off, data, 4);
1997 }
1998 
1999 int
2000 unm_crb_read_adapter(unsigned long off, void *data,
2001     struct unm_adapter_s *adapter)
2002 {
2003 	return (adapter->unm_nic_hw_read_wx(adapter, off, data, 4));
2004 }
2005 
2006 int
2007 unm_crb_read_val_adapter(unsigned long off, struct unm_adapter_s *adapter)
2008 {
2009 	int data;
2010 
2011 	adapter->unm_nic_hw_read_wx(adapter, off, &data, 4);
2012 	return (data);
2013 }
2014 
2015 void
2016 unm_nic_set_link_parameters(struct unm_adapter_s *adapter)
2017 {
2018 	unm_niu_phy_status_t status;
2019 	uint16_t defval = (uint16_t)-1;
2020 	unm_niu_control_t mode;
2021 	u32 port_mode = 0;
2022 
2023 	unm_nic_read_w0(adapter, UNM_NIU_MODE, (uint32_t *)&mode);
2024 	if (mode.enable_ge) { // Gb 10/100/1000 Mbps mode
2025 		adapter->unm_nic_hw_read_wx(adapter, UNM_PORT_MODE_ADDR,
2026 		    &port_mode, 4);
2027 		if (port_mode == UNM_PORT_MODE_802_3_AP) {
2028 			adapter->link_speed = MBPS_1000;
2029 			adapter->link_duplex = LINK_DUPLEX_FULL;
2030 		} else {
2031 		if (unm_nic_phy_read(adapter,
2032 		    UNM_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
2033 		    (unm_crbword_t *)&status) == 0) {
2034 			if (status.link) {
2035 				switch (status.speed) {
2036 				case 0: adapter->link_speed = MBPS_10;
2037 					break;
2038 				case 1: adapter->link_speed = MBPS_100;
2039 					break;
2040 				case 2: adapter->link_speed = MBPS_1000;
2041 					break;
2042 				default:
2043 					adapter->link_speed = defval;
2044 					break;
2045 				}
2046 				switch (status.duplex) {
2047 				case 0: adapter->link_duplex = LINK_DUPLEX_HALF;
2048 					break;
2049 				case 1: adapter->link_duplex = LINK_DUPLEX_FULL;
2050 					break;
2051 				default:
2052 					adapter->link_duplex = defval;
2053 					break;
2054 				}
2055 			} else {
2056 				adapter->link_speed = defval;
2057 				adapter->link_duplex = defval;
2058 			}
2059 		} else {
2060 			adapter->link_speed = defval;
2061 			adapter->link_duplex = defval;
2062 		}
2063 		}
2064 	}
2065 }
2066 
2067 void
2068 unm_nic_flash_print(struct unm_adapter_s *adapter)
2069 {
2070 	int valid = 1;
2071 	unm_board_info_t *board_info = &(adapter->ahw.boardcfg);
2072 
2073 	if (board_info->magic != UNM_BDINFO_MAGIC) {
2074 		cmn_err(CE_WARN, "%s UNM Unknown board config, Read 0x%x "
2075 		    "expected as 0x%x\n", unm_nic_driver_name,
2076 		    board_info->magic, UNM_BDINFO_MAGIC);
2077 		valid = 0;
2078 	}
2079 	if (board_info->header_version != UNM_BDINFO_VERSION) {
2080 		cmn_err(CE_WARN, "%s UNM Unknown board config version."
2081 		    " Read %x, expected %x\n", unm_nic_driver_name,
2082 		    board_info->header_version, UNM_BDINFO_VERSION);
2083 		valid = 0;
2084 	}
2085 	if (valid) {
2086 		unm_user_info_t  user_info;
2087 		int	i;
2088 		int	addr = USER_START;
2089 		int	*ptr32;
2090 
2091 		ptr32 = (int *)&user_info;
2092 		for (i = 0; i < sizeof (unm_user_info_t) / sizeof (uint32_t);
2093 		    i++) {
2094 			if (rom_fast_read(adapter, addr, ptr32) == -1) {
2095 				cmn_err(CE_WARN,
2096 				    "%s: ERROR reading %s board userarea.\n",
2097 				    unm_nic_driver_name, unm_nic_driver_name);
2098 				return;
2099 			}
2100 			ptr32++;
2101 			addr += sizeof (uint32_t);
2102 		}
2103 		if (verbmsg != 0) {
2104 			char	*brd_name;
2105 			GET_BRD_NAME_BY_TYPE(board_info->board_type, brd_name);
2106 			cmn_err(CE_NOTE, "%s %s Board S/N %s  Chip id 0x%x\n",
2107 			    unm_nic_driver_name, brd_name, user_info.serial_num,
2108 			    board_info->chip_id);
2109 		}
2110 	}
2111 }
2112 
2113 static int
2114 nx_nic_send_cmd_descs(unm_adapter *adapter, cmdDescType0_t *cmd_desc_arr,
2115     int nr_elements)
2116 {
2117 	struct unm_cmd_buffer	*pbuf;
2118 	unsigned int		i = 0, producer;
2119 
2120 	/*
2121 	 * We need to check if space is available.
2122 	 */
2123 	UNM_SPIN_LOCK(&adapter->tx_lock);
2124 	producer = adapter->cmdProducer;
2125 
2126 	do {
2127 		pbuf = &adapter->cmd_buf_arr[producer];
2128 		pbuf->head = pbuf->tail = NULL;
2129 		pbuf->msg = NULL;
2130 		(void) memcpy(&adapter->ahw.cmdDescHead[producer],
2131 		    &cmd_desc_arr[i], sizeof (cmdDescType0_t));
2132 		unm_desc_dma_sync(adapter->ahw.cmd_desc_dma_handle, producer,
2133 		    1, adapter->MaxTxDescCount, sizeof (cmdDescType0_t),
2134 		    DDI_DMA_SYNC_FORDEV);
2135 		producer = get_next_index(producer, adapter->MaxTxDescCount);
2136 		i++;
2137 	} while (i != nr_elements);
2138 
2139 	adapter->cmdProducer = adapter->ahw.cmdProducer = producer;
2140 	adapter->freecmds -= i;
2141 
2142 	unm_nic_update_cmd_producer(adapter, producer);
2143 
2144 	UNM_SPIN_UNLOCK(&adapter->tx_lock);
2145 	return (0);
2146 }
2147 
2148 typedef struct {
2149 	u64	qhdr, req_hdr, words[6];
2150 } nx_nic_req_t;
2151 
2152 typedef struct {
2153 	u8	op, tag, mac_addr[6];
2154 } nx_mac_req_t;
2155 
2156 static void
2157 nx_p3_sre_macaddr_change(unm_adapter *adapter, u8 *addr, u8 op)
2158 {
2159 	nx_nic_req_t	req;
2160 	nx_mac_req_t	mac_req;
2161 	int		rv;
2162 
2163 	(void) memset(&req, 0, sizeof (nx_nic_req_t));
2164 	req.qhdr |= (NX_NIC_REQUEST << 23);
2165 	req.req_hdr |= NX_MAC_EVENT;
2166 	req.req_hdr |= ((u64)adapter->portnum << 16);
2167 	mac_req.op = op;
2168 	(void) memcpy(&mac_req.mac_addr, addr, 6);
2169 	req.words[0] = HOST_TO_LE_64(*(u64 *)(uintptr_t)&mac_req);
2170 
2171 	rv = nx_nic_send_cmd_descs(adapter, (cmdDescType0_t *)&req, 1);
2172 	if (rv != 0)
2173 		cmn_err(CE_WARN, "%s%d: Could not send mac update\n",
2174 		    adapter->name, adapter->instance);
2175 }
2176 
2177 static int
2178 nx_p3_nic_set_promisc(unm_adapter *adapter, u32 mode)
2179 {
2180 	nx_nic_req_t	req;
2181 
2182 	(void) memset(&req, 0, sizeof (nx_nic_req_t));
2183 
2184 	req.qhdr |= (NX_HOST_REQUEST << 23);
2185 	req.req_hdr |= NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE;
2186 	req.req_hdr |= ((u64)adapter->portnum << 16);
2187 	req.words[0] = HOST_TO_LE_64(mode);
2188 
2189 	return (nx_nic_send_cmd_descs(adapter, (cmdDescType0_t *)&req, 1));
2190 }
2191 
2192 /*
2193  * Currently only invoked at interface initialization time
2194  */
2195 void
2196 nx_p3_nic_set_multi(unm_adapter *adapter)
2197 {
2198 	u8	bcast_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2199 
2200 	if (nx_p3_nic_set_promisc(adapter, VPORT_MISS_MODE_ACCEPT_ALL))
2201 		cmn_err(CE_WARN, "Could not set promisc mode\n");
2202 
2203 	nx_p3_sre_macaddr_change(adapter, adapter->mac_addr, NETXEN_MAC_ADD);
2204 	nx_p3_sre_macaddr_change(adapter, bcast_addr, NETXEN_MAC_ADD);
2205 }
2206