Print this page
5253 kmem_alloc/kmem_zalloc won't fail with KM_SLEEP
5254 getrbuf won't fail with KM_SLEEP
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/ntxn/unm_nic_init.c
+++ new/usr/src/uts/common/io/ntxn/unm_nic_init.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]
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 #include <sys/types.h>
28 28 #include <sys/conf.h>
29 29 #include <sys/debug.h>
30 30 #include <sys/stropts.h>
31 31 #include <sys/stream.h>
32 32 #include <sys/strlog.h>
33 33 #include <sys/kmem.h>
34 34 #include <sys/stat.h>
35 35 #include <sys/kstat.h>
36 36 #include <sys/vtrace.h>
37 37 #include <sys/dlpi.h>
38 38 #include <sys/strsun.h>
39 39 #include <sys/ethernet.h>
40 40 #include <sys/modctl.h>
41 41 #include <sys/errno.h>
42 42 #include <sys/dditypes.h>
43 43 #include <sys/ddi.h>
44 44 #include <sys/sunddi.h>
45 45 #include <sys/sysmacros.h>
46 46 #include <sys/pci.h>
47 47
48 48 #include "unm_nic.h"
49 49 #include "unm_nic_hw.h"
50 50 #include "nic_cmn.h"
51 51 #include "unm_nic_ioctl.h"
52 52 #include "nic_phan_reg.h"
53 53
54 54 struct crb_addr_pair {
55 55 long addr, data;
56 56 };
57 57
58 58 #define MAX_CRB_XFORM 60
59 59 #define ADDR_ERROR ((unsigned long)0xffffffff)
60 60
61 61 #define crb_addr_transform(name) \
62 62 crb_addr_xform[UNM_HW_PX_MAP_CRB_##name] = \
63 63 UNM_HW_CRB_HUB_AGT_ADR_##name << 20
64 64
65 65 static unsigned int crb_addr_xform[MAX_CRB_XFORM];
66 66
67 67 static void
68 68 crb_addr_transform_setup(void)
69 69 {
70 70 crb_addr_transform(XDMA);
71 71 crb_addr_transform(TIMR);
72 72 crb_addr_transform(SRE);
73 73 crb_addr_transform(SQN3);
74 74 crb_addr_transform(SQN2);
75 75 crb_addr_transform(SQN1);
76 76 crb_addr_transform(SQN0);
77 77 crb_addr_transform(SQS3);
78 78 crb_addr_transform(SQS2);
79 79 crb_addr_transform(SQS1);
80 80 crb_addr_transform(SQS0);
81 81 crb_addr_transform(RPMX7);
82 82 crb_addr_transform(RPMX6);
83 83 crb_addr_transform(RPMX5);
84 84 crb_addr_transform(RPMX4);
85 85 crb_addr_transform(RPMX3);
86 86 crb_addr_transform(RPMX2);
87 87 crb_addr_transform(RPMX1);
88 88 crb_addr_transform(RPMX0);
89 89 crb_addr_transform(ROMUSB);
90 90 crb_addr_transform(SN);
91 91 crb_addr_transform(QMN);
92 92 crb_addr_transform(QMS);
93 93 crb_addr_transform(PGNI);
94 94 crb_addr_transform(PGND);
95 95 crb_addr_transform(PGN3);
96 96 crb_addr_transform(PGN2);
97 97 crb_addr_transform(PGN1);
98 98 crb_addr_transform(PGN0);
99 99 crb_addr_transform(PGSI);
100 100 crb_addr_transform(PGSD);
101 101 crb_addr_transform(PGS3);
102 102 crb_addr_transform(PGS2);
103 103 crb_addr_transform(PGS1);
104 104 crb_addr_transform(PGS0);
105 105 crb_addr_transform(PS);
106 106 crb_addr_transform(PH);
107 107 crb_addr_transform(NIU);
108 108 crb_addr_transform(I2Q);
109 109 crb_addr_transform(EG);
110 110 crb_addr_transform(MN);
111 111 crb_addr_transform(MS);
112 112 crb_addr_transform(CAS2);
113 113 crb_addr_transform(CAS1);
114 114 crb_addr_transform(CAS0);
115 115 crb_addr_transform(CAM);
116 116 crb_addr_transform(C2C1);
117 117 crb_addr_transform(C2C0);
118 118 crb_addr_transform(SMB);
119 119 crb_addr_transform(OCM0);
120 120
121 121 /*
122 122 * Used only in P3 just define it for P2 also.
123 123 */
124 124 crb_addr_transform(I2C0);
125 125 }
126 126
127 127 /*
128 128 * decode_crb_addr(0 - utility to translate from internal Phantom CRB address
129 129 * to external PCI CRB address.
130 130 */
131 131 static unsigned long
132 132 decode_crb_addr(unsigned long addr)
133 133 {
134 134 int i;
135 135 unsigned long base_addr, offset, pci_base;
136 136
137 137 crb_addr_transform_setup();
138 138
139 139 pci_base = ADDR_ERROR;
140 140 base_addr = addr & 0xfff00000;
141 141 offset = addr & 0x000fffff;
142 142
143 143 for (i = 0; i < MAX_CRB_XFORM; i++) {
144 144 if (crb_addr_xform[i] == base_addr) {
145 145 pci_base = i << 20;
146 146 break;
147 147 }
148 148 }
149 149
150 150 if (pci_base == ADDR_ERROR) {
151 151 return (pci_base);
152 152 } else {
153 153 return (pci_base + offset);
154 154 }
155 155 }
156 156
157 157 static long rom_max_timeout = 100;
158 158 static long rom_lock_timeout = 10000;
159 159
160 160 static int
161 161 rom_lock(unm_adapter *adapter)
162 162 {
163 163 uint32_t done = 0;
164 164 long timeout = 0;
165 165
166 166 while (!done) {
167 167 /* acquire semaphore2 from PCI HW block */
168 168 unm_nic_read_w0(adapter, UNM_PCIE_REG(PCIE_SEM2_LOCK), &done);
169 169 if (done == 1)
170 170 break;
171 171 if (timeout >= rom_lock_timeout) {
172 172 cmn_err(CE_WARN, "%s%d rom_lock timed out %d %ld\n",
173 173 adapter->name, adapter->instance, done, timeout);
174 174 return (-1);
175 175 }
176 176 timeout++;
177 177 }
178 178 unm_nic_reg_write(adapter, UNM_ROM_LOCK_ID, ROM_LOCK_DRIVER);
179 179 return (0);
180 180 }
181 181
182 182 static void
183 183 rom_unlock(unm_adapter *adapter)
184 184 {
185 185 uint32_t val;
186 186
187 187 /* release semaphore2 */
188 188 unm_nic_read_w0(adapter, UNM_PCIE_REG(PCIE_SEM2_UNLOCK), &val);
189 189 }
190 190
191 191 static int
192 192 wait_rom_done(unm_adapter *adapter)
193 193 {
194 194 long timeout = 0;
195 195 long done = 0;
196 196
197 197 while (done == 0) {
198 198 unm_nic_reg_read(adapter, UNM_ROMUSB_GLB_STATUS, &done);
199 199 done &= 2;
200 200 timeout++;
201 201 if (timeout >= rom_max_timeout) {
202 202 cmn_err(CE_WARN,
203 203 "Timeout reached waiting for rom done");
204 204 return (-1);
205 205 }
206 206 }
207 207 return (0);
208 208 }
209 209
210 210 static int
211 211 do_rom_fast_read(unm_adapter *adapter, int addr, int *valp)
212 212 {
213 213 unm_nic_reg_write(adapter, UNM_ROMUSB_ROM_ADDRESS, addr);
214 214 unm_nic_reg_write(adapter, UNM_ROMUSB_ROM_ABYTE_CNT, 3);
215 215 drv_usecwait(100); /* prevent bursting on CRB */
216 216 unm_nic_reg_write(adapter, UNM_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
217 217 unm_nic_reg_write(adapter, UNM_ROMUSB_ROM_INSTR_OPCODE, 0xb);
218 218 if (wait_rom_done(adapter) != DDI_SUCCESS) {
219 219 cmn_err(CE_WARN, "Error waiting for rom done\n");
220 220 return (-1);
221 221 }
222 222
223 223 // reset abyte_cnt and dummy_byte_cnt
224 224 unm_nic_reg_write(adapter, UNM_ROMUSB_ROM_ABYTE_CNT, 0);
225 225 drv_usecwait(100); /* prevent bursting on CRB */
226 226 unm_nic_reg_write(adapter, UNM_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
227 227
228 228 unm_nic_reg_read(adapter, UNM_ROMUSB_ROM_RDATA, valp);
229 229 return (0);
230 230 }
231 231
232 232 int
233 233 rom_fast_read(struct unm_adapter_s *adapter, int addr, int *valp)
234 234 {
235 235 int ret;
236 236
237 237 if (rom_lock(adapter) != 0) {
238 238 cmn_err(CE_WARN, "%s(%d)rom_lock failed\n",
239 239 __FUNCTION__, __LINE__);
240 240 return (-1);
241 241 }
242 242
243 243 ret = do_rom_fast_read(adapter, addr, valp);
244 244 if (ret != 0) {
245 245 cmn_err(CE_WARN, "%s do_rom_fast_read returned: %d\n",
246 246 __FUNCTION__, __LINE__);
247 247 return (-1);
248 248 }
249 249 rom_unlock(adapter);
250 250 return (ret);
251 251 }
252 252
253 253 int
254 254 pinit_from_rom(struct unm_adapter_s *adapter, int verbose)
255 255 {
256 256 int addr, val, status, i, init_delay = 0, n;
257 257 struct crb_addr_pair *buf;
258 258 unsigned long off;
259 259 unsigned int offset;
260 260
261 261 status = unm_nic_get_board_info(adapter);
262 262 if (status)
263 263 cmn_err(CE_WARN, "%s: pinit_from_rom: Error getting brdinfo\n",
264 264 unm_nic_driver_name);
265 265
266 266 UNM_CRB_WRITELIT_ADAPTER(UNM_ROMUSB_GLB_SW_RESET, 0xffffffff, adapter);
267 267
268 268 if (verbose) {
269 269 int val;
270 270 if (rom_fast_read(adapter, 0x4008, &val) == 0)
271 271 cmn_err(CE_WARN, "P2 ROM board type: 0x%08x\n", val);
272 272 else
273 273 cmn_err(CE_WARN, "Could not read board type\n");
274 274 if (rom_fast_read(adapter, 0x400c, &val) == 0)
275 275 cmn_err(CE_WARN, "ROM board num: 0x%08x\n", val);
276 276 else
277 277 cmn_err(CE_WARN, "Could not read board number\n");
278 278 if (rom_fast_read(adapter, 0x4010, &val) == 0)
279 279 cmn_err(CE_WARN, "ROM chip num: 0x%08x\n", val);
280 280 else
281 281 cmn_err(CE_WARN, "Could not read chip number\n");
282 282 }
283 283
284 284 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
285 285 if (rom_fast_read(adapter, 0, &n) != 0 ||
286 286 (unsigned int)n != 0xcafecafe ||
287 287 rom_fast_read(adapter, 4, &n) != 0) {
288 288 cmn_err(CE_WARN, "%s: ERROR Reading crb_init area: "
289 289 "n: %08x\n", unm_nic_driver_name, n);
290 290 return (-1);
291 291 }
292 292
293 293 offset = n & 0xffffU;
294 294 n = (n >> 16) & 0xffffU;
295 295 } else {
296 296 if (rom_fast_read(adapter, 0, &n) != 0 ||
297 297 !(n & 0x80000000)) {
298 298 cmn_err(CE_WARN, "%s: ERROR Reading crb_init area: "
299 299 "n: %08x\n", unm_nic_driver_name, n);
300 300 return (-1);
301 301 }
302 302 offset = 1;
303 303 n &= ~0x80000000;
304 304 }
305 305
306 306 if (n >= 1024) {
↓ open down ↓ |
306 lines elided |
↑ open up ↑ |
307 307 cmn_err(CE_WARN, "%s: %s:n=0x%x Card flash not initialized\n",
308 308 unm_nic_driver_name, __FUNCTION__, n);
309 309 return (-1);
310 310 }
311 311
312 312 if (verbose)
313 313 cmn_err(CE_WARN, "%s: %d CRB init values found in ROM.\n",
314 314 unm_nic_driver_name, n);
315 315
316 316 buf = kmem_zalloc(n * sizeof (struct crb_addr_pair), KM_SLEEP);
317 - if (buf == NULL) {
318 - cmn_err(CE_WARN, "%s: pinit_from_rom: Unable to get memory\n",
319 - unm_nic_driver_name);
320 - return (-1);
321 - }
322 317
323 318 for (i = 0; i < n; i++) {
324 319 if (rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 ||
325 320 rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0) {
326 321 kmem_free(buf, n * sizeof (struct crb_addr_pair));
327 322 return (-1);
328 323 }
329 324
330 325 buf[i].addr = addr;
331 326 buf[i].data = val;
332 327
333 328 if (verbose)
334 329 cmn_err(CE_WARN, "%s: PCI: 0x%08x == 0x%08x\n",
335 330 unm_nic_driver_name,
336 331 (unsigned int)decode_crb_addr(
337 332 (unsigned long)addr), val);
338 333 }
339 334
340 335 for (i = 0; i < n; i++) {
341 336 off = decode_crb_addr((unsigned long)buf[i].addr) +
342 337 UNM_PCI_CRBSPACE;
343 338 /* skipping cold reboot MAGIC */
344 339 if (off == UNM_CAM_RAM(0x1fc)) {
345 340 continue;
346 341 }
347 342
348 343 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
349 344 /* do not reset PCI */
350 345 if (off == (ROMUSB_GLB + 0xbc)) {
351 346 continue;
352 347 }
353 348 if (off == (ROMUSB_GLB + 0xc8)) /* core clock */
354 349 continue;
355 350 if (off == (ROMUSB_GLB + 0x24)) /* MN clock */
356 351 continue;
357 352 if (off == (ROMUSB_GLB + 0x1c)) /* MS clock */
358 353 continue;
359 354 if (off == (UNM_CRB_PEG_NET_1 + 0x18)) {
360 355 buf[i].data = 0x1020;
361 356 }
362 357 /* skip the function enable register */
363 358 if (off == UNM_PCIE_REG(PCIE_SETUP_FUNCTION)) {
364 359 continue;
365 360 }
366 361 if (off == UNM_PCIE_REG(PCIE_SETUP_FUNCTION2)) {
367 362 continue;
368 363 }
369 364
370 365 if ((off & 0x0ff00000) == UNM_CRB_SMB) {
371 366 continue;
372 367 }
373 368
374 369 }
375 370
376 371 if (off == ADDR_ERROR) {
377 372 cmn_err(CE_WARN, "%s: Err: Unknown addr: 0x%08lx\n",
378 373 unm_nic_driver_name, buf[i].addr);
379 374 continue;
380 375 }
381 376
382 377 /* After writing this register, HW needs time for CRB */
383 378 /* to quiet down (else crb_window returns 0xffffffff) */
384 379 if (off == UNM_ROMUSB_GLB_SW_RESET) {
385 380 init_delay = 1;
386 381
387 382 if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
388 383 /* hold xdma in reset also */
389 384 buf[i].data = 0x8000ff;
390 385 }
391 386 }
392 387
393 388 adapter->unm_nic_hw_write_wx(adapter, off, &buf[i].data, 4);
394 389
395 390 if (init_delay == 1) {
396 391 nx_msleep(1000); /* Sleep 1000 msecs */
397 392 init_delay = 0;
398 393 }
399 394
400 395 nx_msleep(1); /* Sleep 1 msec */
401 396 }
402 397
403 398 kmem_free(buf, n * sizeof (struct crb_addr_pair));
404 399
405 400 // disable_peg_cache_all
406 401 // unreset_net_cache
407 402 if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
408 403 val = UNM_CRB_READ_VAL_ADAPTER(UNM_ROMUSB_GLB_SW_RESET,
409 404 adapter);
410 405 UNM_CRB_WRITELIT_ADAPTER(UNM_ROMUSB_GLB_SW_RESET,
411 406 (val & 0xffffff0f), adapter);
412 407 }
413 408
414 409 // p2dn replyCount
415 410 UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_D+0xec, 0x1e, adapter);
416 411 // disable_peg_cache 0
417 412 UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_D+0x4c, 8, adapter);
418 413 // disable_peg_cache 1
419 414 UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_I+0x4c, 8, adapter);
420 415
421 416 // peg_clr_all
422 417 // peg_clr 0
423 418 UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_0+0x8, 0, adapter);
424 419 UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_0+0xc, 0, adapter);
425 420 // peg_clr 1
426 421 UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_1+0x8, 0, adapter);
427 422 UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_1+0xc, 0, adapter);
428 423 // peg_clr 2
429 424 UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_2+0x8, 0, adapter);
430 425 UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_2+0xc, 0, adapter);
431 426 // peg_clr 3
432 427 UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_3+0x8, 0, adapter);
433 428 UNM_CRB_WRITELIT_ADAPTER(UNM_CRB_PEG_NET_3+0xc, 0, adapter);
434 429
435 430 return (0);
436 431 }
437 432
438 433 int
439 434 phantom_init(struct unm_adapter_s *adapter, int pegtune_val)
440 435 {
441 436 u32 val = 0;
442 437 int retries = 120;
443 438
444 439 if (!pegtune_val) {
445 440 do {
446 441 val = adapter->unm_nic_pci_read_normalize(adapter,
447 442 CRB_CMDPEG_STATE);
448 443
449 444 if ((val == PHAN_INITIALIZE_COMPLETE) ||
450 445 (val == PHAN_INITIALIZE_ACK))
451 446 return (DDI_SUCCESS);
452 447
453 448 /* 500 msec wait */
454 449 drv_usecwait(500000);
455 450 } while (--retries > 0);
456 451
457 452 if (!retries) {
458 453 val = adapter->unm_nic_pci_read_normalize(adapter,
459 454 UNM_ROMUSB_GLB_PEGTUNE_DONE);
460 455 cmn_err(CE_WARN, "WARNING: Initial boot wait loop"
461 456 "failed...state:%d\n", val);
462 457 return (DDI_FAILURE);
463 458 }
464 459 }
465 460
466 461 return (DDI_SUCCESS);
467 462 }
468 463
469 464 int
470 465 load_from_flash(struct unm_adapter_s *adapter)
471 466 {
472 467 int i;
473 468 long data, size = 0;
474 469 long flashaddr = BOOTLD_START, memaddr = BOOTLD_START;
475 470
476 471 size = (IMAGE_START - BOOTLD_START)/4;
477 472
478 473 if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
479 474 data = 1;
480 475 adapter->unm_nic_hw_write_wx(adapter, UNM_ROMUSB_GLB_CAS_RST,
481 476 &data, 4);
482 477 }
483 478
484 479 for (i = 0; i < size; i++) {
485 480 if (rom_fast_read(adapter, flashaddr, (int *)&data) != 0) {
486 481 cmn_err(CE_WARN, "Error in rom_fast_read: "
487 482 "Will skip loading flash image\n");
488 483 return (DDI_FAILURE);
489 484 }
490 485
491 486 adapter->unm_nic_pci_mem_write(adapter, memaddr, &data, 4);
492 487 flashaddr += 4;
493 488 memaddr += 4;
494 489 }
495 490
496 491 drv_usecwait(100);
497 492 UNM_READ_LOCK(&adapter->adapter_lock);
498 493
499 494 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
500 495 data = 0x80001d;
501 496 adapter->unm_nic_hw_write_wx(adapter, UNM_ROMUSB_GLB_SW_RESET,
502 497 &data, 4);
503 498 } else {
504 499 data = 0x3fff;
505 500 adapter->unm_nic_hw_write_wx(adapter,
506 501 UNM_ROMUSB_GLB_CHIP_CLK_CTRL, &data, 4);
507 502 data = 0;
508 503 adapter->unm_nic_hw_write_wx(adapter, UNM_ROMUSB_GLB_CAS_RST,
509 504 &data, 4);
510 505 }
511 506
512 507 UNM_READ_UNLOCK(&adapter->adapter_lock);
513 508 return (DDI_SUCCESS);
514 509 }
↓ open down ↓ |
183 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX