aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/wl1251_boot.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/wl12xx/wl1251_boot.c')
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_boot.c55
1 files changed, 41 insertions, 14 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c
index 452d748e42c6..2e733e7bdfd4 100644
--- a/drivers/net/wireless/wl12xx/wl1251_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1251_boot.c
@@ -296,8 +296,12 @@ int wl1251_boot_run_firmware(struct wl1251 *wl)
WL1251_ACX_INTR_INIT_COMPLETE;
wl1251_boot_target_enable_interrupts(wl);
- /* unmask all mbox events */
- wl->event_mask = 0xffffffff;
+ wl->event_mask = SCAN_COMPLETE_EVENT_ID | BSS_LOSE_EVENT_ID |
+ SYNCHRONIZATION_TIMEOUT_EVENT_ID |
+ ROAMING_TRIGGER_LOW_RSSI_EVENT_ID |
+ ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID |
+ REGAINED_BSS_EVENT_ID | BT_PTA_SENSE_EVENT_ID |
+ BT_PTA_PREDICTION_EVENT_ID;
ret = wl1251_event_unmask(wl);
if (ret < 0) {
@@ -314,8 +318,8 @@ int wl1251_boot_run_firmware(struct wl1251 *wl)
static int wl1251_boot_upload_firmware(struct wl1251 *wl)
{
int addr, chunk_num, partition_limit;
- size_t fw_data_len;
- u8 *p;
+ size_t fw_data_len, len;
+ u8 *p, *buf;
/* whal_FwCtrl_LoadFwImageSm() */
@@ -334,6 +338,12 @@ static int wl1251_boot_upload_firmware(struct wl1251 *wl)
return -EIO;
}
+ buf = kmalloc(CHUNK_SIZE, GFP_KERNEL);
+ if (!buf) {
+ wl1251_error("allocation for firmware upload chunk failed");
+ return -ENOMEM;
+ }
+
wl1251_set_partition(wl, WL1251_PART_DOWN_MEM_START,
WL1251_PART_DOWN_MEM_SIZE,
WL1251_PART_DOWN_REG_START,
@@ -364,7 +374,11 @@ static int wl1251_boot_upload_firmware(struct wl1251 *wl)
p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
wl1251_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
p, addr);
- wl1251_mem_write(wl, addr, p, CHUNK_SIZE);
+
+ /* need to copy the chunk for dma */
+ len = CHUNK_SIZE;
+ memcpy(buf, p, len);
+ wl1251_mem_write(wl, addr, buf, len);
chunk_num++;
}
@@ -372,9 +386,16 @@ static int wl1251_boot_upload_firmware(struct wl1251 *wl)
/* 10.4 upload the last chunk */
addr = WL1251_PART_DOWN_MEM_START + chunk_num * CHUNK_SIZE;
p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
+
+ /* need to copy the chunk for dma */
+ len = fw_data_len % CHUNK_SIZE;
+ memcpy(buf, p, len);
+
wl1251_debug(DEBUG_BOOT, "uploading fw last chunk (%zu B) 0x%p to 0x%x",
- fw_data_len % CHUNK_SIZE, p, addr);
- wl1251_mem_write(wl, addr, p, fw_data_len % CHUNK_SIZE);
+ len, p, addr);
+ wl1251_mem_write(wl, addr, buf, len);
+
+ kfree(buf);
return 0;
}
@@ -473,13 +494,19 @@ int wl1251_boot(struct wl1251 *wl)
goto out;
/* 2. start processing NVS file */
- ret = wl1251_boot_upload_nvs(wl);
- if (ret < 0)
- goto out;
-
- /* write firmware's last address (ie. it's length) to
- * ACX_EEPROMLESS_IND_REG */
- wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, wl->fw_len);
+ if (wl->use_eeprom) {
+ wl1251_reg_write32(wl, ACX_REG_EE_START, START_EEPROM_MGR);
+ msleep(4000);
+ wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, USE_EEPROM);
+ } else {
+ ret = wl1251_boot_upload_nvs(wl);
+ if (ret < 0)
+ goto out;
+
+ /* write firmware's last address (ie. it's length) to
+ * ACX_EEPROMLESS_IND_REG */
+ wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, wl->fw_len);
+ }
/* 6. read the EEPROM parameters */
tmp = wl1251_reg_read32(wl, SCR_PAD2);