/** * @brief This function downloads helper. * @param priv pointer to wlan_private structure * @return WLAN_STATUS_SUCCESS */ int sbi_prog_firmware(wlan_private * priv) { cfreg *reg = (cfreg *)priv->wlan_dev.ioport; u32 size_total; u32 size_sent; u32 size_block; u8 buf[256]; u8 temp; int r; temp = inb(reg->card.scratch); if (temp == CF_SCRATCH_FIRMWARE_READY) return WLAN_STATUS_SUCCESS; if (temp != CF_SCRATCH_HOST_BOOT_WAITING) return WLAN_STATUS_FAILURE; size_total = sizeof(init_image); size_sent = 0; size_block = FW_BLOCK_SIZE; while (size_sent < size_total) { PRINTM(INFO, "loading %06d of %06d bytes\n", size_sent, size_total); if (size_total - size_sent < size_block) size_block = (size_total - size_sent); memcpy(buf, &init_image[size_sent], size_block); outw(FW_BLOCK_SIZE, reg->host.io_cmd_write_len); outsw(reg->host.io_cmd_write, buf, FW_BLOCK_SIZE / 2); outb(CF_HCR_HS_CmdDnLdOvr, reg->host.status); wmb(); outw(CF_HCR_CIC_CmdDnLdOvr, reg->host.int_cause); #define FW_POLL_DELAY_10US 10 /*10us delay*/ r = poll_reg( reg->card.status, CF_CCR_CS_CmdDnLdRdy, FW_RETRY, FW_POLL_DELAY_10US); if (r != WLAN_STATUS_SUCCESS) return WLAN_STATUS_FAILURE; size_sent += size_block; } outw(0x00, reg->host.io_cmd_write_len); outb(CF_HCR_HS_CmdDnLdOvr, reg->host.status); wmb(); outw(CF_HCR_CIC_CmdDnLdOvr, reg->host.int_cause); return WLAN_STATUS_SUCCESS; }