Commit 9d1ac34ec3a67713308ae0883c3359c557f14d17

Authored by Larry Finger
Committed by John W. Linville
1 parent ce9426d190

ssb: Handle alternate SSPROM location

In kernel Bugzilla #15825 (2 users), in a wireless mailing list thread
(http://lists.infradead.org/pipermail/b43-dev/2010-May/000124.html), and on a
netbook owned by John Linville
(http://marc.info/?l=linux-wireless&m=127230751408818&w=4), there are reports
of ssb failing to detect an SPROM at the normal location. After studying the
MMIO trace dump for the Broadcom wl driver, it was determined that the affected
boxes had a relocated SPROM.

This patch fixes all systems that have reported this problem.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Stable <stable@kernel.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

Showing 2 changed files with 14 additions and 2 deletions Side-by-side Diff

drivers/ssb/driver_chipcommon.c
... ... @@ -259,6 +259,7 @@
259 259 return; /* We don't have a ChipCommon */
260 260 if (cc->dev->id.revision >= 11)
261 261 cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT);
  262 + ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status);
262 263 ssb_pmu_init(cc);
263 264 chipco_powercontrol_init(cc);
264 265 ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
... ... @@ -626,11 +626,22 @@
626 626 return -ENODEV;
627 627 }
628 628 if (bus->chipco.dev) { /* can be unavailible! */
629   - bus->sprom_offset = (bus->chipco.dev->id.revision < 31) ?
630   - SSB_SPROM_BASE1 : SSB_SPROM_BASE31;
  629 + /*
  630 + * get SPROM offset: SSB_SPROM_BASE1 except for
  631 + * chipcommon rev >= 31 or chip ID is 0x4312 and
  632 + * chipcommon status & 3 == 2
  633 + */
  634 + if (bus->chipco.dev->id.revision >= 31)
  635 + bus->sprom_offset = SSB_SPROM_BASE31;
  636 + else if (bus->chip_id == 0x4312 &&
  637 + (bus->chipco.status & 0x03) == 2)
  638 + bus->sprom_offset = SSB_SPROM_BASE31;
  639 + else
  640 + bus->sprom_offset = SSB_SPROM_BASE1;
631 641 } else {
632 642 bus->sprom_offset = SSB_SPROM_BASE1;
633 643 }
  644 + ssb_dprintk(KERN_INFO PFX "SPROM offset is 0x%x\n", bus->sprom_offset);
634 645  
635 646 buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
636 647 if (!buf)