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.c58
1 files changed, 43 insertions, 15 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c
index 452d748e42c6..d5ac79aeaa73 100644
--- a/drivers/net/wireless/wl12xx/wl1251_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1251_boot.c
@@ -22,6 +22,7 @@
22 */ 22 */
23 23
24#include <linux/gpio.h> 24#include <linux/gpio.h>
25#include <linux/slab.h>
25 26
26#include "wl1251_reg.h" 27#include "wl1251_reg.h"
27#include "wl1251_boot.h" 28#include "wl1251_boot.h"
@@ -256,7 +257,7 @@ int wl1251_boot_run_firmware(struct wl1251 *wl)
256 } 257 }
257 } 258 }
258 259
259 if (loop >= INIT_LOOP) { 260 if (loop > INIT_LOOP) {
260 wl1251_error("timeout waiting for the hardware to " 261 wl1251_error("timeout waiting for the hardware to "
261 "complete initialization"); 262 "complete initialization");
262 return -EIO; 263 return -EIO;
@@ -296,8 +297,12 @@ int wl1251_boot_run_firmware(struct wl1251 *wl)
296 WL1251_ACX_INTR_INIT_COMPLETE; 297 WL1251_ACX_INTR_INIT_COMPLETE;
297 wl1251_boot_target_enable_interrupts(wl); 298 wl1251_boot_target_enable_interrupts(wl);
298 299
299 /* unmask all mbox events */ 300 wl->event_mask = SCAN_COMPLETE_EVENT_ID | BSS_LOSE_EVENT_ID |
300 wl->event_mask = 0xffffffff; 301 SYNCHRONIZATION_TIMEOUT_EVENT_ID |
302 ROAMING_TRIGGER_LOW_RSSI_EVENT_ID |
303 ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID |
304 REGAINED_BSS_EVENT_ID | BT_PTA_SENSE_EVENT_ID |
305 BT_PTA_PREDICTION_EVENT_ID;
301 306
302 ret = wl1251_event_unmask(wl); 307 ret = wl1251_event_unmask(wl);
303 if (ret < 0) { 308 if (ret < 0) {
@@ -314,8 +319,8 @@ int wl1251_boot_run_firmware(struct wl1251 *wl)
314static int wl1251_boot_upload_firmware(struct wl1251 *wl) 319static int wl1251_boot_upload_firmware(struct wl1251 *wl)
315{ 320{
316 int addr, chunk_num, partition_limit; 321 int addr, chunk_num, partition_limit;
317 size_t fw_data_len; 322 size_t fw_data_len, len;
318 u8 *p; 323 u8 *p, *buf;
319 324
320 /* whal_FwCtrl_LoadFwImageSm() */ 325 /* whal_FwCtrl_LoadFwImageSm() */
321 326
@@ -334,6 +339,12 @@ static int wl1251_boot_upload_firmware(struct wl1251 *wl)
334 return -EIO; 339 return -EIO;
335 } 340 }
336 341
342 buf = kmalloc(CHUNK_SIZE, GFP_KERNEL);
343 if (!buf) {
344 wl1251_error("allocation for firmware upload chunk failed");
345 return -ENOMEM;
346 }
347
337 wl1251_set_partition(wl, WL1251_PART_DOWN_MEM_START, 348 wl1251_set_partition(wl, WL1251_PART_DOWN_MEM_START,
338 WL1251_PART_DOWN_MEM_SIZE, 349 WL1251_PART_DOWN_MEM_SIZE,
339 WL1251_PART_DOWN_REG_START, 350 WL1251_PART_DOWN_REG_START,
@@ -364,7 +375,11 @@ static int wl1251_boot_upload_firmware(struct wl1251 *wl)
364 p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE; 375 p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
365 wl1251_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x", 376 wl1251_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
366 p, addr); 377 p, addr);
367 wl1251_mem_write(wl, addr, p, CHUNK_SIZE); 378
379 /* need to copy the chunk for dma */
380 len = CHUNK_SIZE;
381 memcpy(buf, p, len);
382 wl1251_mem_write(wl, addr, buf, len);
368 383
369 chunk_num++; 384 chunk_num++;
370 } 385 }
@@ -372,9 +387,16 @@ static int wl1251_boot_upload_firmware(struct wl1251 *wl)
372 /* 10.4 upload the last chunk */ 387 /* 10.4 upload the last chunk */
373 addr = WL1251_PART_DOWN_MEM_START + chunk_num * CHUNK_SIZE; 388 addr = WL1251_PART_DOWN_MEM_START + chunk_num * CHUNK_SIZE;
374 p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE; 389 p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
390
391 /* need to copy the chunk for dma */
392 len = fw_data_len % CHUNK_SIZE;
393 memcpy(buf, p, len);
394
375 wl1251_debug(DEBUG_BOOT, "uploading fw last chunk (%zu B) 0x%p to 0x%x", 395 wl1251_debug(DEBUG_BOOT, "uploading fw last chunk (%zu B) 0x%p to 0x%x",
376 fw_data_len % CHUNK_SIZE, p, addr); 396 len, p, addr);
377 wl1251_mem_write(wl, addr, p, fw_data_len % CHUNK_SIZE); 397 wl1251_mem_write(wl, addr, buf, len);
398
399 kfree(buf);
378 400
379 return 0; 401 return 0;
380} 402}
@@ -473,13 +495,19 @@ int wl1251_boot(struct wl1251 *wl)
473 goto out; 495 goto out;
474 496
475 /* 2. start processing NVS file */ 497 /* 2. start processing NVS file */
476 ret = wl1251_boot_upload_nvs(wl); 498 if (wl->use_eeprom) {
477 if (ret < 0) 499 wl1251_reg_write32(wl, ACX_REG_EE_START, START_EEPROM_MGR);
478 goto out; 500 msleep(4000);
479 501 wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, USE_EEPROM);
480 /* write firmware's last address (ie. it's length) to 502 } else {
481 * ACX_EEPROMLESS_IND_REG */ 503 ret = wl1251_boot_upload_nvs(wl);
482 wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, wl->fw_len); 504 if (ret < 0)
505 goto out;
506
507 /* write firmware's last address (ie. it's length) to
508 * ACX_EEPROMLESS_IND_REG */
509 wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, wl->fw_len);
510 }
483 511
484 /* 6. read the EEPROM parameters */ 512 /* 6. read the EEPROM parameters */
485 tmp = wl1251_reg_read32(wl, SCR_PAD2); 513 tmp = wl1251_reg_read32(wl, SCR_PAD2);