diff options
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r-- | net/mac80211/cfg.c | 66 |
1 files changed, 46 insertions, 20 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index d41974aacf51..929f897a8ded 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -102,6 +102,18 @@ static int ieee80211_change_iface(struct wiphy *wiphy, | |||
102 | return 0; | 102 | return 0; |
103 | } | 103 | } |
104 | 104 | ||
105 | static int ieee80211_start_p2p_device(struct wiphy *wiphy, | ||
106 | struct wireless_dev *wdev) | ||
107 | { | ||
108 | return ieee80211_do_open(wdev, true); | ||
109 | } | ||
110 | |||
111 | static void ieee80211_stop_p2p_device(struct wiphy *wiphy, | ||
112 | struct wireless_dev *wdev) | ||
113 | { | ||
114 | ieee80211_sdata_stop(IEEE80211_WDEV_TO_SUB_IF(wdev)); | ||
115 | } | ||
116 | |||
105 | static int ieee80211_set_noack_map(struct wiphy *wiphy, | 117 | static int ieee80211_set_noack_map(struct wiphy *wiphy, |
106 | struct net_device *dev, | 118 | struct net_device *dev, |
107 | u16 noack_map) | 119 | u16 noack_map) |
@@ -330,7 +342,7 @@ static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, in | |||
330 | if (!(rate->flags & RATE_INFO_FLAGS_MCS)) { | 342 | if (!(rate->flags & RATE_INFO_FLAGS_MCS)) { |
331 | struct ieee80211_supported_band *sband; | 343 | struct ieee80211_supported_band *sband; |
332 | sband = sta->local->hw.wiphy->bands[ | 344 | sband = sta->local->hw.wiphy->bands[ |
333 | sta->local->hw.conf.channel->band]; | 345 | sta->local->oper_channel->band]; |
334 | rate->legacy = sband->bitrates[idx].bitrate; | 346 | rate->legacy = sband->bitrates[idx].bitrate; |
335 | } else | 347 | } else |
336 | rate->mcs = idx; | 348 | rate->mcs = idx; |
@@ -725,25 +737,23 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy, | |||
725 | static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, | 737 | static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, |
726 | const u8 *resp, size_t resp_len) | 738 | const u8 *resp, size_t resp_len) |
727 | { | 739 | { |
728 | struct sk_buff *new, *old; | 740 | struct probe_resp *new, *old; |
729 | 741 | ||
730 | if (!resp || !resp_len) | 742 | if (!resp || !resp_len) |
731 | return 1; | 743 | return 1; |
732 | 744 | ||
733 | old = rtnl_dereference(sdata->u.ap.probe_resp); | 745 | old = rtnl_dereference(sdata->u.ap.probe_resp); |
734 | 746 | ||
735 | new = dev_alloc_skb(resp_len); | 747 | new = kzalloc(sizeof(struct probe_resp) + resp_len, GFP_KERNEL); |
736 | if (!new) | 748 | if (!new) |
737 | return -ENOMEM; | 749 | return -ENOMEM; |
738 | 750 | ||
739 | memcpy(skb_put(new, resp_len), resp, resp_len); | 751 | new->len = resp_len; |
752 | memcpy(new->data, resp, resp_len); | ||
740 | 753 | ||
741 | rcu_assign_pointer(sdata->u.ap.probe_resp, new); | 754 | rcu_assign_pointer(sdata->u.ap.probe_resp, new); |
742 | if (old) { | 755 | if (old) |
743 | /* TODO: use call_rcu() */ | 756 | kfree_rcu(old, rcu_head); |
744 | synchronize_rcu(); | ||
745 | dev_kfree_skb(old); | ||
746 | } | ||
747 | 757 | ||
748 | return 0; | 758 | return 0; |
749 | } | 759 | } |
@@ -950,7 +960,7 @@ static void ieee80211_send_layer2_update(struct sta_info *sta) | |||
950 | /* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID) | 960 | /* 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 */ | 961 | * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */ |
952 | 962 | ||
953 | memset(msg->da, 0xff, ETH_ALEN); | 963 | eth_broadcast_addr(msg->da); |
954 | memcpy(msg->sa, sta->sta.addr, ETH_ALEN); | 964 | memcpy(msg->sa, sta->sta.addr, ETH_ALEN); |
955 | msg->len = htons(6); | 965 | msg->len = htons(6); |
956 | msg->dsap = 0; | 966 | msg->dsap = 0; |
@@ -1285,9 +1295,10 @@ static int ieee80211_change_station(struct wiphy *wiphy, | |||
1285 | mutex_unlock(&local->sta_mtx); | 1295 | mutex_unlock(&local->sta_mtx); |
1286 | 1296 | ||
1287 | if (sdata->vif.type == NL80211_IFTYPE_STATION && | 1297 | if (sdata->vif.type == NL80211_IFTYPE_STATION && |
1288 | params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) | 1298 | params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) { |
1289 | ieee80211_recalc_ps(local, -1); | 1299 | ieee80211_recalc_ps(local, -1); |
1290 | 1300 | ieee80211_recalc_ps_vif(sdata); | |
1301 | } | ||
1291 | return 0; | 1302 | return 0; |
1292 | } | 1303 | } |
1293 | 1304 | ||
@@ -1661,7 +1672,7 @@ static int ieee80211_change_bss(struct wiphy *wiphy, | |||
1661 | } | 1672 | } |
1662 | 1673 | ||
1663 | if (!sdata->vif.bss_conf.use_short_slot && | 1674 | if (!sdata->vif.bss_conf.use_short_slot && |
1664 | sdata->local->hw.conf.channel->band == IEEE80211_BAND_5GHZ) { | 1675 | sdata->local->oper_channel->band == IEEE80211_BAND_5GHZ) { |
1665 | sdata->vif.bss_conf.use_short_slot = true; | 1676 | sdata->vif.bss_conf.use_short_slot = true; |
1666 | changed |= BSS_CHANGED_ERP_SLOT; | 1677 | changed |= BSS_CHANGED_ERP_SLOT; |
1667 | } | 1678 | } |
@@ -1775,6 +1786,7 @@ static int ieee80211_scan(struct wiphy *wiphy, | |||
1775 | case NL80211_IFTYPE_ADHOC: | 1786 | case NL80211_IFTYPE_ADHOC: |
1776 | case NL80211_IFTYPE_MESH_POINT: | 1787 | case NL80211_IFTYPE_MESH_POINT: |
1777 | case NL80211_IFTYPE_P2P_CLIENT: | 1788 | case NL80211_IFTYPE_P2P_CLIENT: |
1789 | case NL80211_IFTYPE_P2P_DEVICE: | ||
1778 | break; | 1790 | break; |
1779 | case NL80211_IFTYPE_P2P_GO: | 1791 | case NL80211_IFTYPE_P2P_GO: |
1780 | if (sdata->local->ops->hw_scan) | 1792 | if (sdata->local->ops->hw_scan) |
@@ -1927,7 +1939,7 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy, | |||
1927 | enum nl80211_tx_power_setting type, int mbm) | 1939 | enum nl80211_tx_power_setting type, int mbm) |
1928 | { | 1940 | { |
1929 | struct ieee80211_local *local = wiphy_priv(wiphy); | 1941 | struct ieee80211_local *local = wiphy_priv(wiphy); |
1930 | struct ieee80211_channel *chan = local->hw.conf.channel; | 1942 | struct ieee80211_channel *chan = local->oper_channel; |
1931 | u32 changes = 0; | 1943 | u32 changes = 0; |
1932 | 1944 | ||
1933 | switch (type) { | 1945 | switch (type) { |
@@ -2079,6 +2091,7 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, | |||
2079 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); | 2091 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); |
2080 | 2092 | ||
2081 | ieee80211_recalc_ps(local, -1); | 2093 | ieee80211_recalc_ps(local, -1); |
2094 | ieee80211_recalc_ps_vif(sdata); | ||
2082 | 2095 | ||
2083 | return 0; | 2096 | return 0; |
2084 | } | 2097 | } |
@@ -2461,6 +2474,9 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | |||
2461 | if (!sdata->u.mgd.associated) | 2474 | if (!sdata->u.mgd.associated) |
2462 | need_offchan = true; | 2475 | need_offchan = true; |
2463 | break; | 2476 | break; |
2477 | case NL80211_IFTYPE_P2P_DEVICE: | ||
2478 | need_offchan = true; | ||
2479 | break; | ||
2464 | default: | 2480 | default: |
2465 | return -EOPNOTSUPP; | 2481 | return -EOPNOTSUPP; |
2466 | } | 2482 | } |
@@ -2653,6 +2669,7 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, | |||
2653 | u16 status_code, struct sk_buff *skb) | 2669 | u16 status_code, struct sk_buff *skb) |
2654 | { | 2670 | { |
2655 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2671 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
2672 | struct ieee80211_local *local = sdata->local; | ||
2656 | struct ieee80211_tdls_data *tf; | 2673 | struct ieee80211_tdls_data *tf; |
2657 | 2674 | ||
2658 | tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u)); | 2675 | tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u)); |
@@ -2672,8 +2689,10 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, | |||
2672 | tf->u.setup_req.capability = | 2689 | tf->u.setup_req.capability = |
2673 | cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); | 2690 | cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); |
2674 | 2691 | ||
2675 | ieee80211_add_srates_ie(sdata, skb, false); | 2692 | ieee80211_add_srates_ie(sdata, skb, false, |
2676 | ieee80211_add_ext_srates_ie(sdata, skb, false); | 2693 | local->oper_channel->band); |
2694 | ieee80211_add_ext_srates_ie(sdata, skb, false, | ||
2695 | local->oper_channel->band); | ||
2677 | ieee80211_tdls_add_ext_capab(skb); | 2696 | ieee80211_tdls_add_ext_capab(skb); |
2678 | break; | 2697 | break; |
2679 | case WLAN_TDLS_SETUP_RESPONSE: | 2698 | case WLAN_TDLS_SETUP_RESPONSE: |
@@ -2686,8 +2705,10 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, | |||
2686 | tf->u.setup_resp.capability = | 2705 | tf->u.setup_resp.capability = |
2687 | cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); | 2706 | cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); |
2688 | 2707 | ||
2689 | ieee80211_add_srates_ie(sdata, skb, false); | 2708 | ieee80211_add_srates_ie(sdata, skb, false, |
2690 | ieee80211_add_ext_srates_ie(sdata, skb, false); | 2709 | local->oper_channel->band); |
2710 | ieee80211_add_ext_srates_ie(sdata, skb, false, | ||
2711 | local->oper_channel->band); | ||
2691 | ieee80211_tdls_add_ext_capab(skb); | 2712 | ieee80211_tdls_add_ext_capab(skb); |
2692 | break; | 2713 | break; |
2693 | case WLAN_TDLS_SETUP_CONFIRM: | 2714 | case WLAN_TDLS_SETUP_CONFIRM: |
@@ -2725,6 +2746,7 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev, | |||
2725 | u16 status_code, struct sk_buff *skb) | 2746 | u16 status_code, struct sk_buff *skb) |
2726 | { | 2747 | { |
2727 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2748 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
2749 | struct ieee80211_local *local = sdata->local; | ||
2728 | struct ieee80211_mgmt *mgmt; | 2750 | struct ieee80211_mgmt *mgmt; |
2729 | 2751 | ||
2730 | mgmt = (void *)skb_put(skb, 24); | 2752 | mgmt = (void *)skb_put(skb, 24); |
@@ -2747,8 +2769,10 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev, | |||
2747 | mgmt->u.action.u.tdls_discover_resp.capability = | 2769 | mgmt->u.action.u.tdls_discover_resp.capability = |
2748 | cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); | 2770 | cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); |
2749 | 2771 | ||
2750 | ieee80211_add_srates_ie(sdata, skb, false); | 2772 | ieee80211_add_srates_ie(sdata, skb, false, |
2751 | ieee80211_add_ext_srates_ie(sdata, skb, false); | 2773 | local->oper_channel->band); |
2774 | ieee80211_add_ext_srates_ie(sdata, skb, false, | ||
2775 | local->oper_channel->band); | ||
2752 | ieee80211_tdls_add_ext_capab(skb); | 2776 | ieee80211_tdls_add_ext_capab(skb); |
2753 | break; | 2777 | break; |
2754 | default: | 2778 | default: |
@@ -3005,6 +3029,8 @@ struct cfg80211_ops mac80211_config_ops = { | |||
3005 | .add_virtual_intf = ieee80211_add_iface, | 3029 | .add_virtual_intf = ieee80211_add_iface, |
3006 | .del_virtual_intf = ieee80211_del_iface, | 3030 | .del_virtual_intf = ieee80211_del_iface, |
3007 | .change_virtual_intf = ieee80211_change_iface, | 3031 | .change_virtual_intf = ieee80211_change_iface, |
3032 | .start_p2p_device = ieee80211_start_p2p_device, | ||
3033 | .stop_p2p_device = ieee80211_stop_p2p_device, | ||
3008 | .add_key = ieee80211_add_key, | 3034 | .add_key = ieee80211_add_key, |
3009 | .del_key = ieee80211_del_key, | 3035 | .del_key = ieee80211_del_key, |
3010 | .get_key = ieee80211_get_key, | 3036 | .get_key = ieee80211_get_key, |