aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2014-07-15 10:54:47 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-07-18 13:45:24 -0400
commitd8aef3239e7d6a1bd550014ac766e5ec11c63ea9 (patch)
treed379652b0da2e2936c3c91a8c5ec32e3d1bc567f
parent6ad59343ecd72dd3f83c4db3bcddbb0beabb4c4c (diff)
bcma: extract antenna gains from SPROM correctly
Just like in case of SSB SPROMs they are encoded in a bit tricky way. SPROM struct already uses s8 type and it's supposed to store decoded values. Signed-off-by: Rafał Miłecki <zajec5@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/bcma/sprom.c41
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c37
2 files changed, 33 insertions, 45 deletions
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c
index 72bf4540f565..a9dfb1ac138d 100644
--- a/drivers/bcma/sprom.c
+++ b/drivers/bcma/sprom.c
@@ -201,6 +201,23 @@ static int bcma_sprom_valid(struct bcma_bus *bus, const u16 *sprom,
201 SPEX(_field[7], _offset + 14, _mask, _shift); \ 201 SPEX(_field[7], _offset + 14, _mask, _shift); \
202 } while (0) 202 } while (0)
203 203
204static s8 sprom_extract_antgain(const u16 *in, u16 offset, u16 mask, u16 shift)
205{
206 u16 v;
207 u8 gain;
208
209 v = in[SPOFF(offset)];
210 gain = (v & mask) >> shift;
211 if (gain == 0xFF) {
212 gain = 8; /* If unset use 2dBm */
213 } else {
214 /* Q5.2 Fractional part is stored in 0xC0 */
215 gain = ((gain & 0xC0) >> 6) | ((gain & 0x3F) << 2);
216 }
217
218 return (s8)gain;
219}
220
204static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) 221static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
205{ 222{
206 u16 v, o; 223 u16 v, o;
@@ -381,14 +398,22 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
381 SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, ~0, 0); 398 SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, ~0, 0);
382 399
383 /* Extract the antenna gain values. */ 400 /* Extract the antenna gain values. */
384 SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01, 401 bus->sprom.antenna_gain.a0 = sprom_extract_antgain(sprom,
385 SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT); 402 SSB_SPROM8_AGAIN01,
386 SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01, 403 SSB_SPROM8_AGAIN0,
387 SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT); 404 SSB_SPROM8_AGAIN0_SHIFT);
388 SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23, 405 bus->sprom.antenna_gain.a1 = sprom_extract_antgain(sprom,
389 SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT); 406 SSB_SPROM8_AGAIN01,
390 SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23, 407 SSB_SPROM8_AGAIN1,
391 SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT); 408 SSB_SPROM8_AGAIN1_SHIFT);
409 bus->sprom.antenna_gain.a2 = sprom_extract_antgain(sprom,
410 SSB_SPROM8_AGAIN23,
411 SSB_SPROM8_AGAIN2,
412 SSB_SPROM8_AGAIN2_SHIFT);
413 bus->sprom.antenna_gain.a3 = sprom_extract_antgain(sprom,
414 SSB_SPROM8_AGAIN23,
415 SSB_SPROM8_AGAIN3,
416 SSB_SPROM8_AGAIN3_SHIFT);
392 417
393 SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON, 418 SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON,
394 SSB_SPROM8_LEDDC_ON_SHIFT); 419 SSB_SPROM8_LEDDC_ON_SHIFT);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index af8ba64ace39..1b474828d5b8 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -4707,41 +4707,6 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
4707 return err; 4707 return err;
4708} 4708}
4709 4709
4710static void brcms_c_attach_antgain_init(struct brcms_c_info *wlc)
4711{
4712 uint unit;
4713 unit = wlc->pub->unit;
4714
4715 if ((wlc->band->antgain == -1) && (wlc->pub->sromrev == 1)) {
4716 /* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */
4717 wlc->band->antgain = 8;
4718 } else if (wlc->band->antgain == -1) {
4719 wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
4720 " srom, using 2dB\n", unit, __func__);
4721 wlc->band->antgain = 8;
4722 } else {
4723 s8 gain, fract;
4724 /* Older sroms specified gain in whole dbm only. In order
4725 * be able to specify qdbm granularity and remain backward
4726 * compatible the whole dbms are now encoded in only
4727 * low 6 bits and remaining qdbms are encoded in the hi 2 bits.
4728 * 6 bit signed number ranges from -32 - 31.
4729 *
4730 * Examples:
4731 * 0x1 = 1 db,
4732 * 0xc1 = 1.75 db (1 + 3 quarters),
4733 * 0x3f = -1 (-1 + 0 quarters),
4734 * 0x7f = -.75 (-1 + 1 quarters) = -3 qdbm.
4735 * 0xbf = -.50 (-1 + 2 quarters) = -2 qdbm.
4736 */
4737 gain = wlc->band->antgain & 0x3f;
4738 gain <<= 2; /* Sign extend */
4739 gain >>= 2;
4740 fract = (wlc->band->antgain & 0xc0) >> 6;
4741 wlc->band->antgain = 4 * gain + fract;
4742 }
4743}
4744
4745static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc) 4710static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc)
4746{ 4711{
4747 int aa; 4712 int aa;
@@ -4780,8 +4745,6 @@ static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc)
4780 else 4745 else
4781 wlc->band->antgain = sprom->antenna_gain.a0; 4746 wlc->band->antgain = sprom->antenna_gain.a0;
4782 4747
4783 brcms_c_attach_antgain_init(wlc);
4784
4785 return true; 4748 return true;
4786} 4749}
4787 4750