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 mwifiex_dbg(priv->adapter, DATA, "%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 (mwifiex_is_tdls_link_setup(status)) {
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 mwifiex_dbg(priv->adapter, DATA, "%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 mwifiex_dbg(priv->adapter, ERROR,
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 memcpy(pos, &assoc_rsp->a_id, sizeof(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 mwifiex_dbg(priv->adapter, ERROR,
203 "TDLS peer station not found in list\n");
207 if (!(le16_to_cpu(sta_ptr->tdls_cap.ht_capb.cap_info))) {
208 mwifiex_dbg(priv->adapter, WARN,
209 "TDLS peer doesn't support ht capabilities\n");
213 pos = (void *)skb_put(skb, sizeof(struct ieee80211_ht_operation) + 2);
214 *pos++ = WLAN_EID_HT_OPERATION;
215 *pos++ = sizeof(struct ieee80211_ht_operation);
216 ht_oper = (void *)pos;
218 ht_oper->primary_chan = bss_desc->channel;
220 /* follow AP's channel bandwidth */
221 if (ISSUPP_CHANWIDTH40(priv->adapter->hw_dot_11n_dev_cap) &&
222 bss_desc->bcn_ht_cap &&
223 ISALLOWED_CHANWIDTH40(bss_desc->bcn_ht_oper->ht_param))
224 ht_oper->ht_param = bss_desc->bcn_ht_oper->ht_param;
228 mwifiex_get_sec_chan_offset(bss_desc->channel);
229 ht_oper->ht_param |= BIT(2);
232 memcpy(&sta_ptr->tdls_cap.ht_oper, ht_oper,
233 sizeof(struct ieee80211_ht_operation));
238 static int mwifiex_tdls_add_vht_oper(struct mwifiex_private *priv,
239 const u8 *mac, struct sk_buff *skb)
241 struct mwifiex_bssdescriptor *bss_desc;
242 struct ieee80211_vht_operation *vht_oper;
243 struct ieee80211_vht_cap *vht_cap, *ap_vht_cap = NULL;
244 struct mwifiex_sta_node *sta_ptr;
245 struct mwifiex_adapter *adapter = priv->adapter;
246 u8 supp_chwd_set, peer_supp_chwd_set;
247 u8 *pos, ap_supp_chwd_set, chan_bw;
248 u16 mcs_map_user, mcs_map_resp, mcs_map_result;
249 u16 mcs_user, mcs_resp, nss;
250 u32 usr_vht_cap_info;
252 bss_desc = &priv->curr_bss_params.bss_descriptor;
254 sta_ptr = mwifiex_get_sta_entry(priv, mac);
255 if (unlikely(!sta_ptr)) {
256 mwifiex_dbg(adapter, ERROR,
257 "TDLS peer station not found in list\n");
261 if (!(le32_to_cpu(sta_ptr->tdls_cap.vhtcap.vht_cap_info))) {
262 mwifiex_dbg(adapter, WARN,
263 "TDLS peer doesn't support vht capabilities\n");
267 if (!mwifiex_is_bss_in_11ac_mode(priv)) {
268 if (sta_ptr->tdls_cap.extcap.ext_capab[7] &
269 WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED) {
270 mwifiex_dbg(adapter, WARN,
271 "TDLS peer doesn't support wider bandwidth\n");
275 ap_vht_cap = bss_desc->bcn_vht_cap;
278 pos = (void *)skb_put(skb, sizeof(struct ieee80211_vht_operation) + 2);
279 *pos++ = WLAN_EID_VHT_OPERATION;
280 *pos++ = sizeof(struct ieee80211_vht_operation);
281 vht_oper = (struct ieee80211_vht_operation *)pos;
283 if (bss_desc->bss_band & BAND_A)
284 usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_a;
286 usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_bg;
288 /* find the minmum bandwith between AP/TDLS peers */
289 vht_cap = &sta_ptr->tdls_cap.vhtcap;
290 supp_chwd_set = GET_VHTCAP_CHWDSET(usr_vht_cap_info);
292 GET_VHTCAP_CHWDSET(le32_to_cpu(vht_cap->vht_cap_info));
293 supp_chwd_set = min_t(u8, supp_chwd_set, peer_supp_chwd_set);
295 /* We need check AP's bandwidth when TDLS_WIDER_BANDWIDTH is off */
297 if (ap_vht_cap && sta_ptr->tdls_cap.extcap.ext_capab[7] &
298 WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED) {
300 GET_VHTCAP_CHWDSET(le32_to_cpu(ap_vht_cap->vht_cap_info));
301 supp_chwd_set = min_t(u8, supp_chwd_set, ap_supp_chwd_set);
304 switch (supp_chwd_set) {
305 case IEEE80211_VHT_CHANWIDTH_80MHZ:
306 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
308 case IEEE80211_VHT_CHANWIDTH_160MHZ:
309 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_160MHZ;
311 case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
312 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80P80MHZ;
315 vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_USE_HT;
319 mcs_map_user = GET_DEVRXMCSMAP(adapter->usr_dot_11ac_mcs_support);
320 mcs_map_resp = le16_to_cpu(vht_cap->supp_mcs.rx_mcs_map);
323 for (nss = 1; nss <= 8; nss++) {
324 mcs_user = GET_VHTNSSMCS(mcs_map_user, nss);
325 mcs_resp = GET_VHTNSSMCS(mcs_map_resp, nss);
327 if ((mcs_user == IEEE80211_VHT_MCS_NOT_SUPPORTED) ||
328 (mcs_resp == IEEE80211_VHT_MCS_NOT_SUPPORTED))
329 SET_VHTNSSMCS(mcs_map_result, nss,
330 IEEE80211_VHT_MCS_NOT_SUPPORTED);
332 SET_VHTNSSMCS(mcs_map_result, nss,
333 min_t(u16, mcs_user, mcs_resp));
336 vht_oper->basic_mcs_set = cpu_to_le16(mcs_map_result);
338 switch (vht_oper->chan_width) {
339 case IEEE80211_VHT_CHANWIDTH_80MHZ:
340 chan_bw = IEEE80211_VHT_CHANWIDTH_80MHZ;
342 case IEEE80211_VHT_CHANWIDTH_160MHZ:
343 chan_bw = IEEE80211_VHT_CHANWIDTH_160MHZ;
345 case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
346 chan_bw = IEEE80211_VHT_CHANWIDTH_80MHZ;
349 chan_bw = IEEE80211_VHT_CHANWIDTH_USE_HT;
352 vht_oper->center_freq_seg1_idx =
353 mwifiex_get_center_freq_index(priv, BAND_AAC,
360 static void mwifiex_tdls_add_ext_capab(struct mwifiex_private *priv,
363 struct ieee_types_extcap *extcap;
365 extcap = (void *)skb_put(skb, sizeof(struct ieee_types_extcap));
366 extcap->ieee_hdr.element_id = WLAN_EID_EXT_CAPABILITY;
367 extcap->ieee_hdr.len = 8;
368 memset(extcap->ext_capab, 0, 8);
369 extcap->ext_capab[4] |= WLAN_EXT_CAPA5_TDLS_ENABLED;
370 extcap->ext_capab[3] |= WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH;
372 if (priv->adapter->is_hw_11ac_capable)
373 extcap->ext_capab[7] |= WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED;
376 static void mwifiex_tdls_add_qos_capab(struct sk_buff *skb)
378 u8 *pos = (void *)skb_put(skb, 3);
380 *pos++ = WLAN_EID_QOS_CAPA;
382 *pos++ = MWIFIEX_TDLS_DEF_QOS_CAPAB;
386 mwifiex_tdls_add_wmm_param_ie(struct mwifiex_private *priv, struct sk_buff *skb)
388 struct ieee80211_wmm_param_ie *wmm;
389 u8 ac_vi[] = {0x42, 0x43, 0x5e, 0x00};
390 u8 ac_vo[] = {0x62, 0x32, 0x2f, 0x00};
391 u8 ac_be[] = {0x03, 0xa4, 0x00, 0x00};
392 u8 ac_bk[] = {0x27, 0xa4, 0x00, 0x00};
394 wmm = (void *)skb_put(skb, sizeof(*wmm));
395 memset(wmm, 0, sizeof(*wmm));
397 wmm->element_id = WLAN_EID_VENDOR_SPECIFIC;
398 wmm->len = sizeof(*wmm) - 2;
399 wmm->oui[0] = 0x00; /* Microsoft OUI 00:50:F2 */
402 wmm->oui_type = 2; /* WME */
403 wmm->oui_subtype = 1; /* WME param */
404 wmm->version = 1; /* WME ver */
405 wmm->qos_info = 0; /* U-APSD not in use */
407 /* use default WMM AC parameters for TDLS link*/
408 memcpy(&wmm->ac[0], ac_be, sizeof(ac_be));
409 memcpy(&wmm->ac[1], ac_bk, sizeof(ac_bk));
410 memcpy(&wmm->ac[2], ac_vi, sizeof(ac_vi));
411 memcpy(&wmm->ac[3], ac_vo, sizeof(ac_vo));
415 mwifiex_add_wmm_info_ie(struct mwifiex_private *priv, struct sk_buff *skb,
420 buf = (void *)skb_put(skb, MWIFIEX_TDLS_WMM_INFO_SIZE +
421 sizeof(struct ieee_types_header));
423 *buf++ = WLAN_EID_VENDOR_SPECIFIC;
424 *buf++ = 7; /* len */
425 *buf++ = 0x00; /* Microsoft OUI 00:50:F2 */
428 *buf++ = 2; /* WME */
429 *buf++ = 0; /* WME info */
430 *buf++ = 1; /* WME ver */
431 *buf++ = qosinfo; /* U-APSD no in use */
434 static int mwifiex_prep_tdls_encap_data(struct mwifiex_private *priv,
435 const u8 *peer, u8 action_code,
437 u16 status_code, struct sk_buff *skb)
439 struct ieee80211_tdls_data *tf;
442 struct ieee80211_ht_cap *ht_cap;
445 capab = priv->curr_bss_params.bss_descriptor.cap_info_bitmap;
447 tf = (void *)skb_put(skb, offsetof(struct ieee80211_tdls_data, u));
448 memcpy(tf->da, peer, ETH_ALEN);
449 memcpy(tf->sa, priv->curr_addr, ETH_ALEN);
450 tf->ether_type = cpu_to_be16(ETH_P_TDLS);
451 tf->payload_type = WLAN_TDLS_SNAP_RFTYPE;
453 switch (action_code) {
454 case WLAN_TDLS_SETUP_REQUEST:
455 tf->category = WLAN_CATEGORY_TDLS;
456 tf->action_code = WLAN_TDLS_SETUP_REQUEST;
457 skb_put(skb, sizeof(tf->u.setup_req));
458 tf->u.setup_req.dialog_token = dialog_token;
459 tf->u.setup_req.capability = cpu_to_le16(capab);
460 ret = mwifiex_tdls_append_rates_ie(priv, skb);
462 dev_kfree_skb_any(skb);
466 pos = (void *)skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
467 *pos++ = WLAN_EID_HT_CAPABILITY;
468 *pos++ = sizeof(struct ieee80211_ht_cap);
469 ht_cap = (void *)pos;
470 radio = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
471 ret = mwifiex_fill_cap_info(priv, radio, ht_cap);
473 dev_kfree_skb_any(skb);
477 if (priv->adapter->is_hw_11ac_capable) {
478 ret = mwifiex_tdls_add_vht_capab(priv, skb);
480 dev_kfree_skb_any(skb);
483 mwifiex_tdls_add_aid(priv, skb);
486 mwifiex_tdls_add_ext_capab(priv, skb);
487 mwifiex_tdls_add_qos_capab(skb);
488 mwifiex_add_wmm_info_ie(priv, skb, 0);
491 case WLAN_TDLS_SETUP_RESPONSE:
492 tf->category = WLAN_CATEGORY_TDLS;
493 tf->action_code = WLAN_TDLS_SETUP_RESPONSE;
494 skb_put(skb, sizeof(tf->u.setup_resp));
495 tf->u.setup_resp.status_code = cpu_to_le16(status_code);
496 tf->u.setup_resp.dialog_token = dialog_token;
497 tf->u.setup_resp.capability = cpu_to_le16(capab);
498 ret = mwifiex_tdls_append_rates_ie(priv, skb);
500 dev_kfree_skb_any(skb);
504 pos = (void *)skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
505 *pos++ = WLAN_EID_HT_CAPABILITY;
506 *pos++ = sizeof(struct ieee80211_ht_cap);
507 ht_cap = (void *)pos;
508 radio = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
509 ret = mwifiex_fill_cap_info(priv, radio, ht_cap);
511 dev_kfree_skb_any(skb);
515 if (priv->adapter->is_hw_11ac_capable) {
516 ret = mwifiex_tdls_add_vht_capab(priv, skb);
518 dev_kfree_skb_any(skb);
521 mwifiex_tdls_add_aid(priv, skb);
524 mwifiex_tdls_add_ext_capab(priv, skb);
525 mwifiex_tdls_add_qos_capab(skb);
526 mwifiex_add_wmm_info_ie(priv, skb, 0);
529 case WLAN_TDLS_SETUP_CONFIRM:
530 tf->category = WLAN_CATEGORY_TDLS;
531 tf->action_code = WLAN_TDLS_SETUP_CONFIRM;
532 skb_put(skb, sizeof(tf->u.setup_cfm));
533 tf->u.setup_cfm.status_code = cpu_to_le16(status_code);
534 tf->u.setup_cfm.dialog_token = dialog_token;
536 mwifiex_tdls_add_wmm_param_ie(priv, skb);
537 if (priv->adapter->is_hw_11ac_capable) {
538 ret = mwifiex_tdls_add_vht_oper(priv, peer, skb);
540 dev_kfree_skb_any(skb);
543 ret = mwifiex_tdls_add_ht_oper(priv, peer, 1, skb);
545 dev_kfree_skb_any(skb);
549 ret = mwifiex_tdls_add_ht_oper(priv, peer, 0, skb);
551 dev_kfree_skb_any(skb);
557 case WLAN_TDLS_TEARDOWN:
558 tf->category = WLAN_CATEGORY_TDLS;
559 tf->action_code = WLAN_TDLS_TEARDOWN;
560 skb_put(skb, sizeof(tf->u.teardown));
561 tf->u.teardown.reason_code = cpu_to_le16(status_code);
564 case WLAN_TDLS_DISCOVERY_REQUEST:
565 tf->category = WLAN_CATEGORY_TDLS;
566 tf->action_code = WLAN_TDLS_DISCOVERY_REQUEST;
567 skb_put(skb, sizeof(tf->u.discover_req));
568 tf->u.discover_req.dialog_token = dialog_token;
571 mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS frame type.\n");
579 mwifiex_tdls_add_link_ie(struct sk_buff *skb, const u8 *src_addr,
580 const u8 *peer, const u8 *bssid)
582 struct ieee80211_tdls_lnkie *lnkid;
584 lnkid = (void *)skb_put(skb, sizeof(struct ieee80211_tdls_lnkie));
585 lnkid->ie_type = WLAN_EID_LINK_ID;
586 lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) -
587 sizeof(struct ieee_types_header);
589 memcpy(lnkid->bssid, bssid, ETH_ALEN);
590 memcpy(lnkid->init_sta, src_addr, ETH_ALEN);
591 memcpy(lnkid->resp_sta, peer, ETH_ALEN);
594 int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, const u8 *peer,
595 u8 action_code, u8 dialog_token,
596 u16 status_code, const u8 *extra_ies,
597 size_t extra_ies_len)
600 struct mwifiex_txinfo *tx_info;
604 skb_len = MWIFIEX_MIN_DATA_HEADER_LEN +
605 max(sizeof(struct ieee80211_mgmt),
606 sizeof(struct ieee80211_tdls_data)) +
607 MWIFIEX_MGMT_FRAME_HEADER_SIZE +
608 MWIFIEX_SUPPORTED_RATES +
610 sizeof(struct ieee_types_extcap) +
611 sizeof(struct ieee80211_ht_cap) +
612 sizeof(struct ieee_types_bss_co_2040) +
613 sizeof(struct ieee80211_ht_operation) +
614 sizeof(struct ieee80211_tdls_lnkie) +
615 sizeof(struct ieee80211_wmm_param_ie) +
618 if (priv->adapter->is_hw_11ac_capable)
619 skb_len += sizeof(struct ieee_types_vht_cap) +
620 sizeof(struct ieee_types_vht_oper) +
621 sizeof(struct ieee_types_aid);
623 skb = dev_alloc_skb(skb_len);
625 mwifiex_dbg(priv->adapter, ERROR,
626 "allocate skb failed for management frame\n");
629 skb_reserve(skb, MWIFIEX_MIN_DATA_HEADER_LEN);
631 switch (action_code) {
632 case WLAN_TDLS_SETUP_REQUEST:
633 case WLAN_TDLS_SETUP_CONFIRM:
634 case WLAN_TDLS_TEARDOWN:
635 case WLAN_TDLS_DISCOVERY_REQUEST:
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, priv->curr_addr, peer,
649 case WLAN_TDLS_SETUP_RESPONSE:
650 ret = mwifiex_prep_tdls_encap_data(priv, peer, action_code,
651 dialog_token, status_code,
654 dev_kfree_skb_any(skb);
658 memcpy(skb_put(skb, extra_ies_len), extra_ies,
660 mwifiex_tdls_add_link_ie(skb, peer, priv->curr_addr,
665 switch (action_code) {
666 case WLAN_TDLS_SETUP_REQUEST:
667 case WLAN_TDLS_SETUP_RESPONSE:
668 skb->priority = MWIFIEX_PRIO_BK;
671 skb->priority = MWIFIEX_PRIO_VI;
675 tx_info = MWIFIEX_SKB_TXCB(skb);
676 memset(tx_info, 0, sizeof(*tx_info));
677 tx_info->bss_num = priv->bss_num;
678 tx_info->bss_type = priv->bss_type;
680 __net_timestamp(skb);
681 mwifiex_queue_tx_pkt(priv, skb);
687 mwifiex_construct_tdls_action_frame(struct mwifiex_private *priv,
689 u8 action_code, u8 dialog_token,
690 u16 status_code, struct sk_buff *skb)
692 struct ieee80211_mgmt *mgmt;
693 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
696 struct ieee80211_ht_cap *ht_cap;
699 capab = priv->curr_bss_params.bss_descriptor.cap_info_bitmap;
701 mgmt = (void *)skb_put(skb, offsetof(struct ieee80211_mgmt, u));
704 memcpy(mgmt->da, peer, ETH_ALEN);
705 memcpy(mgmt->sa, priv->curr_addr, ETH_ALEN);
706 memcpy(mgmt->bssid, priv->cfg_bssid, ETH_ALEN);
707 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
708 IEEE80211_STYPE_ACTION);
711 pos = skb_put(skb, ETH_ALEN);
713 switch (action_code) {
714 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
715 skb_put(skb, sizeof(mgmt->u.action.u.tdls_discover_resp) + 1);
716 mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
717 mgmt->u.action.u.tdls_discover_resp.action_code =
718 WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
719 mgmt->u.action.u.tdls_discover_resp.dialog_token =
721 mgmt->u.action.u.tdls_discover_resp.capability =
723 /* move back for addr4 */
724 memmove(pos + ETH_ALEN, &mgmt->u.action.category,
725 sizeof(mgmt->u.action.u.tdls_discover_resp));
727 memcpy(pos, bc_addr, ETH_ALEN);
729 ret = mwifiex_tdls_append_rates_ie(priv, skb);
731 dev_kfree_skb_any(skb);
735 pos = (void *)skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
736 *pos++ = WLAN_EID_HT_CAPABILITY;
737 *pos++ = sizeof(struct ieee80211_ht_cap);
738 ht_cap = (void *)pos;
739 radio = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
740 ret = mwifiex_fill_cap_info(priv, radio, ht_cap);
742 dev_kfree_skb_any(skb);
746 if (priv->adapter->is_hw_11ac_capable) {
747 ret = mwifiex_tdls_add_vht_capab(priv, skb);
749 dev_kfree_skb_any(skb);
752 mwifiex_tdls_add_aid(priv, skb);
755 mwifiex_tdls_add_ext_capab(priv, skb);
756 mwifiex_tdls_add_qos_capab(skb);
759 mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS action frame type\n");
766 int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, const u8 *peer,
767 u8 action_code, u8 dialog_token,
768 u16 status_code, const u8 *extra_ies,
769 size_t extra_ies_len)
772 struct mwifiex_txinfo *tx_info;
774 u32 pkt_type, tx_control;
775 u16 pkt_len, skb_len;
777 skb_len = MWIFIEX_MIN_DATA_HEADER_LEN +
778 max(sizeof(struct ieee80211_mgmt),
779 sizeof(struct ieee80211_tdls_data)) +
780 MWIFIEX_MGMT_FRAME_HEADER_SIZE +
781 MWIFIEX_SUPPORTED_RATES +
782 sizeof(struct ieee_types_extcap) +
783 sizeof(struct ieee80211_ht_cap) +
784 sizeof(struct ieee_types_bss_co_2040) +
785 sizeof(struct ieee80211_ht_operation) +
786 sizeof(struct ieee80211_tdls_lnkie) +
789 ETH_ALEN; /* Address4 */
791 if (priv->adapter->is_hw_11ac_capable)
792 skb_len += sizeof(struct ieee_types_vht_cap) +
793 sizeof(struct ieee_types_vht_oper) +
794 sizeof(struct ieee_types_aid);
796 skb = dev_alloc_skb(skb_len);
798 mwifiex_dbg(priv->adapter, ERROR,
799 "allocate skb failed for management frame\n");
803 skb_reserve(skb, MWIFIEX_MIN_DATA_HEADER_LEN);
805 pkt_type = PKT_TYPE_MGMT;
807 pos = skb_put(skb, MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(pkt_len));
808 memset(pos, 0, MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(pkt_len));
809 memcpy(pos, &pkt_type, sizeof(pkt_type));
810 memcpy(pos + sizeof(pkt_type), &tx_control, sizeof(tx_control));
812 if (mwifiex_construct_tdls_action_frame(priv, peer, action_code,
813 dialog_token, status_code,
815 dev_kfree_skb_any(skb);
820 memcpy(skb_put(skb, extra_ies_len), extra_ies, extra_ies_len);
822 /* the TDLS link IE is always added last we are the responder */
824 mwifiex_tdls_add_link_ie(skb, peer, priv->curr_addr,
827 skb->priority = MWIFIEX_PRIO_VI;
829 tx_info = MWIFIEX_SKB_TXCB(skb);
830 memset(tx_info, 0, sizeof(*tx_info));
831 tx_info->bss_num = priv->bss_num;
832 tx_info->bss_type = priv->bss_type;
833 tx_info->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT;
835 pkt_len = skb->len - MWIFIEX_MGMT_FRAME_HEADER_SIZE - sizeof(pkt_len);
836 memcpy(skb->data + MWIFIEX_MGMT_FRAME_HEADER_SIZE, &pkt_len,
838 __net_timestamp(skb);
839 mwifiex_queue_tx_pkt(priv, skb);
844 /* This function process tdls action frame from peer.
845 * Peer capabilities are stored into station node structure.
847 void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
850 struct mwifiex_sta_node *sta_ptr;
851 u8 *peer, *pos, *end;
856 if (len < (sizeof(struct ethhdr) + 3))
858 if (*(buf + sizeof(struct ethhdr)) != WLAN_TDLS_SNAP_RFTYPE)
860 if (*(buf + sizeof(struct ethhdr) + 1) != WLAN_CATEGORY_TDLS)
863 peer = buf + ETH_ALEN;
864 action = *(buf + sizeof(struct ethhdr) + 2);
865 mwifiex_dbg(priv->adapter, DATA,
866 "rx:tdls action: peer=%pM, action=%d\n", peer, action);
869 case WLAN_TDLS_SETUP_REQUEST:
870 if (len < (sizeof(struct ethhdr) + TDLS_REQ_FIX_LEN))
873 pos = buf + sizeof(struct ethhdr) + 4;
874 /* payload 1+ category 1 + action 1 + dialog 1 */
875 cap = cpu_to_le16(*(u16 *)pos);
876 ie_len = len - sizeof(struct ethhdr) - TDLS_REQ_FIX_LEN;
880 case WLAN_TDLS_SETUP_RESPONSE:
881 if (len < (sizeof(struct ethhdr) + TDLS_RESP_FIX_LEN))
883 /* payload 1+ category 1 + action 1 + dialog 1 + status code 2*/
884 pos = buf + sizeof(struct ethhdr) + 6;
885 cap = cpu_to_le16(*(u16 *)pos);
886 ie_len = len - sizeof(struct ethhdr) - TDLS_RESP_FIX_LEN;
890 case WLAN_TDLS_SETUP_CONFIRM:
891 if (len < (sizeof(struct ethhdr) + TDLS_CONFIRM_FIX_LEN))
893 pos = buf + sizeof(struct ethhdr) + TDLS_CONFIRM_FIX_LEN;
894 ie_len = len - sizeof(struct ethhdr) - TDLS_CONFIRM_FIX_LEN;
897 mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS frame type.\n");
901 sta_ptr = mwifiex_add_sta_entry(priv, peer);
905 sta_ptr->tdls_cap.capab = cap;
907 for (end = pos + ie_len; pos + 1 < end; pos += 2 + pos[1]) {
908 if (pos + 2 + pos[1] > end)
912 case WLAN_EID_SUPP_RATES:
915 sta_ptr->tdls_cap.rates_len = pos[1];
916 for (i = 0; i < pos[1]; i++)
917 sta_ptr->tdls_cap.rates[i] = pos[i + 2];
920 case WLAN_EID_EXT_SUPP_RATES:
923 basic = sta_ptr->tdls_cap.rates_len;
924 if (pos[1] > 32 - basic)
926 for (i = 0; i < pos[1]; i++)
927 sta_ptr->tdls_cap.rates[basic + i] = pos[i + 2];
928 sta_ptr->tdls_cap.rates_len += pos[1];
930 case WLAN_EID_HT_CAPABILITY:
931 if (pos > end - sizeof(struct ieee80211_ht_cap) - 2)
933 if (pos[1] != sizeof(struct ieee80211_ht_cap))
935 /* copy the ie's value into ht_capb*/
936 memcpy((u8 *)&sta_ptr->tdls_cap.ht_capb, pos + 2,
937 sizeof(struct ieee80211_ht_cap));
938 sta_ptr->is_11n_enabled = 1;
940 case WLAN_EID_HT_OPERATION:
942 sizeof(struct ieee80211_ht_operation) - 2)
944 if (pos[1] != sizeof(struct ieee80211_ht_operation))
946 /* copy the ie's value into ht_oper*/
947 memcpy(&sta_ptr->tdls_cap.ht_oper, pos + 2,
948 sizeof(struct ieee80211_ht_operation));
950 case WLAN_EID_BSS_COEX_2040:
955 sta_ptr->tdls_cap.coex_2040 = pos[2];
957 case WLAN_EID_EXT_CAPABILITY:
958 if (pos > end - sizeof(struct ieee_types_header))
960 if (pos[1] < sizeof(struct ieee_types_header))
964 memcpy((u8 *)&sta_ptr->tdls_cap.extcap, pos,
965 sizeof(struct ieee_types_header) +
966 min_t(u8, pos[1], 8));
969 if (pos > end - sizeof(struct ieee_types_header))
971 if (pos[1] < sizeof(struct ieee_types_header))
973 if (pos[1] > IEEE_MAX_IE_SIZE -
974 sizeof(struct ieee_types_header))
976 memcpy((u8 *)&sta_ptr->tdls_cap.rsn_ie, pos,
977 sizeof(struct ieee_types_header) +
978 min_t(u8, pos[1], IEEE_MAX_IE_SIZE -
979 sizeof(struct ieee_types_header)));
981 case WLAN_EID_QOS_CAPA:
986 sta_ptr->tdls_cap.qos_info = pos[2];
988 case WLAN_EID_VHT_OPERATION:
989 if (priv->adapter->is_hw_11ac_capable) {
991 sizeof(struct ieee80211_vht_operation) - 2)
994 sizeof(struct ieee80211_vht_operation))
996 /* copy the ie's value into vhtoper*/
997 memcpy(&sta_ptr->tdls_cap.vhtoper, pos + 2,
998 sizeof(struct ieee80211_vht_operation));
1001 case WLAN_EID_VHT_CAPABILITY:
1002 if (priv->adapter->is_hw_11ac_capable) {
1004 sizeof(struct ieee80211_vht_cap) - 2)
1006 if (pos[1] != sizeof(struct ieee80211_vht_cap))
1008 /* copy the ie's value into vhtcap*/
1009 memcpy((u8 *)&sta_ptr->tdls_cap.vhtcap, pos + 2,
1010 sizeof(struct ieee80211_vht_cap));
1011 sta_ptr->is_11ac_enabled = 1;
1015 if (priv->adapter->is_hw_11ac_capable) {
1020 sta_ptr->tdls_cap.aid =
1021 le16_to_cpu(*(__le16 *)(pos + 2));
1033 mwifiex_tdls_process_config_link(struct mwifiex_private *priv, const u8 *peer)
1035 struct mwifiex_sta_node *sta_ptr;
1036 struct mwifiex_ds_tdls_oper tdls_oper;
1038 memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper));
1039 sta_ptr = mwifiex_get_sta_entry(priv, peer);
1041 if (!sta_ptr || sta_ptr->tdls_status == TDLS_SETUP_FAILURE) {
1042 mwifiex_dbg(priv->adapter, ERROR,
1043 "link absent for peer %pM; cannot config\n", peer);
1047 memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN);
1048 tdls_oper.tdls_action = MWIFIEX_TDLS_CONFIG_LINK;
1049 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER,
1050 HostCmd_ACT_GEN_SET, 0, &tdls_oper, true);
1054 mwifiex_tdls_process_create_link(struct mwifiex_private *priv, const u8 *peer)
1056 struct mwifiex_sta_node *sta_ptr;
1057 struct mwifiex_ds_tdls_oper tdls_oper;
1059 memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper));
1060 sta_ptr = mwifiex_get_sta_entry(priv, peer);
1062 if (sta_ptr && sta_ptr->tdls_status == TDLS_SETUP_INPROGRESS) {
1063 mwifiex_dbg(priv->adapter, WARN,
1064 "Setup already in progress for peer %pM\n", peer);
1068 sta_ptr = mwifiex_add_sta_entry(priv, peer);
1072 sta_ptr->tdls_status = TDLS_SETUP_INPROGRESS;
1073 mwifiex_hold_tdls_packets(priv, peer);
1074 memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN);
1075 tdls_oper.tdls_action = MWIFIEX_TDLS_CREATE_LINK;
1076 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER,
1077 HostCmd_ACT_GEN_SET, 0, &tdls_oper, true);
1081 mwifiex_tdls_process_disable_link(struct mwifiex_private *priv, const u8 *peer)
1083 struct mwifiex_sta_node *sta_ptr;
1084 struct mwifiex_ds_tdls_oper tdls_oper;
1085 unsigned long flags;
1087 memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper));
1088 sta_ptr = mwifiex_get_sta_entry(priv, peer);
1091 if (sta_ptr->is_11n_enabled) {
1092 mwifiex_11n_cleanup_reorder_tbl(priv);
1093 spin_lock_irqsave(&priv->wmm.ra_list_spinlock,
1095 mwifiex_11n_delete_all_tx_ba_stream_tbl(priv);
1096 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1099 mwifiex_del_sta_entry(priv, peer);
1102 mwifiex_restore_tdls_packets(priv, peer, TDLS_LINK_TEARDOWN);
1103 mwifiex_auto_tdls_update_peer_status(priv, peer, TDLS_NOT_SETUP);
1104 memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN);
1105 tdls_oper.tdls_action = MWIFIEX_TDLS_DISABLE_LINK;
1106 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER,
1107 HostCmd_ACT_GEN_SET, 0, &tdls_oper, true);
1111 mwifiex_tdls_process_enable_link(struct mwifiex_private *priv, const u8 *peer)
1113 struct mwifiex_sta_node *sta_ptr;
1114 struct ieee80211_mcs_info mcs;
1115 unsigned long flags;
1118 sta_ptr = mwifiex_get_sta_entry(priv, peer);
1120 if (sta_ptr && (sta_ptr->tdls_status != TDLS_SETUP_FAILURE)) {
1121 mwifiex_dbg(priv->adapter, MSG,
1122 "tdls: enable link %pM success\n", peer);
1124 sta_ptr->tdls_status = TDLS_SETUP_COMPLETE;
1126 mcs = sta_ptr->tdls_cap.ht_capb.mcs;
1127 if (mcs.rx_mask[0] != 0xff)
1128 sta_ptr->is_11n_enabled = true;
1129 if (sta_ptr->is_11n_enabled) {
1130 if (le16_to_cpu(sta_ptr->tdls_cap.ht_capb.cap_info) &
1131 IEEE80211_HT_CAP_MAX_AMSDU)
1132 sta_ptr->max_amsdu =
1133 MWIFIEX_TX_DATA_BUF_SIZE_8K;
1135 sta_ptr->max_amsdu =
1136 MWIFIEX_TX_DATA_BUF_SIZE_4K;
1138 for (i = 0; i < MAX_NUM_TID; i++)
1139 sta_ptr->ampdu_sta[i] =
1140 priv->aggr_prio_tbl[i].ampdu_user;
1142 for (i = 0; i < MAX_NUM_TID; i++)
1143 sta_ptr->ampdu_sta[i] = BA_STREAM_NOT_ALLOWED;
1145 if (sta_ptr->tdls_cap.extcap.ext_capab[3] &
1146 WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH) {
1147 mwifiex_config_tdls_enable(priv);
1148 mwifiex_config_tdls_cs_params(priv);
1151 memset(sta_ptr->rx_seq, 0xff, sizeof(sta_ptr->rx_seq));
1152 mwifiex_restore_tdls_packets(priv, peer, TDLS_SETUP_COMPLETE);
1153 mwifiex_auto_tdls_update_peer_status(priv, peer,
1154 TDLS_SETUP_COMPLETE);
1156 mwifiex_dbg(priv->adapter, ERROR,
1157 "tdls: enable link %pM failed\n", peer);
1159 mwifiex_11n_cleanup_reorder_tbl(priv);
1160 spin_lock_irqsave(&priv->wmm.ra_list_spinlock,
1162 mwifiex_11n_delete_all_tx_ba_stream_tbl(priv);
1163 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1165 mwifiex_del_sta_entry(priv, peer);
1167 mwifiex_restore_tdls_packets(priv, peer, TDLS_LINK_TEARDOWN);
1168 mwifiex_auto_tdls_update_peer_status(priv, peer,
1177 int mwifiex_tdls_oper(struct mwifiex_private *priv, const u8 *peer, u8 action)
1180 case MWIFIEX_TDLS_ENABLE_LINK:
1181 return mwifiex_tdls_process_enable_link(priv, peer);
1182 case MWIFIEX_TDLS_DISABLE_LINK:
1183 return mwifiex_tdls_process_disable_link(priv, peer);
1184 case MWIFIEX_TDLS_CREATE_LINK:
1185 return mwifiex_tdls_process_create_link(priv, peer);
1186 case MWIFIEX_TDLS_CONFIG_LINK:
1187 return mwifiex_tdls_process_config_link(priv, peer);
1192 int mwifiex_get_tdls_link_status(struct mwifiex_private *priv, const u8 *mac)
1194 struct mwifiex_sta_node *sta_ptr;
1196 sta_ptr = mwifiex_get_sta_entry(priv, mac);
1198 return sta_ptr->tdls_status;
1200 return TDLS_NOT_SETUP;
1203 int mwifiex_get_tdls_list(struct mwifiex_private *priv,
1204 struct tdls_peer_info *buf)
1206 struct mwifiex_sta_node *sta_ptr;
1207 struct tdls_peer_info *peer = buf;
1209 unsigned long flags;
1211 if (!ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info))
1214 /* make sure we are in station mode and connected */
1215 if (!(priv->bss_type == MWIFIEX_BSS_TYPE_STA && priv->media_connected))
1218 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
1219 list_for_each_entry(sta_ptr, &priv->sta_list, list) {
1220 if (mwifiex_is_tdls_link_setup(sta_ptr->tdls_status)) {
1221 ether_addr_copy(peer->peer_addr, sta_ptr->mac_addr);
1224 if (count >= MWIFIEX_MAX_TDLS_PEER_SUPPORTED)
1228 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
1233 void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv)
1235 struct mwifiex_sta_node *sta_ptr;
1236 struct mwifiex_ds_tdls_oper tdls_oper;
1237 unsigned long flags;
1239 if (list_empty(&priv->sta_list))
1242 list_for_each_entry(sta_ptr, &priv->sta_list, list) {
1243 memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper));
1245 if (sta_ptr->is_11n_enabled) {
1246 mwifiex_11n_cleanup_reorder_tbl(priv);
1247 spin_lock_irqsave(&priv->wmm.ra_list_spinlock,
1249 mwifiex_11n_delete_all_tx_ba_stream_tbl(priv);
1250 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1254 mwifiex_restore_tdls_packets(priv, sta_ptr->mac_addr,
1255 TDLS_LINK_TEARDOWN);
1256 memcpy(&tdls_oper.peer_mac, sta_ptr->mac_addr, ETH_ALEN);
1257 tdls_oper.tdls_action = MWIFIEX_TDLS_DISABLE_LINK;
1258 if (mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER,
1259 HostCmd_ACT_GEN_SET, 0, &tdls_oper, false))
1260 mwifiex_dbg(priv->adapter, ERROR,
1261 "Disable link failed for TDLS peer %pM",
1265 mwifiex_del_all_sta_list(priv);
1268 int mwifiex_tdls_check_tx(struct mwifiex_private *priv, struct sk_buff *skb)
1270 struct mwifiex_auto_tdls_peer *peer;
1271 unsigned long flags;
1274 ether_addr_copy(mac, skb->data);
1276 spin_lock_irqsave(&priv->auto_tdls_lock, flags);
1277 list_for_each_entry(peer, &priv->auto_tdls_list, list) {
1278 if (!memcmp(mac, peer->mac_addr, ETH_ALEN)) {
1279 if (peer->rssi <= MWIFIEX_TDLS_RSSI_HIGH &&
1280 peer->tdls_status == TDLS_NOT_SETUP &&
1281 (peer->failure_count <
1282 MWIFIEX_TDLS_MAX_FAIL_COUNT)) {
1283 peer->tdls_status = TDLS_SETUP_INPROGRESS;
1284 mwifiex_dbg(priv->adapter, INFO,
1285 "setup TDLS link, peer=%pM rssi=%d\n",
1286 peer->mac_addr, peer->rssi);
1288 cfg80211_tdls_oper_request(priv->netdev,
1292 peer->do_setup = false;
1293 priv->check_tdls_tx = false;
1294 } else if (peer->failure_count <
1295 MWIFIEX_TDLS_MAX_FAIL_COUNT &&
1296 peer->do_discover) {
1297 mwifiex_send_tdls_data_frame(priv,
1299 WLAN_TDLS_DISCOVERY_REQUEST,
1301 peer->do_discover = false;
1305 spin_unlock_irqrestore(&priv->auto_tdls_lock, flags);
1310 void mwifiex_flush_auto_tdls_list(struct mwifiex_private *priv)
1312 struct mwifiex_auto_tdls_peer *peer, *tmp_node;
1313 unsigned long flags;
1315 spin_lock_irqsave(&priv->auto_tdls_lock, flags);
1316 list_for_each_entry_safe(peer, tmp_node, &priv->auto_tdls_list, list) {
1317 list_del(&peer->list);
1321 INIT_LIST_HEAD(&priv->auto_tdls_list);
1322 spin_unlock_irqrestore(&priv->auto_tdls_lock, flags);
1323 priv->check_tdls_tx = false;
1326 void mwifiex_add_auto_tdls_peer(struct mwifiex_private *priv, const u8 *mac)
1328 struct mwifiex_auto_tdls_peer *tdls_peer;
1329 unsigned long flags;
1331 if (!priv->adapter->auto_tdls)
1334 spin_lock_irqsave(&priv->auto_tdls_lock, flags);
1335 list_for_each_entry(tdls_peer, &priv->auto_tdls_list, list) {
1336 if (!memcmp(tdls_peer->mac_addr, mac, ETH_ALEN)) {
1337 tdls_peer->tdls_status = TDLS_SETUP_INPROGRESS;
1338 tdls_peer->rssi_jiffies = jiffies;
1339 spin_unlock_irqrestore(&priv->auto_tdls_lock, flags);
1344 /* create new TDLS peer */
1345 tdls_peer = kzalloc(sizeof(*tdls_peer), GFP_ATOMIC);
1347 ether_addr_copy(tdls_peer->mac_addr, mac);
1348 tdls_peer->tdls_status = TDLS_SETUP_INPROGRESS;
1349 tdls_peer->rssi_jiffies = jiffies;
1350 INIT_LIST_HEAD(&tdls_peer->list);
1351 list_add_tail(&tdls_peer->list, &priv->auto_tdls_list);
1352 mwifiex_dbg(priv->adapter, INFO,
1353 "Add auto TDLS peer= %pM to list\n", mac);
1356 spin_unlock_irqrestore(&priv->auto_tdls_lock, flags);
1359 void mwifiex_auto_tdls_update_peer_status(struct mwifiex_private *priv,
1360 const u8 *mac, u8 link_status)
1362 struct mwifiex_auto_tdls_peer *peer;
1363 unsigned long flags;
1365 if (!priv->adapter->auto_tdls)
1368 spin_lock_irqsave(&priv->auto_tdls_lock, flags);
1369 list_for_each_entry(peer, &priv->auto_tdls_list, list) {
1370 if (!memcmp(peer->mac_addr, mac, ETH_ALEN)) {
1371 if ((link_status == TDLS_NOT_SETUP) &&
1372 (peer->tdls_status == TDLS_SETUP_INPROGRESS))
1373 peer->failure_count++;
1374 else if (mwifiex_is_tdls_link_setup(link_status))
1375 peer->failure_count = 0;
1377 peer->tdls_status = link_status;
1381 spin_unlock_irqrestore(&priv->auto_tdls_lock, flags);
1384 void mwifiex_auto_tdls_update_peer_signal(struct mwifiex_private *priv,
1385 u8 *mac, s8 snr, s8 nflr)
1387 struct mwifiex_auto_tdls_peer *peer;
1388 unsigned long flags;
1390 if (!priv->adapter->auto_tdls)
1393 spin_lock_irqsave(&priv->auto_tdls_lock, flags);
1394 list_for_each_entry(peer, &priv->auto_tdls_list, list) {
1395 if (!memcmp(peer->mac_addr, mac, ETH_ALEN)) {
1396 peer->rssi = nflr - snr;
1397 peer->rssi_jiffies = jiffies;
1401 spin_unlock_irqrestore(&priv->auto_tdls_lock, flags);
1404 void mwifiex_check_auto_tdls(unsigned long context)
1406 struct mwifiex_private *priv = (struct mwifiex_private *)context;
1407 struct mwifiex_auto_tdls_peer *tdls_peer;
1408 unsigned long flags;
1409 u16 reason = WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED;
1411 if (WARN_ON_ONCE(!priv || !priv->adapter)) {
1412 pr_err("mwifiex: %s: adapter or private structure is NULL\n",
1417 if (unlikely(!priv->adapter->auto_tdls))
1420 if (!priv->auto_tdls_timer_active) {
1421 mwifiex_dbg(priv->adapter, INFO,
1422 "auto TDLS timer inactive; return");
1426 priv->check_tdls_tx = false;
1428 if (list_empty(&priv->auto_tdls_list)) {
1429 mod_timer(&priv->auto_tdls_timer,
1431 msecs_to_jiffies(MWIFIEX_TIMER_10S));
1435 spin_lock_irqsave(&priv->auto_tdls_lock, flags);
1436 list_for_each_entry(tdls_peer, &priv->auto_tdls_list, list) {
1437 if ((jiffies - tdls_peer->rssi_jiffies) >
1438 (MWIFIEX_AUTO_TDLS_IDLE_TIME * HZ)) {
1439 tdls_peer->rssi = 0;
1440 tdls_peer->do_discover = true;
1441 priv->check_tdls_tx = true;
1444 if (((tdls_peer->rssi >= MWIFIEX_TDLS_RSSI_LOW) ||
1445 !tdls_peer->rssi) &&
1446 mwifiex_is_tdls_link_setup(tdls_peer->tdls_status)) {
1447 tdls_peer->tdls_status = TDLS_LINK_TEARDOWN;
1448 mwifiex_dbg(priv->adapter, MSG,
1449 "teardown TDLS link,peer=%pM rssi=%d\n",
1450 tdls_peer->mac_addr, -tdls_peer->rssi);
1451 tdls_peer->do_discover = true;
1452 priv->check_tdls_tx = true;
1453 cfg80211_tdls_oper_request(priv->netdev,
1454 tdls_peer->mac_addr,
1455 NL80211_TDLS_TEARDOWN,
1456 reason, GFP_ATOMIC);
1457 } else if (tdls_peer->rssi &&
1458 tdls_peer->rssi <= MWIFIEX_TDLS_RSSI_HIGH &&
1459 tdls_peer->tdls_status == TDLS_NOT_SETUP &&
1460 tdls_peer->failure_count <
1461 MWIFIEX_TDLS_MAX_FAIL_COUNT) {
1462 priv->check_tdls_tx = true;
1463 tdls_peer->do_setup = true;
1464 mwifiex_dbg(priv->adapter, INFO,
1465 "check TDLS with peer=%pM\t"
1466 "rssi=%d\n", tdls_peer->mac_addr,
1470 spin_unlock_irqrestore(&priv->auto_tdls_lock, flags);
1472 mod_timer(&priv->auto_tdls_timer,
1473 jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S));
1476 void mwifiex_setup_auto_tdls_timer(struct mwifiex_private *priv)
1478 setup_timer(&priv->auto_tdls_timer, mwifiex_check_auto_tdls,
1479 (unsigned long)priv);
1480 priv->auto_tdls_timer_active = true;
1481 mod_timer(&priv->auto_tdls_timer,
1482 jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S));
1485 void mwifiex_clean_auto_tdls(struct mwifiex_private *priv)
1487 if (ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) &&
1488 priv->adapter->auto_tdls &&
1489 priv->bss_type == MWIFIEX_BSS_TYPE_STA) {
1490 priv->auto_tdls_timer_active = false;
1491 del_timer(&priv->auto_tdls_timer);
1492 mwifiex_flush_auto_tdls_list(priv);
1496 static int mwifiex_config_tdls(struct mwifiex_private *priv, u8 enable)
1498 struct mwifiex_tdls_config config;
1500 config.enable = cpu_to_le16(enable);
1501 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG,
1502 ACT_TDLS_CS_ENABLE_CONFIG, 0, &config, true);
1505 int mwifiex_config_tdls_enable(struct mwifiex_private *priv)
1507 return mwifiex_config_tdls(priv, true);
1510 int mwifiex_config_tdls_disable(struct mwifiex_private *priv)
1512 return mwifiex_config_tdls(priv, false);
1515 int mwifiex_config_tdls_cs_params(struct mwifiex_private *priv)
1517 struct mwifiex_tdls_config_cs_params config_tdls_cs_params;
1519 config_tdls_cs_params.unit_time = MWIFIEX_DEF_CS_UNIT_TIME;
1520 config_tdls_cs_params.thr_otherlink = MWIFIEX_DEF_CS_THR_OTHERLINK;
1521 config_tdls_cs_params.thr_directlink = MWIFIEX_DEF_THR_DIRECTLINK;
1523 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG,
1524 ACT_TDLS_CS_PARAMS, 0,
1525 &config_tdls_cs_params, true);
1528 int mwifiex_stop_tdls_cs(struct mwifiex_private *priv, const u8 *peer_mac)
1530 struct mwifiex_tdls_stop_cs_params stop_tdls_cs_params;
1532 ether_addr_copy(stop_tdls_cs_params.peer_mac, peer_mac);
1534 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG,
1535 ACT_TDLS_CS_STOP, 0,
1536 &stop_tdls_cs_params, true);
1539 int mwifiex_start_tdls_cs(struct mwifiex_private *priv, const u8 *peer_mac,
1540 u8 primary_chan, u8 second_chan_offset, u8 band)
1542 struct mwifiex_tdls_init_cs_params start_tdls_cs_params;
1544 ether_addr_copy(start_tdls_cs_params.peer_mac, peer_mac);
1545 start_tdls_cs_params.primary_chan = primary_chan;
1546 start_tdls_cs_params.second_chan_offset = second_chan_offset;
1547 start_tdls_cs_params.band = band;
1549 start_tdls_cs_params.switch_time = cpu_to_le16(MWIFIEX_DEF_CS_TIME);
1550 start_tdls_cs_params.switch_timeout =
1551 cpu_to_le16(MWIFIEX_DEF_CS_TIMEOUT);
1552 start_tdls_cs_params.reg_class = MWIFIEX_DEF_CS_REG_CLASS;
1553 start_tdls_cs_params.periodicity = MWIFIEX_DEF_CS_PERIODICITY;
1555 return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG,
1556 ACT_TDLS_CS_INIT, 0,
1557 &start_tdls_cs_params, true);