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>
This commit is contained in:
Родитель
d5da79ac1f
Коммит
c74ddfd5ea
|
@ -314,8 +314,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 +334,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 +370,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 +382,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;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <linux/irq.h>
|
||||
#include <linux/crc32.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include "wl1251.h"
|
||||
#include "wl12xx_80211.h"
|
||||
|
@ -83,7 +84,7 @@ static int wl1251_fetch_firmware(struct wl1251 *wl)
|
|||
}
|
||||
|
||||
wl->fw_len = fw->size;
|
||||
wl->fw = kmalloc(wl->fw_len, GFP_KERNEL);
|
||||
wl->fw = vmalloc(wl->fw_len);
|
||||
|
||||
if (!wl->fw) {
|
||||
wl1251_error("could not allocate memory for the firmware");
|
||||
|
@ -1427,7 +1428,7 @@ int wl1251_free_hw(struct wl1251 *wl)
|
|||
|
||||
kfree(wl->target_mem_map);
|
||||
kfree(wl->data_path);
|
||||
kfree(wl->fw);
|
||||
vfree(wl->fw);
|
||||
wl->fw = NULL;
|
||||
kfree(wl->nvs);
|
||||
wl->nvs = NULL;
|
||||
|
|
Загрузка…
Ссылка в новой задаче