aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-07-23 08:53:27 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-07-31 10:18:56 -0400
commit6b77863b719a4e32909c218c0d5a83a14f4d98c5 (patch)
treed259001a7b7c4963de72cd6b3b9bf8d350d2f1c8 /net
parent679ef4eadde1f8e55074427c0d8de2da55ca81f9 (diff)
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@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c20
-rw-r--r--net/mac80211/ieee80211_i.h7
-rw-r--r--net/mac80211/mesh_plink.c6
-rw-r--r--net/mac80211/mlme.c4
-rw-r--r--net/mac80211/tx.c6
-rw-r--r--net/mac80211/util.c27
6 files changed, 44 insertions, 26 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 1b8d19112943..5583f5b73dc9 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,
2655 u16 status_code, struct sk_buff *skb) 2655 u16 status_code, struct sk_buff *skb)
2656{ 2656{
2657 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 2657 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2658 struct ieee80211_local *local = sdata->local;
2658 struct ieee80211_tdls_data *tf; 2659 struct ieee80211_tdls_data *tf;
2659 2660
2660 tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u)); 2661 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,
2674 tf->u.setup_req.capability = 2675 tf->u.setup_req.capability =
2675 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); 2676 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
2676 2677
2677 ieee80211_add_srates_ie(sdata, skb, false); 2678 ieee80211_add_srates_ie(sdata, skb, false,
2678 ieee80211_add_ext_srates_ie(sdata, skb, false); 2679 local->oper_channel->band);
2680 ieee80211_add_ext_srates_ie(sdata, skb, false,
2681 local->oper_channel->band);
2679 ieee80211_tdls_add_ext_capab(skb); 2682 ieee80211_tdls_add_ext_capab(skb);
2680 break; 2683 break;
2681 case WLAN_TDLS_SETUP_RESPONSE: 2684 case WLAN_TDLS_SETUP_RESPONSE:
@@ -2688,8 +2691,10 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
2688 tf->u.setup_resp.capability = 2691 tf->u.setup_resp.capability =
2689 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); 2692 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
2690 2693
2691 ieee80211_add_srates_ie(sdata, skb, false); 2694 ieee80211_add_srates_ie(sdata, skb, false,
2692 ieee80211_add_ext_srates_ie(sdata, skb, false); 2695 local->oper_channel->band);
2696 ieee80211_add_ext_srates_ie(sdata, skb, false,
2697 local->oper_channel->band);
2693 ieee80211_tdls_add_ext_capab(skb); 2698 ieee80211_tdls_add_ext_capab(skb);
2694 break; 2699 break;
2695 case WLAN_TDLS_SETUP_CONFIRM: 2700 case WLAN_TDLS_SETUP_CONFIRM:
@@ -2727,6 +2732,7 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
2727 u16 status_code, struct sk_buff *skb) 2732 u16 status_code, struct sk_buff *skb)
2728{ 2733{
2729 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 2734 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2735 struct ieee80211_local *local = sdata->local;
2730 struct ieee80211_mgmt *mgmt; 2736 struct ieee80211_mgmt *mgmt;
2731 2737
2732 mgmt = (void *)skb_put(skb, 24); 2738 mgmt = (void *)skb_put(skb, 24);
@@ -2749,8 +2755,10 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
2749 mgmt->u.action.u.tdls_discover_resp.capability = 2755 mgmt->u.action.u.tdls_discover_resp.capability =
2750 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); 2756 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
2751 2757
2752 ieee80211_add_srates_ie(sdata, skb, false); 2758 ieee80211_add_srates_ie(sdata, skb, false,
2753 ieee80211_add_ext_srates_ie(sdata, skb, false); 2759 local->oper_channel->band);
2760 ieee80211_add_ext_srates_ie(sdata, skb, false,
2761 local->oper_channel->band);
2754 ieee80211_tdls_add_ext_capab(skb); 2762 ieee80211_tdls_add_ext_capab(skb);
2755 break; 2763 break;
2756 default: 2764 default:
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 8e65ad9c870a..0aaad023cdbe 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,
1459 u8 channel); 1459 u8 channel);
1460struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, 1460struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1461 u8 *dst, u32 ratemask, 1461 u8 *dst, u32 ratemask,
1462 struct ieee80211_channel *chan,
1462 const u8 *ssid, size_t ssid_len, 1463 const u8 *ssid, size_t ssid_len,
1463 const u8 *ie, size_t ie_len, 1464 const u8 *ie, size_t ie_len,
1464 bool directed); 1465 bool directed);
@@ -1489,9 +1490,11 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
1489u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, 1490u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
1490 u32 cap); 1491 u32 cap);
1491int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, 1492int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
1492 struct sk_buff *skb, bool need_basic); 1493 struct sk_buff *skb, bool need_basic,
1494 enum ieee80211_band band);
1493int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata, 1495int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
1494 struct sk_buff *skb, bool need_basic); 1496 struct sk_buff *skb, bool need_basic,
1497 enum ieee80211_band band);
1495 1498
1496/* channel management */ 1499/* channel management */
1497enum ieee80211_chan_mode { 1500enum ieee80211_chan_mode {
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index fa642c794719..985b37f7455d 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,
258 pos = skb_put(skb, 2); 258 pos = skb_put(skb, 2);
259 memcpy(pos + 2, &plid, 2); 259 memcpy(pos + 2, &plid, 2);
260 } 260 }
261 if (ieee80211_add_srates_ie(sdata, skb, true) || 261 if (ieee80211_add_srates_ie(sdata, skb, true,
262 ieee80211_add_ext_srates_ie(sdata, skb, true) || 262 local->oper_channel->band) ||
263 ieee80211_add_ext_srates_ie(sdata, skb, true,
264 local->oper_channel->band) ||
263 mesh_add_rsn_ie(skb, sdata) || 265 mesh_add_rsn_ie(skb, sdata) ||
264 mesh_add_meshid_ie(skb, sdata) || 266 mesh_add_meshid_ie(skb, sdata) ||
265 mesh_add_meshconf_ie(skb, sdata)) 267 mesh_add_meshconf_ie(skb, sdata))
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 2657a5645a8a..c416a08d90f1 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,
1683 ssid_len = ssid[1]; 1683 ssid_len = ssid[1];
1684 1684
1685 skb = ieee80211_build_probe_req(sdata, cbss->bssid, 1685 skb = ieee80211_build_probe_req(sdata, cbss->bssid,
1686 (u32) -1, ssid + 2, ssid_len, 1686 (u32) -1,
1687 sdata->local->oper_channel,
1688 ssid + 2, ssid_len,
1687 NULL, 0, true); 1689 NULL, 0, true);
1688 1690
1689 return skb; 1691 return skb;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 7558ba58ea23..b559c6bd8681 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,
2303 struct ieee80211_if_ap *ap = NULL; 2303 struct ieee80211_if_ap *ap = NULL;
2304 struct beacon_data *beacon; 2304 struct beacon_data *beacon;
2305 struct ieee80211_supported_band *sband; 2305 struct ieee80211_supported_band *sband;
2306 enum ieee80211_band band = local->hw.conf.channel->band; 2306 enum ieee80211_band band = local->oper_channel->band;
2307 struct ieee80211_tx_rate_control txrc; 2307 struct ieee80211_tx_rate_control txrc;
2308 2308
2309 sband = local->hw.wiphy->bands[band]; 2309 sband = local->hw.wiphy->bands[band];
@@ -2429,9 +2429,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2429 *pos++ = WLAN_EID_SSID; 2429 *pos++ = WLAN_EID_SSID;
2430 *pos++ = 0x0; 2430 *pos++ = 0x0;
2431 2431
2432 if (ieee80211_add_srates_ie(sdata, skb, true) || 2432 if (ieee80211_add_srates_ie(sdata, skb, true, band) ||
2433 mesh_add_ds_params_ie(skb, sdata) || 2433 mesh_add_ds_params_ie(skb, sdata) ||
2434 ieee80211_add_ext_srates_ie(sdata, skb, true) || 2434 ieee80211_add_ext_srates_ie(sdata, skb, true, band) ||
2435 mesh_add_rsn_ie(skb, sdata) || 2435 mesh_add_rsn_ie(skb, sdata) ||
2436 mesh_add_ht_cap_ie(skb, sdata) || 2436 mesh_add_ht_cap_ie(skb, sdata) ||
2437 mesh_add_ht_oper_ie(skb, sdata) || 2437 mesh_add_ht_oper_ie(skb, sdata) ||
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 39005eca1a59..99e4258bdb26 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,
1100 1100
1101struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, 1101struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1102 u8 *dst, u32 ratemask, 1102 u8 *dst, u32 ratemask,
1103 struct ieee80211_channel *chan,
1103 const u8 *ssid, size_t ssid_len, 1104 const u8 *ssid, size_t ssid_len,
1104 const u8 *ie, size_t ie_len, 1105 const u8 *ie, size_t ie_len,
1105 bool directed) 1106 bool directed)
@@ -1109,7 +1110,7 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1109 struct ieee80211_mgmt *mgmt; 1110 struct ieee80211_mgmt *mgmt;
1110 size_t buf_len; 1111 size_t buf_len;
1111 u8 *buf; 1112 u8 *buf;
1112 u8 chan; 1113 u8 chan_no;
1113 1114
1114 /* FIXME: come up with a proper value */ 1115 /* FIXME: come up with a proper value */
1115 buf = kmalloc(200 + ie_len, GFP_KERNEL); 1116 buf = kmalloc(200 + ie_len, GFP_KERNEL);
@@ -1122,14 +1123,12 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1122 * badly-behaved APs don't respond when this parameter is included. 1123 * badly-behaved APs don't respond when this parameter is included.
1123 */ 1124 */
1124 if (directed) 1125 if (directed)
1125 chan = 0; 1126 chan_no = 0;
1126 else 1127 else
1127 chan = ieee80211_frequency_to_channel( 1128 chan_no = ieee80211_frequency_to_channel(chan->center_freq);
1128 local->hw.conf.channel->center_freq);
1129 1129
1130 buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, 1130 buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, chan->band,
1131 local->hw.conf.channel->band, 1131 ratemask, chan_no);
1132 ratemask, chan);
1133 1132
1134 skb = ieee80211_probereq_get(&local->hw, &sdata->vif, 1133 skb = ieee80211_probereq_get(&local->hw, &sdata->vif,
1135 ssid, ssid_len, 1134 ssid, ssid_len,
@@ -1158,7 +1157,9 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
1158{ 1157{
1159 struct sk_buff *skb; 1158 struct sk_buff *skb;
1160 1159
1161 skb = ieee80211_build_probe_req(sdata, dst, ratemask, ssid, ssid_len, 1160 skb = ieee80211_build_probe_req(sdata, dst, ratemask,
1161 sdata->local->hw.conf.channel,
1162 ssid, ssid_len,
1162 ie, ie_len, directed); 1163 ie, ie_len, directed);
1163 if (skb) { 1164 if (skb) {
1164 if (no_cck) 1165 if (no_cck)
@@ -1810,7 +1811,8 @@ ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper)
1810} 1811}
1811 1812
1812int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, 1813int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
1813 struct sk_buff *skb, bool need_basic) 1814 struct sk_buff *skb, bool need_basic,
1815 enum ieee80211_band band)
1814{ 1816{
1815 struct ieee80211_local *local = sdata->local; 1817 struct ieee80211_local *local = sdata->local;
1816 struct ieee80211_supported_band *sband; 1818 struct ieee80211_supported_band *sband;
@@ -1818,7 +1820,7 @@ int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
1818 u8 i, rates, *pos; 1820 u8 i, rates, *pos;
1819 u32 basic_rates = sdata->vif.bss_conf.basic_rates; 1821 u32 basic_rates = sdata->vif.bss_conf.basic_rates;
1820 1822
1821 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 1823 sband = local->hw.wiphy->bands[band];
1822 rates = sband->n_bitrates; 1824 rates = sband->n_bitrates;
1823 if (rates > 8) 1825 if (rates > 8)
1824 rates = 8; 1826 rates = 8;
@@ -1841,7 +1843,8 @@ int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
1841} 1843}
1842 1844
1843int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata, 1845int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
1844 struct sk_buff *skb, bool need_basic) 1846 struct sk_buff *skb, bool need_basic,
1847 enum ieee80211_band band)
1845{ 1848{
1846 struct ieee80211_local *local = sdata->local; 1849 struct ieee80211_local *local = sdata->local;
1847 struct ieee80211_supported_band *sband; 1850 struct ieee80211_supported_band *sband;
@@ -1849,7 +1852,7 @@ int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata,
1849 u8 i, exrates, *pos; 1852 u8 i, exrates, *pos;
1850 u32 basic_rates = sdata->vif.bss_conf.basic_rates; 1853 u32 basic_rates = sdata->vif.bss_conf.basic_rates;
1851 1854
1852 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 1855 sband = local->hw.wiphy->bands[band];
1853 exrates = sband->n_bitrates; 1856 exrates = sband->n_bitrates;
1854 if (exrates > 8) 1857 if (exrates > 8)
1855 exrates -= 8; 1858 exrates -= 8;