diff options
author | Arik Nemtsov <arik@wizery.com> | 2014-11-09 11:50:15 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-11-19 12:45:04 -0500 |
commit | 9041c1fa5722250025be9a7450622c9108088c5a (patch) | |
tree | 0771cbcc4518a708ac58aec7388c06eb926bba39 /net/mac80211 | |
parent | 78632a17eaa7a5abdc22aac8ca5932d6cad59984 (diff) |
mac80211: track AP and peer STA TDLS chan-switch support
The AP or peer can prohibit TDLS channel switch via a bit in the
extended capabilities IE. Parse the IE and track this bit. Set an
appropriate STA flag if both the AP and peer STA support TDLS
channel-switching.
Add the new STA flag and the missing TDLS_INITIATOR to debugfs.
Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/cfg.c | 7 | ||||
-rw-r--r-- | net/mac80211/debugfs_sta.c | 5 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 3 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 3 | ||||
-rw-r--r-- | net/mac80211/sta_info.h | 2 | ||||
-rw-r--r-- | net/mac80211/util.c | 5 |
6 files changed, 23 insertions, 2 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 3ecbf68dadf1..8195e65d8a91 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1042,6 +1042,13 @@ static int sta_apply_parameters(struct ieee80211_local *local, | |||
1042 | clear_sta_flag(sta, WLAN_STA_TDLS_PEER); | 1042 | clear_sta_flag(sta, WLAN_STA_TDLS_PEER); |
1043 | } | 1043 | } |
1044 | 1044 | ||
1045 | /* mark TDLS channel switch support, if the AP allows it */ | ||
1046 | if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) && | ||
1047 | !sdata->u.mgd.tdls_chan_switch_prohibited && | ||
1048 | params->ext_capab_len >= 4 && | ||
1049 | params->ext_capab[3] & WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH) | ||
1050 | set_sta_flag(sta, WLAN_STA_TDLS_CHAN_SWITCH); | ||
1051 | |||
1045 | if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD) { | 1052 | if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD) { |
1046 | sta->sta.uapsd_queues = params->uapsd_queues; | 1053 | sta->sta.uapsd_queues = params->uapsd_queues; |
1047 | sta->sta.max_sp = params->max_sp; | 1054 | sta->sta.max_sp = params->max_sp; |
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index bafe48916229..2ba7f53746da 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -74,7 +74,7 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf, | |||
74 | test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : "" | 74 | test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : "" |
75 | 75 | ||
76 | int res = scnprintf(buf, sizeof(buf), | 76 | int res = scnprintf(buf, sizeof(buf), |
77 | "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", | 77 | "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", |
78 | TEST(AUTH), TEST(ASSOC), TEST(PS_STA), | 78 | TEST(AUTH), TEST(ASSOC), TEST(PS_STA), |
79 | TEST(PS_DRIVER), TEST(AUTHORIZED), | 79 | TEST(PS_DRIVER), TEST(AUTHORIZED), |
80 | TEST(SHORT_PREAMBLE), | 80 | TEST(SHORT_PREAMBLE), |
@@ -82,7 +82,8 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf, | |||
82 | TEST(WDS), TEST(CLEAR_PS_FILT), | 82 | TEST(WDS), TEST(CLEAR_PS_FILT), |
83 | TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL), | 83 | TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL), |
84 | TEST(UAPSD), TEST(SP), TEST(TDLS_PEER), | 84 | TEST(UAPSD), TEST(SP), TEST(TDLS_PEER), |
85 | TEST(TDLS_PEER_AUTH), TEST(4ADDR_EVENT), | 85 | TEST(TDLS_PEER_AUTH), TEST(TDLS_INITIATOR), |
86 | TEST(TDLS_CHAN_SWITCH), TEST(4ADDR_EVENT), | ||
86 | TEST(INSERTED), TEST(RATE_CONTROL), | 87 | TEST(INSERTED), TEST(RATE_CONTROL), |
87 | TEST(TOFFSET_KNOWN), TEST(MPSP_OWNER), | 88 | TEST(TOFFSET_KNOWN), TEST(MPSP_OWNER), |
88 | TEST(MPSP_RECIPIENT)); | 89 | TEST(MPSP_RECIPIENT)); |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 53eb41fad033..4b3a7e7ec2a0 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -531,6 +531,7 @@ struct ieee80211_if_managed { | |||
531 | struct sk_buff *orig_teardown_skb; /* The original teardown skb */ | 531 | struct sk_buff *orig_teardown_skb; /* The original teardown skb */ |
532 | struct sk_buff *teardown_skb; /* A copy to send through the AP */ | 532 | struct sk_buff *teardown_skb; /* A copy to send through the AP */ |
533 | spinlock_t teardown_lock; /* To lock changing teardown_skb */ | 533 | spinlock_t teardown_lock; /* To lock changing teardown_skb */ |
534 | bool tdls_chan_switch_prohibited; | ||
534 | 535 | ||
535 | /* WMM-AC TSPEC support */ | 536 | /* WMM-AC TSPEC support */ |
536 | struct ieee80211_sta_tx_tspec tx_tspec[IEEE80211_NUM_ACS]; | 537 | struct ieee80211_sta_tx_tspec tx_tspec[IEEE80211_NUM_ACS]; |
@@ -1399,6 +1400,7 @@ struct ieee802_11_elems { | |||
1399 | size_t total_len; | 1400 | size_t total_len; |
1400 | 1401 | ||
1401 | /* pointers to IEs */ | 1402 | /* pointers to IEs */ |
1403 | const u8 *ext_capab; | ||
1402 | const u8 *ssid; | 1404 | const u8 *ssid; |
1403 | const u8 *supp_rates; | 1405 | const u8 *supp_rates; |
1404 | const u8 *ds_params; | 1406 | const u8 *ds_params; |
@@ -1433,6 +1435,7 @@ struct ieee802_11_elems { | |||
1433 | const struct ieee80211_mesh_chansw_params_ie *mesh_chansw_params_ie; | 1435 | const struct ieee80211_mesh_chansw_params_ie *mesh_chansw_params_ie; |
1434 | 1436 | ||
1435 | /* length of them, respectively */ | 1437 | /* length of them, respectively */ |
1438 | u8 ext_capab_len; | ||
1436 | u8 ssid_len; | 1439 | u8 ssid_len; |
1437 | u8 supp_rates_len; | 1440 | u8 supp_rates_len; |
1438 | u8 tim_len; | 1441 | u8 tim_len; |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 11a937f3fdeb..45490a202d9c 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -2802,6 +2802,9 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
2802 | } | 2802 | } |
2803 | 2803 | ||
2804 | ifmgd->aid = aid; | 2804 | ifmgd->aid = aid; |
2805 | ifmgd->tdls_chan_switch_prohibited = | ||
2806 | elems.ext_capab && elems.ext_capab_len >= 5 && | ||
2807 | (elems.ext_capab[4] & WLAN_EXT_CAPA5_TDLS_CH_SW_PROHIBITED); | ||
2805 | 2808 | ||
2806 | /* | 2809 | /* |
2807 | * Some APs are erroneously not including some information in their | 2810 | * Some APs are erroneously not including some information in their |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index bcda2ac7d844..b6702c810ad3 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -49,6 +49,7 @@ | |||
49 | * packets. This means the link is enabled. | 49 | * packets. This means the link is enabled. |
50 | * @WLAN_STA_TDLS_INITIATOR: We are the initiator of the TDLS link with this | 50 | * @WLAN_STA_TDLS_INITIATOR: We are the initiator of the TDLS link with this |
51 | * station. | 51 | * station. |
52 | * @WLAN_STA_TDLS_CHAN_SWITCH: This TDLS peer supports TDLS channel-switching | ||
52 | * @WLAN_STA_UAPSD: Station requested unscheduled SP while driver was | 53 | * @WLAN_STA_UAPSD: Station requested unscheduled SP while driver was |
53 | * keeping station in power-save mode, reply when the driver | 54 | * keeping station in power-save mode, reply when the driver |
54 | * unblocks the station. | 55 | * unblocks the station. |
@@ -78,6 +79,7 @@ enum ieee80211_sta_info_flags { | |||
78 | WLAN_STA_TDLS_PEER, | 79 | WLAN_STA_TDLS_PEER, |
79 | WLAN_STA_TDLS_PEER_AUTH, | 80 | WLAN_STA_TDLS_PEER_AUTH, |
80 | WLAN_STA_TDLS_INITIATOR, | 81 | WLAN_STA_TDLS_INITIATOR, |
82 | WLAN_STA_TDLS_CHAN_SWITCH, | ||
81 | WLAN_STA_UAPSD, | 83 | WLAN_STA_UAPSD, |
82 | WLAN_STA_SP, | 84 | WLAN_STA_SP, |
83 | WLAN_STA_4ADDR_EVENT, | 85 | WLAN_STA_4ADDR_EVENT, |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index f9319a5dca64..3ca0c2e725ff 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -831,6 +831,7 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, | |||
831 | case WLAN_EID_SECONDARY_CHANNEL_OFFSET: | 831 | case WLAN_EID_SECONDARY_CHANNEL_OFFSET: |
832 | case WLAN_EID_WIDE_BW_CHANNEL_SWITCH: | 832 | case WLAN_EID_WIDE_BW_CHANNEL_SWITCH: |
833 | case WLAN_EID_CHAN_SWITCH_PARAM: | 833 | case WLAN_EID_CHAN_SWITCH_PARAM: |
834 | case WLAN_EID_EXT_CAPABILITY: | ||
834 | /* | 835 | /* |
835 | * not listing WLAN_EID_CHANNEL_SWITCH_WRAPPER -- it seems possible | 836 | * not listing WLAN_EID_CHANNEL_SWITCH_WRAPPER -- it seems possible |
836 | * that if the content gets bigger it might be needed more than once | 837 | * that if the content gets bigger it might be needed more than once |
@@ -850,6 +851,10 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, | |||
850 | elem_parse_failed = false; | 851 | elem_parse_failed = false; |
851 | 852 | ||
852 | switch (id) { | 853 | switch (id) { |
854 | case WLAN_EID_EXT_CAPABILITY: | ||
855 | elems->ext_capab = pos; | ||
856 | elems->ext_capab_len = elen; | ||
857 | break; | ||
853 | case WLAN_EID_SSID: | 858 | case WLAN_EID_SSID: |
854 | elems->ssid = pos; | 859 | elems->ssid = pos; |
855 | elems->ssid_len = elen; | 860 | elems->ssid_len = elen; |