diff options
author | Michael Buesch <mb@bu3sch.de> | 2007-12-22 15:51:30 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:09:14 -0500 |
commit | e861b98d5e1be769ca6483b6df97149b956ea834 (patch) | |
tree | 88754e03eddc9a7b1441421125a776c5cbd597d1 /drivers | |
parent | 66c6b139f77e8568f03611422967bfaa4c4a3bbd (diff) |
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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/b43/main.c | 10 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/main.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/phy.c | 2 | ||||
-rw-r--r-- | drivers/ssb/pci.c | 76 |
4 files changed, 66 insertions, 27 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index d7ea671394a8..68bbe8eafd6d 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -3884,16 +3884,6 @@ static void b43_sprom_fixup(struct ssb_bus *bus) | |||
3884 | if (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE && | 3884 | if (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE && |
3885 | bus->boardinfo.type == 0x4E && bus->boardinfo.rev > 0x40) | 3885 | bus->boardinfo.type == 0x4E && bus->boardinfo.rev > 0x40) |
3886 | bus->sprom.boardflags_lo |= B43_BFL_PACTRL; | 3886 | bus->sprom.boardflags_lo |= B43_BFL_PACTRL; |
3887 | |||
3888 | /* Handle case when gain is not set in sprom */ | ||
3889 | if (bus->sprom.antenna_gain_a == 0xFF) | ||
3890 | bus->sprom.antenna_gain_a = 2; | ||
3891 | if (bus->sprom.antenna_gain_bg == 0xFF) | ||
3892 | bus->sprom.antenna_gain_bg = 2; | ||
3893 | |||
3894 | /* Convert Antennagain values to Q5.2 */ | ||
3895 | bus->sprom.antenna_gain_a <<= 2; | ||
3896 | bus->sprom.antenna_gain_bg <<= 2; | ||
3897 | } | 3887 | } |
3898 | 3888 | ||
3899 | static void b43_wireless_exit(struct ssb_device *dev, struct b43_wl *wl) | 3889 | 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 14087fc20f3a..575fd9a5874d 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -3572,11 +3572,6 @@ static void b43legacy_sprom_fixup(struct ssb_bus *bus) | |||
3572 | bus->boardinfo.type == 0x4E && | 3572 | bus->boardinfo.type == 0x4E && |
3573 | bus->boardinfo.rev > 0x40) | 3573 | bus->boardinfo.rev > 0x40) |
3574 | bus->sprom.boardflags_lo |= B43legacy_BFL_PACTRL; | 3574 | bus->sprom.boardflags_lo |= B43legacy_BFL_PACTRL; |
3575 | |||
3576 | /* Convert Antennagain values to Q5.2 */ | ||
3577 | if (bus->sprom.antenna_gain_bg == 0xFF) | ||
3578 | bus->sprom.antenna_gain_bg = 2; /* if unset, use 2 dBm */ | ||
3579 | bus->sprom.antenna_gain_bg <<= 2; | ||
3580 | } | 3575 | } |
3581 | 3576 | ||
3582 | static void b43legacy_wireless_exit(struct ssb_device *dev, | 3577 | 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 9d527e6d6ced..57c668f575fc 100644 --- a/drivers/net/wireless/b43legacy/phy.c +++ b/drivers/net/wireless/b43legacy/phy.c | |||
@@ -1859,7 +1859,7 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev) | |||
1859 | * which accounts for the factor of 4 */ | 1859 | * which accounts for the factor of 4 */ |
1860 | #define REG_MAX_PWR 20 | 1860 | #define REG_MAX_PWR 20 |
1861 | max_pwr = min(REG_MAX_PWR * 4 | 1861 | max_pwr = min(REG_MAX_PWR * 4 |
1862 | - dev->dev->bus->sprom.antenna_gain_bg | 1862 | - dev->dev->bus->sprom.antenna_gain.ghz24.a0 |
1863 | - 0x6, max_pwr); | 1863 | - 0x6, max_pwr); |
1864 | 1864 | ||
1865 | /* find the desired power in Q5.2 - power_level is in dBm | 1865 | /* 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 9777dcb5bfe5..ed2a38752274 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c | |||
@@ -247,7 +247,7 @@ static void sprom_do_read(struct ssb_bus *bus, u16 *sprom) | |||
247 | int i; | 247 | int i; |
248 | 248 | ||
249 | for (i = 0; i < bus->sprom_size; i++) | 249 | for (i = 0; i < bus->sprom_size; i++) |
250 | sprom[i] = readw(bus->mmio + SSB_SPROM_BASE + (i * 2)); | 250 | sprom[i] = ioread16(bus->mmio + SSB_SPROM_BASE + (i * 2)); |
251 | } | 251 | } |
252 | 252 | ||
253 | static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom) | 253 | static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom) |
@@ -297,10 +297,32 @@ err_ctlreg: | |||
297 | return err; | 297 | return err; |
298 | } | 298 | } |
299 | 299 | ||
300 | static s8 r123_extract_antgain(u8 sprom_revision, const u16 *in, | ||
301 | u16 mask, u16 shift) | ||
302 | { | ||
303 | u16 v; | ||
304 | u8 gain; | ||
305 | |||
306 | v = in[SPOFF(SSB_SPROM1_AGAIN)]; | ||
307 | gain = (v & mask) >> shift; | ||
308 | if (gain == 0xFF) | ||
309 | gain = 2; /* If unset use 2dBm */ | ||
310 | if (sprom_revision == 1) { | ||
311 | /* Convert to Q5.2 */ | ||
312 | gain <<= 2; | ||
313 | } else { | ||
314 | /* Q5.2 Fractional part is stored in 0xC0 */ | ||
315 | gain = ((gain & 0xC0) >> 6) | ((gain & 0x3F) << 2); | ||
316 | } | ||
317 | |||
318 | return (s8)gain; | ||
319 | } | ||
320 | |||
300 | static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) | 321 | static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) |
301 | { | 322 | { |
302 | int i; | 323 | int i; |
303 | u16 v; | 324 | u16 v; |
325 | s8 gain; | ||
304 | u16 loc[3]; | 326 | u16 loc[3]; |
305 | 327 | ||
306 | if (out->revision == 3) { /* rev 3 moved MAC */ | 328 | if (out->revision == 3) { /* rev 3 moved MAC */ |
@@ -327,8 +349,15 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) | |||
327 | SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0); | 349 | SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0); |
328 | SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A, | 350 | SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A, |
329 | SSB_SPROM1_ETHPHY_ET1A_SHIFT); | 351 | SSB_SPROM1_ETHPHY_ET1A_SHIFT); |
352 | SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14); | ||
353 | SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15); | ||
354 | SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0); | ||
330 | SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE, | 355 | SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE, |
331 | SSB_SPROM1_BINF_CCODE_SHIFT); | 356 | SSB_SPROM1_BINF_CCODE_SHIFT); |
357 | SPEX(ant_available_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA, | ||
358 | SSB_SPROM1_BINF_ANTA_SHIFT); | ||
359 | SPEX(ant_available_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG, | ||
360 | SSB_SPROM1_BINF_ANTBG_SHIFT); | ||
332 | SPEX(pa0b0, SSB_SPROM1_PA0B0, 0xFFFF, 0); | 361 | SPEX(pa0b0, SSB_SPROM1_PA0B0, 0xFFFF, 0); |
333 | SPEX(pa0b1, SSB_SPROM1_PA0B1, 0xFFFF, 0); | 362 | SPEX(pa0b1, SSB_SPROM1_PA0B1, 0xFFFF, 0); |
334 | SPEX(pa0b2, SSB_SPROM1_PA0B2, 0xFFFF, 0); | 363 | SPEX(pa0b2, SSB_SPROM1_PA0B2, 0xFFFF, 0); |
@@ -348,9 +377,22 @@ static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) | |||
348 | SSB_SPROM1_ITSSI_A_SHIFT); | 377 | SSB_SPROM1_ITSSI_A_SHIFT); |
349 | SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0); | 378 | SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0); |
350 | SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0); | 379 | SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0); |
351 | SPEX(antenna_gain_a, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_A, 0); | 380 | |
352 | SPEX(antenna_gain_bg, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_BG, | 381 | /* Extract the antenna gain values. */ |
353 | SSB_SPROM1_AGAIN_BG_SHIFT); | 382 | gain = r123_extract_antgain(out->revision, in, |
383 | SSB_SPROM1_AGAIN_BG, | ||
384 | SSB_SPROM1_AGAIN_BG_SHIFT); | ||
385 | out->antenna_gain.ghz24.a0 = gain; | ||
386 | out->antenna_gain.ghz24.a1 = gain; | ||
387 | out->antenna_gain.ghz24.a2 = gain; | ||
388 | out->antenna_gain.ghz24.a3 = gain; | ||
389 | gain = r123_extract_antgain(out->revision, in, | ||
390 | SSB_SPROM1_AGAIN_A, | ||
391 | SSB_SPROM1_AGAIN_A_SHIFT); | ||
392 | out->antenna_gain.ghz5.a0 = gain; | ||
393 | out->antenna_gain.ghz5.a1 = gain; | ||
394 | out->antenna_gain.ghz5.a2 = gain; | ||
395 | out->antenna_gain.ghz5.a3 = gain; | ||
354 | } | 396 | } |
355 | 397 | ||
356 | static void sprom_extract_r4(struct ssb_sprom *out, const u16 *in) | 398 | static void sprom_extract_r4(struct ssb_sprom *out, const u16 *in) |
@@ -376,9 +418,10 @@ static void sprom_extract_r4(struct ssb_sprom *out, const u16 *in) | |||
376 | SSB_SPROM4_ETHPHY_ET1A_SHIFT); | 418 | SSB_SPROM4_ETHPHY_ET1A_SHIFT); |
377 | SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0); | 419 | SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0); |
378 | SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0); | 420 | SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0); |
379 | SPEX(antenna_gain_a, SSB_SPROM4_AGAIN, SSB_SPROM4_AGAIN_0, 0); | 421 | SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A, |
380 | SPEX(antenna_gain_bg, SSB_SPROM4_AGAIN, SSB_SPROM4_AGAIN_1, | 422 | SSB_SPROM4_ANTAVAIL_A_SHIFT); |
381 | SSB_SPROM4_AGAIN_1_SHIFT); | 423 | SPEX(ant_available_bg, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_BG, |
424 | SSB_SPROM4_ANTAVAIL_BG_SHIFT); | ||
382 | SPEX(maxpwr_bg, SSB_SPROM4_MAXP_BG, SSB_SPROM4_MAXP_BG_MASK, 0); | 425 | SPEX(maxpwr_bg, SSB_SPROM4_MAXP_BG, SSB_SPROM4_MAXP_BG_MASK, 0); |
383 | SPEX(itssi_bg, SSB_SPROM4_MAXP_BG, SSB_SPROM4_ITSSI_BG, | 426 | SPEX(itssi_bg, SSB_SPROM4_MAXP_BG, SSB_SPROM4_ITSSI_BG, |
384 | SSB_SPROM4_ITSSI_BG_SHIFT); | 427 | SSB_SPROM4_ITSSI_BG_SHIFT); |
@@ -391,6 +434,19 @@ static void sprom_extract_r4(struct ssb_sprom *out, const u16 *in) | |||
391 | SPEX(gpio2, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P2, 0); | 434 | SPEX(gpio2, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P2, 0); |
392 | SPEX(gpio3, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P3, | 435 | SPEX(gpio3, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P3, |
393 | SSB_SPROM4_GPIOB_P3_SHIFT); | 436 | SSB_SPROM4_GPIOB_P3_SHIFT); |
437 | |||
438 | /* Extract the antenna gain values. */ | ||
439 | SPEX(antenna_gain.ghz24.a0, SSB_SPROM4_AGAIN01, | ||
440 | SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT); | ||
441 | SPEX(antenna_gain.ghz24.a1, SSB_SPROM4_AGAIN01, | ||
442 | SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT); | ||
443 | SPEX(antenna_gain.ghz24.a2, SSB_SPROM4_AGAIN23, | ||
444 | SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT); | ||
445 | SPEX(antenna_gain.ghz24.a3, SSB_SPROM4_AGAIN23, | ||
446 | SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT); | ||
447 | memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24, | ||
448 | sizeof(out->antenna_gain.ghz5)); | ||
449 | |||
394 | /* TODO - get remaining rev 4 stuff needed */ | 450 | /* TODO - get remaining rev 4 stuff needed */ |
395 | } | 451 | } |
396 | 452 | ||
@@ -400,7 +456,7 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out, | |||
400 | memset(out, 0, sizeof(*out)); | 456 | memset(out, 0, sizeof(*out)); |
401 | 457 | ||
402 | out->revision = in[size - 1] & 0x00FF; | 458 | out->revision = in[size - 1] & 0x00FF; |
403 | ssb_printk(KERN_INFO PFX "SPROM revision %d detected.\n", out->revision); | 459 | ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision); |
404 | if ((bus->chip_id & 0xFF00) == 0x4400) { | 460 | if ((bus->chip_id & 0xFF00) == 0x4400) { |
405 | /* Workaround: The BCM44XX chip has a stupid revision | 461 | /* Workaround: The BCM44XX chip has a stupid revision |
406 | * number stored in the SPROM. | 462 | * number stored in the SPROM. |
@@ -445,9 +501,7 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, | |||
445 | err = sprom_check_crc(buf, bus->sprom_size); | 501 | err = sprom_check_crc(buf, bus->sprom_size); |
446 | if (err) { | 502 | if (err) { |
447 | /* check for rev 4 sprom - has special signature */ | 503 | /* check for rev 4 sprom - has special signature */ |
448 | if (buf [32] == 0x5372) { | 504 | if (buf[32] == 0x5372) { |
449 | ssb_printk(KERN_WARNING PFX "Extracting a rev 4" | ||
450 | " SPROM\n"); | ||
451 | kfree(buf); | 505 | kfree(buf); |
452 | buf = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16), | 506 | buf = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16), |
453 | GFP_KERNEL); | 507 | GFP_KERNEL); |