Ejemplo n.º 1
0
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);
		}
	}
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
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;
}