1 /* Marvell Wireless LAN device driver: TDLS handling
3 * Copyright (C) 2014, Marvell International Ltd.
5 * This software file (the "File") is distributed by Marvell International
6 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
7 * (the "License"). You may use, redistribute and/or modify this File in
8 * accordance with the terms and conditions of the License, a copy of which
9 * is available on the worldwide web at
10 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
12 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
13 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
14 * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
15 * this warranty disclaimer.
21 #include "11n_rxreorder.h"
24 #define TDLS_REQ_FIX_LEN 6
25 #define TDLS_RESP_FIX_LEN 8
26 #define TDLS_CONFIRM_FIX_LEN 6
27 #define MWIFIEX_TDLS_WMM_INFO_SIZE 7
29 static void mwifiex_restore_tdls_packets(struct mwifiex_private
*priv
,
30 const u8
*mac
, u8 status
)
32 struct mwifiex_ra_list_tbl
*ra_list
;
33 struct list_head
*tid_list
;
34 struct sk_buff
*skb
, *tmp
;
35 struct mwifiex_txinfo
*tx_info
;
40 dev_dbg(priv
->adapter
->dev
, "%s: %pM\n", __func__
, mac
);
41 spin_lock_irqsave(&priv
->wmm
.ra_list_spinlock
, flags
);
43 skb_queue_walk_safe(&priv
->tdls_txq
, skb
, tmp
) {
44 if (!ether_addr_equal(mac
, skb
->data
))
47 __skb_unlink(skb
, &priv
->tdls_txq
);
48 tx_info
= MWIFIEX_SKB_TXCB(skb
);
50 tid_down
= mwifiex_wmm_downgrade_tid(priv
, tid
);
52 if (status
== TDLS_SETUP_COMPLETE
) {
53 ra_list
= mwifiex_wmm_get_queue_raptr(priv
, tid
, mac
);
54 ra_list
->tdls_link
= true;
55 tx_info
->flags
|= MWIFIEX_BUF_FLAG_TDLS_PKT
;
57 tid_list
= &priv
->wmm
.tid_tbl_ptr
[tid_down
].ra_list
;
58 if (!list_empty(tid_list
))
59 ra_list
= list_first_entry(tid_list
,
60 struct mwifiex_ra_list_tbl
, list
);
63 tx_info
->flags
&= ~MWIFIEX_BUF_FLAG_TDLS_PKT
;
67 mwifiex_write_data_complete(priv
->adapter
, skb
, 0, -1);
71 skb_queue_tail(&ra_list
->skb_head
, skb
);
73 ra_list
->ba_pkt_count
++;
74 ra_list
->total_pkt_count
++;
76 if (atomic_read(&priv
->wmm
.highest_queued_prio
) <
77 tos_to_tid_inv
[tid_down
])
78 atomic_set(&priv
->wmm
.highest_queued_prio
,
79 tos_to_tid_inv
[tid_down
]);
81 atomic_inc(&priv
->wmm
.tx_pkts_queued
);
84 spin_unlock_irqrestore(&priv
->wmm
.ra_list_spinlock
, flags
);
88 static void mwifiex_hold_tdls_packets(struct mwifiex_private
*priv
,
91 struct mwifiex_ra_list_tbl
*ra_list
;
92 struct list_head
*ra_list_head
;
93 struct sk_buff
*skb
, *tmp
;
97 dev_dbg(priv
->adapter
->dev
, "%s: %pM\n", __func__
, mac
);
98 spin_lock_irqsave(&priv
->wmm
.ra_list_spinlock
, flags
);
100 for (i
= 0; i
< MAX_NUM_TID
; i
++) {
101 if (!list_empty(&priv
->wmm
.tid_tbl_ptr
[i
].ra_list
)) {
102 ra_list_head
= &priv
->wmm
.tid_tbl_ptr
[i
].ra_list
;
103 list_for_each_entry(ra_list
, ra_list_head
, list
) {
104 skb_queue_walk_safe(&ra_list
->skb_head
, skb
,
106 if (!ether_addr_equal(mac
, skb
->data
))
108 __skb_unlink(skb
, &ra_list
->skb_head
);
109 atomic_dec(&priv
->wmm
.tx_pkts_queued
);
110 ra_list
->total_pkt_count
--;
111 skb_queue_tail(&priv
->tdls_txq
, skb
);
117 spin_unlock_irqrestore(&priv
->wmm
.ra_list_spinlock
, flags
);
121 /* This function appends rate TLV to scan config command. */
123 mwifiex_tdls_append_rates_ie(struct mwifiex_private
*priv
,
126 u8 rates
[MWIFIEX_SUPPORTED_RATES
], *pos
;
127 u16 rates_size
, supp_rates_size
, ext_rates_size
;
129 memset(rates
, 0, sizeof(rates
));
130 rates_size
= mwifiex_get_supported_rates(priv
, rates
);
132 supp_rates_size
= min_t(u16
, rates_size
, MWIFIEX_TDLS_SUPPORTED_RATES
);
134 if (skb_tailroom(skb
) < rates_size
+ 4) {
135 dev_err(priv
->adapter
->dev
,
136 "Insuffient space while adding rates\n");
140 pos
= skb_put(skb
, supp_rates_size
+ 2);
141 *pos
++ = WLAN_EID_SUPP_RATES
;
142 *pos
++ = supp_rates_size
;
143 memcpy(pos
, rates
, supp_rates_size
);
145 if (rates_size
> MWIFIEX_TDLS_SUPPORTED_RATES
) {
146 ext_rates_size
= rates_size
- MWIFIEX_TDLS_SUPPORTED_RATES
;
147 pos
= skb_put(skb
, ext_rates_size
+ 2);
148 *pos
++ = WLAN_EID_EXT_SUPP_RATES
;
149 *pos
++ = ext_rates_size
;
150 memcpy(pos
, rates
+ MWIFIEX_TDLS_SUPPORTED_RATES
,
157 static void mwifiex_tdls_add_aid(struct mwifiex_private
*priv
,
160 struct ieee_types_assoc_rsp
*assoc_rsp
;
163 assoc_rsp
= (struct ieee_types_assoc_rsp
*)&priv
->assoc_rsp_buf
;
164 pos
= (void *)skb_put(skb
, 4);
165 *pos
++ = WLAN_EID_AID
;
167 *pos
++ = le16_to_cpu(assoc_rsp
->a_id
);
172 static int mwifiex_tdls_add_vht_capab(struct mwifiex_private
*priv
,
175 struct ieee80211_vht_cap vht_cap
;
178 pos
= (void *)skb_put(skb
, sizeof(struct ieee80211_vht_cap
) + 2);
179 *pos
++ = WLAN_EID_VHT_CAPABILITY
;
180 *pos
++ = sizeof(struct ieee80211_vht_cap
);
182 memset(&vht_cap
, 0, sizeof(struct ieee80211_vht_cap
));
184 mwifiex_fill_vht_cap_tlv(priv
, &vht_cap
, priv
->curr_bss_params
.band
);
185 memcpy(pos
, &vht_cap
, sizeof(vht_cap
));
191 mwifiex_tdls_add_ht_oper(struct mwifiex_private
*priv
, const u8
*mac
,
192 u8 vht_enabled
, struct sk_buff
*skb
)
194 struct ieee80211_ht_operation
*ht_oper
;
195 struct mwifiex_sta_node
*sta_ptr
;
196 struct mwifiex_bssdescriptor
*bss_desc
=
197 &priv
->curr_bss_params
.bss_descriptor
;
200 sta_ptr
= mwifiex_get_sta_entry(priv
, mac
);
201 if (unlikely(!sta_ptr
)) {
202 dev_warn(priv
->adapter
->dev
,
203 "TDLS peer station not found in list\n");
207 pos
= (void *)skb_put(skb
, sizeof(struct ieee80211_ht_operation
) + 2);
208 *pos
++ = WLAN_EID_HT_OPERATION
;
209 *pos
++ = sizeof(struct ieee80211_ht_operation
);
210 ht_oper
= (void *)pos
;
212 ht_oper
->primary_chan
= bss_desc
->channel
;
214 /* follow AP's channel bandwidth */
215 if (ISSUPP_CHANWIDTH40(priv
->adapter
->hw_dot_11n_dev_cap
) &&
216 bss_desc
->bcn_ht_cap
&&
217 ISALLOWED_CHANWIDTH40(bss_desc
->bcn_ht_oper
->ht_param
))
218 ht_oper
->ht_param
= bss_desc
->bcn_ht_oper
->ht_param
;
222 mwifiex_get_sec_chan_offset(bss_desc
->channel
);
223 ht_oper
->ht_param
|= BIT(2);
226 memcpy(&sta_ptr
->tdls_cap
.ht_oper
, ht_oper
,
227 sizeof(struct ieee80211_ht_operation
));
232 static int mwifiex_tdls_add_vht_oper(struct mwifiex_private
*priv
,
233 const u8
*mac
, struct sk_buff
*skb
)
235 struct mwifiex_bssdescriptor
*bss_desc
;
236 struct ieee80211_vht_operation
*vht_oper
;
237 struct ieee80211_vht_cap
*vht_cap
, *ap_vht_cap
= NULL
;
238 struct mwifiex_sta_node
*sta_ptr
;
239 struct mwifiex_adapter
*adapter
= priv
->adapter
;
240 u8 supp_chwd_set
, peer_supp_chwd_set
;
241 u8
*pos
, ap_supp_chwd_set
, chan_bw
;
242 u16 mcs_map_user
, mcs_map_resp
, mcs_map_result
;
243 u16 mcs_user
, mcs_resp
, nss
;
244 u32 usr_vht_cap_info
;
246 bss_desc
= &priv
->curr_bss_params
.bss_descriptor
;
248 sta_ptr
= mwifiex_get_sta_entry(priv
, mac
);
249 if (unlikely(!sta_ptr
)) {
250 dev_warn(adapter
->dev
, "TDLS peer station not found in list\n");
254 if (!mwifiex_is_bss_in_11ac_mode(priv
)) {
255 if (sta_ptr
->tdls_cap
.extcap
.ext_capab
[7] &
256 WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED
) {
257 dev_dbg(adapter
->dev
,
258 "TDLS peer doesn't support wider bandwitdh\n");
262 ap_vht_cap
= bss_desc
->bcn_vht_cap
;
265 pos
= (void *)skb_put(skb
, sizeof(struct ieee80211_vht_operation
) + 2);
266 *pos
++ = WLAN_EID_VHT_OPERATION
;
267 *pos
++ = sizeof(struct ieee80211_vht_operation
);
268 vht_oper
= (struct ieee80211_vht_operation
*)pos
;
270 if (bss_desc
->bss_band
& BAND_A
)
271 usr_vht_cap_info
= adapter
->usr_dot_11ac_dev_cap_a
;
273 usr_vht_cap_info
= adapter
->usr_dot_11ac_dev_cap_bg
;
275 /* find the minmum bandwith between AP/TDLS peers */
276 vht_cap
= &sta_ptr
->tdls_cap
.vhtcap
;
277 supp_chwd_set
= GET_VHTCAP_CHWDSET(usr_vht_cap_info
);
279 GET_VHTCAP_CHWDSET(le32_to_cpu(vht_cap
->vht_cap_info
));
280 supp_chwd_set
= min_t(u8
, supp_chwd_set
, peer_supp_chwd_set
);
282 /* We need check AP's bandwidth when TDLS_WIDER_BANDWIDTH is off */
284 if (ap_vht_cap
&& sta_ptr
->tdls_cap
.extcap
.ext_capab
[7] &
285 WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED
) {
287 GET_VHTCAP_CHWDSET(le32_to_cpu(ap_vht_cap
->vht_cap_info
));
288 supp_chwd_set
= min_t(u8
, supp_chwd_set
, ap_supp_chwd_set
);
291 switch (supp_chwd_set
) {
292 case IEEE80211_VHT_CHANWIDTH_80MHZ
:
293 vht_oper
->chan_width
= IEEE80211_VHT_CHANWIDTH_80MHZ
;
295 case IEEE80211_VHT_CHANWIDTH_160MHZ
:
296 vht_oper
->chan_width
= IEEE80211_VHT_CHANWIDTH_160MHZ
;
298 case IEEE80211_VHT_CHANWIDTH_80P80MHZ
:
299 vht_oper
->chan_width
= IEEE80211_VHT_CHANWIDTH_80P80MHZ
;
302 vht_oper
->chan_width
= IEEE80211_VHT_CHANWIDTH_USE_HT
;
306 mcs_map_user
= GET_DEVRXMCSMAP(adapter
->usr_dot_11ac_mcs_support
);
307 mcs_map_resp
= le16_to_cpu(vht_cap
->supp_mcs
.rx_mcs_map
);
310 for (nss
= 1; nss
<= 8; nss
++) {
311 mcs_user
= GET_VHTNSSMCS(mcs_map_user
, nss
);
312 mcs_resp
= GET_VHTNSSMCS(mcs_map_resp
, nss
);
314 if ((mcs_user
== IEEE80211_VHT_MCS_NOT_SUPPORTED
) ||
315 (mcs_resp
== IEEE80211_VHT_MCS_NOT_SUPPORTED
))
316 SET_VHTNSSMCS(mcs_map_result
, nss
,
317 IEEE80211_VHT_MCS_NOT_SUPPORTED
);
319 SET_VHTNSSMCS(mcs_map_result
, nss
,
320 min_t(u16
, mcs_user
, mcs_resp
));
323 vht_oper
->basic_mcs_set
= cpu_to_le16(mcs_map_result
);
325 switch (vht_oper
->chan_width
) {
326 case IEEE80211_VHT_CHANWIDTH_80MHZ
:
327 chan_bw
= IEEE80211_VHT_CHANWIDTH_80MHZ
;
329 case IEEE80211_VHT_CHANWIDTH_160MHZ
:
330 chan_bw
= IEEE80211_VHT_CHANWIDTH_160MHZ
;
332 case IEEE80211_VHT_CHANWIDTH_80P80MHZ
:
333 chan_bw
= IEEE80211_VHT_CHANWIDTH_80MHZ
;
336 chan_bw
= IEEE80211_VHT_CHANWIDTH_USE_HT
;
339 vht_oper
->center_freq_seg1_idx
=
340 mwifiex_get_center_freq_index(priv
, BAND_AAC
,
347 static void mwifiex_tdls_add_ext_capab(struct mwifiex_private
*priv
,
350 struct ieee_types_extcap
*extcap
;
352 extcap
= (void *)skb_put(skb
, sizeof(struct ieee_types_extcap
));
353 extcap
->ieee_hdr
.element_id
= WLAN_EID_EXT_CAPABILITY
;
354 extcap
->ieee_hdr
.len
= 8;
355 memset(extcap
->ext_capab
, 0, 8);
356 extcap
->ext_capab
[4] |= WLAN_EXT_CAPA5_TDLS_ENABLED
;
358 if (priv
->adapter
->is_hw_11ac_capable
)
359 extcap
->ext_capab
[7] |= WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED
;
362 static void mwifiex_tdls_add_qos_capab(struct sk_buff
*skb
)
364 u8
*pos
= (void *)skb_put(skb
, 3);
366 *pos
++ = WLAN_EID_QOS_CAPA
;
368 *pos
++ = MWIFIEX_TDLS_DEF_QOS_CAPAB
;
372 mwifiex_tdls_add_wmm_param_ie(struct mwifiex_private
*priv
, struct sk_buff
*skb
)
374 struct ieee80211_wmm_param_ie
*wmm
;
375 u8 ac_vi
[] = {0x42, 0x43, 0x5e, 0x00};
376 u8 ac_vo
[] = {0x62, 0x32, 0x2f, 0x00};
377 u8 ac_be
[] = {0x03, 0xa4, 0x00, 0x00};
378 u8 ac_bk
[] = {0x27, 0xa4, 0x00, 0x00};
380 wmm
= (void *)skb_put(skb
, sizeof(*wmm
));
381 memset(wmm
, 0, sizeof(*wmm
));
383 wmm
->element_id
= WLAN_EID_VENDOR_SPECIFIC
;
384 wmm
->len
= sizeof(*wmm
) - 2;
385 wmm
->oui
[0] = 0x00; /* Microsoft OUI 00:50:F2 */
388 wmm
->oui_type
= 2; /* WME */
389 wmm
->oui_subtype
= 1; /* WME param */
390 wmm
->version
= 1; /* WME ver */
391 wmm
->qos_info
= 0; /* U-APSD not in use */
393 /* use default WMM AC parameters for TDLS link*/
394 memcpy(&wmm
->ac
[0], ac_be
, sizeof(ac_be
));
395 memcpy(&wmm
->ac
[1], ac_bk
, sizeof(ac_bk
));
396 memcpy(&wmm
->ac
[2], ac_vi
, sizeof(ac_vi
));
397 memcpy(&wmm
->ac
[3], ac_vo
, sizeof(ac_vo
));
401 mwifiex_add_wmm_info_ie(struct mwifiex_private
*priv
, struct sk_buff
*skb
,
406 buf
= (void *)skb_put(skb
, MWIFIEX_TDLS_WMM_INFO_SIZE
+
407 sizeof(struct ieee_types_header
));
409 *buf
++ = WLAN_EID_VENDOR_SPECIFIC
;
410 *buf
++ = 7; /* len */
411 *buf
++ = 0x00; /* Microsoft OUI 00:50:F2 */
414 *buf
++ = 2; /* WME */
415 *buf
++ = 0; /* WME info */
416 *buf
++ = 1; /* WME ver */
417 *buf
++ = qosinfo
; /* U-APSD no in use */
420 static int mwifiex_prep_tdls_encap_data(struct mwifiex_private
*priv
,
421 const u8
*peer
, u8 action_code
,
423 u16 status_code
, struct sk_buff
*skb
)
425 struct ieee80211_tdls_data
*tf
;
428 struct ieee80211_ht_cap
*ht_cap
;
431 capab
= priv
->curr_bss_params
.bss_descriptor
.cap_info_bitmap
;
433 tf
= (void *)skb_put(skb
, offsetof(struct ieee80211_tdls_data
, u
));
434 memcpy(tf
->da
, peer
, ETH_ALEN
);
435 memcpy(tf
->sa
, priv
->curr_addr
, ETH_ALEN
);
436 tf
->ether_type
= cpu_to_be16(ETH_P_TDLS
);
437 tf
->payload_type
= WLAN_TDLS_SNAP_RFTYPE
;
439 switch (action_code
) {
440 case WLAN_TDLS_SETUP_REQUEST
:
441 tf
->category
= WLAN_CATEGORY_TDLS
;
442 tf
->action_code
= WLAN_TDLS_SETUP_REQUEST
;
443 skb_put(skb
, sizeof(tf
->u
.setup_req
));
444 tf
->u
.setup_req
.dialog_token
= dialog_token
;
445 tf
->u
.setup_req
.capability
= cpu_to_le16(capab
);
446 ret
= mwifiex_tdls_append_rates_ie(priv
, skb
);
448 dev_kfree_skb_any(skb
);
452 pos
= (void *)skb_put(skb
, sizeof(struct ieee80211_ht_cap
) + 2);
453 *pos
++ = WLAN_EID_HT_CAPABILITY
;
454 *pos
++ = sizeof(struct ieee80211_ht_cap
);
455 ht_cap
= (void *)pos
;
456 radio
= mwifiex_band_to_radio_type(priv
->curr_bss_params
.band
);
457 ret
= mwifiex_fill_cap_info(priv
, radio
, ht_cap
);
459 dev_kfree_skb_any(skb
);
463 if (priv
->adapter
->is_hw_11ac_capable
) {
464 ret
= mwifiex_tdls_add_vht_capab(priv
, skb
);
466 dev_kfree_skb_any(skb
);
469 mwifiex_tdls_add_aid(priv
, skb
);
472 mwifiex_tdls_add_ext_capab(priv
, skb
);
473 mwifiex_tdls_add_qos_capab(skb
);
474 mwifiex_add_wmm_info_ie(priv
, skb
, 0);
477 case WLAN_TDLS_SETUP_RESPONSE
:
478 tf
->category
= WLAN_CATEGORY_TDLS
;
479 tf
->action_code
= WLAN_TDLS_SETUP_RESPONSE
;
480 skb_put(skb
, sizeof(tf
->u
.setup_resp
));
481 tf
->u
.setup_resp
.status_code
= cpu_to_le16(status_code
);
482 tf
->u
.setup_resp
.dialog_token
= dialog_token
;
483 tf
->u
.setup_resp
.capability
= cpu_to_le16(capab
);
484 ret
= mwifiex_tdls_append_rates_ie(priv
, skb
);
486 dev_kfree_skb_any(skb
);
490 pos
= (void *)skb_put(skb
, sizeof(struct ieee80211_ht_cap
) + 2);
491 *pos
++ = WLAN_EID_HT_CAPABILITY
;
492 *pos
++ = sizeof(struct ieee80211_ht_cap
);
493 ht_cap
= (void *)pos
;
494 radio
= mwifiex_band_to_radio_type(priv
->curr_bss_params
.band
);
495 ret
= mwifiex_fill_cap_info(priv
, radio
, ht_cap
);
497 dev_kfree_skb_any(skb
);
501 if (priv
->adapter
->is_hw_11ac_capable
) {
502 ret
= mwifiex_tdls_add_vht_capab(priv
, skb
);
504 dev_kfree_skb_any(skb
);
507 mwifiex_tdls_add_aid(priv
, skb
);
510 mwifiex_tdls_add_ext_capab(priv
, skb
);
511 mwifiex_tdls_add_qos_capab(skb
);
512 mwifiex_add_wmm_info_ie(priv
, skb
, 0);
515 case WLAN_TDLS_SETUP_CONFIRM
:
516 tf
->category
= WLAN_CATEGORY_TDLS
;
517 tf
->action_code
= WLAN_TDLS_SETUP_CONFIRM
;
518 skb_put(skb
, sizeof(tf
->u
.setup_cfm
));
519 tf
->u
.setup_cfm
.status_code
= cpu_to_le16(status_code
);
520 tf
->u
.setup_cfm
.dialog_token
= dialog_token
;
522 mwifiex_tdls_add_wmm_param_ie(priv
, skb
);
523 if (priv
->adapter
->is_hw_11ac_capable
) {
524 ret
= mwifiex_tdls_add_vht_oper(priv
, peer
, skb
);
526 dev_kfree_skb_any(skb
);
529 ret
= mwifiex_tdls_add_ht_oper(priv
, peer
, 1, skb
);
531 dev_kfree_skb_any(skb
);
535 ret
= mwifiex_tdls_add_ht_oper(priv
, peer
, 0, skb
);
537 dev_kfree_skb_any(skb
);
543 case WLAN_TDLS_TEARDOWN
:
544 tf
->category
= WLAN_CATEGORY_TDLS
;
545 tf
->action_code
= WLAN_TDLS_TEARDOWN
;
546 skb_put(skb
, sizeof(tf
->u
.teardown
));
547 tf
->u
.teardown
.reason_code
= cpu_to_le16(status_code
);
550 case WLAN_TDLS_DISCOVERY_REQUEST
:
551 tf
->category
= WLAN_CATEGORY_TDLS
;
552 tf
->action_code
= WLAN_TDLS_DISCOVERY_REQUEST
;
553 skb_put(skb
, sizeof(tf
->u
.discover_req
));
554 tf
->u
.discover_req
.dialog_token
= dialog_token
;
557 dev_err(priv
->adapter
->dev
, "Unknown TDLS frame type.\n");
565 mwifiex_tdls_add_link_ie(struct sk_buff
*skb
, const u8
*src_addr
,
566 const u8
*peer
, const u8
*bssid
)
568 struct ieee80211_tdls_lnkie
*lnkid
;
570 lnkid
= (void *)skb_put(skb
, sizeof(struct ieee80211_tdls_lnkie
));
571 lnkid
->ie_type
= WLAN_EID_LINK_ID
;
572 lnkid
->ie_len
= sizeof(struct ieee80211_tdls_lnkie
) -
573 sizeof(struct ieee_types_header
);
575 memcpy(lnkid
->bssid
, bssid
, ETH_ALEN
);
576 memcpy(lnkid
->init_sta
, src_addr
, ETH_ALEN
);
577 memcpy(lnkid
->resp_sta
, peer
, ETH_ALEN
);
580 int mwifiex_send_tdls_data_frame(struct mwifiex_private
*priv
, const u8
*peer
,
581 u8 action_code
, u8 dialog_token
,
582 u16 status_code
, const u8
*extra_ies
,
583 size_t extra_ies_len
)
586 struct mwifiex_txinfo
*tx_info
;
590 skb_len
= MWIFIEX_MIN_DATA_HEADER_LEN
+
591 max(sizeof(struct ieee80211_mgmt
),
592 sizeof(struct ieee80211_tdls_data
)) +
593 MWIFIEX_MGMT_FRAME_HEADER_SIZE
+
594 MWIFIEX_SUPPORTED_RATES
+
596 sizeof(struct ieee_types_extcap
) +
597 sizeof(struct ieee80211_ht_cap
) +
598 sizeof(struct ieee_types_bss_co_2040
) +
599 sizeof(struct ieee80211_ht_operation
) +
600 sizeof(struct ieee80211_tdls_lnkie
) +
601 sizeof(struct ieee80211_wmm_param_ie
) +
604 if (priv
->adapter
->is_hw_11ac_capable
)
605 skb_len
+= sizeof(struct ieee_types_vht_cap
) +
606 sizeof(struct ieee_types_vht_oper
) +
607 sizeof(struct ieee_types_aid
);
609 skb
= dev_alloc_skb(skb_len
);
611 dev_err(priv
->adapter
->dev
,
612 "allocate skb failed for management frame\n");
615 skb_reserve(skb
, MWIFIEX_MIN_DATA_HEADER_LEN
);
617 switch (action_code
) {
618 case WLAN_TDLS_SETUP_REQUEST
:
619 case WLAN_TDLS_SETUP_CONFIRM
:
620 case WLAN_TDLS_TEARDOWN
:
621 case WLAN_TDLS_DISCOVERY_REQUEST
:
622 ret
= mwifiex_prep_tdls_encap_data(priv
, peer
, action_code
,
623 dialog_token
, status_code
,
626 dev_kfree_skb_any(skb
);
630 memcpy(skb_put(skb
, extra_ies_len
), extra_ies
,
632 mwifiex_tdls_add_link_ie(skb
, priv
->curr_addr
, peer
,
635 case WLAN_TDLS_SETUP_RESPONSE
:
636 ret
= mwifiex_prep_tdls_encap_data(priv
, peer
, action_code
,
637 dialog_token
, status_code
,
640 dev_kfree_skb_any(skb
);
644 memcpy(skb_put(skb
, extra_ies_len
), extra_ies
,
646 mwifiex_tdls_add_link_ie(skb
, peer
, priv
->curr_addr
,
651 switch (action_code
) {
652 case WLAN_TDLS_SETUP_REQUEST
:
653 case WLAN_TDLS_SETUP_RESPONSE
:
654 skb
->priority
= MWIFIEX_PRIO_BK
;
657 skb
->priority
= MWIFIEX_PRIO_VI
;
661 tx_info
= MWIFIEX_SKB_TXCB(skb
);
662 memset(tx_info
, 0, sizeof(*tx_info
));
663 tx_info
->bss_num
= priv
->bss_num
;
664 tx_info
->bss_type
= priv
->bss_type
;
666 __net_timestamp(skb
);
667 mwifiex_queue_tx_pkt(priv
, skb
);
673 mwifiex_construct_tdls_action_frame(struct mwifiex_private
*priv
,
675 u8 action_code
, u8 dialog_token
,
676 u16 status_code
, struct sk_buff
*skb
)
678 struct ieee80211_mgmt
*mgmt
;
679 u8 bc_addr
[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
682 struct ieee80211_ht_cap
*ht_cap
;
685 capab
= priv
->curr_bss_params
.bss_descriptor
.cap_info_bitmap
;
687 mgmt
= (void *)skb_put(skb
, offsetof(struct ieee80211_mgmt
, u
));
690 memcpy(mgmt
->da
, peer
, ETH_ALEN
);
691 memcpy(mgmt
->sa
, priv
->curr_addr
, ETH_ALEN
);
692 memcpy(mgmt
->bssid
, priv
->cfg_bssid
, ETH_ALEN
);
693 mgmt
->frame_control
= cpu_to_le16(IEEE80211_FTYPE_MGMT
|
694 IEEE80211_STYPE_ACTION
);
697 pos
= skb_put(skb
, ETH_ALEN
);
699 switch (action_code
) {
700 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES
:
701 skb_put(skb
, sizeof(mgmt
->u
.action
.u
.tdls_discover_resp
) + 1);
702 mgmt
->u
.action
.category
= WLAN_CATEGORY_PUBLIC
;
703 mgmt
->u
.action
.u
.tdls_discover_resp
.action_code
=
704 WLAN_PUB_ACTION_TDLS_DISCOVER_RES
;
705 mgmt
->u
.action
.u
.tdls_discover_resp
.dialog_token
=
707 mgmt
->u
.action
.u
.tdls_discover_resp
.capability
=
709 /* move back for addr4 */
710 memmove(pos
+ ETH_ALEN
, &mgmt
->u
.action
.category
,
711 sizeof(mgmt
->u
.action
.u
.tdls_discover_resp
));
713 memcpy(pos
, bc_addr
, ETH_ALEN
);
715 ret
= mwifiex_tdls_append_rates_ie(priv
, skb
);
717 dev_kfree_skb_any(skb
);
721 pos
= (void *)skb_put(skb
, sizeof(struct ieee80211_ht_cap
) + 2);
722 *pos
++ = WLAN_EID_HT_CAPABILITY
;
723 *pos
++ = sizeof(struct ieee80211_ht_cap
);
724 ht_cap
= (void *)pos
;
725 radio
= mwifiex_band_to_radio_type(priv
->curr_bss_params
.band
);
726 ret
= mwifiex_fill_cap_info(priv
, radio
, ht_cap
);
728 dev_kfree_skb_any(skb
);
732 if (priv
->adapter
->is_hw_11ac_capable
) {
733 ret
= mwifiex_tdls_add_vht_capab(priv
, skb
);
735 dev_kfree_skb_any(skb
);
738 mwifiex_tdls_add_aid(priv
, skb
);
741 mwifiex_tdls_add_ext_capab(priv
, skb
);
742 mwifiex_tdls_add_qos_capab(skb
);
745 dev_err(priv
->adapter
->dev
, "Unknown TDLS action frame type\n");
752 int mwifiex_send_tdls_action_frame(struct mwifiex_private
*priv
, const u8
*peer
,
753 u8 action_code
, u8 dialog_token
,
754 u16 status_code
, const u8
*extra_ies
,
755 size_t extra_ies_len
)
758 struct mwifiex_txinfo
*tx_info
;
760 u32 pkt_type
, tx_control
;
761 u16 pkt_len
, skb_len
;
763 skb_len
= MWIFIEX_MIN_DATA_HEADER_LEN
+
764 max(sizeof(struct ieee80211_mgmt
),
765 sizeof(struct ieee80211_tdls_data
)) +
766 MWIFIEX_MGMT_FRAME_HEADER_SIZE
+
767 MWIFIEX_SUPPORTED_RATES
+
768 sizeof(struct ieee_types_extcap
) +
769 sizeof(struct ieee80211_ht_cap
) +
770 sizeof(struct ieee_types_bss_co_2040
) +
771 sizeof(struct ieee80211_ht_operation
) +
772 sizeof(struct ieee80211_tdls_lnkie
) +
775 ETH_ALEN
; /* Address4 */
777 if (priv
->adapter
->is_hw_11ac_capable
)
778 skb_len
+= sizeof(struct ieee_types_vht_cap
) +
779 sizeof(struct ieee_types_vht_oper
) +
780 sizeof(struct ieee_types_aid
);
782 skb
= dev_alloc_skb(skb_len
);
784 dev_err(priv
->adapter
->dev
,
785 "allocate skb failed for management frame\n");
789 skb_reserve(skb
, MWIFIEX_MIN_DATA_HEADER_LEN
);
791 pkt_type
= PKT_TYPE_MGMT
;
793 pos
= skb_put(skb
, MWIFIEX_MGMT_FRAME_HEADER_SIZE
+ sizeof(pkt_len
));
794 memset(pos
, 0, MWIFIEX_MGMT_FRAME_HEADER_SIZE
+ sizeof(pkt_len
));
795 memcpy(pos
, &pkt_type
, sizeof(pkt_type
));
796 memcpy(pos
+ sizeof(pkt_type
), &tx_control
, sizeof(tx_control
));
798 if (mwifiex_construct_tdls_action_frame(priv
, peer
, action_code
,
799 dialog_token
, status_code
,
801 dev_kfree_skb_any(skb
);
806 memcpy(skb_put(skb
, extra_ies_len
), extra_ies
, extra_ies_len
);
808 /* the TDLS link IE is always added last we are the responder */
810 mwifiex_tdls_add_link_ie(skb
, peer
, priv
->curr_addr
,
813 skb
->priority
= MWIFIEX_PRIO_VI
;
815 tx_info
= MWIFIEX_SKB_TXCB(skb
);
816 memset(tx_info
, 0, sizeof(*tx_info
));
817 tx_info
->bss_num
= priv
->bss_num
;
818 tx_info
->bss_type
= priv
->bss_type
;
819 tx_info
->flags
|= MWIFIEX_BUF_FLAG_TDLS_PKT
;
821 pkt_len
= skb
->len
- MWIFIEX_MGMT_FRAME_HEADER_SIZE
- sizeof(pkt_len
);
822 memcpy(skb
->data
+ MWIFIEX_MGMT_FRAME_HEADER_SIZE
, &pkt_len
,
824 __net_timestamp(skb
);
825 mwifiex_queue_tx_pkt(priv
, skb
);
830 /* This function process tdls action frame from peer.
831 * Peer capabilities are stored into station node structure.
833 void mwifiex_process_tdls_action_frame(struct mwifiex_private
*priv
,
836 struct mwifiex_sta_node
*sta_ptr
;
837 u8
*peer
, *pos
, *end
;
842 if (len
< (sizeof(struct ethhdr
) + 3))
844 if (*(buf
+ sizeof(struct ethhdr
)) != WLAN_TDLS_SNAP_RFTYPE
)
846 if (*(buf
+ sizeof(struct ethhdr
) + 1) != WLAN_CATEGORY_TDLS
)
849 peer
= buf
+ ETH_ALEN
;
850 action
= *(buf
+ sizeof(struct ethhdr
) + 2);
851 dev_dbg(priv
->adapter
->dev
,
852 "rx:tdls action: peer=%pM, action=%d\n", peer
, action
);
855 case WLAN_TDLS_SETUP_REQUEST
:
856 if (len
< (sizeof(struct ethhdr
) + TDLS_REQ_FIX_LEN
))
859 pos
= buf
+ sizeof(struct ethhdr
) + 4;
860 /* payload 1+ category 1 + action 1 + dialog 1 */
861 cap
= cpu_to_le16(*(u16
*)pos
);
862 ie_len
= len
- sizeof(struct ethhdr
) - TDLS_REQ_FIX_LEN
;
866 case WLAN_TDLS_SETUP_RESPONSE
:
867 if (len
< (sizeof(struct ethhdr
) + TDLS_RESP_FIX_LEN
))
869 /* payload 1+ category 1 + action 1 + dialog 1 + status code 2*/
870 pos
= buf
+ sizeof(struct ethhdr
) + 6;
871 cap
= cpu_to_le16(*(u16
*)pos
);
872 ie_len
= len
- sizeof(struct ethhdr
) - TDLS_RESP_FIX_LEN
;
876 case WLAN_TDLS_SETUP_CONFIRM
:
877 if (len
< (sizeof(struct ethhdr
) + TDLS_CONFIRM_FIX_LEN
))
879 pos
= buf
+ sizeof(struct ethhdr
) + TDLS_CONFIRM_FIX_LEN
;
880 ie_len
= len
- sizeof(struct ethhdr
) - TDLS_CONFIRM_FIX_LEN
;
883 dev_dbg(priv
->adapter
->dev
, "Unknown TDLS frame type.\n");
887 sta_ptr
= mwifiex_add_sta_entry(priv
, peer
);
891 sta_ptr
->tdls_cap
.capab
= cap
;
893 for (end
= pos
+ ie_len
; pos
+ 1 < end
; pos
+= 2 + pos
[1]) {
894 if (pos
+ 2 + pos
[1] > end
)
898 case WLAN_EID_SUPP_RATES
:
899 sta_ptr
->tdls_cap
.rates_len
= pos
[1];
900 for (i
= 0; i
< pos
[1]; i
++)
901 sta_ptr
->tdls_cap
.rates
[i
] = pos
[i
+ 2];
904 case WLAN_EID_EXT_SUPP_RATES
:
905 basic
= sta_ptr
->tdls_cap
.rates_len
;
906 for (i
= 0; i
< pos
[1]; i
++)
907 sta_ptr
->tdls_cap
.rates
[basic
+ i
] = pos
[i
+ 2];
908 sta_ptr
->tdls_cap
.rates_len
+= pos
[1];
910 case WLAN_EID_HT_CAPABILITY
:
911 memcpy((u8
*)&sta_ptr
->tdls_cap
.ht_capb
, pos
,
912 sizeof(struct ieee80211_ht_cap
));
913 sta_ptr
->is_11n_enabled
= 1;
915 case WLAN_EID_HT_OPERATION
:
916 memcpy(&sta_ptr
->tdls_cap
.ht_oper
, pos
,
917 sizeof(struct ieee80211_ht_operation
));
919 case WLAN_EID_BSS_COEX_2040
:
920 sta_ptr
->tdls_cap
.coex_2040
= pos
[2];
922 case WLAN_EID_EXT_CAPABILITY
:
923 memcpy((u8
*)&sta_ptr
->tdls_cap
.extcap
, pos
,
924 sizeof(struct ieee_types_header
) +
925 min_t(u8
, pos
[1], 8));
928 memcpy((u8
*)&sta_ptr
->tdls_cap
.rsn_ie
, pos
,
929 sizeof(struct ieee_types_header
) +
930 min_t(u8
, pos
[1], IEEE_MAX_IE_SIZE
-
931 sizeof(struct ieee_types_header
)));
933 case WLAN_EID_QOS_CAPA
:
934 sta_ptr
->tdls_cap
.qos_info
= pos
[2];
936 case WLAN_EID_VHT_OPERATION
:
937 if (priv
->adapter
->is_hw_11ac_capable
)
938 memcpy(&sta_ptr
->tdls_cap
.vhtoper
, pos
,
939 sizeof(struct ieee80211_vht_operation
));
941 case WLAN_EID_VHT_CAPABILITY
:
942 if (priv
->adapter
->is_hw_11ac_capable
) {
943 memcpy((u8
*)&sta_ptr
->tdls_cap
.vhtcap
, pos
,
944 sizeof(struct ieee80211_vht_cap
));
945 sta_ptr
->is_11ac_enabled
= 1;
949 if (priv
->adapter
->is_hw_11ac_capable
)
950 sta_ptr
->tdls_cap
.aid
=
951 le16_to_cpu(*(__le16
*)(pos
+ 2));
961 mwifiex_tdls_process_config_link(struct mwifiex_private
*priv
, const u8
*peer
)
963 struct mwifiex_sta_node
*sta_ptr
;
964 struct mwifiex_ds_tdls_oper tdls_oper
;
966 memset(&tdls_oper
, 0, sizeof(struct mwifiex_ds_tdls_oper
));
967 sta_ptr
= mwifiex_get_sta_entry(priv
, peer
);
969 if (!sta_ptr
|| sta_ptr
->tdls_status
== TDLS_SETUP_FAILURE
) {
970 dev_err(priv
->adapter
->dev
,
971 "link absent for peer %pM; cannot config\n", peer
);
975 memcpy(&tdls_oper
.peer_mac
, peer
, ETH_ALEN
);
976 tdls_oper
.tdls_action
= MWIFIEX_TDLS_CONFIG_LINK
;
977 return mwifiex_send_cmd(priv
, HostCmd_CMD_TDLS_OPER
,
978 HostCmd_ACT_GEN_SET
, 0, &tdls_oper
, true);
982 mwifiex_tdls_process_create_link(struct mwifiex_private
*priv
, const u8
*peer
)
984 struct mwifiex_sta_node
*sta_ptr
;
985 struct mwifiex_ds_tdls_oper tdls_oper
;
987 memset(&tdls_oper
, 0, sizeof(struct mwifiex_ds_tdls_oper
));
988 sta_ptr
= mwifiex_get_sta_entry(priv
, peer
);
990 if (sta_ptr
&& sta_ptr
->tdls_status
== TDLS_SETUP_INPROGRESS
) {
991 dev_dbg(priv
->adapter
->dev
,
992 "Setup already in progress for peer %pM\n", peer
);
996 sta_ptr
= mwifiex_add_sta_entry(priv
, peer
);
1000 sta_ptr
->tdls_status
= TDLS_SETUP_INPROGRESS
;
1001 mwifiex_hold_tdls_packets(priv
, peer
);
1002 memcpy(&tdls_oper
.peer_mac
, peer
, ETH_ALEN
);
1003 tdls_oper
.tdls_action
= MWIFIEX_TDLS_CREATE_LINK
;
1004 return mwifiex_send_cmd(priv
, HostCmd_CMD_TDLS_OPER
,
1005 HostCmd_ACT_GEN_SET
, 0, &tdls_oper
, true);
1009 mwifiex_tdls_process_disable_link(struct mwifiex_private
*priv
, const u8
*peer
)
1011 struct mwifiex_sta_node
*sta_ptr
;
1012 struct mwifiex_ds_tdls_oper tdls_oper
;
1013 unsigned long flags
;
1015 memset(&tdls_oper
, 0, sizeof(struct mwifiex_ds_tdls_oper
));
1016 sta_ptr
= mwifiex_get_sta_entry(priv
, peer
);
1019 if (sta_ptr
->is_11n_enabled
) {
1020 mwifiex_11n_cleanup_reorder_tbl(priv
);
1021 spin_lock_irqsave(&priv
->wmm
.ra_list_spinlock
,
1023 mwifiex_11n_delete_all_tx_ba_stream_tbl(priv
);
1024 spin_unlock_irqrestore(&priv
->wmm
.ra_list_spinlock
,
1027 mwifiex_del_sta_entry(priv
, peer
);
1030 mwifiex_restore_tdls_packets(priv
, peer
, TDLS_LINK_TEARDOWN
);
1031 mwifiex_auto_tdls_update_peer_status(priv
, peer
, TDLS_NOT_SETUP
);
1032 memcpy(&tdls_oper
.peer_mac
, peer
, ETH_ALEN
);
1033 tdls_oper
.tdls_action
= MWIFIEX_TDLS_DISABLE_LINK
;
1034 return mwifiex_send_cmd(priv
, HostCmd_CMD_TDLS_OPER
,
1035 HostCmd_ACT_GEN_SET
, 0, &tdls_oper
, true);
1039 mwifiex_tdls_process_enable_link(struct mwifiex_private
*priv
, const u8
*peer
)
1041 struct mwifiex_sta_node
*sta_ptr
;
1042 struct ieee80211_mcs_info mcs
;
1043 unsigned long flags
;
1046 sta_ptr
= mwifiex_get_sta_entry(priv
, peer
);
1048 if (sta_ptr
&& (sta_ptr
->tdls_status
!= TDLS_SETUP_FAILURE
)) {
1049 dev_dbg(priv
->adapter
->dev
,
1050 "tdls: enable link %pM success\n", peer
);
1052 sta_ptr
->tdls_status
= TDLS_SETUP_COMPLETE
;
1054 mcs
= sta_ptr
->tdls_cap
.ht_capb
.mcs
;
1055 if (mcs
.rx_mask
[0] != 0xff)
1056 sta_ptr
->is_11n_enabled
= true;
1057 if (sta_ptr
->is_11n_enabled
) {
1058 if (le16_to_cpu(sta_ptr
->tdls_cap
.ht_capb
.cap_info
) &
1059 IEEE80211_HT_CAP_MAX_AMSDU
)
1060 sta_ptr
->max_amsdu
=
1061 MWIFIEX_TX_DATA_BUF_SIZE_8K
;
1063 sta_ptr
->max_amsdu
=
1064 MWIFIEX_TX_DATA_BUF_SIZE_4K
;
1066 for (i
= 0; i
< MAX_NUM_TID
; i
++)
1067 sta_ptr
->ampdu_sta
[i
] =
1068 priv
->aggr_prio_tbl
[i
].ampdu_user
;
1070 for (i
= 0; i
< MAX_NUM_TID
; i
++)
1071 sta_ptr
->ampdu_sta
[i
] = BA_STREAM_NOT_ALLOWED
;
1074 memset(sta_ptr
->rx_seq
, 0xff, sizeof(sta_ptr
->rx_seq
));
1075 mwifiex_restore_tdls_packets(priv
, peer
, TDLS_SETUP_COMPLETE
);
1076 mwifiex_auto_tdls_update_peer_status(priv
, peer
,
1077 TDLS_SETUP_COMPLETE
);
1079 dev_dbg(priv
->adapter
->dev
,
1080 "tdls: enable link %pM failed\n", peer
);
1082 mwifiex_11n_cleanup_reorder_tbl(priv
);
1083 spin_lock_irqsave(&priv
->wmm
.ra_list_spinlock
,
1085 mwifiex_11n_delete_all_tx_ba_stream_tbl(priv
);
1086 spin_unlock_irqrestore(&priv
->wmm
.ra_list_spinlock
,
1088 mwifiex_del_sta_entry(priv
, peer
);
1090 mwifiex_restore_tdls_packets(priv
, peer
, TDLS_LINK_TEARDOWN
);
1091 mwifiex_auto_tdls_update_peer_status(priv
, peer
,
1100 int mwifiex_tdls_oper(struct mwifiex_private
*priv
, const u8
*peer
, u8 action
)
1103 case MWIFIEX_TDLS_ENABLE_LINK
:
1104 return mwifiex_tdls_process_enable_link(priv
, peer
);
1105 case MWIFIEX_TDLS_DISABLE_LINK
:
1106 return mwifiex_tdls_process_disable_link(priv
, peer
);
1107 case MWIFIEX_TDLS_CREATE_LINK
:
1108 return mwifiex_tdls_process_create_link(priv
, peer
);
1109 case MWIFIEX_TDLS_CONFIG_LINK
:
1110 return mwifiex_tdls_process_config_link(priv
, peer
);
1115 int mwifiex_get_tdls_link_status(struct mwifiex_private
*priv
, const u8
*mac
)
1117 struct mwifiex_sta_node
*sta_ptr
;
1119 sta_ptr
= mwifiex_get_sta_entry(priv
, mac
);
1121 return sta_ptr
->tdls_status
;
1123 return TDLS_NOT_SETUP
;
1126 void mwifiex_disable_all_tdls_links(struct mwifiex_private
*priv
)
1128 struct mwifiex_sta_node
*sta_ptr
;
1129 struct mwifiex_ds_tdls_oper tdls_oper
;
1130 unsigned long flags
;
1132 if (list_empty(&priv
->sta_list
))
1135 list_for_each_entry(sta_ptr
, &priv
->sta_list
, list
) {
1136 memset(&tdls_oper
, 0, sizeof(struct mwifiex_ds_tdls_oper
));
1138 if (sta_ptr
->is_11n_enabled
) {
1139 mwifiex_11n_cleanup_reorder_tbl(priv
);
1140 spin_lock_irqsave(&priv
->wmm
.ra_list_spinlock
,
1142 mwifiex_11n_delete_all_tx_ba_stream_tbl(priv
);
1143 spin_unlock_irqrestore(&priv
->wmm
.ra_list_spinlock
,
1147 mwifiex_restore_tdls_packets(priv
, sta_ptr
->mac_addr
,
1148 TDLS_LINK_TEARDOWN
);
1149 memcpy(&tdls_oper
.peer_mac
, sta_ptr
->mac_addr
, ETH_ALEN
);
1150 tdls_oper
.tdls_action
= MWIFIEX_TDLS_DISABLE_LINK
;
1151 if (mwifiex_send_cmd(priv
, HostCmd_CMD_TDLS_OPER
,
1152 HostCmd_ACT_GEN_SET
, 0, &tdls_oper
, false))
1153 dev_warn(priv
->adapter
->dev
,
1154 "Disable link failed for TDLS peer %pM",
1158 mwifiex_del_all_sta_list(priv
);
1161 int mwifiex_tdls_check_tx(struct mwifiex_private
*priv
, struct sk_buff
*skb
)
1163 struct mwifiex_auto_tdls_peer
*peer
;
1164 unsigned long flags
;
1167 ether_addr_copy(mac
, skb
->data
);
1169 spin_lock_irqsave(&priv
->auto_tdls_lock
, flags
);
1170 list_for_each_entry(peer
, &priv
->auto_tdls_list
, list
) {
1171 if (!memcmp(mac
, peer
->mac_addr
, ETH_ALEN
)) {
1172 if (peer
->rssi
<= MWIFIEX_TDLS_RSSI_HIGH
&&
1173 peer
->tdls_status
== TDLS_NOT_SETUP
&&
1174 (peer
->failure_count
<
1175 MWIFIEX_TDLS_MAX_FAIL_COUNT
)) {
1176 peer
->tdls_status
= TDLS_SETUP_INPROGRESS
;
1177 dev_dbg(priv
->adapter
->dev
,
1178 "setup TDLS link, peer=%pM rssi=%d\n",
1179 peer
->mac_addr
, peer
->rssi
);
1181 cfg80211_tdls_oper_request(priv
->netdev
,
1185 peer
->do_setup
= false;
1186 priv
->check_tdls_tx
= false;
1187 } else if (peer
->failure_count
<
1188 MWIFIEX_TDLS_MAX_FAIL_COUNT
&&
1189 peer
->do_discover
) {
1190 mwifiex_send_tdls_data_frame(priv
,
1192 WLAN_TDLS_DISCOVERY_REQUEST
,
1194 peer
->do_discover
= false;
1198 spin_unlock_irqrestore(&priv
->auto_tdls_lock
, flags
);
1203 void mwifiex_flush_auto_tdls_list(struct mwifiex_private
*priv
)
1205 struct mwifiex_auto_tdls_peer
*peer
, *tmp_node
;
1206 unsigned long flags
;
1208 spin_lock_irqsave(&priv
->auto_tdls_lock
, flags
);
1209 list_for_each_entry_safe(peer
, tmp_node
, &priv
->auto_tdls_list
, list
) {
1210 list_del(&peer
->list
);
1214 INIT_LIST_HEAD(&priv
->auto_tdls_list
);
1215 spin_unlock_irqrestore(&priv
->auto_tdls_lock
, flags
);
1216 priv
->check_tdls_tx
= false;
1219 void mwifiex_add_auto_tdls_peer(struct mwifiex_private
*priv
, const u8
*mac
)
1221 struct mwifiex_auto_tdls_peer
*tdls_peer
;
1222 unsigned long flags
;
1224 if (!priv
->adapter
->auto_tdls
)
1227 spin_lock_irqsave(&priv
->auto_tdls_lock
, flags
);
1228 list_for_each_entry(tdls_peer
, &priv
->auto_tdls_list
, list
) {
1229 if (!memcmp(tdls_peer
->mac_addr
, mac
, ETH_ALEN
)) {
1230 tdls_peer
->tdls_status
= TDLS_SETUP_INPROGRESS
;
1231 tdls_peer
->rssi_jiffies
= jiffies
;
1232 spin_unlock_irqrestore(&priv
->auto_tdls_lock
, flags
);
1237 /* create new TDLS peer */
1238 tdls_peer
= kzalloc(sizeof(*tdls_peer
), GFP_ATOMIC
);
1240 ether_addr_copy(tdls_peer
->mac_addr
, mac
);
1241 tdls_peer
->tdls_status
= TDLS_SETUP_INPROGRESS
;
1242 tdls_peer
->rssi_jiffies
= jiffies
;
1243 INIT_LIST_HEAD(&tdls_peer
->list
);
1244 list_add_tail(&tdls_peer
->list
, &priv
->auto_tdls_list
);
1245 dev_dbg(priv
->adapter
->dev
, "Add auto TDLS peer= %pM to list\n",
1249 spin_unlock_irqrestore(&priv
->auto_tdls_lock
, flags
);
1252 void mwifiex_auto_tdls_update_peer_status(struct mwifiex_private
*priv
,
1253 const u8
*mac
, u8 link_status
)
1255 struct mwifiex_auto_tdls_peer
*peer
;
1256 unsigned long flags
;
1258 if (!priv
->adapter
->auto_tdls
)
1261 spin_lock_irqsave(&priv
->auto_tdls_lock
, flags
);
1262 list_for_each_entry(peer
, &priv
->auto_tdls_list
, list
) {
1263 if (!memcmp(peer
->mac_addr
, mac
, ETH_ALEN
)) {
1264 if ((link_status
== TDLS_NOT_SETUP
) &&
1265 (peer
->tdls_status
== TDLS_SETUP_INPROGRESS
))
1266 peer
->failure_count
++;
1267 else if (link_status
== TDLS_SETUP_COMPLETE
)
1268 peer
->failure_count
= 0;
1270 peer
->tdls_status
= link_status
;
1274 spin_unlock_irqrestore(&priv
->auto_tdls_lock
, flags
);
1277 void mwifiex_auto_tdls_update_peer_signal(struct mwifiex_private
*priv
,
1278 u8
*mac
, s8 snr
, s8 nflr
)
1280 struct mwifiex_auto_tdls_peer
*peer
;
1281 unsigned long flags
;
1283 if (!priv
->adapter
->auto_tdls
)
1286 spin_lock_irqsave(&priv
->auto_tdls_lock
, flags
);
1287 list_for_each_entry(peer
, &priv
->auto_tdls_list
, list
) {
1288 if (!memcmp(peer
->mac_addr
, mac
, ETH_ALEN
)) {
1289 peer
->rssi
= nflr
- snr
;
1290 peer
->rssi_jiffies
= jiffies
;
1294 spin_unlock_irqrestore(&priv
->auto_tdls_lock
, flags
);
1297 void mwifiex_check_auto_tdls(unsigned long context
)
1299 struct mwifiex_private
*priv
= (struct mwifiex_private
*)context
;
1300 struct mwifiex_auto_tdls_peer
*tdls_peer
;
1301 unsigned long flags
;
1302 u16 reason
= WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED
;
1304 if (WARN_ON_ONCE(!priv
|| !priv
->adapter
)) {
1305 pr_err("mwifiex: %s: adapter or private structure is NULL\n",
1310 if (unlikely(!priv
->adapter
->auto_tdls
))
1313 if (!priv
->auto_tdls_timer_active
) {
1314 dev_dbg(priv
->adapter
->dev
,
1315 "auto TDLS timer inactive; return");
1319 priv
->check_tdls_tx
= false;
1321 if (list_empty(&priv
->auto_tdls_list
)) {
1322 mod_timer(&priv
->auto_tdls_timer
,
1324 msecs_to_jiffies(MWIFIEX_TIMER_10S
));
1328 spin_lock_irqsave(&priv
->auto_tdls_lock
, flags
);
1329 list_for_each_entry(tdls_peer
, &priv
->auto_tdls_list
, list
) {
1330 if ((jiffies
- tdls_peer
->rssi_jiffies
) >
1331 (MWIFIEX_AUTO_TDLS_IDLE_TIME
* HZ
)) {
1332 tdls_peer
->rssi
= 0;
1333 tdls_peer
->do_discover
= true;
1334 priv
->check_tdls_tx
= true;
1337 if (((tdls_peer
->rssi
>= MWIFIEX_TDLS_RSSI_LOW
) ||
1338 !tdls_peer
->rssi
) &&
1339 tdls_peer
->tdls_status
== TDLS_SETUP_COMPLETE
) {
1340 tdls_peer
->tdls_status
= TDLS_LINK_TEARDOWN
;
1341 dev_dbg(priv
->adapter
->dev
,
1342 "teardown TDLS link,peer=%pM rssi=%d\n",
1343 tdls_peer
->mac_addr
, -tdls_peer
->rssi
);
1344 tdls_peer
->do_discover
= true;
1345 priv
->check_tdls_tx
= true;
1346 cfg80211_tdls_oper_request(priv
->netdev
,
1347 tdls_peer
->mac_addr
,
1348 NL80211_TDLS_TEARDOWN
,
1349 reason
, GFP_ATOMIC
);
1350 } else if (tdls_peer
->rssi
&&
1351 tdls_peer
->rssi
<= MWIFIEX_TDLS_RSSI_HIGH
&&
1352 tdls_peer
->tdls_status
== TDLS_NOT_SETUP
&&
1353 tdls_peer
->failure_count
<
1354 MWIFIEX_TDLS_MAX_FAIL_COUNT
) {
1355 priv
->check_tdls_tx
= true;
1356 tdls_peer
->do_setup
= true;
1357 dev_dbg(priv
->adapter
->dev
,
1358 "check TDLS with peer=%pM rssi=%d\n",
1359 tdls_peer
->mac_addr
, -tdls_peer
->rssi
);
1362 spin_unlock_irqrestore(&priv
->auto_tdls_lock
, flags
);
1364 mod_timer(&priv
->auto_tdls_timer
,
1365 jiffies
+ msecs_to_jiffies(MWIFIEX_TIMER_10S
));
1368 void mwifiex_setup_auto_tdls_timer(struct mwifiex_private
*priv
)
1370 init_timer(&priv
->auto_tdls_timer
);
1371 priv
->auto_tdls_timer
.function
= mwifiex_check_auto_tdls
;
1372 priv
->auto_tdls_timer
.data
= (unsigned long)priv
;
1373 priv
->auto_tdls_timer_active
= true;
1374 mod_timer(&priv
->auto_tdls_timer
,
1375 jiffies
+ msecs_to_jiffies(MWIFIEX_TIMER_10S
));
1378 void mwifiex_clean_auto_tdls(struct mwifiex_private
*priv
)
1380 if (ISSUPP_TDLS_ENABLED(priv
->adapter
->fw_cap_info
) &&
1381 priv
->adapter
->auto_tdls
&&
1382 priv
->bss_type
== MWIFIEX_BSS_TYPE_STA
) {
1383 priv
->auto_tdls_timer_active
= false;
1384 del_timer(&priv
->auto_tdls_timer
);
1385 mwifiex_flush_auto_tdls_list(priv
);