aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ssb/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ssb/pci.c')
-rw-r--r--drivers/ssb/pci.c113
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
329static s8 r123_extract_antgain(u8 sprom_revision, const u16 *in, 329static 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
469static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) 471static 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++) {