|
@@ -770,14 +770,16 @@ 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)
|
|
|
{
|
|
|
u32 addr;
|
|
|
- u32 first_addr;
|
|
|
+ u32 offset;
|
|
|
+ u32 end_of_log;
|
|
|
u8 *block;
|
|
|
|
|
|
if ((wl->quirks & WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED) ||
|
|
|
- (wl->conf.fwlog.mode != WL12XX_FWLOG_ON_DEMAND) ||
|
|
|
(wl->conf.fwlog.mem_blocks == 0))
|
|
|
return;
|
|
|
|
|
@@ -791,19 +793,26 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
|
|
|
* Make sure the chip is awake and the logger isn't active.
|
|
|
* Do not send a stop fwlog command if the fw is hanged.
|
|
|
*/
|
|
|
- if (!wl1271_ps_elp_wakeup(wl) && !wl->watchdog_recovery)
|
|
|
- wl12xx_cmd_stop_fwlog(wl);
|
|
|
- else
|
|
|
+ if (wl1271_ps_elp_wakeup(wl))
|
|
|
goto out;
|
|
|
+ if (!wl->watchdog_recovery)
|
|
|
+ wl12xx_cmd_stop_fwlog(wl);
|
|
|
|
|
|
/* Read the first memory block address */
|
|
|
wl12xx_fw_status(wl, wl->fw_status_1, wl->fw_status_2);
|
|
|
- first_addr = le32_to_cpu(wl->fw_status_2->log_start_addr);
|
|
|
- if (!first_addr)
|
|
|
+ addr = le32_to_cpu(wl->fw_status_2->log_start_addr);
|
|
|
+ if (!addr)
|
|
|
goto out;
|
|
|
|
|
|
+ if (wl->conf.fwlog.mode == WL12XX_FWLOG_CONTINUOUS) {
|
|
|
+ offset = sizeof(addr) + sizeof(struct wl1271_rx_descriptor);
|
|
|
+ end_of_log = WLCORE_FW_LOG_END;
|
|
|
+ } else {
|
|
|
+ offset = sizeof(addr);
|
|
|
+ end_of_log = addr;
|
|
|
+ }
|
|
|
+
|
|
|
/* Traverse the memory blocks linked list */
|
|
|
- addr = first_addr;
|
|
|
do {
|
|
|
memset(block, 0, WL12XX_HW_BLOCK_SIZE);
|
|
|
wl1271_read_hwaddr(wl, addr, block, WL12XX_HW_BLOCK_SIZE,
|
|
@@ -812,13 +821,14 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
|
|
|
/*
|
|
|
* Memory blocks are linked to one another. The first 4 bytes
|
|
|
* of each memory block hold the hardware address of the next
|
|
|
- * one. The last memory block points to the first one.
|
|
|
+ * one. The last memory block points to the first one in
|
|
|
+ * on demand mode and is equal to 0x2000000 in continuous mode.
|
|
|
*/
|
|
|
addr = le32_to_cpup((__le32 *)block);
|
|
|
- if (!wl12xx_copy_fwlog(wl, block + sizeof(addr),
|
|
|
- WL12XX_HW_BLOCK_SIZE - sizeof(addr)))
|
|
|
+ if (!wl12xx_copy_fwlog(wl, block + offset,
|
|
|
+ WL12XX_HW_BLOCK_SIZE - offset))
|
|
|
break;
|
|
|
- } while (addr && (addr != first_addr));
|
|
|
+ } while (addr && (addr != end_of_log));
|
|
|
|
|
|
wake_up_interruptible(&wl->fwlog_waitq);
|
|
|
|