xref: /illumos-gate/usr/src/uts/common/io/ntxn/unm_nic_hw.c (revision d5ace9454616652a717c9831d949dffa319381f9)
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 	adapter->unm_crb_writelit_adapter(adapter, UNM_CRB_WIN_LOCK_ID,
330 	    adapter->portnum);
331 }
332 
333 static void
334 crb_win_unlock(struct unm_adapter_s *adapter)
335 {
336 	int	val;
337 
338 	adapter->unm_nic_hw_read_wx(adapter, UNM_PCIE_REG(PCIE_SEM7_UNLOCK),
339 	    &val, 4);
340 }
341 
342 /*
343  * Changes the CRB window to the specified window.
344  */
345 void
346 unm_nic_pci_change_crbwindow_128M(unm_adapter *adapter, uint32_t wndw)
347 {
348 	unm_pcix_crb_window_t	window;
349 	unsigned long			offset;
350 	uint32_t				tmp;
351 
352 	if (adapter->curr_window == wndw) {
353 		return;
354 	}
355 
356 	/*
357 	 * Move the CRB window.
358 	 * We need to write to the "direct access" region of PCI
359 	 * to avoid a race condition where the window register has
360 	 * not been successfully written across CRB before the target
361 	 * register address is received by PCI. The direct region bypasses
362 	 * the CRB bus.
363 	 */
364 	offset = PCI_OFFSET_SECOND_RANGE(adapter,
365 	    UNM_PCIX_PH_REG(PCIE_CRB_WINDOW_REG(adapter->ahw.pci_func)));
366 
367 	*(unm_crbword_t *)&window = 0;
368 	window.addrbit = wndw;
369 	UNM_NIC_PCI_WRITE_32(*(unsigned int *)&window, (void*) (offset));
370 	/* MUST make sure window is set before we forge on... */
371 	while ((tmp = UNM_NIC_PCI_READ_32((void*) offset)) !=
372 	    *(uint32_t *)&window) {
373 		cmn_err(CE_WARN, "%s: %s WARNING: CRB window value not "
374 		    "registered properly: 0x%08x.\n",
375 		    unm_nic_driver_name, __FUNCTION__, tmp);
376 	}
377 
378 	adapter->curr_window = wndw;
379 }
380 
381 
382 /*
383  * Changes the CRB window to the specified window.
384  */
385 /* ARGSUSED */
386 void
387 unm_nic_pci_change_crbwindow_2M(unm_adapter *adapter, uint32_t wndw)
388 {
389 }
390 
391 
392 uint32_t
393 unm_nic_get_crbwindow(unm_adapter *adapter)
394 {
395 	return (adapter->curr_window);
396 }
397 
398 /*
399  * Return -1 if off is not valid,
400  *	 1 if window access is needed. 'off' is set to offset from
401  *	   CRB space in 128M pci map
402  *	 0 if no window access is needed. 'off' is set to 2M addr
403  * In: 'off' is offset from base in 128M pci map
404  */
405 int
406 unm_nic_pci_get_crb_addr_2M(unm_adapter *adapter, u64 *off, int len)
407 {
408 	unsigned long end = *off + len;
409 	crb_128M_2M_sub_block_map_t *m;
410 
411 
412 	if (*off >= UNM_CRB_MAX)
413 		return (-1);
414 
415 	if (*off >= UNM_PCI_CAMQM && (end <= UNM_PCI_CAMQM_2M_END)) {
416 		*off = (*off - UNM_PCI_CAMQM) + UNM_PCI_CAMQM_2M_BASE +
417 		    adapter->ahw.pci_base0;
418 		return (0);
419 	}
420 
421 	if (*off < UNM_PCI_CRBSPACE)
422 		return (-1);
423 
424 	*off -= UNM_PCI_CRBSPACE;
425 	end = *off + len;
426 	/*
427 	 * Try direct map
428 	 */
429 
430 	m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)];
431 
432 	if (m->valid && (m->start_128M <= *off) && (m->end_128M >= end)) {
433 		*off = *off + m->start_2M - m->start_128M +
434 		    adapter->ahw.pci_base0;
435 		return (0);
436 	}
437 
438 	/*
439 	 * Not in direct map, use crb window
440 	 */
441 	return (1);
442 }
443 /*
444  * In: 'off' is offset from CRB space in 128M pci map
445  * Out: 'off' is 2M pci map addr
446  * side effect: lock crb window
447  */
448 static void
449 unm_nic_pci_set_crbwindow_2M(unm_adapter *adapter, u64 *off)
450 {
451 	u32 win_read;
452 
453 	adapter->crb_win = CRB_HI(*off);
454 	UNM_NIC_PCI_WRITE_32(adapter->crb_win, (void *) (CRB_WINDOW_2M +
455 	    adapter->ahw.pci_base0));
456 	/*
457 	 * Read back value to make sure write has gone through before trying
458 	 * to use it.
459 	 */
460 	win_read = UNM_NIC_PCI_READ_32((void *)
461 	    (CRB_WINDOW_2M + adapter->ahw.pci_base0));
462 	if (win_read != adapter->crb_win) {
463 		cmn_err(CE_WARN, "%s: Written crbwin (0x%x) != Read crbwin "
464 		    "(0x%x), off=0x%llx\n", __FUNCTION__, adapter->crb_win,
465 		    win_read, *off);
466 	}
467 	*off = (*off & MASK(16)) + CRB_INDIRECT_2M +
468 	    adapter->ahw.pci_base0;
469 }
470 
471 int
472 unm_nic_hw_write_ioctl_128M(unm_adapter *adapter, u64 off, void *data, int len)
473 {
474 	void		*addr;
475 	u64		offset = off;
476 
477 	if (ADDR_IN_WINDOW1(off)) { // Window 1
478 		addr = CRB_NORMALIZE(adapter, off);
479 		if (!addr) {
480 			offset = CRB_NORMAL(off);
481 			if (adapter->ahw.pci_len0 == 0)
482 				offset -= UNM_PCI_CRBSPACE;
483 			addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 +
484 			    offset);
485 		}
486 		UNM_READ_LOCK(&adapter->adapter_lock);
487 	} else {// Window 0
488 		addr = (void *) (uptr_t)(pci_base_offset(adapter, off));
489 		if (!addr) {
490 			offset = off;
491 			addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 +
492 			    offset);
493 		}
494 		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
495 		unm_nic_pci_change_crbwindow_128M(adapter, 0);
496 	}
497 
498 	switch (len) {
499 		case 1:
500 			UNM_NIC_PCI_WRITE_8 (*(__uint8_t *)data, addr);
501 			break;
502 		case 2:
503 			UNM_NIC_PCI_WRITE_16 (*(__uint16_t *)data, addr);
504 			break;
505 		case 4:
506 			UNM_NIC_PCI_WRITE_32 (*(__uint32_t *)data, addr);
507 			break;
508 		case 8:
509 			UNM_NIC_PCI_WRITE_64 (*(__uint64_t *)data, addr);
510 			break;
511 		default:
512 #if !defined(NDEBUG)
513 		if ((len & 0x7) != 0)
514 			cmn_err(CE_WARN, "%s: %s len(%d) not multiple of 8.\n",
515 			    unm_nic_driver_name, __FUNCTION__, len);
516 #endif
517 		UNM_NIC_HW_BLOCK_WRITE_64(data, addr, (len>>3));
518 		break;
519 	}
520 	if (ADDR_IN_WINDOW1(off)) {// Window 1
521 		UNM_READ_UNLOCK(&adapter->adapter_lock);
522 	} else {// Window 0
523 		unm_nic_pci_change_crbwindow_128M(adapter, 1);
524 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
525 	}
526 
527 	return (0);
528 }
529 
530 /*
531  * Note : 'len' argument should be either 1, 2, 4, or a multiple of 8.
532  */
533 int
534 unm_nic_hw_write_wx_128M(unm_adapter *adapter, u64 off, void *data, int len)
535 {
536 	/*
537 	 * This is modified from _unm_nic_hw_write().
538 	 * unm_nic_hw_write does not exist now.
539 	 */
540 
541 	void *addr;
542 
543 	if (ADDR_IN_WINDOW1(off)) {// Window 1
544 		addr = CRB_NORMALIZE(adapter, off);
545 		UNM_READ_LOCK(&adapter->adapter_lock);
546 	} else {// Window 0
547 		addr = (void *) (uptr_t)(pci_base_offset(adapter, off));
548 		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
549 		unm_nic_pci_change_crbwindow_128M(adapter, 0);
550 	}
551 
552 
553 	if (!addr) {
554 		if (ADDR_IN_WINDOW1(off)) {// Window 1
555 			UNM_READ_UNLOCK(&adapter->adapter_lock);
556 		} else {// Window 0
557 			unm_nic_pci_change_crbwindow_128M(adapter, 1);
558 			UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
559 		}
560 		return (1);
561 	}
562 
563 	switch (len) {
564 		case 1:
565 			UNM_NIC_PCI_WRITE_8 (*(__uint8_t *)data, addr);
566 			break;
567 		case 2:
568 			UNM_NIC_PCI_WRITE_16 (*(__uint16_t *)data, addr);
569 			break;
570 		case 4:
571 			UNM_NIC_PCI_WRITE_32 (*(__uint32_t *)data, addr);
572 			break;
573 		case 8:
574 			UNM_NIC_PCI_WRITE_64 (*(__uint64_t *)data, addr);
575 			break;
576 		default:
577 #if !defined(NDEBUG)
578 			if ((len & 0x7) != 0)
579 				cmn_err(CE_WARN,
580 				    "%s: %s  len(%d) not multiple of 8.\n",
581 				    unm_nic_driver_name, __FUNCTION__, len);
582 #endif
583 			UNM_NIC_HW_BLOCK_WRITE_64(data, addr, (len>>3));
584 			break;
585 	}
586 	if (ADDR_IN_WINDOW1(off)) {// Window 1
587 		UNM_READ_UNLOCK(&adapter->adapter_lock);
588 	} else {// Window 0
589 		unm_nic_pci_change_crbwindow_128M(adapter, 1);
590 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
591 	}
592 
593 	return (0);
594 }
595 
596 /*
597  * Note : only 32-bit writes!
598  */
599 void
600 unm_nic_pci_write_normalize_128M(unm_adapter *adapter, u64 off, u32 data)
601 {
602 	UNM_NIC_PCI_WRITE_32(data, CRB_NORMALIZE(adapter, off));
603 }
604 
605 /*
606  * Note : only 32-bit reads!
607  */
608 u32
609 unm_nic_pci_read_normalize_128M(unm_adapter *adapter, u64 off)
610 {
611 	return (UNM_NIC_PCI_READ_32(CRB_NORMALIZE(adapter, off)));
612 }
613 
614 /*
615  * Note : only 32-bit writes!
616  */
617 int
618 unm_nic_pci_write_immediate_128M(unm_adapter *adapter, u64 off, u32 *data)
619 {
620 	UNM_NIC_PCI_WRITE_32(*data,
621 	    (void *) (uptr_t)(PCI_OFFSET_SECOND_RANGE(adapter, off)));
622 	return (0);
623 }
624 
625 /*
626  * Note : only 32-bit reads!
627  */
628 int
629 unm_nic_pci_read_immediate_128M(unm_adapter *adapter, u64 off, u32 *data)
630 {
631 	*data = UNM_NIC_PCI_READ_32((void *)
632 	    (uptr_t)(pci_base_offset(adapter, off)));
633 	return (0);
634 }
635 
636 /*
637  * Note : only 32-bit writes!
638  */
639 void
640 unm_nic_pci_write_normalize_2M(unm_adapter *adapter, u64 off, u32 data)
641 {
642 	u32 temp = data;
643 
644 	adapter->unm_nic_hw_write_wx(adapter, off, &temp, 4);
645 }
646 
647 /*
648  * Note : only 32-bit reads!
649  */
650 u32
651 unm_nic_pci_read_normalize_2M(unm_adapter *adapter, u64 off)
652 {
653 	u32 temp;
654 
655 	adapter->unm_nic_hw_read_wx(adapter, off, &temp, 4);
656 
657 	return (temp);
658 }
659 
660 /*
661  * Note : only 32-bit writes!
662  */
663 int
664 unm_nic_pci_write_immediate_2M(unm_adapter *adapter, u64 off, u32 *data)
665 {
666 	u32 temp = *data;
667 
668 	adapter->unm_nic_hw_write_wx(adapter, off, &temp, 4);
669 
670 	return (0);
671 }
672 
673 /*
674  * Note : only 32-bit reads!
675  */
676 int
677 unm_nic_pci_read_immediate_2M(unm_adapter *adapter, u64 off, u32 *data)
678 {
679 	u32 temp;
680 
681 	adapter->unm_nic_hw_read_wx(adapter, off, &temp, 4);
682 
683 	*data = temp;
684 
685 	return (0);
686 }
687 
688 /*
689  * write cross hw window boundary is not supported
690  * 'len' should be either 1, 2, 4, or multiple of 8
691  */
692 int
693 unm_nic_hw_write_wx_2M(unm_adapter *adapter, u64 off, void *data, int len)
694 {
695 	int rv;
696 
697 	rv = unm_nic_pci_get_crb_addr_2M(adapter, &off, len);
698 
699 	if (rv == -1) {
700 		cmn_err(CE_PANIC, "%s: invalid offset: 0x%016llx\n",
701 		    __FUNCTION__, off);
702 		return (-1);
703 	}
704 
705 	if (rv == 1) {
706 		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
707 		crb_win_lock(adapter);
708 		unm_nic_pci_set_crbwindow_2M(adapter, &off);
709 	}
710 
711 	switch (len) {
712 	case 1:
713 		UNM_NIC_PCI_WRITE_8(*(__uint8_t *)data, (void *) (uptr_t)off);
714 		break;
715 	case 2:
716 		UNM_NIC_PCI_WRITE_16(*(__uint16_t *)data, (void *) (uptr_t)off);
717 		break;
718 	case 4:
719 		UNM_NIC_PCI_WRITE_32(*(__uint32_t *)data, (void *) (uptr_t)off);
720 		break;
721 	case 8:
722 		UNM_NIC_PCI_WRITE_64(*(__uint64_t *)data, (void *) (uptr_t)off);
723 		break;
724 	default:
725 #if !defined(NDEBUG)
726 		if ((len & 0x7) != 0)
727 			cmn_err(CE_WARN, "%s: %s  len(%d) not multiple of 8.\n",
728 			    unm_nic_driver_name, __FUNCTION__, len);
729 #endif
730 		UNM_NIC_HW_BLOCK_WRITE_64(data, (uptr_t)off, (len>>3));
731 		break;
732 	}
733 	if (rv == 1) {
734 		crb_win_unlock(adapter);
735 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
736 	}
737 
738 	return (0);
739 }
740 
741 int
742 unm_nic_hw_read_ioctl_128M(unm_adapter *adapter, u64 off, void *data, int len)
743 {
744 	void		*addr;
745 	u64		offset;
746 
747 	if (ADDR_IN_WINDOW1(off)) {// Window 1
748 		addr = CRB_NORMALIZE(adapter, off);
749 		if (!addr) {
750 			offset = CRB_NORMAL(off);
751 			if (adapter->ahw.pci_len0 == 0)
752 				offset -= UNM_PCI_CRBSPACE;
753 			addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 +
754 			    offset);
755 		}
756 		UNM_READ_LOCK(&adapter->adapter_lock);
757 	} else {// Window 0
758 		addr = (void *) (uptr_t)(pci_base_offset(adapter, off));
759 		if (!addr) {
760 			offset = off;
761 			addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 +
762 			    offset);
763 		}
764 		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
765 		unm_nic_pci_change_crbwindow_128M(adapter, 0);
766 	}
767 
768 	switch (len) {
769 	case 1:
770 		*(__uint8_t  *)data = UNM_NIC_PCI_READ_8(addr);
771 		break;
772 	case 2:
773 		*(__uint16_t *)data = UNM_NIC_PCI_READ_16(addr);
774 		break;
775 	case 4:
776 		*(__uint32_t *)data = UNM_NIC_PCI_READ_32(addr);
777 		break;
778 	case 8:
779 		*(__uint64_t *)data = UNM_NIC_PCI_READ_64(addr);
780 		break;
781 	default:
782 #if !defined(NDEBUG)
783 		if ((len & 0x7) != 0)
784 			cmn_err(CE_WARN, "%s: %s len(%d) not multiple of 8.\n",
785 			    unm_nic_driver_name, __FUNCTION__, len);
786 #endif
787 		UNM_NIC_HW_BLOCK_READ_64(data, addr, (len>>3));
788 		break;
789 	}
790 
791 	if (ADDR_IN_WINDOW1(off)) {// Window 1
792 		UNM_READ_UNLOCK(&adapter->adapter_lock);
793 	} else {// Window 0
794 		unm_nic_pci_change_crbwindow_128M(adapter, 1);
795 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
796 	}
797 
798 	return (0);
799 }
800 
801 int
802 unm_nic_hw_read_wx_2M(unm_adapter *adapter, u64 off, void *data, int len)
803 {
804 	int rv;
805 
806 	rv = unm_nic_pci_get_crb_addr_2M(adapter, &off, len);
807 
808 	if (rv == -1) {
809 		cmn_err(CE_PANIC, "%s: invalid offset: 0x%016llx\n",
810 		    __FUNCTION__, off);
811 		return (-1);
812 	}
813 
814 	if (rv == 1) {
815 		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
816 		crb_win_lock(adapter);
817 		unm_nic_pci_set_crbwindow_2M(adapter, &off);
818 	}
819 
820 	switch (len) {
821 	case 1:
822 		*(__uint8_t  *)data = UNM_NIC_PCI_READ_8((void *) (uptr_t)off);
823 		break;
824 	case 2:
825 		*(__uint16_t *)data = UNM_NIC_PCI_READ_16((void *) (uptr_t)off);
826 		break;
827 	case 4:
828 		*(__uint32_t *)data = UNM_NIC_PCI_READ_32((void *) (uptr_t)off);
829 		break;
830 	case 8:
831 		*(__uint64_t *)data = UNM_NIC_PCI_READ_64((void *) (uptr_t)off);
832 		break;
833 	default:
834 #if !defined(NDEBUG)
835 		if ((len & 0x7) != 0)
836 			cmn_err(CE_WARN, "%s: %s len(%d) not multiple of 8.\n",
837 			    unm_nic_driver_name, __FUNCTION__, len);
838 #endif
839 		UNM_NIC_HW_BLOCK_READ_64(data, (void *) (uptr_t)off, (len>>3));
840 		break;
841 	}
842 
843 	if (rv == 1) {
844 		crb_win_unlock(adapter);
845 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
846 	}
847 
848 	return (0);
849 }
850 
851 int
852 unm_nic_hw_read_wx_128M(unm_adapter *adapter, u64 off, void *data, int len)
853 {
854 	void *addr;
855 
856 	if (ADDR_IN_WINDOW1(off)) {
857 		// Window 1
858 		addr = CRB_NORMALIZE(adapter, off);
859 		UNM_READ_LOCK(&adapter->adapter_lock);
860 	} else {// Window 0
861 		addr = (void *) (uptr_t)(pci_base_offset(adapter, off));
862 		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
863 		unm_nic_pci_change_crbwindow_128M(adapter, 0);
864 	}
865 
866 	if (!addr) {
867 		if (ADDR_IN_WINDOW1(off)) {// Window 1
868 			UNM_READ_UNLOCK(&adapter->adapter_lock);
869 		} else {// Window 0
870 			unm_nic_pci_change_crbwindow_128M(adapter, 1);
871 			UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
872 		}
873 		return (1);
874 	}
875 
876 	switch (len) {
877 		case 1:
878 			*(__uint8_t  *)data = UNM_NIC_PCI_READ_8(addr);
879 			break;
880 		case 2:
881 			*(__uint16_t *)data = UNM_NIC_PCI_READ_16(addr);
882 			break;
883 		case 4:
884 			*(__uint32_t *)data = UNM_NIC_PCI_READ_32(addr);
885 			break;
886 		case 8:
887 			*(__uint64_t *)data = UNM_NIC_PCI_READ_64(addr);
888 			break;
889 		default:
890 #if !defined(NDEBUG)
891 			if ((len & 0x7) != 0)
892 				cmn_err(CE_WARN,
893 				    "%s: %s len(%d) not multiple of 8.\n",
894 				    unm_nic_driver_name, __FUNCTION__, len);
895 #endif
896 			UNM_NIC_HW_BLOCK_READ_64(data, addr, (len>>3));
897 			break;
898 	}
899 
900 	if (ADDR_IN_WINDOW1(off)) {// Window 1
901 		UNM_READ_UNLOCK(&adapter->adapter_lock);
902 	} else {// Window 0
903 		unm_nic_pci_change_crbwindow_128M(adapter, 1);
904 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
905 	}
906 
907 	return (0);
908 }
909 
910 /*  PCI Windowing for DDR regions.  */
911 #define	ADDR_IN_RANGE(addr, low, high)	    \
912 	(((addr) <= (high)) && ((low) ? ((addr) >= (low)) : 1))
913 
914 /*
915  * check memory access boundary.
916  * used by test agent. support ddr access only for now
917  */
918 /* ARGSUSED */
919 static unsigned long
920 unm_nic_pci_mem_bound_check(struct unm_adapter_s *adapter,
921     unsigned long long addr, int size)
922 {
923 	if (!ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX) ||
924 	    !ADDR_IN_RANGE(addr + size -1, UNM_ADDR_DDR_NET,
925 	    UNM_ADDR_DDR_NET_MAX) || ((size != 1) && (size != 2) &&
926 	    (size != 4) && (size != 8)))
927 		return (0);
928 
929 	return (1);
930 }
931 
932 int unm_pci_set_window_warning_count = 0;
933 
934 unsigned long long
935 unm_nic_pci_set_window_128M(struct unm_adapter_s *adapter,
936     unsigned long long addr)
937 {
938 	int		window;
939 	unsigned long long	qdr_max;
940 
941 	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
942 		qdr_max = NX_P2_ADDR_QDR_NET_MAX;
943 	} else {
944 		qdr_max = NX_P3_ADDR_QDR_NET_MAX;
945 	}
946 
947 	if (ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX)) {
948 		/* DDR network side */
949 		/* MN access should never come here */
950 		cmn_err(CE_PANIC, "%s\n", __FUNCTION__);
951 		addr = -1ULL;
952 	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM0, UNM_ADDR_OCM0_MAX)) {
953 		addr -= UNM_ADDR_OCM0;
954 		addr += UNM_PCI_OCM0;
955 	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM1, UNM_ADDR_OCM1_MAX)) {
956 		addr -= UNM_ADDR_OCM1;
957 		addr += UNM_PCI_OCM1;
958 	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET, qdr_max)) {
959 		/* QDR network side */
960 		addr -= UNM_ADDR_QDR_NET;
961 		window = (addr >> 22) & 0x3f;
962 		if (adapter->ahw.qdr_sn_window != window) {
963 			adapter->ahw.qdr_sn_window = window;
964 			UNM_NIC_PCI_WRITE_32((window << 22),
965 			    (void *) (uptr_t)(PCI_OFFSET_SECOND_RANGE(adapter,
966 			    UNM_PCIX_PH_REG(PCIE_SN_WINDOW_REG(
967 			    adapter->ahw.pci_func)))));
968 			/* MUST make sure window is set before we forge on... */
969 			(void) UNM_NIC_PCI_READ_32((void *)
970 			    (uptr_t)(PCI_OFFSET_SECOND_RANGE(adapter,
971 			    UNM_PCIX_PH_REG(PCIE_SN_WINDOW_REG(
972 			    adapter->ahw.pci_func)))));
973 		}
974 		addr -= (window * 0x400000);
975 		addr += UNM_PCI_QDR_NET;
976 	} else {
977 		/*
978 		 * peg gdb frequently accesses memory that doesn't exist,
979 		 * this limits the chit chat so debugging isn't slowed down.
980 		 */
981 		if ((unm_pci_set_window_warning_count++ < 8) ||
982 		    (unm_pci_set_window_warning_count%64 == 0)) {
983 			cmn_err(CE_WARN, "%s: Warning:unm_nic_pci_set_window() "
984 			    "Unknown address range!\n", unm_nic_driver_name);
985 		}
986 		addr = -1ULL;
987 	}
988 	return (addr);
989 }
990 
991 unsigned long long
992 unm_nic_pci_set_window_2M(struct unm_adapter_s *adapter,
993     unsigned long long addr)
994 {
995 	int window;
996 	u32 win_read;
997 
998 	if (ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX)) {
999 		/* DDR network side */
1000 		window = MN_WIN(addr);
1001 		adapter->ahw.ddr_mn_window = window;
1002 		adapter->unm_nic_hw_write_wx(adapter, adapter->ahw.mn_win_crb |
1003 		    UNM_PCI_CRBSPACE, &window, 4);
1004 		adapter->unm_nic_hw_read_wx(adapter, adapter->ahw.mn_win_crb |
1005 		    UNM_PCI_CRBSPACE, &win_read, 4);
1006 		if ((win_read << 17) != window) {
1007 			cmn_err(CE_WARN,
1008 			    "%s: Written MNwin (0x%x) != Read MNwin (0x%x)\n",
1009 			    __FUNCTION__, window, win_read);
1010 		}
1011 		addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_DDR_NET;
1012 	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM0, UNM_ADDR_OCM0_MAX)) {
1013 		unsigned int temp1;
1014 // OCM: pci_addr[20:18] == 011 && pci_addr[17:11] != 7f
1015 		if ((addr & 0x00ff800) == 0xff800) {
1016 			// if bits 19:18&17:11 are on
1017 			cmn_err(CE_WARN, "%s: QM access not handled.\n",
1018 			    __FUNCTION__);
1019 			addr = -1ULL;
1020 		}
1021 
1022 		window = OCM_WIN(addr);
1023 		adapter->ahw.ddr_mn_window = window;
1024 		adapter->unm_nic_hw_write_wx(adapter, adapter->ahw.mn_win_crb |
1025 		    UNM_PCI_CRBSPACE, &window, 4);
1026 		adapter->unm_nic_hw_read_wx(adapter, adapter->ahw.mn_win_crb |
1027 		    UNM_PCI_CRBSPACE, &win_read, 4);
1028 		temp1 = ((window & 0x1FF) << 7) |
1029 		    ((window & 0x0FFFE0000) >> 17);
1030 		if (win_read != temp1) {
1031 			cmn_err(CE_WARN,
1032 			    "%s: Written OCMwin(0x%x) != Read OCMwin(0x%x)\n",
1033 			    __FUNCTION__, temp1, win_read);
1034 		}
1035 		addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_OCM0_2M;
1036 
1037 	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET,
1038 	    NX_P3_ADDR_QDR_NET_MAX)) {
1039 		/* QDR network side */
1040 		window = MS_WIN(addr);
1041 		adapter->ahw.qdr_sn_window = window;
1042 		adapter->unm_nic_hw_write_wx(adapter, adapter->ahw.ms_win_crb |
1043 		    UNM_PCI_CRBSPACE, &window, 4);
1044 		adapter->unm_nic_hw_read_wx(adapter, adapter->ahw.ms_win_crb |
1045 		    UNM_PCI_CRBSPACE, &win_read, 4);
1046 		if (win_read != window) {
1047 			cmn_err(CE_WARN,
1048 			    "%s: Written MSwin (0x%x) != Read MSwin (0x%x)\n",
1049 			    __FUNCTION__, window, win_read);
1050 		}
1051 		addr = GET_MEM_OFFS_2M(addr) + UNM_PCI_QDR_NET;
1052 
1053 	} else {
1054 		/*
1055 		 * peg gdb frequently accesses memory that doesn't exist,
1056 		 * this limits the chit chat so debugging isn't slowed down.
1057 		 */
1058 		if ((unm_pci_set_window_warning_count++ < 8) ||
1059 		    (unm_pci_set_window_warning_count%64 == 0)) {
1060 			cmn_err(CE_WARN, "%s%d: %s Unknown address range!\n",
1061 			    adapter->name, adapter->instance, __FUNCTION__);
1062 		}
1063 		addr = -1ULL;
1064 	}
1065 	return (addr);
1066 }
1067 
1068 /* check if address is in the same windows as the previous access */
1069 static unsigned long
1070 unm_nic_pci_is_same_window(struct unm_adapter_s *adapter,
1071     unsigned long long addr)
1072 {
1073 	int			window;
1074 	unsigned long long	qdr_max;
1075 
1076 	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
1077 		qdr_max = NX_P2_ADDR_QDR_NET_MAX;
1078 	} else {
1079 		qdr_max = NX_P3_ADDR_QDR_NET_MAX;
1080 	}
1081 
1082 	if (ADDR_IN_RANGE(addr, UNM_ADDR_DDR_NET, UNM_ADDR_DDR_NET_MAX)) {
1083 		/* DDR network side */
1084 		/* MN access can not come here */
1085 		cmn_err(CE_PANIC, "%s\n", __FUNCTION__);
1086 #if 0
1087 		window = ((addr - UNM_ADDR_DDR_NET) >> 25) & 0x3ff;
1088 		if (adapter->ahw.ddr_mn_window == window) {
1089 			return (1);
1090 		}
1091 #endif
1092 	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM0, UNM_ADDR_OCM0_MAX)) {
1093 		return (1);
1094 	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_OCM1, UNM_ADDR_OCM1_MAX)) {
1095 		return (1);
1096 	} else if (ADDR_IN_RANGE(addr, UNM_ADDR_QDR_NET, qdr_max)) {
1097 		/* QDR network side */
1098 		window = ((addr - UNM_ADDR_QDR_NET) >> 22) & 0x3f;
1099 		if (adapter->ahw.qdr_sn_window == window) {
1100 			return (1);
1101 		}
1102 	}
1103 
1104 	return (0);
1105 }
1106 
1107 static int
1108 unm_nic_pci_mem_read_direct(struct unm_adapter_s *adapter,
1109     u64 off, void *data, int size)
1110 {
1111 	void			*addr;
1112 	int				ret = 0;
1113 	u64				start;
1114 
1115 #if 0
1116 	/*
1117 	 * This check can not be currently executed, since phanmon findq
1118 	 * command breaks this check whereby 8 byte reads are being attempted
1119 	 * on "aligned-by-4" addresses on x86. Reason this works is our version
1120 	 * breaks up the access into 2 consecutive 4 byte writes; on other
1121 	 * architectures, this might require "aligned-by-8" addresses and we
1122 	 * will run into trouble.
1123 	 *
1124 	 * Check alignment for expected sizes of 1, 2, 4, 8. Other size
1125 	 * values will not trigger access.
1126 	 */
1127 	if ((off & (size - 1)) != 0)
1128 		return (-1);
1129 #endif
1130 
1131 	UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1132 
1133 	/*
1134 	 * If attempting to access unknown address or straddle hw windows,
1135 	 * do not access.
1136 	 */
1137 	if (((start = adapter->unm_nic_pci_set_window(adapter, off)) == -1UL) ||
1138 	    (unm_nic_pci_is_same_window(adapter, off + size -1) == 0)) {
1139 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1140 		cmn_err(CE_WARN, "%s out of bound pci memory access. "
1141 		    "offset is 0x%llx\n", unm_nic_driver_name, off);
1142 		return (-1);
1143 	}
1144 
1145 	addr = (void *) (uptr_t)(pci_base_offset(adapter, start));
1146 	if (!addr)
1147 		addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 + start);
1148 
1149 	switch (size) {
1150 		case 1:
1151 			*(__uint8_t  *)data = UNM_NIC_PCI_READ_8(addr);
1152 			break;
1153 		case 2:
1154 			*(__uint16_t *)data = UNM_NIC_PCI_READ_16(addr);
1155 			break;
1156 		case 4:
1157 			*(__uint32_t *)data = UNM_NIC_PCI_READ_32(addr);
1158 			break;
1159 		case 8:
1160 			*(__uint64_t *)data = UNM_NIC_PCI_READ_64(addr);
1161 			break;
1162 		default:
1163 			ret = -1;
1164 			break;
1165 	}
1166 
1167 	UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1168 	return (ret);
1169 }
1170 
1171 static int
1172 unm_nic_pci_mem_write_direct(struct unm_adapter_s *adapter, u64 off,
1173     void *data, int size)
1174 {
1175 	void	*addr;
1176 	int		ret = 0;
1177 	u64		start;
1178 
1179 #if 0
1180 	/*
1181 	 * This check can not be currently executed, since firmware load
1182 	 * breaks this check whereby 8 byte writes are being attempted on
1183 	 * "aligned-by-4" addresses on x86. Reason this works is our version
1184 	 * breaks up the access into 2 consecutive 4 byte writes; on other
1185 	 * architectures, this might require "aligned-by-8" addresses and we
1186 	 * will run into trouble.
1187 	 *
1188 	 * Check alignment for expected sizes of 1, 2, 4, 8. Other size
1189 	 * values will not trigger access.
1190 	 */
1191 	if ((off & (size - 1)) != 0)
1192 		return (-1);
1193 #endif
1194 
1195 	UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1196 
1197 	/*
1198 	 * If attempting to access unknown address or straddle hw windows,
1199 	 * do not access.
1200 	 */
1201 	if (((start = adapter->unm_nic_pci_set_window(adapter, off)) == -1UL) ||
1202 	    (unm_nic_pci_is_same_window(adapter, off + size -1) == 0)) {
1203 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1204 		cmn_err(CE_WARN, "%s out of bound pci memory access. "
1205 		    "offset is 0x%llx\n", unm_nic_driver_name, off);
1206 		return (-1);
1207 	}
1208 
1209 	addr = (void *) (uptr_t)(pci_base_offset(adapter, start));
1210 	if (!addr)
1211 		addr = (void *) ((uint8_t *)adapter->ahw.pci_base0 + start);
1212 
1213 	switch (size) {
1214 		case 1:
1215 			UNM_NIC_PCI_WRITE_8(*(__uint8_t  *)data, addr);
1216 			break;
1217 		case 2:
1218 			UNM_NIC_PCI_WRITE_16(*(__uint16_t *)data, addr);
1219 			break;
1220 		case 4:
1221 			UNM_NIC_PCI_WRITE_32(*(__uint32_t *)data, addr);
1222 			break;
1223 		case 8:
1224 			UNM_NIC_PCI_WRITE_64(*(__uint64_t *)data, addr);
1225 			break;
1226 		default:
1227 			ret = -1;
1228 			break;
1229 	}
1230 	UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1231 	return (ret);
1232 }
1233 
1234 
1235 int
1236 unm_nic_pci_mem_write_128M(struct unm_adapter_s *adapter, u64 off, void *data,
1237     int size)
1238 {
1239 	int		i, j, ret = 0, loop, sz[2], off0;
1240 	__uint32_t		temp;
1241 	__uint64_t		off8, mem_crb, tmpw, word[2] = {0, 0};
1242 #define	MAX_CTL_CHECK   1000
1243 
1244 	/*
1245 	 * If not MN, go check for MS or invalid.
1246 	 */
1247 	if (unm_nic_pci_mem_bound_check(adapter, off, size) == 0)
1248 		return (unm_nic_pci_mem_write_direct(adapter, off, data, size));
1249 
1250 	off8 = off & 0xfffffff8;
1251 	off0 = off & 0x7;
1252 	sz[0] = (size < (8 - off0)) ? size : (8 - off0);
1253 	sz[1] = size - sz[0];
1254 	loop = ((off0 + size - 1) >> 3) + 1;
1255 	/* LINTED: E_FALSE_LOGICAL_EXPR */
1256 	mem_crb = (uptr_t)(pci_base_offset(adapter, UNM_CRB_DDR_NET));
1257 
1258 	if ((size != 8) || (off0 != 0))  {
1259 		for (i = 0; i < loop; i++) {
1260 			if (adapter->unm_nic_pci_mem_read(adapter,
1261 			    off8 + (i << 3), &word[i], 8))
1262 				return (-1);
1263 		}
1264 	}
1265 
1266 	switch (size) {
1267 		case 1:
1268 			tmpw = *((__uint8_t *)data);
1269 			break;
1270 		case 2:
1271 			tmpw = *((__uint16_t *)data);
1272 			break;
1273 		case 4:
1274 			tmpw = *((__uint32_t *)data);
1275 			break;
1276 		case 8:
1277 		default:
1278 			tmpw = *((__uint64_t *)data);
1279 			break;
1280 	}
1281 	word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
1282 	word[0] |= tmpw << (off0 * 8);
1283 
1284 	if (loop == 2) {
1285 		word[1] &= ~(~0ULL << (sz[1] * 8));
1286 		word[1] |= tmpw >> (sz[0] * 8);
1287 	}
1288 
1289 	UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1290 	unm_nic_pci_change_crbwindow_128M(adapter, 0);
1291 
1292 	for (i = 0; i < loop; i++) {
1293 		UNM_NIC_PCI_WRITE_32((__uint32_t)(off8 + (i << 3)),
1294 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_ADDR_LO));
1295 		UNM_NIC_PCI_WRITE_32(0,
1296 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_ADDR_HI));
1297 		UNM_NIC_PCI_WRITE_32(word[i] & 0xffffffff,
1298 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_WRDATA_LO));
1299 		UNM_NIC_PCI_WRITE_32((word[i] >> 32) & 0xffffffff,
1300 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_WRDATA_HI));
1301 		UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
1302 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
1303 		UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_START | MIU_TA_CTL_ENABLE |
1304 		    MIU_TA_CTL_WRITE,
1305 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
1306 
1307 		for (j = 0; j < MAX_CTL_CHECK; j++) {
1308 			temp = UNM_NIC_PCI_READ_32((void *)
1309 			    (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
1310 			if ((temp & MIU_TA_CTL_BUSY) == 0) {
1311 				break;
1312 			}
1313 		}
1314 
1315 		if (j >= MAX_CTL_CHECK) {
1316 			cmn_err(CE_WARN, "%s: %s Fail to write thru agent\n",
1317 			    __FUNCTION__, unm_nic_driver_name);
1318 			ret = -1;
1319 			break;
1320 		}
1321 	}
1322 
1323 	unm_nic_pci_change_crbwindow_128M(adapter, 1);
1324 	UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1325 	return (ret);
1326 }
1327 
1328 int
1329 unm_nic_pci_mem_read_128M(struct unm_adapter_s *adapter, u64 off, void *data,
1330     int size)
1331 {
1332 	int		i, j = 0, k, start, end, loop, sz[2], off0[2];
1333 	__uint32_t		temp;
1334 	__uint64_t		off8, val, mem_crb, word[2] = {0, 0};
1335 #define	MAX_CTL_CHECK   1000
1336 
1337 	/*
1338 	 * If not MN, go check for MS or invalid.
1339 	 */
1340 	if (unm_nic_pci_mem_bound_check(adapter, off, size) == 0)
1341 		return (unm_nic_pci_mem_read_direct(adapter, off, data, size));
1342 
1343 	off8 = off & 0xfffffff8;
1344 	off0[0] = off & 0x7;
1345 	off0[1] = 0;
1346 	sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
1347 	sz[1] = size - sz[0];
1348 	loop = ((off0[0] + size - 1) >> 3) + 1;
1349 	/* LINTED: E_FALSE_LOGICAL_EXPR */
1350 	mem_crb = (uptr_t)(pci_base_offset(adapter, UNM_CRB_DDR_NET));
1351 
1352 	UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1353 	unm_nic_pci_change_crbwindow_128M(adapter, 0);
1354 
1355 	for (i = 0; i < loop; i++) {
1356 		UNM_NIC_PCI_WRITE_32((__uint32_t)(off8 + (i << 3)),
1357 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_ADDR_LO));
1358 		UNM_NIC_PCI_WRITE_32(0,
1359 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_ADDR_HI));
1360 		UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_ENABLE,
1361 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
1362 		UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE,
1363 		    (void *) (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
1364 
1365 		for (j = 0; j < MAX_CTL_CHECK; j++) {
1366 			temp = UNM_NIC_PCI_READ_32((void *)
1367 			    (uptr_t)(mem_crb+MIU_TEST_AGT_CTRL));
1368 			if ((temp & MIU_TA_CTL_BUSY) == 0) {
1369 				break;
1370 			}
1371 		}
1372 
1373 		if (j >= MAX_CTL_CHECK) {
1374 			cmn_err(CE_WARN, "%s: %s Fail to read through agent\n",
1375 			    __FUNCTION__, unm_nic_driver_name);
1376 			break;
1377 		}
1378 
1379 		start = off0[i] >> 2;
1380 		end   = (off0[i] + sz[i] - 1) >> 2;
1381 		word[i] = 0;
1382 		for (k = start; k <= end; k++) {
1383 			word[i] |= ((__uint64_t)UNM_NIC_PCI_READ_32(
1384 			    (void *) (uptr_t)(mem_crb +
1385 			    MIU_TEST_AGT_RDDATA(k))) << (32*k));
1386 		}
1387 	}
1388 
1389 	unm_nic_pci_change_crbwindow_128M(adapter, 1);
1390 	UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1391 
1392 	if (j >= MAX_CTL_CHECK)
1393 		return (-1);
1394 
1395 	if (sz[0] == 8) {
1396 		val = word[0];
1397 	} else {
1398 		val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
1399 		    ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
1400 	}
1401 
1402 	switch (size) {
1403 	case 1:
1404 		*(__uint8_t  *)data = val;
1405 		break;
1406 	case 2:
1407 		*(__uint16_t *)data = val;
1408 		break;
1409 	case 4:
1410 		*(__uint32_t *)data = val;
1411 		break;
1412 	case 8:
1413 		*(__uint64_t *)data = val;
1414 		break;
1415 	}
1416 	return (0);
1417 }
1418 
1419 
1420 
1421 int
1422 unm_nic_pci_mem_write_2M(struct unm_adapter_s *adapter, u64 off, void *data,
1423     int size)
1424 {
1425 	int	i, j, ret = 0, loop, sz[2], off0;
1426 	__uint32_t	temp;
1427 	__uint64_t	off8, mem_crb, tmpw, word[2] = {0, 0};
1428 #define	MAX_CTL_CHECK   1000
1429 
1430 	/*
1431 	 * If not MN, go check for MS or invalid.
1432 	 */
1433 	if (off >= UNM_ADDR_QDR_NET && off <= NX_P3_ADDR_QDR_NET_MAX) {
1434 		mem_crb = UNM_CRB_QDR_NET;
1435 	} else {
1436 		mem_crb = UNM_CRB_DDR_NET;
1437 		if (unm_nic_pci_mem_bound_check(adapter, off, size) == 0)
1438 			return (unm_nic_pci_mem_write_direct(adapter,
1439 			    off, data, size));
1440 	}
1441 
1442 	off8 = off & 0xfffffff8;
1443 	off0 = off & 0x7;
1444 	sz[0] = (size < (8 - off0)) ? size : (8 - off0);
1445 	sz[1] = size - sz[0];
1446 	loop = ((off0 + size - 1) >> 3) + 1;
1447 
1448 	if ((size != 8) || (off0 != 0)) {
1449 		for (i = 0; i < loop; i++) {
1450 			if (adapter->unm_nic_pci_mem_read(adapter,
1451 			    off8 + (i << 3), &word[i], 8))
1452 				return (-1);
1453 		}
1454 	}
1455 
1456 	switch (size) {
1457 		case 1:
1458 			tmpw = *((__uint8_t *)data);
1459 			break;
1460 		case 2:
1461 			tmpw = *((__uint16_t *)data);
1462 			break;
1463 		case 4:
1464 			tmpw = *((__uint32_t *)data);
1465 			break;
1466 		case 8:
1467 		default:
1468 			tmpw = *((__uint64_t *)data);
1469 			break;
1470 	}
1471 
1472 	word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
1473 	word[0] |= tmpw << (off0 * 8);
1474 
1475 	if (loop == 2) {
1476 		word[1] &= ~(~0ULL << (sz[1] * 8));
1477 		word[1] |= tmpw >> (sz[0] * 8);
1478 	}
1479 
1480 // don't lock here - write_wx gets the lock if each time
1481 // UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1482 // unm_nic_pci_change_crbwindow_128M(adapter, 0);
1483 
1484 	for (i = 0; i < loop; i++) {
1485 		temp = off8 + (i << 3);
1486 		adapter->unm_nic_hw_write_wx(adapter,
1487 		    mem_crb+MIU_TEST_AGT_ADDR_LO, &temp, 4);
1488 		temp = 0;
1489 		adapter->unm_nic_hw_write_wx(adapter,
1490 		    mem_crb+MIU_TEST_AGT_ADDR_HI, &temp, 4);
1491 		temp = word[i] & 0xffffffff;
1492 		adapter->unm_nic_hw_write_wx(adapter,
1493 		    mem_crb+MIU_TEST_AGT_WRDATA_LO, &temp, 4);
1494 		temp = (word[i] >> 32) & 0xffffffff;
1495 		adapter->unm_nic_hw_write_wx(adapter,
1496 		    mem_crb+MIU_TEST_AGT_WRDATA_HI, &temp, 4);
1497 		temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
1498 		adapter->unm_nic_hw_write_wx(adapter,
1499 		    mem_crb+MIU_TEST_AGT_CTRL, &temp, 4);
1500 		temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
1501 		adapter->unm_nic_hw_write_wx(adapter,
1502 		    mem_crb+MIU_TEST_AGT_CTRL, &temp, 4);
1503 
1504 		for (j = 0; j < MAX_CTL_CHECK; j++) {
1505 			adapter->unm_nic_hw_read_wx(adapter,
1506 			    mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
1507 			if ((temp & MIU_TA_CTL_BUSY) == 0) {
1508 				break;
1509 			}
1510 		}
1511 
1512 		if (j >= MAX_CTL_CHECK) {
1513 			cmn_err(CE_WARN, "%s: Fail to write through agent\n",
1514 			    unm_nic_driver_name);
1515 			ret = -1;
1516 			break;
1517 		}
1518 	}
1519 
1520 //  unm_nic_pci_change_crbwindow_128M(adapter, 1);
1521 //  UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1522 	return (ret);
1523 }
1524 
1525 int
1526 unm_nic_pci_mem_read_2M(struct unm_adapter_s *adapter, u64 off, void *data,
1527     int size)
1528 {
1529 // unsigned long   flags;
1530 	int		i, j = 0, k, start, end, loop, sz[2], off0[2];
1531 	__uint32_t	temp;
1532 	__uint64_t	off8, val, mem_crb, word[2] = {0, 0};
1533 #define	MAX_CTL_CHECK   1000
1534 
1535 	/*
1536 	 * If not MN, go check for MS or invalid.
1537 	 */
1538 
1539 	if (off >= UNM_ADDR_QDR_NET && off <= NX_P3_ADDR_QDR_NET_MAX) {
1540 		mem_crb = UNM_CRB_QDR_NET;
1541 	} else {
1542 		mem_crb = UNM_CRB_DDR_NET;
1543 		if (unm_nic_pci_mem_bound_check(adapter, off, size) == 0)
1544 			return (unm_nic_pci_mem_read_direct(adapter,
1545 			    off, data, size));
1546 	}
1547 
1548 	off8 = off & 0xfffffff8;
1549 	off0[0] = off & 0x7;
1550 	off0[1] = 0;
1551 	sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
1552 	sz[1] = size - sz[0];
1553 	loop = ((off0[0] + size - 1) >> 3) + 1;
1554 
1555 // don't get lock - write_wx will get it
1556 // UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1557 // unm_nic_pci_change_crbwindow_128M(adapter, 0);
1558 
1559 	for (i = 0; i < loop; i++) {
1560 		temp = off8 + (i << 3);
1561 		adapter->unm_nic_hw_write_wx(adapter,
1562 		    mem_crb + MIU_TEST_AGT_ADDR_LO, &temp, 4);
1563 		temp = 0;
1564 		adapter->unm_nic_hw_write_wx(adapter,
1565 		    mem_crb + MIU_TEST_AGT_ADDR_HI, &temp, 4);
1566 		temp = MIU_TA_CTL_ENABLE;
1567 		adapter->unm_nic_hw_write_wx(adapter,
1568 		    mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
1569 		temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;
1570 		adapter->unm_nic_hw_write_wx(adapter,
1571 		    mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
1572 
1573 		for (j = 0; j < MAX_CTL_CHECK; j++) {
1574 			adapter->unm_nic_hw_read_wx(adapter,
1575 			    mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
1576 			if ((temp & MIU_TA_CTL_BUSY) == 0) {
1577 				break;
1578 			}
1579 		}
1580 
1581 		if (j >= MAX_CTL_CHECK) {
1582 			cmn_err(CE_WARN, "%s: Fail to read through agent\n",
1583 			    unm_nic_driver_name);
1584 			break;
1585 		}
1586 
1587 		start = off0[i] >> 2;
1588 		end   = (off0[i] + sz[i] - 1) >> 2;
1589 		for (k = start; k <= end; k++) {
1590 			adapter->unm_nic_hw_read_wx(adapter,
1591 			    mem_crb + MIU_TEST_AGT_RDDATA(k), &temp, 4);
1592 			word[i] |= ((__uint64_t)temp << (32 * k));
1593 		}
1594 	}
1595 
1596 // unm_nic_pci_change_crbwindow_128M(adapter, 1);
1597 // UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1598 
1599 	if (j >= MAX_CTL_CHECK)
1600 		return (-1);
1601 
1602 	if (sz[0] == 8) {
1603 		val = word[0];
1604 	} else {
1605 		val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
1606 		    ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
1607 	}
1608 
1609 	switch (size) {
1610 		case 1:
1611 			*(__uint8_t  *)data = val;
1612 			break;
1613 		case 2:
1614 			*(__uint16_t *)data = val;
1615 			break;
1616 		case 4:
1617 			*(__uint32_t *)data = val;
1618 			break;
1619 		case 8:
1620 			*(__uint64_t *)data = val;
1621 			break;
1622 	}
1623 	return (0);
1624 }
1625 
1626 int
1627 unm_crb_writelit_adapter_2M(struct unm_adapter_s *adapter, unsigned long off,
1628     int data)
1629 {
1630 	return (unm_nic_hw_write_wx_2M(adapter, off, &data, 4));
1631 }
1632 
1633 int
1634 unm_crb_writelit_adapter_128M(struct unm_adapter_s *adapter, unsigned long off,
1635     int data)
1636 {
1637 	void *addr;
1638 
1639 	if (ADDR_IN_WINDOW1(off)) {
1640 		UNM_READ_LOCK(&adapter->adapter_lock);
1641 		UNM_NIC_PCI_WRITE_32(data, CRB_NORMALIZE(adapter, off));
1642 		UNM_READ_UNLOCK(&adapter->adapter_lock);
1643 	} else {
1644 		// unm_nic_write_w0 (adapter, off, data);
1645 		UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1646 		unm_nic_pci_change_crbwindow_128M(adapter, 0);
1647 		addr = (void *) (pci_base_offset(adapter, off));
1648 		UNM_NIC_PCI_WRITE_32(data, addr);
1649 		unm_nic_pci_change_crbwindow_128M(adapter, 1);
1650 		UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1651 	}
1652 
1653 	return (0);
1654 }
1655 
1656 int
1657 unm_nic_get_board_info(struct unm_adapter_s *adapter)
1658 {
1659 	int	rv = 0;
1660 	unm_board_info_t  *boardinfo;
1661 	int		i;
1662 	int		addr = BRDCFG_START;
1663 	uint32_t	  *ptr32;
1664 	uint32_t	gpioval;
1665 
1666 	boardinfo = &adapter->ahw.boardcfg;
1667 	ptr32 = (uint32_t *)boardinfo;
1668 
1669 	for (i = 0; i < sizeof (unm_board_info_t) / sizeof (uint32_t); i++) {
1670 		if (rom_fast_read(adapter, addr, (int *)ptr32) == -1) {
1671 			return (-1);
1672 		}
1673 		DPRINTF(1, (CE_WARN, "ROM(%d): %x\n", i, *ptr32));
1674 		ptr32++;
1675 		addr += sizeof (uint32_t);
1676 	}
1677 
1678 	if (boardinfo->magic != UNM_BDINFO_MAGIC) {
1679 		DPRINTF(1, (CE_WARN, "%s: ERROR reading board config."
1680 		    " Read %x, expected %x\n", unm_nic_driver_name,
1681 		    boardinfo->magic, UNM_BDINFO_MAGIC));
1682 		rv = -1;
1683 	}
1684 
1685 	if (boardinfo->header_version != UNM_BDINFO_VERSION) {
1686 		DPRINTF(1, (CE_WARN, "%s: Unknown board config version."
1687 		    " Read %x, expected %x\n", unm_nic_driver_name,
1688 		    boardinfo->header_version, UNM_BDINFO_VERSION));
1689 		rv = -1;
1690 	}
1691 
1692 	if (boardinfo->board_type == UNM_BRDTYPE_P3_4_GB_MM) {
1693 		gpioval = UNM_CRB_READ_VAL_ADAPTER(UNM_ROMUSB_GLB_PAD_GPIO_I,
1694 		    adapter);
1695 		if ((gpioval & 0x8000) == 0)
1696 			boardinfo->board_type = UNM_BRDTYPE_P3_10G_TRP;
1697 	}
1698 
1699 	DPRINTF(0, (CE_WARN, "Discovered board type:0x%x  ",
1700 	    boardinfo->board_type));
1701 
1702 	switch ((unm_brdtype_t)boardinfo->board_type) {
1703 	case UNM_BRDTYPE_P2_SB35_4G:
1704 		adapter->ahw.board_type = UNM_NIC_GBE;
1705 		break;
1706 	case UNM_BRDTYPE_P2_SB31_10G:
1707 	case UNM_BRDTYPE_P2_SB31_10G_IMEZ:
1708 	case UNM_BRDTYPE_P2_SB31_10G_HMEZ:
1709 	case UNM_BRDTYPE_P2_SB31_10G_CX4:
1710 	case UNM_BRDTYPE_P3_HMEZ:
1711 	case UNM_BRDTYPE_P3_XG_LOM:
1712 	case UNM_BRDTYPE_P3_10G_CX4:
1713 	case UNM_BRDTYPE_P3_10G_CX4_LP:
1714 	case UNM_BRDTYPE_P3_IMEZ:
1715 	case UNM_BRDTYPE_P3_10G_SFP_PLUS:
1716 	case UNM_BRDTYPE_P3_10G_XFP:
1717 	case UNM_BRDTYPE_P3_10000_BASE_T:
1718 		adapter->ahw.board_type = UNM_NIC_XGBE;
1719 		break;
1720 	case UNM_BRDTYPE_P3_REF_QG:
1721 	case UNM_BRDTYPE_P3_4_GB:
1722 	case UNM_BRDTYPE_P3_4_GB_MM:
1723 		adapter->ahw.board_type = UNM_NIC_GBE;
1724 		break;
1725 	case UNM_BRDTYPE_P1_BD:
1726 	case UNM_BRDTYPE_P1_SB:
1727 	case UNM_BRDTYPE_P1_SMAX:
1728 	case UNM_BRDTYPE_P1_SOCK:
1729 		adapter->ahw.board_type = UNM_NIC_GBE;
1730 		break;
1731 	case UNM_BRDTYPE_P3_10G_TRP:
1732 		if (adapter->portnum < 2)
1733 			adapter->ahw.board_type = UNM_NIC_XGBE;
1734 		else
1735 			adapter->ahw.board_type = UNM_NIC_GBE;
1736 		break;
1737 	default:
1738 		DPRINTF(1, (CE_WARN, "%s: Unknown(%x)\n", unm_nic_driver_name,
1739 		    boardinfo->board_type));
1740 		break;
1741 	}
1742 
1743 	return (rv);
1744 }
1745 
1746 /* NIU access sections */
1747 
1748 int
1749 unm_nic_macaddr_set(struct unm_adapter_s *adapter, __uint8_t *addr)
1750 {
1751 	int		ret = 0, i, retry_count = 10;
1752 	unsigned char		mac_addr[MAX_ADDR_LEN];
1753 
1754 	/* For P3, we should not set MAC in HW any more */
1755 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
1756 		return (0);
1757 
1758 	switch (adapter->ahw.board_type) {
1759 		case UNM_NIC_GBE:
1760 	/*
1761 	 * Flaky Mac address registers on qgig require several writes.
1762 	 */
1763 			for (i = 0; i < retry_count; ++i) {
1764 				if (unm_niu_macaddr_set(adapter, addr) != 0)
1765 					return (-1);
1766 
1767 				(void) unm_niu_macaddr_get(adapter,
1768 				    (unsigned char *)mac_addr);
1769 				if (memcmp(mac_addr, addr, 6) == 0)
1770 					return (0);
1771 			}
1772 			cmn_err(CE_WARN, "%s: Flaky MAC addr registers\n",
1773 			    unm_nic_driver_name);
1774 			break;
1775 
1776 		case UNM_NIC_XGBE:
1777 			ret = unm_niu_xg_macaddr_set(adapter, addr);
1778 			break;
1779 
1780 		default:
1781 			cmn_err(CE_WARN,  "\r\nUnknown board type encountered"
1782 			    " while setting the MAC address.\n");
1783 			return (-1);
1784 	}
1785 	return (ret);
1786 }
1787 
1788 #define	MTU_FUDGE_FACTOR 100
1789 int
1790 unm_nic_set_mtu(struct unm_adapter_s *adapter, int new_mtu)
1791 {
1792 	long		port = adapter->physical_port;
1793 	int			ret = 0;
1794 	u32			port_mode = 0;
1795 
1796 	if (adapter->ahw.revision_id >= NX_P3_A2)
1797 		return (nx_fw_cmd_set_mtu(adapter, new_mtu));
1798 
1799 	new_mtu += MTU_FUDGE_FACTOR; /* so that MAC accepts frames > MTU */
1800 	switch (adapter->ahw.board_type) {
1801 		case UNM_NIC_GBE:
1802 			unm_nic_write_w0(adapter,
1803 			    UNM_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port),
1804 			    new_mtu);
1805 
1806 			break;
1807 
1808 		case UNM_NIC_XGBE:
1809 			adapter->unm_nic_hw_read_wx(adapter, UNM_PORT_MODE_ADDR,
1810 			    &port_mode, 4);
1811 			if (port_mode == UNM_PORT_MODE_802_3_AP) {
1812 				unm_nic_write_w0(adapter,
1813 				    UNM_NIU_AP_MAX_FRAME_SIZE(port), new_mtu);
1814 			} else {
1815 				if (adapter->physical_port == 0) {
1816 					unm_nic_write_w0(adapter,
1817 					    UNM_NIU_XGE_MAX_FRAME_SIZE,
1818 					    new_mtu);
1819 				} else {
1820 					unm_nic_write_w0(adapter,
1821 					    UNM_NIU_XG1_MAX_FRAME_SIZE,
1822 					    new_mtu);
1823 				}
1824 			}
1825 			break;
1826 
1827 		default:
1828 			cmn_err(CE_WARN, "%s: Unknown brdtype\n",
1829 			    unm_nic_driver_name);
1830 	}
1831 
1832 	return (ret);
1833 }
1834 
1835 int
1836 unm_nic_set_promisc_mode(struct unm_adapter_s *adapter)
1837 {
1838 	int		ret;
1839 
1840 	if (adapter->promisc)
1841 		return (0);
1842 
1843 	switch (adapter->ahw.board_type) {
1844 		case UNM_NIC_GBE:
1845 			ret = unm_niu_set_promiscuous_mode(adapter,
1846 			    UNM_NIU_PROMISCOUS_MODE);
1847 			break;
1848 
1849 		case UNM_NIC_XGBE:
1850 			ret = unm_niu_xg_set_promiscuous_mode(adapter,
1851 			    UNM_NIU_PROMISCOUS_MODE);
1852 			break;
1853 
1854 		default:
1855 			cmn_err(CE_WARN, "%s: Unknown brdtype\n",
1856 			    unm_nic_driver_name);
1857 			ret = -1;
1858 			break;
1859 	}
1860 
1861 if (!ret)
1862 	adapter->promisc = 1;
1863 
1864 		return (ret);
1865 }
1866 
1867 int
1868 unm_nic_unset_promisc_mode(struct unm_adapter_s *adapter)
1869 {
1870 	int	ret = 0;
1871 
1872 	/*
1873 	 * P3 does not unset promiscous mode. Why?
1874 	 */
1875 	if (adapter->ahw.revision_id >= NX_P3_A2) {
1876 		return (0);
1877 	}
1878 
1879 	if (!adapter->promisc)
1880 		return (0);
1881 
1882 	switch (adapter->ahw.board_type) {
1883 		case UNM_NIC_GBE:
1884 			ret = unm_niu_set_promiscuous_mode(adapter,
1885 			    UNM_NIU_NON_PROMISCOUS_MODE);
1886 			break;
1887 
1888 		case UNM_NIC_XGBE:
1889 			ret = unm_niu_xg_set_promiscuous_mode(adapter,
1890 			    UNM_NIU_NON_PROMISCOUS_MODE);
1891 			break;
1892 
1893 		default:
1894 			cmn_err(CE_WARN, "%s: Unknown brdtype\n",
1895 			    unm_nic_driver_name);
1896 			ret = -1;
1897 			break;
1898 	}
1899 
1900 	if (!ret)
1901 		adapter->promisc = 0;
1902 
1903 	return (ret);
1904 }
1905 
1906 long
1907 unm_nic_phy_read(unm_adapter *adapter, long reg,
1908 		    __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 	unm_niu_gbe_ifmode_t	mode_dont_care = 0;
1938 	u32			port_mode = 0;
1939 
1940 	unm_nic_set_link_parameters(adapter);
1941 
1942 	switch (adapter->ahw.board_type) {
1943 	case UNM_NIC_GBE:
1944 		ret = unm_niu_enable_gbe_port(adapter, mode_dont_care);
1945 		break;
1946 
1947 	case UNM_NIC_XGBE:
1948 		adapter->unm_nic_hw_read_wx(adapter, UNM_PORT_MODE_ADDR,
1949 		    &port_mode, 4);
1950 		if (port_mode == UNM_PORT_MODE_802_3_AP) {
1951 			ret = unm_niu_enable_gbe_port(adapter, mode_dont_care);
1952 		} else {
1953 			adapter->unm_crb_writelit_adapter(adapter,
1954 			    UNM_NIU_XGE_CONFIG_0 + (0x10000 * portnum), 0x5);
1955 			UNM_CRB_READ_CHECK_ADAPTER(UNM_NIU_XGE_CONFIG_1 +
1956 			    (0x10000 * portnum), &reg, adapter);
1957 			if (adapter->ahw.revision_id < NX_P3_A2)
1958 				reg = (reg & ~0x2000UL);
1959 			adapter->unm_crb_writelit_adapter(adapter,
1960 			    UNM_NIU_XGE_CONFIG_1 + (0x10000 * portnum), reg);
1961 		}
1962 		break;
1963 
1964 	default:
1965 		DPRINTF(1, (CE_WARN, "%s: Unknown board type\n",
1966 		    unm_nic_driver_name));
1967 	}
1968 
1969 	return (ret);
1970 }
1971 
1972 void
1973 unm_nic_stop_port(struct unm_adapter_s *adapter)
1974 {
1975 
1976 	(void) mac_unregister(adapter->mach);
1977 
1978 	switch (adapter->ahw.board_type) {
1979 	case UNM_NIC_GBE:
1980 		(void) unm_niu_disable_gbe_port(adapter);
1981 		break;
1982 
1983 	case UNM_NIC_XGBE:
1984 		(void) unm_niu_disable_xg_port(adapter);
1985 		break;
1986 
1987 	default:
1988 		DPRINTF(1, (CE_WARN, "%s: Unknown board type\n",
1989 		    unm_nic_driver_name));
1990 	}
1991 }
1992 
1993 void
1994 unm_crb_write_adapter(unsigned long off, void *data,
1995     struct unm_adapter_s *adapter)
1996 {
1997 	(void) adapter->unm_nic_hw_write_wx(adapter, off, data, 4);
1998 }
1999 
2000 int
2001 unm_crb_read_adapter(unsigned long off, void *data,
2002     struct unm_adapter_s *adapter)
2003 {
2004 	return (adapter->unm_nic_hw_read_wx(adapter, off, data, 4));
2005 }
2006 
2007 int
2008 unm_crb_read_val_adapter(unsigned long off, struct unm_adapter_s *adapter)
2009 {
2010 	int data;
2011 
2012 	adapter->unm_nic_hw_read_wx(adapter, off, &data, 4);
2013 	return (data);
2014 }
2015 
2016 void
2017 unm_nic_set_link_parameters(struct unm_adapter_s *adapter)
2018 {
2019 	unm_niu_phy_status_t status;
2020 	uint16_t defval = (uint16_t)-1;
2021 	unm_niu_control_t mode;
2022 	u32 port_mode = 0;
2023 
2024 	unm_nic_read_w0(adapter, UNM_NIU_MODE, (uint32_t *)&mode);
2025 	if (mode.enable_ge) { // Gb 10/100/1000 Mbps mode
2026 		adapter->unm_nic_hw_read_wx(adapter, UNM_PORT_MODE_ADDR,
2027 		    &port_mode, 4);
2028 		if (port_mode == UNM_PORT_MODE_802_3_AP) {
2029 			adapter->link_speed = MBPS_1000;
2030 			adapter->link_duplex = LINK_DUPLEX_FULL;
2031 		} else {
2032 		if (unm_nic_phy_read(adapter,
2033 		    UNM_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
2034 		    (unm_crbword_t *)&status) == 0) {
2035 			if (status.link) {
2036 				switch (status.speed) {
2037 				case 0: adapter->link_speed = MBPS_10;
2038 					break;
2039 				case 1: adapter->link_speed = MBPS_100;
2040 					break;
2041 				case 2: adapter->link_speed = MBPS_1000;
2042 					break;
2043 				default:
2044 					adapter->link_speed = defval;
2045 					break;
2046 				}
2047 				switch (status.duplex) {
2048 				case 0: adapter->link_duplex = LINK_DUPLEX_HALF;
2049 					break;
2050 				case 1: adapter->link_duplex = LINK_DUPLEX_FULL;
2051 					break;
2052 				default:
2053 					adapter->link_duplex = defval;
2054 					break;
2055 				}
2056 			} else {
2057 				adapter->link_speed = defval;
2058 				adapter->link_duplex = defval;
2059 			}
2060 		} else {
2061 			adapter->link_speed = defval;
2062 			adapter->link_duplex = defval;
2063 		}
2064 		}
2065 	}
2066 }
2067 
2068 void
2069 unm_nic_flash_print(struct unm_adapter_s *adapter)
2070 {
2071 	int valid = 1;
2072 	unm_board_info_t *board_info = &(adapter->ahw.boardcfg);
2073 
2074 	if (board_info->magic != UNM_BDINFO_MAGIC) {
2075 		cmn_err(CE_WARN, "%s UNM Unknown board config, Read 0x%x "
2076 		    "expected as 0x%x\n", unm_nic_driver_name,
2077 		    board_info->magic, UNM_BDINFO_MAGIC);
2078 		valid = 0;
2079 	}
2080 	if (board_info->header_version != UNM_BDINFO_VERSION) {
2081 		cmn_err(CE_WARN, "%s UNM Unknown board config version."
2082 		    " Read %x, expected %x\n", unm_nic_driver_name,
2083 		    board_info->header_version, UNM_BDINFO_VERSION);
2084 		valid = 0;
2085 	}
2086 	if (valid) {
2087 		unm_user_info_t  user_info;
2088 		int	i;
2089 		int	addr = USER_START;
2090 		int	*ptr32;
2091 
2092 		ptr32 = (int *)&user_info;
2093 		for (i = 0; i < sizeof (unm_user_info_t) / sizeof (uint32_t);
2094 		    i++) {
2095 			if (rom_fast_read(adapter, addr, ptr32) == -1) {
2096 				cmn_err(CE_WARN,
2097 				    "%s: ERROR reading %s board userarea.\n",
2098 				    unm_nic_driver_name, unm_nic_driver_name);
2099 				return;
2100 			}
2101 			ptr32++;
2102 			addr += sizeof (uint32_t);
2103 		}
2104 		if (verbmsg != 0) {
2105 			char	*brd_name;
2106 			GET_BRD_NAME_BY_TYPE(board_info->board_type, brd_name);
2107 			cmn_err(CE_NOTE, "%s %s Board S/N %s  Chip id 0x%x\n",
2108 			    unm_nic_driver_name, brd_name, user_info.serial_num,
2109 			    board_info->chip_id);
2110 		}
2111 	}
2112 }
2113 
2114 static int
2115 nx_nic_send_cmd_descs(unm_adapter *adapter, cmdDescType0_t *cmd_desc_arr,
2116     int nr_elements)
2117 {
2118 	struct unm_cmd_buffer	*pbuf;
2119 	unsigned int		i = 0, producer;
2120 
2121 	/*
2122 	 * We need to check if space is available.
2123 	 */
2124 	UNM_SPIN_LOCK(&adapter->tx_lock);
2125 	producer = adapter->cmdProducer;
2126 
2127 	do {
2128 		pbuf = &adapter->cmd_buf_arr[producer];
2129 		pbuf->head = pbuf->tail = NULL;
2130 		pbuf->msg = NULL;
2131 		(void) memcpy(&adapter->ahw.cmdDescHead[producer],
2132 		    &cmd_desc_arr[i], sizeof (cmdDescType0_t));
2133 		unm_desc_dma_sync(adapter->ahw.cmd_desc_dma_handle, producer,
2134 		    1, adapter->MaxTxDescCount, sizeof (cmdDescType0_t),
2135 		    DDI_DMA_SYNC_FORDEV);
2136 		producer = get_next_index(producer, adapter->MaxTxDescCount);
2137 		i++;
2138 	} while (i != nr_elements);
2139 
2140 	adapter->cmdProducer = adapter->ahw.cmdProducer = producer;
2141 	adapter->freecmds -= i;
2142 
2143 	unm_nic_update_cmd_producer(adapter, producer);
2144 
2145 	UNM_SPIN_UNLOCK(&adapter->tx_lock);
2146 	return (0);
2147 }
2148 
2149 typedef struct {
2150 	u64	qhdr, req_hdr, words[6];
2151 } nx_nic_req_t;
2152 
2153 typedef struct {
2154 	u8	op, tag, mac_addr[6];
2155 } nx_mac_req_t;
2156 
2157 static void
2158 nx_p3_sre_macaddr_change(unm_adapter *adapter, u8 *addr, u8 op)
2159 {
2160 	nx_nic_req_t	req;
2161 	nx_mac_req_t	mac_req;
2162 	int		rv;
2163 
2164 	(void) memset(&req, 0, sizeof (nx_nic_req_t));
2165 	req.qhdr |= (NX_NIC_REQUEST << 23);
2166 	req.req_hdr |= NX_MAC_EVENT;
2167 	req.req_hdr |= ((u64)adapter->portnum << 16);
2168 	mac_req.op = op;
2169 	(void) memcpy(&mac_req.mac_addr, addr, 6);
2170 	req.words[0] = HOST_TO_LE_64(*(u64 *)(uintptr_t)&mac_req);
2171 
2172 	rv = nx_nic_send_cmd_descs(adapter, (cmdDescType0_t *)&req, 1);
2173 	if (rv != 0)
2174 		cmn_err(CE_WARN, "%s%d: Could not send mac update\n",
2175 		    adapter->name, adapter->instance);
2176 }
2177 
2178 static int
2179 nx_p3_nic_set_promisc(unm_adapter *adapter, u32 mode)
2180 {
2181 	nx_nic_req_t	req;
2182 
2183 	(void) memset(&req, 0, sizeof (nx_nic_req_t));
2184 
2185 	req.qhdr |= (NX_HOST_REQUEST << 23);
2186 	req.req_hdr |= NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE;
2187 	req.req_hdr |= ((u64)adapter->portnum << 16);
2188 	req.words[0] = HOST_TO_LE_64(mode);
2189 
2190 	return (nx_nic_send_cmd_descs(adapter, (cmdDescType0_t *)&req, 1));
2191 }
2192 
2193 /*
2194  * Currently only invoked at interface initialization time
2195  */
2196 void
2197 nx_p3_nic_set_multi(unm_adapter *adapter)
2198 {
2199 	u8	bcast_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2200 
2201 	if (nx_p3_nic_set_promisc(adapter, VPORT_MISS_MODE_ACCEPT_ALL))
2202 		cmn_err(CE_WARN, "Could not set promisc mode\n");
2203 
2204 	nx_p3_sre_macaddr_change(adapter, adapter->mac_addr, NETXEN_MAC_ADD);
2205 	nx_p3_sre_macaddr_change(adapter, bcast_addr, NETXEN_MAC_ADD);
2206 }
2207