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