aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/ieee80211.h85
-rw-r--r--include/linux/if_ether.h1
-rw-r--r--net/mac80211/Kconfig12
-rw-r--r--net/mac80211/cfg.c310
-rw-r--r--net/mac80211/main.c4
5 files changed, 412 insertions, 0 deletions
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index b5e0a5c344fd..48363c3c40f8 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -759,6 +759,12 @@ struct ieee80211_mgmt {
759 u8 action; 759 u8 action;
760 u8 smps_control; 760 u8 smps_control;
761 } __attribute__ ((packed)) ht_smps; 761 } __attribute__ ((packed)) ht_smps;
762 struct {
763 u8 action_code;
764 u8 dialog_token;
765 __le16 capability;
766 u8 variable[0];
767 } __packed tdls_discover_resp;
762 } u; 768 } u;
763 } __attribute__ ((packed)) action; 769 } __attribute__ ((packed)) action;
764 } u; 770 } u;
@@ -805,6 +811,52 @@ struct ieee80211_pspoll {
805 u8 ta[6]; 811 u8 ta[6];
806} __attribute__ ((packed)); 812} __attribute__ ((packed));
807 813
814/* TDLS */
815
816/* Link-id information element */
817struct ieee80211_tdls_lnkie {
818 u8 ie_type; /* Link Identifier IE */
819 u8 ie_len;
820 u8 bssid[6];
821 u8 init_sta[6];
822 u8 resp_sta[6];
823} __packed;
824
825struct ieee80211_tdls_data {
826 u8 da[6];
827 u8 sa[6];
828 __be16 ether_type;
829 u8 payload_type;
830 u8 category;
831 u8 action_code;
832 union {
833 struct {
834 u8 dialog_token;
835 __le16 capability;
836 u8 variable[0];
837 } __packed setup_req;
838 struct {
839 __le16 status_code;
840 u8 dialog_token;
841 __le16 capability;
842 u8 variable[0];
843 } __packed setup_resp;
844 struct {
845 __le16 status_code;
846 u8 dialog_token;
847 u8 variable[0];
848 } __packed setup_cfm;
849 struct {
850 __le16 reason_code;
851 u8 variable[0];
852 } __packed teardown;
853 struct {
854 u8 dialog_token;
855 u8 variable[0];
856 } __packed discover_req;
857 } u;
858} __packed;
859
808/** 860/**
809 * struct ieee80211_bar - HT Block Ack Request 861 * struct ieee80211_bar - HT Block Ack Request
810 * 862 *
@@ -1196,6 +1248,8 @@ enum ieee80211_eid {
1196 WLAN_EID_TS_DELAY = 43, 1248 WLAN_EID_TS_DELAY = 43,
1197 WLAN_EID_TCLAS_PROCESSING = 44, 1249 WLAN_EID_TCLAS_PROCESSING = 44,
1198 WLAN_EID_QOS_CAPA = 46, 1250 WLAN_EID_QOS_CAPA = 46,
1251 /* 802.11z */
1252 WLAN_EID_LINK_ID = 101,
1199 /* 802.11s */ 1253 /* 802.11s */
1200 WLAN_EID_MESH_CONFIG = 113, 1254 WLAN_EID_MESH_CONFIG = 113,
1201 WLAN_EID_MESH_ID = 114, 1255 WLAN_EID_MESH_ID = 114,
@@ -1279,6 +1333,7 @@ enum ieee80211_category {
1279 WLAN_CATEGORY_HT = 7, 1333 WLAN_CATEGORY_HT = 7,
1280 WLAN_CATEGORY_SA_QUERY = 8, 1334 WLAN_CATEGORY_SA_QUERY = 8,
1281 WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION = 9, 1335 WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION = 9,
1336 WLAN_CATEGORY_TDLS = 12,
1282 WLAN_CATEGORY_MESH_ACTION = 13, 1337 WLAN_CATEGORY_MESH_ACTION = 13,
1283 WLAN_CATEGORY_MULTIHOP_ACTION = 14, 1338 WLAN_CATEGORY_MULTIHOP_ACTION = 14,
1284 WLAN_CATEGORY_SELF_PROTECTED = 15, 1339 WLAN_CATEGORY_SELF_PROTECTED = 15,
@@ -1342,6 +1397,36 @@ enum ieee80211_key_len {
1342 WLAN_KEY_LEN_AES_CMAC = 16, 1397 WLAN_KEY_LEN_AES_CMAC = 16,
1343}; 1398};
1344 1399
1400/* Public action codes */
1401enum ieee80211_pub_actioncode {
1402 WLAN_PUB_ACTION_TDLS_DISCOVER_RES = 14,
1403};
1404
1405/* TDLS action codes */
1406enum ieee80211_tdls_actioncode {
1407 WLAN_TDLS_SETUP_REQUEST = 0,
1408 WLAN_TDLS_SETUP_RESPONSE = 1,
1409 WLAN_TDLS_SETUP_CONFIRM = 2,
1410 WLAN_TDLS_TEARDOWN = 3,
1411 WLAN_TDLS_PEER_TRAFFIC_INDICATION = 4,
1412 WLAN_TDLS_CHANNEL_SWITCH_REQUEST = 5,
1413 WLAN_TDLS_CHANNEL_SWITCH_RESPONSE = 6,
1414 WLAN_TDLS_PEER_PSM_REQUEST = 7,
1415 WLAN_TDLS_PEER_PSM_RESPONSE = 8,
1416 WLAN_TDLS_PEER_TRAFFIC_RESPONSE = 9,
1417 WLAN_TDLS_DISCOVERY_REQUEST = 10,
1418};
1419
1420/*
1421 * TDLS capabililites to be enabled in the 5th byte of the
1422 * @WLAN_EID_EXT_CAPABILITY information element
1423 */
1424#define WLAN_EXT_CAPA5_TDLS_ENABLED BIT(5)
1425#define WLAN_EXT_CAPA5_TDLS_PROHIBITED BIT(6)
1426
1427/* TDLS specific payload type in the LLC/SNAP header */
1428#define WLAN_TDLS_SNAP_RFTYPE 0x2
1429
1345/** 1430/**
1346 * enum - mesh path selection protocol identifier 1431 * enum - mesh path selection protocol identifier
1347 * 1432 *
diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h
index a3d99ff6e3b5..49c38fc8dbc3 100644
--- a/include/linux/if_ether.h
+++ b/include/linux/if_ether.h
@@ -83,6 +83,7 @@
83#define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */ 83#define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */
84#define ETH_P_1588 0x88F7 /* IEEE 1588 Timesync */ 84#define ETH_P_1588 0x88F7 /* IEEE 1588 Timesync */
85#define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */ 85#define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */
86#define ETH_P_TDLS 0x890D /* TDLS */
86#define ETH_P_FIP 0x8914 /* FCoE Initialization Protocol */ 87#define ETH_P_FIP 0x8914 /* FCoE Initialization Protocol */
87#define ETH_P_QINQ1 0x9100 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */ 88#define ETH_P_QINQ1 0x9100 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
88#define ETH_P_QINQ2 0x9200 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */ 89#define ETH_P_QINQ2 0x9200 /* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index d1886b59bec4..7d3b438755f0 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -225,6 +225,18 @@ config MAC80211_VERBOSE_MHWMP_DEBUG
225 225
226 Do not select this option. 226 Do not select this option.
227 227
228config MAC80211_VERBOSE_TDLS_DEBUG
229 bool "Verbose TDLS debugging"
230 depends on MAC80211_DEBUG_MENU
231 ---help---
232 Selecting this option causes mac80211 to print out very
233 verbose TDLS selection debugging messages (when mac80211
234 is a TDLS STA).
235 It should not be selected on production systems as those
236 messages are remotely triggerable.
237
238 Do not select this option.
239
228config MAC80211_DEBUG_COUNTERS 240config MAC80211_DEBUG_COUNTERS
229 bool "Extra statistics for TX/RX debugging" 241 bool "Extra statistics for TX/RX debugging"
230 depends on MAC80211_DEBUG_MENU 242 depends on MAC80211_DEBUG_MENU
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 13061ebc93ef..1d17677a0ec1 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -12,6 +12,7 @@
12#include <linux/slab.h> 12#include <linux/slab.h>
13#include <net/net_namespace.h> 13#include <net/net_namespace.h>
14#include <linux/rcupdate.h> 14#include <linux/rcupdate.h>
15#include <linux/if_ether.h>
15#include <net/cfg80211.h> 16#include <net/cfg80211.h>
16#include "ieee80211_i.h" 17#include "ieee80211_i.h"
17#include "driver-ops.h" 18#include "driver-ops.h"
@@ -2128,6 +2129,313 @@ static int ieee80211_set_rekey_data(struct wiphy *wiphy,
2128 return 0; 2129 return 0;
2129} 2130}
2130 2131
2132static void ieee80211_tdls_add_ext_capab(struct sk_buff *skb)
2133{
2134 u8 *pos = (void *)skb_put(skb, 7);
2135
2136 *pos++ = WLAN_EID_EXT_CAPABILITY;
2137 *pos++ = 5; /* len */
2138 *pos++ = 0x0;
2139 *pos++ = 0x0;
2140 *pos++ = 0x0;
2141 *pos++ = 0x0;
2142 *pos++ = WLAN_EXT_CAPA5_TDLS_ENABLED;
2143}
2144
2145static u16 ieee80211_get_tdls_sta_capab(struct ieee80211_sub_if_data *sdata)
2146{
2147 struct ieee80211_local *local = sdata->local;
2148 u16 capab;
2149
2150 capab = 0;
2151 if (local->oper_channel->band != IEEE80211_BAND_2GHZ)
2152 return capab;
2153
2154 if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
2155 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
2156 if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE))
2157 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
2158
2159 return capab;
2160}
2161
2162static void ieee80211_tdls_add_link_ie(struct sk_buff *skb, u8 *src_addr,
2163 u8 *peer, u8 *bssid)
2164{
2165 struct ieee80211_tdls_lnkie *lnkid;
2166
2167 lnkid = (void *)skb_put(skb, sizeof(struct ieee80211_tdls_lnkie));
2168
2169 lnkid->ie_type = WLAN_EID_LINK_ID;
2170 lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) - 2;
2171
2172 memcpy(lnkid->bssid, bssid, ETH_ALEN);
2173 memcpy(lnkid->init_sta, src_addr, ETH_ALEN);
2174 memcpy(lnkid->resp_sta, peer, ETH_ALEN);
2175}
2176
2177static int
2178ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
2179 u8 *peer, u8 action_code, u8 dialog_token,
2180 u16 status_code, struct sk_buff *skb)
2181{
2182 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2183 struct ieee80211_tdls_data *tf;
2184
2185 tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u));
2186
2187 memcpy(tf->da, peer, ETH_ALEN);
2188 memcpy(tf->sa, sdata->vif.addr, ETH_ALEN);
2189 tf->ether_type = cpu_to_be16(ETH_P_TDLS);
2190 tf->payload_type = WLAN_TDLS_SNAP_RFTYPE;
2191
2192 switch (action_code) {
2193 case WLAN_TDLS_SETUP_REQUEST:
2194 tf->category = WLAN_CATEGORY_TDLS;
2195 tf->action_code = WLAN_TDLS_SETUP_REQUEST;
2196
2197 skb_put(skb, sizeof(tf->u.setup_req));
2198 tf->u.setup_req.dialog_token = dialog_token;
2199 tf->u.setup_req.capability =
2200 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
2201
2202 ieee80211_add_srates_ie(&sdata->vif, skb);
2203 ieee80211_add_ext_srates_ie(&sdata->vif, skb);
2204 ieee80211_tdls_add_ext_capab(skb);
2205 break;
2206 case WLAN_TDLS_SETUP_RESPONSE:
2207 tf->category = WLAN_CATEGORY_TDLS;
2208 tf->action_code = WLAN_TDLS_SETUP_RESPONSE;
2209
2210 skb_put(skb, sizeof(tf->u.setup_resp));
2211 tf->u.setup_resp.status_code = cpu_to_le16(status_code);
2212 tf->u.setup_resp.dialog_token = dialog_token;
2213 tf->u.setup_resp.capability =
2214 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
2215
2216 ieee80211_add_srates_ie(&sdata->vif, skb);
2217 ieee80211_add_ext_srates_ie(&sdata->vif, skb);
2218 ieee80211_tdls_add_ext_capab(skb);
2219 break;
2220 case WLAN_TDLS_SETUP_CONFIRM:
2221 tf->category = WLAN_CATEGORY_TDLS;
2222 tf->action_code = WLAN_TDLS_SETUP_CONFIRM;
2223
2224 skb_put(skb, sizeof(tf->u.setup_cfm));
2225 tf->u.setup_cfm.status_code = cpu_to_le16(status_code);
2226 tf->u.setup_cfm.dialog_token = dialog_token;
2227 break;
2228 case WLAN_TDLS_TEARDOWN:
2229 tf->category = WLAN_CATEGORY_TDLS;
2230 tf->action_code = WLAN_TDLS_TEARDOWN;
2231
2232 skb_put(skb, sizeof(tf->u.teardown));
2233 tf->u.teardown.reason_code = cpu_to_le16(status_code);
2234 break;
2235 case WLAN_TDLS_DISCOVERY_REQUEST:
2236 tf->category = WLAN_CATEGORY_TDLS;
2237 tf->action_code = WLAN_TDLS_DISCOVERY_REQUEST;
2238
2239 skb_put(skb, sizeof(tf->u.discover_req));
2240 tf->u.discover_req.dialog_token = dialog_token;
2241 break;
2242 default:
2243 return -EINVAL;
2244 }
2245
2246 return 0;
2247}
2248
2249static int
2250ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
2251 u8 *peer, u8 action_code, u8 dialog_token,
2252 u16 status_code, struct sk_buff *skb)
2253{
2254 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2255 struct ieee80211_mgmt *mgmt;
2256
2257 mgmt = (void *)skb_put(skb, 24);
2258 memset(mgmt, 0, 24);
2259 memcpy(mgmt->da, peer, ETH_ALEN);
2260 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
2261 memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN);
2262
2263 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2264 IEEE80211_STYPE_ACTION);
2265
2266 switch (action_code) {
2267 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
2268 skb_put(skb, 1 + sizeof(mgmt->u.action.u.tdls_discover_resp));
2269 mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
2270 mgmt->u.action.u.tdls_discover_resp.action_code =
2271 WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
2272 mgmt->u.action.u.tdls_discover_resp.dialog_token =
2273 dialog_token;
2274 mgmt->u.action.u.tdls_discover_resp.capability =
2275 cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata));
2276
2277 ieee80211_add_srates_ie(&sdata->vif, skb);
2278 ieee80211_add_ext_srates_ie(&sdata->vif, skb);
2279 ieee80211_tdls_add_ext_capab(skb);
2280 break;
2281 default:
2282 return -EINVAL;
2283 }
2284
2285 return 0;
2286}
2287
2288static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
2289 u8 *peer, u8 action_code, u8 dialog_token,
2290 u16 status_code, const u8 *extra_ies,
2291 size_t extra_ies_len)
2292{
2293 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2294 struct ieee80211_local *local = sdata->local;
2295 struct ieee80211_tx_info *info;
2296 struct sk_buff *skb = NULL;
2297 bool send_direct;
2298 int ret;
2299
2300 if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
2301 return -ENOTSUPP;
2302
2303 /* make sure we are in managed mode, and associated */
2304 if (sdata->vif.type != NL80211_IFTYPE_STATION ||
2305 !sdata->u.mgd.associated)
2306 return -EINVAL;
2307
2308#ifdef CONFIG_MAC80211_VERBOSE_TDLS_DEBUG
2309 printk(KERN_DEBUG "TDLS mgmt action %d peer %pM\n", action_code, peer);
2310#endif
2311
2312 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
2313 max(sizeof(struct ieee80211_mgmt),
2314 sizeof(struct ieee80211_tdls_data)) +
2315 50 + /* supported rates */
2316 7 + /* ext capab */
2317 extra_ies_len +
2318 sizeof(struct ieee80211_tdls_lnkie));
2319 if (!skb)
2320 return -ENOMEM;
2321
2322 info = IEEE80211_SKB_CB(skb);
2323 skb_reserve(skb, local->hw.extra_tx_headroom);
2324
2325 switch (action_code) {
2326 case WLAN_TDLS_SETUP_REQUEST:
2327 case WLAN_TDLS_SETUP_RESPONSE:
2328 case WLAN_TDLS_SETUP_CONFIRM:
2329 case WLAN_TDLS_TEARDOWN:
2330 case WLAN_TDLS_DISCOVERY_REQUEST:
2331 ret = ieee80211_prep_tdls_encap_data(wiphy, dev, peer,
2332 action_code, dialog_token,
2333 status_code, skb);
2334 send_direct = false;
2335 break;
2336 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
2337 ret = ieee80211_prep_tdls_direct(wiphy, dev, peer, action_code,
2338 dialog_token, status_code,
2339 skb);
2340 send_direct = true;
2341 break;
2342 default:
2343 ret = -ENOTSUPP;
2344 break;
2345 }
2346
2347 if (ret < 0)
2348 goto fail;
2349
2350 if (extra_ies_len)
2351 memcpy(skb_put(skb, extra_ies_len), extra_ies, extra_ies_len);
2352
2353 /* the TDLS link IE is always added last */
2354 switch (action_code) {
2355 case WLAN_TDLS_SETUP_REQUEST:
2356 case WLAN_TDLS_SETUP_CONFIRM:
2357 case WLAN_TDLS_TEARDOWN:
2358 case WLAN_TDLS_DISCOVERY_REQUEST:
2359 /* we are the initiator */
2360 ieee80211_tdls_add_link_ie(skb, sdata->vif.addr, peer,
2361 sdata->u.mgd.bssid);
2362 break;
2363 case WLAN_TDLS_SETUP_RESPONSE:
2364 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
2365 /* we are the responder */
2366 ieee80211_tdls_add_link_ie(skb, peer, sdata->vif.addr,
2367 sdata->u.mgd.bssid);
2368 break;
2369 default:
2370 ret = -ENOTSUPP;
2371 goto fail;
2372 }
2373
2374 if (send_direct) {
2375 ieee80211_tx_skb(sdata, skb);
2376 return 0;
2377 }
2378
2379 /*
2380 * According to 802.11z: Setup req/resp are sent in AC_BK, otherwise
2381 * we should default to AC_VI.
2382 */
2383 switch (action_code) {
2384 case WLAN_TDLS_SETUP_REQUEST:
2385 case WLAN_TDLS_SETUP_RESPONSE:
2386 skb_set_queue_mapping(skb, IEEE80211_AC_BK);
2387 skb->priority = 2;
2388 break;
2389 default:
2390 skb_set_queue_mapping(skb, IEEE80211_AC_VI);
2391 skb->priority = 5;
2392 break;
2393 }
2394
2395 /* disable bottom halves when entering the Tx path */
2396 local_bh_disable();
2397 ret = ieee80211_subif_start_xmit(skb, dev);
2398 local_bh_enable();
2399
2400 return ret;
2401
2402fail:
2403 dev_kfree_skb(skb);
2404 return ret;
2405}
2406
2407static int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
2408 u8 *peer, enum nl80211_tdls_operation oper)
2409{
2410 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2411
2412 if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
2413 return -ENOTSUPP;
2414
2415 if (sdata->vif.type != NL80211_IFTYPE_STATION)
2416 return -EINVAL;
2417
2418#ifdef CONFIG_MAC80211_VERBOSE_TDLS_DEBUG
2419 printk(KERN_DEBUG "TDLS oper %d peer %pM\n", oper, peer);
2420#endif
2421
2422 switch (oper) {
2423 case NL80211_TDLS_ENABLE_LINK:
2424 break;
2425 case NL80211_TDLS_DISABLE_LINK:
2426 return sta_info_destroy_addr(sdata, peer);
2427 case NL80211_TDLS_TEARDOWN:
2428 case NL80211_TDLS_SETUP:
2429 case NL80211_TDLS_DISCOVERY_REQ:
2430 /* We don't support in-driver setup/teardown/discovery */
2431 return -ENOTSUPP;
2432 default:
2433 return -ENOTSUPP;
2434 }
2435
2436 return 0;
2437}
2438
2131struct cfg80211_ops mac80211_config_ops = { 2439struct cfg80211_ops mac80211_config_ops = {
2132 .add_virtual_intf = ieee80211_add_iface, 2440 .add_virtual_intf = ieee80211_add_iface,
2133 .del_virtual_intf = ieee80211_del_iface, 2441 .del_virtual_intf = ieee80211_del_iface,
@@ -2191,4 +2499,6 @@ struct cfg80211_ops mac80211_config_ops = {
2191 .set_ringparam = ieee80211_set_ringparam, 2499 .set_ringparam = ieee80211_set_ringparam,
2192 .get_ringparam = ieee80211_get_ringparam, 2500 .get_ringparam = ieee80211_get_ringparam,
2193 .set_rekey_data = ieee80211_set_rekey_data, 2501 .set_rekey_data = ieee80211_set_rekey_data,
2502 .tdls_oper = ieee80211_tdls_oper,
2503 .tdls_mgmt = ieee80211_tdls_mgmt,
2194}; 2504};
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index a5809a1a6239..336ceb9d2462 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -863,6 +863,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
863 if (local->ops->sched_scan_start) 863 if (local->ops->sched_scan_start)
864 local->hw.wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; 864 local->hw.wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
865 865
866 /* mac80211 based drivers don't support internal TDLS setup */
867 if (local->hw.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)
868 local->hw.wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
869
866 result = wiphy_register(local->hw.wiphy); 870 result = wiphy_register(local->hw.wiphy);
867 if (result < 0) 871 if (result < 0)
868 goto fail_wiphy_register; 872 goto fail_wiphy_register;