mac80211: fix current vs. operating channel in preq/beacon

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Sat Sep 29 10:59:38 EDT 2012


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=6b77863b719a4e32909c218c0d5a83a14f4d98c5
Commit:     6b77863b719a4e32909c218c0d5a83a14f4d98c5
Parent:     679ef4eadde1f8e55074427c0d8de2da55ca81f9
Author:     Johannes Berg <johannes.berg at intel.com>
AuthorDate: Mon Jul 23 14:53:27 2012 +0200
Committer:  Johannes Berg <johannes.berg at intel.com>
CommitDate: Tue Jul 31 16:18:56 2012 +0200

    mac80211: fix current vs. operating channel in preq/beacon
    
    When sending probe requests, e.g. during software scanning,
    these will go out on the *current* channel, so their IEs
    need to be built from the current channel. At other times,
    e.g. for beacons or probe request templates, the IEs will
    be used on the *operating* channel and using the current
    channel instead might result in errors.
    
    Add the appropriate parameters to respect the difference.
    
    Signed-off-by: Johannes Berg <johannes.berg at intel.com>
---
 net/mac80211/cfg.c         |   20 ++++++++++++++------
 net/mac80211/ieee80211_i.h |    7 +++++--
 net/mac80211/mesh_plink.c  |    6 ++++--
 net/mac80211/mlme.c        |    4 +++-
 net/mac80211/tx.c          |    6 +++---
 net/mac80211/util.c        |   27 +++++++++++++++------------
 6 files changed, 44 insertions(+), 26 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 1b8d191..5583f5b 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2655,6 +2655,7 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
 			       u16 status_code, struct sk_buff *skb)
 {
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_tdls_data *tf;
 
 	tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u));
@@ -2674,8 +2675,10 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
 		tf->u.setup_req.capability =
 			cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
 
-		ieee80211_add_srates_ie(sdata, skb, false);
-		ieee80211_add_ext_srates_ie(sdata, skb, false);
+		ieee80211_add_srates_ie(sdata, skb, false,
+					local->oper_channel->band);
+		ieee80211_add_ext_srates_ie(sdata, skb, false,
+					    local->oper_channel->band);
 		ieee80211_tdls_add_ext_capab(skb);
 		break;
 	case WLAN_TDLS_SETUP_RESPONSE:
@@ -2688,8 +2691,10 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
 		tf->u.setup_resp.capability =
 			cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
 
-		ieee80211_add_srates_ie(sdata, skb, false);
-		ieee80211_add_ext_srates_ie(sdata, skb, false);
+		ieee80211_add_srates_ie(sdata, skb, false,
+					local->oper_channel->band);
+		ieee80211_add_ext_srates_ie(sdata, skb, false,
+					    local->oper_channel->band);
 		ieee80211_tdls_add_ext_capab(skb);
 		break;
 	case WLAN_TDLS_SETUP_CONFIRM:
@@ -2727,6 +2732,7 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
 			   u16 status_code, struct sk_buff *skb)
 {
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_mgmt *mgmt;
 
 	mgmt = (void *)skb_put(skb, 24);
@@ -2749,8 +2755,10 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
 		mgmt->u.action.u.tdls_discover_resp.capability =
 			cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
 
-		ieee80211_add_srates_ie(sdata, skb, false);
-		ieee80211_add_ext_srates_ie(sdata, skb, false);
+		ieee80211_add_srates_ie(sdata, skb, false,
+					local->oper_channel->band);
+		ieee80211_add_ext_srates_ie(sdata, skb, false,
+					    local->oper_channel->band);
 		ieee80211_tdls_add_ext_capab(skb);
 		break;
 	default:
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 8e65ad9..0aaad02 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1459,6 +1459,7 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
 			     u8 channel);
 struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
 					  u8 *dst, u32 ratemask,
+					  struct ieee80211_channel *chan,
 					  const u8 *ssid, size_t ssid_len,
 					  const u8 *ie, size_t ie_len,
 					  bool directed);
@@ -1489,9 +1490,11 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
 u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
 			       u32 cap);
 int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
-			    struct sk_buff *skb, bool need_basic);
+			    struct sk_buff *skb, bool need_basic,
+			    enum ieee80211_band band);
 int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
-				struct sk_buff *skb, bool need_basic);
+				struct sk_buff *skb, bool need_basic,
+				enum ieee80211_band band);
 
 /* channel management */
 enum ieee80211_chan_mode {
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index fa642c7..985b37f 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -258,8 +258,10 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
 			pos = skb_put(skb, 2);
 			memcpy(pos + 2, &plid, 2);
 		}
