diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath6kl/cfg80211.c')
| -rw-r--r-- | drivers/net/wireless/ath/ath6kl/cfg80211.c | 133 | 
1 files changed, 78 insertions, 55 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 5516a8ccc3c..752ffc4f416 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -427,6 +427,30 @@ static bool ath6kl_is_tx_pending(struct ath6kl *ar)  	return ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0;  } +static void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif, +					      bool enable) +{ +	int err; + +	if (WARN_ON(!test_bit(WMI_READY, &vif->ar->flag))) +		return; + +	if (vif->nw_type != INFRA_NETWORK) +		return; + +	if (!test_bit(ATH6KL_FW_CAPABILITY_BMISS_ENHANCE, +		      vif->ar->fw_capabilities)) +		return; + +	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s fw bmiss enhance\n", +		   enable ? "enable" : "disable"); + +	err = ath6kl_wmi_sta_bmiss_enhance_cmd(vif->ar->wmi, +					       vif->fw_vif_idx, enable); +	if (err) +		ath6kl_err("failed to %s enhanced bmiss detection: %d\n", +			   enable ? "enable" : "disable", err); +}  static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,  				   struct cfg80211_connect_params *sme) @@ -616,13 +640,13 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,  					vif->req_bssid, vif->ch_hint,  					ar->connect_ctrl_flags, nw_subtype); -	/* disable background scan if period is 0 */ -	if (sme->bg_scan_period == 0) +	if (sme->bg_scan_period == 0) { +		/* disable background scan if period is 0 */  		sme->bg_scan_period = 0xffff; - -	/* configure default value if not specified */ -	if (sme->bg_scan_period == -1) +	} else if (sme->bg_scan_period == -1) { +		/* configure default value if not specified */  		sme->bg_scan_period = DEFAULT_BG_SCAN_PERIOD; +	}  	ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 0, 0,  				  sme->bg_scan_period, 0, 0, 0, 3, 0, 0, 0); @@ -767,7 +791,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,  		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",  			   nw_type & ADHOC_CREATOR ? "creator" : "joiner");  		cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL); -		cfg80211_put_bss(bss); +		cfg80211_put_bss(ar->wiphy, bss);  		return;  	} @@ -778,7 +802,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,  					assoc_req_ie, assoc_req_len,  					assoc_resp_ie, assoc_resp_len,  					WLAN_STATUS_SUCCESS, GFP_KERNEL); -		cfg80211_put_bss(bss); +		cfg80211_put_bss(ar->wiphy, bss);  	} else if (vif->sme_state == SME_CONNECTED) {  		/* inform roam event to cfg80211 */  		cfg80211_roamed_bss(vif->ndev, bss, assoc_req_ie, assoc_req_len, @@ -1454,10 +1478,10 @@ static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,  		return -EIO;  	if (pmgmt) { -		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__); +		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);  		mode.pwr_mode = REC_POWER;  	} else { -		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__); +		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);  		mode.pwr_mode = MAX_PERF_POWER;  	} @@ -1509,7 +1533,7 @@ static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,  	list_del(&vif->list);  	spin_unlock_bh(&ar->list_lock); -	ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag)); +	ath6kl_cfg80211_vif_stop(vif, test_bit(WMI_READY, &ar->flag));  	ath6kl_cfg80211_vif_cleanup(vif); @@ -1559,17 +1583,13 @@ static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,  set_iface_type:  	switch (type) {  	case NL80211_IFTYPE_STATION: +	case NL80211_IFTYPE_P2P_CLIENT:  		vif->next_mode = INFRA_NETWORK;  		break;  	case NL80211_IFTYPE_ADHOC:  		vif->next_mode = ADHOC_NETWORK;  		break;  	case NL80211_IFTYPE_AP: -		vif->next_mode = AP_NETWORK; -		break; -	case NL80211_IFTYPE_P2P_CLIENT: -		vif->next_mode = INFRA_NETWORK; -		break;  	case NL80211_IFTYPE_P2P_GO:  		vif->next_mode = AP_NETWORK;  		break; @@ -1778,14 +1798,14 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,  	if (vif->target_stats.rx_byte) {  		sinfo->rx_bytes = vif->target_stats.rx_byte; -		sinfo->filled |= STATION_INFO_RX_BYTES; +		sinfo->filled |= STATION_INFO_RX_BYTES64;  		sinfo->rx_packets = vif->target_stats.rx_pkt;  		sinfo->filled |= STATION_INFO_RX_PACKETS;  	}  	if (vif->target_stats.tx_byte) {  		sinfo->tx_bytes = vif->target_stats.tx_byte; -		sinfo->filled |= STATION_INFO_TX_BYTES; +		sinfo->filled |= STATION_INFO_TX_BYTES64;  		sinfo->tx_packets = vif->target_stats.tx_pkt;  		sinfo->filled |= STATION_INFO_TX_PACKETS;  	} @@ -2673,30 +2693,6 @@ static int ath6kl_set_ies(struct ath6kl_vif *vif,  	return 0;  } -void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif, bool enable) -{ -	int err; - -	if (WARN_ON(!test_bit(WMI_READY, &vif->ar->flag))) -		return; - -	if (vif->nw_type != INFRA_NETWORK) -		return; - -	if (!test_bit(ATH6KL_FW_CAPABILITY_BMISS_ENHANCE, -		      vif->ar->fw_capabilities)) -		return; - -	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s fw bmiss enhance\n", -		   enable ? "enable" : "disable"); - -	err = ath6kl_wmi_sta_bmiss_enhance_cmd(vif->ar->wmi, -					       vif->fw_vif_idx, enable); -	if (err) -		ath6kl_err("failed to %s enhanced bmiss detection: %d\n", -			   enable ? "enable" : "disable", err); -} -  static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon,  				u8 *rsn_capab)  { @@ -2776,9 +2772,11 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,  	ar->ap_mode_bkey.valid = false; -	/* TODO: -	 * info->interval -	 */ +	ret = ath6kl_wmi_ap_set_beacon_intvl_cmd(ar->wmi, vif->fw_vif_idx, +						 info->beacon_interval); + +	if (ret) +		ath6kl_warn("Failed to set beacon interval: %d\n", ret);  	ret = ath6kl_wmi_ap_set_dtim_cmd(ar->wmi, vif->fw_vif_idx,  					 info->dtim_period); @@ -3492,8 +3490,8 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar)  		ath6kl_cfg80211_stop(vif);  } -static int ath6kl_cfg80211_reg_notify(struct wiphy *wiphy, -				      struct regulatory_request *request) +static void ath6kl_cfg80211_reg_notify(struct wiphy *wiphy, +				       struct regulatory_request *request)  {  	struct ath6kl *ar = wiphy_priv(wiphy);  	u32 rates[IEEE80211_NUM_BANDS]; @@ -3506,17 +3504,13 @@ static int ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,  		   request->processed ? " processed" : "",  		   request->initiator, request->user_reg_hint_type); -	/* -	 * As firmware is not able intersect regdoms, we can only listen to -	 * cellular hints. -	 */  	if (request->user_reg_hint_type != NL80211_USER_REG_HINT_CELL_BASE) -		return -EOPNOTSUPP; +		return;  	ret = ath6kl_wmi_set_regdomain_cmd(ar->wmi, request->alpha2);  	if (ret) {  		ath6kl_err("failed to set regdomain: %d\n", ret); -		return ret; +		return;  	}  	/* @@ -3536,10 +3530,8 @@ static int ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,  	if (ret) {  		ath6kl_err("failed to start scan for a regdomain change: %d\n",  			   ret); -		return ret; +		return;  	} - -	return 0;  }  static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif) @@ -3563,6 +3555,37 @@ static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif)  	return 0;  } +void ath6kl_cfg80211_vif_stop(struct ath6kl_vif *vif, bool wmi_ready) +{ +	static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; +	bool discon_issued; + +	netif_stop_queue(vif->ndev); + +	clear_bit(WLAN_ENABLED, &vif->flags); + +	if (wmi_ready) { +		discon_issued = test_bit(CONNECTED, &vif->flags) || +				test_bit(CONNECT_PEND, &vif->flags); +		ath6kl_disconnect(vif); +		del_timer(&vif->disconnect_timer); + +		if (discon_issued) +			ath6kl_disconnect_event(vif, DISCONNECT_CMD, +						(vif->nw_type & AP_NETWORK) ? +						bcast_mac : vif->bssid, +						0, NULL, 0); +	} + +	if (vif->scan_req) { +		cfg80211_scan_done(vif->scan_req, true); +		vif->scan_req = NULL; +	} + +	/* need to clean up enhanced bmiss detection fw state */ +	ath6kl_cfg80211_sta_bmiss_enhance(vif, false); +} +  void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif)  {  	struct ath6kl *ar = vif->ar;  |