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