int bcma_sprom_get(struct bcma_bus *bus) { u16 offset; u16 *sprom; int err = 0; if (!bus->drv_cc.core) return -EOPNOTSUPP; if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM)) return -ENOENT; sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16), GFP_KERNEL); if (!sprom) return -ENOMEM; if (bus->chipinfo.id == 0x4331) bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false); /* Most cards have SPROM moved by additional offset 0x30 (48 dwords). * According to brcm80211 this applies to cards with PCIe rev >= 6 * TODO: understand this condition and use it */ offset = (bus->chipinfo.id == 0x4331) ? BCMA_CC_SPROM : BCMA_CC_SPROM_PCIE6; bcma_sprom_read(bus, offset, sprom); if (bus->chipinfo.id == 0x4331) bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true); err = bcma_sprom_valid(sprom); if (err) goto out; bcma_sprom_extract_r8(bus, sprom); out: kfree(sprom); return err; }
int bcma_sprom_get(struct bcma_bus *bus) { u16 offset = BCMA_CC_SPROM; u16 *sprom; size_t sprom_sizes[] = { SSB_SPROMSIZE_WORDS_R4, SSB_SPROMSIZE_WORDS_R10, }; int i, err = 0; if (!bus->drv_cc.core) return -EOPNOTSUPP; if (!bcma_sprom_ext_available(bus)) { bool sprom_onchip; /* * External SPROM takes precedence so check * on-chip OTP only when no external SPROM * is present. */ sprom_onchip = bcma_sprom_onchip_available(bus); if (sprom_onchip) { /* determine offset */ offset = bcma_sprom_onchip_offset(bus); } if (!offset || !sprom_onchip) { /* * Maybe there is no SPROM on the device? * Now we ask the arch code if there is some sprom * available for this device in some other storage. */ err = bcma_fill_sprom_with_fallback(bus, &bus->sprom); return err; } } if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4331 || bus->chipinfo.id == BCMA_CHIP_ID_BCM43431) bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false); bcma_debug(bus, "SPROM offset 0x%x\n", offset); for (i = 0; i < ARRAY_SIZE(sprom_sizes); i++) { size_t words = sprom_sizes[i]; sprom = kcalloc(words, sizeof(u16), GFP_KERNEL); if (!sprom) return -ENOMEM; bcma_sprom_read(bus, offset, sprom, words); err = bcma_sprom_valid(bus, sprom, words); if (!err) break; kfree(sprom); } if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4331 || bus->chipinfo.id == BCMA_CHIP_ID_BCM43431) bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true); if (err) { bcma_warn(bus, "Invalid SPROM read from the PCIe card, trying to use fallback SPROM\n"); err = bcma_fill_sprom_with_fallback(bus, &bus->sprom); } else { bcma_sprom_extract_r8(bus, sprom); kfree(sprom); } return err; }