aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2014-11-09 11:50:15 -0500
committerJohannes Berg <johannes.berg@intel.com>2014-11-19 12:45:04 -0500
commit9041c1fa5722250025be9a7450622c9108088c5a (patch)
tree0771cbcc4518a708ac58aec7388c06eb926bba39 /net/mac80211
parent78632a17eaa7a5abdc22aac8ca5932d6cad59984 (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.c7
-rw-r--r--net/mac80211/debugfs_sta.c5
-rw-r--r--net/mac80211/ieee80211_i.h3
-rw-r--r--net/mac80211/mlme.c3
-rw-r--r--net/mac80211/sta_info.h2
-rw-r--r--net/mac80211/util.c5
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;