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.
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.
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]
23 * Copyright 2008 NetXen, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * Copyright (c) 2018, Joyent, Inc.
31 #include <sys/types.h>
33 #include <sys/debug.h>
34 #include <sys/stropts.h>
35 #include <sys/stream.h>
36 #include <sys/strlog.h>
39 #include <sys/kstat.h>
40 #include <sys/vtrace.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>
48 #include <sys/sunddi.h>
49 #include <sys/sysmacros.h>
54 #include "unm_nic_hw.h"
56 #include "unm_brdcfg.h"
57 #include "driver_info.h"
59 long unm_niu_gbe_phy_read(struct unm_adapter_s
*,
60 long reg
, unm_crbword_t
*readval
);
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))
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)
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 */
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 */
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 */
239 * top 12 bits of crb internal address (hub, agent)
241 static unsigned crb_hub_agt
[64] = {
243 UNM_HW_CRB_HUB_AGT_ADR_PS
,
244 UNM_HW_CRB_HUB_AGT_ADR_MN
,
245 UNM_HW_CRB_HUB_AGT_ADR_MS
,
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
,
270 UNM_HW_CRB_HUB_AGT_ADR_PGSI
,
271 UNM_HW_CRB_HUB_AGT_ADR_SN
,
273 UNM_HW_CRB_HUB_AGT_ADR_EG
,
275 UNM_HW_CRB_HUB_AGT_ADR_PS
,
276 UNM_HW_CRB_HUB_AGT_ADR_CAM
,
282 UNM_HW_CRB_HUB_AGT_ADR_TIMR
,
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
,
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
,
300 UNM_HW_CRB_HUB_AGT_ADR_SMB
,
301 UNM_HW_CRB_HUB_AGT_ADR_I2C0
,
302 UNM_HW_CRB_HUB_AGT_ADR_I2C1
,
304 UNM_HW_CRB_HUB_AGT_ADR_PGNC
,
308 #define CRB_WIN_LOCK_TIMEOUT 100000000
311 crb_win_lock(struct unm_adapter_s
*adapter
)
314 int done
= 0, timeout
= 0;
317 /* acquire semaphore3 from PCI HW block */
318 adapter
->unm_nic_hw_read_wx(adapter
,
319 UNM_PCIE_REG(PCIE_SEM7_LOCK
), &done
, 4);
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
);
331 for (i
= 0; i
< 20; i
++)
334 adapter
->unm_crb_writelit_adapter(adapter
, UNM_CRB_WIN_LOCK_ID
,
339 crb_win_unlock(struct unm_adapter_s
*adapter
)
343 adapter
->unm_nic_hw_read_wx(adapter
, UNM_PCIE_REG(PCIE_SEM7_UNLOCK
),
348 * Changes the CRB window to the specified window.
351 unm_nic_pci_change_crbwindow_128M(unm_adapter
*adapter
, uint32_t wndw
)
353 unm_pcix_crb_window_t window
;
354 unsigned long offset
;
357 if (adapter
->curr_window
== wndw
) {
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
369 offset
= PCI_OFFSET_SECOND_RANGE(adapter
,
370 UNM_PCIX_PH_REG(PCIE_CRB_WINDOW_REG(adapter
->ahw
.pci_func
)));
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
);
383 adapter
->curr_window
= wndw
;
388 * Changes the CRB window to the specified window.
392 unm_nic_pci_change_crbwindow_2M(unm_adapter
*adapter
, uint32_t wndw
)
398 unm_nic_get_crbwindow(unm_adapter
*adapter
)
400 return (adapter
->curr_window
);
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
411 unm_nic_pci_get_crb_addr_2M(unm_adapter
*adapter
, u64
*off
, int len
)
413 unsigned long end
= *off
+ len
;
414 crb_128M_2M_sub_block_map_t
*m
;
417 if (*off
>= UNM_CRB_MAX
)
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
;
426 if (*off
< UNM_PCI_CRBSPACE
)
429 *off
-= UNM_PCI_CRBSPACE
;
435 m
= &crb_128M_2M_map
[CRB_BLK(*off
)].sub_block
[CRB_SUBBLK(*off
)];
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
;
444 * Not in direct map, use crb window
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
454 unm_nic_pci_set_crbwindow_2M(unm_adapter
*adapter
, u64
*off
)
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
));
462 * Read back value to make sure write has gone through before trying
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
,
472 *off
= (*off
& MASK(16)) + CRB_INDIRECT_2M
+
473 adapter
->ahw
.pci_base0
;
477 unm_nic_hw_write_ioctl_128M(unm_adapter
*adapter
, u64 off
, void *data
, int len
)
482 if (ADDR_IN_WINDOW1(off
)) { // Window 1
483 addr
= CRB_NORMALIZE(adapter
, off
);
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
+
491 UNM_READ_LOCK(&adapter
->adapter_lock
);
493 addr
= (void *) (uptr_t
)(pci_base_offset(adapter
, off
));
496 addr
= (void *) ((uint8_t *)adapter
->ahw
.pci_base0
+
499 UNM_WRITE_LOCK_IRQS(&adapter
->adapter_lock
, flags
);
500 unm_nic_pci_change_crbwindow_128M(adapter
, 0);
505 UNM_NIC_PCI_WRITE_8 (*(__uint8_t
*)data
, addr
);
508 UNM_NIC_PCI_WRITE_16 (*(__uint16_t
*)data
, addr
);
511 UNM_NIC_PCI_WRITE_32 (*(__uint32_t
*)data
, addr
);
514 UNM_NIC_PCI_WRITE_64 (*(__uint64_t
*)data
, addr
);
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
);
522 UNM_NIC_HW_BLOCK_WRITE_64(data
, addr
, (len
>>3));
525 if (ADDR_IN_WINDOW1(off
)) {// Window 1
526 UNM_READ_UNLOCK(&adapter
->adapter_lock
);
528 unm_nic_pci_change_crbwindow_128M(adapter
, 1);
529 UNM_WRITE_UNLOCK_IRQR(&adapter
->adapter_lock
, flags
);
536 * Note : 'len' argument should be either 1, 2, 4, or a multiple of 8.
539 unm_nic_hw_write_wx_128M(unm_adapter
*adapter
, u64 off
, void *data
, int len
)
542 * This is modified from _unm_nic_hw_write().
543 * unm_nic_hw_write does not exist now.
548 if (ADDR_IN_WINDOW1(off
)) {// Window 1
549 addr
= CRB_NORMALIZE(adapter
, off
);
550 UNM_READ_LOCK(&adapter
->adapter_lock
);
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);
559 if (ADDR_IN_WINDOW1(off
)) {// Window 1
560 UNM_READ_UNLOCK(&adapter
->adapter_lock
);
562 unm_nic_pci_change_crbwindow_128M(adapter
, 1);
563 UNM_WRITE_UNLOCK_IRQR(&adapter
->adapter_lock
, flags
);
570 UNM_NIC_PCI_WRITE_8 (*(__uint8_t
*)data
, addr
);
573 UNM_NIC_PCI_WRITE_16 (*(__uint16_t
*)data
, addr
);
576 UNM_NIC_PCI_WRITE_32 (*(__uint32_t
*)data
, addr
);
579 UNM_NIC_PCI_WRITE_64 (*(__uint64_t
*)data
, addr
);
583 if ((len
& 0x7) != 0)
585 "%s: %s len(%d) not multiple of 8.\n",
586 unm_nic_driver_name
, __FUNCTION__
, len
);
588 UNM_NIC_HW_BLOCK_WRITE_64(data
, addr
, (len
>>3));
591 if (ADDR_IN_WINDOW1(off
)) {// Window 1
592 UNM_READ_UNLOCK(&adapter
->adapter_lock
);
594 unm_nic_pci_change_crbwindow_128M(adapter
, 1);
595 UNM_WRITE_UNLOCK_IRQR(&adapter
->adapter_lock
, flags
);
602 * Note : only 32-bit writes!
605 unm_nic_pci_write_normalize_128M(unm_adapter
*adapter
, u64 off
, u32 data
)
607 UNM_NIC_PCI_WRITE_32(data
, CRB_NORMALIZE(adapter
, off
));
611 * Note : only 32-bit reads!
614 unm_nic_pci_read_normalize_128M(unm_adapter
*adapter
, u64 off
)
616 return (UNM_NIC_PCI_READ_32(CRB_NORMALIZE(adapter
, off
)));
620 * Note : only 32-bit writes!
623 unm_nic_pci_write_immediate_128M(unm_adapter
*adapter
, u64 off
, u32
*data
)
625 UNM_NIC_PCI_WRITE_32(*data
,
626 (void *) (uptr_t
)(PCI_OFFSET_SECOND_RANGE(adapter
, off
)));
631 * Note : only 32-bit reads!
634 unm_nic_pci_read_immediate_128M(unm_adapter
*adapter
, u64 off
, u32
*data
)
636 *data
= UNM_NIC_PCI_READ_32((void *)
637 (uptr_t
)(pci_base_offset(adapter
, off
)));
642 * Note : only 32-bit writes!
645 unm_nic_pci_write_normalize_2M(unm_adapter
*adapter
, u64 off
, u32 data
)
649 adapter
->unm_nic_hw_write_wx(adapter
, off
, &temp
, 4);
653 * Note : only 32-bit reads!
656 unm_nic_pci_read_normalize_2M(unm_adapter
*adapter
, u64 off
)
660 adapter
->unm_nic_hw_read_wx(adapter
, off
, &temp
, 4);
666 * Note : only 32-bit writes!
669 unm_nic_pci_write_immediate_2M(unm_adapter
*adapter
, u64 off
, u32
*data
)
673 adapter
->unm_nic_hw_write_wx(adapter
, off
, &temp
, 4);
679 * Note : only 32-bit reads!
682 unm_nic_pci_read_immediate_2M(unm_adapter
*adapter
, u64 off
, u32
*data
)
686 adapter
->unm_nic_hw_read_wx(adapter
, off
, &temp
, 4);
694 * write cross hw window boundary is not supported
695 * 'len' should be either 1, 2, 4, or multiple of 8
698 unm_nic_hw_write_wx_2M(unm_adapter
*adapter
, u64 off
, void *data
, int len
)
702 rv
= unm_nic_pci_get_crb_addr_2M(adapter
, &off
, len
);
705 cmn_err(CE_PANIC
, "%s: invalid offset: 0x%016llx\n",
711 UNM_WRITE_LOCK_IRQS(&adapter
->adapter_lock
, flags
);
712 crb_win_lock(adapter
);
713 unm_nic_pci_set_crbwindow_2M(adapter
, &off
);
718 UNM_NIC_PCI_WRITE_8(*(__uint8_t
*)data
, (void *) (uptr_t
)off
);
721 UNM_NIC_PCI_WRITE_16(*(__uint16_t
*)data
, (void *) (uptr_t
)off
);
724 UNM_NIC_PCI_WRITE_32(*(__uint32_t
*)data
, (void *) (uptr_t
)off
);
727 UNM_NIC_PCI_WRITE_64(*(__uint64_t
*)data
, (void *) (uptr_t
)off
);
731 if ((len
& 0x7) != 0)
732 cmn_err(CE_WARN
, "%s: %s len(%d) not multiple of 8.\n",
733 unm_nic_driver_name
, __FUNCTION__
, len
);
735 UNM_NIC_HW_BLOCK_WRITE_64(data
, (uptr_t
)off
, (len
>>3));
739 crb_win_unlock(adapter
);
740 UNM_WRITE_UNLOCK_IRQR(&adapter
->adapter_lock
, flags
);
747 unm_nic_hw_read_ioctl_128M(unm_adapter
*adapter
, u64 off
, void *data
, int len
)
752 if (ADDR_IN_WINDOW1(off
)) {// Window 1
753 addr
= CRB_NORMALIZE(adapter
, off
);
755 offset
= CRB_NORMAL(off
);
756 if (adapter
->ahw
.pci_len0
== 0)
757 offset
-= UNM_PCI_CRBSPACE
;
758 addr
= (void *) ((uint8_t *)adapter
->ahw
.pci_base0
+
761 UNM_READ_LOCK(&adapter
->adapter_lock
);
763 addr
= (void *) (uptr_t
)(pci_base_offset(adapter
, off
));
766 addr
= (void *) ((uint8_t *)adapter
->ahw
.pci_base0
+
769 UNM_WRITE_LOCK_IRQS(&adapter
->adapter_lock
, flags
);
770 unm_nic_pci_change_crbwindow_128M(adapter
, 0);
775 *(__uint8_t
*)data
= UNM_NIC_PCI_READ_8(addr
);
778 *(__uint16_t
*)data
= UNM_NIC_PCI_READ_16(addr
);
781 *(__uint32_t
*)data
= UNM_NIC_PCI_READ_32(addr
);
784 *(__uint64_t
*)data
= UNM_NIC_PCI_READ_64(addr
);
788 if ((len
& 0x7) != 0)
789 cmn_err(CE_WARN
, "%s: %s len(%d) not multiple of 8.\n",
790 unm_nic_driver_name
, __FUNCTION__
, len
);
792 UNM_NIC_HW_BLOCK_READ_64(data
, addr
, (len
>>3));
796 if (ADDR_IN_WINDOW1(off
)) {// Window 1
797 UNM_READ_UNLOCK(&adapter
->adapter_lock
);
799 unm_nic_pci_change_crbwindow_128M(adapter
, 1);
800 UNM_WRITE_UNLOCK_IRQR(&adapter
->adapter_lock
, flags
);
807 unm_nic_hw_read_wx_2M(unm_adapter
*adapter
, u64 off
, void *data
, int len
)
811 rv
= unm_nic_pci_get_crb_addr_2M(adapter
, &off
, len
);
814 cmn_err(CE_PANIC
, "%s: invalid offset: 0x%016llx\n",
820 UNM_WRITE_LOCK_IRQS(&adapter
->adapter_lock
, flags
);
821 crb_win_lock(adapter
);
822 unm_nic_pci_set_crbwindow_2M(adapter
, &off
);
827 *(__uint8_t
*)data
= UNM_NIC_PCI_READ_8((void *) (uptr_t
)off
);
830 *(__uint16_t
*)data
= UNM_NIC_PCI_READ_16((void *) (uptr_t
)off
);
833 *(__uint32_t
*)data
= UNM_NIC_PCI_READ_32((void *) (uptr_t
)off
);
836 *(__uint64_t
*)data
= UNM_NIC_PCI_READ_64((void *) (uptr_t
)off
);
840 if ((len
& 0x7) != 0)
841 cmn_err(CE_WARN
, "%s: %s len(%d) not multiple of 8.\n",
842 unm_nic_driver_name
, __FUNCTION__
, len
);
844 UNM_NIC_HW_BLOCK_READ_64(data
, (void *) (uptr_t
)off
, (len
>>3));
849 crb_win_unlock(adapter
);
850 UNM_WRITE_UNLOCK_IRQR(&adapter
->adapter_lock
, flags
);
857 unm_nic_hw_read_wx_128M(unm_adapter
*adapter
, u64 off
, void *data
, int len
)
861 if (ADDR_IN_WINDOW1(off
)) {
863 addr
= CRB_NORMALIZE(adapter
, off
);
864 UNM_READ_LOCK(&adapter
->adapter_lock
);
866 addr
= (void *) (uptr_t
)(pci_base_offset(adapter
, off
));
867 UNM_WRITE_LOCK_IRQS(&adapter
->adapter_lock
, flags
);
868 unm_nic_pci_change_crbwindow_128M(adapter
, 0);
872 if (ADDR_IN_WINDOW1(off
)) {// Window 1
873 UNM_READ_UNLOCK(&adapter
->adapter_lock
);
875 unm_nic_pci_change_crbwindow_128M(adapter
, 1);
876 UNM_WRITE_UNLOCK_IRQR(&adapter
->adapter_lock
, flags
);
883 *(__uint8_t
*)data
= UNM_NIC_PCI_READ_8(addr
);
886 *(__uint16_t
*)data
= UNM_NIC_PCI_READ_16(addr
);
889 *(__uint32_t
*)data
= UNM_NIC_PCI_READ_32(addr
);
892 *(__uint64_t
*)data
= UNM_NIC_PCI_READ_64(addr
);
896 if ((len
& 0x7) != 0)
898 "%s: %s len(%d) not multiple of 8.\n",
899 unm_nic_driver_name
, __FUNCTION__
, len
);
901 UNM_NIC_HW_BLOCK_READ_64(data
, addr
, (len
>>3));
905 if (ADDR_IN_WINDOW1(off
)) {// Window 1
906 UNM_READ_UNLOCK(&adapter
->adapter_lock
);
908 unm_nic_pci_change_crbwindow_128M(adapter
, 1);
909 UNM_WRITE_UNLOCK_IRQR(&adapter
->adapter_lock
, flags
);
915 /* PCI Windowing for DDR regions. */
916 #define ADDR_IN_RANGE(addr, low, high) \
917 (((addr) <= (high)) && ((low) ? ((addr) >= (low)) : 1))
920 * check memory access boundary.
921 * used by test agent. support ddr access only for now
925 unm_nic_pci_mem_bound_check(struct unm_adapter_s
*adapter
,
926 unsigned long long addr
, int size
)
928 if (!ADDR_IN_RANGE(addr
, UNM_ADDR_DDR_NET
, UNM_ADDR_DDR_NET_MAX
) ||
929 !ADDR_IN_RANGE(addr
+ size
-1, UNM_ADDR_DDR_NET
,
930 UNM_ADDR_DDR_NET_MAX
) || ((size
!= 1) && (size
!= 2) &&
931 (size
!= 4) && (size
!= 8)))
937 int unm_pci_set_window_warning_count
= 0;
940 unm_nic_pci_set_window_128M(struct unm_adapter_s
*adapter
,
941 unsigned long long addr
)
944 unsigned long long qdr_max
;
946 if (NX_IS_REVISION_P2(adapter
->ahw
.revision_id
)) {
947 qdr_max
= NX_P2_ADDR_QDR_NET_MAX
;
949 qdr_max
= NX_P3_ADDR_QDR_NET_MAX
;
952 if (ADDR_IN_RANGE(addr
, UNM_ADDR_DDR_NET
, UNM_ADDR_DDR_NET_MAX
)) {
953 /* DDR network side */
954 /* MN access should never come here */
955 cmn_err(CE_PANIC
, "%s\n", __FUNCTION__
);
957 } else if (ADDR_IN_RANGE(addr
, UNM_ADDR_OCM0
, UNM_ADDR_OCM0_MAX
)) {
958 addr
-= UNM_ADDR_OCM0
;
959 addr
+= UNM_PCI_OCM0
;
960 } else if (ADDR_IN_RANGE(addr
, UNM_ADDR_OCM1
, UNM_ADDR_OCM1_MAX
)) {
961 addr
-= UNM_ADDR_OCM1
;
962 addr
+= UNM_PCI_OCM1
;
963 } else if (ADDR_IN_RANGE(addr
, UNM_ADDR_QDR_NET
, qdr_max
)) {
964 /* QDR network side */
965 addr
-= UNM_ADDR_QDR_NET
;
966 window
= (addr
>> 22) & 0x3f;
967 if (adapter
->ahw
.qdr_sn_window
!= window
) {
968 adapter
->ahw
.qdr_sn_window
= window
;
969 UNM_NIC_PCI_WRITE_32((window
<< 22),
970 (void *) (uptr_t
)(PCI_OFFSET_SECOND_RANGE(adapter
,
971 UNM_PCIX_PH_REG(PCIE_SN_WINDOW_REG(
972 adapter
->ahw
.pci_func
)))));
973 /* MUST make sure window is set before we forge on... */
974 (void) UNM_NIC_PCI_READ_32((void *)
975 (uptr_t
)(PCI_OFFSET_SECOND_RANGE(adapter
,
976 UNM_PCIX_PH_REG(PCIE_SN_WINDOW_REG(
977 adapter
->ahw
.pci_func
)))));
979 addr
-= (window
* 0x400000);
980 addr
+= UNM_PCI_QDR_NET
;
983 * peg gdb frequently accesses memory that doesn't exist,
984 * this limits the chit chat so debugging isn't slowed down.
986 if ((unm_pci_set_window_warning_count
++ < 8) ||
987 (unm_pci_set_window_warning_count
%64 == 0)) {
988 cmn_err(CE_WARN
, "%s: Warning:unm_nic_pci_set_window() "
989 "Unknown address range!\n", unm_nic_driver_name
);
997 unm_nic_pci_set_window_2M(struct unm_adapter_s
*adapter
,
998 unsigned long long addr
)
1003 if (ADDR_IN_RANGE(addr
, UNM_ADDR_DDR_NET
, UNM_ADDR_DDR_NET_MAX
)) {
1004 /* DDR network side */
1005 window
= MN_WIN(addr
);
1006 adapter
->ahw
.ddr_mn_window
= window
;
1007 adapter
->unm_nic_hw_write_wx(adapter
, adapter
->ahw
.mn_win_crb
|
1008 UNM_PCI_CRBSPACE
, &window
, 4);
1009 adapter
->unm_nic_hw_read_wx(adapter
, adapter
->ahw
.mn_win_crb
|
1010 UNM_PCI_CRBSPACE
, &win_read
, 4);
1011 if ((win_read
<< 17) != window
) {
1013 "%s: Written MNwin (0x%x) != Read MNwin (0x%x)\n",
1014 __FUNCTION__
, window
, win_read
);
1016 addr
= GET_MEM_OFFS_2M(addr
) + UNM_PCI_DDR_NET
;
1017 } else if (ADDR_IN_RANGE(addr
, UNM_ADDR_OCM0
, UNM_ADDR_OCM0_MAX
)) {
1019 // OCM: pci_addr[20:18] == 011 && pci_addr[17:11] != 7f
1020 if ((addr
& 0x00ff800) == 0xff800) {
1021 // if bits 19:18&17:11 are on
1022 cmn_err(CE_WARN
, "%s: QM access not handled.\n",
1027 window
= OCM_WIN(addr
);
1028 adapter
->ahw
.ddr_mn_window
= window
;
1029 adapter
->unm_nic_hw_write_wx(adapter
, adapter
->ahw
.mn_win_crb
|
1030 UNM_PCI_CRBSPACE
, &window
, 4);
1031 adapter
->unm_nic_hw_read_wx(adapter
, adapter
->ahw
.mn_win_crb
|
1032 UNM_PCI_CRBSPACE
, &win_read
, 4);
1033 temp1
= ((window
& 0x1FF) << 7) |
1034 ((window
& 0x0FFFE0000) >> 17);
1035 if (win_read
!= temp1
) {
1037 "%s: Written OCMwin(0x%x) != Read OCMwin(0x%x)\n",
1038 __FUNCTION__
, temp1
, win_read
);
1040 addr
= GET_MEM_OFFS_2M(addr
) + UNM_PCI_OCM0_2M
;
1042 } else if (ADDR_IN_RANGE(addr
, UNM_ADDR_QDR_NET
,
1043 NX_P3_ADDR_QDR_NET_MAX
)) {
1044 /* QDR network side */
1045 window
= MS_WIN(addr
);
1046 adapter
->ahw
.qdr_sn_window
= window
;
1047 adapter
->unm_nic_hw_write_wx(adapter
, adapter
->ahw
.ms_win_crb
|
1048 UNM_PCI_CRBSPACE
, &window
, 4);
1049 adapter
->unm_nic_hw_read_wx(adapter
, adapter
->ahw
.ms_win_crb
|
1050 UNM_PCI_CRBSPACE
, &win_read
, 4);
1051 if (win_read
!= window
) {
1053 "%s: Written MSwin (0x%x) != Read MSwin (0x%x)\n",
1054 __FUNCTION__
, window
, win_read
);
1056 addr
= GET_MEM_OFFS_2M(addr
) + UNM_PCI_QDR_NET
;
1060 * peg gdb frequently accesses memory that doesn't exist,
1061 * this limits the chit chat so debugging isn't slowed down.
1063 if ((unm_pci_set_window_warning_count
++ < 8) ||
1064 (unm_pci_set_window_warning_count
%64 == 0)) {
1065 cmn_err(CE_WARN
, "%s%d: %s Unknown address range!\n",
1066 adapter
->name
, adapter
->instance
, __FUNCTION__
);
1073 /* check if address is in the same windows as the previous access */
1074 static unsigned long
1075 unm_nic_pci_is_same_window(struct unm_adapter_s
*adapter
,
1076 unsigned long long addr
)
1079 unsigned long long qdr_max
;
1081 if (NX_IS_REVISION_P2(adapter
->ahw
.revision_id
)) {
1082 qdr_max
= NX_P2_ADDR_QDR_NET_MAX
;
1084 qdr_max
= NX_P3_ADDR_QDR_NET_MAX
;
1087 if (ADDR_IN_RANGE(addr
, UNM_ADDR_DDR_NET
, UNM_ADDR_DDR_NET_MAX
)) {
1088 /* DDR network side */
1089 /* MN access can not come here */
1090 cmn_err(CE_PANIC
, "%s\n", __FUNCTION__
);
1092 window
= ((addr
- UNM_ADDR_DDR_NET
) >> 25) & 0x3ff;
1093 if (adapter
->ahw
.ddr_mn_window
== window
) {
1097 } else if (ADDR_IN_RANGE(addr
, UNM_ADDR_OCM0
, UNM_ADDR_OCM0_MAX
)) {
1099 } else if (ADDR_IN_RANGE(addr
, UNM_ADDR_OCM1
, UNM_ADDR_OCM1_MAX
)) {
1101 } else if (ADDR_IN_RANGE(addr
, UNM_ADDR_QDR_NET
, qdr_max
)) {
1102 /* QDR network side */
1103 window
= ((addr
- UNM_ADDR_QDR_NET
) >> 22) & 0x3f;
1104 if (adapter
->ahw
.qdr_sn_window
== window
) {
1113 unm_nic_pci_mem_read_direct(struct unm_adapter_s
*adapter
,
1114 u64 off
, void *data
, int size
)
1122 * This check can not be currently executed, since phanmon findq
1123 * command breaks this check whereby 8 byte reads are being attempted
1124 * on "aligned-by-4" addresses on x86. Reason this works is our version
1125 * breaks up the access into 2 consecutive 4 byte writes; on other
1126 * architectures, this might require "aligned-by-8" addresses and we
1127 * will run into trouble.
1129 * Check alignment for expected sizes of 1, 2, 4, 8. Other size
1130 * values will not trigger access.
1132 if ((off
& (size
- 1)) != 0)
1136 UNM_WRITE_LOCK_IRQS(&adapter
->adapter_lock
, flags
);
1139 * If attempting to access unknown address or straddle hw windows,
1142 if (((start
= adapter
->unm_nic_pci_set_window(adapter
, off
)) == -1UL) ||
1143 (unm_nic_pci_is_same_window(adapter
, off
+ size
-1) == 0)) {
1144 UNM_WRITE_UNLOCK_IRQR(&adapter
->adapter_lock
, flags
);
1145 cmn_err(CE_WARN
, "%s out of bound pci memory access. "
1146 "offset is 0x%llx\n", unm_nic_driver_name
, off
);
1150 addr
= (void *) (uptr_t
)(pci_base_offset(adapter
, start
));
1152 addr
= (void *) ((uint8_t *)adapter
->ahw
.pci_base0
+ start
);
1156 *(__uint8_t
*)data
= UNM_NIC_PCI_READ_8(addr
);
1159 *(__uint16_t
*)data
= UNM_NIC_PCI_READ_16(addr
);
1162 *(__uint32_t
*)data
= UNM_NIC_PCI_READ_32(addr
);
1165 *(__uint64_t
*)data
= UNM_NIC_PCI_READ_64(addr
);
1172 UNM_WRITE_UNLOCK_IRQR(&adapter
->adapter_lock
, flags
);
1177 unm_nic_pci_mem_write_direct(struct unm_adapter_s
*adapter
, u64 off
,
1178 void *data
, int size
)
1186 * This check can not be currently executed, since firmware load
1187 * breaks this check whereby 8 byte writes are being attempted on
1188 * "aligned-by-4" addresses on x86. Reason this works is our version
1189 * breaks up the access into 2 consecutive 4 byte writes; on other
1190 * architectures, this might require "aligned-by-8" addresses and we
1191 * will run into trouble.
1193 * Check alignment for expected sizes of 1, 2, 4, 8. Other size
1194 * values will not trigger access.
1196 if ((off
& (size
- 1)) != 0)
1200 UNM_WRITE_LOCK_IRQS(&adapter
->adapter_lock
, flags
);
1203 * If attempting to access unknown address or straddle hw windows,
1206 if (((start
= adapter
->unm_nic_pci_set_window(adapter
, off
)) == -1UL) ||
1207 (unm_nic_pci_is_same_window(adapter
, off
+ size
-1) == 0)) {
1208 UNM_WRITE_UNLOCK_IRQR(&adapter
->adapter_lock
, flags
);
1209 cmn_err(CE_WARN
, "%s out of bound pci memory access. "
1210 "offset is 0x%llx\n", unm_nic_driver_name
, off
);
1214 addr
= (void *) (uptr_t
)(pci_base_offset(adapter
, start
));
1216 addr
= (void *) ((uint8_t *)adapter
->ahw
.pci_base0
+ start
);
1220 UNM_NIC_PCI_WRITE_8(*(__uint8_t
*)data
, addr
);
1223 UNM_NIC_PCI_WRITE_16(*(__uint16_t
*)data
, addr
);
1226 UNM_NIC_PCI_WRITE_32(*(__uint32_t
*)data
, addr
);
1229 UNM_NIC_PCI_WRITE_64(*(__uint64_t
*)data
, addr
);
1235 UNM_WRITE_UNLOCK_IRQR(&adapter
->adapter_lock
, flags
);
1241 unm_nic_pci_mem_write_128M(struct unm_adapter_s
*adapter
, u64 off
, void *data
,
1244 int i
, j
, ret
= 0, loop
, sz
[2], off0
;
1246 __uint64_t off8
, mem_crb
, tmpw
, word
[2] = {0, 0};
1247 #define MAX_CTL_CHECK 1000
1250 * If not MN, go check for MS or invalid.
1252 if (unm_nic_pci_mem_bound_check(adapter
, off
, size
) == 0)
1253 return (unm_nic_pci_mem_write_direct(adapter
, off
, data
, size
));
1255 off8
= off
& 0xfffffff8;
1257 sz
[0] = (size
< (8 - off0
)) ? size
: (8 - off0
);
1258 sz
[1] = size
- sz
[0];
1259 loop
= ((off0
+ size
- 1) >> 3) + 1;
1260 /* LINTED: E_FALSE_LOGICAL_EXPR */
1261 mem_crb
= (uptr_t
)(pci_base_offset(adapter
, UNM_CRB_DDR_NET
));
1263 if ((size
!= 8) || (off0
!= 0)) {
1264 for (i
= 0; i
< loop
; i
++) {
1265 if (adapter
->unm_nic_pci_mem_read(adapter
,
1266 off8
+ (i
<< 3), &word
[i
], 8))
1273 tmpw
= *((__uint8_t
*)data
);
1276 tmpw
= *((__uint16_t
*)data
);
1279 tmpw
= *((__uint32_t
*)data
);
1283 tmpw
= *((__uint64_t
*)data
);
1286 word
[0] &= ~((~(~0ULL << (sz
[0] * 8))) << (off0
* 8));
1287 word
[0] |= tmpw
<< (off0
* 8);
1290 word
[1] &= ~(~0ULL << (sz
[1] * 8));
1291 word
[1] |= tmpw
>> (sz
[0] * 8);
1294 UNM_WRITE_LOCK_IRQS(&adapter
->adapter_lock
, flags
);
1295 unm_nic_pci_change_crbwindow_128M(adapter
, 0);
1297 for (i
= 0; i
< loop
; i
++) {
1298 UNM_NIC_PCI_WRITE_32((__uint32_t
)(off8
+ (i
<< 3)),
1299 (void *) (uptr_t
)(mem_crb
+MIU_TEST_AGT_ADDR_LO
));
1300 UNM_NIC_PCI_WRITE_32(0,
1301 (void *) (uptr_t
)(mem_crb
+MIU_TEST_AGT_ADDR_HI
));
1302 UNM_NIC_PCI_WRITE_32(word
[i
] & 0xffffffff,
1303 (void *) (uptr_t
)(mem_crb
+MIU_TEST_AGT_WRDATA_LO
));
1304 UNM_NIC_PCI_WRITE_32((word
[i
] >> 32) & 0xffffffff,
1305 (void *) (uptr_t
)(mem_crb
+MIU_TEST_AGT_WRDATA_HI
));
1306 UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_ENABLE
|MIU_TA_CTL_WRITE
,
1307 (void *) (uptr_t
)(mem_crb
+MIU_TEST_AGT_CTRL
));
1308 UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_START
| MIU_TA_CTL_ENABLE
|
1310 (void *) (uptr_t
)(mem_crb
+MIU_TEST_AGT_CTRL
));
1312 for (j
= 0; j
< MAX_CTL_CHECK
; j
++) {
1313 temp
= UNM_NIC_PCI_READ_32((void *)
1314 (uptr_t
)(mem_crb
+MIU_TEST_AGT_CTRL
));
1315 if ((temp
& MIU_TA_CTL_BUSY
) == 0) {
1320 if (j
>= MAX_CTL_CHECK
) {
1321 cmn_err(CE_WARN
, "%s: %s Fail to write thru agent\n",
1322 __FUNCTION__
, unm_nic_driver_name
);
1328 unm_nic_pci_change_crbwindow_128M(adapter
, 1);
1329 UNM_WRITE_UNLOCK_IRQR(&adapter
->adapter_lock
, flags
);
1334 unm_nic_pci_mem_read_128M(struct unm_adapter_s
*adapter
, u64 off
, void *data
,
1337 int i
, j
= 0, k
, start
, end
, loop
, sz
[2], off0
[2];
1339 __uint64_t off8
, val
, mem_crb
, word
[2] = {0, 0};
1340 #define MAX_CTL_CHECK 1000
1343 * If not MN, go check for MS or invalid.
1345 if (unm_nic_pci_mem_bound_check(adapter
, off
, size
) == 0)
1346 return (unm_nic_pci_mem_read_direct(adapter
, off
, data
, size
));
1348 off8
= off
& 0xfffffff8;
1349 off0
[0] = off
& 0x7;
1351 sz
[0] = (size
< (8 - off0
[0])) ? size
: (8 - off0
[0]);
1352 sz
[1] = size
- sz
[0];
1353 loop
= ((off0
[0] + size
- 1) >> 3) + 1;
1354 /* LINTED: E_FALSE_LOGICAL_EXPR */
1355 mem_crb
= (uptr_t
)(pci_base_offset(adapter
, UNM_CRB_DDR_NET
));
1357 UNM_WRITE_LOCK_IRQS(&adapter
->adapter_lock
, flags
);
1358 unm_nic_pci_change_crbwindow_128M(adapter
, 0);
1360 for (i
= 0; i
< loop
; i
++) {
1361 UNM_NIC_PCI_WRITE_32((__uint32_t
)(off8
+ (i
<< 3)),
1362 (void *) (uptr_t
)(mem_crb
+MIU_TEST_AGT_ADDR_LO
));
1363 UNM_NIC_PCI_WRITE_32(0,
1364 (void *) (uptr_t
)(mem_crb
+MIU_TEST_AGT_ADDR_HI
));
1365 UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_ENABLE
,
1366 (void *) (uptr_t
)(mem_crb
+MIU_TEST_AGT_CTRL
));
1367 UNM_NIC_PCI_WRITE_32(MIU_TA_CTL_START
|MIU_TA_CTL_ENABLE
,
1368 (void *) (uptr_t
)(mem_crb
+MIU_TEST_AGT_CTRL
));
1370 for (j
= 0; j
< MAX_CTL_CHECK
; j
++) {
1371 temp
= UNM_NIC_PCI_READ_32((void *)
1372 (uptr_t
)(mem_crb
+MIU_TEST_AGT_CTRL
));
1373 if ((temp
& MIU_TA_CTL_BUSY
) == 0) {
1378 if (j
>= MAX_CTL_CHECK
) {
1379 cmn_err(CE_WARN
, "%s: %s Fail to read through agent\n",
1380 __FUNCTION__
, unm_nic_driver_name
);
1384 start
= off0
[i
] >> 2;
1385 end
= (off0
[i
] + sz
[i
] - 1) >> 2;
1387 for (k
= start
; k
<= end
; k
++) {
1388 word
[i
] |= ((__uint64_t
)UNM_NIC_PCI_READ_32(
1389 (void *) (uptr_t
)(mem_crb
+
1390 MIU_TEST_AGT_RDDATA(k
))) << (32*k
));
1394 unm_nic_pci_change_crbwindow_128M(adapter
, 1);
1395 UNM_WRITE_UNLOCK_IRQR(&adapter
->adapter_lock
, flags
);
1397 if (j
>= MAX_CTL_CHECK
)
1403 val
= ((word
[0] >> (off0
[0] * 8)) & (~(~0ULL << (sz
[0] * 8)))) |
1404 ((word
[1] & (~(~0ULL << (sz
[1] * 8)))) << (sz
[0] * 8));
1409 *(__uint8_t
*)data
= val
;
1412 *(__uint16_t
*)data
= val
;
1415 *(__uint32_t
*)data
= val
;
1418 *(__uint64_t
*)data
= val
;
1427 unm_nic_pci_mem_write_2M(struct unm_adapter_s
*adapter
, u64 off
, void *data
,
1430 int i
, j
, ret
= 0, loop
, sz
[2], off0
;
1432 __uint64_t off8
, mem_crb
, tmpw
, word
[2] = {0, 0};
1433 #define MAX_CTL_CHECK 1000
1436 * If not MN, go check for MS or invalid.
1438 if (off
>= UNM_ADDR_QDR_NET
&& off
<= NX_P3_ADDR_QDR_NET_MAX
) {
1439 mem_crb
= UNM_CRB_QDR_NET
;
1441 mem_crb
= UNM_CRB_DDR_NET
;
1442 if (unm_nic_pci_mem_bound_check(adapter
, off
, size
) == 0)
1443 return (unm_nic_pci_mem_write_direct(adapter
,
1447 off8
= off
& 0xfffffff8;
1449 sz
[0] = (size
< (8 - off0
)) ? size
: (8 - off0
);
1450 sz
[1] = size
- sz
[0];
1451 loop
= ((off0
+ size
- 1) >> 3) + 1;
1453 if ((size
!= 8) || (off0
!= 0)) {
1454 for (i
= 0; i
< loop
; i
++) {
1455 if (adapter
->unm_nic_pci_mem_read(adapter
,
1456 off8
+ (i
<< 3), &word
[i
], 8))
1463 tmpw
= *((__uint8_t
*)data
);
1466 tmpw
= *((__uint16_t
*)data
);
1469 tmpw
= *((__uint32_t
*)data
);
1473 tmpw
= *((__uint64_t
*)data
);
1477 word
[0] &= ~((~(~0ULL << (sz
[0] * 8))) << (off0
* 8));
1478 word
[0] |= tmpw
<< (off0
* 8);
1481 word
[1] &= ~(~0ULL << (sz
[1] * 8));
1482 word
[1] |= tmpw
>> (sz
[0] * 8);
1485 // don't lock here - write_wx gets the lock if each time
1486 // UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1487 // unm_nic_pci_change_crbwindow_128M(adapter, 0);
1489 for (i
= 0; i
< loop
; i
++) {
1490 temp
= off8
+ (i
<< 3);
1491 adapter
->unm_nic_hw_write_wx(adapter
,
1492 mem_crb
+MIU_TEST_AGT_ADDR_LO
, &temp
, 4);
1494 adapter
->unm_nic_hw_write_wx(adapter
,
1495 mem_crb
+MIU_TEST_AGT_ADDR_HI
, &temp
, 4);
1496 temp
= word
[i
] & 0xffffffff;
1497 adapter
->unm_nic_hw_write_wx(adapter
,
1498 mem_crb
+MIU_TEST_AGT_WRDATA_LO
, &temp
, 4);
1499 temp
= (word
[i
] >> 32) & 0xffffffff;
1500 adapter
->unm_nic_hw_write_wx(adapter
,
1501 mem_crb
+MIU_TEST_AGT_WRDATA_HI
, &temp
, 4);
1502 temp
= MIU_TA_CTL_ENABLE
| MIU_TA_CTL_WRITE
;
1503 adapter
->unm_nic_hw_write_wx(adapter
,
1504 mem_crb
+MIU_TEST_AGT_CTRL
, &temp
, 4);
1505 temp
= MIU_TA_CTL_START
| MIU_TA_CTL_ENABLE
| MIU_TA_CTL_WRITE
;
1506 adapter
->unm_nic_hw_write_wx(adapter
,
1507 mem_crb
+MIU_TEST_AGT_CTRL
, &temp
, 4);
1509 for (j
= 0; j
< MAX_CTL_CHECK
; j
++) {
1510 adapter
->unm_nic_hw_read_wx(adapter
,
1511 mem_crb
+ MIU_TEST_AGT_CTRL
, &temp
, 4);
1512 if ((temp
& MIU_TA_CTL_BUSY
) == 0) {
1517 if (j
>= MAX_CTL_CHECK
) {
1518 cmn_err(CE_WARN
, "%s: Fail to write through agent\n",
1519 unm_nic_driver_name
);
1525 // unm_nic_pci_change_crbwindow_128M(adapter, 1);
1526 // UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1531 unm_nic_pci_mem_read_2M(struct unm_adapter_s
*adapter
, u64 off
, void *data
,
1534 // unsigned long flags;
1535 int i
, j
= 0, k
, start
, end
, loop
, sz
[2], off0
[2];
1537 __uint64_t off8
, val
, mem_crb
, word
[2] = {0, 0};
1538 #define MAX_CTL_CHECK 1000
1541 * If not MN, go check for MS or invalid.
1544 if (off
>= UNM_ADDR_QDR_NET
&& off
<= NX_P3_ADDR_QDR_NET_MAX
) {
1545 mem_crb
= UNM_CRB_QDR_NET
;
1547 mem_crb
= UNM_CRB_DDR_NET
;
1548 if (unm_nic_pci_mem_bound_check(adapter
, off
, size
) == 0)
1549 return (unm_nic_pci_mem_read_direct(adapter
,
1553 off8
= off
& 0xfffffff8;
1554 off0
[0] = off
& 0x7;
1556 sz
[0] = (size
< (8 - off0
[0])) ? size
: (8 - off0
[0]);
1557 sz
[1] = size
- sz
[0];
1558 loop
= ((off0
[0] + size
- 1) >> 3) + 1;
1560 // don't get lock - write_wx will get it
1561 // UNM_WRITE_LOCK_IRQS(&adapter->adapter_lock, flags);
1562 // unm_nic_pci_change_crbwindow_128M(adapter, 0);
1564 for (i
= 0; i
< loop
; i
++) {
1565 temp
= off8
+ (i
<< 3);
1566 adapter
->unm_nic_hw_write_wx(adapter
,
1567 mem_crb
+ MIU_TEST_AGT_ADDR_LO
, &temp
, 4);
1569 adapter
->unm_nic_hw_write_wx(adapter
,
1570 mem_crb
+ MIU_TEST_AGT_ADDR_HI
, &temp
, 4);
1571 temp
= MIU_TA_CTL_ENABLE
;
1572 adapter
->unm_nic_hw_write_wx(adapter
,
1573 mem_crb
+ MIU_TEST_AGT_CTRL
, &temp
, 4);
1574 temp
= MIU_TA_CTL_START
| MIU_TA_CTL_ENABLE
;
1575 adapter
->unm_nic_hw_write_wx(adapter
,
1576 mem_crb
+ MIU_TEST_AGT_CTRL
, &temp
, 4);
1578 for (j
= 0; j
< MAX_CTL_CHECK
; j
++) {
1579 adapter
->unm_nic_hw_read_wx(adapter
,
1580 mem_crb
+ MIU_TEST_AGT_CTRL
, &temp
, 4);
1581 if ((temp
& MIU_TA_CTL_BUSY
) == 0) {
1586 if (j
>= MAX_CTL_CHECK
) {
1587 cmn_err(CE_WARN
, "%s: Fail to read through agent\n",
1588 unm_nic_driver_name
);
1592 start
= off0
[i
] >> 2;
1593 end
= (off0
[i
] + sz
[i
] - 1) >> 2;
1594 for (k
= start
; k
<= end
; k
++) {
1595 adapter
->unm_nic_hw_read_wx(adapter
,
1596 mem_crb
+ MIU_TEST_AGT_RDDATA(k
), &temp
, 4);
1597 word
[i
] |= ((__uint64_t
)temp
<< (32 * k
));
1601 // unm_nic_pci_change_crbwindow_128M(adapter, 1);
1602 // UNM_WRITE_UNLOCK_IRQR(&adapter->adapter_lock, flags);
1604 if (j
>= MAX_CTL_CHECK
)
1610 val
= ((word
[0] >> (off0
[0] * 8)) & (~(~0ULL << (sz
[0] * 8)))) |
1611 ((word
[1] & (~(~0ULL << (sz
[1] * 8)))) << (sz
[0] * 8));
1616 *(__uint8_t
*)data
= val
;
1619 *(__uint16_t
*)data
= val
;
1622 *(__uint32_t
*)data
= val
;
1625 *(__uint64_t
*)data
= val
;
1632 unm_crb_writelit_adapter_2M(struct unm_adapter_s
*adapter
, unsigned long off
,
1635 return (unm_nic_hw_write_wx_2M(adapter
, off
, &data
, 4));
1639 unm_crb_writelit_adapter_128M(struct unm_adapter_s
*adapter
, unsigned long off
,
1644 if (ADDR_IN_WINDOW1(off
)) {
1645 UNM_READ_LOCK(&adapter
->adapter_lock
);
1646 UNM_NIC_PCI_WRITE_32(data
, CRB_NORMALIZE(adapter
, off
));
1647 UNM_READ_UNLOCK(&adapter
->adapter_lock
);
1649 // unm_nic_write_w0 (adapter, off, data);
1650 UNM_WRITE_LOCK_IRQS(&adapter
->adapter_lock
, flags
);
1651 unm_nic_pci_change_crbwindow_128M(adapter
, 0);
1652 addr
= (void *) (pci_base_offset(adapter
, off
));
1653 UNM_NIC_PCI_WRITE_32(data
, addr
);
1654 unm_nic_pci_change_crbwindow_128M(adapter
, 1);
1655 UNM_WRITE_UNLOCK_IRQR(&adapter
->adapter_lock
, flags
);
1662 unm_nic_get_board_info(struct unm_adapter_s
*adapter
)
1665 unm_board_info_t
*boardinfo
;
1667 int addr
= BRDCFG_START
;
1671 boardinfo
= &adapter
->ahw
.boardcfg
;
1672 ptr32
= (uint32_t *)boardinfo
;
1674 for (i
= 0; i
< sizeof (unm_board_info_t
) / sizeof (uint32_t); i
++) {
1675 if (rom_fast_read(adapter
, addr
, (int *)ptr32
) == -1) {
1678 DPRINTF(1, (CE_WARN
, "ROM(%d): %x\n", i
, *ptr32
));
1680 addr
+= sizeof (uint32_t);
1683 if (boardinfo
->magic
!= UNM_BDINFO_MAGIC
) {
1684 DPRINTF(1, (CE_WARN
, "%s: ERROR reading board config."
1685 " Read %x, expected %x\n", unm_nic_driver_name
,
1686 boardinfo
->magic
, UNM_BDINFO_MAGIC
));
1690 if (boardinfo
->header_version
!= UNM_BDINFO_VERSION
) {
1691 DPRINTF(1, (CE_WARN
, "%s: Unknown board config version."
1692 " Read %x, expected %x\n", unm_nic_driver_name
,
1693 boardinfo
->header_version
, UNM_BDINFO_VERSION
));
1697 if (boardinfo
->board_type
== UNM_BRDTYPE_P3_4_GB_MM
) {
1698 gpioval
= UNM_CRB_READ_VAL_ADAPTER(UNM_ROMUSB_GLB_PAD_GPIO_I
,
1700 if ((gpioval
& 0x8000) == 0)
1701 boardinfo
->board_type
= UNM_BRDTYPE_P3_10G_TRP
;
1704 DPRINTF(0, (CE_WARN
, "Discovered board type:0x%x ",
1705 boardinfo
->board_type
));
1707 switch ((unm_brdtype_t
)boardinfo
->board_type
) {
1708 case UNM_BRDTYPE_P2_SB35_4G
:
1709 adapter
->ahw
.board_type
= UNM_NIC_GBE
;
1711 case UNM_BRDTYPE_P2_SB31_10G
:
1712 case UNM_BRDTYPE_P2_SB31_10G_IMEZ
:
1713 case UNM_BRDTYPE_P2_SB31_10G_HMEZ
:
1714 case UNM_BRDTYPE_P2_SB31_10G_CX4
:
1715 case UNM_BRDTYPE_P3_HMEZ
:
1716 case UNM_BRDTYPE_P3_XG_LOM
:
1717 case UNM_BRDTYPE_P3_10G_CX4
:
1718 case UNM_BRDTYPE_P3_10G_CX4_LP
:
1719 case UNM_BRDTYPE_P3_IMEZ
:
1720 case UNM_BRDTYPE_P3_10G_SFP_PLUS
:
1721 case UNM_BRDTYPE_P3_10G_XFP
:
1722 case UNM_BRDTYPE_P3_10000_BASE_T
:
1723 adapter
->ahw
.board_type
= UNM_NIC_XGBE
;
1725 case UNM_BRDTYPE_P3_REF_QG
:
1726 case UNM_BRDTYPE_P3_4_GB
:
1727 case UNM_BRDTYPE_P3_4_GB_MM
:
1728 adapter
->ahw
.board_type
= UNM_NIC_GBE
;
1730 case UNM_BRDTYPE_P1_BD
:
1731 case UNM_BRDTYPE_P1_SB
:
1732 case UNM_BRDTYPE_P1_SMAX
:
1733 case UNM_BRDTYPE_P1_SOCK
:
1734 adapter
->ahw
.board_type
= UNM_NIC_GBE
;
1736 case UNM_BRDTYPE_P3_10G_TRP
:
1737 if (adapter
->portnum
< 2)
1738 adapter
->ahw
.board_type
= UNM_NIC_XGBE
;
1740 adapter
->ahw
.board_type
= UNM_NIC_GBE
;
1743 DPRINTF(1, (CE_WARN
, "%s: Unknown(%x)\n", unm_nic_driver_name
,
1744 boardinfo
->board_type
));
1751 /* NIU access sections */
1754 unm_nic_macaddr_set(struct unm_adapter_s
*adapter
, __uint8_t
*addr
)
1756 int ret
= 0, i
, retry_count
= 10;
1757 unsigned char mac_addr
[MAX_ADDR_LEN
];
1759 /* For P3, we should not set MAC in HW any more */
1760 if (NX_IS_REVISION_P3(adapter
->ahw
.revision_id
))
1763 switch (adapter
->ahw
.board_type
) {
1766 * Flaky Mac address registers on qgig require several writes.
1768 for (i
= 0; i
< retry_count
; ++i
) {
1769 if (unm_niu_macaddr_set(adapter
, addr
) != 0)
1772 (void) unm_niu_macaddr_get(adapter
,
1773 (unsigned char *)mac_addr
);
1774 if (memcmp(mac_addr
, addr
, 6) == 0)
1777 cmn_err(CE_WARN
, "%s: Flaky MAC addr registers\n",
1778 unm_nic_driver_name
);
1782 ret
= unm_niu_xg_macaddr_set(adapter
, addr
);
1786 cmn_err(CE_WARN
, "\r\nUnknown board type encountered"
1787 " while setting the MAC address.\n");
1793 #define MTU_FUDGE_FACTOR 100
1795 unm_nic_set_mtu(struct unm_adapter_s
*adapter
, int new_mtu
)
1797 long port
= adapter
->physical_port
;
1801 if (adapter
->ahw
.revision_id
>= NX_P3_A2
)
1802 return (nx_fw_cmd_set_mtu(adapter
, new_mtu
));
1804 new_mtu
+= MTU_FUDGE_FACTOR
; /* so that MAC accepts frames > MTU */
1805 switch (adapter
->ahw
.board_type
) {
1807 unm_nic_write_w0(adapter
,
1808 UNM_NIU_GB_MAX_FRAME_SIZE(adapter
->physical_port
),
1814 adapter
->unm_nic_hw_read_wx(adapter
, UNM_PORT_MODE_ADDR
,
1816 if (port_mode
== UNM_PORT_MODE_802_3_AP
) {
1817 unm_nic_write_w0(adapter
,
1818 UNM_NIU_AP_MAX_FRAME_SIZE(port
), new_mtu
);
1820 if (adapter
->physical_port
== 0) {
1821 unm_nic_write_w0(adapter
,
1822 UNM_NIU_XGE_MAX_FRAME_SIZE
,
1825 unm_nic_write_w0(adapter
,
1826 UNM_NIU_XG1_MAX_FRAME_SIZE
,
1833 cmn_err(CE_WARN
, "%s: Unknown brdtype\n",
1834 unm_nic_driver_name
);
1841 unm_nic_set_promisc_mode(struct unm_adapter_s
*adapter
)
1845 if (adapter
->promisc
)
1848 switch (adapter
->ahw
.board_type
) {
1850 ret
= unm_niu_set_promiscuous_mode(adapter
,
1851 UNM_NIU_PROMISCOUS_MODE
);
1855 ret
= unm_niu_xg_set_promiscuous_mode(adapter
,
1856 UNM_NIU_PROMISCOUS_MODE
);
1860 cmn_err(CE_WARN
, "%s: Unknown brdtype\n",
1861 unm_nic_driver_name
);
1867 adapter
->promisc
= 1;
1873 unm_nic_unset_promisc_mode(struct unm_adapter_s
*adapter
)
1878 * P3 does not unset promiscous mode. Why?
1880 if (adapter
->ahw
.revision_id
>= NX_P3_A2
) {
1884 if (!adapter
->promisc
)
1887 switch (adapter
->ahw
.board_type
) {
1889 ret
= unm_niu_set_promiscuous_mode(adapter
,
1890 UNM_NIU_NON_PROMISCOUS_MODE
);
1894 ret
= unm_niu_xg_set_promiscuous_mode(adapter
,
1895 UNM_NIU_NON_PROMISCOUS_MODE
);
1899 cmn_err(CE_WARN
, "%s: Unknown brdtype\n",
1900 unm_nic_driver_name
);
1906 adapter
->promisc
= 0;
1912 unm_nic_phy_read(unm_adapter
*adapter
, long reg
, __uint32_t
*readval
)
1916 switch (adapter
->ahw
.board_type
) {
1918 ret
= unm_niu_gbe_phy_read(adapter
, reg
, readval
);
1922 DPRINTF(1, (CE_WARN
,
1923 "%s: Function %s is not implemented for XG\n",
1924 unm_nic_driver_name
, __FUNCTION__
));
1928 DPRINTF(1, (CE_WARN
, "%s: Unknown board type\n",
1929 unm_nic_driver_name
));
1936 unm_nic_init_port(struct unm_adapter_s
*adapter
)
1938 long portnum
= adapter
->physical_port
;
1943 unm_nic_set_link_parameters(adapter
);
1945 switch (adapter
->ahw
.board_type
) {
1947 ret
= unm_niu_enable_gbe_port(adapter
);
1951 adapter
->unm_nic_hw_read_wx(adapter
, UNM_PORT_MODE_ADDR
,
1953 if (port_mode
== UNM_PORT_MODE_802_3_AP
) {
1954 ret
= unm_niu_enable_gbe_port(adapter
);
1956 adapter
->unm_crb_writelit_adapter(adapter
,
1957 UNM_NIU_XGE_CONFIG_0
+ (0x10000 * portnum
), 0x5);
1958 UNM_CRB_READ_CHECK_ADAPTER(UNM_NIU_XGE_CONFIG_1
+
1959 (0x10000 * portnum
), ®
, adapter
);
1960 if (adapter
->ahw
.revision_id
< NX_P3_A2
)
1961 reg
= (reg
& ~0x2000UL
);
1962 adapter
->unm_crb_writelit_adapter(adapter
,
1963 UNM_NIU_XGE_CONFIG_1
+ (0x10000 * portnum
), reg
);
1968 DPRINTF(1, (CE_WARN
, "%s: Unknown board type\n",
1969 unm_nic_driver_name
));
1976 unm_nic_stop_port(struct unm_adapter_s
*adapter
)
1979 (void) mac_unregister(adapter
->mach
);
1981 switch (adapter
->ahw
.board_type
) {
1983 (void) unm_niu_disable_gbe_port(adapter
);
1987 (void) unm_niu_disable_xg_port(adapter
);
1991 DPRINTF(1, (CE_WARN
, "%s: Unknown board type\n",
1992 unm_nic_driver_name
));
1997 unm_crb_write_adapter(unsigned long off
, void *data
,
1998 struct unm_adapter_s
*adapter
)
2000 (void) adapter
->unm_nic_hw_write_wx(adapter
, off
, data
, 4);
2004 unm_crb_read_adapter(unsigned long off
, void *data
,
2005 struct unm_adapter_s
*adapter
)
2007 return (adapter
->unm_nic_hw_read_wx(adapter
, off
, data
, 4));
2011 unm_crb_read_val_adapter(unsigned long off
, struct unm_adapter_s
*adapter
)
2015 adapter
->unm_nic_hw_read_wx(adapter
, off
, &data
, 4);
2020 unm_nic_set_link_parameters(struct unm_adapter_s
*adapter
)
2022 unm_niu_phy_status_t status
;
2023 uint16_t defval
= (uint16_t)-1;
2024 unm_niu_control_t mode
;
2027 unm_nic_read_w0(adapter
, UNM_NIU_MODE
, (uint32_t *)&mode
);
2028 if (mode
.enable_ge
) { // Gb 10/100/1000 Mbps mode
2029 adapter
->unm_nic_hw_read_wx(adapter
, UNM_PORT_MODE_ADDR
,
2031 if (port_mode
== UNM_PORT_MODE_802_3_AP
) {
2032 adapter
->link_speed
= MBPS_1000
;
2033 adapter
->link_duplex
= LINK_DUPLEX_FULL
;
2035 if (unm_nic_phy_read(adapter
,
2036 UNM_NIU_GB_MII_MGMT_ADDR_PHY_STATUS
,
2037 (unm_crbword_t
*)&status
) == 0) {
2039 switch (status
.speed
) {
2040 case 0: adapter
->link_speed
= MBPS_10
;
2042 case 1: adapter
->link_speed
= MBPS_100
;
2044 case 2: adapter
->link_speed
= MBPS_1000
;
2047 adapter
->link_speed
= defval
;
2050 switch (status
.duplex
) {
2051 case 0: adapter
->link_duplex
= LINK_DUPLEX_HALF
;
2053 case 1: adapter
->link_duplex
= LINK_DUPLEX_FULL
;
2056 adapter
->link_duplex
= defval
;
2060 adapter
->link_speed
= defval
;
2061 adapter
->link_duplex
= defval
;
2064 adapter
->link_speed
= defval
;
2065 adapter
->link_duplex
= defval
;
2072 unm_nic_flash_print(struct unm_adapter_s
*adapter
)
2075 unm_board_info_t
*board_info
= &(adapter
->ahw
.boardcfg
);
2077 if (board_info
->magic
!= UNM_BDINFO_MAGIC
) {
2078 cmn_err(CE_WARN
, "%s UNM Unknown board config, Read 0x%x "
2079 "expected as 0x%x\n", unm_nic_driver_name
,
2080 board_info
->magic
, UNM_BDINFO_MAGIC
);
2083 if (board_info
->header_version
!= UNM_BDINFO_VERSION
) {
2084 cmn_err(CE_WARN
, "%s UNM Unknown board config version."
2085 " Read %x, expected %x\n", unm_nic_driver_name
,
2086 board_info
->header_version
, UNM_BDINFO_VERSION
);
2090 unm_user_info_t user_info
;
2092 int addr
= USER_START
;
2095 ptr32
= (int *)&user_info
;
2096 for (i
= 0; i
< sizeof (unm_user_info_t
) / sizeof (uint32_t);
2098 if (rom_fast_read(adapter
, addr
, ptr32
) == -1) {
2100 "%s: ERROR reading %s board userarea.\n",
2101 unm_nic_driver_name
, unm_nic_driver_name
);
2105 addr
+= sizeof (uint32_t);
2109 GET_BRD_NAME_BY_TYPE(board_info
->board_type
, brd_name
);
2110 cmn_err(CE_NOTE
, "%s %s Board S/N %s Chip id 0x%x\n",
2111 unm_nic_driver_name
, brd_name
, user_info
.serial_num
,
2112 board_info
->chip_id
);
2118 nx_nic_send_cmd_descs(unm_adapter
*adapter
, cmdDescType0_t
*cmd_desc_arr
,
2121 struct unm_cmd_buffer
*pbuf
;
2122 unsigned int i
= 0, producer
;
2125 * We need to check if space is available.
2127 UNM_SPIN_LOCK(&adapter
->tx_lock
);
2128 producer
= adapter
->cmdProducer
;
2131 pbuf
= &adapter
->cmd_buf_arr
[producer
];
2132 pbuf
->head
= pbuf
->tail
= NULL
;
2134 (void) memcpy(&adapter
->ahw
.cmdDescHead
[producer
],
2135 &cmd_desc_arr
[i
], sizeof (cmdDescType0_t
));
2136 unm_desc_dma_sync(adapter
->ahw
.cmd_desc_dma_handle
, producer
,
2137 1, adapter
->MaxTxDescCount
, sizeof (cmdDescType0_t
),
2138 DDI_DMA_SYNC_FORDEV
);
2139 producer
= get_next_index(producer
, adapter
->MaxTxDescCount
);
2141 } while (i
!= nr_elements
);
2143 adapter
->cmdProducer
= adapter
->ahw
.cmdProducer
= producer
;
2144 adapter
->freecmds
-= i
;
2146 unm_nic_update_cmd_producer(adapter
, producer
);
2148 UNM_SPIN_UNLOCK(&adapter
->tx_lock
);
2153 u64 qhdr
, req_hdr
, words
[6];
2157 u8 op
, tag
, mac_addr
[6];
2161 nx_p3_sre_macaddr_change(unm_adapter
*adapter
, u8
*addr
, u8 op
)
2164 nx_mac_req_t mac_req
;
2167 (void) memset(&req
, 0, sizeof (nx_nic_req_t
));
2168 req
.qhdr
|= (NX_NIC_REQUEST
<< 23);
2169 req
.req_hdr
|= NX_MAC_EVENT
;
2170 req
.req_hdr
|= ((u64
)adapter
->portnum
<< 16);
2172 (void) memcpy(&mac_req
.mac_addr
, addr
, 6);
2173 req
.words
[0] = HOST_TO_LE_64(*(u64
*)(uintptr_t)&mac_req
);
2175 rv
= nx_nic_send_cmd_descs(adapter
, (cmdDescType0_t
*)&req
, 1);
2177 cmn_err(CE_WARN
, "%s%d: Could not send mac update\n",
2178 adapter
->name
, adapter
->instance
);
2182 nx_p3_nic_set_promisc(unm_adapter
*adapter
, u32 mode
)
2186 (void) memset(&req
, 0, sizeof (nx_nic_req_t
));
2188 req
.qhdr
|= (NX_HOST_REQUEST
<< 23);
2189 req
.req_hdr
|= NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE
;
2190 req
.req_hdr
|= ((u64
)adapter
->portnum
<< 16);
2191 req
.words
[0] = HOST_TO_LE_64(mode
);
2193 return (nx_nic_send_cmd_descs(adapter
, (cmdDescType0_t
*)&req
, 1));
2197 * Currently only invoked at interface initialization time
2200 nx_p3_nic_set_multi(unm_adapter
*adapter
)
2202 u8 bcast_addr
[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2204 if (nx_p3_nic_set_promisc(adapter
, VPORT_MISS_MODE_ACCEPT_ALL
))
2205 cmn_err(CE_WARN
, "Could not set promisc mode\n");
2207 nx_p3_sre_macaddr_change(adapter
, adapter
->mac_addr
, NETXEN_MAC_ADD
);
2208 nx_p3_sre_macaddr_change(adapter
, bcast_addr
, NETXEN_MAC_ADD
);