diff options
Diffstat (limited to 'drivers/net/wireless/ath/wcn36xx/main.c')
| -rw-r--r-- | drivers/net/wireless/ath/wcn36xx/main.c | 53 | 
1 files changed, 46 insertions, 7 deletions
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index 69d6be59d97f..aeb5e6e806be 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -26,6 +26,7 @@  #include <linux/soc/qcom/smem_state.h>  #include <linux/soc/qcom/wcnss_ctrl.h>  #include "wcn36xx.h" +#include "testmode.h"  unsigned int wcn36xx_dbg_mask;  module_param_named(debug_mask, wcn36xx_dbg_mask, uint, 0644); @@ -353,6 +354,19 @@ static void wcn36xx_stop(struct ieee80211_hw *hw)  	wcn36xx_dbg(WCN36XX_DBG_MAC, "mac stop\n"); +	cancel_work_sync(&wcn->scan_work); + +	mutex_lock(&wcn->scan_lock); +	if (wcn->scan_req) { +		struct cfg80211_scan_info scan_info = { +			.aborted = true, +		}; + +		ieee80211_scan_completed(wcn->hw, &scan_info); +	} +	wcn->scan_req = NULL; +	mutex_unlock(&wcn->scan_lock); +  	wcn36xx_debugfs_exit(wcn);  	wcn36xx_smd_stop(wcn);  	wcn36xx_dxe_deinit(wcn); @@ -549,6 +563,7 @@ static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,  		} else {  			wcn36xx_smd_set_bsskey(wcn,  				vif_priv->encrypt_type, +				vif_priv->bss_index,  				key_conf->keyidx,  				key_conf->keylen,  				key); @@ -566,10 +581,13 @@ static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,  		break;  	case DISABLE_KEY:  		if (!(IEEE80211_KEY_FLAG_PAIRWISE & key_conf->flags)) { +			if (vif_priv->bss_index != WCN36XX_HAL_BSS_INVALID_IDX) +				wcn36xx_smd_remove_bsskey(wcn, +					vif_priv->encrypt_type, +					vif_priv->bss_index, +					key_conf->keyidx); +  			vif_priv->encrypt_type = WCN36XX_HAL_ED_NONE; -			wcn36xx_smd_remove_bsskey(wcn, -				vif_priv->encrypt_type, -				key_conf->keyidx);  		} else {  			sta_priv->is_data_encrypted = false;  			/* do not remove key if disassociated */ @@ -670,10 +688,18 @@ static void wcn36xx_cancel_hw_scan(struct ieee80211_hw *hw,  	wcn->scan_aborted = true;  	mutex_unlock(&wcn->scan_lock); -	/* ieee80211_scan_completed will be called on FW scan indication */ -	wcn36xx_smd_stop_hw_scan(wcn); - -	cancel_work_sync(&wcn->scan_work); +	if (get_feat_caps(wcn->fw_feat_caps, SCAN_OFFLOAD)) { +		/* ieee80211_scan_completed will be called on FW scan +		 * indication */ +		wcn36xx_smd_stop_hw_scan(wcn); +	} else { +		struct cfg80211_scan_info scan_info = { +			.aborted = true, +		}; + +		cancel_work_sync(&wcn->scan_work); +		ieee80211_scan_completed(wcn->hw, &scan_info); +	}  }  static void wcn36xx_update_allowed_rates(struct ieee80211_sta *sta, @@ -773,6 +799,8 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,  		if (!is_zero_ether_addr(bss_conf->bssid)) {  			vif_priv->is_joining = true;  			vif_priv->bss_index = WCN36XX_HAL_BSS_INVALID_IDX; +			wcn36xx_smd_set_link_st(wcn, bss_conf->bssid, vif->addr, +						WCN36XX_HAL_LINK_PREASSOC_STATE);  			wcn36xx_smd_join(wcn, bss_conf->bssid,  					 vif->addr, WCN36XX_HW_CHANNEL(wcn));  			wcn36xx_smd_config_bss(wcn, vif, NULL, @@ -780,6 +808,8 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,  		} else {  			vif_priv->is_joining = false;  			wcn36xx_smd_delete_bss(wcn, vif); +			wcn36xx_smd_set_link_st(wcn, bss_conf->bssid, vif->addr, +						WCN36XX_HAL_LINK_IDLE_STATE);  			vif_priv->encrypt_type = WCN36XX_HAL_ED_NONE;  		}  	} @@ -953,6 +983,7 @@ static int wcn36xx_add_interface(struct ieee80211_hw *hw,  	mutex_lock(&wcn->conf_mutex); +	vif_priv->bss_index = WCN36XX_HAL_BSS_INVALID_IDX;  	list_add(&vif_priv->list, &wcn->vif_list);  	wcn36xx_smd_add_sta_self(wcn, vif); @@ -1116,6 +1147,8 @@ static const struct ieee80211_ops wcn36xx_ops = {  	.sta_add		= wcn36xx_sta_add,  	.sta_remove		= wcn36xx_sta_remove,  	.ampdu_action		= wcn36xx_ampdu_action, + +	CFG80211_TESTMODE_CMD(wcn36xx_tm_cmd)  };  static int wcn36xx_init_ieee80211(struct wcn36xx *wcn) @@ -1283,6 +1316,12 @@ static int wcn36xx_probe(struct platform_device *pdev)  	mutex_init(&wcn->hal_mutex);  	mutex_init(&wcn->scan_lock); +	ret = dma_set_mask_and_coherent(wcn->dev, DMA_BIT_MASK(32)); +	if (ret < 0) { +		wcn36xx_err("failed to set DMA mask: %d\n", ret); +		goto out_wq; +	} +  	INIT_WORK(&wcn->scan_work, wcn36xx_hw_scan_worker);  	wcn->smd_channel = qcom_wcnss_open_channel(wcnss, "WLAN_CTRL", wcn36xx_smd_rsp_process, hw);  | 
