finally move buildroot-ng to trunk
[openwrt/staging/dedeckeh.git] / target / linux / brcm-2.4 / patches / 001-bcm47xx.patch
1 diff -urN linux.old/arch/mips/bcm947xx/bcmsrom.c linux.dev/arch/mips/bcm947xx/bcmsrom.c
2 --- linux.old/arch/mips/bcm947xx/bcmsrom.c 1970-01-01 01:00:00.000000000 +0100
3 +++ linux.dev/arch/mips/bcm947xx/bcmsrom.c 2006-10-02 21:19:59.000000000 +0200
4 @@ -0,0 +1,1212 @@
5 +/*
6 + * Misc useful routines to access NIC SROM/OTP .
7 + *
8 + * Copyright 2006, Broadcom Corporation
9 + * All Rights Reserved.
10 + *
11 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
12 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
13 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
14 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
15 + * $Id: bcmsrom.c,v 1.1.1.14 2006/04/15 01:28:25 michael Exp $
16 + */
17 +
18 +#include <typedefs.h>
19 +#include <bcmdefs.h>
20 +#include <osl.h>
21 +#include <bcmutils.h>
22 +#include <bcmsrom.h>
23 +#include <bcmdevs.h>
24 +#include <bcmendian.h>
25 +#include <sbpcmcia.h>
26 +#include <pcicfg.h>
27 +#include <sbutils.h>
28 +#include <bcmnvram.h>
29 +
30 +/* debug/trace */
31 +#if defined(WLTEST)
32 +#define BS_ERROR(args) printf args
33 +#else
34 +#define BS_ERROR(args)
35 +#endif /* BCMDBG_ERR || WLTEST */
36 +
37 +#define VARS_MAX 4096 /* should be reduced */
38 +
39 +#define WRITE_ENABLE_DELAY 500 /* 500 ms after write enable/disable toggle */
40 +#define WRITE_WORD_DELAY 20 /* 20 ms between each word write */
41 +
42 +static int initvars_srom_pci(void *sbh, void *curmap, char **vars, uint *count);
43 +static int initvars_cis_pcmcia(void *sbh, osl_t *osh, char **vars, uint *count);
44 +static int initvars_flash_sb(void *sbh, char **vars, uint *count);
45 +static int srom_parsecis(osl_t *osh, uint8 **pcis, uint ciscnt, char **vars, uint *count);
46 +static int sprom_cmd_pcmcia(osl_t *osh, uint8 cmd);
47 +static int sprom_read_pcmcia(osl_t *osh, uint16 addr, uint16 *data);
48 +static int sprom_write_pcmcia(osl_t *osh, uint16 addr, uint16 data);
49 +static int sprom_read_pci(osl_t *osh, uint16 *sprom, uint wordoff, uint16 *buf, uint nwords,
50 + bool check_crc);
51 +
52 +static int initvars_table(osl_t *osh, char *start, char *end, char **vars, uint *count);
53 +static int initvars_flash(osl_t *osh, char **vp, uint len, char *devpath);
54 +
55 +/*
56 + * Initialize local vars from the right source for this platform.
57 + * Return 0 on success, nonzero on error.
58 + */
59 +int
60 +srom_var_init(void *sbh, uint bustype, void *curmap, osl_t *osh, char **vars, uint *count)
61 +{
62 + ASSERT(bustype == BUSTYPE(bustype));
63 + if (vars == NULL || count == NULL)
64 + return (0);
65 +
66 + switch (BUSTYPE(bustype)) {
67 + case SB_BUS:
68 + case JTAG_BUS:
69 + return initvars_flash_sb(sbh, vars, count);
70 +
71 + case PCI_BUS:
72 + ASSERT(curmap); /* can not be NULL */
73 + return initvars_srom_pci(sbh, curmap, vars, count);
74 +
75 + case PCMCIA_BUS:
76 + return initvars_cis_pcmcia(sbh, osh, vars, count);
77 +
78 +
79 + default:
80 + ASSERT(0);
81 + }
82 + return (-1);
83 +}
84 +
85 +/* support only 16-bit word read from srom */
86 +int
87 +srom_read(uint bustype, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf)
88 +{
89 + void *srom;
90 + uint i, off, nw;
91 +
92 + ASSERT(bustype == BUSTYPE(bustype));
93 +
94 + /* check input - 16-bit access only */
95 + if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2))
96 + return 1;
97 +
98 + off = byteoff / 2;
99 + nw = nbytes / 2;
100 +
101 + if (BUSTYPE(bustype) == PCI_BUS) {
102 + if (!curmap)
103 + return 1;
104 + srom = (uchar*)curmap + PCI_BAR0_SPROM_OFFSET;
105 + if (sprom_read_pci(osh, srom, off, buf, nw, FALSE))
106 + return 1;
107 + } else if (BUSTYPE(bustype) == PCMCIA_BUS) {
108 + for (i = 0; i < nw; i++) {
109 + if (sprom_read_pcmcia(osh, (uint16)(off + i), (uint16*)(buf + i)))
110 + return 1;
111 + }
112 + } else {
113 + return 1;
114 + }
115 +
116 + return 0;
117 +}
118 +
119 +/* support only 16-bit word write into srom */
120 +int
121 +srom_write(uint bustype, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf)
122 +{
123 + uint16 *srom;
124 + uint i, nw, crc_range;
125 + uint16 image[SPROM_SIZE];
126 + uint8 crc;
127 + volatile uint32 val32;
128 +
129 + ASSERT(bustype == BUSTYPE(bustype));
130 +
131 + /* check input - 16-bit access only */
132 + if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2))
133 + return 1;
134 +
135 + /* Are we writing the whole thing at once? */
136 + if ((byteoff == 0) &&
137 + ((nbytes == SPROM_SIZE) ||
138 + (nbytes == (SPROM_CRC_RANGE * 2)) ||
139 + (nbytes == (SROM4_WORDS * 2)))) {
140 + crc_range = nbytes;
141 + bcopy((void*)buf, (void*)image, nbytes);
142 + nw = nbytes / 2;
143 + } else {
144 + if ((BUSTYPE(bustype) == PCMCIA_BUS) || (BUSTYPE(bustype) == SDIO_BUS))
145 + crc_range = SPROM_SIZE;
146 + else
147 + crc_range = SPROM_CRC_RANGE * 2; /* Tentative */
148 +
149 + nw = crc_range / 2;
150 + /* read first 64 words from srom */
151 + if (srom_read(bustype, curmap, osh, 0, nw * 2, image))
152 + return 1;
153 + if (image[SROM4_SIGN] == SROM4_SIGNATURE) {
154 + crc_range = SROM4_WORDS;
155 + nw = crc_range / 2;
156 + if (srom_read(bustype, curmap, osh, 0, nw * 2, image))
157 + return 1;
158 + }
159 + /* make changes */
160 + bcopy((void*)buf, (void*)&image[byteoff / 2], nbytes);
161 + }
162 +
163 + /* calculate crc */
164 + htol16_buf(image, crc_range);
165 + crc = ~hndcrc8((uint8 *)image, crc_range - 1, CRC8_INIT_VALUE);
166 + ltoh16_buf(image, crc_range);
167 + image[(crc_range / 2) - 1] = (crc << 8) | (image[(crc_range / 2) - 1] & 0xff);
168 +
169 + if (BUSTYPE(bustype) == PCI_BUS) {
170 + srom = (uint16*)((uchar*)curmap + PCI_BAR0_SPROM_OFFSET);
171 + /* enable writes to the SPROM */
172 + val32 = OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32));
173 + val32 |= SPROM_WRITEEN;
174 + OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32);
175 + bcm_mdelay(WRITE_ENABLE_DELAY);
176 + /* write srom */
177 + for (i = 0; i < nw; i++) {
178 + W_REG(osh, &srom[i], image[i]);
179 + bcm_mdelay(WRITE_WORD_DELAY);
180 + }
181 + /* disable writes to the SPROM */
182 + OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32 &
183 + ~SPROM_WRITEEN);
184 + } else if (BUSTYPE(bustype) == PCMCIA_BUS) {
185 + /* enable writes to the SPROM */
186 + if (sprom_cmd_pcmcia(osh, SROM_WEN))
187 + return 1;
188 + bcm_mdelay(WRITE_ENABLE_DELAY);
189 + /* write srom */
190 + for (i = 0; i < nw; i++) {
191 + sprom_write_pcmcia(osh, (uint16)(i), image[i]);
192 + bcm_mdelay(WRITE_WORD_DELAY);
193 + }
194 + /* disable writes to the SPROM */
195 + if (sprom_cmd_pcmcia(osh, SROM_WDS))
196 + return 1;
197 + } else {
198 + return 1;
199 + }
200 +
201 + bcm_mdelay(WRITE_ENABLE_DELAY);
202 + return 0;
203 +}
204 +
205 +
206 +static int
207 +srom_parsecis(osl_t *osh, uint8 **pcis, uint ciscnt, char **vars, uint *count)
208 +{
209 + char eabuf[32];
210 + char *vp, *base;
211 + uint8 *cis, tup, tlen, sromrev = 1;
212 + int i, j;
213 + uint varsize;
214 + bool ag_init = FALSE;
215 + uint32 w32;
216 +
217 + ASSERT(vars);
218 + ASSERT(count);
219 +
220 + base = vp = MALLOC(osh, VARS_MAX);
221 + ASSERT(vp);
222 + if (!vp)
223 + return -2;
224 +
225 + while (ciscnt--) {
226 + cis = *pcis++;
227 + i = 0;
228 + do {
229 + tup = cis[i++];
230 + tlen = cis[i++];
231 + if ((i + tlen) >= CIS_SIZE)
232 + break;
233 +
234 + switch (tup) {
235 + case CISTPL_MANFID:
236 + vp += sprintf(vp, "manfid=%d", (cis[i + 1] << 8) + cis[i]);
237 + vp++;
238 + vp += sprintf(vp, "prodid=%d", (cis[i + 3] << 8) + cis[i + 2]);
239 + vp++;
240 + break;
241 +
242 + case CISTPL_FUNCE:
243 + switch (cis[i]) {
244 + case LAN_NID:
245 + ASSERT(cis[i + 1] == 6);
246 + bcm_ether_ntoa((struct ether_addr *)&cis[i + 2], eabuf);
247 + vp += sprintf(vp, "il0macaddr=%s", eabuf);
248 + vp++;
249 + break;
250 + case 1: /* SDIO Extended Data */
251 + vp += sprintf(vp, "sdmaxblk=%d",
252 + (cis[i + 13] << 8) | cis[i + 12]);
253 + vp++;
254 + break;
255 + }
256 + break;
257 +
258 + case CISTPL_CFTABLE:
259 + vp += sprintf(vp, "regwindowsz=%d", (cis[i + 7] << 8) | cis[i + 6]);
260 + vp++;
261 + break;
262 +
263 + case CISTPL_BRCM_HNBU:
264 + switch (cis[i]) {
265 + case HNBU_SROMREV:
266 + sromrev = cis[i + 1];
267 + break;
268 +
269 + case HNBU_CHIPID:
270 + vp += sprintf(vp, "vendid=%d", (cis[i + 2] << 8) +
271 + cis[i + 1]);
272 + vp++;
273 + vp += sprintf(vp, "devid=%d", (cis[i + 4] << 8) +
274 + cis[i + 3]);
275 + vp++;
276 + if (tlen == 7) {
277 + vp += sprintf(vp, "chiprev=%d",
278 + (cis[i + 6] << 8) + cis[i + 5]);
279 + vp++;
280 + }
281 + break;
282 +
283 + case HNBU_BOARDREV:
284 + vp += sprintf(vp, "boardrev=%d", cis[i + 1]);
285 + vp++;
286 + break;
287 +
288 + case HNBU_AA:
289 + vp += sprintf(vp, "aa2g=%d", cis[i + 1]);
290 + vp++;
291 + break;
292 +
293 + case HNBU_AG:
294 + vp += sprintf(vp, "ag0=%d", cis[i + 1]);
295 + vp++;
296 + ag_init = TRUE;
297 + break;
298 +
299 + case HNBU_CC:
300 + ASSERT(sromrev == 1);
301 + vp += sprintf(vp, "cc=%d", cis[i + 1]);
302 + vp++;
303 + break;
304 +
305 + case HNBU_PAPARMS:
306 + if (tlen == 2) {
307 + ASSERT(sromrev == 1);
308 + vp += sprintf(vp, "pa0maxpwr=%d", cis[i + 1]);
309 + vp++;
310 + } else if (tlen >= 9) {
311 + if (tlen == 10) {
312 + ASSERT(sromrev == 2);
313 + vp += sprintf(vp, "opo=%d", cis[i + 9]);
314 + vp++;
315 + } else
316 + ASSERT(tlen == 9);
317 +
318 + for (j = 0; j < 3; j++) {
319 + vp += sprintf(vp, "pa0b%d=%d", j,
320 + (cis[i + (j * 2) + 2] << 8) +
321 + cis[i + (j * 2) + 1]);
322 + vp++;
323 + }
324 + vp += sprintf(vp, "pa0itssit=%d", cis[i + 7]);
325 + vp++;
326 + vp += sprintf(vp, "pa0maxpwr=%d", cis[i + 8]);
327 + vp++;
328 + } else
329 + ASSERT(tlen >= 9);
330 + break;
331 +
332 + case HNBU_OEM:
333 + ASSERT(sromrev == 1);
334 + vp += sprintf(vp, "oem=%02x%02x%02x%02x%02x%02x%02x%02x",
335 + cis[i + 1], cis[i + 2],
336 + cis[i + 3], cis[i + 4],
337 + cis[i + 5], cis[i + 6],
338 + cis[i + 7], cis[i + 8]);
339 + vp++;
340 + break;
341 +
342 + case HNBU_BOARDFLAGS:
343 + w32 = (cis[i + 2] << 8) + cis[i + 1];
344 + if (tlen == 5)
345 + w32 |= (cis[i + 4] << 24) + (cis[i + 3] << 16);
346 + vp += sprintf(vp, "boardflags=0x%x", w32);
347 + vp++;
348 + break;
349 +
350 + case HNBU_LEDS:
351 + if (cis[i + 1] != 0xff) {
352 + vp += sprintf(vp, "ledbh0=%d", cis[i + 1]);
353 + vp++;
354 + }
355 + if (cis[i + 2] != 0xff) {
356 + vp += sprintf(vp, "ledbh1=%d", cis[i + 2]);
357 + vp++;
358 + }
359 + if (cis[i + 3] != 0xff) {
360 + vp += sprintf(vp, "ledbh2=%d", cis[i + 3]);
361 + vp++;
362 + }
363 + if (cis[i + 4] != 0xff) {
364 + vp += sprintf(vp, "ledbh3=%d", cis[i + 4]);
365 + vp++;
366 + }
367 + break;
368 +
369 + case HNBU_CCODE:
370 + {
371 + char str[3];
372 + ASSERT(sromrev > 1);
373 + str[0] = cis[i + 1];
374 + str[1] = cis[i + 2];
375 + str[2] = 0;
376 + vp += sprintf(vp, "ccode=%s", str);
377 + vp++;
378 + vp += sprintf(vp, "cctl=0x%x", cis[i + 3]);
379 + vp++;
380 + break;
381 + }
382 +
383 + case HNBU_CCKPO:
384 + ASSERT(sromrev > 2);
385 + vp += sprintf(vp, "cckpo=0x%x",
386 + (cis[i + 2] << 8) | cis[i + 1]);
387 + vp++;
388 + break;
389 +
390 + case HNBU_OFDMPO:
391 + ASSERT(sromrev > 2);
392 + vp += sprintf(vp, "ofdmpo=0x%x",
393 + (cis[i + 4] << 24) |
394 + (cis[i + 3] << 16) |
395 + (cis[i + 2] << 8) |
396 + cis[i + 1]);
397 + vp++;
398 + break;
399 + }
400 + break;
401 +
402 + }
403 + i += tlen;
404 + } while (tup != 0xff);
405 + }
406 +
407 + /* Set the srom version */
408 + vp += sprintf(vp, "sromrev=%d", sromrev);
409 + vp++;
410 +
411 + /* if there is no antenna gain field, set default */
412 + if (ag_init == FALSE) {
413 + ASSERT(sromrev == 1);
414 + vp += sprintf(vp, "ag0=%d", 0xff);
415 + vp++;
416 + }
417 +
418 + /* final nullbyte terminator */
419 + *vp++ = '\0';
420 + varsize = (uint)(vp - base);
421 +
422 + ASSERT((vp - base) < VARS_MAX);
423 +
424 + if (varsize == VARS_MAX) {
425 + *vars = base;
426 + } else {
427 + vp = MALLOC(osh, varsize);
428 + ASSERT(vp);
429 + if (vp)
430 + bcopy(base, vp, varsize);
431 + MFREE(osh, base, VARS_MAX);
432 + *vars = vp;
433 + if (!vp) {
434 + *count = 0;
435 + return -2;
436 + }
437 + }
438 + *count = varsize;
439 +
440 + return (0);
441 +}
442 +
443 +
444 +/* set PCMCIA sprom command register */
445 +static int
446 +sprom_cmd_pcmcia(osl_t *osh, uint8 cmd)
447 +{
448 + uint8 status = 0;
449 + uint wait_cnt = 1000;
450 +
451 + /* write sprom command register */
452 + OSL_PCMCIA_WRITE_ATTR(osh, SROM_CS, &cmd, 1);
453 +
454 + /* wait status */
455 + while (wait_cnt--) {
456 + OSL_PCMCIA_READ_ATTR(osh, SROM_CS, &status, 1);
457 + if (status & SROM_DONE)
458 + return 0;
459 + }
460 +
461 + return 1;
462 +}
463 +
464 +/* read a word from the PCMCIA srom */
465 +static int
466 +sprom_read_pcmcia(osl_t *osh, uint16 addr, uint16 *data)
467 +{
468 + uint8 addr_l, addr_h, data_l, data_h;
469 +
470 + addr_l = (uint8)((addr * 2) & 0xff);
471 + addr_h = (uint8)(((addr * 2) >> 8) & 0xff);
472 +
473 + /* set address */
474 + OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRH, &addr_h, 1);
475 + OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRL, &addr_l, 1);
476 +
477 + /* do read */
478 + if (sprom_cmd_pcmcia(osh, SROM_READ))
479 + return 1;
480 +
481 + /* read data */
482 + data_h = data_l = 0;
483 + OSL_PCMCIA_READ_ATTR(osh, SROM_DATAH, &data_h, 1);
484 + OSL_PCMCIA_READ_ATTR(osh, SROM_DATAL, &data_l, 1);
485 +
486 + *data = (data_h << 8) | data_l;
487 + return 0;
488 +}
489 +
490 +/* write a word to the PCMCIA srom */
491 +static int
492 +sprom_write_pcmcia(osl_t *osh, uint16 addr, uint16 data)
493 +{
494 + uint8 addr_l, addr_h, data_l, data_h;
495 +
496 + addr_l = (uint8)((addr * 2) & 0xff);
497 + addr_h = (uint8)(((addr * 2) >> 8) & 0xff);
498 + data_l = (uint8)(data & 0xff);
499 + data_h = (uint8)((data >> 8) & 0xff);
500 +
501 + /* set address */
502 + OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRH, &addr_h, 1);
503 + OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRL, &addr_l, 1);
504 +
505 + /* write data */
506 + OSL_PCMCIA_WRITE_ATTR(osh, SROM_DATAH, &data_h, 1);
507 + OSL_PCMCIA_WRITE_ATTR(osh, SROM_DATAL, &data_l, 1);
508 +
509 + /* do write */
510 + return sprom_cmd_pcmcia(osh, SROM_WRITE);
511 +}
512 +
513 +/*
514 + * Read in and validate sprom.
515 + * Return 0 on success, nonzero on error.
516 + */
517 +static int
518 +sprom_read_pci(osl_t *osh, uint16 *sprom, uint wordoff, uint16 *buf, uint nwords, bool check_crc)
519 +{
520 + int err = 0;
521 + uint i;
522 +
523 + /* read the sprom */
524 + for (i = 0; i < nwords; i++)
525 + buf[i] = R_REG(osh, &sprom[wordoff + i]);
526 +
527 + if (check_crc) {
528 + /* fixup the endianness so crc8 will pass */
529 + htol16_buf(buf, nwords * 2);
530 + if (hndcrc8((uint8*)buf, nwords * 2, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE)
531 + err = 1;
532 + /* now correct the endianness of the byte array */
533 + ltoh16_buf(buf, nwords * 2);
534 + }
535 +
536 + return err;
537 +}
538 +
539 +/*
540 +* Create variable table from memory.
541 +* Return 0 on success, nonzero on error.
542 +*/
543 +static int
544 +initvars_table(osl_t *osh, char *start, char *end, char **vars, uint *count)
545 +{
546 + int c = (int)(end - start);
547 +
548 + /* do it only when there is more than just the null string */
549 + if (c > 1) {
550 + char *vp = MALLOC(osh, c);
551 + ASSERT(vp);
552 + if (!vp)
553 + return BCME_NOMEM;
554 + bcopy(start, vp, c);
555 + *vars = vp;
556 + *count = c;
557 + }
558 + else {
559 + *vars = NULL;
560 + *count = 0;
561 + }
562 +
563 + return 0;
564 +}
565 +
566 +/*
567 + * Find variables with <devpath> from flash. 'base' points to the beginning
568 + * of the table upon enter and to the end of the table upon exit when success.
569 + * Return 0 on success, nonzero on error.
570 + */
571 +static int
572 +initvars_flash(osl_t *osh, char **base, uint len, char *devpath)
573 +{
574 + char *vp = *base;
575 + char *flash;
576 + int err;
577 + char *s;
578 + uint l, dl, copy_len;
579 +
580 + /* allocate memory and read in flash */
581 + if (!(flash = MALLOC(osh, NVRAM_SPACE)))
582 + return BCME_NOMEM;
583 + if ((err = nvram_getall(flash, NVRAM_SPACE)))
584 + goto exit;
585 +
586 + /* grab vars with the <devpath> prefix in name */
587 + dl = strlen(devpath);
588 + for (s = flash; s && *s; s += l + 1) {
589 + l = strlen(s);
590 +
591 + /* skip non-matching variable */
592 + if (strncmp(s, devpath, dl))
593 + continue;
594 +
595 + /* is there enough room to copy? */
596 + copy_len = l - dl + 1;
597 + if (len < copy_len) {
598 + err = BCME_BUFTOOSHORT;
599 + goto exit;
600 + }
601 +
602 + /* no prefix, just the name=value */
603 + strcpy(vp, &s[dl]);
604 + vp += copy_len;
605 + len -= copy_len;
606 + }
607 +
608 + /* add null string as terminator */
609 + if (len < 1) {
610 + err = BCME_BUFTOOSHORT;
611 + goto exit;
612 + }
613 + *vp++ = '\0';
614 +
615 + *base = vp;
616 +
617 +exit: MFREE(osh, flash, NVRAM_SPACE);
618 + return err;
619 +}
620 +
621 +/*
622 + * Initialize nonvolatile variable table from flash.
623 + * Return 0 on success, nonzero on error.
624 + */
625 +static int
626 +initvars_flash_sb(void *sbh, char **vars, uint *count)
627 +{
628 + osl_t *osh = sb_osh(sbh);
629 + char devpath[SB_DEVPATH_BUFSZ];
630 + char *vp, *base;
631 + int err;
632 +
633 + ASSERT(vars);
634 + ASSERT(count);
635 +
636 + if ((err = sb_devpath(sbh, devpath, sizeof(devpath))))
637 + return err;
638 +
639 + base = vp = MALLOC(osh, VARS_MAX);
640 + ASSERT(vp);
641 + if (!vp)
642 + return BCME_NOMEM;
643 +
644 + if ((err = initvars_flash(osh, &vp, VARS_MAX, devpath)))
645 + goto err;
646 +
647 + err = initvars_table(osh, base, vp, vars, count);
648 +
649 +err: MFREE(osh, base, VARS_MAX);
650 + return err;
651 +}
652 +
653 +#ifdef WLTEST
654 +char mfgsromvars[256];
655 +char *defaultsromvars = "il0macaddr=00:11:22:33:44:51\0"
656 + "et0macaddr=00:11:22:33:44:52\0"
657 + "et1macaddr=00:11:22:33:44:53\0"
658 + "boardtype=0xffff\0"
659 + "boardrev=0x10\0"
660 + "boardflags=8\0"
661 + "sromrev=2\0"
662 + "aa2g=3";
663 +#define MFGSROM_DEFVARSLEN 147 /* default srom len */
664 +#endif /* WL_TEST */
665 +
666 +/*
667 + * Initialize nonvolatile variable table from sprom.
668 + * Return 0 on success, nonzero on error.
669 + */
670 +static int
671 +initvars_srom_pci(void *sbh, void *curmap, char **vars, uint *count)
672 +{
673 + uint16 w, *b;
674 + uint8 sromrev = 0;
675 + struct ether_addr ea;
676 + char eabuf[32];
677 + uint32 w32;
678 + int woff, i;
679 + char *vp, *base;
680 + osl_t *osh = sb_osh(sbh);
681 + bool flash = FALSE;
682 + char name[SB_DEVPATH_BUFSZ+16], *value;
683 + char devpath[SB_DEVPATH_BUFSZ];
684 + int err;
685 +
686 + /*
687 + * Apply CRC over SROM content regardless SROM is present or not,
688 + * and use variable <devpath>sromrev's existance in flash to decide
689 + * if we should return an error when CRC fails or read SROM variables
690 + * from flash.
691 + */
692 + b = MALLOC(osh, SROM_MAX);
693 + ASSERT(b);
694 + if (!b)
695 + return -2;
696 +
697 + err = sprom_read_pci(osh, (void*)((int8*)curmap + PCI_BAR0_SPROM_OFFSET), 0, b,
698 + 64, TRUE);
699 + if (err == 0) {
700 + /* srom is good and is rev < 4 */
701 + /* top word of sprom contains version and crc8 */
702 + sromrev = b[63] & 0xff;
703 + /* bcm4401 sroms misprogrammed */
704 + if (sromrev == 0x10)
705 + sromrev = 1;
706 + } else if (b[SROM4_SIGN] == SROM4_SIGNATURE) {
707 + /* If sromrev >= 4, read more */
708 + err = sprom_read_pci(osh, (void*)((int8*)curmap + PCI_BAR0_SPROM_OFFSET), 0, b,
709 + SROM4_WORDS, TRUE);
710 + sromrev = b[SROM4_WORDS - 1] & 0xff;
711 + }
712 +
713 + if (err) {
714 +#ifdef WLTEST
715 + BS_ERROR(("SROM Crc Error, so see if we could use a default\n"));
716 + w32 = OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32));
717 + if (w32 & SPROM_OTPIN_USE) {
718 + BS_ERROR(("srom crc failed with OTP, use default vars....\n"));
719 + vp = base = mfgsromvars;
720 + if (sb_chip(sbh) == BCM4311_CHIP_ID) {
721 + BS_ERROR(("setting the devid to be 4311\n"));
722 + vp += sprintf(vp, "devid=0x4311");
723 + vp++;
724 + }
725 + bcopy(defaultsromvars, vp, MFGSROM_DEFVARSLEN);
726 + vp += MFGSROM_DEFVARSLEN;
727 + goto varsdone;
728 + } else {
729 + BS_ERROR(("srom crc failed with SPROM....\n"));
730 +#endif /* WLTEST */
731 + if ((err = sb_devpath(sbh, devpath, sizeof(devpath))))
732 + return err;
733 + sprintf(name, "%ssromrev", devpath);
734 + if (!(value = getvar(NULL, name)))
735 + return (-1);
736 + sromrev = (uint8)bcm_strtoul(value, NULL, 0);
737 + flash = TRUE;
738 +#ifdef WLTEST
739 + }
740 +#endif /* WLTEST */
741 + }
742 +
743 + /* srom version check */
744 + if (sromrev > 4)
745 + return (-2);
746 +
747 + ASSERT(vars);
748 + ASSERT(count);
749 +
750 + base = vp = MALLOC(osh, VARS_MAX);
751 + ASSERT(vp);
752 + if (!vp)
753 + return -2;
754 +
755 + /* read variables from flash */
756 + if (flash) {
757 + if ((err = initvars_flash(osh, &vp, VARS_MAX, devpath)))
758 + goto err;
759 + goto varsdone;
760 + }
761 +
762 + vp += sprintf(vp, "sromrev=%d", sromrev);
763 + vp++;
764 +
765 + if (sromrev >= 4) {
766 + uint path, pathbase;
767 + const uint pathbases[MAX_PATH] = {SROM4_PATH0, SROM4_PATH1,
768 + SROM4_PATH2, SROM4_PATH3};
769 +
770 + vp += sprintf(vp, "boardrev=%d", b[SROM4_BREV]);
771 + vp++;
772 +
773 + vp += sprintf(vp, "boardflags=%d", (b[SROM4_BFL1] << 16) | b[SROM4_BFL0]);
774 + vp++;
775 +
776 + vp += sprintf(vp, "boardflags2=%d", (b[SROM4_BFL3] << 16) | b[SROM4_BFL2]);
777 + vp++;
778 +
779 + /* The macaddr */
780 + ea.octet[0] = (b[SROM4_MACHI] >> 8) & 0xff;
781 + ea.octet[1] = b[SROM4_MACHI] & 0xff;
782 + ea.octet[2] = (b[SROM4_MACMID] >> 8) & 0xff;
783 + ea.octet[3] = b[SROM4_MACMID] & 0xff;
784 + ea.octet[4] = (b[SROM4_MACLO] >> 8) & 0xff;
785 + ea.octet[5] = b[SROM4_MACLO] & 0xff;
786 + bcm_ether_ntoa(&ea, eabuf);
787 + vp += sprintf(vp, "macaddr=%s", eabuf);
788 + vp++;
789 +
790 + w = b[SROM4_CCODE];
791 + if (w == 0)
792 + vp += sprintf(vp, "ccode=");
793 + else
794 + vp += sprintf(vp, "ccode=%c%c", (w >> 8), (w & 0xff));
795 + vp++;
796 + vp += sprintf(vp, "regrev=%d", b[SROM4_REGREV]);
797 + vp++;
798 +
799 + w = b[SROM4_LEDBH10];
800 + if ((w != 0) && (w != 0xffff)) {
801 + /* ledbh0 */
802 + vp += sprintf(vp, "ledbh0=%d", (w & 0xff));
803 + vp++;
804 +
805 + /* ledbh1 */
806 + vp += sprintf(vp, "ledbh1=%d", (w >> 8) & 0xff);
807 + vp++;
808 + }
809 + w = b[SROM4_LEDBH32];
810 + if ((w != 0) && (w != 0xffff)) {
811 + /* ledbh2 */
812 + vp += sprintf(vp, "ledbh2=%d", w & 0xff);
813 + vp++;
814 +
815 + /* ledbh3 */
816 + vp += sprintf(vp, "ledbh3=%d", (w >> 8) & 0xff);
817 + vp++;
818 + }
819 + /* LED Powersave duty cycle (oncount >> 24) (offcount >> 8) */
820 + w = b[SROM4_LEDDC];
821 + w32 = ((uint32)((unsigned char)(w >> 8) & 0xff) << 24) | /* oncount */
822 + ((uint32)((unsigned char)(w & 0xff)) << 8); /* offcount */
823 + vp += sprintf(vp, "leddc=%d", w32);
824 + vp++;
825 +
826 + w = b[SROM4_AA];
827 + vp += sprintf(vp, "aa2g=%d", w & SROM4_AA2G_MASK);
828 + vp++;
829 + vp += sprintf(vp, "aa5g=%d", w >> SROM4_AA5G_SHIFT);
830 + vp++;
831 +
832 + w = b[SROM4_AG10];
833 + vp += sprintf(vp, "ag0=%d", w & 0xff);
834 + vp++;
835 + vp += sprintf(vp, "ag1=%d", (w >> 8) & 0xff);
836 + vp++;
837 + w = b[SROM4_AG32];
838 + vp += sprintf(vp, "ag2=%d", w & 0xff);
839 + vp++;
840 + vp += sprintf(vp, "ag3=%d", (w >> 8) & 0xff);
841 + vp++;
842 +
843 + /* Fixed power indices when power control is disabled */
844 + for (i = 0; i < 2; i++) {
845 + w = b[SROM4_TXPID2G + i];
846 + vp += sprintf(vp, "txpid2ga%d=%d", 2 * i, w & 0xff);
847 + vp++;
848 + vp += sprintf(vp, "txpid2ga%d=%d", (2 * i) + 1, (w >> 8) & 0xff);
849 + vp++;
850 + w = b[SROM4_TXPID5G + i];
851 + vp += sprintf(vp, "txpid5ga%d=%d", 2 * i, w & 0xff);
852 + vp++;
853 + vp += sprintf(vp, "txpid5ga%d=%d", (2 * i) + 1, (w >> 8) & 0xff);
854 + vp++;
855 + w = b[SROM4_TXPID5GL + i];
856 + vp += sprintf(vp, "txpid5gla%d=%d", 2 * i, w & 0xff);
857 + vp++;
858 + vp += sprintf(vp, "txpid5gla%d=%d", (2 * i) + 1, (w >> 8) & 0xff);
859 + vp++;
860 + w = b[SROM4_TXPID5GH + i];
861 + vp += sprintf(vp, "txpid5gha%d=%d", 2 * i, w & 0xff);
862 + vp++;
863 + vp += sprintf(vp, "txpid5gha%d=%d", (2 * i) + 1, (w >> 8) & 0xff);
864 + vp++;
865 + }
866 +
867 + /* Per path variables */
868 + for (path = 0; path < MAX_PATH; path++) {
869 + pathbase = pathbases[path];
870 + w = b[pathbase + SROM4_2G_ITT_MAXP];
871 + vp += sprintf(vp, "itt2ga%d=%d", path, w >> B2G_ITT_SHIFT);
872 + vp++;
873 + vp += sprintf(vp, "maxp2ga%d=%d", path, w & B2G_MAXP_MASK);
874 + vp++;
875 +
876 + for (i = 0; i < 4; i++) {
877 + vp += sprintf(vp, "pa2gw%da%d=%d", i, path,
878 + b[pathbase + SROM4_2G_PA + i]);
879 + vp++;
880 + }
881 +
882 + w = b[pathbase + SROM4_5G_ITT_MAXP];
883 + vp += sprintf(vp, "itt5ga%d=%d", path, w >> B5G_ITT_SHIFT);
884 + vp++;
885 + vp += sprintf(vp, "maxp5ga%d=%d", path, w & B5G_MAXP_MASK);
886 + vp++;
887 +
888 + w = b[pathbase + SROM4_5GLH_MAXP];
889 + vp += sprintf(vp, "maxp5lga%d=%d", path, w >> B5GL_MAXP_SHIFT);
890 + vp++;
891 + vp += sprintf(vp, "maxp5gha%d=%d", path, w & B5GH_MAXP_MASK);
892 + vp++;
893 +
894 + for (i = 0; i < 4; i++) {
895 + vp += sprintf(vp, "pa5gw%da%d=%d", i, path,
896 + b[pathbase + SROM4_5G_PA + i]);
897 + vp++;
898 + vp += sprintf(vp, "pa5glw%da%d=%d", i, path,
899 + b[pathbase + SROM4_5GL_PA + i]);
900 + vp++;
901 + vp += sprintf(vp, "pa5hgw%da%d=%d", i, path,
902 + b[pathbase + SROM4_5GH_PA + i]);
903 + vp++;
904 + }
905 + }
906 +
907 + vp += sprintf(vp, "cck2gpo=%d", b[SROM4_2G_CCKPO]);
908 + vp++;
909 +
910 + w32 = ((uint32)b[SROM4_2G_OFDMPO + 1] << 16) | b[SROM4_2G_OFDMPO];
911 + vp += sprintf(vp, "ofdm2gpo=%d", w32);
912 + vp++;
913 +
914 + w32 = ((uint32)b[SROM4_5G_OFDMPO + 1] << 16) | b[SROM4_5G_OFDMPO];
915 + vp += sprintf(vp, "ofdm5gpo=%d", w32);
916 + vp++;
917 +
918 + w32 = ((uint32)b[SROM4_5GL_OFDMPO + 1] << 16) | b[SROM4_5GL_OFDMPO];
919 + vp += sprintf(vp, "ofdm5glpo=%d", w32);
920 + vp++;
921 +
922 + w32 = ((uint32)b[SROM4_5GH_OFDMPO + 1] << 16) | b[SROM4_5GH_OFDMPO];
923 + vp += sprintf(vp, "ofdm5ghpo=%d", w32);
924 + vp++;
925 +
926 + for (i = 0; i < 8; i++) {
927 + vp += sprintf(vp, "mcs2gpo%d=%d", i, b[SROM4_2G_MCSPO]);
928 + vp++;
929 + vp += sprintf(vp, "mcs5gpo%d=%d", i, b[SROM4_5G_MCSPO]);
930 + vp++;
931 + vp += sprintf(vp, "mcs5glpo%d=%d", i, b[SROM4_5GL_MCSPO]);
932 + vp++;
933 + vp += sprintf(vp, "mcs5ghpo%d=%d", i, b[SROM4_5GH_MCSPO]);
934 + vp++;
935 + }
936 +
937 + vp += sprintf(vp, "ccdpo%d=%d", i, b[SROM4_CCDPO]);
938 + vp++;
939 + vp += sprintf(vp, "stbcpo%d=%d", i, b[SROM4_STBCPO]);
940 + vp++;
941 + vp += sprintf(vp, "bw40po%d=%d", i, b[SROM4_BW40PO]);
942 + vp++;
943 + vp += sprintf(vp, "bwduppo%d=%d", i, b[SROM4_BWDUPPO]);
944 + vp++;
945 +
946 + goto done;
947 + }
948 + if (sromrev >= 3) {
949 + /* New section takes over the 3th hardware function space */
950 +
951 + /* Words 22+23 are 11a (mid) ofdm power offsets */
952 + w32 = ((uint32)b[23] << 16) | b[22];
953 + vp += sprintf(vp, "ofdmapo=%d", w32);
954 + vp++;
955 +
956 + /* Words 24+25 are 11a (low) ofdm power offsets */
957 + w32 = ((uint32)b[25] << 16) | b[24];
958 + vp += sprintf(vp, "ofdmalpo=%d", w32);
959 + vp++;
960 +
961 + /* Words 26+27 are 11a (high) ofdm power offsets */
962 + w32 = ((uint32)b[27] << 16) | b[26];
963 + vp += sprintf(vp, "ofdmahpo=%d", w32);
964 + vp++;
965 +
966 + /* LED Powersave duty cycle (oncount >> 24) (offcount >> 8) */
967 + w32 = ((uint32)((unsigned char)(b[21] >> 8) & 0xff) << 24) | /* oncount */
968 + ((uint32)((unsigned char)(b[21] & 0xff)) << 8); /* offcount */
969 + vp += sprintf(vp, "leddc=%d", w32);
970 +
971 + vp++;
972 + }
973 +
974 + if (sromrev >= 2) {
975 + /* New section takes over the 4th hardware function space */
976 +
977 + /* Word 29 is max power 11a high/low */
978 + w = b[29];
979 + vp += sprintf(vp, "pa1himaxpwr=%d", w & 0xff);
980 + vp++;
981 + vp += sprintf(vp, "pa1lomaxpwr=%d", (w >> 8) & 0xff);
982 + vp++;
983 +
984 + /* Words 30-32 set the 11alow pa settings,
985 + * 33-35 are the 11ahigh ones.
986 + */
987 + for (i = 0; i < 3; i++) {
988 + vp += sprintf(vp, "pa1lob%d=%d", i, b[30 + i]);
989 + vp++;
990 + vp += sprintf(vp, "pa1hib%d=%d", i, b[33 + i]);
991 + vp++;
992 + }
993 + w = b[59];
994 + if (w == 0)
995 + vp += sprintf(vp, "ccode=");
996 + else
997 + vp += sprintf(vp, "ccode=%c%c", (w >> 8), (w & 0xff));
998 + vp++;
999 +
1000 + }
1001 +
1002 + /* parameter section of sprom starts at byte offset 72 */
1003 + woff = 72/2;
1004 +
1005 + /* first 6 bytes are il0macaddr */
1006 + ea.octet[0] = (b[woff] >> 8) & 0xff;
1007 + ea.octet[1] = b[woff] & 0xff;
1008 + ea.octet[2] = (b[woff+1] >> 8) & 0xff;
1009 + ea.octet[3] = b[woff+1] & 0xff;
1010 + ea.octet[4] = (b[woff+2] >> 8) & 0xff;
1011 + ea.octet[5] = b[woff+2] & 0xff;
1012 + woff += 3;
1013 + bcm_ether_ntoa(&ea, eabuf);
1014 + vp += sprintf(vp, "il0macaddr=%s", eabuf);
1015 + vp++;
1016 +
1017 + /* next 6 bytes are et0macaddr */
1018 + ea.octet[0] = (b[woff] >> 8) & 0xff;
1019 + ea.octet[1] = b[woff] & 0xff;
1020 + ea.octet[2] = (b[woff+1] >> 8) & 0xff;
1021 + ea.octet[3] = b[woff+1] & 0xff;
1022 + ea.octet[4] = (b[woff+2] >> 8) & 0xff;
1023 + ea.octet[5] = b[woff+2] & 0xff;
1024 + woff += 3;
1025 + bcm_ether_ntoa(&ea, eabuf);
1026 + vp += sprintf(vp, "et0macaddr=%s", eabuf);
1027 + vp++;
1028 +
1029 + /* next 6 bytes are et1macaddr */
1030 + ea.octet[0] = (b[woff] >> 8) & 0xff;
1031 + ea.octet[1] = b[woff] & 0xff;
1032 + ea.octet[2] = (b[woff+1] >> 8) & 0xff;
1033 + ea.octet[3] = b[woff+1] & 0xff;
1034 + ea.octet[4] = (b[woff+2] >> 8) & 0xff;
1035 + ea.octet[5] = b[woff+2] & 0xff;
1036 + woff += 3;
1037 + bcm_ether_ntoa(&ea, eabuf);
1038 + vp += sprintf(vp, "et1macaddr=%s", eabuf);
1039 + vp++;
1040 +
1041 + /*
1042 + * Enet phy settings one or two singles or a dual
1043 + * Bits 4-0 : MII address for enet0 (0x1f for not there)
1044 + * Bits 9-5 : MII address for enet1 (0x1f for not there)
1045 + * Bit 14 : Mdio for enet0
1046 + * Bit 15 : Mdio for enet1
1047 + */
1048 + w = b[woff];
1049 + vp += sprintf(vp, "et0phyaddr=%d", (w & 0x1f));
1050 + vp++;
1051 + vp += sprintf(vp, "et1phyaddr=%d", ((w >> 5) & 0x1f));
1052 + vp++;
1053 + vp += sprintf(vp, "et0mdcport=%d", ((w >> 14) & 0x1));
1054 + vp++;
1055 + vp += sprintf(vp, "et1mdcport=%d", ((w >> 15) & 0x1));
1056 + vp++;
1057 +
1058 + /* Word 46 has board rev, antennas 0/1 & Country code/control */
1059 + w = b[46];
1060 + vp += sprintf(vp, "boardrev=%d", w & 0xff);
1061 + vp++;
1062 +
1063 + if (sromrev > 1)
1064 + vp += sprintf(vp, "cctl=%d", (w >> 8) & 0xf);
1065 + else
1066 + vp += sprintf(vp, "cc=%d", (w >> 8) & 0xf);
1067 + vp++;
1068 +
1069 + vp += sprintf(vp, "aa2g=%d", (w >> 12) & 0x3);
1070 + vp++;
1071 +
1072 + vp += sprintf(vp, "aa5g=%d", (w >> 14) & 0x3);
1073 + vp++;
1074 +
1075 + /* Words 47-49 set the (wl) pa settings */
1076 + woff = 47;
1077 +
1078 + for (i = 0; i < 3; i++) {
1079 + vp += sprintf(vp, "pa0b%d=%d", i, b[woff+i]);
1080 + vp++;
1081 + vp += sprintf(vp, "pa1b%d=%d", i, b[woff+i+6]);
1082 + vp++;
1083 + }
1084 +
1085 + /*
1086 + * Words 50-51 set the customer-configured wl led behavior.
1087 + * 8 bits/gpio pin. High bit: activehi=0, activelo=1;
1088 + * LED behavior values defined in wlioctl.h .
1089 + */
1090 + w = b[50];
1091 + if ((w != 0) && (w != 0xffff)) {
1092 + /* ledbh0 */
1093 + vp += sprintf(vp, "ledbh0=%d", (w & 0xff));
1094 + vp++;
1095 +
1096 + /* ledbh1 */
1097 + vp += sprintf(vp, "ledbh1=%d", (w >> 8) & 0xff);
1098 + vp++;
1099 + }
1100 + w = b[51];
1101 + if ((w != 0) && (w != 0xffff)) {
1102 + /* ledbh2 */
1103 + vp += sprintf(vp, "ledbh2=%d", w & 0xff);
1104 + vp++;
1105 +
1106 + /* ledbh */
1107 + vp += sprintf(vp, "ledbh3=%d", (w >> 8) & 0xff);
1108 + vp++;
1109 + }
1110 +
1111 + /* Word 52 is max power 0/1 */
1112 + w = b[52];
1113 + vp += sprintf(vp, "pa0maxpwr=%d", w & 0xff);
1114 + vp++;
1115 + vp += sprintf(vp, "pa1maxpwr=%d", (w >> 8) & 0xff);
1116 + vp++;
1117 +
1118 + /* Word 56 is idle tssi target 0/1 */
1119 + w = b[56];
1120 + vp += sprintf(vp, "pa0itssit=%d", w & 0xff);
1121 + vp++;
1122 + vp += sprintf(vp, "pa1itssit=%d", (w >> 8) & 0xff);
1123 + vp++;
1124 +
1125 + /* Word 57 is boardflags, if not programmed make it zero */
1126 + w32 = (uint32)b[57];
1127 + if (w32 == 0xffff) w32 = 0;
1128 + if (sromrev > 1) {
1129 + /* Word 28 is the high bits of boardflags */
1130 + w32 |= (uint32)b[28] << 16;
1131 + }
1132 + vp += sprintf(vp, "boardflags=%d", w32);
1133 + vp++;
1134 +
1135 + /* Word 58 is antenna gain 0/1 */
1136 + w = b[58];
1137 + vp += sprintf(vp, "ag0=%d", w & 0xff);
1138 + vp++;
1139 +
1140 + vp += sprintf(vp, "ag1=%d", (w >> 8) & 0xff);
1141 + vp++;
1142 +
1143 + if (sromrev == 1) {
1144 + /* set the oem string */
1145 + vp += sprintf(vp, "oem=%02x%02x%02x%02x%02x%02x%02x%02x",
1146 + ((b[59] >> 8) & 0xff), (b[59] & 0xff),
1147 + ((b[60] >> 8) & 0xff), (b[60] & 0xff),
1148 + ((b[61] >> 8) & 0xff), (b[61] & 0xff),
1149 + ((b[62] >> 8) & 0xff), (b[62] & 0xff));
1150 + vp++;
1151 + } else if (sromrev == 2) {
1152 + /* Word 60 OFDM tx power offset from CCK level */
1153 + /* OFDM Power Offset - opo */
1154 + vp += sprintf(vp, "opo=%d", b[60] & 0xff);
1155 + vp++;
1156 + } else {
1157 + /* Word 60: cck power offsets */
1158 + vp += sprintf(vp, "cckpo=%d", b[60]);
1159 + vp++;
1160 +
1161 + /* Words 61+62: 11g ofdm power offsets */
1162 + w32 = ((uint32)b[62] << 16) | b[61];
1163 + vp += sprintf(vp, "ofdmgpo=%d", w32);
1164 + vp++;
1165 + }
1166 +
1167 + /* final nullbyte terminator */
1168 +done: *vp++ = '\0';
1169 +
1170 + ASSERT((vp - base) <= VARS_MAX);
1171 +
1172 +varsdone:
1173 + err = initvars_table(osh, base, vp, vars, count);
1174 +
1175 +err:
1176 +#ifdef WLTEST
1177 + if (base != mfgsromvars)
1178 +#endif
1179 + MFREE(osh, base, VARS_MAX);
1180 + MFREE(osh, b, SROM_MAX);
1181 + return err;
1182 +}
1183 +
1184 +/*
1185 + * Read the cis and call parsecis to initialize the vars.
1186 + * Return 0 on success, nonzero on error.
1187 + */
1188 +static int
1189 +initvars_cis_pcmcia(void *sbh, osl_t *osh, char **vars, uint *count)
1190 +{
1191 + uint8 *cis = NULL;
1192 + int rc;
1193 + uint data_sz;
1194 +
1195 + data_sz = (sb_pcmciarev(sbh) == 1) ? (SPROM_SIZE * 2) : CIS_SIZE;
1196 +
1197 + if ((cis = MALLOC(osh, data_sz)) == NULL)
1198 + return (-2);
1199 +
1200 + if (sb_pcmciarev(sbh) == 1) {
1201 + if (srom_read(PCMCIA_BUS, (void *)NULL, osh, 0, data_sz, (uint16 *)cis)) {
1202 + MFREE(osh, cis, data_sz);
1203 + return (-1);
1204 + }
1205 + /* fix up endianess for 16-bit data vs 8-bit parsing */
1206 + ltoh16_buf((uint16 *)cis, data_sz);
1207 + } else
1208 + OSL_PCMCIA_READ_ATTR(osh, 0, cis, data_sz);
1209 +
1210 + rc = srom_parsecis(osh, &cis, 1, vars, count);
1211 +
1212 + MFREE(osh, cis, data_sz);
1213 +
1214 + return (rc);
1215 +}
1216 +
1217 diff -urN linux.old/arch/mips/bcm947xx/bcmutils.c linux.dev/arch/mips/bcm947xx/bcmutils.c
1218 --- linux.old/arch/mips/bcm947xx/bcmutils.c 1970-01-01 01:00:00.000000000 +0100
1219 +++ linux.dev/arch/mips/bcm947xx/bcmutils.c 2006-10-02 21:19:59.000000000 +0200
1220 @@ -0,0 +1,247 @@
1221 +/*
1222 + * Misc useful OS-independent routines.
1223 + *
1224 + * Copyright 2006, Broadcom Corporation
1225 + * All Rights Reserved.
1226 + *
1227 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
1228 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
1229 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
1230 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
1231 + * $Id: bcmutils.c,v 1.1.1.12 2006/02/27 03:43:16 honor Exp $
1232 + */
1233 +
1234 +#include <typedefs.h>
1235 +#include <bcmdefs.h>
1236 +#include <stdarg.h>
1237 +#include <bcmutils.h>
1238 +#include <osl.h>
1239 +#include <sbutils.h>
1240 +#include <bcmnvram.h>
1241 +#include <bcmendian.h>
1242 +#include <bcmdevs.h>
1243 +
1244 +unsigned char bcm_ctype[] = {
1245 + _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */
1246 + _BCM_C, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C,
1247 + _BCM_C, /* 8-15 */
1248 + _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 16-23 */
1249 + _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 24-31 */
1250 + _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 32-39 */
1251 + _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 40-47 */
1252 + _BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D, /* 48-55 */
1253 + _BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 56-63 */
1254 + _BCM_P, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X,
1255 + _BCM_U|_BCM_X, _BCM_U, /* 64-71 */
1256 + _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 72-79 */
1257 + _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 80-87 */
1258 + _BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 88-95 */
1259 + _BCM_P, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X,
1260 + _BCM_L|_BCM_X, _BCM_L, /* 96-103 */
1261 + _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 104-111 */
1262 + _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 112-119 */
1263 + _BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_C, /* 120-127 */
1264 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 128-143 */
1265 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 144-159 */
1266 + _BCM_S|_BCM_SP, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,
1267 + _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 160-175 */
1268 + _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,
1269 + _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 176-191 */
1270 + _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U,
1271 + _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, /* 192-207 */
1272 + _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_P, _BCM_U, _BCM_U, _BCM_U,
1273 + _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_L, /* 208-223 */
1274 + _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L,
1275 + _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, /* 224-239 */
1276 + _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_P, _BCM_L, _BCM_L, _BCM_L,
1277 + _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L /* 240-255 */
1278 +};
1279 +
1280 +
1281 +ulong
1282 +bcm_strtoul(char *cp, char **endp, uint base)
1283 +{
1284 + ulong result, value;
1285 + bool minus;
1286 +
1287 + minus = FALSE;
1288 +
1289 + while (bcm_isspace(*cp))
1290 + cp++;
1291 +
1292 + if (cp[0] == '+')
1293 + cp++;
1294 + else if (cp[0] == '-') {
1295 + minus = TRUE;
1296 + cp++;
1297 + }
1298 +
1299 + if (base == 0) {
1300 + if (cp[0] == '0') {
1301 + if ((cp[1] == 'x') || (cp[1] == 'X')) {
1302 + base = 16;
1303 + cp = &cp[2];
1304 + } else {
1305 + base = 8;
1306 + cp = &cp[1];
1307 + }
1308 + } else
1309 + base = 10;
1310 + } else if (base == 16 && (cp[0] == '0') && ((cp[1] == 'x') || (cp[1] == 'X'))) {
1311 + cp = &cp[2];
1312 + }
1313 +
1314 + result = 0;
1315 +
1316 + while (bcm_isxdigit(*cp) &&
1317 + (value = bcm_isdigit(*cp) ? *cp-'0' : bcm_toupper(*cp)-'A'+10) < base) {
1318 + result = result*base + value;
1319 + cp++;
1320 + }
1321 +
1322 + if (minus)
1323 + result = (ulong)(result * -1);
1324 +
1325 + if (endp)
1326 + *endp = (char *)cp;
1327 +
1328 + return (result);
1329 +}
1330 +
1331 +uchar
1332 +bcm_toupper(uchar c)
1333 +{
1334 + if (bcm_islower(c))
1335 + c -= 'a'-'A';
1336 + return (c);
1337 +}
1338 +
1339 +char*
1340 +bcm_ether_ntoa(struct ether_addr *ea, char *buf)
1341 +{
1342 + sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
1343 + ea->octet[0]&0xff, ea->octet[1]&0xff, ea->octet[2]&0xff,
1344 + ea->octet[3]&0xff, ea->octet[4]&0xff, ea->octet[5]&0xff);
1345 + return (buf);
1346 +}
1347 +
1348 +
1349 +/*
1350 + * Search the name=value vars for a specific one and return its value.
1351 + * Returns NULL if not found.
1352 + */
1353 +char*
1354 +getvar(char *vars, char *name)
1355 +{
1356 + char *s;
1357 + int len;
1358 +
1359 + len = strlen(name);
1360 +
1361 + /* first look in vars[] */
1362 + for (s = vars; s && *s;) {
1363 + /* CSTYLED */
1364 + if ((memcmp(s, name, len) == 0) && (s[len] == '='))
1365 + return (&s[len+1]);
1366 +
1367 + while (*s++)
1368 + ;
1369 + }
1370 +
1371 + /* then query nvram */
1372 + return (nvram_get(name));
1373 +}
1374 +
1375 +/*
1376 + * Search the vars for a specific one and return its value as
1377 + * an integer. Returns 0 if not found.
1378 + */
1379 +int
1380 +getintvar(char *vars, char *name)
1381 +{
1382 + char *val;
1383 +
1384 + if ((val = getvar(vars, name)) == NULL)
1385 + return (0);
1386 +
1387 + return (bcm_strtoul(val, NULL, 0));
1388 +}
1389 +
1390 +
1391 +/*******************************************************************************
1392 + * crc8
1393 + *
1394 + * Computes a crc8 over the input data using the polynomial:
1395 + *
1396 + * x^8 + x^7 +x^6 + x^4 + x^2 + 1
1397 + *
1398 + * The caller provides the initial value (either CRC8_INIT_VALUE
1399 + * or the previous returned value) to allow for processing of
1400 + * discontiguous blocks of data. When generating the CRC the
1401 + * caller is responsible for complementing the final return value
1402 + * and inserting it into the byte stream. When checking, a final
1403 + * return value of CRC8_GOOD_VALUE indicates a valid CRC.
1404 + *
1405 + * Reference: Dallas Semiconductor Application Note 27
1406 + * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms",
1407 + * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd.,
1408 + * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt
1409 + *
1410 + * ****************************************************************************
1411 + */
1412 +
1413 +static uint8 crc8_table[256] = {
1414 + 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
1415 + 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
1416 + 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
1417 + 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
1418 + 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
1419 + 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
1420 + 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
1421 + 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
1422 + 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
1423 + 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
1424 + 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
1425 + 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
1426 + 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
1427 + 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
1428 + 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
1429 + 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
1430 + 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
1431 + 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
1432 + 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
1433 + 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
1434 + 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
1435 + 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
1436 + 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
1437 + 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
1438 + 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
1439 + 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
1440 + 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
1441 + 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
1442 + 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
1443 + 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
1444 + 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
1445 + 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F
1446 +};
1447 +
1448 +#define CRC_INNER_LOOP(n, c, x) \
1449 + (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff]
1450 +
1451 +uint8
1452 +hndcrc8(
1453 + uint8 *pdata, /* pointer to array of data to process */
1454 + uint nbytes, /* number of input data bytes to process */
1455 + uint8 crc /* either CRC8_INIT_VALUE or previous return value */
1456 +)
1457 +{
1458 + /* hard code the crc loop instead of using CRC_INNER_LOOP macro
1459 + * to avoid the undefined and unnecessary (uint8 >> 8) operation.
1460 + */
1461 + while (nbytes-- > 0)
1462 + crc = crc8_table[(crc ^ *pdata++) & 0xff];
1463 +
1464 + return crc;
1465 +}
1466 +
1467 +
1468 diff -urN linux.old/arch/mips/bcm947xx/cfe_env.c linux.dev/arch/mips/bcm947xx/cfe_env.c
1469 --- linux.old/arch/mips/bcm947xx/cfe_env.c 1970-01-01 01:00:00.000000000 +0100
1470 +++ linux.dev/arch/mips/bcm947xx/cfe_env.c 2006-10-02 21:19:59.000000000 +0200
1471 @@ -0,0 +1,234 @@
1472 +/*
1473 + * NVRAM variable manipulation (Linux kernel half)
1474 + *
1475 + * Copyright 2001-2003, Broadcom Corporation
1476 + * All Rights Reserved.
1477 + *
1478 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
1479 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
1480 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
1481 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
1482 + *
1483 + * $Id$
1484 + */
1485 +
1486 +#include <linux/config.h>
1487 +#include <linux/init.h>
1488 +#include <linux/module.h>
1489 +#include <linux/kernel.h>
1490 +#include <linux/string.h>
1491 +#include <asm/io.h>
1492 +#include <asm/uaccess.h>
1493 +
1494 +#include <typedefs.h>
1495 +#include <osl.h>
1496 +#include <bcmendian.h>
1497 +#include <bcmutils.h>
1498 +
1499 +#define NVRAM_SIZE (0x1ff0)
1500 +static char _nvdata[NVRAM_SIZE] __initdata;
1501 +static char _valuestr[256] __initdata;
1502 +
1503 +/*
1504 + * TLV types. These codes are used in the "type-length-value"
1505 + * encoding of the items stored in the NVRAM device (flash or EEPROM)
1506 + *
1507 + * The layout of the flash/nvram is as follows:
1508 + *
1509 + * <type> <length> <data ...> <type> <length> <data ...> <type_end>
1510 + *
1511 + * The type code of "ENV_TLV_TYPE_END" marks the end of the list.
1512 + * The "length" field marks the length of the data section, not
1513 + * including the type and length fields.
1514 + *
1515 + * Environment variables are stored as follows:
1516 + *
1517 + * <type_env> <length> <flags> <name> = <value>
1518 + *
1519 + * If bit 0 (low bit) is set, the length is an 8-bit value.
1520 + * If bit 0 (low bit) is clear, the length is a 16-bit value
1521 + *
1522 + * Bit 7 set indicates "user" TLVs. In this case, bit 0 still
1523 + * indicates the size of the length field.
1524 + *
1525 + * Flags are from the constants below:
1526 + *
1527 + */
1528 +#define ENV_LENGTH_16BITS 0x00 /* for low bit */
1529 +#define ENV_LENGTH_8BITS 0x01
1530 +
1531 +#define ENV_TYPE_USER 0x80
1532 +
1533 +#define ENV_CODE_SYS(n,l) (((n)<<1)|(l))
1534 +#define ENV_CODE_USER(n,l) ((((n)<<1)|(l)) | ENV_TYPE_USER)
1535 +
1536 +/*
1537 + * The actual TLV types we support
1538 + */
1539 +
1540 +#define ENV_TLV_TYPE_END 0x00
1541 +#define ENV_TLV_TYPE_ENV ENV_CODE_SYS(0,ENV_LENGTH_8BITS)
1542 +
1543 +/*
1544 + * Environment variable flags
1545 + */
1546 +
1547 +#define ENV_FLG_NORMAL 0x00 /* normal read/write */
1548 +#define ENV_FLG_BUILTIN 0x01 /* builtin - not stored in flash */
1549 +#define ENV_FLG_READONLY 0x02 /* read-only - cannot be changed */
1550 +
1551 +#define ENV_FLG_MASK 0xFF /* mask of attributes we keep */
1552 +#define ENV_FLG_ADMIN 0x100 /* lets us internally override permissions */
1553 +
1554 +
1555 +/* *********************************************************************
1556 + * _nvram_read(buffer,offset,length)
1557 + *
1558 + * Read data from the NVRAM device
1559 + *
1560 + * Input parameters:
1561 + * buffer - destination buffer
1562 + * offset - offset of data to read
1563 + * length - number of bytes to read
1564 + *
1565 + * Return value:
1566 + * number of bytes read, or <0 if error occured
1567 + ********************************************************************* */
1568 +static int
1569 +_nvram_read(unsigned char *nv_buf, unsigned char *buffer, int offset, int length)
1570 +{
1571 + int i;
1572 + if (offset > NVRAM_SIZE)
1573 + return -1;
1574 +
1575 + for ( i = 0; i < length; i++) {
1576 + buffer[i] = ((volatile unsigned char*)nv_buf)[offset + i];
1577 + }
1578 + return length;
1579 +}
1580 +
1581 +
1582 +static char*
1583 +_strnchr(const char *dest,int c,size_t cnt)
1584 +{
1585 + while (*dest && (cnt > 0)) {
1586 + if (*dest == c) return (char *) dest;
1587 + dest++;
1588 + cnt--;
1589 + }
1590 + return NULL;
1591 +}
1592 +
1593 +
1594 +
1595 +/*
1596 + * Core support API: Externally visible.
1597 + */
1598 +
1599 +/*
1600 + * Get the value of an NVRAM variable
1601 + * @param name name of variable to get
1602 + * @return value of variable or NULL if undefined
1603 + */
1604 +
1605 +char*
1606 +cfe_env_get(unsigned char *nv_buf, char* name)
1607 +{
1608 + int size;
1609 + unsigned char *buffer;
1610 + unsigned char *ptr;
1611 + unsigned char *envval;
1612 + unsigned int reclen;
1613 + unsigned int rectype;
1614 + int offset;
1615 + int flg;
1616 +
1617 + size = NVRAM_SIZE;
1618 + buffer = &_nvdata[0];
1619 +
1620 + ptr = buffer;
1621 + offset = 0;
1622 +
1623 + /* Read the record type and length */
1624 + if (_nvram_read(nv_buf, ptr,offset,1) != 1) {
1625 + goto error;
1626 + }
1627 +
1628 + while ((*ptr != ENV_TLV_TYPE_END) && (size > 1)) {
1629 +
1630 + /* Adjust pointer for TLV type */
1631 + rectype = *(ptr);
1632 + offset++;
1633 + size--;
1634 +
1635 + /*
1636 + * Read the length. It can be either 1 or 2 bytes
1637 + * depending on the code
1638 + */
1639 + if (rectype & ENV_LENGTH_8BITS) {
1640 + /* Read the record type and length - 8 bits */
1641 + if (_nvram_read(nv_buf, ptr,offset,1) != 1) {
1642 + goto error;
1643 + }
1644 + reclen = *(ptr);
1645 + size--;
1646 + offset++;
1647 + }
1648 + else {
1649 + /* Read the record type and length - 16 bits, MSB first */
1650 + if (_nvram_read(nv_buf, ptr,offset,2) != 2) {
1651 + goto error;
1652 + }
1653 + reclen = (((unsigned int) *(ptr)) << 8) + (unsigned int) *(ptr+1);
1654 + size -= 2;
1655 + offset += 2;
1656 + }
1657 +
1658 + if (reclen > size)
1659 + break; /* should not happen, bad NVRAM */
1660 +
1661 + switch (rectype) {
1662 + case ENV_TLV_TYPE_ENV:
1663 + /* Read the TLV data */
1664 + if (_nvram_read(nv_buf, ptr,offset,reclen) != reclen)
1665 + goto error;
1666 + flg = *ptr++;
1667 + envval = (unsigned char *) _strnchr(ptr,'=',(reclen-1));
1668 + if (envval) {
1669 + *envval++ = '\0';
1670 + memcpy(_valuestr,envval,(reclen-1)-(envval-ptr));
1671 + _valuestr[(reclen-1)-(envval-ptr)] = '\0';
1672 +#if 0
1673 + printk(KERN_INFO "NVRAM:%s=%s\n", ptr, _valuestr);
1674 +#endif
1675 + if(!strcmp(ptr, name)){
1676 + return _valuestr;
1677 + }
1678 + if((strlen(ptr) > 1) && !strcmp(&ptr[1], name))
1679 + return _valuestr;
1680 + }
1681 + break;
1682 +
1683 + default:
1684 + /* Unknown TLV type, skip it. */
1685 + break;
1686 + }
1687 +
1688 + /*
1689 + * Advance to next TLV
1690 + */
1691 +
1692 + size -= (int)reclen;
1693 + offset += reclen;
1694 +
1695 + /* Read the next record type */
1696 + ptr = buffer;
1697 + if (_nvram_read(nv_buf, ptr,offset,1) != 1)
1698 + goto error;
1699 + }
1700 +
1701 +error:
1702 + return NULL;
1703 +
1704 +}
1705 +
1706 diff -urN linux.old/arch/mips/bcm947xx/compressed/Makefile linux.dev/arch/mips/bcm947xx/compressed/Makefile
1707 --- linux.old/arch/mips/bcm947xx/compressed/Makefile 1970-01-01 01:00:00.000000000 +0100
1708 +++ linux.dev/arch/mips/bcm947xx/compressed/Makefile 2006-10-02 21:19:59.000000000 +0200
1709 @@ -0,0 +1,33 @@
1710 +#
1711 +# Makefile for Broadcom BCM947XX boards
1712 +#
1713 +# Copyright 2001-2003, Broadcom Corporation
1714 +# All Rights Reserved.
1715 +#
1716 +# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
1717 +# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
1718 +# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
1719 +# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
1720 +#
1721 +# $Id: Makefile,v 1.2 2005/04/02 12:12:57 wbx Exp $
1722 +#
1723 +
1724 +OBJCOPY_ARGS = -O binary -R .reginfo -R .note -R .comment -R .mdebug -S
1725 +SYSTEM ?= $(TOPDIR)/vmlinux
1726 +
1727 +all: vmlinuz
1728 +
1729 +# Don't build dependencies, this may die if $(CC) isn't gcc
1730 +dep:
1731 +
1732 +# Create a gzipped version named vmlinuz for compatibility
1733 +vmlinuz: piggy
1734 + gzip -c9 $< > $@
1735 +
1736 +piggy: $(SYSTEM)
1737 + $(OBJCOPY) $(OBJCOPY_ARGS) $< $@
1738 +
1739 +mrproper: clean
1740 +
1741 +clean:
1742 + rm -f vmlinuz piggy
1743 diff -urN linux.old/arch/mips/bcm947xx/export.c linux.dev/arch/mips/bcm947xx/export.c
1744 --- linux.old/arch/mips/bcm947xx/export.c 1970-01-01 01:00:00.000000000 +0100
1745 +++ linux.dev/arch/mips/bcm947xx/export.c 2006-10-02 21:19:59.000000000 +0200
1746 @@ -0,0 +1,65 @@
1747 +#include <linux/module.h>
1748 +
1749 +#define _export(n) \
1750 + void n(void); \
1751 + EXPORT_SYMBOL(n);
1752 +
1753 +_export(bcm947xx_sbh)
1754 +
1755 +_export(sb_attach)
1756 +_export(sb_kattach)
1757 +_export(sb_boardtype)
1758 +_export(sb_boardvendor)
1759 +_export(sb_btcgpiowar)
1760 +_export(sb_bus)
1761 +_export(sb_chip)
1762 +_export(sb_chiprev)
1763 +_export(sb_chipcrev)
1764 +_export(sb_chippkg)
1765 +_export(sb_clkctl_clk)
1766 +_export(sb_clkctl_fast_pwrup_delay)
1767 +_export(sb_clkctl_init)
1768 +_export(sb_clkctl_xtal)
1769 +_export(sb_core_disable)
1770 +_export(sb_core_reset)
1771 +_export(sb_core_tofixup)
1772 +_export(sb_coreflags)
1773 +_export(sb_coreflagshi)
1774 +_export(sb_coreidx)
1775 +_export(sb_corerev)
1776 +_export(sb_coreunit)
1777 +_export(sb_detach)
1778 +_export(sb_deviceremoved)
1779 +_export(sb_gpiosetcore)
1780 +_export(sb_gpiocontrol)
1781 +_export(sb_gpioled)
1782 +_export(sb_gpioin)
1783 +_export(sb_gpioout)
1784 +_export(sb_gpioouten)
1785 +_export(sb_gpiotimerval)
1786 +_export(sb_iscoreup)
1787 +_export(sb_pci_setup)
1788 +_export(sb_pcirev)
1789 +_export(sb_pcmcia_init)
1790 +_export(sb_pcmciarev)
1791 +_export(sb_register_intr_callback)
1792 +_export(sb_setcore)
1793 +_export(sb_war16165)
1794 +_export(sb_osh)
1795 +
1796 +_export(getvar)
1797 +_export(getintvar)
1798 +_export(bcm_strtoul)
1799 +_export(bcm_ctype)
1800 +_export(bcm_toupper)
1801 +_export(bcm_ether_ntoa)
1802 +
1803 +_export(nvram_get)
1804 +_export(nvram_getall)
1805 +_export(nvram_set)
1806 +_export(nvram_unset)
1807 +_export(nvram_commit)
1808 +
1809 +_export(srom_read)
1810 +_export(srom_write)
1811 +
1812 diff -urN linux.old/arch/mips/bcm947xx/generic/int-handler.S linux.dev/arch/mips/bcm947xx/generic/int-handler.S
1813 --- linux.old/arch/mips/bcm947xx/generic/int-handler.S 1970-01-01 01:00:00.000000000 +0100
1814 +++ linux.dev/arch/mips/bcm947xx/generic/int-handler.S 2006-10-02 21:19:59.000000000 +0200
1815 @@ -0,0 +1,51 @@
1816 +/*
1817 + * Generic interrupt handler for Broadcom MIPS boards
1818 + *
1819 + * Copyright 2004, Broadcom Corporation
1820 + * All Rights Reserved.
1821 + *
1822 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
1823 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
1824 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
1825 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
1826 + *
1827 + * $Id: int-handler.S,v 1.1 2005/03/16 13:50:00 wbx Exp $
1828 + */
1829 +
1830 +#include <linux/config.h>
1831 +
1832 +#include <asm/asm.h>
1833 +#include <asm/mipsregs.h>
1834 +#include <asm/regdef.h>
1835 +#include <asm/stackframe.h>
1836 +
1837 +/*
1838 + * MIPS IRQ Source
1839 + * -------- ------
1840 + * 0 Software (ignored)
1841 + * 1 Software (ignored)
1842 + * 2 Combined hardware interrupt (hw0)
1843 + * 3 Hardware
1844 + * 4 Hardware
1845 + * 5 Hardware
1846 + * 6 Hardware
1847 + * 7 R4k timer
1848 + */
1849 +
1850 + .text
1851 + .set noreorder
1852 + .set noat
1853 + .align 5
1854 + NESTED(brcmIRQ, PT_SIZE, sp)
1855 + SAVE_ALL
1856 + CLI
1857 + .set at
1858 + .set noreorder
1859 +
1860 + jal brcm_irq_dispatch
1861 + move a0, sp
1862 +
1863 + j ret_from_irq
1864 + nop
1865 +
1866 + END(brcmIRQ)
1867 diff -urN linux.old/arch/mips/bcm947xx/generic/irq.c linux.dev/arch/mips/bcm947xx/generic/irq.c
1868 --- linux.old/arch/mips/bcm947xx/generic/irq.c 1970-01-01 01:00:00.000000000 +0100
1869 +++ linux.dev/arch/mips/bcm947xx/generic/irq.c 2006-10-02 21:19:59.000000000 +0200
1870 @@ -0,0 +1,130 @@
1871 +/*
1872 + * Generic interrupt control functions for Broadcom MIPS boards
1873 + *
1874 + * Copyright 2004, Broadcom Corporation
1875 + * All Rights Reserved.
1876 + *
1877 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
1878 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
1879 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
1880 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
1881 + *
1882 + * $Id: irq.c,v 1.1 2005/03/16 13:50:00 wbx Exp $
1883 + */
1884 +
1885 +#include <linux/config.h>
1886 +#include <linux/init.h>
1887 +#include <linux/kernel.h>
1888 +#include <linux/types.h>
1889 +#include <linux/interrupt.h>
1890 +#include <linux/irq.h>
1891 +
1892 +#include <asm/irq.h>
1893 +#include <asm/mipsregs.h>
1894 +#include <asm/gdb-stub.h>
1895 +
1896 +#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
1897 +
1898 +extern asmlinkage void brcmIRQ(void);
1899 +extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs);
1900 +
1901 +void
1902 +brcm_irq_dispatch(struct pt_regs *regs)
1903 +{
1904 + u32 cause;
1905 +
1906 + cause = read_c0_cause() &
1907 + read_c0_status() &
1908 + CAUSEF_IP;
1909 +
1910 +#ifdef CONFIG_KERNPROF
1911 + change_c0_status(cause | 1, 1);
1912 +#else
1913 + clear_c0_status(cause);
1914 +#endif
1915 +
1916 + if (cause & CAUSEF_IP7)
1917 + do_IRQ(7, regs);
1918 + if (cause & CAUSEF_IP2)
1919 + do_IRQ(2, regs);
1920 + if (cause & CAUSEF_IP3)
1921 + do_IRQ(3, regs);
1922 + if (cause & CAUSEF_IP4)
1923 + do_IRQ(4, regs);
1924 + if (cause & CAUSEF_IP5)
1925 + do_IRQ(5, regs);
1926 + if (cause & CAUSEF_IP6)
1927 + do_IRQ(6, regs);
1928 +}
1929 +
1930 +static void
1931 +enable_brcm_irq(unsigned int irq)
1932 +{
1933 + if (irq < 8)
1934 + set_c0_status(1 << (irq + 8));
1935 + else
1936 + set_c0_status(IE_IRQ0);
1937 +}
1938 +
1939 +static void
1940 +disable_brcm_irq(unsigned int irq)
1941 +{
1942 + if (irq < 8)
1943 + clear_c0_status(1 << (irq + 8));
1944 + else
1945 + clear_c0_status(IE_IRQ0);
1946 +}
1947 +
1948 +static void
1949 +ack_brcm_irq(unsigned int irq)
1950 +{
1951 + /* Already done in brcm_irq_dispatch */
1952 +}
1953 +
1954 +static unsigned int
1955 +startup_brcm_irq(unsigned int irq)
1956 +{
1957 + enable_brcm_irq(irq);
1958 +
1959 + return 0; /* never anything pending */
1960 +}
1961 +
1962 +static void
1963 +end_brcm_irq(unsigned int irq)
1964 +{
1965 + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
1966 + enable_brcm_irq(irq);
1967 +}
1968 +
1969 +static struct hw_interrupt_type brcm_irq_type = {
1970 + typename: "MIPS",
1971 + startup: startup_brcm_irq,
1972 + shutdown: disable_brcm_irq,
1973 + enable: enable_brcm_irq,
1974 + disable: disable_brcm_irq,
1975 + ack: ack_brcm_irq,
1976 + end: end_brcm_irq,
1977 + NULL
1978 +};
1979 +
1980 +void __init
1981 +init_IRQ(void)
1982 +{
1983 + int i;
1984 +
1985 + for (i = 0; i < NR_IRQS; i++) {
1986 + irq_desc[i].status = IRQ_DISABLED;
1987 + irq_desc[i].action = 0;
1988 + irq_desc[i].depth = 1;
1989 + irq_desc[i].handler = &brcm_irq_type;
1990 + }
1991 +
1992 + set_except_vector(0, brcmIRQ);
1993 + change_c0_status(ST0_IM, ALLINTS);
1994 +
1995 +#ifdef CONFIG_REMOTE_DEBUG
1996 + printk("Breaking into debugger...\n");
1997 + set_debug_traps();
1998 + breakpoint();
1999 +#endif
2000 +}
2001 diff -urN linux.old/arch/mips/bcm947xx/generic/Makefile linux.dev/arch/mips/bcm947xx/generic/Makefile
2002 --- linux.old/arch/mips/bcm947xx/generic/Makefile 1970-01-01 01:00:00.000000000 +0100
2003 +++ linux.dev/arch/mips/bcm947xx/generic/Makefile 2006-10-02 21:26:29.000000000 +0200
2004 @@ -0,0 +1,16 @@
2005 +#
2006 +# Makefile for the BCM947xx specific kernel interface routines
2007 +# under Linux.
2008 +#
2009 +EXTRA_CFLAGS += -fno-delayed-branch
2010 +
2011 +.S.s:
2012 + $(CPP) $(AFLAGS) $< -o $*.s
2013 +.S.o:
2014 + $(CC) $(AFLAGS) -c $< -o $*.o
2015 +
2016 +O_TARGET := brcm.o
2017 +
2018 +obj-y := int-handler.o irq.o
2019 +
2020 +include $(TOPDIR)/Rules.make
2021 diff -urN linux.old/arch/mips/bcm947xx/gpio.c linux.dev/arch/mips/bcm947xx/gpio.c
2022 --- linux.old/arch/mips/bcm947xx/gpio.c 1970-01-01 01:00:00.000000000 +0100
2023 +++ linux.dev/arch/mips/bcm947xx/gpio.c 2006-10-02 21:19:59.000000000 +0200
2024 @@ -0,0 +1,159 @@
2025 +/*
2026 + * GPIO char driver
2027 + *
2028 + * Copyright 2005, Broadcom Corporation
2029 + * All Rights Reserved.
2030 + *
2031 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
2032 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
2033 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
2034 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
2035 + *
2036 + * $Id$
2037 + */
2038 +
2039 +#include <linux/module.h>
2040 +#include <linux/init.h>
2041 +#include <linux/fs.h>
2042 +#include <linux/miscdevice.h>
2043 +#include <asm/uaccess.h>
2044 +
2045 +#include <typedefs.h>
2046 +#include <osl.h>
2047 +#include <bcmutils.h>
2048 +#include <sbutils.h>
2049 +#include <bcmdevs.h>
2050 +
2051 +static sb_t *gpio_sbh;
2052 +static int gpio_major;
2053 +static devfs_handle_t gpio_dir;
2054 +static struct {
2055 + char *name;
2056 + devfs_handle_t handle;
2057 +} gpio_file[] = {
2058 + { "in", NULL },
2059 + { "out", NULL },
2060 + { "outen", NULL },
2061 + { "control", NULL }
2062 +};
2063 +
2064 +static int
2065 +gpio_open(struct inode *inode, struct file * file)
2066 +{
2067 + if (MINOR(inode->i_rdev) > ARRAYSIZE(gpio_file))
2068 + return -ENODEV;
2069 +
2070 + MOD_INC_USE_COUNT;
2071 + return 0;
2072 +}
2073 +
2074 +static int
2075 +gpio_release(struct inode *inode, struct file * file)
2076 +{
2077 + MOD_DEC_USE_COUNT;
2078 + return 0;
2079 +}
2080 +
2081 +static ssize_t
2082 +gpio_read(struct file *file, char *buf, size_t count, loff_t *ppos)
2083 +{
2084 + u32 val;
2085 +
2086 + switch (MINOR(file->f_dentry->d_inode->i_rdev)) {
2087 + case 0:
2088 + val = sb_gpioin(gpio_sbh);
2089 + break;
2090 + case 1:
2091 + val = sb_gpioout(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY);
2092 + break;
2093 + case 2:
2094 + val = sb_gpioouten(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY);
2095 + break;
2096 + case 3:
2097 + val = sb_gpiocontrol(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY);
2098 + break;
2099 + default:
2100 + return -ENODEV;
2101 + }
2102 +
2103 + if (put_user(val, (u32 *) buf))
2104 + return -EFAULT;
2105 +
2106 + return sizeof(val);
2107 +}
2108 +
2109 +static ssize_t
2110 +gpio_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
2111 +{
2112 + u32 val;
2113 +
2114 + if (get_user(val, (u32 *) buf))
2115 + return -EFAULT;
2116 +
2117 + switch (MINOR(file->f_dentry->d_inode->i_rdev)) {
2118 + case 0:
2119 + return -EACCES;
2120 + case 1:
2121 + sb_gpioout(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY);
2122 + break;
2123 + case 2:
2124 + sb_gpioouten(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY);
2125 + break;
2126 + case 3:
2127 + sb_gpiocontrol(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY);
2128 + break;
2129 + default:
2130 + return -ENODEV;
2131 + }
2132 +
2133 + return sizeof(val);
2134 +}
2135 +
2136 +static struct file_operations gpio_fops = {
2137 + owner: THIS_MODULE,
2138 + open: gpio_open,
2139 + release: gpio_release,
2140 + read: gpio_read,
2141 + write: gpio_write,
2142 +};
2143 +
2144 +static int __init
2145 +gpio_init(void)
2146 +{
2147 + int i;
2148 +
2149 + if (!(gpio_sbh = sb_kattach()))
2150 + return -ENODEV;
2151 +
2152 + sb_gpiosetcore(gpio_sbh);
2153 +
2154 + if ((gpio_major = devfs_register_chrdev(0, "gpio", &gpio_fops)) < 0)
2155 + return gpio_major;
2156 +
2157 + gpio_dir = devfs_mk_dir(NULL, "gpio", NULL);
2158 +
2159 + for (i = 0; i < ARRAYSIZE(gpio_file); i++) {
2160 + gpio_file[i].handle = devfs_register(gpio_dir,
2161 + gpio_file[i].name,
2162 + DEVFS_FL_DEFAULT, gpio_major, i,
2163 + S_IFCHR | S_IRUGO | S_IWUGO,
2164 + &gpio_fops, NULL);
2165 + }
2166 +
2167 + return 0;
2168 +}
2169 +
2170 +static void __exit
2171 +gpio_exit(void)
2172 +{
2173 + int i;
2174 +
2175 + for (i = 0; i < ARRAYSIZE(gpio_file); i++)
2176 + devfs_unregister(gpio_file[i].handle);
2177 + devfs_unregister(gpio_dir);
2178 + devfs_unregister_chrdev(gpio_major, "gpio");
2179 + sb_detach(gpio_sbh);
2180 +}
2181 +
2182 +module_init(gpio_init);
2183 +module_exit(gpio_exit);
2184 diff -urN linux.old/arch/mips/bcm947xx/hndchipc.c linux.dev/arch/mips/bcm947xx/hndchipc.c
2185 --- linux.old/arch/mips/bcm947xx/hndchipc.c 1970-01-01 01:00:00.000000000 +0100
2186 +++ linux.dev/arch/mips/bcm947xx/hndchipc.c 2006-10-02 21:19:59.000000000 +0200
2187 @@ -0,0 +1,158 @@
2188 +/*
2189 + * BCM47XX support code for some chipcommon (old extif) facilities (uart)
2190 + *
2191 + * Copyright 2006, Broadcom Corporation
2192 + * All Rights Reserved.
2193 + *
2194 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
2195 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
2196 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
2197 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
2198 + *
2199 + * $Id: hndchipc.c,v 1.1.1.1 2006/02/27 03:43:16 honor Exp $
2200 + */
2201 +
2202 +#include <typedefs.h>
2203 +#include <bcmdefs.h>
2204 +#include <osl.h>
2205 +#include <bcmutils.h>
2206 +#include <sbutils.h>
2207 +#include <bcmdevs.h>
2208 +#include <bcmnvram.h>
2209 +#include <sbconfig.h>
2210 +#include <sbextif.h>
2211 +#include <sbchipc.h>
2212 +#include <hndcpu.h>
2213 +
2214 +/*
2215 + * Returns TRUE if an external UART exists at the given base
2216 + * register.
2217 + */
2218 +static bool
2219 +BCMINITFN(serial_exists)(osl_t *osh, uint8 *regs)
2220 +{
2221 + uint8 save_mcr, status1;
2222 +
2223 + save_mcr = R_REG(osh, &regs[UART_MCR]);
2224 + W_REG(osh, &regs[UART_MCR], UART_MCR_LOOP | 0x0a);
2225 + status1 = R_REG(osh, &regs[UART_MSR]) & 0xf0;
2226 + W_REG(osh, &regs[UART_MCR], save_mcr);
2227 +
2228 + return (status1 == 0x90);
2229 +}
2230 +
2231 +/*
2232 + * Initializes UART access. The callback function will be called once
2233 + * per found UART.
2234 + */
2235 +void
2236 +BCMINITFN(sb_serial_init)(sb_t *sbh, void (*add)(void *regs, uint irq, uint baud_base,
2237 + uint reg_shift))
2238 +{
2239 + osl_t *osh;
2240 + void *regs;
2241 + ulong base;
2242 + uint irq;
2243 + int i, n;
2244 +
2245 + osh = sb_osh(sbh);
2246 +
2247 + if ((regs = sb_setcore(sbh, SB_EXTIF, 0))) {
2248 + extifregs_t *eir = (extifregs_t *) regs;
2249 + sbconfig_t *sb;
2250 +
2251 + /* Determine external UART register base */
2252 + sb = (sbconfig_t *)((ulong) eir + SBCONFIGOFF);
2253 + base = EXTIF_CFGIF_BASE(sb_base(R_REG(osh, &sb->sbadmatch1)));
2254 +
2255 + /* Determine IRQ */
2256 + irq = sb_irq(sbh);
2257 +
2258 + /* Disable GPIO interrupt initially */
2259 + W_REG(osh, &eir->gpiointpolarity, 0);
2260 + W_REG(osh, &eir->gpiointmask, 0);
2261 +
2262 + /* Search for external UARTs */
2263 + n = 2;
2264 + for (i = 0; i < 2; i++) {
2265 + regs = (void *) REG_MAP(base + (i * 8), 8);
2266 + if (serial_exists(osh, regs)) {
2267 + /* Set GPIO 1 to be the external UART IRQ */
2268 + W_REG(osh, &eir->gpiointmask, 2);
2269 + /* XXXDetermine external UART clock */
2270 + if (add)
2271 + add(regs, irq, 13500000, 0);
2272 + }
2273 + }
2274 +
2275 + /* Add internal UART if enabled */
2276 + if (R_REG(osh, &eir->corecontrol) & CC_UE)
2277 + if (add)
2278 + add((void *) &eir->uartdata, irq, sb_clock(sbh), 2);
2279 + } else if ((regs = sb_setcore(sbh, SB_CC, 0))) {
2280 + chipcregs_t *cc = (chipcregs_t *) regs;
2281 + uint32 rev, cap, pll, baud_base, div;
2282 +
2283 + /* Determine core revision and capabilities */
2284 + rev = sb_corerev(sbh);
2285 + cap = R_REG(osh, &cc->capabilities);
2286 + pll = cap & CAP_PLL_MASK;
2287 +
2288 + /* Determine IRQ */
2289 + irq = sb_irq(sbh);
2290 +
2291 + if (pll == PLL_TYPE1) {
2292 + /* PLL clock */
2293 + baud_base = sb_clock_rate(pll,
2294 + R_REG(osh, &cc->clockcontrol_n),
2295 + R_REG(osh, &cc->clockcontrol_m2));
2296 + div = 1;
2297 + } else {
2298 + /* Fixed ALP clock */
2299 + if (rev >= 11 && rev != 15) {
2300 + baud_base = 20000000;
2301 + div = 1;
2302 + /* Set the override bit so we don't divide it */
2303 + W_REG(osh, &cc->corecontrol, CC_UARTCLKO);
2304 + }
2305 + /* Internal backplane clock */
2306 + else if (rev >= 3) {
2307 + baud_base = sb_clock(sbh);
2308 + div = 2; /* Minimum divisor */
2309 + W_REG(osh, &cc->clkdiv,
2310 + ((R_REG(osh, &cc->clkdiv) & ~CLKD_UART) | div));
2311 + }
2312 + /* Fixed internal backplane clock */
2313 + else {
2314 + baud_base = 88000000;
2315 + div = 48;
2316 + }
2317 +
2318 + /* Clock source depends on strapping if UartClkOverride is unset */
2319 + if ((rev > 0) &&
2320 + ((R_REG(osh, &cc->corecontrol) & CC_UARTCLKO) == 0)) {
2321 + if ((cap & CAP_UCLKSEL) == CAP_UINTCLK) {
2322 + /* Internal divided backplane clock */
2323 + baud_base /= div;
2324 + } else {
2325 + /* Assume external clock of 1.8432 MHz */
2326 + baud_base = 1843200;
2327 + }
2328 + }
2329 + }
2330 +
2331 + /* Add internal UARTs */
2332 + n = cap & CAP_UARTS_MASK;
2333 + for (i = 0; i < n; i++) {
2334 + /* Register offset changed after revision 0 */
2335 + if (rev)
2336 + regs = (void *)((ulong) &cc->uart0data + (i * 256));
2337 + else
2338 + regs = (void *)((ulong) &cc->uart0data + (i * 8));
2339 +
2340 + if (add)
2341 + add(regs, irq, baud_base, 0);
2342 + }
2343 + }
2344 +}
2345 +
2346 diff -urN linux.old/arch/mips/bcm947xx/include/bcm4710.h linux.dev/arch/mips/bcm947xx/include/bcm4710.h
2347 --- linux.old/arch/mips/bcm947xx/include/bcm4710.h 1970-01-01 01:00:00.000000000 +0100
2348 +++ linux.dev/arch/mips/bcm947xx/include/bcm4710.h 2006-10-02 21:19:59.000000000 +0200
2349 @@ -0,0 +1,91 @@
2350 +/*
2351 + * BCM4710 address space map and definitions
2352 + * Think twice before adding to this file, this is not the kitchen sink
2353 + * These definitions are not guaranteed for all 47xx chips, only the 4710
2354 + *
2355 + * Copyright 2004, Broadcom Corporation
2356 + * All Rights Reserved.
2357 + *
2358 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
2359 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
2360 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
2361 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
2362 + *
2363 + * $Id: bcm4710.h,v 1.3 2004/09/27 07:23:30 tallest Exp $
2364 + */
2365 +
2366 +#ifndef _bcm4710_h_
2367 +#define _bcm4710_h_
2368 +
2369 +/* Address map */
2370 +#define BCM4710_SDRAM 0x00000000 /* Physical SDRAM */
2371 +#define BCM4710_PCI_MEM 0x08000000 /* Host Mode PCI memory access space (64 MB) */
2372 +#define BCM4710_PCI_CFG 0x0c000000 /* Host Mode PCI configuration space (64 MB) */
2373 +#define BCM4710_PCI_DMA 0x40000000 /* Client Mode PCI memory access space (1 GB) */
2374 +#define BCM4710_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */
2375 +#define BCM4710_ENUM 0x18000000 /* Beginning of core enumeration space */
2376 +
2377 +/* Core register space */
2378 +#define BCM4710_REG_SDRAM 0x18000000 /* SDRAM core registers */
2379 +#define BCM4710_REG_ILINE20 0x18001000 /* InsideLine20 core registers */
2380 +#define BCM4710_REG_EMAC0 0x18002000 /* Ethernet MAC 0 core registers */
2381 +#define BCM4710_REG_CODEC 0x18003000 /* Codec core registers */
2382 +#define BCM4710_REG_USB 0x18004000 /* USB core registers */
2383 +#define BCM4710_REG_PCI 0x18005000 /* PCI core registers */
2384 +#define BCM4710_REG_MIPS 0x18006000 /* MIPS core registers */
2385 +#define BCM4710_REG_EXTIF 0x18007000 /* External Interface core registers */
2386 +#define BCM4710_REG_EMAC1 0x18008000 /* Ethernet MAC 1 core registers */
2387 +
2388 +#define BCM4710_EXTIF 0x1f000000 /* External Interface base address */
2389 +#define BCM4710_PCMCIA_MEM 0x1f000000 /* External Interface PCMCIA memory access */
2390 +#define BCM4710_PCMCIA_IO 0x1f100000 /* PCMCIA I/O access */
2391 +#define BCM4710_PCMCIA_CONF 0x1f200000 /* PCMCIA configuration */
2392 +#define BCM4710_PROG 0x1f800000 /* Programable interface */
2393 +#define BCM4710_FLASH 0x1fc00000 /* Flash */
2394 +
2395 +#define BCM4710_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */
2396 +
2397 +#define BCM4710_UART (BCM4710_REG_EXTIF + 0x00000300)
2398 +
2399 +#define BCM4710_EUART (BCM4710_EXTIF + 0x00800000)
2400 +#define BCM4710_LED (BCM4710_EXTIF + 0x00900000)
2401 +
2402 +#define SBFLAG_PCI 0
2403 +#define SBFLAG_ENET0 1
2404 +#define SBFLAG_ILINE20 2
2405 +#define SBFLAG_CODEC 3
2406 +#define SBFLAG_USB 4
2407 +#define SBFLAG_EXTIF 5
2408 +#define SBFLAG_ENET1 6
2409 +
2410 +#ifdef CONFIG_HWSIM
2411 +#define BCM4710_TRACE(trval) do { *((int *)0xa0000f18) = (trval); } while (0)
2412 +#else
2413 +#define BCM4710_TRACE(trval)
2414 +#endif
2415 +
2416 +
2417 +/* BCM94702 CPCI -ExtIF used for LocalBus devs */
2418 +
2419 +#define BCM94702_CPCI_RESET_ADDR BCM4710_EXTIF
2420 +#define BCM94702_CPCI_BOARDID_ADDR (BCM4710_EXTIF | 0x4000)
2421 +#define BCM94702_CPCI_DOC_ADDR (BCM4710_EXTIF | 0x6000)
2422 +#define BCM94702_DOC_ADDR BCM94702_CPCI_DOC_ADDR
2423 +#define BCM94702_CPCI_LED_ADDR (BCM4710_EXTIF | 0xc000)
2424 +#define BCM94702_CPCI_NVRAM_ADDR (BCM4710_EXTIF | 0xe000)
2425 +#define BCM94702_CPCI_NVRAM_SIZE 0x1ff0 /* 8K NVRAM : DS1743/STM48txx*/
2426 +#define BCM94702_CPCI_TOD_REG_BASE (BCM94702_CPCI_NVRAM_ADDR | 0x1ff0)
2427 +
2428 +#define LED_REG(x) \
2429 + (*(volatile unsigned char *) (KSEG1ADDR(BCM94702_CPCI_LED_ADDR) + (x)))
2430 +
2431 +/*
2432 + * Reset function implemented in PLD. Read or write should trigger hard reset
2433 + */
2434 +#define SYS_HARD_RESET() \
2435 + { for (;;) \
2436 + *( (volatile unsigned char *)\
2437 + KSEG1ADDR(BCM94702_CPCI_RESET_ADDR) ) = 0x80; \
2438 + }
2439 +
2440 +#endif /* _bcm4710_h_ */
2441 diff -urN linux.old/arch/mips/bcm947xx/include/bcmdefs.h linux.dev/arch/mips/bcm947xx/include/bcmdefs.h
2442 --- linux.old/arch/mips/bcm947xx/include/bcmdefs.h 1970-01-01 01:00:00.000000000 +0100
2443 +++ linux.dev/arch/mips/bcm947xx/include/bcmdefs.h 2006-10-02 21:19:59.000000000 +0200
2444 @@ -0,0 +1,106 @@
2445 +/*
2446 + * Misc system wide definitions
2447 + *
2448 + * Copyright 2006, Broadcom Corporation
2449 + * All Rights Reserved.
2450 + *
2451 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
2452 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
2453 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
2454 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
2455 + * $Id: bcmdefs.h,v 1.1.1.3 2006/04/08 06:13:39 honor Exp $
2456 + */
2457 +
2458 +#ifndef _bcmdefs_h_
2459 +#define _bcmdefs_h_
2460 +
2461 +/*
2462 + * One doesn't need to include this file explicitly, gets included automatically if
2463 + * typedefs.h is included.
2464 + */
2465 +
2466 +/* Reclaiming text and data :
2467 + * The following macros specify special linker sections that can be reclaimed
2468 + * after a system is considered 'up'.
2469 + */
2470 +#if defined(__GNUC__) && defined(BCMRECLAIM)
2471 +extern bool bcmreclaimed;
2472 +#define BCMINITDATA(_data) __attribute__ ((__section__ (".dataini." #_data))) _data
2473 +#define BCMINITFN(_fn) __attribute__ ((__section__ (".textini." #_fn))) _fn
2474 +#else /* #if defined(__GNUC__) && defined(BCMRECLAIM) */
2475 +#define BCMINITDATA(_data) _data
2476 +#define BCMINITFN(_fn) _fn
2477 +#define bcmreclaimed 0
2478 +#endif /* #if defined(__GNUC__) && defined(BCMRECLAIM) */
2479 +
2480 +/* Reclaim uninit functions if BCMNODOWN is defined */
2481 +/* and if they are not already removed by -gc-sections */
2482 +#ifdef BCMNODOWN
2483 +#define BCMUNINITFN(_fn) BCMINITFN(_fn)
2484 +#else
2485 +#define BCMUNINITFN(_fn) _fn
2486 +#endif
2487 +
2488 +#ifdef BCMRECLAIM
2489 +#define CONST
2490 +#else
2491 +#define CONST const
2492 +#endif /* BCMRECLAIM */
2493 +
2494 +/* Compatibility with old-style BCMRECLAIM */
2495 +#define BCMINIT(_id) _id
2496 +
2497 +
2498 +/* Put some library data/code into ROM to reduce RAM requirements */
2499 +#if defined(__GNUC__) && defined(BCMROMOFFLOAD)
2500 +#define BCMROMDATA(_data) __attribute__ ((__section__ (".datarom." #_data))) _data
2501 +#define BCMROMFN(_fn) __attribute__ ((__section__ (".textrom." #_fn))) _fn
2502 +#else
2503 +#define BCMROMDATA(_data) _data
2504 +#define BCMROMFN(_fn) _fn
2505 +#endif
2506 +
2507 +/* Bus types */
2508 +#define SB_BUS 0 /* Silicon Backplane */
2509 +#define PCI_BUS 1 /* PCI target */
2510 +#define PCMCIA_BUS 2 /* PCMCIA target */
2511 +#define SDIO_BUS 3 /* SDIO target */
2512 +#define JTAG_BUS 4 /* JTAG */
2513 +#define NO_BUS 0xFF /* Bus that does not support R/W REG */
2514 +
2515 +/* Allows optimization for single-bus support */
2516 +#ifdef BCMBUSTYPE
2517 +#define BUSTYPE(bus) (BCMBUSTYPE)
2518 +#else
2519 +#define BUSTYPE(bus) (bus)
2520 +#endif
2521 +
2522 +/* Defines for DMA Address Width - Shared between OSL and HNDDMA */
2523 +#define DMADDR_MASK_32 0x0 /* Address mask for 32-bits */
2524 +#define DMADDR_MASK_30 0xc0000000 /* Address mask for 30-bits */
2525 +#define DMADDR_MASK_0 0xffffffff /* Address mask for 0-bits (hi-part) */
2526 +
2527 +#define DMADDRWIDTH_30 30 /* 30-bit addressing capability */
2528 +#define DMADDRWIDTH_32 32 /* 32-bit addressing capability */
2529 +#define DMADDRWIDTH_63 63 /* 64-bit addressing capability */
2530 +#define DMADDRWIDTH_64 64 /* 64-bit addressing capability */
2531 +
2532 +/* packet headroom necessary to accomodate the largest header in the system, (i.e TXOFF).
2533 + * By doing, we avoid the need to allocate an extra buffer for the header when bridging to WL.
2534 + * There is a compile time check in wlc.c which ensure that this value is at least as big
2535 + * as TXOFF. This value is used in dma_rxfill (hnddma.c).
2536 + */
2537 +#define BCMEXTRAHDROOM 160
2538 +
2539 +/* Headroom required for dongle-to-host communication. Packets allocated
2540 + * locally in the dongle (e.g. for CDC ioctls or RNDIS messages) should
2541 + * leave this much room in front for low-level message headers which may
2542 + * be needed to get across the dongle bus to the host. (These messages
2543 + * don't go over the network, so room for the full WL header above would
2544 + * be a waste.)
2545 + */
2546 +#define BCMDONGLEHDRSZ 8
2547 +
2548 +
2549 +
2550 +#endif /* _bcmdefs_h_ */
2551 diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs1.h linux.dev/arch/mips/bcm947xx/include/bcmdevs1.h
2552 --- linux.old/arch/mips/bcm947xx/include/bcmdevs1.h 1970-01-01 01:00:00.000000000 +0100
2553 +++ linux.dev/arch/mips/bcm947xx/include/bcmdevs1.h 2006-10-02 21:19:59.000000000 +0200
2554 @@ -0,0 +1,391 @@
2555 +/*
2556 + * Broadcom device-specific manifest constants.
2557 + *
2558 + * Copyright 2005, Broadcom Corporation
2559 + * All Rights Reserved.
2560 + *
2561 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
2562 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
2563 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
2564 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
2565 + * $Id$
2566 + */
2567 +
2568 +#ifndef _BCMDEVS_H
2569 +#define _BCMDEVS_H
2570 +
2571 +
2572 +/* Known PCI vendor Id's */
2573 +#define VENDOR_EPIGRAM 0xfeda
2574 +#define VENDOR_BROADCOM 0x14e4
2575 +#define VENDOR_3COM 0x10b7
2576 +#define VENDOR_NETGEAR 0x1385
2577 +#define VENDOR_DIAMOND 0x1092
2578 +#define VENDOR_DELL 0x1028
2579 +#define VENDOR_HP 0x0e11
2580 +#define VENDOR_APPLE 0x106b
2581 +
2582 +/* PCI Device Id's */
2583 +#define BCM4210_DEVICE_ID 0x1072 /* never used */
2584 +#define BCM4211_DEVICE_ID 0x4211
2585 +#define BCM4230_DEVICE_ID 0x1086 /* never used */
2586 +#define BCM4231_DEVICE_ID 0x4231
2587 +
2588 +#define BCM4410_DEVICE_ID 0x4410 /* bcm44xx family pci iline */
2589 +#define BCM4430_DEVICE_ID 0x4430 /* bcm44xx family cardbus iline */
2590 +#define BCM4412_DEVICE_ID 0x4412 /* bcm44xx family pci enet */
2591 +#define BCM4432_DEVICE_ID 0x4432 /* bcm44xx family cardbus enet */
2592 +
2593 +#define BCM3352_DEVICE_ID 0x3352 /* bcm3352 device id */
2594 +#define BCM3360_DEVICE_ID 0x3360 /* bcm3360 device id */
2595 +
2596 +#define EPI41210_DEVICE_ID 0xa0fa /* bcm4210 */
2597 +#define EPI41230_DEVICE_ID 0xa10e /* bcm4230 */
2598 +
2599 +#define BCM47XX_ILINE_ID 0x4711 /* 47xx iline20 */
2600 +#define BCM47XX_V90_ID 0x4712 /* 47xx v90 codec */
2601 +#define BCM47XX_ENET_ID 0x4713 /* 47xx enet */
2602 +#define BCM47XX_EXT_ID 0x4714 /* 47xx external i/f */
2603 +#define BCM47XX_USB_ID 0x4715 /* 47xx usb */
2604 +#define BCM47XX_USBH_ID 0x4716 /* 47xx usb host */
2605 +#define BCM47XX_USBD_ID 0x4717 /* 47xx usb device */
2606 +#define BCM47XX_IPSEC_ID 0x4718 /* 47xx ipsec */
2607 +#define BCM47XX_ROBO_ID 0x4719 /* 47xx/53xx roboswitch core */
2608 +#define BCM47XX_USB20H_ID 0x471a /* 47xx usb 2.0 host */
2609 +#define BCM47XX_USB20D_ID 0x471b /* 47xx usb 2.0 device */
2610 +
2611 +#define BCM4710_DEVICE_ID 0x4710 /* 4710 primary function 0 */
2612 +
2613 +#define BCM4610_DEVICE_ID 0x4610 /* 4610 primary function 0 */
2614 +#define BCM4610_ILINE_ID 0x4611 /* 4610 iline100 */
2615 +#define BCM4610_V90_ID 0x4612 /* 4610 v90 codec */
2616 +#define BCM4610_ENET_ID 0x4613 /* 4610 enet */
2617 +#define BCM4610_EXT_ID 0x4614 /* 4610 external i/f */
2618 +#define BCM4610_USB_ID 0x4615 /* 4610 usb */
2619 +
2620 +#define BCM4402_DEVICE_ID 0x4402 /* 4402 primary function 0 */
2621 +#define BCM4402_ENET_ID 0x4402 /* 4402 enet */
2622 +#define BCM4402_V90_ID 0x4403 /* 4402 v90 codec */
2623 +#define BCM4401_ENET_ID 0x170c /* 4401b0 production enet cards */
2624 +
2625 +#define BCM4301_DEVICE_ID 0x4301 /* 4301 primary function 0 */
2626 +#define BCM4301_D11B_ID 0x4301 /* 4301 802.11b */
2627 +
2628 +#define BCM4307_DEVICE_ID 0x4307 /* 4307 primary function 0 */
2629 +#define BCM4307_V90_ID 0x4305 /* 4307 v90 codec */
2630 +#define BCM4307_ENET_ID 0x4306 /* 4307 enet */
2631 +#define BCM4307_D11B_ID 0x4307 /* 4307 802.11b */
2632 +
2633 +#define BCM4306_DEVICE_ID 0x4306 /* 4306 chipcommon chipid */
2634 +#define BCM4306_D11G_ID 0x4320 /* 4306 802.11g */
2635 +#define BCM4306_D11G_ID2 0x4325
2636 +#define BCM4306_D11A_ID 0x4321 /* 4306 802.11a */
2637 +#define BCM4306_UART_ID 0x4322 /* 4306 uart */
2638 +#define BCM4306_V90_ID 0x4323 /* 4306 v90 codec */
2639 +#define BCM4306_D11DUAL_ID 0x4324 /* 4306 dual A+B */
2640 +
2641 +#define BCM4309_PKG_ID 1 /* 4309 package id */
2642 +
2643 +#define BCM4303_D11B_ID 0x4303 /* 4303 802.11b */
2644 +#define BCM4303_PKG_ID 2 /* 4303 package id */
2645 +
2646 +#define BCM4310_DEVICE_ID 0x4310 /* 4310 chipcommon chipid */
2647 +#define BCM4310_D11B_ID 0x4311 /* 4310 802.11b */
2648 +#define BCM4310_UART_ID 0x4312 /* 4310 uart */
2649 +#define BCM4310_ENET_ID 0x4313 /* 4310 enet */
2650 +#define BCM4310_USB_ID 0x4315 /* 4310 usb */
2651 +
2652 +#define BCMGPRS_UART_ID 0x4333 /* Uart id used by 4306/gprs card */
2653 +#define BCMGPRS2_UART_ID 0x4344 /* Uart id used by 4306/gprs card */
2654 +
2655 +
2656 +#define BCM4704_DEVICE_ID 0x4704 /* 4704 chipcommon chipid */
2657 +#define BCM4704_ENET_ID 0x4706 /* 4704 enet (Use 47XX_ENET_ID instead!) */
2658 +
2659 +#define BCM4317_DEVICE_ID 0x4317 /* 4317 chip common chipid */
2660 +
2661 +#define BCM4318_DEVICE_ID 0x4318 /* 4318 chip common chipid */
2662 +#define BCM4318_D11G_ID 0x4318 /* 4318 801.11b/g id */
2663 +#define BCM4318_D11DUAL_ID 0x4319 /* 4318 801.11a/b/g id */
2664 +#define BCM4318_JTAGM_ID 0x4331 /* 4318 jtagm device id */
2665 +
2666 +#define FPGA_JTAGM_ID 0x4330 /* ??? */
2667 +
2668 +/* Address map */
2669 +#define BCM4710_SDRAM 0x00000000 /* Physical SDRAM */
2670 +#define BCM4710_PCI_MEM 0x08000000 /* Host Mode PCI memory access space (64 MB) */
2671 +#define BCM4710_PCI_CFG 0x0c000000 /* Host Mode PCI configuration space (64 MB) */
2672 +#define BCM4710_PCI_DMA 0x40000000 /* Client Mode PCI memory access space (1 GB) */
2673 +#define BCM4710_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */
2674 +#define BCM4710_ENUM 0x18000000 /* Beginning of core enumeration space */
2675 +
2676 +/* Core register space */
2677 +#define BCM4710_REG_SDRAM 0x18000000 /* SDRAM core registers */
2678 +#define BCM4710_REG_ILINE20 0x18001000 /* InsideLine20 core registers */
2679 +#define BCM4710_REG_EMAC0 0x18002000 /* Ethernet MAC 0 core registers */
2680 +#define BCM4710_REG_CODEC 0x18003000 /* Codec core registers */
2681 +#define BCM4710_REG_USB 0x18004000 /* USB core registers */
2682 +#define BCM4710_REG_PCI 0x18005000 /* PCI core registers */
2683 +#define BCM4710_REG_MIPS 0x18006000 /* MIPS core registers */
2684 +#define BCM4710_REG_EXTIF 0x18007000 /* External Interface core registers */
2685 +#define BCM4710_REG_EMAC1 0x18008000 /* Ethernet MAC 1 core registers */
2686 +
2687 +#define BCM4710_EXTIF 0x1f000000 /* External Interface base address */
2688 +#define BCM4710_PCMCIA_MEM 0x1f000000 /* External Interface PCMCIA memory access */
2689 +#define BCM4710_PCMCIA_IO 0x1f100000 /* PCMCIA I/O access */
2690 +#define BCM4710_PCMCIA_CONF 0x1f200000 /* PCMCIA configuration */
2691 +#define BCM4710_PROG 0x1f800000 /* Programable interface */
2692 +#define BCM4710_FLASH 0x1fc00000 /* Flash */
2693 +
2694 +#define BCM4710_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */
2695 +
2696 +#define BCM4710_UART (BCM4710_REG_EXTIF + 0x00000300)
2697 +
2698 +#define BCM4710_EUART (BCM4710_EXTIF + 0x00800000)
2699 +#define BCM4710_LED (BCM4710_EXTIF + 0x00900000)
2700 +
2701 +#define BCM4712_DEVICE_ID 0x4712 /* 4712 chipcommon chipid */
2702 +#define BCM4712_MIPS_ID 0x4720 /* 4712 base devid */
2703 +#define BCM4712LARGE_PKG_ID 0 /* 340pin 4712 package id */
2704 +#define BCM4712SMALL_PKG_ID 1 /* 200pin 4712 package id */
2705 +#define BCM4712MID_PKG_ID 2 /* 225pin 4712 package id */
2706 +
2707 +#define SDIOH_FPGA_ID 0x4380 /* sdio host fpga */
2708 +
2709 +#define BCM5365_DEVICE_ID 0x5365 /* 5365 chipcommon chipid */
2710 +#define BCM5350_DEVICE_ID 0x5350 /* bcm5350 chipcommon chipid */
2711 +#define BCM5352_DEVICE_ID 0x5352 /* bcm5352 chipcommon chipid */
2712 +
2713 +#define BCM4320_DEVICE_ID 0x4320 /* bcm4320 chipcommon chipid */
2714 +
2715 +/* PCMCIA vendor Id's */
2716 +
2717 +#define VENDOR_BROADCOM_PCMCIA 0x02d0
2718 +
2719 +/* SDIO vendor Id's */
2720 +#define VENDOR_BROADCOM_SDIO 0x00BF
2721 +
2722 +
2723 +/* boardflags */
2724 +#define BFL_BTCOEXIST 0x0001 /* This board implements Bluetooth coexistance */
2725 +#define BFL_PACTRL 0x0002 /* This board has gpio 9 controlling the PA */
2726 +#define BFL_AIRLINEMODE 0x0004 /* This board implements gpio13 radio disable indication */
2727 +#define BFL_ENETROBO 0x0010 /* This board has robo switch or core */
2728 +#define BFL_CCKHIPWR 0x0040 /* Can do high-power CCK transmission */
2729 +#define BFL_ENETADM 0x0080 /* This board has ADMtek switch */
2730 +#define BFL_ENETVLAN 0x0100 /* This board has vlan capability */
2731 +#define BFL_AFTERBURNER 0x0200 /* This board supports Afterburner mode */
2732 +#define BFL_NOPCI 0x0400 /* This board leaves PCI floating */
2733 +#define BFL_FEM 0x0800 /* This board supports the Front End Module */
2734 +#define BFL_EXTLNA 0x1000 /* This board has an external LNA */
2735 +#define BFL_HGPA 0x2000 /* This board has a high gain PA */
2736 +#define BFL_BTCMOD 0x4000 /* This board' BTCOEXIST is in the alternate gpios */
2737 +#define BFL_ALTIQ 0x8000 /* Alternate I/Q settings */
2738 +
2739 +/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */
2740 +#define BOARD_GPIO_HWRAD_B 0x010 /* bit 4 is HWRAD input on 4301 */
2741 +#define BOARD_GPIO_BTCMOD_IN 0x010 /* bit 4 is the alternate BT Coexistance Input */
2742 +#define BOARD_GPIO_BTCMOD_OUT 0x020 /* bit 5 is the alternate BT Coexistance Out */
2743 +#define BOARD_GPIO_BTC_IN 0x080 /* bit 7 is BT Coexistance Input */
2744 +#define BOARD_GPIO_BTC_OUT 0x100 /* bit 8 is BT Coexistance Out */
2745 +#define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */
2746 +#define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */
2747 +#define PCI_CFG_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */
2748 +#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */
2749 +#define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */
2750 +
2751 +/* Bus types */
2752 +#define SB_BUS 0 /* Silicon Backplane */
2753 +#define PCI_BUS 1 /* PCI target */
2754 +#define PCMCIA_BUS 2 /* PCMCIA target */
2755 +#define SDIO_BUS 3 /* SDIO target */
2756 +#define JTAG_BUS 4 /* JTAG */
2757 +
2758 +/* Allows optimization for single-bus support */
2759 +#ifdef BCMBUSTYPE
2760 +#define BUSTYPE(bus) (BCMBUSTYPE)
2761 +#else
2762 +#define BUSTYPE(bus) (bus)
2763 +#endif
2764 +
2765 +/* power control defines */
2766 +#define PLL_DELAY 150 /* us pll on delay */
2767 +#define FREF_DELAY 200 /* us fref change delay */
2768 +#define MIN_SLOW_CLK 32 /* us Slow clock period */
2769 +#define XTAL_ON_DELAY 1000 /* us crystal power-on delay */
2770 +
2771 +/* Reference Board Types */
2772 +
2773 +#define BU4710_BOARD 0x0400
2774 +#define VSIM4710_BOARD 0x0401
2775 +#define QT4710_BOARD 0x0402
2776 +
2777 +#define BU4610_BOARD 0x0403
2778 +#define VSIM4610_BOARD 0x0404
2779 +
2780 +#define BU4307_BOARD 0x0405
2781 +#define BCM94301CB_BOARD 0x0406
2782 +#define BCM94301PC_BOARD 0x0406 /* Pcmcia 5v card */
2783 +#define BCM94301MP_BOARD 0x0407
2784 +#define BCM94307MP_BOARD 0x0408
2785 +#define BCMAP4307_BOARD 0x0409
2786 +
2787 +#define BU4309_BOARD 0x040a
2788 +#define BCM94309CB_BOARD 0x040b
2789 +#define BCM94309MP_BOARD 0x040c
2790 +#define BCM4309AP_BOARD 0x040d
2791 +
2792 +#define BCM94302MP_BOARD 0x040e
2793 +
2794 +#define VSIM4310_BOARD 0x040f
2795 +#define BU4711_BOARD 0x0410
2796 +#define BCM94310U_BOARD 0x0411
2797 +#define BCM94310AP_BOARD 0x0412
2798 +#define BCM94310MP_BOARD 0x0414
2799 +
2800 +#define BU4306_BOARD 0x0416
2801 +#define BCM94306CB_BOARD 0x0417
2802 +#define BCM94306MP_BOARD 0x0418
2803 +
2804 +#define BCM94710D_BOARD 0x041a
2805 +#define BCM94710R1_BOARD 0x041b
2806 +#define BCM94710R4_BOARD 0x041c
2807 +#define BCM94710AP_BOARD 0x041d
2808 +
2809 +
2810 +#define BU2050_BOARD 0x041f
2811 +
2812 +
2813 +#define BCM94309G_BOARD 0x0421
2814 +
2815 +#define BCM94301PC3_BOARD 0x0422 /* Pcmcia 3.3v card */
2816 +
2817 +#define BU4704_BOARD 0x0423
2818 +#define BU4702_BOARD 0x0424
2819 +
2820 +#define BCM94306PC_BOARD 0x0425 /* pcmcia 3.3v 4306 card */
2821 +
2822 +#define BU4317_BOARD 0x0426
2823 +
2824 +
2825 +#define BCM94702MN_BOARD 0x0428
2826 +
2827 +/* BCM4702 1U CompactPCI Board */
2828 +#define BCM94702CPCI_BOARD 0x0429
2829 +
2830 +/* BCM4702 with BCM95380 VLAN Router */
2831 +#define BCM95380RR_BOARD 0x042a
2832 +
2833 +/* cb4306 with SiGe PA */
2834 +#define BCM94306CBSG_BOARD 0x042b
2835 +
2836 +/* mp4301 with 2050 radio */
2837 +#define BCM94301MPL_BOARD 0x042c
2838 +
2839 +/* cb4306 with SiGe PA */
2840 +#define PCSG94306_BOARD 0x042d
2841 +
2842 +/* bu4704 with sdram */
2843 +#define BU4704SD_BOARD 0x042e
2844 +
2845 +/* Dual 11a/11g Router */
2846 +#define BCM94704AGR_BOARD 0x042f
2847 +
2848 +/* 11a-only minipci */
2849 +#define BCM94308MP_BOARD 0x0430
2850 +
2851 +
2852 +
2853 +/* BCM94317 boards */
2854 +#define BCM94317CB_BOARD 0x0440
2855 +#define BCM94317MP_BOARD 0x0441
2856 +#define BCM94317PCMCIA_BOARD 0x0442
2857 +#define BCM94317SDIO_BOARD 0x0443
2858 +
2859 +#define BU4712_BOARD 0x0444
2860 +#define BU4712SD_BOARD 0x045d
2861 +#define BU4712L_BOARD 0x045f
2862 +
2863 +/* BCM4712 boards */
2864 +#define BCM94712AP_BOARD 0x0445
2865 +#define BCM94712P_BOARD 0x0446
2866 +
2867 +/* BCM4318 boards */
2868 +#define BU4318_BOARD 0x0447
2869 +#define CB4318_BOARD 0x0448
2870 +#define MPG4318_BOARD 0x0449
2871 +#define MP4318_BOARD 0x044a
2872 +#define SD4318_BOARD 0x044b
2873 +
2874 +/* BCM63XX boards */
2875 +#define BCM96338_BOARD 0x6338
2876 +#define BCM96345_BOARD 0x6345
2877 +#define BCM96348_BOARD 0x6348
2878 +
2879 +/* Another mp4306 with SiGe */
2880 +#define BCM94306P_BOARD 0x044c
2881 +
2882 +/* CF-like 4317 modules */
2883 +#define BCM94317CF_BOARD 0x044d
2884 +
2885 +/* mp4303 */
2886 +#define BCM94303MP_BOARD 0x044e
2887 +
2888 +/* mpsgh4306 */
2889 +#define BCM94306MPSGH_BOARD 0x044f
2890 +
2891 +/* BRCM 4306 w/ Front End Modules */
2892 +#define BCM94306MPM 0x0450
2893 +#define BCM94306MPL 0x0453
2894 +
2895 +/* 4712agr */
2896 +#define BCM94712AGR_BOARD 0x0451
2897 +
2898 +/* The real CF 4317 board */
2899 +#define CFI4317_BOARD 0x0452
2900 +
2901 +/* pcmcia 4303 */
2902 +#define PC4303_BOARD 0x0454
2903 +
2904 +/* 5350K */
2905 +#define BCM95350K_BOARD 0x0455
2906 +
2907 +/* 5350R */
2908 +#define BCM95350R_BOARD 0x0456
2909 +
2910 +/* 4306mplna */
2911 +#define BCM94306MPLNA_BOARD 0x0457
2912 +
2913 +/* 4320 boards */
2914 +#define BU4320_BOARD 0x0458
2915 +#define BU4320S_BOARD 0x0459
2916 +#define BCM94320PH_BOARD 0x045a
2917 +
2918 +/* 4306mph */
2919 +#define BCM94306MPH_BOARD 0x045b
2920 +
2921 +/* 4306pciv */
2922 +#define BCM94306PCIV_BOARD 0x045c
2923 +
2924 +#define BU4712SD_BOARD 0x045d
2925 +
2926 +#define BCM94320PFLSH_BOARD 0x045e
2927 +
2928 +#define BU4712L_BOARD 0x045f
2929 +#define BCM94712LGR_BOARD 0x0460
2930 +#define BCM94320R_BOARD 0x0461
2931 +
2932 +#define BU5352_BOARD 0x0462
2933 +
2934 +#define BCM94318MPGH_BOARD 0x0463
2935 +
2936 +
2937 +#define BCM95352GR_BOARD 0x0467
2938 +
2939 +/* bcm95351agr */
2940 +#define BCM95351AGR_BOARD 0x0470
2941 +
2942 +/* # of GPIO pins */
2943 +#define GPIO_NUMPINS 16
2944 +
2945 +#endif /* _BCMDEVS_H */
2946 diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm947xx/include/bcmdevs.h
2947 --- linux.old/arch/mips/bcm947xx/include/bcmdevs.h 1970-01-01 01:00:00.000000000 +0100
2948 +++ linux.dev/arch/mips/bcm947xx/include/bcmdevs.h 2006-10-02 21:19:59.000000000 +0200
2949 @@ -0,0 +1,369 @@
2950 +/*
2951 + * Broadcom device-specific manifest constants.
2952 + *
2953 + * Copyright 2006, Broadcom Corporation
2954 + * All Rights Reserved.
2955 + *
2956 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
2957 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
2958 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
2959 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
2960 + * $Id: bcmdevs.h,v 1.1.1.17 2006/04/15 01:29:08 michael Exp $
2961 + */
2962 +
2963 +#ifndef _BCMDEVS_H
2964 +#define _BCMDEVS_H
2965 +
2966 +#include "bcm4710.h"
2967 +
2968 +/* Known PCI vendor Id's */
2969 +#define VENDOR_EPIGRAM 0xfeda
2970 +#define VENDOR_BROADCOM 0x14e4
2971 +#define VENDOR_3COM 0x10b7
2972 +#define VENDOR_NETGEAR 0x1385
2973 +#define VENDOR_DIAMOND 0x1092
2974 +#define VENDOR_DELL 0x1028
2975 +#define VENDOR_HP 0x0e11
2976 +#define VENDOR_APPLE 0x106b
2977 +
2978 +/* PCI Device Id's */
2979 +#define BCM4210_DEVICE_ID 0x1072 /* never used */
2980 +#define BCM4211_DEVICE_ID 0x4211
2981 +#define BCM4230_DEVICE_ID 0x1086 /* never used */
2982 +#define BCM4231_DEVICE_ID 0x4231
2983 +
2984 +#define BCM4410_DEVICE_ID 0x4410 /* bcm44xx family pci iline */
2985 +#define BCM4430_DEVICE_ID 0x4430 /* bcm44xx family cardbus iline */
2986 +#define BCM4412_DEVICE_ID 0x4412 /* bcm44xx family pci enet */
2987 +#define BCM4432_DEVICE_ID 0x4432 /* bcm44xx family cardbus enet */
2988 +
2989 +#define BCM3352_DEVICE_ID 0x3352 /* bcm3352 device id */
2990 +#define BCM3360_DEVICE_ID 0x3360 /* bcm3360 device id */
2991 +
2992 +#define EPI41210_DEVICE_ID 0xa0fa /* bcm4210 */
2993 +#define EPI41230_DEVICE_ID 0xa10e /* bcm4230 */
2994 +
2995 +#define BCM47XX_ILINE_ID 0x4711 /* 47xx iline20 */
2996 +#define BCM47XX_V90_ID 0x4712 /* 47xx v90 codec */
2997 +#define BCM47XX_ENET_ID 0x4713 /* 47xx enet */
2998 +#define BCM47XX_EXT_ID 0x4714 /* 47xx external i/f */
2999 +#define BCM47XX_USB_ID 0x4715 /* 47xx usb */
3000 +#define BCM47XX_USBH_ID 0x4716 /* 47xx usb host */
3001 +#define BCM47XX_USBD_ID 0x4717 /* 47xx usb device */
3002 +#define BCM47XX_IPSEC_ID 0x4718 /* 47xx ipsec */
3003 +#define BCM47XX_ROBO_ID 0x4719 /* 47xx/53xx roboswitch core */
3004 +#define BCM47XX_USB20H_ID 0x471a /* 47xx usb 2.0 host */
3005 +#define BCM47XX_USB20D_ID 0x471b /* 47xx usb 2.0 device */
3006 +#define BCM47XX_ATA100_ID 0x471d /* 47xx parallel ATA */
3007 +#define BCM47XX_SATAXOR_ID 0x471e /* 47xx serial ATA & XOR DMA */
3008 +#define BCM47XX_GIGETH_ID 0x471f /* 47xx GbE (5700) */
3009 +
3010 +#define BCM47XX_SMBUS_EMU_ID 0x47fe /* 47xx emulated SMBus device */
3011 +#define BCM47XX_XOR_EMU_ID 0x47ff /* 47xx emulated XOR engine */
3012 +
3013 +#define BCM4710_CHIP_ID 0x4710 /* 4710 chipid returned by sb_chip() */
3014 +#define BCM4710_DEVICE_ID 0x4710 /* 4710 primary function 0 */
3015 +
3016 +#define BCM4402_CHIP_ID 0x4402 /* 4402 chipid */
3017 +#define BCM4402_ENET_ID 0x4402 /* 4402 enet */
3018 +#define BCM4402_V90_ID 0x4403 /* 4402 v90 codec */
3019 +#define BCM4401_ENET_ID 0x170c /* 4401b0 production enet cards */
3020 +
3021 +#define BCM4306_CHIP_ID 0x4306 /* 4306 chipcommon chipid */
3022 +#define BCM4306_D11G_ID 0x4320 /* 4306 802.11g */
3023 +#define BCM4306_D11G_ID2 0x4325
3024 +#define BCM4306_D11A_ID 0x4321 /* 4306 802.11a */
3025 +#define BCM4306_UART_ID 0x4322 /* 4306 uart */
3026 +#define BCM4306_V90_ID 0x4323 /* 4306 v90 codec */
3027 +#define BCM4306_D11DUAL_ID 0x4324 /* 4306 dual A+B */
3028 +
3029 +#define BCM4309_PKG_ID 1 /* 4309 package id */
3030 +
3031 +#define BCM4311_CHIP_ID 0x4311 /* 4311 PCIe 802.11a/b/g */
3032 +#define BCM4311_D11G_ID 0x4311 /* 4311 802.11b/g id */
3033 +#define BCM4311_D11DUAL_ID 0x4312 /* 4311 802.11a/b/g id */
3034 +#define BCM4311_D11A_ID 0x4313 /* 4311 802.11a id */
3035 +
3036 +#define BCM4303_D11B_ID 0x4303 /* 4303 802.11b */
3037 +#define BCM4303_PKG_ID 2 /* 4303 package id */
3038 +
3039 +#define BCMGPRS_UART_ID 0x4333 /* Uart id used by 4306/gprs card */
3040 +#define BCMGPRS2_UART_ID 0x4344 /* Uart id used by 4306/gprs card */
3041 +
3042 +#define BCM4704_CHIP_ID 0x4704 /* 4704 chipcommon chipid */
3043 +#define BCM4704_ENET_ID 0x4706 /* 4704 enet (Use 47XX_ENET_ID instead!) */
3044 +
3045 +#define BCM4318_CHIP_ID 0x4318 /* 4318 chip common chipid */
3046 +#define BCM4318_D11G_ID 0x4318 /* 4318 802.11b/g id */
3047 +#define BCM4318_D11DUAL_ID 0x4319 /* 4318 802.11a/b/g id */
3048 +#define BCM4318_D11A_ID 0x431a /* 4318 802.11a id */
3049 +
3050 +#define BCM4321_CHIP_ID 0x4321 /* 4321 chip common chipid */
3051 +#define BCM4321_D11N_ID 0x4328 /* 4321 802.11n dualband id */
3052 +#define BCM4321_D11N2G_ID 0x4329 /* 4321 802.11n 2.4Hgz band id */
3053 +#define BCM4321_D11N5G_ID 0x432a /* 4321 802.11n 5Ghz band id */
3054 +
3055 +#define BCM4331_CHIP_ID 0x4331 /* 4331 chip common chipid */
3056 +#define BCM4331_D11N2G_ID 0x4330 /* 4331 802.11n 2.4Ghz band id */
3057 +#define BCM4331_D11N_ID 0x4331 /* 4331 802.11n dualband id */
3058 +#define BCM4331_D11N5G_ID 0x4332 /* 4331 802.11n 5Ghz band id */
3059 +
3060 +#define HDLSIM5350_PKG_ID 1 /* HDL simulator package id for a 5350 */
3061 +#define HDLSIM_PKG_ID 14 /* HDL simulator package id */
3062 +#define HWSIM_PKG_ID 15 /* Hardware simulator package id */
3063 +
3064 +#define BCM4712_CHIP_ID 0x4712 /* 4712 chipcommon chipid */
3065 +#define BCM4712_MIPS_ID 0x4720 /* 4712 base devid */
3066 +#define BCM4712LARGE_PKG_ID 0 /* 340pin 4712 package id */
3067 +#define BCM4712SMALL_PKG_ID 1 /* 200pin 4712 package id */
3068 +#define BCM4712MID_PKG_ID 2 /* 225pin 4712 package id */
3069 +
3070 +#define BCM5365_CHIP_ID 0x5365 /* 5365 chipcommon chipid */
3071 +#define BCM5350_CHIP_ID 0x5350 /* bcm5350 chipcommon chipid */
3072 +#define BCM5352_CHIP_ID 0x5352 /* bcm5352 chipcommon chipid */
3073 +
3074 +#define BCM4320_CHIP_ID 0x4320 /* bcm4320 chipcommon chipid */
3075 +
3076 +#define BCM4328_CHIP_ID 0x4328 /* bcm4328 chipcommon chipid */
3077 +
3078 +#define FPGA_JTAGM_ID 0x43f0 /* FPGA jtagm device id */
3079 +#define BCM43XX_JTAGM_ID 0x43f1 /* 43xx jtagm device id */
3080 +#define BCM43XXOLD_JTAGM_ID 0x4331 /* 43xx old jtagm device id */
3081 +
3082 +#define SDIOH_FPGA_ID 0x43f2 /* sdio host fpga */
3083 +#define SDIOD_FPGA_ID 0x43f4 /* sdio device fpga */
3084 +
3085 +#define MIMO_FPGA_ID 0x43f8 /* FPGA mimo minimacphy device id */
3086 +
3087 +#define BCM4785_CHIP_ID 0x4785 /* 4785 chipcommon chipid */
3088 +
3089 +/* PCMCIA vendor Id's */
3090 +
3091 +#define VENDOR_BROADCOM_PCMCIA 0x02d0
3092 +
3093 +/* SDIO vendor Id's */
3094 +#define VENDOR_BROADCOM_SDIO 0x00BF
3095 +
3096 +
3097 +/* boardflags */
3098 +#define BFL_BTCOEXIST 0x0001 /* This board implements Bluetooth coexistance */
3099 +#define BFL_PACTRL 0x0002 /* This board has gpio 9 controlling the PA */
3100 +#define BFL_AIRLINEMODE 0x0004 /* This board implements gpio13 radio disable indication */
3101 +#define BFL_ENETROBO 0x0010 /* This board has robo switch or core */
3102 +#define BFL_CCKHIPWR 0x0040 /* Can do high-power CCK transmission */
3103 +#define BFL_ENETADM 0x0080 /* This board has ADMtek switch */
3104 +#define BFL_ENETVLAN 0x0100 /* This board has vlan capability */
3105 +#define BFL_AFTERBURNER 0x0200 /* This board supports Afterburner mode */
3106 +#define BFL_NOPCI 0x0400 /* This board leaves PCI floating */
3107 +#define BFL_FEM 0x0800 /* This board supports the Front End Module */
3108 +#define BFL_EXTLNA 0x1000 /* This board has an external LNA */
3109 +#define BFL_HGPA 0x2000 /* This board has a high gain PA */
3110 +#define BFL_BTCMOD 0x4000 /* This board' BTCOEXIST is in the alternate gpios */
3111 +#define BFL_ALTIQ 0x8000 /* Alternate I/Q settings */
3112 +
3113 +/* boardflags2 */
3114 +#define BFL2_RXBB_INT_REG_DIS 0x00000001 /* This board has an external rxbb regulator */
3115 +#define BFL2_SSWITCH_AVAIL 0x00000002 /* This board has a superswitch for > 2 antennas */
3116 +#define BFL2_TXPWRCTRL_EN 0x00000004 /* This board permits TX Power Control to be enabled */
3117 +
3118 +/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */
3119 +#define BOARD_GPIO_BTCMOD_IN 0x010 /* bit 4 is the alternate BT Coexistance Input */
3120 +#define BOARD_GPIO_BTCMOD_OUT 0x020 /* bit 5 is the alternate BT Coexistance Out */
3121 +#define BOARD_GPIO_BTC_IN 0x080 /* bit 7 is BT Coexistance Input */
3122 +#define BOARD_GPIO_BTC_OUT 0x100 /* bit 8 is BT Coexistance Out */
3123 +#define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */
3124 +#define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */
3125 +#define PCI_CFG_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */
3126 +#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */
3127 +#define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */
3128 +
3129 +/* power control defines */
3130 +#define PLL_DELAY 150 /* us pll on delay */
3131 +#define FREF_DELAY 200 /* us fref change delay */
3132 +#define MIN_SLOW_CLK 32 /* us Slow clock period */
3133 +#define XTAL_ON_DELAY 1000 /* us crystal power-on delay */
3134 +
3135 +/* Reference Board Types */
3136 +
3137 +#define BU4710_BOARD 0x0400
3138 +#define VSIM4710_BOARD 0x0401
3139 +#define QT4710_BOARD 0x0402
3140 +
3141 +#define BU4309_BOARD 0x040a
3142 +#define BCM94309CB_BOARD 0x040b
3143 +#define BCM94309MP_BOARD 0x040c
3144 +#define BCM4309AP_BOARD 0x040d
3145 +
3146 +#define BCM94302MP_BOARD 0x040e
3147 +
3148 +#define BU4306_BOARD 0x0416
3149 +#define BCM94306CB_BOARD 0x0417
3150 +#define BCM94306MP_BOARD 0x0418
3151 +
3152 +#define BCM94710D_BOARD 0x041a
3153 +#define BCM94710R1_BOARD 0x041b
3154 +#define BCM94710R4_BOARD 0x041c
3155 +#define BCM94710AP_BOARD 0x041d
3156 +
3157 +#define BU2050_BOARD 0x041f
3158 +
3159 +
3160 +#define BCM94309G_BOARD 0x0421
3161 +
3162 +#define BU4704_BOARD 0x0423
3163 +#define BU4702_BOARD 0x0424
3164 +
3165 +#define BCM94306PC_BOARD 0x0425 /* pcmcia 3.3v 4306 card */
3166 +
3167 +
3168 +#define BCM94702MN_BOARD 0x0428
3169 +
3170 +/* BCM4702 1U CompactPCI Board */
3171 +#define BCM94702CPCI_BOARD 0x0429
3172 +
3173 +/* BCM4702 with BCM95380 VLAN Router */
3174 +#define BCM95380RR_BOARD 0x042a
3175 +
3176 +/* cb4306 with SiGe PA */
3177 +#define BCM94306CBSG_BOARD 0x042b
3178 +
3179 +/* cb4306 with SiGe PA */
3180 +#define PCSG94306_BOARD 0x042d
3181 +
3182 +/* bu4704 with sdram */
3183 +#define BU4704SD_BOARD 0x042e
3184 +
3185 +/* Dual 11a/11g Router */
3186 +#define BCM94704AGR_BOARD 0x042f
3187 +
3188 +/* 11a-only minipci */
3189 +#define BCM94308MP_BOARD 0x0430
3190 +
3191 +
3192 +
3193 +#define BU4712_BOARD 0x0444
3194 +#define BU4712SD_BOARD 0x045d
3195 +#define BU4712L_BOARD 0x045f
3196 +
3197 +/* BCM4712 boards */
3198 +#define BCM94712AP_BOARD 0x0445
3199 +#define BCM94712P_BOARD 0x0446
3200 +
3201 +/* BCM4318 boards */
3202 +#define BU4318_BOARD 0x0447
3203 +#define CB4318_BOARD 0x0448
3204 +#define MPG4318_BOARD 0x0449
3205 +#define MP4318_BOARD 0x044a
3206 +#define SD4318_BOARD 0x044b
3207 +
3208 +/* BCM63XX boards */
3209 +#define BCM96338_BOARD 0x6338
3210 +#define BCM96348_BOARD 0x6348
3211 +
3212 +/* Another mp4306 with SiGe */
3213 +#define BCM94306P_BOARD 0x044c
3214 +
3215 +/* mp4303 */
3216 +#define BCM94303MP_BOARD 0x044e
3217 +
3218 +/* mpsgh4306 */
3219 +#define BCM94306MPSGH_BOARD 0x044f
3220 +
3221 +/* BRCM 4306 w/ Front End Modules */
3222 +#define BCM94306MPM 0x0450
3223 +#define BCM94306MPL 0x0453
3224 +
3225 +/* 4712agr */
3226 +#define BCM94712AGR_BOARD 0x0451
3227 +
3228 +/* pcmcia 4303 */
3229 +#define PC4303_BOARD 0x0454
3230 +
3231 +/* 5350K */
3232 +#define BCM95350K_BOARD 0x0455
3233 +
3234 +/* 5350R */
3235 +#define BCM95350R_BOARD 0x0456
3236 +
3237 +/* 4306mplna */
3238 +#define BCM94306MPLNA_BOARD 0x0457
3239 +
3240 +/* 4320 boards */
3241 +#define BU4320_BOARD 0x0458
3242 +#define BU4320S_BOARD 0x0459
3243 +#define BCM94320PH_BOARD 0x045a
3244 +
3245 +/* 4306mph */
3246 +#define BCM94306MPH_BOARD 0x045b
3247 +
3248 +/* 4306pciv */
3249 +#define BCM94306PCIV_BOARD 0x045c
3250 +
3251 +#define BU4712SD_BOARD 0x045d
3252 +
3253 +#define BCM94320PFLSH_BOARD 0x045e
3254 +
3255 +#define BU4712L_BOARD 0x045f
3256 +#define BCM94712LGR_BOARD 0x0460
3257 +#define BCM94320R_BOARD 0x0461
3258 +
3259 +#define BU5352_BOARD 0x0462
3260 +
3261 +#define BCM94318MPGH_BOARD 0x0463
3262 +
3263 +#define BU4311_BOARD 0x0464
3264 +#define BCM94311MC_BOARD 0x0465
3265 +#define BCM94311MCAG_BOARD 0x0466
3266 +
3267 +#define BCM95352GR_BOARD 0x0467
3268 +
3269 +/* bcm95351agr */
3270 +#define BCM95351AGR_BOARD 0x0470
3271 +
3272 +/* bcm94704mpcb */
3273 +#define BCM94704MPCB_BOARD 0x0472
3274 +
3275 +/* 4785 boards */
3276 +#define BU4785_BOARD 0x0478
3277 +
3278 +/* 4321 boards */
3279 +#define BU4321_BOARD 0x046b
3280 +#define BU4321E_BOARD 0x047c
3281 +#define MP4321_BOARD 0x046c
3282 +#define CB2_4321_BOARD 0x046d
3283 +#define MC4321_BOARD 0x046e
3284 +
3285 +/* # of GPIO pins */
3286 +#define GPIO_NUMPINS 16
3287 +
3288 +/* radio ID codes */
3289 +#define NORADIO_ID 0xe4f5
3290 +#define NORADIO_IDCODE 0x4e4f5246
3291 +
3292 +#define BCM2050_ID 0x2050
3293 +#define BCM2050_IDCODE 0x02050000
3294 +#define BCM2050A0_IDCODE 0x1205017f
3295 +#define BCM2050A1_IDCODE 0x2205017f
3296 +#define BCM2050R8_IDCODE 0x8205017f
3297 +
3298 +#define BCM2055_ID 0x2055
3299 +#define BCM2055_IDCODE 0x02055000
3300 +#define BCM2055A0_IDCODE 0x1205517f
3301 +
3302 +#define BCM2060_ID 0x2060
3303 +#define BCM2060_IDCODE 0x02060000
3304 +#define BCM2060WW_IDCODE 0x1206017f
3305 +
3306 +#define BCM2062_ID 0x2062
3307 +#define BCM2062_IDCODE 0x02062000
3308 +#define BCM2062A0_IDCODE 0x0206217f
3309 +
3310 +/* parts of an idcode: */
3311 +#define IDCODE_MFG_MASK 0x00000fff
3312 +#define IDCODE_MFG_SHIFT 0
3313 +#define IDCODE_ID_MASK 0x0ffff000
3314 +#define IDCODE_ID_SHIFT 12
3315 +#define IDCODE_REV_MASK 0xf0000000
3316 +#define IDCODE_REV_SHIFT 28
3317 +
3318 +#endif /* _BCMDEVS_H */
3319 diff -urN linux.old/arch/mips/bcm947xx/include/bcmendian.h linux.dev/arch/mips/bcm947xx/include/bcmendian.h
3320 --- linux.old/arch/mips/bcm947xx/include/bcmendian.h 1970-01-01 01:00:00.000000000 +0100
3321 +++ linux.dev/arch/mips/bcm947xx/include/bcmendian.h 2006-10-02 21:19:59.000000000 +0200
3322 @@ -0,0 +1,198 @@
3323 +/*
3324 + * local version of endian.h - byte order defines
3325 + *
3326 + * Copyright 2006, Broadcom Corporation
3327 + * All Rights Reserved.
3328 + *
3329 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
3330 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
3331 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
3332 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
3333 + *
3334 + * $Id: bcmendian.h,v 1.1.1.10 2006/02/27 03:43:16 honor Exp $
3335 +*/
3336 +
3337 +#ifndef _BCMENDIAN_H_
3338 +#define _BCMENDIAN_H_
3339 +
3340 +#include <typedefs.h>
3341 +
3342 +/* Byte swap a 16 bit value */
3343 +#define BCMSWAP16(val) \
3344 + ((uint16)(\
3345 + (((uint16)(val) & (uint16)0x00ffU) << 8) | \
3346 + (((uint16)(val) & (uint16)0xff00U) >> 8)))
3347 +
3348 +/* Byte swap a 32 bit value */
3349 +#define BCMSWAP32(val) \
3350 + ((uint32)(\
3351 + (((uint32)(val) & (uint32)0x000000ffUL) << 24) | \
3352 + (((uint32)(val) & (uint32)0x0000ff00UL) << 8) | \
3353 + (((uint32)(val) & (uint32)0x00ff0000UL) >> 8) | \
3354 + (((uint32)(val) & (uint32)0xff000000UL) >> 24)))
3355 +
3356 +/* 2 Byte swap a 32 bit value */
3357 +#define BCMSWAP32BY16(val) \
3358 + ((uint32)(\
3359 + (((uint32)(val) & (uint32)0x0000ffffUL) << 16) | \
3360 + (((uint32)(val) & (uint32)0xffff0000UL) >> 16)))
3361 +
3362 +
3363 +static INLINE uint16
3364 +bcmswap16(uint16 val)
3365 +{
3366 + return BCMSWAP16(val);
3367 +}
3368 +
3369 +static INLINE uint32
3370 +bcmswap32(uint32 val)
3371 +{
3372 + return BCMSWAP32(val);
3373 +}
3374 +
3375 +static INLINE uint32
3376 +bcmswap32by16(uint32 val)
3377 +{
3378 + return BCMSWAP32BY16(val);
3379 +}
3380 +
3381 +/* buf - start of buffer of shorts to swap */
3382 +/* len - byte length of buffer */
3383 +static INLINE void
3384 +bcmswap16_buf(uint16 *buf, uint len)
3385 +{
3386 + len = len/2;
3387 +
3388 + while (len--) {
3389 + *buf = bcmswap16(*buf);
3390 + buf++;
3391 + }
3392 +}
3393 +
3394 +#ifndef hton16
3395 +#ifndef IL_BIGENDIAN
3396 +#define HTON16(i) BCMSWAP16(i)
3397 +#define hton16(i) bcmswap16(i)
3398 +#define hton32(i) bcmswap32(i)
3399 +#define ntoh16(i) bcmswap16(i)
3400 +#define ntoh32(i) bcmswap32(i)
3401 +#define ltoh16(i) (i)
3402 +#define ltoh32(i) (i)
3403 +#define htol16(i) (i)
3404 +#define htol32(i) (i)
3405 +#else
3406 +#define HTON16(i) (i)
3407 +#define hton16(i) (i)
3408 +#define hton32(i) (i)
3409 +#define ntoh16(i) (i)
3410 +#define ntoh32(i) (i)
3411 +#define ltoh16(i) bcmswap16(i)
3412 +#define ltoh32(i) bcmswap32(i)
3413 +#define htol16(i) bcmswap16(i)
3414 +#define htol32(i) bcmswap32(i)
3415 +#endif /* IL_BIGENDIAN */
3416 +#endif /* hton16 */
3417 +
3418 +#ifndef IL_BIGENDIAN
3419 +#define ltoh16_buf(buf, i)
3420 +#define htol16_buf(buf, i)
3421 +#else
3422 +#define ltoh16_buf(buf, i) bcmswap16_buf((uint16*)buf, i)
3423 +#define htol16_buf(buf, i) bcmswap16_buf((uint16*)buf, i)
3424 +#endif /* IL_BIGENDIAN */
3425 +
3426 +/*
3427 +* store 16-bit value to unaligned little endian byte array.
3428 +*/
3429 +static INLINE void
3430 +htol16_ua_store(uint16 val, uint8 *bytes)
3431 +{
3432 + bytes[0] = val&0xff;
3433 + bytes[1] = val>>8;
3434 +}
3435 +
3436 +/*
3437 +* store 32-bit value to unaligned little endian byte array.
3438 +*/
3439 +static INLINE void
3440 +htol32_ua_store(uint32 val, uint8 *bytes)
3441 +{
3442 + bytes[0] = val&0xff;
3443 + bytes[1] = (val>>8)&0xff;
3444 + bytes[2] = (val>>16)&0xff;
3445 + bytes[3] = val>>24;
3446 +}
3447 +
3448 +/*
3449 +* store 16-bit value to unaligned network(big) endian byte array.
3450 +*/
3451 +static INLINE void
3452 +hton16_ua_store(uint16 val, uint8 *bytes)
3453 +{
3454 + bytes[1] = val&0xff;
3455 + bytes[0] = val>>8;
3456 +}
3457 +
3458 +/*
3459 +* store 32-bit value to unaligned network(big) endian byte array.
3460 +*/
3461 +static INLINE void
3462 +hton32_ua_store(uint32 val, uint8 *bytes)
3463 +{
3464 + bytes[3] = val&0xff;
3465 + bytes[2] = (val>>8)&0xff;
3466 + bytes[1] = (val>>16)&0xff;
3467 + bytes[0] = val>>24;
3468 +}
3469 +
3470 +/*
3471 +* load 16-bit value from unaligned little endian byte array.
3472 +*/
3473 +static INLINE uint16
3474 +ltoh16_ua(void *bytes)
3475 +{
3476 + return (((uint8*)bytes)[1]<<8)+((uint8 *)bytes)[0];
3477 +}
3478 +
3479 +/*
3480 +* load 32-bit value from unaligned little endian byte array.
3481 +*/
3482 +static INLINE uint32
3483 +ltoh32_ua(void *bytes)
3484 +{
3485 + return (((uint8*)bytes)[3]<<24)+(((uint8*)bytes)[2]<<16)+
3486 + (((uint8*)bytes)[1]<<8)+((uint8*)bytes)[0];
3487 +}
3488 +
3489 +/*
3490 +* load 16-bit value from unaligned big(network) endian byte array.
3491 +*/
3492 +static INLINE uint16
3493 +ntoh16_ua(void *bytes)
3494 +{
3495 + return (((uint8*)bytes)[0]<<8)+((uint8*)bytes)[1];
3496 +}
3497 +
3498 +/*
3499 +* load 32-bit value from unaligned big(network) endian byte array.
3500 +*/
3501 +static INLINE uint32
3502 +ntoh32_ua(void *bytes)
3503 +{
3504 + return (((uint8*)bytes)[0]<<24)+(((uint8*)bytes)[1]<<16)+
3505 + (((uint8*)bytes)[2]<<8)+((uint8*)bytes)[3];
3506 +}
3507 +
3508 +#define ltoh_ua(ptr) (\
3509 + sizeof(*(ptr)) == sizeof(uint8) ? *(uint8 *)ptr : \
3510 + sizeof(*(ptr)) == sizeof(uint16) ? (((uint8 *)ptr)[1]<<8)+((uint8 *)ptr)[0] : \
3511 + (((uint8 *)ptr)[3]<<24)+(((uint8 *)ptr)[2]<<16)+(((uint8 *)ptr)[1]<<8)+((uint8 *)ptr)[0] \
3512 +)
3513 +
3514 +#define ntoh_ua(ptr) (\
3515 + sizeof(*(ptr)) == sizeof(uint8) ? *(uint8 *)ptr : \
3516 + sizeof(*(ptr)) == sizeof(uint16) ? (((uint8 *)ptr)[0]<<8)+((uint8 *)ptr)[1] : \
3517 + (((uint8 *)ptr)[0]<<24)+(((uint8 *)ptr)[1]<<16)+(((uint8 *)ptr)[2]<<8)+((uint8 *)ptr)[3] \
3518 +)
3519 +
3520 +#endif /* _BCMENDIAN_H_ */
3521 diff -urN linux.old/arch/mips/bcm947xx/include/bcmnvram.h linux.dev/arch/mips/bcm947xx/include/bcmnvram.h
3522 --- linux.old/arch/mips/bcm947xx/include/bcmnvram.h 1970-01-01 01:00:00.000000000 +0100
3523 +++ linux.dev/arch/mips/bcm947xx/include/bcmnvram.h 2006-10-02 21:19:59.000000000 +0200
3524 @@ -0,0 +1,159 @@
3525 +/*
3526 + * NVRAM variable manipulation
3527 + *
3528 + * Copyright 2006, Broadcom Corporation
3529 + * All Rights Reserved.
3530 + *
3531 + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
3532 + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
3533 + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
3534 + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
3535 + *
3536 + * $Id: bcmnvram.h,v 1.17 2006/03/02 12:33:44 honor Exp $
3537 + */
3538 +
3539 +#ifndef _bcmnvram_h_
3540 +#define _bcmnvram_h_
3541 +
3542 +#ifndef _LANGUAGE_ASSEMBLY
3543 +
3544 +#include <typedefs.h>
3545 +#include <bcmdefs.h>
3546 +
3547 +struct nvram_header {
3548 + uint32 magic;
3549 + uint32 len;
3550 + uint32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
3551 + uint32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */
3552 + uint32 config_ncdl; /* ncdl values for memc */
3553 +};
3554 +
3555 +struct nvram_tuple {
3556 + char *name;
3557 + char *value;
3558 + struct nvram_tuple *next;
3559 +};
3560 +
3561 +/*
3562 + * Initialize NVRAM access. May be unnecessary or undefined on certain
3563 + * platforms.
3564 + */
3565 +extern int nvram_init(void *sbh);
3566 +
3567 +/*
3568 + * Disable NVRAM access. May be unnecessary or undefined on certain
3569 + * platforms.
3570 + */
3571 +extern void nvram_exit(void *sbh);
3572 +
3573 +/*
3574 + * Get the value of an NVRAM variable. The pointer returned may be
3575 + * invalid after a set.
3576 + * @param name name of variable to get
3577 + * @return value of variable or NULL if undefined
3578 + */
3579 +extern char * nvram_get(const char *name);
3580 +
3581 +/*
3582 + * Read the reset GPIO value from the nvram and set the GPIO
3583 + * as input
3584 + */
3585 +extern int BCMINITFN(nvram_resetgpio_init)(void *sbh);
3586 +extern int BCMINITFN(nvram_gpio_init)(const char *name, void *sbh);
3587 +extern int BCMINITFN(nvram_gpio_set)(const char *name, void *sbh, int type);
3588 +
3589 +/*
3590 + * Get the value of an NVRAM variable.
3591 + * @param name name of variable to get
3592 + * @return value of variable or NUL if undefined
3593 + */
3594 +#define nvram_safe_get(name) (nvram_get(name) ? : "")
3595 +
3596 +#define nvram_safe_unset(name) ({ \
3597 + if(nvram_get(name)) \
3598 + nvram_unset(name); \
3599 +})
3600 +
3601 +#define nvram_safe_set(name, value) ({ \
3602 + if(!nvram_get(name) || strcmp(nvram_get(name), value)) \
3603 + nvram_set(name, value); \
3604 +})
3605 +
3606 +/*
3607 + * Match an NVRAM variable.
3608 + * @param name name of variable to match
3609 + * @param match value to compare against value of variable
3610 + * @return TRUE if variable is defined and its value is string equal
3611 + * to match or FALSE otherwise
3612 + */
3613 +static INLINE int
3614 +nvram_match(char *name, char *match) {
3615 + const char *value = nvram_get(name);
3616 + return (value && !strcmp(value, match));
3617 +}
3618 +
3619 +/*
3620 + * Inversely match an NVRAM variable.
3621 + * @param name name of variable to match
3622 + * @param match value to compare against value of variable
3623 + * @return TRUE if variable is defined and its value is not string
3624 + * equal to invmatch or FALSE otherwise
3625 + */
3626 +static INLINE int
3627 +nvram_invmatch(char *name, char *invmatch) {
3628 + const char *value = nvram_get(name);
3629 + return (value && strcmp(value, invmatch));
3630 +}
3631 +
3632 +/*