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