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.c112
1 files changed, 84 insertions, 28 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index d41974aacf5..05f3a313db8 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
@@ -1378,6 +1422,8 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
1378 else 1422 else
1379 memset(next_hop, 0, ETH_ALEN); 1423 memset(next_hop, 0, ETH_ALEN);
1380 1424
1425 memset(pinfo, 0, sizeof(*pinfo));
1426
1381 pinfo->generation = mesh_paths_generation; 1427 pinfo->generation = mesh_paths_generation;
1382 1428
1383 pinfo->filled = MPATH_INFO_FRAME_QLEN | 1429 pinfo->filled = MPATH_INFO_FRAME_QLEN |
@@ -1396,7 +1442,6 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
1396 pinfo->discovery_timeout = 1442 pinfo->discovery_timeout =
1397 jiffies_to_msecs(mpath->discovery_timeout); 1443 jiffies_to_msecs(mpath->discovery_timeout);
1398 pinfo->discovery_retries = mpath->discovery_retries; 1444 pinfo->discovery_retries = mpath->discovery_retries;
1399 pinfo->flags = 0;
1400 if (mpath->flags & MESH_PATH_ACTIVE) 1445 if (mpath->flags & MESH_PATH_ACTIVE)
1401 pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE; 1446 pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE;
1402 if (mpath->flags & MESH_PATH_RESOLVING) 1447 if (mpath->flags & MESH_PATH_RESOLVING)
@@ -1405,10 +1450,8 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
1405 pinfo->flags |= NL80211_MPATH_FLAG_SN_VALID; 1450 pinfo->flags |= NL80211_MPATH_FLAG_SN_VALID;
1406 if (mpath->flags & MESH_PATH_FIXED) 1451 if (mpath->flags & MESH_PATH_FIXED)
1407 pinfo->flags |= NL80211_MPATH_FLAG_FIXED; 1452 pinfo->flags |= NL80211_MPATH_FLAG_FIXED;
1408 if (mpath->flags & MESH_PATH_RESOLVING) 1453 if (mpath->flags & MESH_PATH_RESOLVED)
1409 pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING; 1454 pinfo->flags |= NL80211_MPATH_FLAG_RESOLVED;
1410
1411 pinfo->flags = mpath->flags;
1412} 1455}
1413 1456
1414static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev, 1457static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev,
@@ -1661,7 +1704,7 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
1661 } 1704 }
1662 1705
1663 if (!sdata->vif.bss_conf.use_short_slot && 1706 if (!sdata->vif.bss_conf.use_short_slot &&
1664 sdata->local->hw.conf.channel->band == IEEE80211_BAND_5GHZ) { 1707 sdata->local->oper_channel->band == IEEE80211_BAND_5GHZ) {
1665 sdata->vif.bss_conf.use_short_slot = true; 1708 sdata->vif.bss_conf.use_short_slot = true;
1666 changed |= BSS_CHANGED_ERP_SLOT; 1709 changed |= BSS_CHANGED_ERP_SLOT;
1667 } 1710 }
@@ -1775,6 +1818,7 @@ static int ieee80211_scan(struct wiphy *wiphy,
1775 case NL80211_IFTYPE_ADHOC: 1818 case NL80211_IFTYPE_ADHOC:
1776 case NL80211_IFTYPE_MESH_POINT: 1819 case NL80211_IFTYPE_MESH_POINT:
1777 case NL80211_IFTYPE_P2P_CLIENT: 1820 case NL80211_IFTYPE_P2P_CLIENT:
1821 case NL80211_IFTYPE_P2P_DEVICE:
1778 break; 1822 break;
1779 case NL80211_IFTYPE_P2P_GO: 1823 case NL80211_IFTYPE_P2P_GO:
1780 if (sdata->local->ops->hw_scan) 1824 if (sdata->local->ops->hw_scan)
@@ -1927,7 +1971,7 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
1927 enum nl80211_tx_power_setting type, int mbm) 1971 enum nl80211_tx_power_setting type, int mbm)
1928{ 1972{
1929 struct ieee80211_local *local = wiphy_priv(wiphy); 1973 struct ieee80211_local *local = wiphy_priv(wiphy);
1930 struct ieee80211_channel *chan = local->hw.conf.channel; 1974 struct ieee80211_channel *chan = local->oper_channel;
1931 u32 changes = 0; 1975 u32 changes = 0;
1932 1976
1933 switch (type) { 1977 switch (type) {
@@ -2027,9 +2071,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
2027 */ 2071 */
2028 if (!sdata->u.mgd.associated || 2072 if (!sdata->u.mgd.associated ||
2029 sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) { 2073 sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) {
2030 mutex_lock(&sdata->local->iflist_mtx);
2031 ieee80211_recalc_smps(sdata->local); 2074 ieee80211_recalc_smps(sdata->local);
2032 mutex_unlock(&sdata->local->iflist_mtx);
2033 return 0; 2075 return 0;
2034 } 2076 }
2035 2077
@@ -2079,6 +2121,7 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2079 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 2121 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
2080 2122
2081 ieee80211_recalc_ps(local, -1); 2123 ieee80211_recalc_ps(local, -1);
2124 ieee80211_recalc_ps_vif(sdata);
2082 2125
2083 return 0; 2126 return 0;
2084} 2127}
@@ -2461,6 +2504,9 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
2461 if (!sdata->u.mgd.associated) 2504 if (!sdata->u.mgd.associated)
2462 need_offchan = true; 2505 need_offchan = true;
2463 break; 2506 break;
2507 case NL80211_IFTYPE_P2P_DEVICE:
2508 need_offchan = true;
2509 break;
2464 default: 2510 default:
2465 return -EOPNOTSUPP; 2511 return -EOPNOTSUPP;
2466 } 2512 }
@@ -2653,6 +2699,7 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
2653 u16 status_code, struct sk_buff *skb) 2699 u16 status_code, struct sk_buff *skb)
2654{ 2700{
2655 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;
2656 struct ieee80211_tdls_data *tf; 2703 struct ieee80211_tdls_data *tf;
2657 2704
2658 tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u)); 2705 tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u));
@@ -2672,8 +2719,10 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
2672 tf->u.setup_req.capability = 2719 tf->u.setup_req.capability =
2673 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); 2720 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
2674 2721
2675 ieee80211_add_srates_ie(sdata, skb, false); 2722 ieee80211_add_srates_ie(sdata, skb, false,
2676 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);
2677 ieee80211_tdls_add_ext_capab(skb); 2726 ieee80211_tdls_add_ext_capab(skb);
2678 break; 2727 break;
2679 case WLAN_TDLS_SETUP_RESPONSE: 2728 case WLAN_TDLS_SETUP_RESPONSE:
@@ -2686,8 +2735,10 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
2686 tf->u.setup_resp.capability = 2735 tf->u.setup_resp.capability =
2687 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); 2736 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
2688 2737
2689 ieee80211_add_srates_ie(sdata, skb, false); 2738 ieee80211_add_srates_ie(sdata, skb, false,
2690 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);
2691 ieee80211_tdls_add_ext_capab(skb); 2742 ieee80211_tdls_add_ext_capab(skb);
2692 break; 2743 break;
2693 case WLAN_TDLS_SETUP_CONFIRM: 2744 case WLAN_TDLS_SETUP_CONFIRM:
@@ -2725,6 +2776,7 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
2725 u16 status_code, struct sk_buff *skb) 2776 u16 status_code, struct sk_buff *skb)
2726{ 2777{
2727 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;
2728 struct ieee80211_mgmt *mgmt; 2780 struct ieee80211_mgmt *mgmt;
2729 2781
2730 mgmt = (void *)skb_put(skb, 24); 2782 mgmt = (void *)skb_put(skb, 24);
@@ -2747,8 +2799,10 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
2747 mgmt->u.action.u.tdls_discover_resp.capability = 2799 mgmt->u.action.u.tdls_discover_resp.capability =
2748 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); 2800 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
2749 2801
2750 ieee80211_add_srates_ie(sdata, skb, false); 2802 ieee80211_add_srates_ie(sdata, skb, false,
2751 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);
2752 ieee80211_tdls_add_ext_capab(skb); 2806 ieee80211_tdls_add_ext_capab(skb);
2753 break; 2807 break;
2754 default: 2808 default:
@@ -3005,6 +3059,8 @@ struct cfg80211_ops mac80211_config_ops = {
3005 .add_virtual_intf = ieee80211_add_iface, 3059 .add_virtual_intf = ieee80211_add_iface,
3006 .del_virtual_intf = ieee80211_del_iface, 3060 .del_virtual_intf = ieee80211_del_iface,
3007 .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,
3008 .add_key = ieee80211_add_key, 3064 .add_key = ieee80211_add_key,
3009 .del_key = ieee80211_del_key, 3065 .del_key = ieee80211_del_key,
3010 .get_key = ieee80211_get_key, 3066 .get_key = ieee80211_get_key,