-		if (ieee80211_add_srates_ie(sdata, skb, true) ||
-		    ieee80211_add_ext_srates_ie(sdata, skb, true) ||
+		if (ieee80211_add_srates_ie(sdata, skb, true,
+					    local->oper_channel->band) ||
+		    ieee80211_add_ext_srates_ie(sdata, skb, true,
+						local->oper_channel->band) ||
 		    mesh_add_rsn_ie(skb, sdata) ||
 		    mesh_add_meshid_ie(skb, sdata) ||
 		    mesh_add_meshconf_ie(skb, sdata))
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 2657a56..c416a08 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1683,7 +1683,9 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
 		ssid_len = ssid[1];
 
 	skb = ieee80211_build_probe_req(sdata, cbss->bssid,
-					(u32) -1, ssid + 2, ssid_len,
+					(u32) -1,
+					sdata->local->oper_channel,
+					ssid + 2, ssid_len,
 					NULL, 0, true);
 
 	return skb;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 7558ba5..b559c6b 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2303,7 +2303,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
 	struct ieee80211_if_ap *ap = NULL;
 	struct beacon_data *beacon;
 	struct ieee80211_supported_band *sband;
-	enum ieee80211_band band = local->hw.conf.channel->band;
+	enum ieee80211_band band = local->oper_channel->band;
 	struct ieee80211_tx_rate_control txrc;
 
 	sband = local->hw.wiphy->bands[band];
@@ -2429,9 +2429,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
 		*pos++ = WLAN_EID_SSID;
 		*pos++ = 0x0;
 
-		if (ieee80211_add_srates_ie(sdata, skb, true) ||
+		if (ieee80211_add_srates_ie(sdata, skb, true, band) ||
 		    mesh_add_ds_params_ie(skb, sdata) ||
-		    ieee80211_add_ext_srates_ie(sdata, skb, true) ||
+		    ieee80211_add_ext_srates_ie(sdata, skb, true, band) ||
 		    mesh_add_rsn_ie(skb, sdata) ||
 		    mesh_add_ht_cap_ie(skb, sdata) ||
 		    mesh_add_ht_oper_ie(skb, sdata) ||
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 39005ec..99e4258 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1100,6 +1100,7 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
 
 struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
 					  u8 *dst, u32 ratemask,
+					  struct ieee80211_channel *chan,
 					  const u8 *ssid, size_t ssid_len,
 					  const u8 *ie, size_t ie_len,
 					  bool directed)
@@ -1109,7 +1110,7 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
 	struct ieee80211_mgmt *mgmt;
 	size_t buf_len;
 	u8 *buf;
-	u8 chan;
+	u8 chan_no;
 
 	/* FIXME: come up with a proper value */
 	buf = kmalloc(200 + ie_len, GFP_KERNEL);
@@ -1122,14 +1123,12 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
 	 * badly-behaved APs don't respond when this parameter is included.
 	 */
 	if (directed)
-		chan = 0;
+		chan_no = 0;
 	else
-		chan = ieee80211_frequency_to_channel(
-			local->hw.conf.channel->center_freq);
+		chan_no = ieee80211_frequency_to_channel(chan->center_freq);
 
-	buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len,
-					   local->hw.conf.channel->band,
-					   ratemask, chan);
+	buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, chan->band,
+					   ratemask, chan_no);
 
 	skb = ieee80211_probereq_get(&local->hw, &sdata->vif,
 				     ssid, ssid_len,
@@ -1158,7 +1157,9 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
 {
 	struct sk_buff *skb;
 
-	skb = ieee80211_build_probe_req(sdata, dst, ratemask, ssid, ssid_len,
+	skb = ieee80211_build_probe_req(sdata, dst, ratemask,
+					sdata->local->hw.conf.channel,
+					ssid, ssid_len,
 					ie, ie_len, directed);
 	if (skb) {
 		if (no_cck)
@@ -1810,7 +1811,8 @@ ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper)
 }
 
 int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
-			    struct sk_buff *skb, bool need_basic)
+			    struct sk_buff *skb, bool need_basic,
+			    enum ieee80211_band band)
 {
 	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_supported_band *sband;
@@ -1818,7 +1820,7 @@ int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
 	u8 i, rates, *pos;
 	u32 basic_rates = sdata->vif.bss_conf.basic_rates;
 
-	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+	sband = local->hw.wiphy->bands[band];
 	rates = sband->n_bitrates;
 	if (rates > 8)
 		rates = 8;
@@ -1841,7 +1843,8 @@ int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
 }
 
 int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
-				struct sk_buff *skb, bool need_basic)
+				struct sk_buff *skb, bool need_basic,
+				enum ieee80211_band band)
 {
 	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_supported_band *sband;
@@ -1849,7 +1852,7 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
 	u8 i, exrates, *pos;
 	u32 basic_rates = sdata->vif.bss_conf.basic_rates;
 
-	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+	sband = local->hw.wiphy->bands[band];
 	exrates = sband->n_bitrates;
 	if (exrates > 8)
 		exrates -= 8;



More information about the linux-mtd-cvs mailing list