aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/cfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r--net/mac80211/cfg.c103
1 files changed, 80 insertions, 23 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index a58c0b649ba1..05f3a313db88 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -20,7 +20,8 @@
20#include "rate.h" 20#include "rate.h"
21#include "mesh.h" 21#include "mesh.h"
22 22
23static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy, char *name, 23static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy,
24 const char *name,
24 enum nl80211_iftype type, 25 enum nl80211_iftype type,
25 u32 *flags, 26 u32 *flags,
26 struct vif_params *params) 27 struct vif_params *params)
@@ -102,6 +103,18 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
102 return 0; 103 return 0;
103} 104}
104 105
106static int ieee80211_start_p2p_device(struct wiphy *wiphy,
107 struct wireless_dev *wdev)
108{
109 return ieee80211_do_open(wdev, true);
110}
111
112static void ieee80211_stop_p2p_device(struct wiphy *wiphy,
113 struct wireless_dev *wdev)
114{
115 ieee80211_sdata_stop(IEEE80211_WDEV_TO_SUB_IF(wdev));
116}
117
105static int ieee80211_set_noack_map(struct wiphy *wiphy, 118static int ieee80211_set_noack_map(struct wiphy *wiphy,
106 struct net_device *dev, 119 struct net_device *dev,
107 u16 noack_map) 120 u16 noack_map)
@@ -158,6 +171,38 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
158 } 171 }
159 } 172 }
160 173
174 switch (sdata->vif.type) {
175 case NL80211_IFTYPE_STATION:
176 if (sdata->u.mgd.mfp != IEEE80211_MFP_DISABLED)
177 key->conf.flags |= IEEE80211_KEY_FLAG_RX_MGMT;
178 break;
179 case NL80211_IFTYPE_AP:
180 case NL80211_IFTYPE_AP_VLAN:
181 /* Keys without a station are used for TX only */
182 if (key->sta && test_sta_flag(key->sta, WLAN_STA_MFP))
183 key->conf.flags |= IEEE80211_KEY_FLAG_RX_MGMT;
184 break;
185 case NL80211_IFTYPE_ADHOC:
186 /* no MFP (yet) */
187 break;
188 case NL80211_IFTYPE_MESH_POINT:
189#ifdef CONFIG_MAC80211_MESH
190 if (sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE)
191 key->conf.flags |= IEEE80211_KEY_FLAG_RX_MGMT;
192 break;
193#endif
194 case NL80211_IFTYPE_WDS:
195 case NL80211_IFTYPE_MONITOR:
196 case NL80211_IFTYPE_P2P_DEVICE:
197 case NL80211_IFTYPE_UNSPECIFIED:
198 case NUM_NL80211_IFTYPES:
199 case NL80211_IFTYPE_P2P_CLIENT:
200 case NL80211_IFTYPE_P2P_GO:
201 /* shouldn't happen */
202 WARN_ON_ONCE(1);
203 break;
204 }
205
161 err = ieee80211_key_link(key, sdata, sta); 206 err = ieee80211_key_link(key, sdata, sta);
162 if (err) 207 if (err)
163 ieee80211_key_free(sdata->local, key); 208 ieee80211_key_free(sdata->local, key);
@@ -330,7 +375,7 @@ static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, in
330 if (!(rate->flags & RATE_INFO_FLAGS_MCS)) { 375 if (!(rate->flags & RATE_INFO_FLAGS_MCS)) {
331 struct ieee80211_supported_band *sband; 376 struct ieee80211_supported_band *sband;
332 sband = sta->local->hw.wiphy->bands[ 377 sband = sta->local->hw.wiphy->bands[
333 sta->local->hw.conf.channel->band]; 378 sta->local->oper_channel->band];
334 rate->legacy = sband->bitrates[idx].bitrate; 379 rate->legacy = sband->bitrates[idx].bitrate;
335 } else 380 } else
336 rate->mcs = idx; 381 rate->mcs = idx;
@@ -725,25 +770,23 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
725static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, 770static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
726 const u8 *resp, size_t resp_len) 771 const u8 *resp, size_t resp_len)
727{ 772{
728 struct sk_buff *new, *old; 773 struct probe_resp *new, *old;
729 774
730 if (!resp || !resp_len) 775 if (!resp || !resp_len)
731 return 1; 776 return 1;
732 777
733 old = rtnl_dereference(sdata->u.ap.probe_resp); 778 old = rtnl_dereference(sdata->u.ap.probe_resp);
734 779
735 new = dev_alloc_skb(resp_len); 780 new = kzalloc(sizeof(struct probe_resp) + resp_len, GFP_KERNEL);
736 if (!new) 781 if (!new)
737 return -ENOMEM; 782 return -ENOMEM;
738 783
739 memcpy(skb_put(new, resp_len), resp, resp_len); 784 new->len = resp_len;
785 memcpy(new->data, resp, resp_len);
740 786
741 rcu_assign_pointer(sdata->u.ap.probe_resp, new); 787 rcu_assign_pointer(sdata->u.ap.probe_resp, new);
742 if (old) { 788 if (old)
743 /* TODO: use call_rcu() */ 789 kfree_rcu(old, rcu_head);
744 synchronize_rcu();
745 dev_kfree_skb(old);
746 }
747 790
748 return 0; 791 return 0;
749} 792}
@@ -950,7 +993,7 @@ static void ieee80211_send_layer2_update(struct sta_info *sta)
950 /* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID) 993 /* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID)
951 * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */ 994 * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */
952 995
953 memset(msg->da, 0xff, ETH_ALEN); 996 eth_broadcast_addr(msg->da);
954 memcpy(msg->sa, sta->sta.addr, ETH_ALEN); 997 memcpy(msg->sa, sta->sta.addr, ETH_ALEN);
955 msg->len = htons(6); 998 msg->len = htons(6);
956 msg->dsap = 0; 999 msg->dsap = 0;
@@ -1285,9 +1328,10 @@ static int ieee80211_change_station(struct wiphy *wiphy,
1285 mutex_unlock(&local->sta_mtx); 1328 mutex_unlock(&local->sta_mtx);
1286 1329
1287 if (sdata->vif.type == NL80211_IFTYPE_STATION && 1330 if (sdata->vif.type == NL80211_IFTYPE_STATION &&
1288 params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) 1331 params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
1289 ieee80211_recalc_ps(local, -1); 1332 ieee80211_recalc_ps(local, -1);
1290 1333 ieee80211_recalc_ps_vif(sdata);
1334 }
1291 return 0; 1335 return 0;
1292} 1336}
1293 1337
@@ -1660,7 +1704,7 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
1660 } 1704 }
1661 1705
1662 if (!sdata->vif.bss_conf.use_short_slot && 1706 if (!sdata->vif.bss_conf.use_short_slot &&
1663 sdata->local->hw.conf.channel->band == IEEE80211_BAND_5GHZ) { 1707 sdata->local->oper_channel->band == IEEE80211_BAND_5GHZ) {
1664 sdata->vif.bss_conf.use_short_slot = true; 1708 sdata->vif.bss_conf.use_short_slot = true;
1665 changed |= BSS_CHANGED_ERP_SLOT; 1709 changed |= BSS_CHANGED_ERP_SLOT;
1666 } 1710 }
@@ -1774,6 +1818,7 @@ static int ieee80211_scan(struct wiphy *wiphy,
1774 case NL80211_IFTYPE_ADHOC: 1818 case NL80211_IFTYPE_ADHOC:
1775 case NL80211_IFTYPE_MESH_POINT: 1819 case NL80211_IFTYPE_MESH_POINT:
1776 case NL80211_IFTYPE_P2P_CLIENT: 1820 case NL80211_IFTYPE_P2P_CLIENT:
1821 case NL80211_IFTYPE_P2P_DEVICE:
1777 break; 1822 break;
1778 case NL80211_IFTYPE_P2P_GO: 1823 case NL80211_IFTYPE_P2P_GO:
1779 if (sdata->local->ops->hw_scan) 1824 if (sdata->local->ops->hw_scan)
@@ -1926,7 +1971,7 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
1926 enum nl80211_tx_power_setting type, int mbm) 1971 enum nl80211_tx_power_setting type, int mbm)
1927{ 1972{
1928 struct ieee80211_local *local = wiphy_priv(wiphy); 1973 struct ieee80211_local *local = wiphy_priv(wiphy);
1929 struct ieee80211_channel *chan = local->hw.conf.channel; 1974 struct ieee80211_channel *chan = local->oper_channel;
1930 u32 changes = 0; 1975 u32 changes = 0;
1931 1976
1932 switch (type) { 1977 switch (type) {
@@ -2026,9 +2071,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
2026 */ 2071 */
2027 if (!sdata->u.mgd.associated || 2072 if (!sdata->u.mgd.associated ||
2028 sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) { 2073 sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) {
2029 mutex_lock(&sdata->local->iflist_mtx);
2030 ieee80211_recalc_smps(sdata->local); 2074 ieee80211_recalc_smps(sdata->local);
2031 mutex_unlock(&sdata->local->iflist_mtx);
2032 return 0; 2075 return 0;
2033 } 2076 }
2034 2077
@@ -2078,6 +2121,7 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2078 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 2121 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
2079 2122
2080 ieee80211_recalc_ps(local, -1); 2123 ieee80211_recalc_ps(local, -1);
2124 ieee80211_recalc_ps_vif(sdata);
2081 2125
2082 return 0; 2126 return 0;
2083} 2127}
@@ -2460,6 +2504,9 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
2460 if (!sdata->u.mgd.associated) 2504 if (!sdata->u.mgd.associated)
2461 need_offchan = true; 2505 need_offchan = true;
2462 break; 2506 break;
2507 case NL80211_IFTYPE_P2P_DEVICE:
2508 need_offchan = true;
2509 break;
2463 default: 2510 default:
2464 return -EOPNOTSUPP; 2511 return -EOPNOTSUPP;
2465 } 2512 }
@@ -2652,6 +2699,7 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
2652 u16 status_code, struct sk_buff *skb) 2699 u16 status_code, struct sk_buff *skb)
2653{ 2700{
2654 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 2701 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2702 struct ieee80211_local *local = sdata->local;
2655 struct ieee80211_tdls_data *tf; 2703 struct ieee80211_tdls_data *tf;
2656 2704
2657 tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u)); 2705 tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u));
@@ -2671,8 +2719,10 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
2671 tf->u.setup_req.capability = 2719 tf->u.setup_req.capability =
2672 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); 2720 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
2673 2721
2674 ieee80211_add_srates_ie(sdata, skb, false); 2722 ieee80211_add_srates_ie(sdata, skb, false,
2675 ieee80211_add_ext_srates_ie(sdata, skb, false); 2723 local->oper_channel->band);
2724 ieee80211_add_ext_srates_ie(sdata, skb, false,
2725 local->oper_channel->band);
2676 ieee80211_tdls_add_ext_capab(skb); 2726 ieee80211_tdls_add_ext_capab(skb);
2677 break; 2727 break;
2678 case WLAN_TDLS_SETUP_RESPONSE: 2728 case WLAN_TDLS_SETUP_RESPONSE:
@@ -2685,8 +2735,10 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
2685 tf->u.setup_resp.capability = 2735 tf->u.setup_resp.capability =
2686 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); 2736 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
2687 2737
2688 ieee80211_add_srates_ie(sdata, skb, false); 2738 ieee80211_add_srates_ie(sdata, skb, false,
2689 ieee80211_add_ext_srates_ie(sdata, skb, false); 2739 local->oper_channel->band);
2740 ieee80211_add_ext_srates_ie(sdata, skb, false,
2741 local->oper_channel->band);
2690 ieee80211_tdls_add_ext_capab(skb); 2742 ieee80211_tdls_add_ext_capab(skb);
2691 break; 2743 break;
2692 case WLAN_TDLS_SETUP_CONFIRM: 2744 case WLAN_TDLS_SETUP_CONFIRM:
@@ -2724,6 +2776,7 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
2724 u16 status_code, struct sk_buff *skb) 2776 u16 status_code, struct sk_buff *skb)
2725{ 2777{
2726 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 2778 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2779 struct ieee80211_local *local = sdata->local;
2727 struct ieee80211_mgmt *mgmt; 2780 struct ieee80211_mgmt *mgmt;
2728 2781
2729 mgmt = (void *)skb_put(skb, 24); 2782 mgmt = (void *)skb_put(skb, 24);
@@ -2746,8 +2799,10 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
2746 mgmt->u.action.u.tdls_discover_resp.capability = 2799 mgmt->u.action.u.tdls_discover_resp.capability =
2747 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); 2800 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
2748 2801
2749 ieee80211_add_srates_ie(sdata, skb, false); 2802 ieee80211_add_srates_ie(sdata, skb, false,
2750 ieee80211_add_ext_srates_ie(sdata, skb, false); 2803 local->oper_channel->band);
2804 ieee80211_add_ext_srates_ie(sdata, skb, false,
2805 local->oper_channel->band);
2751 ieee80211_tdls_add_ext_capab(skb); 2806 ieee80211_tdls_add_ext_capab(skb);
2752 break; 2807 break;
2753 default: 2808 default:
@@ -3004,6 +3059,8 @@ struct cfg80211_ops mac80211_config_ops = {
3004 .add_virtual_intf = ieee80211_add_iface, 3059 .add_virtual_intf = ieee80211_add_iface,
3005 .del_virtual_intf = ieee80211_del_iface, 3060 .del_virtual_intf = ieee80211_del_iface,
3006 .change_virtual_intf = ieee80211_change_iface, 3061 .change_virtual_intf = ieee80211_change_iface,
3062 .start_p2p_device = ieee80211_start_p2p_device,
3063 .stop_p2p_device = ieee80211_stop_p2p_device,
3007 .add_key = ieee80211_add_key, 3064 .add_key = ieee80211_add_key,
3008 .del_key = ieee80211_del_key, 3065 .del_key = ieee80211_del_key,
3009 .get_key = ieee80211_get_key, 3066 .get_key = ieee80211_get_key,