Search Linux Wireless

Re: [PATCH 08/12] wlcore: read FW logs from FW memory on watchdog recovery

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



And Igal on this one...

On Thu, 2012-06-21 at 17:13 +0300, Luciano Coelho wrote:
> From: Igal Chernobelsky <igalc@xxxxxx>
> 
> FW uses a few memory blocks as a buffer to accumulate FW logs before
> transmitting them to the host over SDIO. When FW WatchDog recovery
> occurs, the last FW traces are still pending in the buffer. Driver is
> to read these FW traces whether log mode is continuous or on demand.
> 
> FW memory blocks allocated for the log buffer are handled as a link list:
> the first 4 bytes in each memory block contain FW address to the next block.
> The end of list condition depends on FW log mode:
> - on demand: the list is cyclic, the next address is equal to the first address
> - continuous: the address is  equal to 0x2000000
> 
> Log data resides inside FW memory block with offset depending on
> logger mode:
> - on demand:  4 bytes (address of the next memory block)
> - continuous: 4 bytes and Rx Descriptor structure size
> 
> Described FW logger API is backward compatible with previous FW versions.
> 
> Signed-off-by: Igal Chernobelsky <igalc@xxxxxx>
> Signed-off-by: Luciano Coelho <coelho@xxxxxx>
> ---
>  drivers/net/wireless/ti/wlcore/main.c |   34 +++++++++++++++++++++------------
>  1 file changed, 22 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
> index a7c5e32..78edc58 100644
> --- a/drivers/net/wireless/ti/wlcore/main.c
> +++ b/drivers/net/wireless/ti/wlcore/main.c
> @@ -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);
>  


--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux