diff options
Diffstat (limited to 'drivers/ssb')
-rw-r--r-- | drivers/ssb/pci.c | 84 |
1 files changed, 49 insertions, 35 deletions
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index f883dcfffe06..d5cde051806b 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c | |||
@@ -327,11 +327,9 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) | |||
327 | s8 gain; | 327 | s8 gain; |
328 | u16 loc[3]; | 328 | u16 loc[3]; |
329 | 329 | ||
330 | if (out->revision == 3) { /* rev 3 moved MAC */ | 330 | if (out->revision == 3) /* rev 3 moved MAC */ |
331 | loc[0] = SSB_SPROM3_IL0MAC; | 331 | loc[0] = SSB_SPROM3_IL0MAC; |
332 | loc[1] = SSB_SPROM3_ET0MAC; | 332 | else { |
333 | loc[2] = SSB_SPROM3_ET1MAC; | ||
334 | } else { | ||
335 | loc[0] = SSB_SPROM1_IL0MAC; | 333 | loc[0] = SSB_SPROM1_IL0MAC; |
336 | loc[1] = SSB_SPROM1_ET0MAC; | 334 | loc[1] = SSB_SPROM1_ET0MAC; |
337 | loc[2] = SSB_SPROM1_ET1MAC; | 335 | loc[2] = SSB_SPROM1_ET1MAC; |
@@ -340,13 +338,15 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) | |||
340 | v = in[SPOFF(loc[0]) + i]; | 338 | v = in[SPOFF(loc[0]) + i]; |
341 | *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v); | 339 | *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v); |
342 | } | 340 | } |
343 | for (i = 0; i < 3; i++) { | 341 | if (out->revision < 3) { /* only rev 1-2 have et0, et1 */ |
344 | v = in[SPOFF(loc[1]) + i]; | 342 | for (i = 0; i < 3; i++) { |
345 | *(((__be16 *)out->et0mac) + i) = cpu_to_be16(v); | 343 | v = in[SPOFF(loc[1]) + i]; |
346 | } | 344 | *(((__be16 *)out->et0mac) + i) = cpu_to_be16(v); |
347 | for (i = 0; i < 3; i++) { | 345 | } |
348 | v = in[SPOFF(loc[2]) + i]; | 346 | for (i = 0; i < 3; i++) { |
349 | *(((__be16 *)out->et1mac) + i) = cpu_to_be16(v); | 347 | v = in[SPOFF(loc[2]) + i]; |
348 | *(((__be16 *)out->et1mac) + i) = cpu_to_be16(v); | ||
349 | } | ||
350 | } | 350 | } |
351 | SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0); | 351 | SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0); |
352 | SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A, | 352 | SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A, |
@@ -399,30 +399,33 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) | |||
399 | out->antenna_gain.ghz5.a3 = gain; | 399 | out->antenna_gain.ghz5.a3 = gain; |
400 | } | 400 | } |
401 | 401 | ||
402 | static void sprom_extract_r4(struct ssb_sprom *out, const u16 *in) | 402 | static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) |
403 | { | 403 | { |
404 | int i; | 404 | int i; |
405 | u16 v; | 405 | u16 v; |
406 | u16 il0mac_offset; | ||
406 | 407 | ||
407 | /* extract the equivalent of the r1 variables */ | 408 | if (out->revision == 4) |
409 | il0mac_offset = SSB_SPROM4_IL0MAC; | ||
410 | else | ||
411 | il0mac_offset = SSB_SPROM5_IL0MAC; | ||
412 | /* extract the MAC address */ | ||
408 | for (i = 0; i < 3; i++) { | 413 | for (i = 0; i < 3; i++) { |
409 | v = in[SPOFF(SSB_SPROM4_IL0MAC) + i]; | 414 | v = in[SPOFF(il0mac_offset) + i]; |
410 | *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v); | 415 | *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v); |
411 | } | 416 | } |
412 | for (i = 0; i < 3; i++) { | ||
413 | v = in[SPOFF(SSB_SPROM4_ET0MAC) + i]; | ||
414 | *(((__be16 *)out->et0mac) + i) = cpu_to_be16(v); | ||
415 | } | ||
416 | for (i = 0; i < 3; i++) { | ||
417 | v = in[SPOFF(SSB_SPROM4_ET1MAC) + i]; | ||
418 | *(((__be16 *)out->et1mac) + i) = cpu_to_be16(v); | ||
419 | } | ||
420 | SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0); | 417 | SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0); |
421 | SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A, | 418 | SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A, |
422 | SSB_SPROM4_ETHPHY_ET1A_SHIFT); | 419 | SSB_SPROM4_ETHPHY_ET1A_SHIFT); |
423 | SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0); | 420 | if (out->revision == 4) { |
424 | SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0); | 421 | SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0); |
425 | SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0); | 422 | SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0); |
423 | SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0); | ||
424 | } else { | ||
425 | SPEX(country_code, SSB_SPROM5_CCODE, 0xFFFF, 0); | ||
426 | SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0); | ||
427 | SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0); | ||
428 | } | ||
426 | SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A, | 429 | SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A, |
427 | SSB_SPROM4_ANTAVAIL_A_SHIFT); | 430 | SSB_SPROM4_ANTAVAIL_A_SHIFT); |
428 | SPEX(ant_available_bg, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_BG, | 431 | SPEX(ant_available_bg, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_BG, |
@@ -433,12 +436,21 @@ static void sprom_extract_r4(struct ssb_sprom *out, const u16 *in) | |||
433 | SPEX(maxpwr_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_MAXP_A_MASK, 0); | 436 | SPEX(maxpwr_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_MAXP_A_MASK, 0); |
434 | SPEX(itssi_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_ITSSI_A, | 437 | SPEX(itssi_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_ITSSI_A, |
435 | SSB_SPROM4_ITSSI_A_SHIFT); | 438 | SSB_SPROM4_ITSSI_A_SHIFT); |
436 | SPEX(gpio0, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P0, 0); | 439 | if (out->revision == 4) { |
437 | SPEX(gpio1, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P1, | 440 | SPEX(gpio0, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P0, 0); |
438 | SSB_SPROM4_GPIOA_P1_SHIFT); | 441 | SPEX(gpio1, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P1, |
439 | SPEX(gpio2, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P2, 0); | 442 | SSB_SPROM4_GPIOA_P1_SHIFT); |
440 | SPEX(gpio3, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P3, | 443 | SPEX(gpio2, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P2, 0); |
441 | SSB_SPROM4_GPIOB_P3_SHIFT); | 444 | SPEX(gpio3, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P3, |
445 | SSB_SPROM4_GPIOB_P3_SHIFT); | ||
446 | } else { | ||
447 | SPEX(gpio0, SSB_SPROM5_GPIOA, SSB_SPROM5_GPIOA_P0, 0); | ||
448 | SPEX(gpio1, SSB_SPROM5_GPIOA, SSB_SPROM5_GPIOA_P1, | ||
449 | SSB_SPROM5_GPIOA_P1_SHIFT); | ||
450 | SPEX(gpio2, SSB_SPROM5_GPIOB, SSB_SPROM5_GPIOB_P2, 0); | ||
451 | SPEX(gpio3, SSB_SPROM5_GPIOB, SSB_SPROM5_GPIOB_P3, | ||
452 | SSB_SPROM5_GPIOB_P3_SHIFT); | ||
453 | } | ||
442 | 454 | ||
443 | /* Extract the antenna gain values. */ | 455 | /* Extract the antenna gain values. */ |
444 | SPEX(antenna_gain.ghz24.a0, SSB_SPROM4_AGAIN01, | 456 | SPEX(antenna_gain.ghz24.a0, SSB_SPROM4_AGAIN01, |
@@ -462,6 +474,8 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out, | |||
462 | 474 | ||
463 | out->revision = in[size - 1] & 0x00FF; | 475 | out->revision = in[size - 1] & 0x00FF; |
464 | ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision); | 476 | ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision); |
477 | memset(out->et0mac, 0xFF, 6); /* preset et0 and et1 mac */ | ||
478 | memset(out->et1mac, 0xFF, 6); | ||
465 | if ((bus->chip_id & 0xFF00) == 0x4400) { | 479 | if ((bus->chip_id & 0xFF00) == 0x4400) { |
466 | /* Workaround: The BCM44XX chip has a stupid revision | 480 | /* Workaround: The BCM44XX chip has a stupid revision |
467 | * number stored in the SPROM. | 481 | * number stored in the SPROM. |
@@ -471,16 +485,16 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out, | |||
471 | } else if (bus->chip_id == 0x4321) { | 485 | } else if (bus->chip_id == 0x4321) { |
472 | /* the BCM4328 has a chipid == 0x4321 and a rev 4 SPROM */ | 486 | /* the BCM4328 has a chipid == 0x4321 and a rev 4 SPROM */ |
473 | out->revision = 4; | 487 | out->revision = 4; |
474 | sprom_extract_r4(out, in); | 488 | sprom_extract_r45(out, in); |
475 | } else { | 489 | } else { |
476 | if (out->revision == 0) | 490 | if (out->revision == 0) |
477 | goto unsupported; | 491 | goto unsupported; |
478 | if (out->revision >= 1 && out->revision <= 3) { | 492 | if (out->revision >= 1 && out->revision <= 3) { |
479 | sprom_extract_r123(out, in); | 493 | sprom_extract_r123(out, in); |
480 | } | 494 | } |
481 | if (out->revision == 4) | 495 | if (out->revision == 4 || out->revision == 5) |
482 | sprom_extract_r4(out, in); | 496 | sprom_extract_r45(out, in); |
483 | if (out->revision >= 5) | 497 | if (out->revision > 5) |
484 | goto unsupported; | 498 | goto unsupported; |
485 | } | 499 | } |
486 | 500 | ||