|
@@ -800,19 +800,10 @@ void wl12xx_queue_recovery_work(struct wl1271 *wl)
|
|
|
|
|
|
size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen)
|
|
|
{
|
|
|
- size_t len = 0;
|
|
|
-
|
|
|
- /* The FW log is a length-value list, find where the log end */
|
|
|
- while (len < maxlen) {
|
|
|
- if (memblock[len] == 0)
|
|
|
- break;
|
|
|
- if (len + memblock[len] + 1 > maxlen)
|
|
|
- break;
|
|
|
- len += memblock[len] + 1;
|
|
|
- }
|
|
|
+ size_t len;
|
|
|
|
|
|
/* Make sure we have enough room */
|
|
|
- len = min(len, (size_t)(PAGE_SIZE - wl->fwlog_size));
|
|
|
+ len = min(maxlen, (size_t)(PAGE_SIZE - wl->fwlog_size));
|
|
|
|
|
|
/* Fill the FW log file, consumed by the sysfs fwlog entry */
|
|
|
memcpy(wl->fwlog + wl->fwlog_size, memblock, len);
|
|
@@ -821,10 +812,9 @@ size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen)
|
|
|
return len;
|
|
|
}
|
|
|
|
|
|
-#define WLCORE_FW_LOG_END 0x2000000
|
|
|
-
|
|
|
static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
|
|
|
{
|
|
|
+ struct wlcore_partition_set part, old_part;
|
|
|
u32 addr;
|
|
|
u32 offset;
|
|
|
u32 end_of_log;
|
|
@@ -837,7 +827,7 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
|
|
|
|
|
|
wl1271_info("Reading FW panic log");
|
|
|
|
|
|
- block = kmalloc(WL12XX_HW_BLOCK_SIZE, GFP_KERNEL);
|
|
|
+ block = kmalloc(wl->fw_mem_block_size, GFP_KERNEL);
|
|
|
if (!block)
|
|
|
return;
|
|
|
|
|
@@ -863,17 +853,31 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
|
|
|
|
|
|
if (wl->conf.fwlog.mode == WL12XX_FWLOG_CONTINUOUS) {
|
|
|
offset = sizeof(addr) + sizeof(struct wl1271_rx_descriptor);
|
|
|
- end_of_log = WLCORE_FW_LOG_END;
|
|
|
+ end_of_log = wl->fwlog_end;
|
|
|
} else {
|
|
|
offset = sizeof(addr);
|
|
|
end_of_log = addr;
|
|
|
}
|
|
|
|
|
|
+ old_part = wl->curr_part;
|
|
|
+ memset(&part, 0, sizeof(part));
|
|
|
+
|
|
|
/* Traverse the memory blocks linked list */
|
|
|
do {
|
|
|
- memset(block, 0, WL12XX_HW_BLOCK_SIZE);
|
|
|
- ret = wlcore_read_hwaddr(wl, addr, block, WL12XX_HW_BLOCK_SIZE,
|
|
|
- false);
|
|
|
+ part.mem.start = wlcore_hw_convert_hwaddr(wl, addr);
|
|
|
+ part.mem.size = PAGE_SIZE;
|
|
|
+
|
|
|
+ ret = wlcore_set_partition(wl, &part);
|
|
|
+ if (ret < 0) {
|
|
|
+ wl1271_error("%s: set_partition start=0x%X size=%d",
|
|
|
+ __func__, part.mem.start, part.mem.size);
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ memset(block, 0, wl->fw_mem_block_size);
|
|
|
+ ret = wlcore_read_hwaddr(wl, addr, block,
|
|
|
+ wl->fw_mem_block_size, false);
|
|
|
+
|
|
|
if (ret < 0)
|
|
|
goto out;
|
|
|
|
|
@@ -884,8 +888,9 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
|
|
|
* on demand mode and is equal to 0x2000000 in continuous mode.
|
|
|
*/
|
|
|
addr = le32_to_cpup((__le32 *)block);
|
|
|
+
|
|
|
if (!wl12xx_copy_fwlog(wl, block + offset,
|
|
|
- WL12XX_HW_BLOCK_SIZE - offset))
|
|
|
+ wl->fw_mem_block_size - offset))
|
|
|
break;
|
|
|
} while (addr && (addr != end_of_log));
|
|
|
|
|
@@ -893,6 +898,7 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
|
|
|
|
|
|
out:
|
|
|
kfree(block);
|
|
|
+ wlcore_set_partition(wl, &old_part);
|
|
|
}
|
|
|
|
|
|
static void wlcore_print_recovery(struct wl1271 *wl)
|