diff options
author | Rafał Miłecki <zajec5@gmail.com> | 2014-07-15 10:54:47 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-07-18 13:45:24 -0400 |
commit | d8aef3239e7d6a1bd550014ac766e5ec11c63ea9 (patch) | |
tree | d379652b0da2e2936c3c91a8c5ec32e3d1bc567f | |
parent | 6ad59343ecd72dd3f83c4db3bcddbb0beabb4c4c (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.c | 41 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmsmac/main.c | 37 |
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 | ||
204 | static 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 | |||
204 | static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) | 221 | static 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 | ||
4710 | static 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 | |||
4745 | static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc) | 4710 | static 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 | ||