ssb: Fix extraction of values from SPROM
This fixes extraction of some values from the SPROM.
It mainly fixes extraction of antenna related values, which
is needed for another b43 fix sent later.
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index d7ea671..68bbe8e 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -3884,16 +3884,6 @@
if (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE &&
bus->boardinfo.type == 0x4E && bus->boardinfo.rev > 0x40)
bus->sprom.boardflags_lo |= B43_BFL_PACTRL;
-
- /* Handle case when gain is not set in sprom */
- if (bus->sprom.antenna_gain_a == 0xFF)
- bus->sprom.antenna_gain_a = 2;
- if (bus->sprom.antenna_gain_bg == 0xFF)
- bus->sprom.antenna_gain_bg = 2;
-
- /* Convert Antennagain values to Q5.2 */
- bus->sprom.antenna_gain_a <<= 2;
- bus->sprom.antenna_gain_bg <<= 2;
}
static void b43_wireless_exit(struct ssb_device *dev, struct b43_wl *wl)
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 14087fc..575fd9a 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -3572,11 +3572,6 @@
bus->boardinfo.type == 0x4E &&
bus->boardinfo.rev > 0x40)
bus->sprom.boardflags_lo |= B43legacy_BFL_PACTRL;
-
- /* Convert Antennagain values to Q5.2 */
- if (bus->sprom.antenna_gain_bg == 0xFF)
- bus->sprom.antenna_gain_bg = 2; /* if unset, use 2 dBm */
- bus->sprom.antenna_gain_bg <<= 2;
}
static void b43legacy_wireless_exit(struct ssb_device *dev,
diff --git a/drivers/net/wireless/b43legacy/phy.c b/drivers/net/wireless/b43legacy/phy.c
index 9d527e6..57c668f 100644
--- a/drivers/net/wireless/b43legacy/phy.c
+++ b/drivers/net/wireless/b43legacy/phy.c
@@ -1859,7 +1859,7 @@
* which accounts for the factor of 4 */
#define REG_MAX_PWR 20
max_pwr = min(REG_MAX_PWR * 4
- - dev->dev->bus->sprom.antenna_gain_bg
+ - dev->dev->bus->sprom.antenna_gain.ghz24.a0
- 0x6, max_pwr);
/* find the desired power in Q5.2 - power_level is in dBm
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index 9777dcb..ed2a387 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -247,7 +247,7 @@
int i;
for (i = 0; i < bus->sprom_size; i++)
- sprom[i] = readw(bus->mmio + SSB_SPROM_BASE + (i * 2));
+ sprom[i] = ioread16(bus->mmio + SSB_SPROM_BASE + (i * 2));
}
static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom)
@@ -297,10 +297,32 @@
return err;
}
+static s8 r123_extract_antgain(u8 sprom_revision, const u16 *in,
+ u16 mask, u16 shift)
+{
+ u16 v;
+ u8 gain;
+
+ v = in[SPOFF(SSB_SPROM1_AGAIN)];
+ gain = (v & mask) >> shift;
+ if (gain == 0xFF)
+ gain = 2; /* If unset use 2dBm */
+ if (sprom_revision == 1) {
+ /* Convert to Q5.2 */
+ gain <<= 2;
+ } else {
+ /* Q5.2 Fractional part is stored in 0xC0 */
+ gain = ((gain & 0xC0) >> 6) | ((gain & 0x3F) << 2);
+ }
+
+ return (s8)gain;
+}
+
static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
{
int i;
u16 v;
+ s8 gain;
u16 loc[3];
if (out->revision == 3) { /* rev 3 moved MAC */
@@ -327,8 +349,15 @@
SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0);
SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A,
SSB_SPROM1_ETHPHY_ET1A_SHIFT);
+ SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14);
+ SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15);
+ SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0);
SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE,
SSB_SPROM1_BINF_CCODE_SHIFT);
+ SPEX(ant_available_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA,
+ SSB_SPROM1_BINF_ANTA_SHIFT);
+ SPEX(ant_available_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG,
+ SSB_SPROM1_BINF_ANTBG_SHIFT);
SPEX(pa0b0, SSB_SPROM1_PA0B0, 0xFFFF, 0);
SPEX(pa0b1, SSB_SPROM1_PA0B1, 0xFFFF, 0);
SPEX(pa0b2, SSB_SPROM1_PA0B2, 0xFFFF, 0);
@@ -348,9 +377,22 @@
SSB_SPROM1_ITSSI_A_SHIFT);
SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0);
SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0);
- SPEX(antenna_gain_a, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_A, 0);
- SPEX(antenna_gain_bg, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_BG,
- SSB_SPROM1_AGAIN_BG_SHIFT);
+
+ /* Extract the antenna gain values. */
+ gain = r123_extract_antgain(out->revision, in,
+ SSB_SPROM1_AGAIN_BG,
+ SSB_SPROM1_AGAIN_BG_SHIFT);
+ out->antenna_gain.ghz24.a0 = gain;
+ out->antenna_gain.ghz24.a1 = gain;
+ out->antenna_gain.ghz24.a2 = gain;
+ out->antenna_gain.ghz24.a3 = gain;
+ gain = r123_extract_antgain(out->revision, in,
+ SSB_SPROM1_AGAIN_A,
+ SSB_SPROM1_AGAIN_A_SHIFT);
+ out->antenna_gain.ghz5.a0 = gain;
+ out->antenna_gain.ghz5.a1 = gain;
+ out->antenna_gain.ghz5.a2 = gain;
+ out->antenna_gain.ghz5.a3 = gain;
}
static void sprom_extract_r4(struct ssb_sprom *out, const u16 *in)
@@ -376,9 +418,10 @@
SSB_SPROM4_ETHPHY_ET1A_SHIFT);
SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0);
SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0);
- SPEX(antenna_gain_a, SSB_SPROM4_AGAIN, SSB_SPROM4_AGAIN_0, 0);
- SPEX(antenna_gain_bg, SSB_SPROM4_AGAIN, SSB_SPROM4_AGAIN_1,
- SSB_SPROM4_AGAIN_1_SHIFT);
+ SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A,
+ SSB_SPROM4_ANTAVAIL_A_SHIFT);
+ SPEX(ant_available_bg, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_BG,
+ SSB_SPROM4_ANTAVAIL_BG_SHIFT);
SPEX(maxpwr_bg, SSB_SPROM4_MAXP_BG, SSB_SPROM4_MAXP_BG_MASK, 0);
SPEX(itssi_bg, SSB_SPROM4_MAXP_BG, SSB_SPROM4_ITSSI_BG,
SSB_SPROM4_ITSSI_BG_SHIFT);
@@ -391,6 +434,19 @@
SPEX(gpio2, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P2, 0);
SPEX(gpio3, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P3,
SSB_SPROM4_GPIOB_P3_SHIFT);
+
+ /* Extract the antenna gain values. */
+ SPEX(antenna_gain.ghz24.a0, SSB_SPROM4_AGAIN01,
+ SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT);
+ SPEX(antenna_gain.ghz24.a1, SSB_SPROM4_AGAIN01,
+ SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT);
+ SPEX(antenna_gain.ghz24.a2, SSB_SPROM4_AGAIN23,
+ SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT);
+ SPEX(antenna_gain.ghz24.a3, SSB_SPROM4_AGAIN23,
+ SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT);
+ memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
+ sizeof(out->antenna_gain.ghz5));
+
/* TODO - get remaining rev 4 stuff needed */
}
@@ -400,7 +456,7 @@
memset(out, 0, sizeof(*out));
out->revision = in[size - 1] & 0x00FF;
- ssb_printk(KERN_INFO PFX "SPROM revision %d detected.\n", out->revision);
+ ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision);
if ((bus->chip_id & 0xFF00) == 0x4400) {
/* Workaround: The BCM44XX chip has a stupid revision
* number stored in the SPROM.
@@ -445,9 +501,7 @@
err = sprom_check_crc(buf, bus->sprom_size);
if (err) {
/* check for rev 4 sprom - has special signature */
- if (buf [32] == 0x5372) {
- ssb_printk(KERN_WARNING PFX "Extracting a rev 4"
- " SPROM\n");
+ if (buf[32] == 0x5372) {
kfree(buf);
buf = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
GFP_KERNEL);