diff options
author | Johannes Berg <johannes.berg@intel.com> | 2012-07-23 08:53:27 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2012-07-31 10:18:56 -0400 |
commit | 6b77863b719a4e32909c218c0d5a83a14f4d98c5 (patch) | |
tree | d259001a7b7c4963de72cd6b3b9bf8d350d2f1c8 /net | |
parent | 679ef4eadde1f8e55074427c0d8de2da55ca81f9 (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.c | 20 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 7 | ||||
-rw-r--r-- | net/mac80211/mesh_plink.c | 6 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 4 | ||||
-rw-r--r-- | net/mac80211/tx.c | 6 | ||||
-rw-r--r-- | 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 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); |
1460 | struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, | 1460 | struct 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, | |||
1489 | u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, | 1490 | u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, |
1490 | u32 cap); | 1491 | u32 cap); |
1491 | int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, | 1492 | int 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); | ||
1493 | int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata, | 1495 | int 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 */ |
1497 | enum ieee80211_chan_mode { | 1500 | enum 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 | ||
1101 | struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, | 1101 | struct 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 | ||
1812 | int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, | 1813 | int 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 | ||
1843 | int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata, | 1845 | int 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; |