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>
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c
index 72bf454..a9dfb1a 100644
--- a/drivers/bcma/sprom.c
+++ b/drivers/bcma/sprom.c
@@ -201,6 +201,23 @@
SPEX(_field[7], _offset + 14, _mask, _shift); \
} while (0)
+static s8 sprom_extract_antgain(const u16 *in, u16 offset, u16 mask, u16 shift)
+{
+ u16 v;
+ u8 gain;
+
+ v = in[SPOFF(offset)];
+ gain = (v & mask) >> shift;
+ if (gain == 0xFF) {
+ gain = 8; /* If unset use 2dBm */
+ } else {
+ /* Q5.2 Fractional part is stored in 0xC0 */
+ gain = ((gain & 0xC0) >> 6) | ((gain & 0x3F) << 2);
+ }
+
+ return (s8)gain;
+}
+
static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
{
u16 v, o;
@@ -381,14 +398,22 @@
SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, ~0, 0);
/* Extract the antenna gain values. */
- SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01,
- SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
- SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01,
- SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
- SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23,
- SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
- SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23,
- SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
+ bus->sprom.antenna_gain.a0 = sprom_extract_antgain(sprom,
+ SSB_SPROM8_AGAIN01,
+ SSB_SPROM8_AGAIN0,
+ SSB_SPROM8_AGAIN0_SHIFT);
+ bus->sprom.antenna_gain.a1 = sprom_extract_antgain(sprom,
+ SSB_SPROM8_AGAIN01,
+ SSB_SPROM8_AGAIN1,
+ SSB_SPROM8_AGAIN1_SHIFT);
+ bus->sprom.antenna_gain.a2 = sprom_extract_antgain(sprom,
+ SSB_SPROM8_AGAIN23,
+ SSB_SPROM8_AGAIN2,
+ SSB_SPROM8_AGAIN2_SHIFT);
+ bus->sprom.antenna_gain.a3 = sprom_extract_antgain(sprom,
+ SSB_SPROM8_AGAIN23,
+ SSB_SPROM8_AGAIN3,
+ SSB_SPROM8_AGAIN3_SHIFT);
SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON,
SSB_SPROM8_LEDDC_ON_SHIFT);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index af8ba64..1b47482 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -4707,41 +4707,6 @@
return err;
}
-static void brcms_c_attach_antgain_init(struct brcms_c_info *wlc)
-{
- uint unit;
- unit = wlc->pub->unit;
-
- if ((wlc->band->antgain == -1) && (wlc->pub->sromrev == 1)) {
- /* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */
- wlc->band->antgain = 8;
- } else if (wlc->band->antgain == -1) {
- wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
- " srom, using 2dB\n", unit, __func__);
- wlc->band->antgain = 8;
- } else {
- s8 gain, fract;
- /* Older sroms specified gain in whole dbm only. In order
- * be able to specify qdbm granularity and remain backward
- * compatible the whole dbms are now encoded in only
- * low 6 bits and remaining qdbms are encoded in the hi 2 bits.
- * 6 bit signed number ranges from -32 - 31.
- *
- * Examples:
- * 0x1 = 1 db,
- * 0xc1 = 1.75 db (1 + 3 quarters),
- * 0x3f = -1 (-1 + 0 quarters),
- * 0x7f = -.75 (-1 + 1 quarters) = -3 qdbm.
- * 0xbf = -.50 (-1 + 2 quarters) = -2 qdbm.
- */
- gain = wlc->band->antgain & 0x3f;
- gain <<= 2; /* Sign extend */
- gain >>= 2;
- fract = (wlc->band->antgain & 0xc0) >> 6;
- wlc->band->antgain = 4 * gain + fract;
- }
-}
-
static bool brcms_c_attach_stf_ant_init(struct brcms_c_info *wlc)
{
int aa;
@@ -4780,8 +4745,6 @@
else
wlc->band->antgain = sprom->antenna_gain.a0;
- brcms_c_attach_antgain_init(wlc);
-
return true;
}