static void bcma_core_chipcommon_flash_detect(struct bcma_drv_cc *cc) { struct bcma_bus *bus = cc->core->bus; switch (cc->capabilities & BCMA_CC_CAP_FLASHT) { case BCMA_CC_FLASHT_STSER: case BCMA_CC_FLASHT_ATSER: bcma_debug(bus, "Found serial flash\n"); bcma_sflash_init(cc); break; case BCMA_CC_FLASHT_PARA: bcma_debug(bus, "Found parallel flash\n"); bcma_pflash_init(cc); break; default: bcma_err(bus, "Flash type not supported\n"); } if (cc->core->id.rev == 38 || bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) { if (cc->capabilities & BCMA_CC_CAP_NFLASH) { bcma_debug(bus, "Found NAND flash\n"); bcma_nflash_init(cc); } } }
static void bcma_host_pci_switch_core(struct bcma_device *core) { pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN, core->addr); pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN2, core->wrap); core->bus->mapped_core = core; bcma_debug(core->bus, "Switched to core: 0x%X\n", core->id.id); }
static int bcma_fill_sprom_with_fallback(struct bcma_bus *bus, struct ssb_sprom *out) { int err; if (!get_fallback_sprom) { err = -ENOENT; goto fail; } err = get_fallback_sprom(bus, out); if (err) goto fail; bcma_debug(bus, "Using SPROM revision %d provided by platform.\n", bus->sprom.revision); return 0; fail: bcma_warn(bus, "Using fallback SPROM failed (err %d)\n", err); return err; }
static int bcma_sprom_valid(struct bcma_bus *bus, const u16 *sprom, size_t words) { u16 revision; int err; err = bcma_sprom_check_crc(sprom, words); if (err) return err; revision = sprom[words - 1] & SSB_SPROM_REVISION_REV; if (revision != 8 && revision != 9 && revision != 10) { pr_err("Unsupported SPROM revision: %d\n", revision); return -ENOENT; } bus->sprom.revision = revision; bcma_debug(bus, "Found SPROM revision %d\n", revision); return 0; }
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; }