static void brcmf_fw_free_request(struct brcmf_fw_request *req) { struct brcmf_fw_item *item; int i; for (i = 0, item = &req->items[0]; i < req->n_items; i++, item++) { if (item->type == BRCMF_FW_TYPE_BINARY) release_firmware(item->binary); else if (item->type == BRCMF_FW_TYPE_NVRAM) brcmf_fw_nvram_free(item->nv_data.data); } kfree(req); }
static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo, const struct firmware *fw, void *nvram, u32 nvram_len) { u32 sharedram_addr; u32 sharedram_addr_written; u32 loop_counter; int err; u32 address; u32 resetintr; devinfo->ringbell = brcmf_pcie_ringbell_v2; devinfo->generic_corerev = BRCMF_PCIE_GENREV2; brcmf_dbg(PCIE, "Halt ARM.\n"); err = brcmf_pcie_enter_download_state(devinfo); if (err) return err; brcmf_dbg(PCIE, "Download FW %s\n", devinfo->fw_name); brcmf_pcie_copy_mem_todev(devinfo, devinfo->ci->rambase, (void *)fw->data, fw->size); resetintr = get_unaligned_le32(fw->data); release_firmware(fw); /* reset last 4 bytes of RAM address. to be used for shared * area. This identifies when FW is running */ brcmf_pcie_write_ram32(devinfo, devinfo->ci->ramsize - 4, 0); if (nvram) { brcmf_dbg(PCIE, "Download NVRAM %s\n", devinfo->nvram_name); address = devinfo->ci->rambase + devinfo->ci->ramsize - nvram_len; brcmf_pcie_copy_mem_todev(devinfo, address, nvram, nvram_len); brcmf_fw_nvram_free(nvram); } else { brcmf_dbg(PCIE, "No matching NVRAM file found %s\n", devinfo->nvram_name); } sharedram_addr_written = brcmf_pcie_read_ram32(devinfo, devinfo->ci->ramsize - 4); brcmf_dbg(PCIE, "Bring ARM in running state\n"); err = brcmf_pcie_exit_download_state(devinfo, resetintr); if (err) return err; brcmf_dbg(PCIE, "Wait for FW init\n"); sharedram_addr = sharedram_addr_written; loop_counter = BRCMF_PCIE_FW_UP_TIMEOUT / 50; while ((sharedram_addr == sharedram_addr_written) && (loop_counter)) { msleep(50); sharedram_addr = brcmf_pcie_read_ram32(devinfo, devinfo->ci->ramsize - 4); loop_counter--; } if (sharedram_addr == sharedram_addr_written) { brcmf_err("FW failed to initialize\n"); return -ENODEV; } brcmf_dbg(PCIE, "Shared RAM addr: 0x%08x\n", sharedram_addr); return (brcmf_pcie_init_share_ram_info(devinfo, sharedram_addr)); }