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