This patch and the patch by Gabor entitled "[PATCH] ssb: Implement fast powerup delay calculation" are enough to allow the netbook from John to work with ssb/b43. As this patch tampers with the SPROM offset for 14e4:4315 devices, it should be tested by anyone with an LP PHY that works to ensure that it is not killed. The essential elements of this patch will also be tested as part of kernel Bug #15825. V2 removes the attempt to read the chipcommon status in the scan routine in favor of the one already in chipcommon init. In addition, there was a small error in the test for an alternate location for the SPROM. If you tested with V1, it should not be necessary to retest. Larry Index: wireless-testing/drivers/ssb/pci.c =================================================================== --- wireless-testing.orig/drivers/ssb/pci.c +++ wireless-testing/drivers/ssb/pci.c @@ -631,8 +631,17 @@ static int ssb_pci_sprom_get(struct ssb_ return -ENODEV; } - bus->sprom_offset = (bus->chipco.dev->id.revision < 31) ? - SSB_SPROM_BASE1 : SSB_SPROM_BASE31; + /* get SPROM offset: SSB_SPROM_BASE1 except for chipcommon rev >= 31 + * or chip ID is 0x4312 and chipcommon status & 3 == 2 + */ + if (bus->chipco.dev->id.revision >= 31) + bus->sprom_offset = SSB_SPROM_BASE31; + else if (bus->chip_id == 0x4312 && (bus->chipco.status & 0x03) == 2) + bus->sprom_offset = SSB_SPROM_BASE31; + else + bus->sprom_offset = SSB_SPROM_BASE1; + + ssb_dprintk(KERN_INFO PFX "SPROM offset is 0x%x\n", bus->sprom_offset); buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL); if (!buf) Index: wireless-testing/drivers/ssb/driver_chipcommon.c =================================================================== --- wireless-testing.orig/drivers/ssb/driver_chipcommon.c +++ wireless-testing/drivers/ssb/driver_chipcommon.c @@ -252,15 +252,17 @@ void ssb_chipcommon_init(struct ssb_chip { u16 delay; + cc->status = 0; if (!cc->dev) return; /* We don't have a ChipCommon */ if (cc->dev->id.revision >= 11) cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT); + ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status); ssb_pmu_init(cc); chipco_powercontrol_init(cc); ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST); delay = calc_fast_powerup_delay(cc); - ssb_printk(KERN_INFO PFX "fast_pwrup_delay is %d\n", delay); + ssb_dprintk(KERN_INFO PFX "fast_pwrup_delay is %d\n", delay); cc->fast_pwrup_delay = delay; ssb_write16(cc->dev, SSB_MMIO_POWERUP_DELAY, delay); }