aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKalle Valo <kalle.valo@nokia.com>2009-11-17 11:48:45 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-11-18 17:09:20 -0500
commitc74ddfd5ea9c0c67d0aae77eeb5b610188cb8bc4 (patch)
tree83b9b65950079b8c4d1ee1428009fa4832791fd8 /drivers
parentd5da79ac1f5050cccaa68d814ccce292371f25fa (diff)
wl1251: allocate space for firmware with vmalloc()
Earlier firmware was stored to a memory area allocated with kmalloc() but finding a a contiguous area of memory long enough for the firmware is very difficult in certain cases. better to allocate the memory for firmware with vmalloc() instead and use a small buffer for DMA transfers. Thanks to Eero Tamminen for the idea. Signed-off-by: Kalle Valo <kalle.valo@nokia.com> Reviewed-by: Vidhya Govindan <vidhya.govindan@nokia.com> Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_boot.c27
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_main.c5
2 files changed, 25 insertions, 7 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c
index 452d748e42c6..8febf27ab28d 100644
--- a/drivers/net/wireless/wl12xx/wl1251_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1251_boot.c
@@ -314,8 +314,8 @@ int wl1251_boot_run_firmware(struct wl1251 *wl)
314static int wl1251_boot_upload_firmware(struct wl1251 *wl) 314static int wl1251_boot_upload_firmware(struct wl1251 *wl)
315{ 315{
316 int addr, chunk_num, partition_limit; 316 int addr, chunk_num, partition_limit;
317 size_t fw_data_len; 317 size_t fw_data_len, len;
318 u8 *p; 318 u8 *p, *buf;
319 319
320 /* whal_FwCtrl_LoadFwImageSm() */ 320 /* whal_FwCtrl_LoadFwImageSm() */
321 321
@@ -334,6 +334,12 @@ static int wl1251_boot_upload_firmware(struct wl1251 *wl)
334 return -EIO; 334 return -EIO;
335 } 335 }
336 336
337 buf = kmalloc(CHUNK_SIZE, GFP_KERNEL);
338 if (!buf) {
339 wl1251_error("allocation for firmware upload chunk failed");
340 return -ENOMEM;
341 }
342
337 wl1251_set_partition(wl, WL1251_PART_DOWN_MEM_START, 343 wl1251_set_partition(wl, WL1251_PART_DOWN_MEM_START,
338 WL1251_PART_DOWN_MEM_SIZE, 344 WL1251_PART_DOWN_MEM_SIZE,
339 WL1251_PART_DOWN_REG_START, 345 WL1251_PART_DOWN_REG_START,
@@ -364,7 +370,11 @@ static int wl1251_boot_upload_firmware(struct wl1251 *wl)
364 p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE; 370 p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
365 wl1251_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x", 371 wl1251_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
366 p, addr); 372 p, addr);
367 wl1251_mem_write(wl, addr, p, CHUNK_SIZE); 373
374 /* need to copy the chunk for dma */
375 len = CHUNK_SIZE;
376 memcpy(buf, p, len);
377 wl1251_mem_write(wl, addr, buf, len);
368 378
369 chunk_num++; 379 chunk_num++;
370 } 380 }
@@ -372,9 +382,16 @@ static int wl1251_boot_upload_firmware(struct wl1251 *wl)
372 /* 10.4 upload the last chunk */ 382 /* 10.4 upload the last chunk */
373 addr = WL1251_PART_DOWN_MEM_START + chunk_num * CHUNK_SIZE; 383 addr = WL1251_PART_DOWN_MEM_START + chunk_num * CHUNK_SIZE;
374 p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE; 384 p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
385
386 /* need to copy the chunk for dma */
387 len = fw_data_len % CHUNK_SIZE;
388 memcpy(buf, p, len);
389
375 wl1251_debug(DEBUG_BOOT, "uploading fw last chunk (%zu B) 0x%p to 0x%x", 390 wl1251_debug(DEBUG_BOOT, "uploading fw last chunk (%zu B) 0x%p to 0x%x",
376 fw_data_len % CHUNK_SIZE, p, addr); 391 len, p, addr);
377 wl1251_mem_write(wl, addr, p, fw_data_len % CHUNK_SIZE); 392 wl1251_mem_write(wl, addr, buf, len);
393
394 kfree(buf);
378 395
379 return 0; 396 return 0;
380} 397}
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index b5e3bdb08448..1f4c238a3371 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -28,6 +28,7 @@
28#include <linux/irq.h> 28#include <linux/irq.h>
29#include <linux/crc32.h> 29#include <linux/crc32.h>
30#include <linux/etherdevice.h> 30#include <linux/etherdevice.h>
31#include <linux/vmalloc.h>
31 32
32#include "wl1251.h" 33#include "wl1251.h"
33#include "wl12xx_80211.h" 34#include "wl12xx_80211.h"
@@ -83,7 +84,7 @@ static int wl1251_fetch_firmware(struct wl1251 *wl)
83 } 84 }
84 85
85 wl->fw_len = fw->size; 86 wl->fw_len = fw->size;
86 wl->fw = kmalloc(wl->fw_len, GFP_KERNEL); 87 wl->fw = vmalloc(wl->fw_len);
87 88
88 if (!wl->fw) { 89 if (!wl->fw) {
89 wl1251_error("could not allocate memory for the firmware"); 90 wl1251_error("could not allocate memory for the firmware");
@@ -1427,7 +1428,7 @@ int wl1251_free_hw(struct wl1251 *wl)
1427 1428
1428 kfree(wl->target_mem_map); 1429 kfree(wl->target_mem_map);
1429 kfree(wl->data_path); 1430 kfree(wl->data_path);
1430 kfree(wl->fw); 1431 vfree(wl->fw);
1431 wl->fw = NULL; 1432 wl->fw = NULL;
1432 kfree(wl->nvs); 1433 kfree(wl->nvs);
1433 wl->nvs = NULL; 1434 wl->nvs = NULL;