diff options
Diffstat (limited to 'net/mac80211/ibss.c')
| -rw-r--r-- | net/mac80211/ibss.c | 114 | 
1 files changed, 42 insertions, 72 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 170f9a7fa319..ea7b9c2c7e66 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -54,7 +54,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,  	struct beacon_data *presp;  	int frame_len; -	lockdep_assert_held(&ifibss->mtx); +	sdata_assert_lock(sdata);  	/* Reset own TSF to allow time synchronization work. */  	drv_reset_tsf(local, sdata); @@ -74,14 +74,14 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,  	}  	presp = rcu_dereference_protected(ifibss->presp, -					  lockdep_is_held(&ifibss->mtx)); +					  lockdep_is_held(&sdata->wdev.mtx));  	rcu_assign_pointer(ifibss->presp, NULL);  	if (presp)  		kfree_rcu(presp, rcu_head);  	sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; -	cfg80211_chandef_create(&chandef, chan, ifibss->channel_type); +	chandef = ifibss->chandef;  	if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) {  		chandef.width = NL80211_CHAN_WIDTH_20;  		chandef.center_freq1 = chan->center_freq; @@ -176,6 +176,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,  	/* add HT capability and information IEs */  	if (chandef.width != NL80211_CHAN_WIDTH_20_NOHT && +	    chandef.width != NL80211_CHAN_WIDTH_5 && +	    chandef.width != NL80211_CHAN_WIDTH_10 &&  	    sband->ht_cap.ht_supported) {  		pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap,  						sband->ht_cap.cap); @@ -263,7 +265,7 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,  	const struct cfg80211_bss_ies *ies;  	u64 tsf; -	lockdep_assert_held(&sdata->u.ibss.mtx); +	sdata_assert_lock(sdata);  	if (beacon_int < 10)  		beacon_int = 10; @@ -298,8 +300,7 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,  				  tsf, false);  } -static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, -						  bool auth) +static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta)  	__acquires(RCU)  {  	struct ieee80211_sub_if_data *sdata = sta->sdata; @@ -321,26 +322,19 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta,  	/* If it fails, maybe we raced another insertion? */  	if (sta_info_insert_rcu(sta))  		return sta_info_get(sdata, addr); -	if (auth && !sdata->u.ibss.auth_frame_registrations) { -		ibss_dbg(sdata, -			 "TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n", -			 sdata->vif.addr, addr, sdata->u.ibss.bssid); -		ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, 0, NULL, 0, -				    addr, sdata->u.ibss.bssid, NULL, 0, 0, 0); -	}  	return sta;  }  static struct sta_info * -ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, -		       const u8 *bssid, const u8 *addr, -		       u32 supp_rates, bool auth) +ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, const u8 *bssid, +		       const u8 *addr, u32 supp_rates)  	__acquires(RCU)  {  	struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;  	struct ieee80211_local *local = sdata->local;  	struct sta_info *sta;  	struct ieee80211_chanctx_conf *chanctx_conf; +	struct ieee80211_supported_band *sband;  	int band;  	/* @@ -380,10 +374,11 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,  	sta->last_rx = jiffies;  	/* make sure mandatory rates are always added */ +	sband = local->hw.wiphy->bands[band];  	sta->sta.supp_rates[band] = supp_rates | -			ieee80211_mandatory_rates(local, band); +			ieee80211_mandatory_rates(sband); -	return ieee80211_ibss_finish_sta(sta, auth); +	return ieee80211_ibss_finish_sta(sta);  }  static void ieee80211_rx_mgmt_deauth_ibss(struct ieee80211_sub_if_data *sdata, @@ -405,10 +400,8 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,  					size_t len)  {  	u16 auth_alg, auth_transaction; -	struct sta_info *sta; -	u8 deauth_frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; -	lockdep_assert_held(&sdata->u.ibss.mtx); +	sdata_assert_lock(sdata);  	if (len < 24 + 6)  		return; @@ -423,22 +416,6 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,  	if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)  		return; -	sta_info_destroy_addr(sdata, mgmt->sa); -	sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false); -	rcu_read_unlock(); - -	/* -	 * if we have any problem in allocating the new station, we reply with a -	 * DEAUTH frame to tell the other end that we had a problem -	 */ -	if (!sta) { -		ieee80211_send_deauth_disassoc(sdata, sdata->u.ibss.bssid, -					       IEEE80211_STYPE_DEAUTH, -					       WLAN_REASON_UNSPECIFIED, true, -					       deauth_frame_buf); -		return; -	} -  	/*  	 * IEEE 802.11 standard does not require authentication in IBSS  	 * networks and most implementations do not seem to use it. @@ -492,7 +469,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,  				prev_rates = sta->sta.supp_rates[band];  				/* make sure mandatory rates are always added */  				sta->sta.supp_rates[band] = supp_rates | -					ieee80211_mandatory_rates(local, band); +					ieee80211_mandatory_rates(sband);  				if (sta->sta.supp_rates[band] != prev_rates) {  					ibss_dbg(sdata, @@ -504,7 +481,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,  			} else {  				rcu_read_unlock();  				sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, -						mgmt->sa, supp_rates, true); +						mgmt->sa, supp_rates);  			}  		} @@ -512,7 +489,9 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,  			set_sta_flag(sta, WLAN_STA_WME);  		if (sta && elems->ht_operation && elems->ht_cap_elem && -		    sdata->u.ibss.channel_type != NL80211_CHAN_NO_HT) { +		    sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT && +		    sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_5 && +		    sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_10) {  			/* we both use HT */  			struct ieee80211_ht_cap htcap_ie;  			struct cfg80211_chan_def chandef; @@ -527,8 +506,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,  			 * fall back to HT20 if we don't use or use  			 * the other extension channel  			 */ -			if (cfg80211_get_chandef_type(&chandef) != -						sdata->u.ibss.channel_type) +			if (chandef.center_freq1 != +			    sdata->u.ibss.chandef.center_freq1)  				htcap_ie.cap_info &=  					cpu_to_le16(~IEEE80211_HT_CAP_SUP_WIDTH_20_40); @@ -567,7 +546,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,  	/* different channel */  	if (sdata->u.ibss.fixed_channel && -	    sdata->u.ibss.channel != cbss->channel) +	    sdata->u.ibss.chandef.chan != cbss->channel)  		goto put_bss;  	/* different SSID */ @@ -608,7 +587,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,  		ieee80211_sta_join_ibss(sdata, bss);  		supp_rates = ieee80211_sta_get_rates(local, elems, band, NULL);  		ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, -				       supp_rates, true); +				       supp_rates);  		rcu_read_unlock();  	} @@ -624,6 +603,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,  	struct ieee80211_local *local = sdata->local;  	struct sta_info *sta;  	struct ieee80211_chanctx_conf *chanctx_conf; +	struct ieee80211_supported_band *sband;  	int band;  	/* @@ -658,8 +638,9 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,  	sta->last_rx = jiffies;  	/* make sure mandatory rates are always added */ +	sband = local->hw.wiphy->bands[band];  	sta->sta.supp_rates[band] = supp_rates | -			ieee80211_mandatory_rates(local, band); +			ieee80211_mandatory_rates(sband);  	spin_lock(&ifibss->incomplete_lock);  	list_add(&sta->list, &ifibss->incomplete_stations); @@ -673,7 +654,7 @@ static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)  	int active = 0;  	struct sta_info *sta; -	lockdep_assert_held(&sdata->u.ibss.mtx); +	sdata_assert_lock(sdata);  	rcu_read_lock(); @@ -699,7 +680,7 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)  {  	struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; -	lockdep_assert_held(&ifibss->mtx); +	sdata_assert_lock(sdata);  	mod_timer(&ifibss->timer,  		  round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL)); @@ -730,7 +711,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)  	u16 capability;  	int i; -	lockdep_assert_held(&ifibss->mtx); +	sdata_assert_lock(sdata);  	if (ifibss->fixed_bssid) {  		memcpy(bssid, ifibss->bssid, ETH_ALEN); @@ -755,7 +736,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)  		sdata->drop_unencrypted = 0;  	__ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int, -				  ifibss->channel, ifibss->basic_rates, +				  ifibss->chandef.chan, ifibss->basic_rates,  				  capability, 0, true);  } @@ -773,7 +754,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)  	int active_ibss;  	u16 capability; -	lockdep_assert_held(&ifibss->mtx); +	sdata_assert_lock(sdata);  	active_ibss = ieee80211_sta_active_ibss(sdata);  	ibss_dbg(sdata, "sta_find_ibss (active_ibss=%d)\n", active_ibss); @@ -787,7 +768,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)  	if (ifibss->fixed_bssid)  		bssid = ifibss->bssid;  	if (ifibss->fixed_channel) -		chan = ifibss->channel; +		chan = ifibss->chandef.chan;  	if (!is_zero_ether_addr(ifibss->bssid))  		bssid = ifibss->bssid;  	cbss = cfg80211_get_bss(local->hw.wiphy, chan, bssid, @@ -843,10 +824,10 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,  	struct beacon_data *presp;  	u8 *pos, *end; -	lockdep_assert_held(&ifibss->mtx); +	sdata_assert_lock(sdata);  	presp = rcu_dereference_protected(ifibss->presp, -					  lockdep_is_held(&ifibss->mtx)); +					  lockdep_is_held(&sdata->wdev.mtx));  	if (ifibss->state != IEEE80211_IBSS_MLME_JOINED ||  	    len < 24 + 2 || !presp) @@ -930,7 +911,7 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,  	mgmt = (struct ieee80211_mgmt *) skb->data;  	fc = le16_to_cpu(mgmt->frame_control); -	mutex_lock(&sdata->u.ibss.mtx); +	sdata_lock(sdata);  	if (!sdata->u.ibss.ssid_len)  		goto mgmt_out; /* not ready to merge yet */ @@ -953,7 +934,7 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,  	}   mgmt_out: -	mutex_unlock(&sdata->u.ibss.mtx); +	sdata_unlock(sdata);  }  void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata) @@ -961,7 +942,7 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)  	struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;  	struct sta_info *sta; -	mutex_lock(&ifibss->mtx); +	sdata_lock(sdata);  	/*  	 * Work could be scheduled after scan or similar @@ -978,7 +959,7 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)  		list_del(&sta->list);  		spin_unlock_bh(&ifibss->incomplete_lock); -		ieee80211_ibss_finish_sta(sta, true); +		ieee80211_ibss_finish_sta(sta);  		rcu_read_unlock();  		spin_lock_bh(&ifibss->incomplete_lock);  	} @@ -997,7 +978,7 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)  	}   out: -	mutex_unlock(&ifibss->mtx); +	sdata_unlock(sdata);  }  static void ieee80211_ibss_timer(unsigned long data) @@ -1014,7 +995,6 @@ void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata)  	setup_timer(&ifibss->timer, ieee80211_ibss_timer,  		    (unsigned long) sdata); -	mutex_init(&ifibss->mtx);  	INIT_LIST_HEAD(&ifibss->incomplete_stations);  	spin_lock_init(&ifibss->incomplete_lock);  } @@ -1041,8 +1021,6 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,  {  	u32 changed = 0; -	mutex_lock(&sdata->u.ibss.mtx); -  	if (params->bssid) {  		memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN);  		sdata->u.ibss.fixed_bssid = true; @@ -1057,9 +1035,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,  	sdata->vif.bss_conf.beacon_int = params->beacon_interval; -	sdata->u.ibss.channel = params->chandef.chan; -	sdata->u.ibss.channel_type = -		cfg80211_get_chandef_type(¶ms->chandef); +	sdata->u.ibss.chandef = params->chandef;  	sdata->u.ibss.fixed_channel = params->channel_fixed;  	if (params->ie) { @@ -1075,8 +1051,6 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,  	memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len);  	sdata->u.ibss.ssid_len = params->ssid_len; -	mutex_unlock(&sdata->u.ibss.mtx); -  	/*  	 * 802.11n-2009 9.13.3.1: In an IBSS, the HT Protection field is  	 * reserved, but an HT STA shall protect HT transmissions as though @@ -1112,8 +1086,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)  	struct sta_info *sta;  	struct beacon_data *presp; -	mutex_lock(&sdata->u.ibss.mtx); -  	active_ibss = ieee80211_sta_active_ibss(sdata);  	if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) { @@ -1122,7 +1094,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)  		if (ifibss->privacy)  			capability |= WLAN_CAPABILITY_PRIVACY; -		cbss = cfg80211_get_bss(local->hw.wiphy, ifibss->channel, +		cbss = cfg80211_get_bss(local->hw.wiphy, ifibss->chandef.chan,  					ifibss->bssid, ifibss->ssid,  					ifibss->ssid_len, WLAN_CAPABILITY_IBSS |  					WLAN_CAPABILITY_PRIVACY, @@ -1157,7 +1129,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)  	/* remove beacon */  	kfree(sdata->u.ibss.ie);  	presp = rcu_dereference_protected(ifibss->presp, -					  lockdep_is_held(&sdata->u.ibss.mtx)); +					  lockdep_is_held(&sdata->wdev.mtx));  	RCU_INIT_POINTER(sdata->u.ibss.presp, NULL);  	sdata->vif.bss_conf.ibss_joined = false;  	sdata->vif.bss_conf.ibss_creator = false; @@ -1173,7 +1145,5 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)  	del_timer_sync(&sdata->u.ibss.timer); -	mutex_unlock(&sdata->u.ibss.mtx); -  	return 0;  }  | 
