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
crb_win_lock(struct unm_adapter_s * adapter)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
crb_win_unlock(struct unm_adapter_s * adapter)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
unm_nic_pci_change_crbwindow_128M(unm_adapter * adapter,uint32_t wndw)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
unm_nic_pci_change_crbwindow_2M(unm_adapter * adapter,uint32_t wndw)387 unm_nic_pci_change_crbwindow_2M(unm_adapter *adapter, uint32_t wndw)
388 {
389 }
390
391
392 uint32_t
unm_nic_get_crbwindow(unm_adapter * adapter)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
unm_nic_pci_get_crb_addr_2M(unm_adapter * adapter,u64 * off,int len)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
unm_nic_pci_set_crbwindow_2M(unm_adapter * adapter,u64 * off)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
unm_nic_hw_write_ioctl_128M(unm_adapter * adapter,u64 off,void * data,int len)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
unm_nic_hw_write_wx_128M(unm_adapter * adapter,u64 off,void * data,int len)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
unm_nic_pci_write_normalize_128M(unm_adapter * adapter,u64 off,u32 data)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
unm_nic_pci_read_normalize_128M(unm_adapter * adapter,u64 off)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
unm_nic_pci_write_immediate_128M(unm_adapter * adapter,u64 off,u32 * data)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
unm_nic_pci_read_immediate_128M(unm_adapter * adapter,u64 off,u32 * data)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
unm_nic_pci_write_normalize_2M(unm_adapter * adapter,u64 off,u32 data)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
unm_nic_pci_read_normalize_2M(unm_adapter * adapter,u64 off)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
unm_nic_pci_write_immediate_2M(unm_adapter * adapter,u64 off,u32 * data)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
unm_nic_pci_read_immediate_2M(unm_adapter * adapter,u64 off,u32 * data)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
unm_nic_hw_write_wx_2M(unm_adapter * adapter,u64 off,void * data,int len)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
unm_nic_hw_read_ioctl_128M(unm_adapter * adapter,u64 off,void * data,int len)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
unm_nic_hw_read_wx_2M(unm_adapter * adapter,u64 off,void * data,int len)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
unm_nic_hw_read_wx_128M(unm_adapter * adapter,u64 off,void * data,int len)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
unm_nic_pci_mem_bound_check(struct unm_adapter_s * adapter,unsigned long long addr,int size)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
unm_nic_pci_set_window_128M(struct unm_adapter_s * adapter,unsigned long long addr)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
unm_nic_pci_set_window_2M(struct unm_adapter_s * adapter,unsigned long long addr)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
unm_nic_pci_is_same_window(struct unm_adapter_s * adapter,unsigned long long addr)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
unm_nic_pci_mem_read_direct(struct unm_adapter_s * adapter,u64 off,void * data,int size)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
unm_nic_pci_mem_write_direct(struct unm_adapter_s * adapter,u64 off,void * data,int size)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
unm_nic_pci_mem_write_128M(struct unm_adapter_s * adapter,u64 off,void * data,int size)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
unm_nic_pci_mem_read_128M(struct unm_adapter_s * adapter,u64 off,void * data,int size)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
unm_nic_pci_mem_write_2M(struct unm_adapter_s * adapter,u64 off,void * data,int size)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
unm_nic_pci_mem_read_2M(struct unm_adapter_s * adapter,u64 off,void * data,int size)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
unm_crb_writelit_adapter_2M(struct unm_adapter_s * adapter,unsigned long off,int data)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
unm_crb_writelit_adapter_128M(struct unm_adapter_s * adapter,unsigned long off,int data)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
unm_nic_get_board_info(struct unm_adapter_s * adapter)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
unm_nic_macaddr_set(struct unm_adapter_s * adapter,__uint8_t * addr)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
unm_nic_set_mtu(struct unm_adapter_s * adapter,int new_mtu)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
unm_nic_set_promisc_mode(struct unm_adapter_s * adapter)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
unm_nic_unset_promisc_mode(struct unm_adapter_s * adapter)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
unm_nic_phy_read(unm_adapter * adapter,long reg,__uint32_t * readval)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
unm_nic_init_port(struct unm_adapter_s * adapter)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), ®, 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
unm_nic_stop_port(struct unm_adapter_s * adapter)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
unm_crb_write_adapter(unsigned long off,void * data,struct unm_adapter_s * adapter)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
unm_crb_read_adapter(unsigned long off,void * data,struct unm_adapter_s * adapter)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
unm_crb_read_val_adapter(unsigned long off,struct unm_adapter_s * adapter)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
unm_nic_set_link_parameters(struct unm_adapter_s * adapter)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
unm_nic_flash_print(struct unm_adapter_s * adapter)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
nx_nic_send_cmd_descs(unm_adapter * adapter,cmdDescType0_t * cmd_desc_arr,int nr_elements)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
nx_p3_sre_macaddr_change(unm_adapter * adapter,u8 * addr,u8 op)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
nx_p3_nic_set_promisc(unm_adapter * adapter,u32 mode)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
nx_p3_nic_set_multi(unm_adapter * adapter)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