diff options
Diffstat (limited to 'drivers/ssb/pci.c')
-rw-r--r-- | drivers/ssb/pci.c | 113 |
1 files changed, 88 insertions, 25 deletions
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index a8dc95ebf2d6..0f28c08fcb3c 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c | |||
@@ -326,13 +326,13 @@ err_ctlreg: | |||
326 | return err; | 326 | return err; |
327 | } | 327 | } |
328 | 328 | ||
329 | static s8 r123_extract_antgain(u8 sprom_revision, const u16 *in, | 329 | static s8 sprom_extract_antgain(u8 sprom_revision, const u16 *in, u16 offset, |
330 | u16 mask, u16 shift) | 330 | u16 mask, u16 shift) |
331 | { | 331 | { |
332 | u16 v; | 332 | u16 v; |
333 | u8 gain; | 333 | u8 gain; |
334 | 334 | ||
335 | v = in[SPOFF(SSB_SPROM1_AGAIN)]; | 335 | v = in[SPOFF(offset)]; |
336 | gain = (v & mask) >> shift; | 336 | gain = (v & mask) >> shift; |
337 | if (gain == 0xFF) | 337 | if (gain == 0xFF) |
338 | gain = 2; /* If unset use 2dBm */ | 338 | gain = 2; /* If unset use 2dBm */ |
@@ -416,12 +416,14 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) | |||
416 | SPEX(alpha2[1], SSB_SPROM1_CCODE, 0x00ff, 0); | 416 | SPEX(alpha2[1], SSB_SPROM1_CCODE, 0x00ff, 0); |
417 | 417 | ||
418 | /* Extract the antenna gain values. */ | 418 | /* Extract the antenna gain values. */ |
419 | out->antenna_gain.a0 = r123_extract_antgain(out->revision, in, | 419 | out->antenna_gain.a0 = sprom_extract_antgain(out->revision, in, |
420 | SSB_SPROM1_AGAIN_BG, | 420 | SSB_SPROM1_AGAIN, |
421 | SSB_SPROM1_AGAIN_BG_SHIFT); | 421 | SSB_SPROM1_AGAIN_BG, |
422 | out->antenna_gain.a1 = r123_extract_antgain(out->revision, in, | 422 | SSB_SPROM1_AGAIN_BG_SHIFT); |
423 | SSB_SPROM1_AGAIN_A, | 423 | out->antenna_gain.a1 = sprom_extract_antgain(out->revision, in, |
424 | SSB_SPROM1_AGAIN_A_SHIFT); | 424 | SSB_SPROM1_AGAIN, |
425 | SSB_SPROM1_AGAIN_A, | ||
426 | SSB_SPROM1_AGAIN_A_SHIFT); | ||
425 | if (out->revision >= 2) | 427 | if (out->revision >= 2) |
426 | sprom_extract_r23(out, in); | 428 | sprom_extract_r23(out, in); |
427 | } | 429 | } |
@@ -468,7 +470,15 @@ static void sprom_extract_r458(struct ssb_sprom *out, const u16 *in) | |||
468 | 470 | ||
469 | static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) | 471 | static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) |
470 | { | 472 | { |
473 | static const u16 pwr_info_offset[] = { | ||
474 | SSB_SPROM4_PWR_INFO_CORE0, SSB_SPROM4_PWR_INFO_CORE1, | ||
475 | SSB_SPROM4_PWR_INFO_CORE2, SSB_SPROM4_PWR_INFO_CORE3 | ||
476 | }; | ||
471 | u16 il0mac_offset; | 477 | u16 il0mac_offset; |
478 | int i; | ||
479 | |||
480 | BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) != | ||
481 | ARRAY_SIZE(out->core_pwr_info)); | ||
472 | 482 | ||
473 | if (out->revision == 4) | 483 | if (out->revision == 4) |
474 | il0mac_offset = SSB_SPROM4_IL0MAC; | 484 | il0mac_offset = SSB_SPROM4_IL0MAC; |
@@ -524,14 +534,59 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) | |||
524 | } | 534 | } |
525 | 535 | ||
526 | /* Extract the antenna gain values. */ | 536 | /* Extract the antenna gain values. */ |
527 | SPEX(antenna_gain.a0, SSB_SPROM4_AGAIN01, | 537 | out->antenna_gain.a0 = sprom_extract_antgain(out->revision, in, |
528 | SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT); | 538 | SSB_SPROM4_AGAIN01, |
529 | SPEX(antenna_gain.a1, SSB_SPROM4_AGAIN01, | 539 | SSB_SPROM4_AGAIN0, |
530 | SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT); | 540 | SSB_SPROM4_AGAIN0_SHIFT); |
531 | SPEX(antenna_gain.a2, SSB_SPROM4_AGAIN23, | 541 | out->antenna_gain.a1 = sprom_extract_antgain(out->revision, in, |
532 | SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT); | 542 | SSB_SPROM4_AGAIN01, |
533 | SPEX(antenna_gain.a3, SSB_SPROM4_AGAIN23, | 543 | SSB_SPROM4_AGAIN1, |
534 | SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT); | 544 | SSB_SPROM4_AGAIN1_SHIFT); |
545 | out->antenna_gain.a2 = sprom_extract_antgain(out->revision, in, | ||
546 | SSB_SPROM4_AGAIN23, | ||
547 | SSB_SPROM4_AGAIN2, | ||
548 | SSB_SPROM4_AGAIN2_SHIFT); | ||
549 | out->antenna_gain.a3 = sprom_extract_antgain(out->revision, in, | ||
550 | SSB_SPROM4_AGAIN23, | ||
551 | SSB_SPROM4_AGAIN3, | ||
552 | SSB_SPROM4_AGAIN3_SHIFT); | ||
553 | |||
554 | /* Extract cores power info info */ | ||
555 | for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) { | ||
556 | u16 o = pwr_info_offset[i]; | ||
557 | |||
558 | SPEX(core_pwr_info[i].itssi_2g, o + SSB_SPROM4_2G_MAXP_ITSSI, | ||
559 | SSB_SPROM4_2G_ITSSI, SSB_SPROM4_2G_ITSSI_SHIFT); | ||
560 | SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SPROM4_2G_MAXP_ITSSI, | ||
561 | SSB_SPROM4_2G_MAXP, 0); | ||
562 | |||
563 | SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SPROM4_2G_PA_0, ~0, 0); | ||
564 | SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SPROM4_2G_PA_1, ~0, 0); | ||
565 | SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SPROM4_2G_PA_2, ~0, 0); | ||
566 | SPEX(core_pwr_info[i].pa_2g[3], o + SSB_SPROM4_2G_PA_3, ~0, 0); | ||
567 | |||
568 | SPEX(core_pwr_info[i].itssi_5g, o + SSB_SPROM4_5G_MAXP_ITSSI, | ||
569 | SSB_SPROM4_5G_ITSSI, SSB_SPROM4_5G_ITSSI_SHIFT); | ||
570 | SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SPROM4_5G_MAXP_ITSSI, | ||
571 | SSB_SPROM4_5G_MAXP, 0); | ||
572 | SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM4_5GHL_MAXP, | ||
573 | SSB_SPROM4_5GH_MAXP, 0); | ||
574 | SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM4_5GHL_MAXP, | ||
575 | SSB_SPROM4_5GL_MAXP, SSB_SPROM4_5GL_MAXP_SHIFT); | ||
576 | |||
577 | SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SPROM4_5GL_PA_0, ~0, 0); | ||
578 | SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SPROM4_5GL_PA_1, ~0, 0); | ||
579 | SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SPROM4_5GL_PA_2, ~0, 0); | ||
580 | SPEX(core_pwr_info[i].pa_5gl[3], o + SSB_SPROM4_5GL_PA_3, ~0, 0); | ||
581 | SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SPROM4_5G_PA_0, ~0, 0); | ||
582 | SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SPROM4_5G_PA_1, ~0, 0); | ||
583 | SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SPROM4_5G_PA_2, ~0, 0); | ||
584 | SPEX(core_pwr_info[i].pa_5g[3], o + SSB_SPROM4_5G_PA_3, ~0, 0); | ||
585 | SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SPROM4_5GH_PA_0, ~0, 0); | ||
586 | SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SPROM4_5GH_PA_1, ~0, 0); | ||
587 | SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SPROM4_5GH_PA_2, ~0, 0); | ||
588 | SPEX(core_pwr_info[i].pa_5gh[3], o + SSB_SPROM4_5GH_PA_3, ~0, 0); | ||
589 | } | ||
535 | 590 | ||
536 | sprom_extract_r458(out, in); | 591 | sprom_extract_r458(out, in); |
537 | 592 | ||
@@ -621,14 +676,22 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in) | |||
621 | SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0); | 676 | SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0); |
622 | 677 | ||
623 | /* Extract the antenna gain values. */ | 678 | /* Extract the antenna gain values. */ |
624 | SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01, | 679 | out->antenna_gain.a0 = sprom_extract_antgain(out->revision, in, |
625 | SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT); | 680 | SSB_SPROM8_AGAIN01, |
626 | SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01, | 681 | SSB_SPROM8_AGAIN0, |
627 | SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT); | 682 | SSB_SPROM8_AGAIN0_SHIFT); |
628 | SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23, | 683 | out->antenna_gain.a1 = sprom_extract_antgain(out->revision, in, |
629 | SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT); | 684 | SSB_SPROM8_AGAIN01, |
630 | SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23, | 685 | SSB_SPROM8_AGAIN1, |
631 | SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT); | 686 | SSB_SPROM8_AGAIN1_SHIFT); |
687 | out->antenna_gain.a2 = sprom_extract_antgain(out->revision, in, | ||
688 | SSB_SPROM8_AGAIN23, | ||
689 | SSB_SPROM8_AGAIN2, | ||
690 | SSB_SPROM8_AGAIN2_SHIFT); | ||
691 | out->antenna_gain.a3 = sprom_extract_antgain(out->revision, in, | ||
692 | SSB_SPROM8_AGAIN23, | ||
693 | SSB_SPROM8_AGAIN3, | ||
694 | SSB_SPROM8_AGAIN3_SHIFT); | ||
632 | 695 | ||
633 | /* Extract cores power info info */ | 696 | /* Extract cores power info info */ |
634 | for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) { | 697 | for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) { |