1  /*
2   * NXP Wireless LAN device driver: TDLS handling
3   *
4   * Copyright 2011-2020 NXP
5   *
6   * This software file (the "File") is distributed by NXP
7   * under the terms of the GNU General Public License Version 2, June 1991
8   * (the "License").  You may use, redistribute and/or modify this File in
9   * accordance with the terms and conditions of the License, a copy of which
10   * is available on the worldwide web at
11   * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
12   *
13   * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
14   * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
15   * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
16   * this warranty disclaimer.
17   */
18  
19  #include "main.h"
20  #include "wmm.h"
21  #include "11n.h"
22  #include "11n_rxreorder.h"
23  #include "11ac.h"
24  
25  #define TDLS_REQ_FIX_LEN      6
26  #define TDLS_RESP_FIX_LEN     8
27  #define TDLS_CONFIRM_FIX_LEN  6
28  #define MWIFIEX_TDLS_WMM_INFO_SIZE 7
29  
mwifiex_restore_tdls_packets(struct mwifiex_private * priv,const u8 * mac,u8 status)30  static void mwifiex_restore_tdls_packets(struct mwifiex_private *priv,
31  					 const u8 *mac, u8 status)
32  {
33  	struct mwifiex_ra_list_tbl *ra_list;
34  	struct list_head *tid_list;
35  	struct sk_buff *skb, *tmp;
36  	struct mwifiex_txinfo *tx_info;
37  	u32 tid;
38  	u8 tid_down;
39  
40  	mwifiex_dbg(priv->adapter, DATA, "%s: %pM\n", __func__, mac);
41  	spin_lock_bh(&priv->wmm.ra_list_spinlock);
42  
43  	skb_queue_walk_safe(&priv->tdls_txq, skb, tmp) {
44  		if (!ether_addr_equal(mac, skb->data))
45  			continue;
46  
47  		__skb_unlink(skb, &priv->tdls_txq);
48  		tx_info = MWIFIEX_SKB_TXCB(skb);
49  		tid = skb->priority;
50  		tid_down = mwifiex_wmm_downgrade_tid(priv, tid);
51  
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;
56  		} else {
57  			tid_list = &priv->wmm.tid_tbl_ptr[tid_down].ra_list;
58  			ra_list = list_first_entry_or_null(tid_list,
59  					struct mwifiex_ra_list_tbl, list);
60  			tx_info->flags &= ~MWIFIEX_BUF_FLAG_TDLS_PKT;
61  		}
62  
63  		if (!ra_list) {
64  			mwifiex_write_data_complete(priv->adapter, skb, 0, -1);
65  			continue;
66  		}
67  
68  		skb_queue_tail(&ra_list->skb_head, skb);
69  
70  		ra_list->ba_pkt_count++;
71  		ra_list->total_pkt_count++;
72  
73  		if (atomic_read(&priv->wmm.highest_queued_prio) <
74  						       tos_to_tid_inv[tid_down])
75  			atomic_set(&priv->wmm.highest_queued_prio,
76  				   tos_to_tid_inv[tid_down]);
77  
78  		atomic_inc(&priv->wmm.tx_pkts_queued);
79  	}
80  
81  	spin_unlock_bh(&priv->wmm.ra_list_spinlock);
82  	return;
83  }
84  
mwifiex_hold_tdls_packets(struct mwifiex_private * priv,const u8 * mac)85  static void mwifiex_hold_tdls_packets(struct mwifiex_private *priv,
86  				      const u8 *mac)
87  {
88  	struct mwifiex_ra_list_tbl *ra_list;
89  	struct list_head *ra_list_head;
90  	struct sk_buff *skb, *tmp;
91  	int i;
92  
93  	mwifiex_dbg(priv->adapter, DATA, "%s: %pM\n", __func__, mac);
94  	spin_lock_bh(&priv->wmm.ra_list_spinlock);
95  
96  	for (i = 0; i < MAX_NUM_TID; i++) {
97  		if (!list_empty(&priv->wmm.tid_tbl_ptr[i].ra_list)) {
98  			ra_list_head = &priv->wmm.tid_tbl_ptr[i].ra_list;
99  			list_for_each_entry(ra_list, ra_list_head, list) {
100  				skb_queue_walk_safe(&ra_list->skb_head, skb,
101  						    tmp) {
102  					if (!ether_addr_equal(mac, skb->data))
103  						continue;
104  					__skb_unlink(skb, &ra_list->skb_head);
105  					atomic_dec(&priv->wmm.tx_pkts_queued);
106  					ra_list->total_pkt_count--;
107  					skb_queue_tail(&priv->tdls_txq, skb);
108  				}
109  			}
110  		}
111  	}
112  
113  	spin_unlock_bh(&priv->wmm.ra_list_spinlock);
114  	return;
115  }
116  
117  /* This function appends rate TLV to scan config command. */
118  static int
mwifiex_tdls_append_rates_ie(struct mwifiex_private * priv,struct sk_buff * skb)119  mwifiex_tdls_append_rates_ie(struct mwifiex_private *priv,
120  			     struct sk_buff *skb)
121  {
122  	u8 rates[MWIFIEX_SUPPORTED_RATES], *pos;
123  	u16 rates_size, supp_rates_size, ext_rates_size;
124  
125  	memset(rates, 0, sizeof(rates));
126  	rates_size = mwifiex_get_supported_rates(priv, rates);
127  
128  	supp_rates_size = min_t(u16, rates_size, MWIFIEX_TDLS_SUPPORTED_RATES);
129  
130  	if (skb_tailroom(skb) < rates_size + 4) {
131  		mwifiex_dbg(priv->adapter, ERROR,
132  			    "Insufficient space while adding rates\n");
133  		return -ENOMEM;
134  	}
135  
136  	pos = skb_put(skb, supp_rates_size + 2);
137  	*pos++ = WLAN_EID_SUPP_RATES;
138  	*pos++ = supp_rates_size;
139  	memcpy(pos, rates, supp_rates_size);
140  
141  	if (rates_size > MWIFIEX_TDLS_SUPPORTED_RATES) {
142  		ext_rates_size = rates_size - MWIFIEX_TDLS_SUPPORTED_RATES;
143  		pos = skb_put(skb, ext_rates_size + 2);
144  		*pos++ = WLAN_EID_EXT_SUPP_RATES;
145  		*pos++ = ext_rates_size;
146  		memcpy(pos, rates + MWIFIEX_TDLS_SUPPORTED_RATES,
147  		       ext_rates_size);
148  	}
149  
150  	return 0;
151  }
152  
mwifiex_tdls_add_aid(struct mwifiex_private * priv,struct sk_buff * skb)153  static void mwifiex_tdls_add_aid(struct mwifiex_private *priv,
154  				struct sk_buff *skb)
155  {
156  	struct ieee_types_assoc_rsp *assoc_rsp;
157  	u8 *pos;
158  
159  	assoc_rsp = (struct ieee_types_assoc_rsp *)&priv->assoc_rsp_buf;
160  	pos = skb_put(skb, 4);
161  	*pos++ = WLAN_EID_AID;
162  	*pos++ = 2;
163  	memcpy(pos, &assoc_rsp->a_id, sizeof(assoc_rsp->a_id));
164  
165  	return;
166  }
167  
mwifiex_tdls_add_vht_capab(struct mwifiex_private * priv,struct sk_buff * skb)168  static int mwifiex_tdls_add_vht_capab(struct mwifiex_private *priv,
169  				      struct sk_buff *skb)
170  {
171  	struct ieee80211_vht_cap vht_cap;
172  	u8 *pos;
173  
174  	pos = skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2);
175  	*pos++ = WLAN_EID_VHT_CAPABILITY;
176  	*pos++ = sizeof(struct ieee80211_vht_cap);
177  
178  	memset(&vht_cap, 0, sizeof(struct ieee80211_vht_cap));
179  
180  	mwifiex_fill_vht_cap_tlv(priv, &vht_cap, priv->curr_bss_params.band);
181  	memcpy(pos, &vht_cap, sizeof(vht_cap));
182  
183  	return 0;
184  }
185  
186  static int
mwifiex_tdls_add_ht_oper(struct mwifiex_private * priv,const u8 * mac,u8 vht_enabled,struct sk_buff * skb)187  mwifiex_tdls_add_ht_oper(struct mwifiex_private *priv, const u8 *mac,
188  			 u8 vht_enabled, struct sk_buff *skb)
189  {
190  	struct ieee80211_ht_operation *ht_oper;
191  	struct mwifiex_sta_node *sta_ptr;
192  	struct mwifiex_bssdescriptor *bss_desc =
193  					&priv->curr_bss_params.bss_descriptor;
194  	u8 *pos;
195  
196  	sta_ptr = mwifiex_get_sta_entry(priv, mac);
197  	if (unlikely(!sta_ptr)) {
198  		mwifiex_dbg(priv->adapter, ERROR,
199  			    "TDLS peer station not found in list\n");
200  		return -1;
201  	}
202  
203  	if (!(le16_to_cpu(sta_ptr->tdls_cap.ht_capb.cap_info))) {
204  		mwifiex_dbg(priv->adapter, WARN,
205  			    "TDLS peer doesn't support ht capabilities\n");
206  		return 0;
207  	}
208  
209  	pos = skb_put(skb, sizeof(struct ieee80211_ht_operation) + 2);
210  	*pos++ = WLAN_EID_HT_OPERATION;
211  	*pos++ = sizeof(struct ieee80211_ht_operation);
212  	ht_oper = (void *)pos;
213  
214  	ht_oper->primary_chan = bss_desc->channel;
215  
216  	/* follow AP's channel bandwidth */
217  	if (ISSUPP_CHANWIDTH40(priv->adapter->hw_dot_11n_dev_cap) &&
218  	    bss_desc->bcn_ht_cap &&
219  	    ISALLOWED_CHANWIDTH40(bss_desc->bcn_ht_oper->ht_param))
220  		ht_oper->ht_param = bss_desc->bcn_ht_oper->ht_param;
221  
222  	if (vht_enabled) {
223  		ht_oper->ht_param =
224  			  mwifiex_get_sec_chan_offset(bss_desc->channel);
225  		ht_oper->ht_param |= BIT(2);
226  	}
227  
228  	memcpy(&sta_ptr->tdls_cap.ht_oper, ht_oper,
229  	       sizeof(struct ieee80211_ht_operation));
230  
231  	return 0;
232  }
233  
mwifiex_tdls_add_vht_oper(struct mwifiex_private * priv,const u8 * mac,struct sk_buff * skb)234  static int mwifiex_tdls_add_vht_oper(struct mwifiex_private *priv,
235  				     const u8 *mac, struct sk_buff *skb)
236  {
237  	struct mwifiex_bssdescriptor *bss_desc;
238  	struct ieee80211_vht_operation *vht_oper;
239  	struct ieee80211_vht_cap *vht_cap, *ap_vht_cap = NULL;
240  	struct mwifiex_sta_node *sta_ptr;
241  	struct mwifiex_adapter *adapter = priv->adapter;
242  	u8 supp_chwd_set, peer_supp_chwd_set;
243  	u8 *pos, ap_supp_chwd_set, chan_bw;
244  	u16 mcs_map_user, mcs_map_resp, mcs_map_result;
245  	u16 mcs_user, mcs_resp, nss;
246  	u32 usr_vht_cap_info;
247  
248  	bss_desc = &priv->curr_bss_params.bss_descriptor;
249  
250  	sta_ptr = mwifiex_get_sta_entry(priv, mac);
251  	if (unlikely(!sta_ptr)) {
252  		mwifiex_dbg(adapter, ERROR,
253  			    "TDLS peer station not found in list\n");
254  		return -1;
255  	}
256  
257  	if (!(le32_to_cpu(sta_ptr->tdls_cap.vhtcap.vht_cap_info))) {
258  		mwifiex_dbg(adapter, WARN,
259  			    "TDLS peer doesn't support vht capabilities\n");
260  		return 0;
261  	}
262  
263  	if (!mwifiex_is_bss_in_11ac_mode(priv)) {
264  		if (sta_ptr->tdls_cap.extcap.ext_capab[7] &
265  		   WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED) {
266  			mwifiex_dbg(adapter, WARN,
267  				    "TDLS peer doesn't support wider bandwidth\n");
268  			return 0;
269  		}
270  	} else {
271  		ap_vht_cap = bss_desc->bcn_vht_cap;
272  	}
273  
274  	pos = skb_put(skb, sizeof(struct ieee80211_vht_operation) + 2);
275  	*pos++ = WLAN_EID_VHT_OPERATION;
276  	*pos++ = sizeof(struct ieee80211_vht_operation);
277  	vht_oper = (struct ieee80211_vht_operation *)pos;
278  
279  	if (bss_desc->bss_band & BAND_A)
280  		usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_a;
281  	else
282  		usr_vht_cap_info = adapter->usr_dot_11ac_dev_cap_bg;
283  
284  	/* find the minimum bandwidth between AP/TDLS peers */
285  	vht_cap = &sta_ptr->tdls_cap.vhtcap;
286  	supp_chwd_set = GET_VHTCAP_CHWDSET(usr_vht_cap_info);
287  	peer_supp_chwd_set =
288  			 GET_VHTCAP_CHWDSET(le32_to_cpu(vht_cap->vht_cap_info));
289  	supp_chwd_set = min_t(u8, supp_chwd_set, peer_supp_chwd_set);
290  
291  	/* We need check AP's bandwidth when TDLS_WIDER_BANDWIDTH is off */
292  
293  	if (ap_vht_cap && sta_ptr->tdls_cap.extcap.ext_capab[7] &
294  	    WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED) {
295  		ap_supp_chwd_set =
296  		      GET_VHTCAP_CHWDSET(le32_to_cpu(ap_vht_cap->vht_cap_info));
297  		supp_chwd_set = min_t(u8, supp_chwd_set, ap_supp_chwd_set);
298  	}
299  
300  	switch (supp_chwd_set) {
301  	case IEEE80211_VHT_CHANWIDTH_80MHZ:
302  		vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80MHZ;
303  		break;
304  	case IEEE80211_VHT_CHANWIDTH_160MHZ:
305  		vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_160MHZ;
306  		break;
307  	case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
308  		vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_80P80MHZ;
309  		break;
310  	default:
311  		vht_oper->chan_width = IEEE80211_VHT_CHANWIDTH_USE_HT;
312  		break;
313  	}
314  
315  	mcs_map_user = GET_DEVRXMCSMAP(adapter->usr_dot_11ac_mcs_support);
316  	mcs_map_resp = le16_to_cpu(vht_cap->supp_mcs.rx_mcs_map);
317  	mcs_map_result = 0;
318  
319  	for (nss = 1; nss <= 8; nss++) {
320  		mcs_user = GET_VHTNSSMCS(mcs_map_user, nss);
321  		mcs_resp = GET_VHTNSSMCS(mcs_map_resp, nss);
322  
323  		if ((mcs_user == IEEE80211_VHT_MCS_NOT_SUPPORTED) ||
324  		    (mcs_resp == IEEE80211_VHT_MCS_NOT_SUPPORTED))
325  			SET_VHTNSSMCS(mcs_map_result, nss,
326  				      IEEE80211_VHT_MCS_NOT_SUPPORTED);
327  		else
328  			SET_VHTNSSMCS(mcs_map_result, nss,
329  				      min_t(u16, mcs_user, mcs_resp));
330  	}
331  
332  	vht_oper->basic_mcs_set = cpu_to_le16(mcs_map_result);
333  
334  	switch (vht_oper->chan_width) {
335  	case IEEE80211_VHT_CHANWIDTH_80MHZ:
336  		chan_bw = IEEE80211_VHT_CHANWIDTH_80MHZ;
337  		break;
338  	case IEEE80211_VHT_CHANWIDTH_160MHZ:
339  		chan_bw = IEEE80211_VHT_CHANWIDTH_160MHZ;
340  		break;
341  	case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
342  		chan_bw = IEEE80211_VHT_CHANWIDTH_80MHZ;
343  		break;
344  	default:
345  		chan_bw = IEEE80211_VHT_CHANWIDTH_USE_HT;
346  		break;
347  	}
348  	vht_oper->center_freq_seg0_idx =
349  			mwifiex_get_center_freq_index(priv, BAND_AAC,
350  						      bss_desc->channel,
351  						      chan_bw);
352  
353  	return 0;
354  }
355  
mwifiex_tdls_add_ext_capab(struct mwifiex_private * priv,struct sk_buff * skb)356  static void mwifiex_tdls_add_ext_capab(struct mwifiex_private *priv,
357  				       struct sk_buff *skb)
358  {
359  	struct ieee_types_extcap *extcap;
360  
361  	extcap = skb_put(skb, sizeof(struct ieee_types_extcap));
362  	extcap->ieee_hdr.element_id = WLAN_EID_EXT_CAPABILITY;
363  	extcap->ieee_hdr.len = 8;
364  	memset(extcap->ext_capab, 0, 8);
365  	extcap->ext_capab[4] |= WLAN_EXT_CAPA5_TDLS_ENABLED;
366  	extcap->ext_capab[3] |= WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH;
367  
368  	if (priv->adapter->is_hw_11ac_capable)
369  		extcap->ext_capab[7] |= WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED;
370  }
371  
mwifiex_tdls_add_qos_capab(struct sk_buff * skb)372  static void mwifiex_tdls_add_qos_capab(struct sk_buff *skb)
373  {
374  	u8 *pos = skb_put(skb, 3);
375  
376  	*pos++ = WLAN_EID_QOS_CAPA;
377  	*pos++ = 1;
378  	*pos++ = MWIFIEX_TDLS_DEF_QOS_CAPAB;
379  }
380  
381  static void
mwifiex_tdls_add_wmm_param_ie(struct mwifiex_private * priv,struct sk_buff * skb)382  mwifiex_tdls_add_wmm_param_ie(struct mwifiex_private *priv, struct sk_buff *skb)
383  {
384  	struct ieee80211_wmm_param_ie *wmm;
385  	u8 ac_vi[] = {0x42, 0x43, 0x5e, 0x00};
386  	u8 ac_vo[] = {0x62, 0x32, 0x2f, 0x00};
387  	u8 ac_be[] = {0x03, 0xa4, 0x00, 0x00};
388  	u8 ac_bk[] = {0x27, 0xa4, 0x00, 0x00};
389  
390  	wmm = skb_put_zero(skb, sizeof(*wmm));
391  
392  	wmm->element_id = WLAN_EID_VENDOR_SPECIFIC;
393  	wmm->len = sizeof(*wmm) - 2;
394  	wmm->oui[0] = 0x00; /* Microsoft OUI 00:50:F2 */
395  	wmm->oui[1] = 0x50;
396  	wmm->oui[2] = 0xf2;
397  	wmm->oui_type = 2; /* WME */
398  	wmm->oui_subtype = 1; /* WME param */
399  	wmm->version = 1; /* WME ver */
400  	wmm->qos_info = 0; /* U-APSD not in use */
401  
402  	/* use default WMM AC parameters for TDLS link*/
403  	memcpy(&wmm->ac[0], ac_be, sizeof(ac_be));
404  	memcpy(&wmm->ac[1], ac_bk, sizeof(ac_bk));
405  	memcpy(&wmm->ac[2], ac_vi, sizeof(ac_vi));
406  	memcpy(&wmm->ac[3], ac_vo, sizeof(ac_vo));
407  }
408  
409  static void
mwifiex_add_wmm_info_ie(struct mwifiex_private * priv,struct sk_buff * skb,u8 qosinfo)410  mwifiex_add_wmm_info_ie(struct mwifiex_private *priv, struct sk_buff *skb,
411  			u8 qosinfo)
412  {
413  	u8 *buf;
414  
415  	buf = skb_put(skb,
416  		      MWIFIEX_TDLS_WMM_INFO_SIZE + sizeof(struct ieee_types_header));
417  
418  	*buf++ = WLAN_EID_VENDOR_SPECIFIC;
419  	*buf++ = 7; /* len */
420  	*buf++ = 0x00; /* Microsoft OUI 00:50:F2 */
421  	*buf++ = 0x50;
422  	*buf++ = 0xf2;
423  	*buf++ = 2; /* WME */
424  	*buf++ = 0; /* WME info */
425  	*buf++ = 1; /* WME ver */
426  	*buf++ = qosinfo; /* U-APSD no in use */
427  }
428  
mwifiex_tdls_add_bss_co_2040(struct sk_buff * skb)429  static void mwifiex_tdls_add_bss_co_2040(struct sk_buff *skb)
430  {
431  	struct ieee_types_bss_co_2040 *bssco;
432  
433  	bssco = skb_put(skb, sizeof(struct ieee_types_bss_co_2040));
434  	bssco->ieee_hdr.element_id = WLAN_EID_BSS_COEX_2040;
435  	bssco->ieee_hdr.len = sizeof(struct ieee_types_bss_co_2040) -
436  			      sizeof(struct ieee_types_header);
437  	bssco->bss_2040co = 0x01;
438  }
439  
mwifiex_tdls_add_supported_chan(struct sk_buff * skb)440  static void mwifiex_tdls_add_supported_chan(struct sk_buff *skb)
441  {
442  	struct ieee_types_generic *supp_chan;
443  	u8 chan_supp[] = {1, 11};
444  
445  	supp_chan = skb_put(skb,
446  			    (sizeof(struct ieee_types_header) + sizeof(chan_supp)));
447  	supp_chan->ieee_hdr.element_id = WLAN_EID_SUPPORTED_CHANNELS;
448  	supp_chan->ieee_hdr.len = sizeof(chan_supp);
449  	memcpy(supp_chan->data, chan_supp, sizeof(chan_supp));
450  }
451  
mwifiex_tdls_add_oper_class(struct sk_buff * skb)452  static void mwifiex_tdls_add_oper_class(struct sk_buff *skb)
453  {
454  	struct ieee_types_generic *reg_class;
455  	u8 rc_list[] = {1,
456  		1, 2, 3, 4, 12, 22, 23, 24, 25, 27, 28, 29, 30, 32, 33};
457  	reg_class = skb_put(skb,
458  			    (sizeof(struct ieee_types_header) + sizeof(rc_list)));
459  	reg_class->ieee_hdr.element_id = WLAN_EID_SUPPORTED_REGULATORY_CLASSES;
460  	reg_class->ieee_hdr.len = sizeof(rc_list);
461  	memcpy(reg_class->data, rc_list, sizeof(rc_list));
462  }
463  
mwifiex_prep_tdls_encap_data(struct mwifiex_private * priv,const u8 * peer,u8 action_code,u8 dialog_token,u16 status_code,struct sk_buff * skb)464  static int mwifiex_prep_tdls_encap_data(struct mwifiex_private *priv,
465  					const u8 *peer, u8 action_code,
466  					u8 dialog_token,
467  					u16 status_code, struct sk_buff *skb)
468  {
469  	struct ieee80211_tdls_data *tf;
470  	int ret;
471  	u16 capab;
472  	struct ieee80211_ht_cap *ht_cap;
473  	u8 radio, *pos;
474  
475  	capab = priv->curr_bss_params.bss_descriptor.cap_info_bitmap;
476  
477  	tf = skb_put(skb, offsetof(struct ieee80211_tdls_data, u));
478  	memcpy(tf->da, peer, ETH_ALEN);
479  	memcpy(tf->sa, priv->curr_addr, ETH_ALEN);
480  	tf->ether_type = cpu_to_be16(ETH_P_TDLS);
481  	tf->payload_type = WLAN_TDLS_SNAP_RFTYPE;
482  
483  	switch (action_code) {
484  	case WLAN_TDLS_SETUP_REQUEST:
485  		tf->category = WLAN_CATEGORY_TDLS;
486  		tf->action_code = WLAN_TDLS_SETUP_REQUEST;
487  		skb_put(skb, sizeof(tf->u.setup_req));
488  		tf->u.setup_req.dialog_token = dialog_token;
489  		tf->u.setup_req.capability = cpu_to_le16(capab);
490  		ret = mwifiex_tdls_append_rates_ie(priv, skb);
491  		if (ret) {
492  			dev_kfree_skb_any(skb);
493  			return ret;
494  		}
495  
496  		pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
497  		*pos++ = WLAN_EID_HT_CAPABILITY;
498  		*pos++ = sizeof(struct ieee80211_ht_cap);
499  		ht_cap = (void *)pos;
500  		radio = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
501  		ret = mwifiex_fill_cap_info(priv, radio, ht_cap);
502  		if (ret) {
503  			dev_kfree_skb_any(skb);
504  			return ret;
505  		}
506  
507  		if (priv->adapter->is_hw_11ac_capable) {
508  			ret = mwifiex_tdls_add_vht_capab(priv, skb);
509  			if (ret) {
510  				dev_kfree_skb_any(skb);
511  				return ret;
512  			}
513  			mwifiex_tdls_add_aid(priv, skb);
514  		}
515  
516  		mwifiex_tdls_add_ext_capab(priv, skb);
517  		mwifiex_tdls_add_bss_co_2040(skb);
518  		mwifiex_tdls_add_supported_chan(skb);
519  		mwifiex_tdls_add_oper_class(skb);
520  		mwifiex_add_wmm_info_ie(priv, skb, 0);
521  		break;
522  
523  	case WLAN_TDLS_SETUP_RESPONSE:
524  		tf->category = WLAN_CATEGORY_TDLS;
525  		tf->action_code = WLAN_TDLS_SETUP_RESPONSE;
526  		skb_put(skb, sizeof(tf->u.setup_resp));
527  		tf->u.setup_resp.status_code = cpu_to_le16(status_code);
528  		tf->u.setup_resp.dialog_token = dialog_token;
529  		tf->u.setup_resp.capability = cpu_to_le16(capab);
530  		ret = mwifiex_tdls_append_rates_ie(priv, skb);
531  		if (ret) {
532  			dev_kfree_skb_any(skb);
533  			return ret;
534  		}
535  
536  		pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
537  		*pos++ = WLAN_EID_HT_CAPABILITY;
538  		*pos++ = sizeof(struct ieee80211_ht_cap);
539  		ht_cap = (void *)pos;
540  		radio = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
541  		ret = mwifiex_fill_cap_info(priv, radio, ht_cap);
542  		if (ret) {
543  			dev_kfree_skb_any(skb);
544  			return ret;
545  		}
546  
547  		if (priv->adapter->is_hw_11ac_capable) {
548  			ret = mwifiex_tdls_add_vht_capab(priv, skb);
549  			if (ret) {
550  				dev_kfree_skb_any(skb);
551  				return ret;
552  			}
553  			mwifiex_tdls_add_aid(priv, skb);
554  		}
555  
556  		mwifiex_tdls_add_ext_capab(priv, skb);
557  		mwifiex_tdls_add_bss_co_2040(skb);
558  		mwifiex_tdls_add_supported_chan(skb);
559  		mwifiex_tdls_add_oper_class(skb);
560  		mwifiex_add_wmm_info_ie(priv, skb, 0);
561  		break;
562  
563  	case WLAN_TDLS_SETUP_CONFIRM:
564  		tf->category = WLAN_CATEGORY_TDLS;
565  		tf->action_code = WLAN_TDLS_SETUP_CONFIRM;
566  		skb_put(skb, sizeof(tf->u.setup_cfm));
567  		tf->u.setup_cfm.status_code = cpu_to_le16(status_code);
568  		tf->u.setup_cfm.dialog_token = dialog_token;
569  
570  		mwifiex_tdls_add_wmm_param_ie(priv, skb);
571  		if (priv->adapter->is_hw_11ac_capable) {
572  			ret = mwifiex_tdls_add_vht_oper(priv, peer, skb);
573  			if (ret) {
574  				dev_kfree_skb_any(skb);
575  				return ret;
576  			}
577  			ret = mwifiex_tdls_add_ht_oper(priv, peer, 1, skb);
578  			if (ret) {
579  				dev_kfree_skb_any(skb);
580  				return ret;
581  			}
582  		} else {
583  			ret = mwifiex_tdls_add_ht_oper(priv, peer, 0, skb);
584  			if (ret) {
585  				dev_kfree_skb_any(skb);
586  				return ret;
587  			}
588  		}
589  		break;
590  
591  	case WLAN_TDLS_TEARDOWN:
592  		tf->category = WLAN_CATEGORY_TDLS;
593  		tf->action_code = WLAN_TDLS_TEARDOWN;
594  		skb_put(skb, sizeof(tf->u.teardown));
595  		tf->u.teardown.reason_code = cpu_to_le16(status_code);
596  		break;
597  
598  	case WLAN_TDLS_DISCOVERY_REQUEST:
599  		tf->category = WLAN_CATEGORY_TDLS;
600  		tf->action_code = WLAN_TDLS_DISCOVERY_REQUEST;
601  		skb_put(skb, sizeof(tf->u.discover_req));
602  		tf->u.discover_req.dialog_token = dialog_token;
603  		break;
604  	default:
605  		mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS frame type.\n");
606  		return -EINVAL;
607  	}
608  
609  	return 0;
610  }
611  
612  static void
mwifiex_tdls_add_link_ie(struct sk_buff * skb,const u8 * src_addr,const u8 * peer,const u8 * bssid)613  mwifiex_tdls_add_link_ie(struct sk_buff *skb, const u8 *src_addr,
614  			 const u8 *peer, const u8 *bssid)
615  {
616  	struct ieee80211_tdls_lnkie *lnkid;
617  
618  	lnkid = skb_put(skb, sizeof(struct ieee80211_tdls_lnkie));
619  	lnkid->ie_type = WLAN_EID_LINK_ID;
620  	lnkid->ie_len = sizeof(struct ieee80211_tdls_lnkie) -
621  			sizeof(struct ieee_types_header);
622  
623  	memcpy(lnkid->bssid, bssid, ETH_ALEN);
624  	memcpy(lnkid->init_sta, src_addr, ETH_ALEN);
625  	memcpy(lnkid->resp_sta, peer, ETH_ALEN);
626  }
627  
mwifiex_send_tdls_data_frame(struct mwifiex_private * priv,const u8 * peer,u8 action_code,u8 dialog_token,u16 status_code,const u8 * extra_ies,size_t extra_ies_len)628  int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, const u8 *peer,
629  				 u8 action_code, u8 dialog_token,
630  				 u16 status_code, const u8 *extra_ies,
631  				 size_t extra_ies_len)
632  {
633  	struct sk_buff *skb;
634  	struct mwifiex_txinfo *tx_info;
635  	int ret;
636  	u16 skb_len;
637  
638  	skb_len = MWIFIEX_MIN_DATA_HEADER_LEN +
639  		  max(sizeof(struct ieee80211_mgmt),
640  		      sizeof(struct ieee80211_tdls_data)) +
641  		  MWIFIEX_MGMT_FRAME_HEADER_SIZE +
642  		  MWIFIEX_SUPPORTED_RATES +
643  		  3 + /* Qos Info */
644  		  sizeof(struct ieee_types_extcap) +
645  		  sizeof(struct ieee80211_ht_cap) +
646  		  sizeof(struct ieee_types_bss_co_2040) +
647  		  sizeof(struct ieee80211_ht_operation) +
648  		  sizeof(struct ieee80211_tdls_lnkie) +
649  		  (2 * (sizeof(struct ieee_types_header))) +
650  		   MWIFIEX_SUPPORTED_CHANNELS +
651  		   MWIFIEX_OPERATING_CLASSES +
652  		  sizeof(struct ieee80211_wmm_param_ie) +
653  		  extra_ies_len;
654  
655  	if (priv->adapter->is_hw_11ac_capable)
656  		skb_len += sizeof(struct ieee_types_vht_cap) +
657  			   sizeof(struct ieee_types_vht_oper) +
658  			   sizeof(struct ieee_types_aid);
659  
660  	skb = dev_alloc_skb(skb_len);
661  	if (!skb) {
662  		mwifiex_dbg(priv->adapter, ERROR,
663  			    "allocate skb failed for management frame\n");
664  		return -ENOMEM;
665  	}
666  	skb_reserve(skb, MWIFIEX_MIN_DATA_HEADER_LEN);
667  
668  	switch (action_code) {
669  	case WLAN_TDLS_SETUP_REQUEST:
670  	case WLAN_TDLS_SETUP_CONFIRM:
671  	case WLAN_TDLS_TEARDOWN:
672  	case WLAN_TDLS_DISCOVERY_REQUEST:
673  		ret = mwifiex_prep_tdls_encap_data(priv, peer, action_code,
674  						   dialog_token, status_code,
675  						   skb);
676  		if (ret) {
677  			dev_kfree_skb_any(skb);
678  			return ret;
679  		}
680  		if (extra_ies_len)
681  			skb_put_data(skb, extra_ies, extra_ies_len);
682  		mwifiex_tdls_add_link_ie(skb, priv->curr_addr, peer,
683  					 priv->cfg_bssid);
684  		break;
685  	case WLAN_TDLS_SETUP_RESPONSE:
686  		ret = mwifiex_prep_tdls_encap_data(priv, peer, action_code,
687  						   dialog_token, status_code,
688  						   skb);
689  		if (ret) {
690  			dev_kfree_skb_any(skb);
691  			return ret;
692  		}
693  		if (extra_ies_len)
694  			skb_put_data(skb, extra_ies, extra_ies_len);
695  		mwifiex_tdls_add_link_ie(skb, peer, priv->curr_addr,
696  					 priv->cfg_bssid);
697  		break;
698  	}
699  
700  	switch (action_code) {
701  	case WLAN_TDLS_SETUP_REQUEST:
702  	case WLAN_TDLS_SETUP_RESPONSE:
703  		skb->priority = MWIFIEX_PRIO_BK;
704  		break;
705  	default:
706  		skb->priority = MWIFIEX_PRIO_VI;
707  		break;
708  	}
709  
710  	tx_info = MWIFIEX_SKB_TXCB(skb);
711  	memset(tx_info, 0, sizeof(*tx_info));
712  	tx_info->bss_num = priv->bss_num;
713  	tx_info->bss_type = priv->bss_type;
714  
715  	__net_timestamp(skb);
716  	mwifiex_queue_tx_pkt(priv, skb);
717  
718  	/* Delay 10ms to make sure tdls setup confirm/teardown frame
719  	 * is received by peer
720  	*/
721  	if (action_code == WLAN_TDLS_SETUP_CONFIRM ||
722  	    action_code == WLAN_TDLS_TEARDOWN)
723  		msleep_interruptible(10);
724  
725  	return 0;
726  }
727  
728  static int
mwifiex_construct_tdls_action_frame(struct mwifiex_private * priv,const u8 * peer,u8 action_code,u8 dialog_token,u16 status_code,struct sk_buff * skb)729  mwifiex_construct_tdls_action_frame(struct mwifiex_private *priv,
730  				    const u8 *peer,
731  				    u8 action_code, u8 dialog_token,
732  				    u16 status_code, struct sk_buff *skb)
733  {
734  	struct ieee80211_mgmt *mgmt;
735  	int ret;
736  	u16 capab;
737  	struct ieee80211_ht_cap *ht_cap;
738  	unsigned int extra;
739  	u8 radio, *pos;
740  
741  	capab = priv->curr_bss_params.bss_descriptor.cap_info_bitmap;
742  
743  	mgmt = skb_put(skb, offsetof(struct ieee80211_mgmt, u));
744  
745  	memset(mgmt, 0, 24);
746  	memcpy(mgmt->da, peer, ETH_ALEN);
747  	memcpy(mgmt->sa, priv->curr_addr, ETH_ALEN);
748  	memcpy(mgmt->bssid, priv->cfg_bssid, ETH_ALEN);
749  	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
750  					  IEEE80211_STYPE_ACTION);
751  
752  	/* add address 4 */
753  	pos = skb_put(skb, ETH_ALEN);
754  
755  	switch (action_code) {
756  	case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
757  		/* See the layout of 'struct ieee80211_mgmt'. */
758  		extra = sizeof(mgmt->u.action.u.tdls_discover_resp) +
759  			sizeof(mgmt->u.action.category);
760  		skb_put(skb, extra);
761  		mgmt->u.action.category = WLAN_CATEGORY_PUBLIC;
762  		mgmt->u.action.u.tdls_discover_resp.action_code =
763  					      WLAN_PUB_ACTION_TDLS_DISCOVER_RES;
764  		mgmt->u.action.u.tdls_discover_resp.dialog_token =
765  								   dialog_token;
766  		mgmt->u.action.u.tdls_discover_resp.capability =
767  							     cpu_to_le16(capab);
768  		/* move back for addr4 */
769  		memmove(pos + ETH_ALEN, &mgmt->u.action, extra);
770  		/* init address 4 */
771  		eth_broadcast_addr(pos);
772  
773  		ret = mwifiex_tdls_append_rates_ie(priv, skb);
774  		if (ret) {
775  			dev_kfree_skb_any(skb);
776  			return ret;
777  		}
778  
779  		pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
780  		*pos++ = WLAN_EID_HT_CAPABILITY;
781  		*pos++ = sizeof(struct ieee80211_ht_cap);
782  		ht_cap = (void *)pos;
783  		radio = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
784  		ret = mwifiex_fill_cap_info(priv, radio, ht_cap);
785  		if (ret) {
786  			dev_kfree_skb_any(skb);
787  			return ret;
788  		}
789  
790  		if (priv->adapter->is_hw_11ac_capable) {
791  			ret = mwifiex_tdls_add_vht_capab(priv, skb);
792  			if (ret) {
793  				dev_kfree_skb_any(skb);
794  				return ret;
795  			}
796  			mwifiex_tdls_add_aid(priv, skb);
797  		}
798  
799  		mwifiex_tdls_add_ext_capab(priv, skb);
800  		mwifiex_tdls_add_bss_co_2040(skb);
801  		mwifiex_tdls_add_supported_chan(skb);
802  		mwifiex_tdls_add_qos_capab(skb);
803  		mwifiex_tdls_add_oper_class(skb);
804  		break;
805  	default:
806  		mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS action frame type\n");
807  		return -EINVAL;
808  	}
809  
810  	return 0;
811  }
812  
mwifiex_send_tdls_action_frame(struct mwifiex_private * priv,const u8 * peer,u8 action_code,u8 dialog_token,u16 status_code,const u8 * extra_ies,size_t extra_ies_len)813  int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, const u8 *peer,
814  				   u8 action_code, u8 dialog_token,
815  				   u16 status_code, const u8 *extra_ies,
816  				   size_t extra_ies_len)
817  {
818  	struct sk_buff *skb;
819  	struct mwifiex_txinfo *tx_info;
820  	u8 *pos;
821  	u32 pkt_type, tx_control;
822  	u16 pkt_len, skb_len;
823  
824  	skb_len = MWIFIEX_MIN_DATA_HEADER_LEN +
825  		  max(sizeof(struct ieee80211_mgmt),
826  		      sizeof(struct ieee80211_tdls_data)) +
827  		  MWIFIEX_MGMT_FRAME_HEADER_SIZE +
828  		  MWIFIEX_SUPPORTED_RATES +
829  		  sizeof(struct ieee_types_extcap) +
830  		  sizeof(struct ieee80211_ht_cap) +
831  		  sizeof(struct ieee_types_bss_co_2040) +
832  		  sizeof(struct ieee80211_ht_operation) +
833  		  sizeof(struct ieee80211_tdls_lnkie) +
834  		  extra_ies_len +
835  		  3 + /* Qos Info */
836  		  ETH_ALEN; /* Address4 */
837  
838  	if (priv->adapter->is_hw_11ac_capable)
839  		skb_len += sizeof(struct ieee_types_vht_cap) +
840  			   sizeof(struct ieee_types_vht_oper) +
841  			   sizeof(struct ieee_types_aid);
842  
843  	skb = dev_alloc_skb(skb_len);
844  	if (!skb) {
845  		mwifiex_dbg(priv->adapter, ERROR,
846  			    "allocate skb failed for management frame\n");
847  		return -ENOMEM;
848  	}
849  
850  	skb_reserve(skb, MWIFIEX_MIN_DATA_HEADER_LEN);
851  
852  	pkt_type = PKT_TYPE_MGMT;
853  	tx_control = 0;
854  	pos = skb_put_zero(skb,
855  			   MWIFIEX_MGMT_FRAME_HEADER_SIZE + sizeof(pkt_len));
856  	memcpy(pos, &pkt_type, sizeof(pkt_type));
857  	memcpy(pos + sizeof(pkt_type), &tx_control, sizeof(tx_control));
858  
859  	if (mwifiex_construct_tdls_action_frame(priv, peer, action_code,
860  						dialog_token, status_code,
861  						skb)) {
862  		dev_kfree_skb_any(skb);
863  		return -EINVAL;
864  	}
865  
866  	if (extra_ies_len)
867  		skb_put_data(skb, extra_ies, extra_ies_len);
868  
869  	/* the TDLS link IE is always added last we are the responder */
870  
871  	mwifiex_tdls_add_link_ie(skb, peer, priv->curr_addr,
872  				 priv->cfg_bssid);
873  
874  	skb->priority = MWIFIEX_PRIO_VI;
875  
876  	tx_info = MWIFIEX_SKB_TXCB(skb);
877  	memset(tx_info, 0, sizeof(*tx_info));
878  	tx_info->bss_num = priv->bss_num;
879  	tx_info->bss_type = priv->bss_type;
880  	tx_info->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT;
881  
882  	pkt_len = skb->len - MWIFIEX_MGMT_FRAME_HEADER_SIZE - sizeof(pkt_len);
883  	memcpy(skb->data + MWIFIEX_MGMT_FRAME_HEADER_SIZE, &pkt_len,
884  	       sizeof(pkt_len));
885  	__net_timestamp(skb);
886  	mwifiex_queue_tx_pkt(priv, skb);
887  
888  	return 0;
889  }
890  
891  /* This function process tdls action frame from peer.
892   * Peer capabilities are stored into station node structure.
893   */
mwifiex_process_tdls_action_frame(struct mwifiex_private * priv,u8 * buf,int len)894  void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
895  				       u8 *buf, int len)
896  {
897  	struct mwifiex_sta_node *sta_ptr;
898  	u8 *peer, *pos, *end;
899  	u8 i, action, basic;
900  	u16 cap = 0;
901  	int ies_len = 0;
902  
903  	if (len < (sizeof(struct ethhdr) + 3))
904  		return;
905  	if (*(buf + sizeof(struct ethhdr)) != WLAN_TDLS_SNAP_RFTYPE)
906  		return;
907  	if (*(buf + sizeof(struct ethhdr) + 1) != WLAN_CATEGORY_TDLS)
908  		return;
909  
910  	peer = buf + ETH_ALEN;
911  	action = *(buf + sizeof(struct ethhdr) + 2);
912  	mwifiex_dbg(priv->adapter, DATA,
913  		    "rx:tdls action: peer=%pM, action=%d\n", peer, action);
914  
915  	switch (action) {
916  	case WLAN_TDLS_SETUP_REQUEST:
917  		if (len < (sizeof(struct ethhdr) + TDLS_REQ_FIX_LEN))
918  			return;
919  
920  		pos = buf + sizeof(struct ethhdr) + 4;
921  		/* payload 1+ category 1 + action 1 + dialog 1 */
922  		cap = get_unaligned_le16(pos);
923  		ies_len = len - sizeof(struct ethhdr) - TDLS_REQ_FIX_LEN;
924  		pos += 2;
925  		break;
926  
927  	case WLAN_TDLS_SETUP_RESPONSE:
928  		if (len < (sizeof(struct ethhdr) + TDLS_RESP_FIX_LEN))
929  			return;
930  		/* payload 1+ category 1 + action 1 + dialog 1 + status code 2*/
931  		pos = buf + sizeof(struct ethhdr) + 6;
932  		cap = get_unaligned_le16(pos);
933  		ies_len = len - sizeof(struct ethhdr) - TDLS_RESP_FIX_LEN;
934  		pos += 2;
935  		break;
936  
937  	case WLAN_TDLS_SETUP_CONFIRM:
938  		if (len < (sizeof(struct ethhdr) + TDLS_CONFIRM_FIX_LEN))
939  			return;
940  		pos = buf + sizeof(struct ethhdr) + TDLS_CONFIRM_FIX_LEN;
941  		ies_len = len - sizeof(struct ethhdr) - TDLS_CONFIRM_FIX_LEN;
942  		break;
943  	default:
944  		mwifiex_dbg(priv->adapter, ERROR, "Unknown TDLS frame type.\n");
945  		return;
946  	}
947  
948  	sta_ptr = mwifiex_add_sta_entry(priv, peer);
949  	if (!sta_ptr)
950  		return;
951  
952  	sta_ptr->tdls_cap.capab = cpu_to_le16(cap);
953  
954  	for (end = pos + ies_len; pos + 1 < end; pos += 2 + pos[1]) {
955  		u8 ie_len = pos[1];
956  
957  		if (pos + 2 + ie_len > end)
958  			break;
959  
960  		switch (*pos) {
961  		case WLAN_EID_SUPP_RATES:
962  			if (ie_len > sizeof(sta_ptr->tdls_cap.rates))
963  				return;
964  			sta_ptr->tdls_cap.rates_len = ie_len;
965  			for (i = 0; i < ie_len; i++)
966  				sta_ptr->tdls_cap.rates[i] = pos[i + 2];
967  			break;
968  
969  		case WLAN_EID_EXT_SUPP_RATES:
970  			if (ie_len > sizeof(sta_ptr->tdls_cap.rates))
971  				return;
972  			basic = sta_ptr->tdls_cap.rates_len;
973  			if (ie_len > sizeof(sta_ptr->tdls_cap.rates) - basic)
974  				return;
975  			for (i = 0; i < ie_len; i++)
976  				sta_ptr->tdls_cap.rates[basic + i] = pos[i + 2];
977  			sta_ptr->tdls_cap.rates_len += ie_len;
978  			break;
979  		case WLAN_EID_HT_CAPABILITY:
980  			if (ie_len != sizeof(struct ieee80211_ht_cap))
981  				return;
982  			/* copy the ie's value into ht_capb*/
983  			memcpy((u8 *)&sta_ptr->tdls_cap.ht_capb, pos + 2,
984  			       sizeof(struct ieee80211_ht_cap));
985  			sta_ptr->is_11n_enabled = 1;
986  			break;
987  		case WLAN_EID_HT_OPERATION:
988  			if (ie_len != sizeof(struct ieee80211_ht_operation))
989  				return;
990  			/* copy the ie's value into ht_oper*/
991  			memcpy(&sta_ptr->tdls_cap.ht_oper, pos + 2,
992  			       sizeof(struct ieee80211_ht_operation));
993  			break;
994  		case WLAN_EID_BSS_COEX_2040:
995  			if (ie_len != sizeof(pos[2]))
996  				return;
997  			sta_ptr->tdls_cap.coex_2040 = pos[2];
998  			break;
999  		case WLAN_EID_EXT_CAPABILITY:
1000  			if (ie_len < sizeof(struct ieee_types_header))
1001  				return;
1002  			if (ie_len > 8)
1003  				return;
1004  			memcpy((u8 *)&sta_ptr->tdls_cap.extcap, pos,
1005  			       sizeof(struct ieee_types_header) +
1006  			       min_t(u8, ie_len, 8));
1007  			break;
1008  		case WLAN_EID_RSN:
1009  			if (ie_len < sizeof(struct ieee_types_header))
1010  				return;
1011  			if (ie_len > IEEE_MAX_IE_SIZE -
1012  			    sizeof(struct ieee_types_header))
1013  				return;
1014  			memcpy((u8 *)&sta_ptr->tdls_cap.rsn_ie, pos,
1015  			       sizeof(struct ieee_types_header) +
1016  			       min_t(u8, ie_len, IEEE_MAX_IE_SIZE -
1017  				     sizeof(struct ieee_types_header)));
1018  			break;
1019  		case WLAN_EID_QOS_CAPA:
1020  			if (ie_len != sizeof(pos[2]))
1021  				return;
1022  			sta_ptr->tdls_cap.qos_info = pos[2];
1023  			break;
1024  		case WLAN_EID_VHT_OPERATION:
1025  			if (priv->adapter->is_hw_11ac_capable) {
1026  				if (ie_len !=
1027  				    sizeof(struct ieee80211_vht_operation))
1028  					return;
1029  				/* copy the ie's value into vhtoper*/
1030  				memcpy(&sta_ptr->tdls_cap.vhtoper, pos + 2,
1031  				       sizeof(struct ieee80211_vht_operation));
1032  			}
1033  			break;
1034  		case WLAN_EID_VHT_CAPABILITY:
1035  			if (priv->adapter->is_hw_11ac_capable) {
1036  				if (ie_len != sizeof(struct ieee80211_vht_cap))
1037  					return;
1038  				/* copy the ie's value into vhtcap*/
1039  				memcpy((u8 *)&sta_ptr->tdls_cap.vhtcap, pos + 2,
1040  				       sizeof(struct ieee80211_vht_cap));
1041  				sta_ptr->is_11ac_enabled = 1;
1042  			}
1043  			break;
1044  		case WLAN_EID_AID:
1045  			if (priv->adapter->is_hw_11ac_capable) {
1046  				if (ie_len != sizeof(u16))
1047  					return;
1048  				sta_ptr->tdls_cap.aid =
1049  					get_unaligned_le16((pos + 2));
1050  			}
1051  			break;
1052  		default:
1053  			break;
1054  		}
1055  	}
1056  
1057  	return;
1058  }
1059  
1060  static int
mwifiex_tdls_process_config_link(struct mwifiex_private * priv,const u8 * peer)1061  mwifiex_tdls_process_config_link(struct mwifiex_private *priv, const u8 *peer)
1062  {
1063  	struct mwifiex_sta_node *sta_ptr;
1064  	struct mwifiex_ds_tdls_oper tdls_oper;
1065  
1066  	memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper));
1067  	sta_ptr = mwifiex_get_sta_entry(priv, peer);
1068  
1069  	if (!sta_ptr || sta_ptr->tdls_status == TDLS_SETUP_FAILURE) {
1070  		mwifiex_dbg(priv->adapter, ERROR,
1071  			    "link absent for peer %pM; cannot config\n", peer);
1072  		return -EINVAL;
1073  	}
1074  
1075  	memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN);
1076  	tdls_oper.tdls_action = MWIFIEX_TDLS_CONFIG_LINK;
1077  	return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER,
1078  				HostCmd_ACT_GEN_SET, 0, &tdls_oper, true);
1079  }
1080  
1081  static int
mwifiex_tdls_process_create_link(struct mwifiex_private * priv,const u8 * peer)1082  mwifiex_tdls_process_create_link(struct mwifiex_private *priv, const u8 *peer)
1083  {
1084  	struct mwifiex_sta_node *sta_ptr;
1085  	struct mwifiex_ds_tdls_oper tdls_oper;
1086  
1087  	memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper));
1088  	sta_ptr = mwifiex_get_sta_entry(priv, peer);
1089  
1090  	if (sta_ptr && sta_ptr->tdls_status == TDLS_SETUP_INPROGRESS) {
1091  		mwifiex_dbg(priv->adapter, WARN,
1092  			    "Setup already in progress for peer %pM\n", peer);
1093  		return 0;
1094  	}
1095  
1096  	sta_ptr = mwifiex_add_sta_entry(priv, peer);
1097  	if (!sta_ptr)
1098  		return -ENOMEM;
1099  
1100  	sta_ptr->tdls_status = TDLS_SETUP_INPROGRESS;
1101  	mwifiex_hold_tdls_packets(priv, peer);
1102  	memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN);
1103  	tdls_oper.tdls_action = MWIFIEX_TDLS_CREATE_LINK;
1104  	return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER,
1105  				HostCmd_ACT_GEN_SET, 0, &tdls_oper, true);
1106  }
1107  
1108  static int
mwifiex_tdls_process_disable_link(struct mwifiex_private * priv,const u8 * peer)1109  mwifiex_tdls_process_disable_link(struct mwifiex_private *priv, const u8 *peer)
1110  {
1111  	struct mwifiex_sta_node *sta_ptr;
1112  	struct mwifiex_ds_tdls_oper tdls_oper;
1113  
1114  	memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper));
1115  	sta_ptr = mwifiex_get_sta_entry(priv, peer);
1116  
1117  	if (sta_ptr) {
1118  		if (sta_ptr->is_11n_enabled) {
1119  			mwifiex_11n_cleanup_reorder_tbl(priv);
1120  			spin_lock_bh(&priv->wmm.ra_list_spinlock);
1121  			mwifiex_11n_delete_all_tx_ba_stream_tbl(priv);
1122  			spin_unlock_bh(&priv->wmm.ra_list_spinlock);
1123  		}
1124  		mwifiex_del_sta_entry(priv, peer);
1125  	}
1126  
1127  	mwifiex_restore_tdls_packets(priv, peer, TDLS_LINK_TEARDOWN);
1128  	mwifiex_auto_tdls_update_peer_status(priv, peer, TDLS_NOT_SETUP);
1129  	memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN);
1130  	tdls_oper.tdls_action = MWIFIEX_TDLS_DISABLE_LINK;
1131  	return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER,
1132  				HostCmd_ACT_GEN_SET, 0, &tdls_oper, true);
1133  }
1134  
1135  static int
mwifiex_tdls_process_enable_link(struct mwifiex_private * priv,const u8 * peer)1136  mwifiex_tdls_process_enable_link(struct mwifiex_private *priv, const u8 *peer)
1137  {
1138  	struct mwifiex_sta_node *sta_ptr;
1139  	struct ieee80211_mcs_info mcs;
1140  	int i;
1141  
1142  	sta_ptr = mwifiex_get_sta_entry(priv, peer);
1143  
1144  	if (sta_ptr && (sta_ptr->tdls_status != TDLS_SETUP_FAILURE)) {
1145  		mwifiex_dbg(priv->adapter, MSG,
1146  			    "tdls: enable link %pM success\n", peer);
1147  
1148  		sta_ptr->tdls_status = TDLS_SETUP_COMPLETE;
1149  
1150  		mcs = sta_ptr->tdls_cap.ht_capb.mcs;
1151  		if (mcs.rx_mask[0] != 0xff)
1152  			sta_ptr->is_11n_enabled = true;
1153  		if (sta_ptr->is_11n_enabled) {
1154  			if (le16_to_cpu(sta_ptr->tdls_cap.ht_capb.cap_info) &
1155  			    IEEE80211_HT_CAP_MAX_AMSDU)
1156  				sta_ptr->max_amsdu =
1157  					MWIFIEX_TX_DATA_BUF_SIZE_8K;
1158  			else
1159  				sta_ptr->max_amsdu =
1160  					MWIFIEX_TX_DATA_BUF_SIZE_4K;
1161  
1162  			for (i = 0; i < MAX_NUM_TID; i++)
1163  				sta_ptr->ampdu_sta[i] =
1164  					      priv->aggr_prio_tbl[i].ampdu_user;
1165  		} else {
1166  			for (i = 0; i < MAX_NUM_TID; i++)
1167  				sta_ptr->ampdu_sta[i] = BA_STREAM_NOT_ALLOWED;
1168  		}
1169  		if (sta_ptr->tdls_cap.extcap.ext_capab[3] &
1170  		    WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH) {
1171  			mwifiex_config_tdls_enable(priv);
1172  			mwifiex_config_tdls_cs_params(priv);
1173  		}
1174  
1175  		memset(sta_ptr->rx_seq, 0xff, sizeof(sta_ptr->rx_seq));
1176  		mwifiex_restore_tdls_packets(priv, peer, TDLS_SETUP_COMPLETE);
1177  		mwifiex_auto_tdls_update_peer_status(priv, peer,
1178  						     TDLS_SETUP_COMPLETE);
1179  	} else {
1180  		mwifiex_dbg(priv->adapter, ERROR,
1181  			    "tdls: enable link %pM failed\n", peer);
1182  		if (sta_ptr) {
1183  			mwifiex_11n_cleanup_reorder_tbl(priv);
1184  			spin_lock_bh(&priv->wmm.ra_list_spinlock);
1185  			mwifiex_11n_delete_all_tx_ba_stream_tbl(priv);
1186  			spin_unlock_bh(&priv->wmm.ra_list_spinlock);
1187  			mwifiex_del_sta_entry(priv, peer);
1188  		}
1189  		mwifiex_restore_tdls_packets(priv, peer, TDLS_LINK_TEARDOWN);
1190  		mwifiex_auto_tdls_update_peer_status(priv, peer,
1191  						     TDLS_NOT_SETUP);
1192  
1193  		return -1;
1194  	}
1195  
1196  	return 0;
1197  }
1198  
mwifiex_tdls_oper(struct mwifiex_private * priv,const u8 * peer,u8 action)1199  int mwifiex_tdls_oper(struct mwifiex_private *priv, const u8 *peer, u8 action)
1200  {
1201  	switch (action) {
1202  	case MWIFIEX_TDLS_ENABLE_LINK:
1203  		return mwifiex_tdls_process_enable_link(priv, peer);
1204  	case MWIFIEX_TDLS_DISABLE_LINK:
1205  		return mwifiex_tdls_process_disable_link(priv, peer);
1206  	case MWIFIEX_TDLS_CREATE_LINK:
1207  		return mwifiex_tdls_process_create_link(priv, peer);
1208  	case MWIFIEX_TDLS_CONFIG_LINK:
1209  		return mwifiex_tdls_process_config_link(priv, peer);
1210  	}
1211  	return 0;
1212  }
1213  
mwifiex_get_tdls_link_status(struct mwifiex_private * priv,const u8 * mac)1214  int mwifiex_get_tdls_link_status(struct mwifiex_private *priv, const u8 *mac)
1215  {
1216  	struct mwifiex_sta_node *sta_ptr;
1217  
1218  	sta_ptr = mwifiex_get_sta_entry(priv, mac);
1219  	if (sta_ptr)
1220  		return sta_ptr->tdls_status;
1221  
1222  	return TDLS_NOT_SETUP;
1223  }
1224  
mwifiex_get_tdls_list(struct mwifiex_private * priv,struct tdls_peer_info * buf)1225  int mwifiex_get_tdls_list(struct mwifiex_private *priv,
1226  			  struct tdls_peer_info *buf)
1227  {
1228  	struct mwifiex_sta_node *sta_ptr;
1229  	struct tdls_peer_info *peer = buf;
1230  	int count = 0;
1231  
1232  	if (!ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info))
1233  		return 0;
1234  
1235  	/* make sure we are in station mode and connected */
1236  	if (!(priv->bss_type == MWIFIEX_BSS_TYPE_STA && priv->media_connected))
1237  		return 0;
1238  
1239  	spin_lock_bh(&priv->sta_list_spinlock);
1240  	list_for_each_entry(sta_ptr, &priv->sta_list, list) {
1241  		if (mwifiex_is_tdls_link_setup(sta_ptr->tdls_status)) {
1242  			ether_addr_copy(peer->peer_addr, sta_ptr->mac_addr);
1243  			peer++;
1244  			count++;
1245  			if (count >= MWIFIEX_MAX_TDLS_PEER_SUPPORTED)
1246  				break;
1247  		}
1248  	}
1249  	spin_unlock_bh(&priv->sta_list_spinlock);
1250  
1251  	return count;
1252  }
1253  
mwifiex_disable_all_tdls_links(struct mwifiex_private * priv)1254  void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv)
1255  {
1256  	struct mwifiex_sta_node *sta_ptr;
1257  	struct mwifiex_ds_tdls_oper tdls_oper;
1258  
1259  	if (list_empty(&priv->sta_list))
1260  		return;
1261  
1262  	list_for_each_entry(sta_ptr, &priv->sta_list, list) {
1263  		memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper));
1264  
1265  		if (sta_ptr->is_11n_enabled) {
1266  			mwifiex_11n_cleanup_reorder_tbl(priv);
1267  			spin_lock_bh(&priv->wmm.ra_list_spinlock);
1268  			mwifiex_11n_delete_all_tx_ba_stream_tbl(priv);
1269  			spin_unlock_bh(&priv->wmm.ra_list_spinlock);
1270  		}
1271  
1272  		mwifiex_restore_tdls_packets(priv, sta_ptr->mac_addr,
1273  					     TDLS_LINK_TEARDOWN);
1274  		memcpy(&tdls_oper.peer_mac, sta_ptr->mac_addr, ETH_ALEN);
1275  		tdls_oper.tdls_action = MWIFIEX_TDLS_DISABLE_LINK;
1276  		if (mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_OPER,
1277  				     HostCmd_ACT_GEN_SET, 0, &tdls_oper, false))
1278  			mwifiex_dbg(priv->adapter, ERROR,
1279  				    "Disable link failed for TDLS peer %pM",
1280  				    sta_ptr->mac_addr);
1281  	}
1282  
1283  	mwifiex_del_all_sta_list(priv);
1284  }
1285  
mwifiex_tdls_check_tx(struct mwifiex_private * priv,struct sk_buff * skb)1286  int mwifiex_tdls_check_tx(struct mwifiex_private *priv, struct sk_buff *skb)
1287  {
1288  	struct mwifiex_auto_tdls_peer *peer;
1289  	u8 mac[ETH_ALEN];
1290  
1291  	ether_addr_copy(mac, skb->data);
1292  
1293  	spin_lock_bh(&priv->auto_tdls_lock);
1294  	list_for_each_entry(peer, &priv->auto_tdls_list, list) {
1295  		if (!memcmp(mac, peer->mac_addr, ETH_ALEN)) {
1296  			if (peer->rssi <= MWIFIEX_TDLS_RSSI_HIGH &&
1297  			    peer->tdls_status == TDLS_NOT_SETUP &&
1298  			    (peer->failure_count <
1299  			     MWIFIEX_TDLS_MAX_FAIL_COUNT)) {
1300  				peer->tdls_status = TDLS_SETUP_INPROGRESS;
1301  				mwifiex_dbg(priv->adapter, INFO,
1302  					    "setup TDLS link, peer=%pM rssi=%d\n",
1303  					    peer->mac_addr, peer->rssi);
1304  
1305  				cfg80211_tdls_oper_request(priv->netdev,
1306  							   peer->mac_addr,
1307  							   NL80211_TDLS_SETUP,
1308  							   0, GFP_ATOMIC);
1309  				peer->do_setup = false;
1310  				priv->check_tdls_tx = false;
1311  			} else if (peer->failure_count <
1312  				   MWIFIEX_TDLS_MAX_FAIL_COUNT &&
1313  				   peer->do_discover) {
1314  				mwifiex_send_tdls_data_frame(priv,
1315  							     peer->mac_addr,
1316  						    WLAN_TDLS_DISCOVERY_REQUEST,
1317  							     1, 0, NULL, 0);
1318  				peer->do_discover = false;
1319  			}
1320  		}
1321  	}
1322  	spin_unlock_bh(&priv->auto_tdls_lock);
1323  
1324  	return 0;
1325  }
1326  
mwifiex_flush_auto_tdls_list(struct mwifiex_private * priv)1327  void mwifiex_flush_auto_tdls_list(struct mwifiex_private *priv)
1328  {
1329  	struct mwifiex_auto_tdls_peer *peer, *tmp_node;
1330  
1331  	spin_lock_bh(&priv->auto_tdls_lock);
1332  	list_for_each_entry_safe(peer, tmp_node, &priv->auto_tdls_list, list) {
1333  		list_del(&peer->list);
1334  		kfree(peer);
1335  	}
1336  
1337  	INIT_LIST_HEAD(&priv->auto_tdls_list);
1338  	spin_unlock_bh(&priv->auto_tdls_lock);
1339  	priv->check_tdls_tx = false;
1340  }
1341  
mwifiex_add_auto_tdls_peer(struct mwifiex_private * priv,const u8 * mac)1342  void mwifiex_add_auto_tdls_peer(struct mwifiex_private *priv, const u8 *mac)
1343  {
1344  	struct mwifiex_auto_tdls_peer *tdls_peer;
1345  
1346  	if (!priv->adapter->auto_tdls)
1347  		return;
1348  
1349  	spin_lock_bh(&priv->auto_tdls_lock);
1350  	list_for_each_entry(tdls_peer, &priv->auto_tdls_list, list) {
1351  		if (!memcmp(tdls_peer->mac_addr, mac, ETH_ALEN)) {
1352  			tdls_peer->tdls_status = TDLS_SETUP_INPROGRESS;
1353  			tdls_peer->rssi_jiffies = jiffies;
1354  			spin_unlock_bh(&priv->auto_tdls_lock);
1355  			return;
1356  		}
1357  	}
1358  
1359  	/* create new TDLS peer */
1360  	tdls_peer = kzalloc(sizeof(*tdls_peer), GFP_ATOMIC);
1361  	if (tdls_peer) {
1362  		ether_addr_copy(tdls_peer->mac_addr, mac);
1363  		tdls_peer->tdls_status = TDLS_SETUP_INPROGRESS;
1364  		tdls_peer->rssi_jiffies = jiffies;
1365  		INIT_LIST_HEAD(&tdls_peer->list);
1366  		list_add_tail(&tdls_peer->list, &priv->auto_tdls_list);
1367  		mwifiex_dbg(priv->adapter, INFO,
1368  			    "Add auto TDLS peer= %pM to list\n", mac);
1369  	}
1370  
1371  	spin_unlock_bh(&priv->auto_tdls_lock);
1372  }
1373  
mwifiex_auto_tdls_update_peer_status(struct mwifiex_private * priv,const u8 * mac,u8 link_status)1374  void mwifiex_auto_tdls_update_peer_status(struct mwifiex_private *priv,
1375  					  const u8 *mac, u8 link_status)
1376  {
1377  	struct mwifiex_auto_tdls_peer *peer;
1378  
1379  	if (!priv->adapter->auto_tdls)
1380  		return;
1381  
1382  	spin_lock_bh(&priv->auto_tdls_lock);
1383  	list_for_each_entry(peer, &priv->auto_tdls_list, list) {
1384  		if (!memcmp(peer->mac_addr, mac, ETH_ALEN)) {
1385  			if ((link_status == TDLS_NOT_SETUP) &&
1386  			    (peer->tdls_status == TDLS_SETUP_INPROGRESS))
1387  				peer->failure_count++;
1388  			else if (mwifiex_is_tdls_link_setup(link_status))
1389  				peer->failure_count = 0;
1390  
1391  			peer->tdls_status = link_status;
1392  			break;
1393  		}
1394  	}
1395  	spin_unlock_bh(&priv->auto_tdls_lock);
1396  }
1397  
mwifiex_auto_tdls_update_peer_signal(struct mwifiex_private * priv,u8 * mac,s8 snr,s8 nflr)1398  void mwifiex_auto_tdls_update_peer_signal(struct mwifiex_private *priv,
1399  					  u8 *mac, s8 snr, s8 nflr)
1400  {
1401  	struct mwifiex_auto_tdls_peer *peer;
1402  
1403  	if (!priv->adapter->auto_tdls)
1404  		return;
1405  
1406  	spin_lock_bh(&priv->auto_tdls_lock);
1407  	list_for_each_entry(peer, &priv->auto_tdls_list, list) {
1408  		if (!memcmp(peer->mac_addr, mac, ETH_ALEN)) {
1409  			peer->rssi = nflr - snr;
1410  			peer->rssi_jiffies = jiffies;
1411  			break;
1412  		}
1413  	}
1414  	spin_unlock_bh(&priv->auto_tdls_lock);
1415  }
1416  
mwifiex_check_auto_tdls(struct timer_list * t)1417  void mwifiex_check_auto_tdls(struct timer_list *t)
1418  {
1419  	struct mwifiex_private *priv = from_timer(priv, t, auto_tdls_timer);
1420  	struct mwifiex_auto_tdls_peer *tdls_peer;
1421  	u16 reason = WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED;
1422  
1423  	if (WARN_ON_ONCE(!priv || !priv->adapter)) {
1424  		pr_err("mwifiex: %s: adapter or private structure is NULL\n",
1425  		       __func__);
1426  		return;
1427  	}
1428  
1429  	if (unlikely(!priv->adapter->auto_tdls))
1430  		return;
1431  
1432  	if (!priv->auto_tdls_timer_active) {
1433  		mwifiex_dbg(priv->adapter, INFO,
1434  			    "auto TDLS timer inactive; return");
1435  		return;
1436  	}
1437  
1438  	priv->check_tdls_tx = false;
1439  
1440  	spin_lock_bh(&priv->auto_tdls_lock);
1441  	list_for_each_entry(tdls_peer, &priv->auto_tdls_list, list) {
1442  		if (time_after(jiffies, tdls_peer->rssi_jiffies +
1443  					 MWIFIEX_AUTO_TDLS_IDLE_TIME * HZ)) {
1444  			tdls_peer->rssi = 0;
1445  			tdls_peer->do_discover = true;
1446  			priv->check_tdls_tx = true;
1447  		}
1448  
1449  		if (((tdls_peer->rssi >= MWIFIEX_TDLS_RSSI_LOW) ||
1450  		     !tdls_peer->rssi) &&
1451  		    mwifiex_is_tdls_link_setup(tdls_peer->tdls_status)) {
1452  			tdls_peer->tdls_status = TDLS_LINK_TEARDOWN;
1453  			mwifiex_dbg(priv->adapter, MSG,
1454  				    "teardown TDLS link,peer=%pM rssi=%d\n",
1455  				    tdls_peer->mac_addr, -tdls_peer->rssi);
1456  			tdls_peer->do_discover = true;
1457  			priv->check_tdls_tx = true;
1458  			cfg80211_tdls_oper_request(priv->netdev,
1459  						   tdls_peer->mac_addr,
1460  						   NL80211_TDLS_TEARDOWN,
1461  						   reason, GFP_ATOMIC);
1462  		} else if (tdls_peer->rssi &&
1463  			   tdls_peer->rssi <= MWIFIEX_TDLS_RSSI_HIGH &&
1464  			   tdls_peer->tdls_status == TDLS_NOT_SETUP &&
1465  			   tdls_peer->failure_count <
1466  			   MWIFIEX_TDLS_MAX_FAIL_COUNT) {
1467  				priv->check_tdls_tx = true;
1468  				tdls_peer->do_setup = true;
1469  				mwifiex_dbg(priv->adapter, INFO,
1470  					    "check TDLS with peer=%pM\t"
1471  					    "rssi=%d\n", tdls_peer->mac_addr,
1472  					    tdls_peer->rssi);
1473  		}
1474  	}
1475  	spin_unlock_bh(&priv->auto_tdls_lock);
1476  
1477  	mod_timer(&priv->auto_tdls_timer,
1478  		  jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S));
1479  }
1480  
mwifiex_setup_auto_tdls_timer(struct mwifiex_private * priv)1481  void mwifiex_setup_auto_tdls_timer(struct mwifiex_private *priv)
1482  {
1483  	timer_setup(&priv->auto_tdls_timer, mwifiex_check_auto_tdls, 0);
1484  	priv->auto_tdls_timer_active = true;
1485  	mod_timer(&priv->auto_tdls_timer,
1486  		  jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S));
1487  }
1488  
mwifiex_clean_auto_tdls(struct mwifiex_private * priv)1489  void mwifiex_clean_auto_tdls(struct mwifiex_private *priv)
1490  {
1491  	if (ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) &&
1492  	    priv->adapter->auto_tdls &&
1493  	    priv->bss_type == MWIFIEX_BSS_TYPE_STA) {
1494  		priv->auto_tdls_timer_active = false;
1495  		del_timer(&priv->auto_tdls_timer);
1496  		mwifiex_flush_auto_tdls_list(priv);
1497  	}
1498  }
1499  
mwifiex_config_tdls(struct mwifiex_private * priv,u8 enable)1500  static int mwifiex_config_tdls(struct mwifiex_private *priv, u8 enable)
1501  {
1502  	struct mwifiex_tdls_config config;
1503  
1504  	config.enable = cpu_to_le16(enable);
1505  	return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG,
1506  				ACT_TDLS_CS_ENABLE_CONFIG, 0, &config, true);
1507  }
1508  
mwifiex_config_tdls_enable(struct mwifiex_private * priv)1509  int mwifiex_config_tdls_enable(struct mwifiex_private *priv)
1510  {
1511  	return mwifiex_config_tdls(priv, true);
1512  }
1513  
mwifiex_config_tdls_disable(struct mwifiex_private * priv)1514  int mwifiex_config_tdls_disable(struct mwifiex_private *priv)
1515  {
1516  	return mwifiex_config_tdls(priv, false);
1517  }
1518  
mwifiex_config_tdls_cs_params(struct mwifiex_private * priv)1519  int mwifiex_config_tdls_cs_params(struct mwifiex_private *priv)
1520  {
1521  	struct mwifiex_tdls_config_cs_params config_tdls_cs_params;
1522  
1523  	config_tdls_cs_params.unit_time = MWIFIEX_DEF_CS_UNIT_TIME;
1524  	config_tdls_cs_params.thr_otherlink = MWIFIEX_DEF_CS_THR_OTHERLINK;
1525  	config_tdls_cs_params.thr_directlink = MWIFIEX_DEF_THR_DIRECTLINK;
1526  
1527  	return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG,
1528  				ACT_TDLS_CS_PARAMS, 0,
1529  				&config_tdls_cs_params, true);
1530  }
1531  
mwifiex_stop_tdls_cs(struct mwifiex_private * priv,const u8 * peer_mac)1532  int mwifiex_stop_tdls_cs(struct mwifiex_private *priv, const u8 *peer_mac)
1533  {
1534  	struct mwifiex_tdls_stop_cs_params stop_tdls_cs_params;
1535  
1536  	ether_addr_copy(stop_tdls_cs_params.peer_mac, peer_mac);
1537  
1538  	return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG,
1539  				ACT_TDLS_CS_STOP, 0,
1540  				&stop_tdls_cs_params, true);
1541  }
1542  
mwifiex_start_tdls_cs(struct mwifiex_private * priv,const u8 * peer_mac,u8 primary_chan,u8 second_chan_offset,u8 band)1543  int mwifiex_start_tdls_cs(struct mwifiex_private *priv, const u8 *peer_mac,
1544  			  u8 primary_chan, u8 second_chan_offset, u8 band)
1545  {
1546  	struct mwifiex_tdls_init_cs_params start_tdls_cs_params;
1547  
1548  	ether_addr_copy(start_tdls_cs_params.peer_mac, peer_mac);
1549  	start_tdls_cs_params.primary_chan = primary_chan;
1550  	start_tdls_cs_params.second_chan_offset = second_chan_offset;
1551  	start_tdls_cs_params.band = band;
1552  
1553  	start_tdls_cs_params.switch_time = cpu_to_le16(MWIFIEX_DEF_CS_TIME);
1554  	start_tdls_cs_params.switch_timeout =
1555  					cpu_to_le16(MWIFIEX_DEF_CS_TIMEOUT);
1556  	start_tdls_cs_params.reg_class = MWIFIEX_DEF_CS_REG_CLASS;
1557  	start_tdls_cs_params.periodicity = MWIFIEX_DEF_CS_PERIODICITY;
1558  
1559  	return mwifiex_send_cmd(priv, HostCmd_CMD_TDLS_CONFIG,
1560  				ACT_TDLS_CS_INIT, 0,
1561  				&start_tdls_cs_params, true);
1562  }
1563