Search Linux Wireless

Re: [PATCH] wcn36xx: dequeue all pending indicator messages

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

 



On Thu 15 Mar 15:37 PDT 2018, Daniel Mack wrote:

> In case wcn36xx_smd_rsp_process() is called more than once before
> hal_ind_work was dispatched, the messages will end up in hal_ind_queue,
> but wcn36xx_ind_smd_work() will only look at the first message in that
> list.
> 
> Fix this by dequeing the messages from the list in a loop, and only stop
> when it's empty.
> 

Reviewed-by: Bjorn Andersson <bjorn.andersson@xxxxxxxxxx>

Thanks for fixing this, I thought I already had done that.

Regards,
Bjorn

> Signed-off-by: Daniel Mack <daniel@xxxxxxxxxx>
> ---
>  drivers/net/wireless/ath/wcn36xx/smd.c | 95 +++++++++++++++++++---------------
>  1 file changed, 52 insertions(+), 43 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
> index 7cc29285e052..a6b5352f59e9 100644
> --- a/drivers/net/wireless/ath/wcn36xx/smd.c
> +++ b/drivers/net/wireless/ath/wcn36xx/smd.c
> @@ -2409,54 +2409,63 @@ static void wcn36xx_ind_smd_work(struct work_struct *work)
>  {
>  	struct wcn36xx *wcn =
>  		container_of(work, struct wcn36xx, hal_ind_work);
> -	struct wcn36xx_hal_msg_header *msg_header;
> -	struct wcn36xx_hal_ind_msg *hal_ind_msg;
> -	unsigned long flags;
>  
> -	spin_lock_irqsave(&wcn->hal_ind_lock, flags);
> +	for (;;) {
> +		struct wcn36xx_hal_msg_header *msg_header;
> +		struct wcn36xx_hal_ind_msg *hal_ind_msg;
> +		unsigned long flags;
>  
> -	hal_ind_msg = list_first_entry(&wcn->hal_ind_queue,
> -				       struct wcn36xx_hal_ind_msg,
> -				       list);
> -	list_del(wcn->hal_ind_queue.next);
> -	spin_unlock_irqrestore(&wcn->hal_ind_lock, flags);
> +		spin_lock_irqsave(&wcn->hal_ind_lock, flags);
>  
> -	msg_header = (struct wcn36xx_hal_msg_header *)hal_ind_msg->msg;
> +		if (list_empty(&wcn->hal_ind_queue)) {
> +			spin_unlock_irqrestore(&wcn->hal_ind_lock, flags);
> +			return;
> +		}
>  
> -	switch (msg_header->msg_type) {
> -	case WCN36XX_HAL_COEX_IND:
> -	case WCN36XX_HAL_DEL_BA_IND:
> -	case WCN36XX_HAL_AVOID_FREQ_RANGE_IND:
> -		break;
> -	case WCN36XX_HAL_OTA_TX_COMPL_IND:
> -		wcn36xx_smd_tx_compl_ind(wcn,
> -					 hal_ind_msg->msg,
> -					 hal_ind_msg->msg_len);
> -		break;
> -	case WCN36XX_HAL_MISSED_BEACON_IND:
> -		wcn36xx_smd_missed_beacon_ind(wcn,
> -					      hal_ind_msg->msg,
> -					      hal_ind_msg->msg_len);
> -		break;
> -	case WCN36XX_HAL_DELETE_STA_CONTEXT_IND:
> -		wcn36xx_smd_delete_sta_context_ind(wcn,
> -						   hal_ind_msg->msg,
> -						   hal_ind_msg->msg_len);
> -		break;
> -	case WCN36XX_HAL_PRINT_REG_INFO_IND:
> -		wcn36xx_smd_print_reg_info_ind(wcn,
> -					       hal_ind_msg->msg,
> -					       hal_ind_msg->msg_len);
> -		break;
> -	case WCN36XX_HAL_SCAN_OFFLOAD_IND:
> -		wcn36xx_smd_hw_scan_ind(wcn, hal_ind_msg->msg,
> -					hal_ind_msg->msg_len);
> -		break;
> -	default:
> -		wcn36xx_err("SMD_EVENT (%d) not supported\n",
> -			      msg_header->msg_type);
> +		hal_ind_msg = list_first_entry(&wcn->hal_ind_queue,
> +					       struct wcn36xx_hal_ind_msg,
> +					       list);
> +		list_del(&hal_ind_msg->list);
> +		spin_unlock_irqrestore(&wcn->hal_ind_lock, flags);
> +
> +		msg_header = (struct wcn36xx_hal_msg_header *)hal_ind_msg->msg;
> +
> +		switch (msg_header->msg_type) {
> +		case WCN36XX_HAL_COEX_IND:
> +		case WCN36XX_HAL_DEL_BA_IND:
> +		case WCN36XX_HAL_AVOID_FREQ_RANGE_IND:
> +			break;
> +		case WCN36XX_HAL_OTA_TX_COMPL_IND:
> +			wcn36xx_smd_tx_compl_ind(wcn,
> +						 hal_ind_msg->msg,
> +						 hal_ind_msg->msg_len);
> +			break;
> +		case WCN36XX_HAL_MISSED_BEACON_IND:
> +			wcn36xx_smd_missed_beacon_ind(wcn,
> +						      hal_ind_msg->msg,
> +						      hal_ind_msg->msg_len);
> +			break;
> +		case WCN36XX_HAL_DELETE_STA_CONTEXT_IND:
> +			wcn36xx_smd_delete_sta_context_ind(wcn,
> +							   hal_ind_msg->msg,
> +							   hal_ind_msg->msg_len);
> +			break;
> +		case WCN36XX_HAL_PRINT_REG_INFO_IND:
> +			wcn36xx_smd_print_reg_info_ind(wcn,
> +						       hal_ind_msg->msg,
> +						       hal_ind_msg->msg_len);
> +			break;
> +		case WCN36XX_HAL_SCAN_OFFLOAD_IND:
> +			wcn36xx_smd_hw_scan_ind(wcn, hal_ind_msg->msg,
> +						hal_ind_msg->msg_len);
> +			break;
> +		default:
> +			wcn36xx_err("SMD_EVENT (%d) not supported\n",
> +				    msg_header->msg_type);
> +		}
> +
> +		kfree(hal_ind_msg);
>  	}
> -	kfree(hal_ind_msg);
>  }
>  int wcn36xx_smd_open(struct wcn36xx *wcn)
>  {
> -- 
> 2.14.3
> 
> 
> _______________________________________________
> wcn36xx mailing list
> wcn36xx@xxxxxxxxxxxxxxxxxxx
> http://lists.infradead.org/mailman/listinfo/wcn36xx



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

  Powered by Linux