xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852bs/core/rtw_tdls.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2019 Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  *****************************************************************************/
15 #define _RTW_TDLS_C_
16 
17 #include <drv_types.h>
18 
19 #ifdef CONFIG_TDLS
20 #define ONE_SEC 	1000 /* 1000 ms */
21 
22 extern unsigned char MCS_rate_2R[16];
23 extern unsigned char MCS_rate_1R[16];
24 
rtw_tdls_set_link_established(_adapter * adapter,bool en)25 inline void rtw_tdls_set_link_established(_adapter *adapter, bool en)
26 {
27 	adapter->tdlsinfo.link_established = en;
28 	rtw_mi_update_iface_status(&(adapter->mlmepriv), 0);
29 }
30 
rtw_reset_tdls_info(_adapter * padapter)31 void rtw_reset_tdls_info(_adapter *padapter)
32 {
33 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
34 
35 	ptdlsinfo->ap_prohibited = _FALSE;
36 
37 	/* For TDLS channel switch, currently we only allow it to work in wifi logo test mode */
38 	if (padapter->registrypriv.wifi_spec == 1)
39 		ptdlsinfo->ch_switch_prohibited = _FALSE;
40 	else
41 		ptdlsinfo->ch_switch_prohibited = _TRUE;
42 
43 	rtw_tdls_set_link_established(padapter, _FALSE);
44 	ptdlsinfo->sta_cnt = 0;
45 	ptdlsinfo->sta_maximum = _FALSE;
46 
47 #ifdef CONFIG_TDLS_CH_SW
48 	ptdlsinfo->chsw_info.ch_sw_state = TDLS_STATE_NONE;
49 	ATOMIC_SET(&ptdlsinfo->chsw_info.chsw_on, _FALSE);
50 	ptdlsinfo->chsw_info.off_ch_num = 0;
51 	ptdlsinfo->chsw_info.ch_offset = CHAN_OFFSET_NO_EXT;
52 	ptdlsinfo->chsw_info.cur_time = 0;
53 	ptdlsinfo->chsw_info.delay_switch_back = _FALSE;
54 	ptdlsinfo->chsw_info.dump_stack = _FALSE;
55 #endif
56 
57 	ptdlsinfo->ch_sensing = 0;
58 	ptdlsinfo->watchdog_count = 0;
59 	ptdlsinfo->dev_discovered = _FALSE;
60 
61 #ifdef CONFIG_WFD
62 	ptdlsinfo->wfd_info = &padapter->wfd_info;
63 #endif
64 
65 	ptdlsinfo->tdls_sctx = NULL;
66 }
67 
rtw_init_tdls_info(_adapter * padapter)68 int rtw_init_tdls_info(_adapter *padapter)
69 {
70 	int	res = _SUCCESS;
71 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
72 
73 	rtw_reset_tdls_info(padapter);
74 
75 #ifdef CONFIG_TDLS_DRIVER_SETUP
76 	ptdlsinfo->driver_setup = _TRUE;
77 #else
78 	ptdlsinfo->driver_setup = _FALSE;
79 #endif /* CONFIG_TDLS_DRIVER_SETUP */
80 
81 	_rtw_spinlock_init(&ptdlsinfo->cmd_lock);
82 	_rtw_spinlock_init(&ptdlsinfo->hdl_lock);
83 
84 	return res;
85 
86 }
87 
rtw_free_tdls_info(struct tdls_info * ptdlsinfo)88 void rtw_free_tdls_info(struct tdls_info *ptdlsinfo)
89 {
90 	_rtw_spinlock_free(&ptdlsinfo->cmd_lock);
91 	_rtw_spinlock_free(&ptdlsinfo->hdl_lock);
92 
93 	_rtw_memset(ptdlsinfo, 0, sizeof(struct tdls_info));
94 
95 }
96 
rtw_free_all_tdls_sta(_adapter * padapter,u8 enqueue_cmd)97 void rtw_free_all_tdls_sta(_adapter *padapter, u8 enqueue_cmd)
98 {
99 	struct sta_priv *pstapriv = &padapter->stapriv;
100 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
101 	_list	*plist, *phead;
102 	s32	index;
103 	struct sta_info *psta = NULL;
104 	struct sta_info *ptdls_sta[NUM_STA];
105 	u8 empty_hwaddr[ETH_ALEN] = { 0x00 };
106 
107 	_rtw_memset(ptdls_sta, 0x00, sizeof(ptdls_sta));
108 
109 	_rtw_spinlock_bh(&pstapriv->sta_hash_lock);
110 	for (index = 0; index < NUM_STA; index++) {
111 		phead = &(pstapriv->sta_hash[index]);
112 		plist = get_next(phead);
113 
114 		while (rtw_end_of_queue_search(phead, plist) == _FALSE) {
115 			psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
116 
117 			plist = get_next(plist);
118 
119 			if (psta->tdls_sta_state != TDLS_STATE_NONE)
120 				ptdls_sta[index] = psta;
121 		}
122 	}
123 	_rtw_spinunlock_bh(&pstapriv->sta_hash_lock);
124 
125 	for (index = 0; index < NUM_STA; index++) {
126 		if (ptdls_sta[index]) {
127 			struct TDLSoption_param tdls_param;
128 
129 			psta = ptdls_sta[index];
130 
131 			RTW_INFO("Do tear down to "MAC_FMT" by enqueue_cmd = %d\n", MAC_ARG(psta->phl_sta->mac_addr), enqueue_cmd);
132 
133 			_rtw_memcpy(&(tdls_param.addr), psta->phl_sta->mac_addr, ETH_ALEN);
134 			tdls_param.option = TDLS_TEARDOWN_STA_NO_WAIT;
135 			tdls_hdl(padapter, (unsigned char *)&(tdls_param));
136 
137 			rtw_tdls_teardown_pre_hdl(padapter, psta);
138 
139 			if (enqueue_cmd == _TRUE)
140 				rtw_tdls_cmd(padapter, psta->phl_sta->mac_addr, TDLS_TEARDOWN_STA_LOCALLY_POST);
141 			else
142 			 {
143 				tdls_param.option = TDLS_TEARDOWN_STA_LOCALLY_POST;
144 				tdls_hdl(padapter, (unsigned char *)&(tdls_param));
145 			}
146 		}
147 	}
148 }
149 
check_ap_tdls_prohibited(u8 * pframe,u8 pkt_len)150 int check_ap_tdls_prohibited(u8 *pframe, u8 pkt_len)
151 {
152 	u8 tdls_prohibited_bit = 0x40; /* bit(38); TDLS_prohibited */
153 
154 	if (pkt_len < 5)
155 		return _FALSE;
156 
157 	pframe += 4;
158 	if ((*pframe) & tdls_prohibited_bit)
159 		return _TRUE;
160 
161 	return _FALSE;
162 }
163 
check_ap_tdls_ch_switching_prohibited(u8 * pframe,u8 pkt_len)164 int check_ap_tdls_ch_switching_prohibited(u8 *pframe, u8 pkt_len)
165 {
166 	u8 tdls_ch_swithcing_prohibited_bit = 0x80; /* bit(39); TDLS_channel_switching prohibited */
167 
168 	if (pkt_len < 5)
169 		return _FALSE;
170 
171 	pframe += 4;
172 	if ((*pframe) & tdls_ch_swithcing_prohibited_bit)
173 		return _TRUE;
174 
175 	return _FALSE;
176 }
177 
rtw_is_tdls_enabled(_adapter * padapter)178 u8 rtw_is_tdls_enabled(_adapter *padapter)
179 {
180 	return padapter->registrypriv.en_tdls;
181 }
182 
rtw_set_tdls_enable(_adapter * padapter,u8 enable)183 void rtw_set_tdls_enable(_adapter *padapter, u8 enable)
184 {
185 	padapter->registrypriv.en_tdls = enable;
186 	RTW_INFO("%s: en_tdls = %d\n", __func__, rtw_is_tdls_enabled(padapter));
187 }
188 
rtw_enable_tdls_func(_adapter * padapter)189 void rtw_enable_tdls_func(_adapter *padapter)
190 {
191 	if (rtw_is_tdls_enabled(padapter) == _TRUE)
192 		return;
193 	rtw_set_tdls_enable(padapter, _TRUE);
194 }
195 
rtw_disable_tdls_func(_adapter * padapter,u8 enqueue_cmd)196 void rtw_disable_tdls_func(_adapter *padapter, u8 enqueue_cmd)
197 {
198 	if (rtw_is_tdls_enabled(padapter) == _FALSE)
199 		return;
200 
201 	rtw_free_all_tdls_sta(padapter, enqueue_cmd);
202 	rtw_tdls_cmd(padapter, NULL, TDLS_RS_RCR);
203 	rtw_reset_tdls_info(padapter);
204 
205 	rtw_set_tdls_enable(padapter, _FALSE);
206 }
207 
rtw_is_tdls_sta_existed(_adapter * padapter)208 u8 rtw_is_tdls_sta_existed(_adapter *padapter)
209 {
210 	struct sta_priv *pstapriv = &padapter->stapriv;
211 	struct sta_info *psta;
212 	int i = 0;
213 	_list	*plist, *phead;
214 	u8 ret = _FALSE;
215 
216 	if (rtw_is_tdls_enabled(padapter) == _FALSE)
217 		return _FALSE;
218 
219 	_rtw_spinlock_bh(&pstapriv->sta_hash_lock);
220 
221 	for (i = 0; i < NUM_STA; i++) {
222 		phead = &(pstapriv->sta_hash[i]);
223 		plist = get_next(phead);
224 		while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
225 			psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
226 			plist = get_next(plist);
227 			if (psta->tdls_sta_state != TDLS_STATE_NONE) {
228 				ret = _TRUE;
229 				goto Exit;
230 			}
231 		}
232 	}
233 
234 Exit:
235 
236 	_rtw_spinunlock_bh(&pstapriv->sta_hash_lock);
237 
238 	return ret;
239 }
240 
rtw_tdls_is_setup_allowed(_adapter * padapter)241 u8 rtw_tdls_is_setup_allowed(_adapter *padapter)
242 {
243 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
244 
245 	if (is_client_associated_to_ap(padapter) == _FALSE)
246 		return _FALSE;
247 
248 	if (ptdlsinfo->ap_prohibited == _TRUE)
249 		return _FALSE;
250 
251 	return _TRUE;
252 }
253 
254 #ifdef CONFIG_TDLS_CH_SW
rtw_tdls_is_chsw_allowed(_adapter * padapter)255 u8 rtw_tdls_is_chsw_allowed(_adapter *padapter)
256 {
257 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
258 
259 	if (ptdlsinfo->ch_switch_prohibited == _TRUE)
260 		return _FALSE;
261 
262 	if (padapter->registrypriv.wifi_spec == 0)
263 		return _FALSE;
264 
265 	return _TRUE;
266 }
267 #endif
268 
_issue_nulldata_to_TDLS_peer_STA(_adapter * padapter,unsigned char * da,unsigned int power_mode,int wait_ms)269 int _issue_nulldata_to_TDLS_peer_STA(_adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ms)
270 {
271 	int ret = _FAIL;
272 	struct xmit_frame			*pmgntframe;
273 	struct pkt_attrib			*pattrib;
274 	unsigned char					*pframe;
275 	struct rtw_ieee80211_hdr	*pwlanhdr;
276 	unsigned short				*fctrl, *qc;
277 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
278 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
279 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
280 
281 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
282 	if (pmgntframe == NULL)
283 		goto exit;
284 
285 	pattrib = &pmgntframe->attrib;
286 	update_mgntframe_attrib(padapter, pattrib);
287 
288 	pattrib->hdrlen += 2;
289 	pattrib->qos_en = _TRUE;
290 	pattrib->eosp = 1;
291 	pattrib->ack_policy = 0;
292 	pattrib->mdata = 0;
293 	pattrib->retry_ctrl = _FALSE;
294 
295 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
296 
297 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
298 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
299 
300 	fctrl = &(pwlanhdr->frame_ctl);
301 	*(fctrl) = 0;
302 
303 	if (power_mode)
304 		SetPwrMgt(fctrl);
305 
306 	qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
307 
308 	SetPriority(qc, 7);	/* Set priority to VO */
309 
310 	SetEOSP(qc, pattrib->eosp);
311 
312 	SetAckpolicy(qc, pattrib->ack_policy);
313 
314 	_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
315 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
316 	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
317 
318 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
319 	pmlmeext->mgnt_seq++;
320 	set_frame_sub_type(pframe, WIFI_QOS_DATA_NULL);
321 
322 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos);
323 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
324 
325 	pattrib->last_txcmdsz = pattrib->pktlen;
326 
327 	if (wait_ms)
328 		ret = dump_mgntframe_and_wait_ack_timeout(padapter, pmgntframe, wait_ms);
329 	else {
330 		dump_mgntframe(padapter, pmgntframe);
331 		ret = _SUCCESS;
332 	}
333 
334 exit:
335 	return ret;
336 
337 }
338 
339 /*
340  *wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
341  *wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
342  *try_cnt means the maximal TX count to try
343  */
issue_nulldata_to_TDLS_peer_STA(_adapter * padapter,unsigned char * da,unsigned int power_mode,int try_cnt,int wait_ms)344 int issue_nulldata_to_TDLS_peer_STA(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
345 {
346 	int ret;
347 	int i = 0;
348 	systime start = rtw_get_current_time();
349 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
350 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
351 
352 #if 0
353 	psta = rtw_get_stainfo(&padapter->stapriv, da);
354 	if (psta) {
355 		if (power_mode)
356 			rtw_hal_macid_sleep(padapter, psta->phl_sta->macid);
357 		else
358 			rtw_hal_macid_wakeup(padapter, psta->phl_sta->macid);
359 	} else {
360 		RTW_INFO(FUNC_ADPT_FMT ": Can't find sta info for " MAC_FMT ", skip macid %s!!\n",
361 			FUNC_ADPT_ARG(padapter), MAC_ARG(da), power_mode ? "sleep" : "wakeup");
362 		rtw_warn_on(1);
363 	}
364 #endif
365 
366 	do {
367 		ret = _issue_nulldata_to_TDLS_peer_STA(padapter, da, power_mode, wait_ms);
368 
369 		i++;
370 
371 		if (RTW_CANNOT_RUN(adapter_to_dvobj(padapter)))
372 			break;
373 
374 		if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
375 			rtw_msleep_os(wait_ms);
376 
377 	} while ((i < try_cnt) && (ret == _FAIL || wait_ms == 0));
378 
379 	if (ret != _FAIL) {
380 		ret = _SUCCESS;
381 #ifndef DBG_XMIT_ACK
382 		goto exit;
383 #endif
384 	}
385 
386 	if (try_cnt && wait_ms) {
387 		if (da)
388 			RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
389 				FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
390 				ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
391 		else
392 			RTW_INFO(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
393 				FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
394 				ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
395 	}
396 exit:
397 	return ret;
398 }
399 
400 /* TDLS encryption(if needed) will always be CCMP */
rtw_tdls_set_key(_adapter * padapter,struct sta_info * ptdls_sta)401 void rtw_tdls_set_key(_adapter *padapter, struct sta_info *ptdls_sta)
402 {
403 	ptdls_sta->dot118021XPrivacy = _AES_;
404 	rtw_setstakey_cmd(padapter, ptdls_sta, TDLS_KEY, _TRUE);
405 }
406 
407 #ifdef CONFIG_80211N_HT
rtw_tdls_process_ht_cap(_adapter * padapter,struct sta_info * ptdls_sta,u8 * data,u8 Length)408 void rtw_tdls_process_ht_cap(_adapter *padapter, struct sta_info *ptdls_sta, u8 *data, u8 Length)
409 {
410 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
411 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
412 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
413 	struct ht_priv			*phtpriv = &pmlmepriv->htpriv;
414 	u8	max_AMPDU_len, min_MPDU_spacing;
415 	u8	cur_ldpc_cap = 0, cur_stbc_cap = 0, cur_beamform_cap = 0;
416 
417 	/* Save HT capabilities in the sta object */
418 	_rtw_memset(&ptdls_sta->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap));
419 	if (data && Length >= sizeof(struct rtw_ieee80211_ht_cap)) {
420 		ptdls_sta->flags |= WLAN_STA_HT;
421 		ptdls_sta->flags |= WLAN_STA_WME;
422 
423 		_rtw_memcpy(&ptdls_sta->htpriv.ht_cap, data, sizeof(struct rtw_ieee80211_ht_cap));
424 	} else {
425 		ptdls_sta->flags &= ~WLAN_STA_HT;
426 		return;
427 	}
428 
429 	if (ptdls_sta->flags & WLAN_STA_HT) {
430 		if (padapter->registrypriv.ht_enable == _TRUE && is_supported_ht(padapter->registrypriv.wireless_mode) ) {
431 			ptdls_sta->htpriv.ht_option = _TRUE;
432 			ptdls_sta->qos_option = _TRUE;
433 		} else {
434 			ptdls_sta->htpriv.ht_option = _FALSE;
435 			ptdls_sta->qos_option = _FALSE;
436 		}
437 	}
438 
439 	/* HT related cap */
440 	if (ptdls_sta->htpriv.ht_option) {
441 		/* Check if sta supports rx ampdu */
442 		if (padapter->registrypriv.ampdu_enable == 1)
443 			ptdls_sta->htpriv.ampdu_enable = _TRUE;
444 
445 		/* AMPDU Parameters field */
446 		/* Get MIN of MAX AMPDU Length Exp */
447 		if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3) > (data[2] & 0x3))
448 			max_AMPDU_len = (data[2] & 0x3);
449 		else
450 			max_AMPDU_len = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3);
451 		/* Get MAX of MIN MPDU Start Spacing */
452 		if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) > (data[2] & 0x1c))
453 			min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c);
454 		else
455 			min_MPDU_spacing = (data[2] & 0x1c);
456 		ptdls_sta->htpriv.rx_ampdu_min_spacing = max_AMPDU_len | min_MPDU_spacing;
457 
458 		/* Check if sta support s Short GI 20M */
459 		if ((phtpriv->sgi_20m == _TRUE) && (ptdls_sta->htpriv.ht_cap.cap_info & cpu_to_le16(IEEE80211_HT_CAP_SGI_20)))
460 			ptdls_sta->htpriv.sgi_20m = _TRUE;
461 
462 		/* Check if sta support s Short GI 40M */
463 		if ((phtpriv->sgi_40m == _TRUE) && (ptdls_sta->htpriv.ht_cap.cap_info & cpu_to_le16(IEEE80211_HT_CAP_SGI_40)))
464 			ptdls_sta->htpriv.sgi_40m = _TRUE;
465 
466 		/* Bwmode would still followed AP's setting */
467 		if (ptdls_sta->htpriv.ht_cap.cap_info & cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH)) {
468 			if (padapter->mlmeextpriv.chandef.bw >= CHANNEL_WIDTH_40)
469 				ptdls_sta->phl_sta->chandef.bw = CHANNEL_WIDTH_40;
470 			ptdls_sta->htpriv.ch_offset = padapter->mlmeextpriv.chandef.offset;
471 		}
472 
473 		/* Config LDPC Coding Capability */
474 		if (TEST_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_TX) && GET_HT_CAP_ELE_LDPC_CAP(data)) {
475 			SET_FLAG(cur_ldpc_cap, (LDPC_HT_ENABLE_TX | LDPC_HT_CAP_TX));
476 			RTW_INFO("Enable HT Tx LDPC!\n");
477 		}
478 		ptdls_sta->htpriv.ldpc_cap = cur_ldpc_cap;
479 
480 		/* Config STBC setting */
481 		if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX) && GET_HT_CAP_ELE_RX_STBC(data)) {
482 			SET_FLAG(cur_stbc_cap, (STBC_HT_ENABLE_TX | STBC_HT_CAP_TX));
483 			RTW_INFO("Enable HT Tx STBC!\n");
484 		}
485 		ptdls_sta->htpriv.stbc_cap = cur_stbc_cap;
486 
487 #ifdef CONFIG_BEAMFORMING
488 		/* Config Tx beamforming setting */
489 		if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE) &&
490 		    GET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(data))
491 			SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE);
492 
493 		if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE) &&
494 		    GET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(data))
495 			SET_FLAG(cur_beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE);
496 		ptdls_sta->htpriv.beamform_cap = cur_beamform_cap;
497 		if (cur_beamform_cap)
498 			RTW_INFO("Client HT Beamforming Cap = 0x%02X\n", cur_beamform_cap);
499 #endif /* CONFIG_BEAMFORMING */
500 	}
501 
502 }
503 
rtw_tdls_set_ht_cap(_adapter * padapter,u8 * pframe,struct pkt_attrib * pattrib)504 u8 *rtw_tdls_set_ht_cap(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib)
505 {
506 	rtw_ht_use_default_setting(padapter);
507 
508 	if (padapter->registrypriv.wifi_spec == 1) {
509 		padapter->mlmepriv.htpriv.sgi_20m = _FALSE;
510 		padapter->mlmepriv.htpriv.sgi_40m = _FALSE;
511 	}
512 
513 	rtw_restructure_ht_ie(padapter, NULL, pframe, 0, &(pattrib->pktlen), padapter->mlmeextpriv.chandef.chan, NULL);
514 
515 	return pframe + pattrib->pktlen;
516 }
517 #endif
518 
519 #ifdef CONFIG_80211AC_VHT
rtw_tdls_process_vht_cap(_adapter * padapter,struct sta_info * ptdls_sta,u8 * data,u8 Length)520 void rtw_tdls_process_vht_cap(_adapter *padapter, struct sta_info *ptdls_sta, u8 *data, u8 Length)
521 {
522 	struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
523 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
524 	struct vht_priv			*pvhtpriv = &pmlmepriv->vhtpriv;
525 	u8	cur_ldpc_cap = 0, cur_stbc_cap = 0, tx_nss = 0;
526 	u16 cur_beamform_cap = 0;
527 	u8	*pcap_mcs;
528 
529 	_rtw_memset(&ptdls_sta->vhtpriv, 0, sizeof(struct vht_priv));
530 	if (data && Length == 12) {
531 		ptdls_sta->flags |= WLAN_STA_VHT;
532 
533 		_rtw_memcpy(ptdls_sta->vhtpriv.vht_cap, data, 12);
534 
535 #if 0
536 		if (elems.vht_op_mode_notify && elems.vht_op_mode_notify_len == 1)
537 			_rtw_memcpy(&pstat->vhtpriv.vht_op_mode_notify, elems.vht_op_mode_notify, 1);
538 		else /* for Frame without Operating Mode notify ie; default: 80M */
539 			pstat->vhtpriv.vht_op_mode_notify = CHANNEL_WIDTH_80;
540 #else
541 		ptdls_sta->vhtpriv.vht_op_mode_notify = CHANNEL_WIDTH_80;
542 #endif
543 	} else {
544 		ptdls_sta->flags &= ~WLAN_STA_VHT;
545 		return;
546 	}
547 
548 	if (ptdls_sta->flags & WLAN_STA_VHT) {
549 		if (REGSTY_IS_11AC_ENABLE(&padapter->registrypriv)
550 		    && is_supported_vht(padapter->registrypriv.wireless_mode)
551 		    && RFCTL_REG_EN_11AC(rfctl)
552 		) {
553 			ptdls_sta->vhtpriv.vht_option = _TRUE;
554 			/* ToDo: need to API to inform hal_sta->ra_info.is_vht_enable  */
555 			#if 0
556 			ptdls_sta->phl_sta->ra_info.is_vht_enable = _TRUE;
557 			#endif
558 		}
559 		else
560 			ptdls_sta->vhtpriv.vht_option = _FALSE;
561 	}
562 
563 	/* B4 Rx LDPC */
564 	if (TEST_FLAG(pvhtpriv->ldpc_cap, LDPC_VHT_ENABLE_TX) &&
565 	    GET_VHT_CAPABILITY_ELE_RX_LDPC(data)) {
566 		SET_FLAG(cur_ldpc_cap, (LDPC_VHT_ENABLE_TX | LDPC_VHT_CAP_TX));
567 		RTW_INFO("Current VHT LDPC Setting = %02X\n", cur_ldpc_cap);
568 	}
569 	ptdls_sta->vhtpriv.ldpc_cap = cur_ldpc_cap;
570 
571 	/* B5 Short GI for 80 MHz */
572 	ptdls_sta->vhtpriv.sgi_80m = (GET_VHT_CAPABILITY_ELE_SHORT_GI80M(data) & pvhtpriv->sgi_80m) ? _TRUE : _FALSE;
573 
574 	/* B8 B9 B10 Rx STBC */
575 	if (TEST_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_TX) &&
576 	    GET_VHT_CAPABILITY_ELE_RX_STBC(data)) {
577 		SET_FLAG(cur_stbc_cap, (STBC_VHT_ENABLE_TX | STBC_VHT_CAP_TX));
578 		RTW_INFO("Current VHT STBC Setting = %02X\n", cur_stbc_cap);
579 	}
580 	ptdls_sta->vhtpriv.stbc_cap = cur_stbc_cap;
581 
582 	#ifdef CONFIG_BEAMFORMING
583 	/* B11 SU Beamformer Capable, the target supports Beamformer and we are Beamformee */
584 	if (TEST_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE) &&
585 	    GET_VHT_CAPABILITY_ELE_SU_BFEE(data))
586 		SET_FLAG(cur_beamform_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE);
587 
588 	/* B12 SU Beamformee Capable, the target supports Beamformee and we are Beamformer */
589 	if (TEST_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE) &&
590 	    GET_VHT_CAPABILITY_ELE_SU_BFER(data))
591 		SET_FLAG(cur_beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE);
592 	ptdls_sta->vhtpriv.beamform_cap = cur_beamform_cap;
593 	/* ToDo: need to API to inform hal_sta->bf_info.vht_beamform_cap  */
594 	#if 0
595 	ptdls_sta->phl_sta->bf_info.vht_beamform_cap = cur_beamform_cap;
596 	#endif
597 	if (cur_beamform_cap)
598 		RTW_INFO("Current VHT Beamforming Setting = %02X\n", cur_beamform_cap);
599 	#endif /*CONFIG_BEAMFORMING*/
600 
601 	/* B23 B24 B25 Maximum A-MPDU Length Exponent */
602 	ptdls_sta->vhtpriv.ampdu_len = GET_VHT_CAPABILITY_ELE_MAX_RXAMPDU_FACTOR(data);
603 
604 	pcap_mcs = GET_VHT_CAPABILITY_ELE_RX_MCS(data);
605 	tx_nss = get_phy_tx_nss(adapter);
606 	rtw_vht_nss_to_mcsmap(tx_nss, ptdls_sta->vhtpriv.vht_mcs_map, pcap_mcs);
607 	ptdls_sta->vhtpriv.vht_highest_rate = rtw_get_vht_highest_rate(ptdls_sta->vhtpriv.vht_mcs_map);
608 }
609 
rtw_tdls_process_vht_operation(_adapter * padapter,struct sta_info * ptdls_sta,u8 * data,u8 Length)610 void rtw_tdls_process_vht_operation(_adapter *padapter, struct sta_info *ptdls_sta, u8 *data, u8 Length)
611 {
612 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
613 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
614 	struct registry_priv *regsty = adapter_to_regsty(padapter);
615 	u8 operation_bw = 0;
616 
617 	if (GET_VHT_OPERATION_ELE_CHL_WIDTH(data) >= 1) {
618 
619 		operation_bw = CHANNEL_WIDTH_80;
620 
621 		if (rtw_hw_is_bw_support(adapter_to_dvobj(padapter), operation_bw) && REGSTY_IS_BW_5G_SUPPORT(regsty, operation_bw)
622 			&& (operation_bw <= pmlmeext->chandef.bw))
623 			ptdls_sta->phl_sta->chandef.bw = operation_bw;
624 		else
625 			ptdls_sta->phl_sta->chandef.bw = pmlmeext->chandef.bw;
626 	} else
627 		ptdls_sta->phl_sta->chandef.bw = pmlmeext->chandef.bw;
628 }
629 
rtw_tdls_process_vht_op_mode_notify(_adapter * padapter,struct sta_info * ptdls_sta,u8 * data,u8 Length)630 void rtw_tdls_process_vht_op_mode_notify(_adapter *padapter, struct sta_info *ptdls_sta, u8 *data, u8 Length)
631 {
632 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
633 	struct vht_priv		*pvhtpriv = &pmlmepriv->vhtpriv;
634 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
635 	struct registry_priv *regsty = adapter_to_regsty(padapter);
636 	u8	target_bw;
637 	u8	target_rxss, current_rxss;
638 
639 	if (pvhtpriv->vht_option == _FALSE)
640 		return;
641 
642 	target_bw = GET_VHT_OPERATING_MODE_FIELD_CHNL_WIDTH(data);
643 	target_rxss = (GET_VHT_OPERATING_MODE_FIELD_RX_NSS(data) + 1);
644 
645 	if (rtw_hw_is_bw_support(adapter_to_dvobj(padapter), target_bw) && REGSTY_IS_BW_5G_SUPPORT(regsty, target_bw)
646 		&& (target_bw <= pmlmeext->chandef.bw))
647 		ptdls_sta->phl_sta->chandef.bw = target_bw;
648 	else
649 		ptdls_sta->phl_sta->chandef.bw = pmlmeext->chandef.bw;
650 
651 	current_rxss = rtw_vht_mcsmap_to_nss(ptdls_sta->vhtpriv.vht_mcs_map);
652 	if (target_rxss != current_rxss) {
653 		u8	vht_mcs_map[2] = {};
654 
655 		rtw_vht_nss_to_mcsmap(target_rxss, vht_mcs_map, ptdls_sta->vhtpriv.vht_mcs_map);
656 		_rtw_memcpy(ptdls_sta->vhtpriv.vht_mcs_map, vht_mcs_map, 2);
657 	}
658 }
659 
rtw_tdls_set_aid(_adapter * padapter,u8 * pframe,struct pkt_attrib * pattrib)660 u8 *rtw_tdls_set_aid(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib)
661 {
662 	return rtw_set_ie(pframe, EID_AID, 2, (u8 *)&(padapter->mlmepriv.cur_network.aid), &(pattrib->pktlen));
663 }
664 
rtw_tdls_set_vht_cap(_adapter * padapter,u8 * pframe,struct pkt_attrib * pattrib)665 u8 *rtw_tdls_set_vht_cap(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib)
666 {
667 	u32 ie_len = 0;
668 
669 	rtw_vht_get_real_setting(padapter);
670 
671 	ie_len = rtw_build_vht_cap_ie(padapter, pframe);
672 	pattrib->pktlen += ie_len;
673 
674 	return pframe + ie_len;
675 }
676 
rtw_tdls_set_vht_operation(_adapter * padapter,u8 * pframe,struct pkt_attrib * pattrib,u8 channel)677 u8 *rtw_tdls_set_vht_operation(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib, u8 channel)
678 {
679 	u32 ie_len = 0;
680 
681 	ie_len = rtw_build_vht_operation_ie(padapter, pframe, channel);
682 	pattrib->pktlen += ie_len;
683 
684 	return pframe + ie_len;
685 }
686 
rtw_tdls_set_vht_op_mode_notify(_adapter * padapter,u8 * pframe,struct pkt_attrib * pattrib,u8 bw)687 u8 *rtw_tdls_set_vht_op_mode_notify(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib, u8 bw)
688 {
689 	u32 ie_len = 0;
690 
691 	ie_len = rtw_build_vht_op_mode_notify_ie(padapter, pframe, bw);
692 	pattrib->pktlen += ie_len;
693 
694 	return pframe + ie_len;
695 }
696 #endif
697 
698 
rtw_tdls_set_sup_ch(_adapter * adapter,u8 * pframe,struct pkt_attrib * pattrib)699 u8 *rtw_tdls_set_sup_ch(_adapter *adapter, u8 *pframe, struct pkt_attrib *pattrib)
700 {
701 	struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
702 	u8 sup_ch[30 * 2] = {0x00}, ch_set_idx = 0, sup_ch_idx = 2;
703 
704 	while (ch_set_idx < rfctl->max_chan_nums && rfctl->channel_set[ch_set_idx].ChannelNum != 0) {
705 		if (rfctl->channel_set[ch_set_idx].ChannelNum <= 14) {
706 			/* TODO: fix 2.4G supported channel when channel doesn't start from 1 and continuous */
707 			sup_ch[0] = 1;	/* First channel number */
708 			sup_ch[1] = rfctl->channel_set[ch_set_idx].ChannelNum;	/* Number of channel */
709 		} else {
710 			sup_ch[sup_ch_idx++] = rfctl->channel_set[ch_set_idx].ChannelNum;
711 			sup_ch[sup_ch_idx++] = 1;
712 		}
713 		ch_set_idx++;
714 	}
715 
716 	return rtw_set_ie(pframe, _SUPPORTED_CH_IE_, sup_ch_idx, sup_ch, &(pattrib->pktlen));
717 }
718 
rtw_tdls_set_rsnie(struct tdls_txmgmt * ptxmgmt,u8 * pframe,struct pkt_attrib * pattrib,int init,struct sta_info * ptdls_sta)719 u8 *rtw_tdls_set_rsnie(struct tdls_txmgmt *ptxmgmt, u8 *pframe, struct pkt_attrib *pattrib,  int init, struct sta_info *ptdls_sta)
720 {
721 	u8 *p = NULL;
722 	int len = 0;
723 
724 	if (ptxmgmt->len > 0)
725 		p = rtw_get_ie(ptxmgmt->buf, _RSN_IE_2_, &len, ptxmgmt->len);
726 
727 	if (p != NULL)
728 		return rtw_set_ie(pframe, _RSN_IE_2_, len, p + 2, &(pattrib->pktlen));
729 	else if (init == _TRUE)
730 		return rtw_set_ie(pframe, _RSN_IE_2_, sizeof(TDLS_RSNIE), TDLS_RSNIE, &(pattrib->pktlen));
731 	else
732 		return rtw_set_ie(pframe, _RSN_IE_2_, sizeof(ptdls_sta->TDLS_RSNIE), ptdls_sta->TDLS_RSNIE, &(pattrib->pktlen));
733 }
734 
rtw_tdls_set_ext_cap(u8 * pframe,struct pkt_attrib * pattrib)735 u8 *rtw_tdls_set_ext_cap(u8 *pframe, struct pkt_attrib *pattrib)
736 {
737 	return rtw_set_ie(pframe, WLAN_EID_EXT_CAP , sizeof(TDLS_EXT_CAPIE), TDLS_EXT_CAPIE, &(pattrib->pktlen));
738 }
739 
rtw_tdls_set_qos_cap(u8 * pframe,struct pkt_attrib * pattrib)740 u8 *rtw_tdls_set_qos_cap(u8 *pframe, struct pkt_attrib *pattrib)
741 {
742 	return rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(TDLS_WMMIE), TDLS_WMMIE,  &(pattrib->pktlen));
743 }
744 
rtw_tdls_set_ftie(struct tdls_txmgmt * ptxmgmt,u8 * pframe,struct pkt_attrib * pattrib,u8 * ANonce,u8 * SNonce)745 u8 *rtw_tdls_set_ftie(struct tdls_txmgmt *ptxmgmt, u8 *pframe, struct pkt_attrib *pattrib, u8 *ANonce, u8 *SNonce)
746 {
747 	struct wpa_tdls_ftie FTIE = {0};
748 	u8 *p = NULL;
749 	int len = 0;
750 
751 	if (ptxmgmt->len > 0)
752 		p = rtw_get_ie(ptxmgmt->buf, _FTIE_, &len, ptxmgmt->len);
753 
754 	if (p != NULL)
755 		return rtw_set_ie(pframe, _FTIE_, len, p + 2, &(pattrib->pktlen));
756 	else {
757 		if (ANonce != NULL)
758 			_rtw_memcpy(FTIE.Anonce, ANonce, WPA_NONCE_LEN);
759 		if (SNonce != NULL)
760 			_rtw_memcpy(FTIE.Snonce, SNonce, WPA_NONCE_LEN);
761 
762 		return rtw_set_ie(pframe, _FTIE_, TDLS_FTIE_DATA_LEN,
763 						  (u8 *)FTIE.data, &(pattrib->pktlen));
764 	}
765 }
766 
rtw_tdls_set_timeout_interval(struct tdls_txmgmt * ptxmgmt,u8 * pframe,struct pkt_attrib * pattrib,int init,struct sta_info * ptdls_sta)767 u8 *rtw_tdls_set_timeout_interval(struct tdls_txmgmt *ptxmgmt, u8 *pframe, struct pkt_attrib *pattrib, int init, struct sta_info *ptdls_sta)
768 {
769 	u8 timeout_itvl[5];	/* set timeout interval to maximum value */
770 	u32 timeout_interval = TDLS_TPK_RESEND_COUNT;
771 	u8 *p = NULL;
772 	int len = 0;
773 
774 	if (ptxmgmt->len > 0)
775 		p = rtw_get_ie(ptxmgmt->buf, _TIMEOUT_ITVL_IE_, &len, ptxmgmt->len);
776 
777 	if (p != NULL)
778 		return rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, len, p + 2, &(pattrib->pktlen));
779 	else {
780 		/* Timeout interval */
781 		timeout_itvl[0] = 0x02;
782 		if (init == _TRUE)
783 			_rtw_memcpy(timeout_itvl + 1, &timeout_interval, 4);
784 		else
785 			_rtw_memcpy(timeout_itvl + 1, (u8 *)(&ptdls_sta->TDLS_PeerKey_Lifetime), 4);
786 
787 		return rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
788 	}
789 }
790 
rtw_tdls_set_bss_coexist(_adapter * padapter,u8 * pframe,struct pkt_attrib * pattrib)791 u8 *rtw_tdls_set_bss_coexist(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib)
792 {
793 	u8 iedata = 0;
794 
795 	if (padapter->mlmepriv.num_FortyMHzIntolerant > 0)
796 		iedata |= BIT(2);	/* 20 MHz BSS Width Request */
797 
798 	/* Information Bit should be set by TDLS test plan 5.9 */
799 	iedata |= BIT(0);
800 	return rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
801 }
802 
rtw_tdls_set_payload_type(u8 * pframe,struct pkt_attrib * pattrib)803 u8 *rtw_tdls_set_payload_type(u8 *pframe, struct pkt_attrib *pattrib)
804 {
805 	u8 payload_type = 0x02;
806 	return rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
807 }
808 
rtw_tdls_set_category(u8 * pframe,struct pkt_attrib * pattrib,u8 category)809 u8 *rtw_tdls_set_category(u8 *pframe, struct pkt_attrib *pattrib, u8 category)
810 {
811 	return rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
812 }
813 
rtw_tdls_set_action(u8 * pframe,struct pkt_attrib * pattrib,struct tdls_txmgmt * ptxmgmt)814 u8 *rtw_tdls_set_action(u8 *pframe, struct pkt_attrib *pattrib, struct tdls_txmgmt *ptxmgmt)
815 {
816 	return rtw_set_fixed_ie(pframe, 1, &(ptxmgmt->action_code), &(pattrib->pktlen));
817 }
818 
rtw_tdls_set_status_code(u8 * pframe,struct pkt_attrib * pattrib,struct tdls_txmgmt * ptxmgmt)819 u8 *rtw_tdls_set_status_code(u8 *pframe, struct pkt_attrib *pattrib, struct tdls_txmgmt *ptxmgmt)
820 {
821 	return rtw_set_fixed_ie(pframe, 2, (u8 *)&(ptxmgmt->status_code), &(pattrib->pktlen));
822 }
823 
rtw_tdls_set_dialog(u8 * pframe,struct pkt_attrib * pattrib,struct tdls_txmgmt * ptxmgmt)824 u8 *rtw_tdls_set_dialog(u8 *pframe, struct pkt_attrib *pattrib, struct tdls_txmgmt *ptxmgmt)
825 {
826 	u8 dialogtoken = 1;
827 	if (ptxmgmt->dialog_token)
828 		return rtw_set_fixed_ie(pframe, 1, &(ptxmgmt->dialog_token), &(pattrib->pktlen));
829 	else
830 		return rtw_set_fixed_ie(pframe, 1, &(dialogtoken), &(pattrib->pktlen));
831 }
832 
rtw_tdls_set_reg_class(u8 * pframe,struct pkt_attrib * pattrib,struct sta_info * ptdls_sta)833 u8 *rtw_tdls_set_reg_class(u8 *pframe, struct pkt_attrib *pattrib, struct sta_info *ptdls_sta)
834 {
835 	u8 reg_class = 22;
836 	return rtw_set_fixed_ie(pframe, 1, &(reg_class), &(pattrib->pktlen));
837 }
838 
rtw_tdls_set_second_channel_offset(u8 * pframe,struct pkt_attrib * pattrib,u8 ch_offset)839 u8 *rtw_tdls_set_second_channel_offset(u8 *pframe, struct pkt_attrib *pattrib, u8 ch_offset)
840 {
841 	return rtw_set_ie(pframe, EID_SecondaryChnlOffset , 1, &ch_offset, &(pattrib->pktlen));
842 }
843 
rtw_tdls_set_capability(_adapter * padapter,u8 * pframe,struct pkt_attrib * pattrib)844 u8 *rtw_tdls_set_capability(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib)
845 {
846 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
847 	struct mlme_ext_info	*pmlmeinfo = &pmlmeext->mlmext_info;
848 	u8 cap_from_ie[2] = {0};
849 
850 	_rtw_memcpy(cap_from_ie, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
851 
852 	return rtw_set_fixed_ie(pframe, 2, cap_from_ie, &(pattrib->pktlen));
853 }
854 
rtw_tdls_set_supported_rate(_adapter * padapter,u8 * pframe,struct pkt_attrib * pattrib)855 u8 *rtw_tdls_set_supported_rate(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib)
856 {
857 	u8 bssrate[NDIS_802_11_LENGTH_RATES_EX];
858 	int bssrate_len = 0;
859 	u8 more_supportedrates = 0;
860 
861 	rtw_set_supported_rate(bssrate,
862 		(padapter->registrypriv.wireless_mode == WIRELESS_MODE_MAX) ? padapter->mlmeextpriv.cur_wireless_mode : padapter->registrypriv.wireless_mode,
863 			GET_WIFI_ROLE_CURRENT_CH(padapter));
864 	bssrate_len = rtw_get_rateset_len(bssrate);
865 
866 	if (bssrate_len > 8) {
867 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
868 		more_supportedrates = 1;
869 	} else
870 		pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
871 
872 	/* extended supported rates */
873 	if (more_supportedrates == 1)
874 		pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
875 
876 	return pframe;
877 }
878 
rtw_tdls_set_sup_reg_class(u8 * pframe,struct pkt_attrib * pattrib)879 u8 *rtw_tdls_set_sup_reg_class(u8 *pframe, struct pkt_attrib *pattrib)
880 {
881 	return rtw_set_ie(pframe, _SRC_IE_ , sizeof(TDLS_SRC), TDLS_SRC, &(pattrib->pktlen));
882 }
883 
rtw_tdls_set_linkid(_adapter * padapter,u8 * pframe,struct pkt_attrib * pattrib,u8 init)884 u8 *rtw_tdls_set_linkid(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib, u8 init)
885 {
886 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
887 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
888 
889 	u8 link_id_addr[18] = {0};
890 
891 	_rtw_memcpy(link_id_addr, get_my_bssid(&(pmlmeinfo->network)), 6);
892 
893 	if (init == _TRUE) {
894 		_rtw_memcpy((link_id_addr + 6), pattrib->src, 6);
895 		_rtw_memcpy((link_id_addr + 12), pattrib->dst, 6);
896 	} else {
897 		_rtw_memcpy((link_id_addr + 6), pattrib->dst, 6);
898 		_rtw_memcpy((link_id_addr + 12), pattrib->src, 6);
899 	}
900 	return rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
901 }
902 
903 #ifdef CONFIG_TDLS_CH_SW
rtw_tdls_set_target_ch(_adapter * padapter,u8 * pframe,struct pkt_attrib * pattrib)904 u8 *rtw_tdls_set_target_ch(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib)
905 {
906 	u8 target_ch = 1;
907 	if (padapter->tdlsinfo.chsw_info.off_ch_num)
908 		return rtw_set_fixed_ie(pframe, 1, &(padapter->tdlsinfo.chsw_info.off_ch_num), &(pattrib->pktlen));
909 	else
910 		return rtw_set_fixed_ie(pframe, 1, &(target_ch), &(pattrib->pktlen));
911 }
912 
rtw_tdls_set_ch_sw(u8 * pframe,struct pkt_attrib * pattrib,struct sta_info * ptdls_sta)913 u8 *rtw_tdls_set_ch_sw(u8 *pframe, struct pkt_attrib *pattrib, struct sta_info *ptdls_sta)
914 {
915 	u8 ch_switch_timing[4] = {0};
916 	u16 switch_time = (ptdls_sta->ch_switch_time >= TDLS_CH_SWITCH_TIME * 1000) ?
917 			  ptdls_sta->ch_switch_time : TDLS_CH_SWITCH_TIME;
918 	u16 switch_timeout = (ptdls_sta->ch_switch_timeout >= TDLS_CH_SWITCH_TIMEOUT * 1000) ?
919 		     ptdls_sta->ch_switch_timeout : TDLS_CH_SWITCH_TIMEOUT;
920 
921 	_rtw_memcpy(ch_switch_timing, &switch_time, 2);
922 	_rtw_memcpy(ch_switch_timing + 2, &switch_timeout, 2);
923 
924 	return rtw_set_ie(pframe, _CH_SWITCH_TIMING_,  4, ch_switch_timing, &(pattrib->pktlen));
925 }
926 
rtw_tdls_set_ch_sw_oper_control(_adapter * padapter,u8 enable)927 void rtw_tdls_set_ch_sw_oper_control(_adapter *padapter, u8 enable)
928 {
929 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
930 	struct rtw_phl_com_t *phl_com = GET_PHL_COM(dvobj);
931 
932 	if (enable == _TRUE) {
933 #ifdef CONFIG_TDLS_CH_SW_V2
934 		phl_com->ch_switch_offload = _TRUE;
935 #endif
936 
937 #ifdef CONFIG_TDLS_CH_SW_BY_DRV
938 		phl_com->ch_switch_offload = _FALSE;
939 #endif
940 	}
941 	else
942 		phl_com->ch_switch_offload = _FALSE;
943 
944 	if (ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on) != enable)
945 		ATOMIC_SET(&padapter->tdlsinfo.chsw_info.chsw_on, enable);
946 
947 	rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_BCN_EARLY_C2H_RPT, &enable);
948 	RTW_INFO("[TDLS] %s Bcn Early C2H Report\n", (enable == _TRUE) ? "Start" : "Stop");
949 }
950 
rtw_tdls_ch_sw_back_to_base_chnl(_adapter * padapter)951 void rtw_tdls_ch_sw_back_to_base_chnl(_adapter *padapter)
952 {
953 	struct mlme_priv *pmlmepriv;
954 	struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
955 
956 	pmlmepriv = &padapter->mlmepriv;
957 
958 	if ((ATOMIC_READ(&pchsw_info->chsw_on) == _TRUE) &&
959 	    (padapter->mlmeextpriv.chandef.chan != rtw_get_oper_ch(padapter)))
960 		rtw_tdls_cmd(padapter, pchsw_info->addr, TDLS_CH_SW_TO_BASE_CHNL_UNSOLICITED);
961 }
962 
rtw_tdls_chsw_oper_init(_adapter * padapter,u32 timeout_ms)963 static void rtw_tdls_chsw_oper_init(_adapter *padapter, u32 timeout_ms)
964 {
965 	struct submit_ctx	*chsw_sctx = &padapter->tdlsinfo.chsw_info.chsw_sctx;
966 
967 	rtw_sctx_init(chsw_sctx, timeout_ms);
968 }
969 
rtw_tdls_chsw_oper_wait(_adapter * padapter)970 static int rtw_tdls_chsw_oper_wait(_adapter *padapter)
971 {
972 	struct submit_ctx	*chsw_sctx = &padapter->tdlsinfo.chsw_info.chsw_sctx;
973 
974 	return rtw_sctx_wait(chsw_sctx, __func__);
975 }
976 
rtw_tdls_chsw_oper_done(_adapter * padapter)977 void rtw_tdls_chsw_oper_done(_adapter *padapter)
978 {
979 	struct submit_ctx	*chsw_sctx = &padapter->tdlsinfo.chsw_info.chsw_sctx;
980 
981 	rtw_sctx_done(&chsw_sctx);
982 }
983 
rtw_tdls_do_ch_sw(_adapter * padapter,struct sta_info * ptdls_sta,u8 chnl_type,u8 channel,u8 channel_offset,u16 bwmode,u16 ch_switch_time)984 s32 rtw_tdls_do_ch_sw(_adapter *padapter, struct sta_info *ptdls_sta, u8 chnl_type, u8 channel, u8 channel_offset, u16 bwmode, u16 ch_switch_time)
985 {
986 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
987 	u8 center_ch, chnl_offset80 = CHAN_OFFSET_NO_EXT;
988 	u32 ch_sw_time_start, ch_sw_time_spent, wait_time;
989 	u8 take_care_iqk;
990 	s32 ret = _FAIL;
991 
992 	ch_sw_time_start = rtw_systime_to_ms(rtw_get_current_time());
993 
994 	/* set mac_id sleep before channel switch */
995 	rtw_hal_macid_sleep(padapter, ptdls_sta->phl_sta->macid);
996 
997 #if defined(CONFIG_TDLS_CH_SW_BY_DRV) || defined(CONFIG_TDLS_CH_SW_V2)
998 	set_channel_bwmode(padapter, channel, channel_offset, bwmode, _FALSE);
999 	ret = _SUCCESS;
1000 #else
1001 	rtw_tdls_chsw_oper_init(padapter, TDLS_CH_SWITCH_OPER_OFFLOAD_TIMEOUT);
1002 
1003 #if 0 /*GEORGIA_TODO_FIXIT*/
1004 
1005 	/* channel switch IOs offload to FW */
1006 	if (rtw_hal_ch_sw_oper_offload(padapter, channel, channel_offset, bwmode) == _SUCCESS) {
1007 		if (rtw_tdls_chsw_oper_wait(padapter) == _SUCCESS) {
1008 			/* set channel and bw related variables in driver */
1009 			_rtw_mutex_lock_interruptible(&(dvobj->setch_mutex));
1010 
1011 			rtw_set_oper_ch(padapter, channel);
1012 			rtw_set_oper_choffset(padapter, channel_offset);
1013 			rtw_set_oper_bw(padapter, bwmode);
1014 
1015 			center_ch = rtw_phl_get_center_ch(channel, bwmode, channel_offset);
1016 			pHalData->current_channel = center_ch;
1017 			pHalData->CurrentCenterFrequencyIndex1 = center_ch;
1018 			pHalData->current_channel_bw = bwmode;
1019 			pHalData->nCur40MhzPrimeSC = channel_offset;
1020 
1021 			if (bwmode == CHANNEL_WIDTH_80) {
1022 				if (center_ch > channel)
1023 					chnl_offset80 = CHAN_OFFSET_UPPER;
1024 				else if (center_ch < channel)
1025 					chnl_offset80 = CHAN_OFFSET_LOWER;
1026 				else
1027 					chnl_offset80 = CHAN_OFFSET_NO_EXT;
1028 			}
1029 			pHalData->nCur80MhzPrimeSC = chnl_offset80;
1030 
1031 			pHalData->CurrentCenterFrequencyIndex1 = center_ch;
1032 
1033 			_rtw_mutex_unlock(&(dvobj->setch_mutex));
1034 
1035 			rtw_hal_get_hwreg(padapter, HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO, &take_care_iqk);
1036 			if (take_care_iqk == _TRUE)
1037 				rtw_hal_ch_sw_iqk_info_restore(padapter, CH_SW_USE_CASE_TDLS);
1038 
1039 			ret = _SUCCESS;
1040 		} else
1041 			RTW_INFO("[TDLS] chsw oper wait fail !!\n");
1042 	}
1043 #endif
1044 #endif
1045 
1046 	if (ret == _SUCCESS) {
1047 		ch_sw_time_spent = rtw_systime_to_ms(rtw_get_current_time()) - ch_sw_time_start;
1048 		if (chnl_type == TDLS_CH_SW_OFF_CHNL) {
1049 			if ((u32)ch_switch_time / 1000 > ch_sw_time_spent)
1050 				wait_time = (u32)ch_switch_time / 1000 - ch_sw_time_spent;
1051 			else
1052 				wait_time = 0;
1053 
1054 			if (wait_time > 0)
1055 				rtw_msleep_os(wait_time);
1056 		}
1057 	}
1058 
1059 	/* set mac_id wakeup after channel switch */
1060 	rtw_hal_macid_wakeup(padapter, ptdls_sta->phl_sta->macid);
1061 
1062 	return ret;
1063 }
1064 #endif
1065 
rtw_tdls_set_wmm_params(_adapter * padapter,u8 * pframe,struct pkt_attrib * pattrib)1066 u8 *rtw_tdls_set_wmm_params(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib)
1067 {
1068 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
1069 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
1070 	u8 wmm_param_ele[24] = {0};
1071 
1072 	if (&pmlmeinfo->WMM_param) {
1073 		_rtw_memcpy(wmm_param_ele, WMM_PARA_OUI, 6);
1074 		if (_rtw_memcmp(&pmlmeinfo->WMM_param, &wmm_param_ele[6], 18) == _TRUE)
1075 			/* Use default WMM Param */
1076 			_rtw_memcpy(wmm_param_ele + 6, (u8 *)&TDLS_WMM_PARAM_IE, sizeof(TDLS_WMM_PARAM_IE));
1077 		else
1078 			_rtw_memcpy(wmm_param_ele + 6, (u8 *)&pmlmeinfo->WMM_param, sizeof(pmlmeinfo->WMM_param));
1079 		return rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_,  24, wmm_param_ele, &(pattrib->pktlen));
1080 	} else
1081 		return pframe;
1082 }
1083 
1084 #ifdef CONFIG_WFD
rtw_tdls_process_wfd_ie(struct tdls_info * ptdlsinfo,u8 * ptr,u8 length)1085 void rtw_tdls_process_wfd_ie(struct tdls_info *ptdlsinfo, u8 *ptr, u8 length)
1086 {
1087 	u8 *wfd_ie;
1088 	u32 wfd_ielen = 0;
1089 	_adapter *adapter = tdls_info_to_adapter(ptdlsinfo);
1090 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1091 
1092 	if (!rtw_hw_chk_wl_func(dvobj, WL_FUNC_MIRACAST))
1093 		return;
1094 
1095 	/* Try to get the TCP port information when receiving the negotiation response. */
1096 
1097 	wfd_ie = rtw_get_wfd_ie(ptr, length, NULL, &wfd_ielen);
1098 	while (wfd_ie) {
1099 		u8 *attr_content;
1100 		u32	attr_contentlen = 0;
1101 		int	i;
1102 
1103 		RTW_INFO("[%s] WFD IE Found!!\n", __FUNCTION__);
1104 		attr_content = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &attr_contentlen);
1105 		if (attr_content && attr_contentlen) {
1106 			ptdlsinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16(attr_content + 2);
1107 			RTW_INFO("[%s] Peer PORT NUM = %d\n", __FUNCTION__, ptdlsinfo->wfd_info->peer_rtsp_ctrlport);
1108 		}
1109 
1110 		attr_content = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_LOCAL_IP_ADDR, NULL, &attr_contentlen);
1111 		if (attr_content && attr_contentlen) {
1112 			_rtw_memcpy(ptdlsinfo->wfd_info->peer_ip_address, (attr_content + 1), 4);
1113 			RTW_INFO("[%s] Peer IP = %02u.%02u.%02u.%02u\n", __FUNCTION__,
1114 				ptdlsinfo->wfd_info->peer_ip_address[0], ptdlsinfo->wfd_info->peer_ip_address[1],
1115 				ptdlsinfo->wfd_info->peer_ip_address[2], ptdlsinfo->wfd_info->peer_ip_address[3]);
1116 		}
1117 
1118 		wfd_ie = rtw_get_wfd_ie(wfd_ie + wfd_ielen, (ptr + length) - (wfd_ie + wfd_ielen), NULL, &wfd_ielen);
1119 	}
1120 }
1121 
issue_tunneled_probe_req(_adapter * padapter)1122 int issue_tunneled_probe_req(_adapter *padapter)
1123 {
1124 	struct xmit_frame			*pmgntframe;
1125 	struct pkt_attrib			*pattrib;
1126 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
1127 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
1128 	u8 baddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1129 	struct tdls_txmgmt txmgmt;
1130 	int ret = _FAIL;
1131 
1132 	RTW_INFO("[%s]\n", __FUNCTION__);
1133 
1134 	_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
1135 	txmgmt.action_code = TUNNELED_PROBE_REQ;
1136 
1137 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
1138 	if (pmgntframe == NULL)
1139 		goto exit;
1140 
1141 	pattrib = &pmgntframe->attrib;
1142 
1143 	pmgntframe->frame_tag = DATA_FRAMETAG;
1144 	pattrib->ether_type = 0x890d;
1145 
1146 	_rtw_memcpy(pattrib->dst, baddr, ETH_ALEN);
1147 	_rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
1148 	_rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
1149 	_rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1150 
1151 	update_tdls_attrib(padapter, pattrib);
1152 	pattrib->qsel = pattrib->priority;
1153 	if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, &txmgmt) != _SUCCESS) {
1154 		#if 0 /*CONFIG_CORE_XMITBUF*/
1155 		rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
1156 		#endif
1157 		rtw_free_xmitframe(pxmitpriv, pmgntframe);
1158 		goto exit;
1159 	}
1160 	dump_mgntframe(padapter, pmgntframe);
1161 	ret = _SUCCESS;
1162 exit:
1163 
1164 	return ret;
1165 }
1166 
issue_tunneled_probe_rsp(_adapter * padapter,union recv_frame * precv_frame)1167 int issue_tunneled_probe_rsp(_adapter *padapter, union recv_frame *precv_frame)
1168 {
1169 	struct xmit_frame			*pmgntframe;
1170 	struct pkt_attrib			*pattrib;
1171 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
1172 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
1173 	struct tdls_txmgmt txmgmt;
1174 	int ret = _FAIL;
1175 
1176 	RTW_INFO("[%s]\n", __FUNCTION__);
1177 
1178 	_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
1179 	txmgmt.action_code = TUNNELED_PROBE_RSP;
1180 
1181 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
1182 	if (pmgntframe == NULL)
1183 		goto exit;
1184 
1185 	pattrib = &pmgntframe->attrib;
1186 
1187 	pmgntframe->frame_tag = DATA_FRAMETAG;
1188 	pattrib->ether_type = 0x890d;
1189 
1190 	_rtw_memcpy(pattrib->dst, precv_frame->u.hdr.attrib.src, ETH_ALEN);
1191 	_rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
1192 	_rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
1193 	_rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1194 
1195 	update_tdls_attrib(padapter, pattrib);
1196 	pattrib->qsel = pattrib->priority;
1197 	if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, &txmgmt) != _SUCCESS) {
1198 		#if 0 /*CONFIG_CORE_XMITBUF*/
1199 		rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
1200 		#endif
1201 		rtw_free_xmitframe(pxmitpriv, pmgntframe);
1202 		goto exit;
1203 	}
1204 	dump_mgntframe(padapter, pmgntframe);
1205 	ret = _SUCCESS;
1206 exit:
1207 
1208 	return ret;
1209 }
1210 #endif /* CONFIG_WFD */
1211 
issue_tdls_setup_req(_adapter * padapter,struct tdls_txmgmt * ptxmgmt,int wait_ack)1212 int issue_tdls_setup_req(_adapter *padapter, struct tdls_txmgmt *ptxmgmt, int wait_ack)
1213 {
1214 	struct tdls_info	*ptdlsinfo = &padapter->tdlsinfo;
1215 	struct xmit_frame			*pmgntframe;
1216 	struct pkt_attrib			*pattrib;
1217 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
1218 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
1219 	struct sta_priv *pstapriv = &padapter->stapriv;
1220 	struct sta_info *ptdls_sta = NULL;
1221 	int ret = _FAIL;
1222 	/* Retry timer should be set at least 301 sec, using TPK_count counting 301 times. */
1223 	u32 timeout_interval = TDLS_TPK_RESEND_COUNT;
1224 
1225 	RTW_INFO("[TDLS] %s\n", __FUNCTION__);
1226 
1227 	if (rtw_tdls_is_setup_allowed(padapter) == _FALSE)
1228 		goto exit;
1229 
1230 	if (IS_MCAST(ptxmgmt->peer))
1231 		goto exit;
1232 
1233 	ptdls_sta = rtw_get_stainfo(pstapriv, ptxmgmt->peer);
1234 	if (ptdlsinfo->sta_maximum == _TRUE) {
1235 		if (ptdls_sta == NULL)
1236 			goto exit;
1237 		else if (!(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE))
1238 			goto exit;
1239 	}
1240 
1241 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
1242 	if (pmgntframe == NULL)
1243 		goto exit;
1244 
1245 	if (ptdls_sta == NULL) {
1246 		ptdls_sta = rtw_alloc_stainfo(pstapriv, ptxmgmt->peer);
1247 		if (ptdls_sta == NULL) {
1248 			RTW_INFO("[%s] rtw_alloc_stainfo fail\n", __FUNCTION__);
1249 			#if 0 /*CONFIG_CORE_XMITBUF*/
1250 			rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
1251 			#endif
1252 			rtw_free_xmitframe(pxmitpriv, pmgntframe);
1253 			goto exit;
1254 		}
1255 		ptdlsinfo->sta_cnt++;
1256 	}
1257 
1258 	ptxmgmt->action_code = TDLS_SETUP_REQUEST;
1259 
1260 	pattrib = &pmgntframe->attrib;
1261 	pmgntframe->frame_tag = DATA_FRAMETAG;
1262 	pattrib->ether_type = 0x890d;
1263 
1264 	_rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN);
1265 	_rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
1266 	_rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
1267 	_rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1268 
1269 	update_tdls_attrib(padapter, pattrib);
1270 
1271 	if (ptdlsinfo->sta_cnt == MAX_ALLOWED_TDLS_STA_NUM)
1272 		ptdlsinfo->sta_maximum  = _TRUE;
1273 
1274 	ptdls_sta->tdls_sta_state |= TDLS_RESPONDER_STATE;
1275 
1276 	if (rtw_tdls_is_driver_setup(padapter) == _TRUE) {
1277 		ptdls_sta->TDLS_PeerKey_Lifetime = timeout_interval;
1278 		_set_timer(&ptdls_sta->handshake_timer, TDLS_HANDSHAKE_TIME);
1279 	}
1280 
1281 	pattrib->qsel = pattrib->priority;
1282 
1283 	if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) != _SUCCESS) {
1284 		#if 0 /*CONFIG_CORE_XMITBUF*/
1285 		rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
1286 		#endif
1287 		rtw_free_xmitframe(pxmitpriv, pmgntframe);
1288 		goto exit;
1289 	}
1290 
1291 	if (wait_ack)
1292 		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
1293 	else {
1294 		dump_mgntframe(padapter, pmgntframe);
1295 		ret = _SUCCESS;
1296 	}
1297 
1298 exit:
1299 
1300 	return ret;
1301 }
1302 
_issue_tdls_teardown(_adapter * padapter,struct tdls_txmgmt * ptxmgmt,struct sta_info * ptdls_sta,u8 wait_ack)1303 int _issue_tdls_teardown(_adapter *padapter, struct tdls_txmgmt *ptxmgmt, struct sta_info *ptdls_sta, u8 wait_ack)
1304 {
1305 	struct xmit_frame			*pmgntframe;
1306 	struct pkt_attrib			*pattrib;
1307 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
1308 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
1309 	struct sta_priv *pstapriv = &padapter->stapriv;
1310 	int ret = _FAIL;
1311 
1312 	RTW_INFO("[TDLS] %s\n", __FUNCTION__);
1313 
1314 	ptxmgmt->action_code = TDLS_TEARDOWN;
1315 
1316 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
1317 	if (pmgntframe == NULL)
1318 		goto exit;
1319 
1320 	rtw_mi_set_scan_deny(padapter, 550);
1321 	rtw_mi_scan_abort(padapter, _TRUE);
1322 
1323 	pattrib = &pmgntframe->attrib;
1324 
1325 	pmgntframe->frame_tag = DATA_FRAMETAG;
1326 	pattrib->ether_type = 0x890d;
1327 
1328 	_rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN);
1329 	_rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
1330 
1331 	if (ptxmgmt->status_code == _RSON_TDLS_TEAR_UN_RSN_)
1332 		_rtw_memcpy(pattrib->ra, ptxmgmt->peer, ETH_ALEN);
1333 	else
1334 		_rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
1335 
1336 	_rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1337 
1338 	update_tdls_attrib(padapter, pattrib);
1339 	pattrib->qsel = pattrib->priority;
1340 	if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) != _SUCCESS) {
1341 		#if 0 /*CONFIG_CORE_XMITBUF*/
1342 		rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
1343 		#endif
1344 		rtw_free_xmitframe(pxmitpriv, pmgntframe);
1345 		goto exit;
1346 	}
1347 
1348 	if (rtw_tdls_is_driver_setup(padapter) == _TRUE)
1349 		if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE)
1350 			if (pattrib->encrypt)
1351 				_cancel_timer_ex(&ptdls_sta->TPK_timer);
1352 
1353 	if (wait_ack)
1354 		ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
1355 	else {
1356 		dump_mgntframe(padapter, pmgntframe);
1357 		ret = _SUCCESS;
1358 	}
1359 
1360 exit:
1361 
1362 	return ret;
1363 }
1364 
issue_tdls_teardown(_adapter * padapter,struct tdls_txmgmt * ptxmgmt,u8 wait_ack)1365 int issue_tdls_teardown(_adapter *padapter, struct tdls_txmgmt *ptxmgmt, u8 wait_ack)
1366 {
1367 	struct sta_info *ptdls_sta = NULL;
1368 	int ret = _FAIL;
1369 
1370 	ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), ptxmgmt->peer);
1371 	if (ptdls_sta == NULL) {
1372 		RTW_INFO("No tdls_sta for tearing down\n");
1373 		goto exit;
1374 	}
1375 
1376 	ret = _issue_tdls_teardown(padapter, ptxmgmt, ptdls_sta, wait_ack);
1377 	if ((ptxmgmt->status_code == _RSON_TDLS_TEAR_UN_RSN_) && (ret == _FAIL)) {
1378 		/* Change status code and send teardown again via AP */
1379 		ptxmgmt->status_code = _RSON_TDLS_TEAR_TOOFAR_;
1380 		ret = _issue_tdls_teardown(padapter, ptxmgmt, ptdls_sta, wait_ack);
1381 	}
1382 
1383 	if (rtw_tdls_is_driver_setup(padapter)) {
1384 		rtw_tdls_teardown_pre_hdl(padapter, ptdls_sta);
1385 		rtw_tdls_cmd(padapter, ptxmgmt->peer, TDLS_TEARDOWN_STA_LOCALLY_POST);
1386 	}
1387 
1388 exit:
1389 	return ret;
1390 }
1391 
issue_tdls_dis_req(_adapter * padapter,struct tdls_txmgmt * ptxmgmt)1392 int issue_tdls_dis_req(_adapter *padapter, struct tdls_txmgmt *ptxmgmt)
1393 {
1394 	struct xmit_frame			*pmgntframe;
1395 	struct pkt_attrib			*pattrib;
1396 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
1397 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
1398 	int ret = _FAIL;
1399 
1400 	RTW_INFO("[TDLS] %s\n", __FUNCTION__);
1401 
1402 	ptxmgmt->action_code = TDLS_DISCOVERY_REQUEST;
1403 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
1404 	if (pmgntframe == NULL)
1405 		goto exit;
1406 
1407 	pattrib = &pmgntframe->attrib;
1408 	pmgntframe->frame_tag = DATA_FRAMETAG;
1409 	pattrib->ether_type = 0x890d;
1410 
1411 	_rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN);
1412 	_rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
1413 	_rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
1414 	_rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1415 
1416 	update_tdls_attrib(padapter, pattrib);
1417 	pattrib->qsel = pattrib->priority;
1418 	if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) != _SUCCESS) {
1419 		#if 0 /*CONFIG_CORE_XMITBUF*/
1420 		rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
1421 		#endif
1422 		rtw_free_xmitframe(pxmitpriv, pmgntframe);
1423 		goto exit;
1424 	}
1425 	dump_mgntframe(padapter, pmgntframe);
1426 	RTW_INFO("issue tdls dis req\n");
1427 
1428 	ret = _SUCCESS;
1429 exit:
1430 
1431 	return ret;
1432 }
1433 
issue_tdls_setup_rsp(_adapter * padapter,struct tdls_txmgmt * ptxmgmt)1434 int issue_tdls_setup_rsp(_adapter *padapter, struct tdls_txmgmt *ptxmgmt)
1435 {
1436 	struct xmit_frame			*pmgntframe;
1437 	struct pkt_attrib			*pattrib;
1438 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
1439 	int ret = _FAIL;
1440 
1441 	RTW_INFO("[TDLS] %s\n", __FUNCTION__);
1442 
1443 	ptxmgmt->action_code = TDLS_SETUP_RESPONSE;
1444 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
1445 	if (pmgntframe == NULL)
1446 		goto exit;
1447 
1448 	pattrib = &pmgntframe->attrib;
1449 	pmgntframe->frame_tag = DATA_FRAMETAG;
1450 	pattrib->ether_type = 0x890d;
1451 
1452 	_rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN);
1453 	_rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
1454 	_rtw_memcpy(pattrib->ra, get_bssid(&(padapter->mlmepriv)), ETH_ALEN);
1455 	_rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1456 
1457 	update_tdls_attrib(padapter, pattrib);
1458 	pattrib->qsel = pattrib->priority;
1459 	if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) != _SUCCESS) {
1460 		#if 0 /*CONFIG_CORE_XMITBUF*/
1461 		rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
1462 		#endif
1463 		rtw_free_xmitframe(pxmitpriv, pmgntframe);
1464 		goto exit;
1465 	}
1466 
1467 	dump_mgntframe(padapter, pmgntframe);
1468 
1469 	ret = _SUCCESS;
1470 exit:
1471 
1472 	return ret;
1473 
1474 }
1475 
issue_tdls_setup_cfm(_adapter * padapter,struct tdls_txmgmt * ptxmgmt)1476 int issue_tdls_setup_cfm(_adapter *padapter, struct tdls_txmgmt *ptxmgmt)
1477 {
1478 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
1479 	struct xmit_frame			*pmgntframe;
1480 	struct pkt_attrib			*pattrib;
1481 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
1482 	int ret = _FAIL;
1483 
1484 	RTW_INFO("[TDLS] %s\n", __FUNCTION__);
1485 
1486 	ptxmgmt->action_code = TDLS_SETUP_CONFIRM;
1487 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
1488 	if (pmgntframe == NULL)
1489 		goto exit;
1490 
1491 	pattrib = &pmgntframe->attrib;
1492 	pmgntframe->frame_tag = DATA_FRAMETAG;
1493 	pattrib->ether_type = 0x890d;
1494 
1495 	_rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN);
1496 	_rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
1497 	_rtw_memcpy(pattrib->ra, get_bssid(&padapter->mlmepriv), ETH_ALEN);
1498 	_rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1499 
1500 	update_tdls_attrib(padapter, pattrib);
1501 	pattrib->qsel = pattrib->priority;
1502 	if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) != _SUCCESS) {
1503 		#if 0 /*CONFIG_CORE_XMITBUF*/
1504 		rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
1505 		#endif
1506 		rtw_free_xmitframe(pxmitpriv, pmgntframe);
1507 		goto exit;
1508 	}
1509 
1510 	dump_mgntframe(padapter, pmgntframe);
1511 
1512 	ret = _SUCCESS;
1513 exit:
1514 
1515 	return ret;
1516 
1517 }
1518 
1519 /* TDLS Discovery Response frame is a management action frame */
issue_tdls_dis_rsp(_adapter * padapter,struct tdls_txmgmt * ptxmgmt,u8 privacy)1520 int issue_tdls_dis_rsp(_adapter *padapter, struct tdls_txmgmt *ptxmgmt, u8 privacy)
1521 {
1522 	struct xmit_frame		*pmgntframe;
1523 	struct pkt_attrib		*pattrib;
1524 	unsigned char			*pframe;
1525 	struct rtw_ieee80211_hdr	*pwlanhdr;
1526 	unsigned short		*fctrl;
1527 	struct xmit_priv		*pxmitpriv = &(padapter->xmitpriv);
1528 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
1529 	int ret = _FAIL;
1530 
1531 	RTW_INFO("[TDLS] %s\n", __FUNCTION__);
1532 
1533 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
1534 	if (pmgntframe == NULL)
1535 		goto exit;
1536 
1537 	pattrib = &pmgntframe->attrib;
1538 	update_mgntframe_attrib(padapter, pattrib);
1539 
1540 	_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
1541 
1542 	pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
1543 	pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
1544 
1545 	fctrl = &(pwlanhdr->frame_ctl);
1546 	*(fctrl) = 0;
1547 
1548 	/* unicast probe request frame */
1549 	_rtw_memcpy(pwlanhdr->addr1, ptxmgmt->peer, ETH_ALEN);
1550 	_rtw_memcpy(pattrib->dst, pwlanhdr->addr1, ETH_ALEN);
1551 	_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
1552 	_rtw_memcpy(pattrib->src, pwlanhdr->addr2, ETH_ALEN);
1553 	_rtw_memcpy(pwlanhdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN);
1554 	_rtw_memcpy(pattrib->ra, pwlanhdr->addr3, ETH_ALEN);
1555 
1556 	SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
1557 	pmlmeext->mgnt_seq++;
1558 	set_frame_sub_type(pframe, WIFI_ACTION);
1559 
1560 	pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
1561 	pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
1562 
1563 	rtw_build_tdls_dis_rsp_ies(padapter, pmgntframe, pframe, ptxmgmt, privacy);
1564 
1565 	pattrib->nr_frags = 1;
1566 	pattrib->last_txcmdsz = pattrib->pktlen;
1567 
1568 	dump_mgntframe(padapter, pmgntframe);
1569 	ret = _SUCCESS;
1570 
1571 exit:
1572 	return ret;
1573 }
1574 
issue_tdls_peer_traffic_rsp(_adapter * padapter,struct sta_info * ptdls_sta,struct tdls_txmgmt * ptxmgmt)1575 int issue_tdls_peer_traffic_rsp(_adapter *padapter, struct sta_info *ptdls_sta, struct tdls_txmgmt *ptxmgmt)
1576 {
1577 	struct xmit_frame	*pmgntframe;
1578 	struct pkt_attrib	*pattrib;
1579 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
1580 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
1581 	int ret = _FAIL;
1582 
1583 	RTW_INFO("[TDLS] %s\n", __FUNCTION__);
1584 
1585 	ptxmgmt->action_code = TDLS_PEER_TRAFFIC_RESPONSE;
1586 
1587 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
1588 	if (pmgntframe == NULL)
1589 		goto exit;
1590 
1591 	pattrib = &pmgntframe->attrib;
1592 
1593 	pmgntframe->frame_tag = DATA_FRAMETAG;
1594 	pattrib->ether_type = 0x890d;
1595 
1596 	_rtw_memcpy(pattrib->dst, ptdls_sta->phl_sta->mac_addr, ETH_ALEN);
1597 	_rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
1598 	_rtw_memcpy(pattrib->ra, ptdls_sta->phl_sta->mac_addr, ETH_ALEN);
1599 	_rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1600 
1601 	update_tdls_attrib(padapter, pattrib);
1602 	pattrib->qsel = pattrib->priority;
1603 
1604 	if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) != _SUCCESS) {
1605 		#if 0 /*CONFIG_CORE_XMITBUF*/
1606 		rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
1607 		#endif
1608 		rtw_free_xmitframe(pxmitpriv, pmgntframe);
1609 		goto exit;
1610 	}
1611 
1612 	dump_mgntframe(padapter, pmgntframe);
1613 	ret = _SUCCESS;
1614 
1615 exit:
1616 
1617 	return ret;
1618 }
1619 
issue_tdls_peer_traffic_indication(_adapter * padapter,struct sta_info * ptdls_sta)1620 int issue_tdls_peer_traffic_indication(_adapter *padapter, struct sta_info *ptdls_sta)
1621 {
1622 	struct xmit_frame			*pmgntframe;
1623 	struct pkt_attrib			*pattrib;
1624 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
1625 	struct xmit_priv			*pxmitpriv = &(padapter->xmitpriv);
1626 	struct tdls_txmgmt txmgmt;
1627 	int ret = _FAIL;
1628 
1629 	RTW_INFO("[TDLS] %s\n", __FUNCTION__);
1630 
1631 	_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
1632 	txmgmt.action_code = TDLS_PEER_TRAFFIC_INDICATION;
1633 
1634 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
1635 	if (pmgntframe == NULL)
1636 		goto exit;
1637 
1638 	pattrib = &pmgntframe->attrib;
1639 
1640 	pmgntframe->frame_tag = DATA_FRAMETAG;
1641 	pattrib->ether_type = 0x890d;
1642 
1643 	_rtw_memcpy(pattrib->dst, ptdls_sta->phl_sta->mac_addr, ETH_ALEN);
1644 	_rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
1645 	_rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
1646 	_rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1647 
1648 	/* PTI frame's priority should be AC_VO */
1649 	pattrib->priority = 7;
1650 
1651 	update_tdls_attrib(padapter, pattrib);
1652 	pattrib->qsel = pattrib->priority;
1653 	if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, &txmgmt) != _SUCCESS) {
1654 		#if 0 /*CONFIG_CORE_XMITBUF*/
1655 		rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
1656 		#endif
1657 		rtw_free_xmitframe(pxmitpriv, pmgntframe);
1658 		goto exit;
1659 	}
1660 
1661 	dump_mgntframe(padapter, pmgntframe);
1662 	ret = _SUCCESS;
1663 
1664 exit:
1665 
1666 	return ret;
1667 }
1668 
1669 #ifdef CONFIG_TDLS_CH_SW
issue_tdls_ch_switch_req(_adapter * padapter,struct sta_info * ptdls_sta)1670 int issue_tdls_ch_switch_req(_adapter *padapter, struct sta_info *ptdls_sta)
1671 {
1672 	struct xmit_frame	*pmgntframe;
1673 	struct pkt_attrib	*pattrib;
1674 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
1675 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
1676 	struct tdls_txmgmt txmgmt;
1677 	int ret = _FAIL;
1678 
1679 	RTW_INFO("[TDLS] %s\n", __FUNCTION__);
1680 
1681 	if (rtw_tdls_is_chsw_allowed(padapter) == _FALSE) {
1682 		RTW_INFO("[TDLS] Ignore %s since channel switch is not allowed\n", __func__);
1683 		goto exit;
1684 	}
1685 
1686 	_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
1687 	txmgmt.action_code = TDLS_CHANNEL_SWITCH_REQUEST;
1688 
1689 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
1690 	if (pmgntframe == NULL)
1691 		goto exit;
1692 
1693 	pattrib = &pmgntframe->attrib;
1694 
1695 	pmgntframe->frame_tag = DATA_FRAMETAG;
1696 	pattrib->ether_type = 0x890d;
1697 
1698 	_rtw_memcpy(pattrib->dst, ptdls_sta->phl_sta->mac_addr, ETH_ALEN);
1699 	_rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
1700 	_rtw_memcpy(pattrib->ra, ptdls_sta->phl_sta->mac_addr, ETH_ALEN);
1701 	_rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1702 
1703 	update_tdls_attrib(padapter, pattrib);
1704 	pattrib->qsel = pattrib->priority;
1705 	if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, &txmgmt) != _SUCCESS) {
1706 		#if 0 /*CONFIG_CORE_XMITBUF*/
1707 		rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
1708 		#endif
1709 		rtw_free_xmitframe(pxmitpriv, pmgntframe);
1710 		goto exit;
1711 	}
1712 
1713 	dump_mgntframe(padapter, pmgntframe);
1714 	ret = _SUCCESS;
1715 exit:
1716 
1717 	return ret;
1718 }
1719 
issue_tdls_ch_switch_rsp(_adapter * padapter,struct tdls_txmgmt * ptxmgmt,int wait_ack)1720 int issue_tdls_ch_switch_rsp(_adapter *padapter, struct tdls_txmgmt *ptxmgmt, int wait_ack)
1721 {
1722 	struct xmit_frame	*pmgntframe;
1723 	struct pkt_attrib	*pattrib;
1724 	struct mlme_priv	*pmlmepriv = &padapter->mlmepriv;
1725 	struct xmit_priv	*pxmitpriv = &(padapter->xmitpriv);
1726 	int ret = _FAIL;
1727 
1728 	RTW_INFO("[TDLS] %s\n", __FUNCTION__);
1729 
1730 	if (rtw_tdls_is_chsw_allowed(padapter) == _FALSE) {
1731 		RTW_INFO("[TDLS] Ignore %s since channel switch is not allowed\n", __func__);
1732 		goto exit;
1733 	}
1734 
1735 	ptxmgmt->action_code = TDLS_CHANNEL_SWITCH_RESPONSE;
1736 
1737 	pmgntframe = alloc_mgtxmitframe(pxmitpriv);
1738 	if (pmgntframe == NULL)
1739 		goto exit;
1740 
1741 	pattrib = &pmgntframe->attrib;
1742 
1743 	pmgntframe->frame_tag = DATA_FRAMETAG;
1744 	pattrib->ether_type = 0x890d;
1745 
1746 	_rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN);
1747 	_rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
1748 	_rtw_memcpy(pattrib->ra, ptxmgmt->peer, ETH_ALEN);
1749 	_rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1750 
1751 	update_tdls_attrib(padapter, pattrib);
1752 	pattrib->qsel = pattrib->priority;
1753 	/*
1754 		_rtw_spinlock_bh(&pxmitpriv->lock);
1755 		if(xmitframe_enqueue_for_tdls_sleeping_sta(padapter, pmgntframe)==_TRUE){
1756 			_rtw_spinunlock_bh(&pxmitpriv->lock);
1757 			return _FALSE;
1758 		}
1759 	*/
1760 	if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) != _SUCCESS) {
1761 		#if 0 /*CONFIG_CORE_XMITBUF*/
1762 		rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
1763 		#endif
1764 		rtw_free_xmitframe(pxmitpriv, pmgntframe);
1765 		goto exit;
1766 	}
1767 
1768 	if (wait_ack)
1769 		ret = dump_mgntframe_and_wait_ack_timeout(padapter, pmgntframe, 10);
1770 	else {
1771 		dump_mgntframe(padapter, pmgntframe);
1772 		ret = _SUCCESS;
1773 	}
1774 exit:
1775 
1776 	return ret;
1777 }
1778 #endif
1779 
On_TDLS_Dis_Rsp(_adapter * padapter,union recv_frame * precv_frame)1780 int On_TDLS_Dis_Rsp(_adapter *padapter, union recv_frame *precv_frame)
1781 {
1782 	struct sta_info *ptdls_sta = NULL, *psta = rtw_get_stainfo(&(padapter->stapriv), get_bssid(&(padapter->mlmepriv)));
1783 	u8 *ptr = precv_frame->u.hdr.rx_data, *psa;
1784 	struct rx_pkt_attrib *pattrib = &(precv_frame->u.hdr.attrib);
1785 	struct tdls_info *ptdlsinfo = &(padapter->tdlsinfo);
1786 	u8 empty_addr[ETH_ALEN] = { 0x00 };
1787 	int rssi = 0;
1788 	struct tdls_txmgmt txmgmt;
1789 	int ret = _SUCCESS;
1790 
1791 	if (psta)
1792 		rssi = psta->phl_sta->rssi_stat.rssi;
1793 
1794 	_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
1795 	/* WFDTDLS: for sigma test, not to setup direct link automatically */
1796 	ptdlsinfo->dev_discovered = _TRUE;
1797 
1798 	psa = get_sa(ptr);
1799 	ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), psa);
1800 	if (ptdls_sta != NULL)
1801 		ptdls_sta->sta_stats.rx_tdls_disc_rsp_pkts++;
1802 
1803 #ifdef CONFIG_TDLS_AUTOSETUP
1804 	if (ptdls_sta != NULL) {
1805 		/* Record the tdls sta with lowest signal strength */
1806 		if (ptdlsinfo->sta_maximum == _TRUE && ptdls_sta->alive_count >= 1) {
1807 			if (_rtw_memcmp(ptdlsinfo->ss_record.macaddr, empty_addr, ETH_ALEN)) {
1808 				_rtw_memcpy(ptdlsinfo->ss_record.macaddr, psa, ETH_ALEN);
1809 				ptdlsinfo->ss_record.RxPWDBAll = pattrib->phy_info.rx_pwdb_all;
1810 			} else {
1811 				if (ptdlsinfo->ss_record.RxPWDBAll < pattrib->phy_info.rx_pwdb_all) {
1812 					_rtw_memcpy(ptdlsinfo->ss_record.macaddr, psa, ETH_ALEN);
1813 					ptdlsinfo->ss_record.RxPWDBAll = pattrib->phy_info.rx_pwdb_all;
1814 				}
1815 			}
1816 		}
1817 	} else {
1818 		if (ptdlsinfo->sta_maximum == _TRUE) {
1819 			if (_rtw_memcmp(ptdlsinfo->ss_record.macaddr, empty_addr, ETH_ALEN)) {
1820 				/* All traffics are busy, do not set up another direct link. */
1821 				ret = _FAIL;
1822 				goto exit;
1823 			} else {
1824 				if (pattrib->phy_info.rx_pwdb_all > ptdlsinfo->ss_record.RxPWDBAll) {
1825 					_rtw_memcpy(txmgmt.peer, ptdlsinfo->ss_record.macaddr, ETH_ALEN);
1826 					/* issue_tdls_teardown(padapter, ptdlsinfo->ss_record.macaddr, _FALSE); */
1827 				} else {
1828 					ret = _FAIL;
1829 					goto exit;
1830 				}
1831 			}
1832 		}
1833 
1834 
1835 		if (pattrib->phy_info.rx_pwdb_all + TDLS_SIGNAL_THRESH >= rssi) {
1836 			RTW_INFO("pattrib->RxPWDBAll=%d, pdmpriv->undecorated_smoothed_pwdb=%d\n", pattrib->phy_info.rx_pwdb_all, rssi);
1837 			_rtw_memcpy(txmgmt.peer, psa, ETH_ALEN);
1838 			issue_tdls_setup_req(padapter, &txmgmt, _FALSE);
1839 		}
1840 	}
1841 exit:
1842 #endif /* CONFIG_TDLS_AUTOSETUP */
1843 
1844 	return ret;
1845 
1846 }
1847 
On_TDLS_Setup_Req(_adapter * padapter,union recv_frame * precv_frame,struct sta_info * ptdls_sta)1848 sint On_TDLS_Setup_Req(_adapter *padapter, union recv_frame *precv_frame, struct sta_info *ptdls_sta)
1849 {
1850 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
1851 	u8 *psa, *pmyid;
1852 	struct sta_priv *pstapriv = &padapter->stapriv;
1853 	u8 *ptr = precv_frame->u.hdr.rx_data;
1854 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1855 	struct security_priv *psecuritypriv = &padapter->securitypriv;
1856 	struct rx_pkt_attrib	*prx_pkt_attrib = &precv_frame->u.hdr.attrib;
1857 	u8 *prsnie, *ppairwise_cipher;
1858 	u8 i, k;
1859 	u8 ccmp_included = 0, rsnie_included = 0;
1860 	u16 j, pairwise_count;
1861 	u8 SNonce[32];
1862 	u32 timeout_interval = TDLS_TPK_RESEND_COUNT;
1863 	sint parsing_length;	/* Frame body length, without icv_len */
1864 	PNDIS_802_11_VARIABLE_IEs	pIE;
1865 	u8 FIXED_IE = 5;
1866 	unsigned char		supportRate[16];
1867 	int				supportRateNum = 0;
1868 	struct tdls_txmgmt txmgmt;
1869 
1870 	if (rtw_tdls_is_setup_allowed(padapter) == _FALSE)
1871 		goto exit;
1872 
1873 	_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
1874 	psa = get_sa(ptr);
1875 
1876 	if (ptdlsinfo->sta_maximum == _TRUE) {
1877 		if (ptdls_sta == NULL)
1878 			goto exit;
1879 		else if (!(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE))
1880 			goto exit;
1881 	}
1882 
1883 	pmyid = adapter_mac_addr(padapter);
1884 	ptr += prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len + LLC_HEADER_SIZE + ETH_TYPE_LEN + PAYLOAD_TYPE_LEN;
1885 	parsing_length = ((union recv_frame *)precv_frame)->u.hdr.len
1886 			 - prx_pkt_attrib->hdrlen
1887 			 - prx_pkt_attrib->iv_len
1888 			 - prx_pkt_attrib->icv_len
1889 			 - LLC_HEADER_SIZE
1890 			 - ETH_TYPE_LEN
1891 			 - PAYLOAD_TYPE_LEN;
1892 
1893 	if (ptdls_sta == NULL) {
1894 		ptdls_sta = rtw_alloc_stainfo(pstapriv, psa);
1895 		if (ptdls_sta == NULL)
1896 			goto exit;
1897 
1898 		ptdlsinfo->sta_cnt++;
1899 	}
1900 	else {
1901 		if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) {
1902 			/* If the direct link is already set up */
1903 			/* Process as re-setup after tear down */
1904 			RTW_INFO("re-setup a direct link\n");
1905 		}
1906 		/* Already receiving TDLS setup request */
1907 		else if (ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE) {
1908 			RTW_INFO("receive duplicated TDLS setup request frame in handshaking\n");
1909 			goto exit;
1910 		}
1911 		/* When receiving and sending setup_req to the same link at the same time */
1912 		/* STA with higher MAC_addr would be initiator */
1913 		else if (ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE) {
1914 			RTW_INFO("receive setup_req after sending setup_req\n");
1915 			for (i = 0; i < 6; i++) {
1916 				if (*(pmyid + i) == *(psa + i)) {
1917 				} else if (*(pmyid + i) > *(psa + i)) {
1918 					ptdls_sta->tdls_sta_state = TDLS_INITIATOR_STATE;
1919 					break;
1920 				} else if (*(pmyid + i) < *(psa + i))
1921 					goto exit;
1922 			}
1923 		}
1924 	}
1925 
1926 	if (ptdls_sta) {
1927 		txmgmt.dialog_token = *(ptr + 2);	/* Copy dialog token */
1928 		txmgmt.status_code = _STATS_SUCCESSFUL_;
1929 
1930 		/* Parsing information element */
1931 		for (j = FIXED_IE; j < parsing_length;) {
1932 
1933 			pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr + j);
1934 
1935 			switch (pIE->ElementID) {
1936 			case _SUPPORTEDRATES_IE_:
1937 				if (pIE->Length <= sizeof(supportRate)) {
1938 					_rtw_memcpy(supportRate, pIE->data, pIE->Length);
1939 					supportRateNum = pIE->Length;
1940 				}
1941 				break;
1942 			case WLAN_EID_COUNTRY:
1943 				break;
1944 			case _EXT_SUPPORTEDRATES_IE_:
1945 				if ((supportRateNum + pIE->Length) <= sizeof(supportRate)) {
1946 					_rtw_memcpy(supportRate + supportRateNum, pIE->data, pIE->Length);
1947 					supportRateNum += pIE->Length;
1948 				}
1949 				break;
1950 			case _SUPPORTED_CH_IE_:
1951 				break;
1952 			case _RSN_IE_2_:
1953 				rsnie_included = 1;
1954 				if (prx_pkt_attrib->encrypt) {
1955 					prsnie = (u8 *)pIE;
1956 					if (pIE->Length <= sizeof(ptdls_sta->TDLS_RSNIE)) {
1957 						/* Check CCMP pairwise_cipher presence. */
1958 						ppairwise_cipher = prsnie + 10;
1959 						_rtw_memcpy(ptdls_sta->TDLS_RSNIE, pIE->data, pIE->Length);
1960 						pairwise_count = *(u16 *)(ppairwise_cipher - 2);
1961 						for (k = 0; k < pairwise_count; k++) {
1962 							if (_rtw_memcmp(ppairwise_cipher + 4 * k, RSN_CIPHER_SUITE_CCMP, 4) == _TRUE)
1963 								ccmp_included = 1;
1964 						}
1965 
1966 						if (ccmp_included == 0)
1967 							txmgmt.status_code = _STATS_INVALID_RSNIE_;
1968 					}
1969 				}
1970 				break;
1971 			case WLAN_EID_EXT_CAP:
1972 				break;
1973 			case _VENDOR_SPECIFIC_IE_:
1974 				break;
1975 			case _FTIE_:
1976 				if (prx_pkt_attrib->encrypt)
1977 					_rtw_memcpy(SNonce, (ptr + j + 52), 32);
1978 				break;
1979 			case _TIMEOUT_ITVL_IE_:
1980 				if (prx_pkt_attrib->encrypt)
1981 					timeout_interval = cpu_to_le32(*(u32 *)(ptr + j + 3));
1982 				break;
1983 			case _RIC_Descriptor_IE_:
1984 				break;
1985 #ifdef CONFIG_80211N_HT
1986 			case _HT_CAPABILITY_IE_:
1987 				rtw_tdls_process_ht_cap(padapter, ptdls_sta, pIE->data, pIE->Length);
1988 				break;
1989 #endif
1990 #ifdef CONFIG_80211AC_VHT
1991 			case EID_AID:
1992 				break;
1993 			case EID_VHTCapability:
1994 				rtw_tdls_process_vht_cap(padapter, ptdls_sta, pIE->data, pIE->Length);
1995 				break;
1996 #endif
1997 			case EID_BSSCoexistence:
1998 				break;
1999 			case _LINK_ID_IE_:
2000 				if (_rtw_memcmp(get_bssid(pmlmepriv), pIE->data, 6) == _FALSE)
2001 					txmgmt.status_code = _STATS_NOT_IN_SAME_BSS_;
2002 				break;
2003 			default:
2004 				break;
2005 			}
2006 
2007 			j += (pIE->Length + 2);
2008 
2009 		}
2010 
2011 		/* Check status code */
2012 		/* If responder STA has/hasn't security on AP, but request hasn't/has RSNIE, it should reject */
2013 		if (txmgmt.status_code == _STATS_SUCCESSFUL_) {
2014 			if (rsnie_included && prx_pkt_attrib->encrypt == 0)
2015 				txmgmt.status_code = _STATS_SEC_DISABLED_;
2016 			else if (rsnie_included == 0 && prx_pkt_attrib->encrypt)
2017 				txmgmt.status_code = _STATS_INVALID_PARAMETERS_;
2018 
2019 #ifdef CONFIG_WFD
2020 			/* WFD test plan version 0.18.2 test item 5.1.5 */
2021 			/* SoUT does not use TDLS if AP uses weak security */
2022 			if (padapter->wdinfo.wfd_tdls_enable && (rsnie_included && prx_pkt_attrib->encrypt != _AES_))
2023 				txmgmt.status_code = _STATS_SEC_DISABLED_;
2024 #endif /* CONFIG_WFD */
2025 		}
2026 
2027 		ptdls_sta->tdls_sta_state |= TDLS_INITIATOR_STATE;
2028 		if (prx_pkt_attrib->encrypt) {
2029 			_rtw_memcpy(ptdls_sta->SNonce, SNonce, 32);
2030 
2031 			if (timeout_interval <= 300)
2032 				ptdls_sta->TDLS_PeerKey_Lifetime = TDLS_TPK_RESEND_COUNT;
2033 			else
2034 				ptdls_sta->TDLS_PeerKey_Lifetime = timeout_interval;
2035 		}
2036 
2037 		/* Update station supportRate */
2038 		ptdls_sta->bssratelen = supportRateNum;
2039 		_rtw_memcpy(ptdls_sta->bssrateset, supportRate, supportRateNum);
2040 
2041 		/* -2: AP + BC/MC sta, -4: default key */
2042 		if (ptdlsinfo->sta_cnt == MAX_ALLOWED_TDLS_STA_NUM)
2043 			ptdlsinfo->sta_maximum = _TRUE;
2044 
2045 #ifdef CONFIG_WFD
2046 		rtw_tdls_process_wfd_ie(ptdlsinfo, ptr + FIXED_IE, parsing_length);
2047 #endif
2048 
2049 	} else
2050 		goto exit;
2051 
2052 	_rtw_memcpy(txmgmt.peer, prx_pkt_attrib->src, ETH_ALEN);
2053 
2054 	if (rtw_tdls_is_driver_setup(padapter)) {
2055 		issue_tdls_setup_rsp(padapter, &txmgmt);
2056 
2057 		if (txmgmt.status_code == _STATS_SUCCESSFUL_)
2058 			_set_timer(&ptdls_sta->handshake_timer, TDLS_HANDSHAKE_TIME);
2059 		else {
2060 			rtw_tdls_teardown_pre_hdl(padapter, ptdls_sta);
2061 			rtw_tdls_cmd(padapter, ptdls_sta->phl_sta->mac_addr, TDLS_TEARDOWN_STA_LOCALLY_POST);
2062 		}
2063 	}
2064 
2065 exit:
2066 
2067 	return _SUCCESS;
2068 }
2069 
On_TDLS_Setup_Rsp(_adapter * padapter,union recv_frame * precv_frame,struct sta_info * ptdls_sta)2070 int On_TDLS_Setup_Rsp(_adapter *padapter, union recv_frame *precv_frame, struct sta_info *ptdls_sta)
2071 {
2072 	struct registry_priv	*pregistrypriv = &padapter->registrypriv;
2073 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
2074 	struct sta_priv *pstapriv = &padapter->stapriv;
2075 	u8 *ptr = precv_frame->u.hdr.rx_data;
2076 	struct rx_pkt_attrib	*prx_pkt_attrib = &precv_frame->u.hdr.attrib;
2077 	u8 *psa;
2078 	u16 status_code = 0;
2079 	sint parsing_length;	/* Frame body length, without icv_len */
2080 	PNDIS_802_11_VARIABLE_IEs	pIE;
2081 	u8 FIXED_IE = 7;
2082 	u8 ANonce[32];
2083 	u8  *pftie = NULL, *ptimeout_ie = NULL, *plinkid_ie = NULL, *prsnie = NULL, *pftie_mic = NULL, *ppairwise_cipher = NULL;
2084 	u16 pairwise_count, j, k;
2085 	u8 verify_ccmp = 0;
2086 	unsigned char		supportRate[16];
2087 	int				supportRateNum = 0;
2088 	struct tdls_txmgmt txmgmt;
2089 	int ret = _SUCCESS;
2090 	u32 timeout_interval = TDLS_TPK_RESEND_COUNT;
2091 
2092 	_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
2093 	psa = get_sa(ptr);
2094 
2095 	ptr += prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len + LLC_HEADER_SIZE + ETH_TYPE_LEN + PAYLOAD_TYPE_LEN;
2096 	parsing_length = ((union recv_frame *)precv_frame)->u.hdr.len
2097 			 - prx_pkt_attrib->hdrlen
2098 			 - prx_pkt_attrib->iv_len
2099 			 - prx_pkt_attrib->icv_len
2100 			 - LLC_HEADER_SIZE
2101 			 - ETH_TYPE_LEN
2102 			 - PAYLOAD_TYPE_LEN;
2103 
2104 	_rtw_memcpy(&status_code, ptr + 2, 2);
2105 
2106 	if (status_code != 0) {
2107 		RTW_INFO("[TDLS] %s status_code = %d, free_tdls_sta\n", __FUNCTION__, status_code);
2108 		rtw_tdls_teardown_pre_hdl(padapter, ptdls_sta);
2109 		rtw_tdls_cmd(padapter, ptdls_sta->phl_sta->mac_addr, TDLS_TEARDOWN_STA_LOCALLY_POST);
2110 		ret = _FAIL;
2111 		goto exit;
2112 	}
2113 
2114 	status_code = 0;
2115 
2116 	/* parsing information element */
2117 	for (j = FIXED_IE; j < parsing_length;) {
2118 		pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr + j);
2119 
2120 		switch (pIE->ElementID) {
2121 		case _SUPPORTEDRATES_IE_:
2122 			if (pIE->Length <= sizeof(supportRate)) {
2123 				_rtw_memcpy(supportRate, pIE->data, pIE->Length);
2124 				supportRateNum = pIE->Length;
2125 			}
2126 			break;
2127 		case WLAN_EID_COUNTRY:
2128 			break;
2129 		case _EXT_SUPPORTEDRATES_IE_:
2130 			if ((supportRateNum + pIE->Length) <= sizeof(supportRate)) {
2131 				_rtw_memcpy(supportRate + supportRateNum, pIE->data, pIE->Length);
2132 				supportRateNum += pIE->Length;
2133 			}
2134 			break;
2135 		case _SUPPORTED_CH_IE_:
2136 			break;
2137 		case _RSN_IE_2_:
2138 			prsnie = (u8 *)pIE;
2139 			/* Check CCMP pairwise_cipher presence. */
2140 			ppairwise_cipher = prsnie + 10;
2141 			_rtw_memcpy(&pairwise_count, (u16 *)(ppairwise_cipher - 2), 2);
2142 			for (k = 0; k < pairwise_count; k++) {
2143 				if (_rtw_memcmp(ppairwise_cipher + 4 * k, RSN_CIPHER_SUITE_CCMP, 4) == _TRUE)
2144 					verify_ccmp = 1;
2145 			}
2146 		case WLAN_EID_EXT_CAP:
2147 			break;
2148 		case _VENDOR_SPECIFIC_IE_:
2149 			if (_rtw_memcmp((u8 *)pIE + 2, WMM_INFO_OUI, 6) == _TRUE) {
2150 				/* WMM Info ID and OUI */
2151 				if ((pregistrypriv->wmm_enable == _TRUE) || (padapter->mlmepriv.htpriv.ht_option == _TRUE))
2152 					ptdls_sta->qos_option = _TRUE;
2153 			}
2154 			break;
2155 		case _FTIE_:
2156 			pftie = (u8 *)pIE;
2157 			_rtw_memcpy(ANonce, (ptr + j + 20), 32);
2158 			break;
2159 		case _TIMEOUT_ITVL_IE_:
2160 			ptimeout_ie = (u8 *)pIE;
2161 			timeout_interval = cpu_to_le32(*(u32 *)(ptimeout_ie + 3));
2162 			break;
2163 		case _RIC_Descriptor_IE_:
2164 			break;
2165 #ifdef CONFIG_80211N_HT
2166 		case _HT_CAPABILITY_IE_:
2167 			rtw_tdls_process_ht_cap(padapter, ptdls_sta, pIE->data, pIE->Length);
2168 			break;
2169 #endif
2170 #ifdef CONFIG_80211AC_VHT
2171 		case EID_AID:
2172 			/* todo in the future if necessary */
2173 			break;
2174 		case EID_VHTCapability:
2175 			rtw_tdls_process_vht_cap(padapter, ptdls_sta, pIE->data, pIE->Length);
2176 			break;
2177 		case EID_OpModeNotification:
2178 			rtw_tdls_process_vht_op_mode_notify(padapter, ptdls_sta, pIE->data, pIE->Length);
2179 			break;
2180 #endif
2181 		case EID_BSSCoexistence:
2182 			break;
2183 		case _LINK_ID_IE_:
2184 			plinkid_ie = (u8 *)pIE;
2185 			break;
2186 		default:
2187 			break;
2188 		}
2189 
2190 		j += (pIE->Length + 2);
2191 
2192 	}
2193 
2194 	ptdls_sta->bssratelen = supportRateNum;
2195 	_rtw_memcpy(ptdls_sta->bssrateset, supportRate, supportRateNum);
2196 	_rtw_memcpy(ptdls_sta->ANonce, ANonce, 32);
2197 
2198 #ifdef CONFIG_WFD
2199 	rtw_tdls_process_wfd_ie(ptdlsinfo, ptr + FIXED_IE, parsing_length);
2200 #endif
2201 
2202 	if (prx_pkt_attrib->encrypt) {
2203 		if (verify_ccmp == 1) {
2204 			txmgmt.status_code = _STATS_SUCCESSFUL_;
2205 			if (rtw_tdls_is_driver_setup(padapter) == _TRUE) {
2206 				wpa_tdls_generate_tpk(padapter, ptdls_sta);
2207 				if (tdls_verify_mic(ptdls_sta->tpk.kck, 2, plinkid_ie, prsnie, ptimeout_ie, pftie) == _FAIL) {
2208 					RTW_INFO("[TDLS] %s tdls_verify_mic fail, free_tdls_sta\n", __FUNCTION__);
2209 					rtw_tdls_teardown_pre_hdl(padapter, ptdls_sta);
2210 					rtw_tdls_cmd(padapter, ptdls_sta->phl_sta->mac_addr, TDLS_TEARDOWN_STA_LOCALLY_POST);
2211 					ret = _FAIL;
2212 					goto exit;
2213 				}
2214 				ptdls_sta->TDLS_PeerKey_Lifetime = timeout_interval;
2215 			}
2216 		} else
2217 			txmgmt.status_code = _STATS_INVALID_RSNIE_;
2218 	} else
2219 		txmgmt.status_code = _STATS_SUCCESSFUL_;
2220 
2221 	if (rtw_tdls_is_driver_setup(padapter) == _TRUE) {
2222 		_rtw_memcpy(txmgmt.peer, prx_pkt_attrib->src, ETH_ALEN);
2223 		issue_tdls_setup_cfm(padapter, &txmgmt);
2224 
2225 		if (txmgmt.status_code == _STATS_SUCCESSFUL_) {
2226 			rtw_tdls_set_link_established(padapter, _TRUE);
2227 
2228 			if (ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE) {
2229 				ptdls_sta->tdls_sta_state |= TDLS_LINKED_STATE;
2230 				ptdls_sta->state |= WIFI_ASOC_STATE;
2231 				_cancel_timer_ex(&ptdls_sta->handshake_timer);
2232 			}
2233 
2234 			if (prx_pkt_attrib->encrypt)
2235 				rtw_tdls_set_key(padapter, ptdls_sta);
2236 
2237 			rtw_tdls_cmd(padapter, ptdls_sta->phl_sta->mac_addr, TDLS_ESTABLISHED);
2238 
2239 		}
2240 	}
2241 
2242 exit:
2243 	if (rtw_tdls_is_driver_setup(padapter) == _TRUE)
2244 		return ret;
2245 	else
2246 		return _SUCCESS;
2247 
2248 }
2249 
On_TDLS_Setup_Cfm(_adapter * padapter,union recv_frame * precv_frame,struct sta_info * ptdls_sta)2250 int On_TDLS_Setup_Cfm(_adapter *padapter, union recv_frame *precv_frame, struct sta_info *ptdls_sta)
2251 {
2252 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
2253 	struct sta_priv *pstapriv = &padapter->stapriv;
2254 	u8 *ptr = precv_frame->u.hdr.rx_data;
2255 	struct rx_pkt_attrib	*prx_pkt_attrib = &precv_frame->u.hdr.attrib;
2256 	u8 *psa;
2257 	u16 status_code = 0;
2258 	sint parsing_length;
2259 	PNDIS_802_11_VARIABLE_IEs	pIE;
2260 	u8 FIXED_IE = 5;
2261 	u8  *pftie = NULL, *ptimeout_ie = NULL, *plinkid_ie = NULL, *prsnie = NULL, *pftie_mic = NULL, *ppairwise_cipher = NULL;
2262 	u16 j, pairwise_count;
2263 	int ret = _SUCCESS;
2264 
2265 	psa = get_sa(ptr);
2266 
2267 	ptr += prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len + LLC_HEADER_SIZE + ETH_TYPE_LEN + PAYLOAD_TYPE_LEN;
2268 	parsing_length = ((union recv_frame *)precv_frame)->u.hdr.len
2269 			 - prx_pkt_attrib->hdrlen
2270 			 - prx_pkt_attrib->iv_len
2271 			 - prx_pkt_attrib->icv_len
2272 			 - LLC_HEADER_SIZE
2273 			 - ETH_TYPE_LEN
2274 			 - PAYLOAD_TYPE_LEN;
2275 
2276 	_rtw_memcpy(&status_code, ptr + 2, 2);
2277 
2278 	if (status_code != 0) {
2279 		RTW_INFO("[%s] status_code = %d\n, free_tdls_sta", __FUNCTION__, status_code);
2280 		rtw_tdls_teardown_pre_hdl(padapter, ptdls_sta);
2281 		rtw_tdls_cmd(padapter, ptdls_sta->phl_sta->mac_addr, TDLS_TEARDOWN_STA_LOCALLY_POST);
2282 		ret = _FAIL;
2283 		goto exit;
2284 	}
2285 
2286 	/* Parsing information element */
2287 	for (j = FIXED_IE; j < parsing_length;) {
2288 
2289 		pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr + j);
2290 
2291 		switch (pIE->ElementID) {
2292 		case _RSN_IE_2_:
2293 			prsnie = (u8 *)pIE;
2294 			break;
2295 		case _VENDOR_SPECIFIC_IE_:
2296 			if (_rtw_memcmp((u8 *)pIE + 2, WMM_PARA_OUI, 6) == _TRUE) {
2297 				/* WMM Parameter ID and OUI */
2298 				ptdls_sta->qos_option = _TRUE;
2299 			}
2300 			break;
2301 		case _FTIE_:
2302 			pftie = (u8 *)pIE;
2303 			break;
2304 		case _TIMEOUT_ITVL_IE_:
2305 			ptimeout_ie = (u8 *)pIE;
2306 			break;
2307 #ifdef CONFIG_80211N_HT
2308 		case _HT_EXTRA_INFO_IE_:
2309 			break;
2310 #endif
2311 #ifdef CONFIG_80211AC_VHT
2312 		case EID_VHTOperation:
2313 			rtw_tdls_process_vht_operation(padapter, ptdls_sta, pIE->data, pIE->Length);
2314 			break;
2315 		case EID_OpModeNotification:
2316 			rtw_tdls_process_vht_op_mode_notify(padapter, ptdls_sta, pIE->data, pIE->Length);
2317 			break;
2318 #endif
2319 		case _LINK_ID_IE_:
2320 			plinkid_ie = (u8 *)pIE;
2321 			break;
2322 		default:
2323 			break;
2324 		}
2325 
2326 		j += (pIE->Length + 2);
2327 
2328 	}
2329 
2330 	if (prx_pkt_attrib->encrypt) {
2331 		/* Verify mic in FTIE MIC field */
2332 		if (rtw_tdls_is_driver_setup(padapter) &&
2333 		    (tdls_verify_mic(ptdls_sta->tpk.kck, 3, plinkid_ie, prsnie, ptimeout_ie, pftie) == _FAIL)) {
2334 			rtw_tdls_teardown_pre_hdl(padapter, ptdls_sta);
2335 			rtw_tdls_cmd(padapter, ptdls_sta->phl_sta->mac_addr, TDLS_TEARDOWN_STA_LOCALLY_POST);
2336 			ret = _FAIL;
2337 			goto exit;
2338 		}
2339 	}
2340 
2341 	if (rtw_tdls_is_driver_setup(padapter)) {
2342 		rtw_tdls_set_link_established(padapter, _TRUE);
2343 
2344 		if (ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE) {
2345 			ptdls_sta->tdls_sta_state |= TDLS_LINKED_STATE;
2346 			ptdls_sta->state |= WIFI_ASOC_STATE;
2347 			_cancel_timer_ex(&ptdls_sta->handshake_timer);
2348 		}
2349 
2350 		if (prx_pkt_attrib->encrypt) {
2351 			rtw_tdls_set_key(padapter, ptdls_sta);
2352 
2353 			/* Start  TPK timer */
2354 			ptdls_sta->TPK_count = 0;
2355 			_set_timer(&ptdls_sta->TPK_timer, ONE_SEC);
2356 		}
2357 
2358 		rtw_tdls_cmd(padapter, ptdls_sta->phl_sta->mac_addr, TDLS_ESTABLISHED);
2359 	}
2360 
2361 exit:
2362 	return ret;
2363 
2364 }
2365 
On_TDLS_Dis_Req(_adapter * padapter,union recv_frame * precv_frame)2366 int On_TDLS_Dis_Req(_adapter *padapter, union recv_frame *precv_frame)
2367 {
2368 	struct rx_pkt_attrib	*prx_pkt_attrib = &precv_frame->u.hdr.attrib;
2369 	struct sta_priv *pstapriv = &padapter->stapriv;
2370 	struct sta_info *psta_ap;
2371 	u8 *ptr = precv_frame->u.hdr.rx_data;
2372 	sint parsing_length;	/* Frame body length, without icv_len */
2373 	PNDIS_802_11_VARIABLE_IEs	pIE;
2374 	u8 FIXED_IE = 3, *dst;
2375 	u16 j;
2376 	struct tdls_txmgmt txmgmt;
2377 	int ret = _SUCCESS;
2378 
2379 	if (rtw_tdls_is_driver_setup(padapter) == _FALSE)
2380 		goto exit;
2381 
2382 	_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
2383 	ptr += prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len + LLC_HEADER_SIZE + ETH_TYPE_LEN + PAYLOAD_TYPE_LEN;
2384 	txmgmt.dialog_token = *(ptr + 2);
2385 	_rtw_memcpy(&txmgmt.peer, precv_frame->u.hdr.attrib.src, ETH_ALEN);
2386 	txmgmt.action_code = TDLS_DISCOVERY_RESPONSE;
2387 	parsing_length = ((union recv_frame *)precv_frame)->u.hdr.len
2388 			 - prx_pkt_attrib->hdrlen
2389 			 - prx_pkt_attrib->iv_len
2390 			 - prx_pkt_attrib->icv_len
2391 			 - LLC_HEADER_SIZE
2392 			 - ETH_TYPE_LEN
2393 			 - PAYLOAD_TYPE_LEN;
2394 
2395 	/* Parsing information element */
2396 	for (j = FIXED_IE; j < parsing_length;) {
2397 
2398 		pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr + j);
2399 
2400 		switch (pIE->ElementID) {
2401 		case _LINK_ID_IE_:
2402 			psta_ap = rtw_get_stainfo(pstapriv, pIE->data);
2403 			if (psta_ap == NULL)
2404 				goto exit;
2405 			dst = pIE->data + 12;
2406 			if (MacAddr_isBcst(dst) == _FALSE && (_rtw_memcmp(adapter_mac_addr(padapter), dst, ETH_ALEN) == _FALSE))
2407 				goto exit;
2408 			break;
2409 		default:
2410 			break;
2411 		}
2412 
2413 		j += (pIE->Length + 2);
2414 
2415 	}
2416 
2417 	issue_tdls_dis_rsp(padapter, &txmgmt, prx_pkt_attrib->privacy);
2418 
2419 exit:
2420 	return ret;
2421 
2422 }
2423 
On_TDLS_Teardown(_adapter * padapter,union recv_frame * precv_frame,struct sta_info * ptdls_sta)2424 int On_TDLS_Teardown(_adapter *padapter, union recv_frame *precv_frame, struct sta_info *ptdls_sta)
2425 {
2426 	u8 *ptr = precv_frame->u.hdr.rx_data;
2427 	struct rx_pkt_attrib	*prx_pkt_attrib = &precv_frame->u.hdr.attrib;
2428 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
2429 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
2430 	struct sta_priv	*pstapriv = &padapter->stapriv;
2431 	u8 reason;
2432 
2433 	reason = *(ptr + prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len + LLC_HEADER_SIZE + ETH_TYPE_LEN + PAYLOAD_TYPE_LEN + 2);
2434 	RTW_INFO("[TDLS] %s Reason code(%d)\n", __FUNCTION__, reason);
2435 
2436 	if (rtw_tdls_is_driver_setup(padapter)) {
2437 		rtw_tdls_teardown_pre_hdl(padapter, ptdls_sta);
2438 		rtw_tdls_cmd(padapter, ptdls_sta->phl_sta->mac_addr, TDLS_TEARDOWN_STA_LOCALLY_POST);
2439 	}
2440 
2441 	return _SUCCESS;
2442 
2443 }
2444 
2445 #if 0
2446 u8 TDLS_check_ch_state(uint state)
2447 {
2448 	if (state & TDLS_CH_SWITCH_ON_STATE &&
2449 	    state & TDLS_PEER_AT_OFF_STATE) {
2450 		if (state & TDLS_PEER_SLEEP_STATE)
2451 			return 2;	/* U-APSD + ch. switch */
2452 		else
2453 			return 1;	/* ch. switch */
2454 	} else
2455 		return 0;
2456 }
2457 #endif
2458 
On_TDLS_Peer_Traffic_Indication(_adapter * padapter,union recv_frame * precv_frame,struct sta_info * ptdls_sta)2459 int On_TDLS_Peer_Traffic_Indication(_adapter *padapter, union recv_frame *precv_frame, struct sta_info *ptdls_sta)
2460 {
2461 	struct rx_pkt_attrib	*pattrib = &precv_frame->u.hdr.attrib;
2462 	u8 *ptr = precv_frame->u.hdr.rx_data;
2463 	struct tdls_txmgmt txmgmt;
2464 
2465 	ptr += pattrib->hdrlen + pattrib->iv_len + LLC_HEADER_SIZE + ETH_TYPE_LEN + PAYLOAD_TYPE_LEN;
2466 	_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
2467 
2468 		txmgmt.dialog_token = *(ptr + 2);
2469 		issue_tdls_peer_traffic_rsp(padapter, ptdls_sta, &txmgmt);
2470 		/* issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->phl_sta->mac_addr, 0, 0, 0); */
2471 
2472 	return _SUCCESS;
2473 }
2474 
2475 /* We process buffered data for 1. U-APSD, 2. ch. switch, 3. U-APSD + ch. switch here */
On_TDLS_Peer_Traffic_Rsp(_adapter * padapter,union recv_frame * precv_frame,struct sta_info * ptdls_sta)2476 int On_TDLS_Peer_Traffic_Rsp(_adapter *padapter, union recv_frame *precv_frame, struct sta_info *ptdls_sta)
2477 {
2478 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
2479 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2480 	struct rx_pkt_attrib	*pattrib = &precv_frame->u.hdr.attrib;
2481 	struct sta_priv *pstapriv = &padapter->stapriv;
2482 	u8 wmmps_ac = 0;
2483 	/* u8 state=TDLS_check_ch_state(ptdls_sta->tdls_sta_state); */
2484 	int i;
2485 
2486 	ptdls_sta->sta_stats.rx_data_pkts++;
2487 
2488 	ptdls_sta->tdls_sta_state &= ~(TDLS_WAIT_PTR_STATE);
2489 
2490 	/* Check 4-AC queue bit */
2491 	if (ptdls_sta->uapsd_vo || ptdls_sta->uapsd_vi || ptdls_sta->uapsd_be || ptdls_sta->uapsd_bk)
2492 		wmmps_ac = 1;
2493 
2494 	/* If it's a direct link and have buffered frame */
2495 	if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) {
2496 		if (wmmps_ac) {
2497 			_list	*xmitframe_plist, *xmitframe_phead;
2498 			struct xmit_frame *pxmitframe = NULL;
2499 
2500 			_rtw_spinlock_bh(&ptdls_sta->sleep_q.lock);
2501 
2502 			xmitframe_phead = get_list_head(&ptdls_sta->sleep_q);
2503 			xmitframe_plist = get_next(xmitframe_phead);
2504 
2505 			/* transmit buffered frames */
2506 			while (rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist) == _FALSE) {
2507 				pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
2508 				xmitframe_plist = get_next(xmitframe_plist);
2509 				rtw_list_delete(&pxmitframe->list);
2510 
2511 				ptdls_sta->sleepq_len--;
2512 				ptdls_sta->sleepq_ac_len--;
2513 				if (ptdls_sta->sleepq_len > 0) {
2514 					pxmitframe->attrib.mdata = 1;
2515 					pxmitframe->attrib.eosp = 0;
2516 				} else {
2517 					pxmitframe->attrib.mdata = 0;
2518 					pxmitframe->attrib.eosp = 1;
2519 				}
2520 				pxmitframe->attrib.triggered = 1;
2521 
2522 				rtw_intf_xmitframe_enqueue(padapter, pxmitframe);
2523 			}
2524 
2525 			if (ptdls_sta->sleepq_len == 0)
2526 				RTW_INFO("no buffered packets for tdls to xmit\n");
2527 			else {
2528 				RTW_INFO("error!psta->sleepq_len=%d\n", ptdls_sta->sleepq_len);
2529 				ptdls_sta->sleepq_len = 0;
2530 			}
2531 
2532 			_rtw_spinunlock_bh(&ptdls_sta->sleep_q.lock);
2533 
2534 		}
2535 
2536 	}
2537 
2538 	return _SUCCESS;
2539 }
2540 
2541 #ifdef CONFIG_TDLS_CH_SW
On_TDLS_Ch_Switch_Req(_adapter * padapter,union recv_frame * precv_frame,struct sta_info * ptdls_sta)2542 sint On_TDLS_Ch_Switch_Req(_adapter *padapter, union recv_frame *precv_frame, struct sta_info *ptdls_sta)
2543 {
2544 	struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
2545 	struct sta_priv *pstapriv = &padapter->stapriv;
2546 	u8 *ptr = precv_frame->u.hdr.rx_data;
2547 	struct rx_pkt_attrib	*prx_pkt_attrib = &precv_frame->u.hdr.attrib;
2548 	sint parsing_length;
2549 	PNDIS_802_11_VARIABLE_IEs	pIE;
2550 	u8 FIXED_IE = 4;
2551 	u16 j;
2552 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2553 	u8 zaddr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2554 	u16 switch_time = TDLS_CH_SWITCH_TIME * 1000, switch_timeout = TDLS_CH_SWITCH_TIMEOUT * 1000;
2555 	u8 take_care_iqk;
2556 
2557 	if (rtw_tdls_is_chsw_allowed(padapter) == _FALSE) {
2558 		RTW_INFO("[TDLS] Ignore %s since channel switch is not allowed\n", __func__);
2559 		return _FAIL;
2560 	}
2561 
2562 	ptdls_sta->ch_switch_time = switch_time;
2563 	ptdls_sta->ch_switch_timeout = switch_timeout;
2564 
2565 	ptr += prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len + LLC_HEADER_SIZE + ETH_TYPE_LEN + PAYLOAD_TYPE_LEN;
2566 	parsing_length = ((union recv_frame *)precv_frame)->u.hdr.len
2567 			 - prx_pkt_attrib->hdrlen
2568 			 - prx_pkt_attrib->iv_len
2569 			 - prx_pkt_attrib->icv_len
2570 			 - LLC_HEADER_SIZE
2571 			 - ETH_TYPE_LEN
2572 			 - PAYLOAD_TYPE_LEN;
2573 
2574 	pchsw_info->off_ch_num = *(ptr + 2);
2575 
2576 	if ((*(ptr + 2) == 2) && (rtw_hw_is_band_support(adapter_to_dvobj(padapter), BAND_ON_5G)))
2577 		pchsw_info->off_ch_num = 44;
2578 
2579 	if (pchsw_info->off_ch_num != pmlmeext->chandef.chan)
2580 		pchsw_info->delay_switch_back = _FALSE;
2581 
2582 	/* Parsing information element */
2583 	for (j = FIXED_IE; j < parsing_length;) {
2584 		pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr + j);
2585 
2586 		switch (pIE->ElementID) {
2587 		case EID_SecondaryChnlOffset:
2588 			switch (*(pIE->data)) {
2589 			case IEEE80211_SCA:
2590 				pchsw_info->ch_offset = CHAN_OFFSET_UPPER;
2591 				break;
2592 
2593 			case IEEE80211_SCB:
2594 				pchsw_info->ch_offset = CHAN_OFFSET_LOWER;
2595 				break;
2596 
2597 			default:/*IEEE80211_SCN*/
2598 				pchsw_info->ch_offset = CHAN_OFFSET_NO_EXT;
2599 				break;
2600 			}
2601 			break;
2602 		case _LINK_ID_IE_:
2603 			break;
2604 		case _CH_SWITCH_TIMING_:
2605 			ptdls_sta->ch_switch_time = (RTW_GET_LE16(pIE->data) >= TDLS_CH_SWITCH_TIME * 1000) ?
2606 				RTW_GET_LE16(pIE->data) : TDLS_CH_SWITCH_TIME * 1000;
2607 			ptdls_sta->ch_switch_timeout = (RTW_GET_LE16(pIE->data + 2) >= TDLS_CH_SWITCH_TIMEOUT * 1000) ?
2608 				RTW_GET_LE16(pIE->data + 2) : TDLS_CH_SWITCH_TIMEOUT * 1000;
2609 			RTW_INFO("[TDLS] %s ch_switch_time:%d, ch_switch_timeout:%d\n"
2610 				, __FUNCTION__, RTW_GET_LE16(pIE->data), RTW_GET_LE16(pIE->data + 2));
2611 		default:
2612 			break;
2613 		}
2614 
2615 		j += (pIE->Length + 2);
2616 	}
2617 
2618 	rtw_hal_get_hwreg(padapter, HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO, &take_care_iqk);
2619 	if (take_care_iqk == _TRUE) {
2620 		u8 central_chnl;
2621 		u8 bw_mode;
2622 
2623 		bw_mode = (pchsw_info->ch_offset) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20;
2624 		central_chnl = rtw_phl_get_center_ch(pchsw_info->off_ch_num, bw_mode, pchsw_info->ch_offset);
2625 		if (rtw_hal_ch_sw_iqk_info_search(padapter, central_chnl, bw_mode) < 0) {
2626 			if (!(pchsw_info->ch_sw_state & TDLS_CH_SWITCH_PREPARE_STATE))
2627 				rtw_tdls_cmd(padapter, ptdls_sta->phl_sta->mac_addr, TDLS_CH_SW_PREPARE);
2628 
2629 			return _FAIL;
2630 		}
2631 	}
2632 
2633 	/* cancel ch sw monitor timer for responder */
2634 	if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
2635 		_cancel_timer_ex(&ptdls_sta->ch_sw_monitor_timer);
2636 
2637 	if (_rtw_memcmp(pchsw_info->addr, zaddr, ETH_ALEN) == _TRUE)
2638 		_rtw_memcpy(pchsw_info->addr, ptdls_sta->phl_sta->mac_addr, ETH_ALEN);
2639 
2640 	if (ATOMIC_READ(&pchsw_info->chsw_on) == _FALSE)
2641 		rtw_tdls_cmd(padapter, ptdls_sta->phl_sta->mac_addr, TDLS_CH_SW_START);
2642 
2643 	rtw_tdls_cmd(padapter, ptdls_sta->phl_sta->mac_addr, TDLS_CH_SW_RESP);
2644 
2645 	return _SUCCESS;
2646 }
2647 
On_TDLS_Ch_Switch_Rsp(_adapter * padapter,union recv_frame * precv_frame,struct sta_info * ptdls_sta)2648 sint On_TDLS_Ch_Switch_Rsp(_adapter *padapter, union recv_frame *precv_frame, struct sta_info *ptdls_sta)
2649 {
2650 	struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
2651 	struct sta_priv *pstapriv = &padapter->stapriv;
2652 	u8 *ptr = precv_frame->u.hdr.rx_data;
2653 	struct rx_pkt_attrib	*prx_pkt_attrib = &precv_frame->u.hdr.attrib;
2654 	sint parsing_length;
2655 	PNDIS_802_11_VARIABLE_IEs	pIE;
2656 	u8 FIXED_IE = 4;
2657 	u16 status_code, j, switch_time, switch_timeout;
2658 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2659 	int ret = _SUCCESS;
2660 
2661 	if (rtw_tdls_is_chsw_allowed(padapter) == _FALSE) {
2662 		RTW_INFO("[TDLS] Ignore %s since channel switch is not allowed\n", __func__);
2663 		return _SUCCESS;
2664 	}
2665 
2666 	/* If we receive Unsolicited TDLS Channel Switch Response when channel switch is running, */
2667 	/* we will go back to base channel and terminate this channel switch procedure */
2668 	if (ATOMIC_READ(&pchsw_info->chsw_on) == _TRUE) {
2669 		if (pmlmeext->chandef.chan != rtw_get_oper_ch(padapter)) {
2670 			RTW_INFO("[TDLS] Rx unsolicited channel switch response\n");
2671 			rtw_tdls_cmd(padapter, ptdls_sta->phl_sta->mac_addr, TDLS_CH_SW_TO_BASE_CHNL);
2672 			goto exit;
2673 		}
2674 	}
2675 
2676 	ptr += prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len + LLC_HEADER_SIZE + ETH_TYPE_LEN + PAYLOAD_TYPE_LEN;
2677 	parsing_length = ((union recv_frame *)precv_frame)->u.hdr.len
2678 			 - prx_pkt_attrib->hdrlen
2679 			 - prx_pkt_attrib->iv_len
2680 			 - prx_pkt_attrib->icv_len
2681 			 - LLC_HEADER_SIZE
2682 			 - ETH_TYPE_LEN
2683 			 - PAYLOAD_TYPE_LEN;
2684 
2685 	_rtw_memcpy(&status_code, ptr + 2, 2);
2686 
2687 	if (status_code != 0) {
2688 		RTW_INFO("[TDLS] %s status_code:%d\n", __func__, status_code);
2689 		pchsw_info->ch_sw_state &= ~(TDLS_CH_SW_INITIATOR_STATE);
2690 		rtw_tdls_cmd(padapter, ptdls_sta->phl_sta->mac_addr, TDLS_CH_SW_END);
2691 		ret = _FAIL;
2692 		goto exit;
2693 	}
2694 
2695 	/* Parsing information element */
2696 	for (j = FIXED_IE; j < parsing_length;) {
2697 		pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr + j);
2698 
2699 		switch (pIE->ElementID) {
2700 		case _LINK_ID_IE_:
2701 			break;
2702 		case _CH_SWITCH_TIMING_:
2703 			_rtw_memcpy(&switch_time, pIE->data, 2);
2704 			if (switch_time > ptdls_sta->ch_switch_time)
2705 				_rtw_memcpy(&ptdls_sta->ch_switch_time, &switch_time, 2);
2706 
2707 			_rtw_memcpy(&switch_timeout, pIE->data + 2, 2);
2708 			if (switch_timeout > ptdls_sta->ch_switch_timeout)
2709 				_rtw_memcpy(&ptdls_sta->ch_switch_timeout, &switch_timeout, 2);
2710 			break;
2711 		default:
2712 			break;
2713 		}
2714 
2715 		j += (pIE->Length + 2);
2716 	}
2717 
2718 	if ((pmlmeext->chandef.chan == rtw_get_oper_ch(padapter)) &&
2719 	    (pchsw_info->ch_sw_state & TDLS_WAIT_CH_RSP_STATE)) {
2720 		if (ATOMIC_READ(&pchsw_info->chsw_on) == _TRUE)
2721 			rtw_tdls_cmd(padapter, ptdls_sta->phl_sta->mac_addr, TDLS_CH_SW_TO_OFF_CHNL);
2722 	}
2723 
2724 exit:
2725 	return ret;
2726 }
2727 #endif /* CONFIG_TDLS_CH_SW */
2728 
2729 #ifdef CONFIG_WFD
wfd_ie_tdls(_adapter * padapter,u8 * pframe,u32 * pktlen)2730 void wfd_ie_tdls(_adapter *padapter, u8 *pframe, u32 *pktlen)
2731 {
2732 	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
2733 	struct wifi_display_info	*pwfd_info = padapter->tdlsinfo.wfd_info;
2734 	u8 wfdie[MAX_WFD_IE_LEN] = { 0x00 };
2735 	u32 wfdielen = 0;
2736 	u16 v16 = 0;
2737 
2738 	if (!rtw_hw_chk_wl_func(adapter_to_dvobj(padapter), WL_FUNC_MIRACAST))
2739 		return;
2740 
2741 	/* WFD OUI */
2742 	wfdielen = 0;
2743 	wfdie[wfdielen++] = 0x50;
2744 	wfdie[wfdielen++] = 0x6F;
2745 	wfdie[wfdielen++] = 0x9A;
2746 	wfdie[wfdielen++] = 0x0A;	/* WFA WFD v1.0 */
2747 
2748 	/*
2749 	 *	Commented by Albert 20110825
2750 	 *	According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes
2751 	 *	1. WFD Device Information
2752 	 *	2. Associated BSSID ( Optional )
2753 	 *	3. Local IP Adress ( Optional )
2754 	 */
2755 
2756 	/* WFD Device Information ATTR */
2757 	/* Type: */
2758 	wfdie[wfdielen++] = WFD_ATTR_DEVICE_INFO;
2759 
2760 	/* Length: */
2761 	/* Note: In the WFD specification, the size of length field is 2. */
2762 	RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
2763 	wfdielen += 2;
2764 
2765 	/* Value1: */
2766 	/* WFD device information */
2767 	/* available for WFD session + Preferred TDLS + WSD ( WFD Service Discovery ) */
2768 	v16 = pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL
2769 		| WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_WSD;
2770 	RTW_PUT_BE16(wfdie + wfdielen, v16);
2771 	wfdielen += 2;
2772 
2773 	/* Value2: */
2774 	/* Session Management Control Port */
2775 	/* Default TCP port for RTSP messages is 554 */
2776 	RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->tdls_rtsp_ctrlport);
2777 	wfdielen += 2;
2778 
2779 	/* Value3: */
2780 	/* WFD Device Maximum Throughput */
2781 	/* 300Mbps is the maximum throughput */
2782 	RTW_PUT_BE16(wfdie + wfdielen, 300);
2783 	wfdielen += 2;
2784 
2785 	/* Associated BSSID ATTR */
2786 	/* Type: */
2787 	wfdie[wfdielen++] = WFD_ATTR_ASSOC_BSSID;
2788 
2789 	/* Length: */
2790 	/* Note: In the WFD specification, the size of length field is 2. */
2791 	RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
2792 	wfdielen += 2;
2793 
2794 	/* Value: */
2795 	/* Associated BSSID */
2796 	if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)
2797 		_rtw_memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[0], ETH_ALEN);
2798 	else
2799 		_rtw_memset(wfdie + wfdielen, 0x00, ETH_ALEN);
2800 
2801 	/* Local IP Address ATTR */
2802 	wfdie[wfdielen++] = WFD_ATTR_LOCAL_IP_ADDR;
2803 
2804 	/* Length: */
2805 	/* Note: In the WFD specification, the size of length field is 2. */
2806 	RTW_PUT_BE16(wfdie + wfdielen, 0x0005);
2807 	wfdielen += 2;
2808 
2809 	/* Version: */
2810 	/* 0x01: Version1;IPv4 */
2811 	wfdie[wfdielen++] = 0x01;
2812 
2813 	/* IPv4 Address */
2814 	_rtw_memcpy(wfdie + wfdielen, pwfd_info->ip_address, 4);
2815 	wfdielen += 4;
2816 
2817 	pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, pktlen);
2818 
2819 }
2820 #endif /* CONFIG_WFD */
2821 
rtw_build_tdls_setup_req_ies(_adapter * padapter,struct xmit_frame * pxmitframe,u8 * pframe,struct tdls_txmgmt * ptxmgmt,struct sta_info * ptdls_sta)2822 void rtw_build_tdls_setup_req_ies(_adapter *padapter, struct xmit_frame *pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt, struct sta_info *ptdls_sta)
2823 {
2824 	struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
2825 	struct registry_priv	*pregistrypriv = &padapter->registrypriv;
2826 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
2827 	struct pkt_attrib	*pattrib = &pxmitframe->attrib;
2828 	int i = 0 ;
2829 	u32 time;
2830 	u8 *pframe_head;
2831 
2832 	/* SNonce */
2833 	if (pattrib->encrypt) {
2834 		for (i = 0; i < 8; i++) {
2835 			time = rtw_get_current_time();
2836 			_rtw_memcpy(&ptdls_sta->SNonce[4 * i], (u8 *)&time, 4);
2837 		}
2838 	}
2839 
2840 	pframe_head = pframe;	/* For rtw_tdls_set_ht_cap() */
2841 
2842 	pframe = rtw_tdls_set_payload_type(pframe, pattrib);
2843 	pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS);
2844 	pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt);
2845 	pframe = rtw_tdls_set_dialog(pframe, pattrib, ptxmgmt);
2846 
2847 	pframe = rtw_tdls_set_capability(padapter, pframe, pattrib);
2848 	pframe = rtw_tdls_set_supported_rate(padapter, pframe, pattrib);
2849 	pframe = rtw_tdls_set_sup_ch(padapter, pframe, pattrib);
2850 	pframe = rtw_tdls_set_sup_reg_class(pframe, pattrib);
2851 
2852 	if (pattrib->encrypt)
2853 		pframe = rtw_tdls_set_rsnie(ptxmgmt, pframe, pattrib,  _TRUE, ptdls_sta);
2854 
2855 	pframe = rtw_tdls_set_ext_cap(pframe, pattrib);
2856 
2857 	if (pattrib->encrypt) {
2858 		pframe = rtw_tdls_set_ftie(ptxmgmt
2859 					   , pframe
2860 					   , pattrib
2861 					   , NULL
2862 					   , ptdls_sta->SNonce);
2863 
2864 		pframe = rtw_tdls_set_timeout_interval(ptxmgmt, pframe, pattrib, _TRUE, ptdls_sta);
2865 	}
2866 
2867 #ifdef CONFIG_80211N_HT
2868 	/* Sup_reg_classes(optional) */
2869 	if (pregistrypriv->ht_enable == _TRUE)
2870 		pframe = rtw_tdls_set_ht_cap(padapter, pframe_head, pattrib);
2871 #endif
2872 
2873 	pframe = rtw_tdls_set_bss_coexist(padapter, pframe, pattrib);
2874 
2875 	pframe = rtw_tdls_set_linkid(padapter, pframe, pattrib, _TRUE);
2876 
2877 	if ((pregistrypriv->wmm_enable == _TRUE) || (padapter->mlmepriv.htpriv.ht_option == _TRUE))
2878 		pframe = rtw_tdls_set_qos_cap(pframe, pattrib);
2879 
2880 #ifdef CONFIG_80211AC_VHT
2881 	if ((padapter->mlmepriv.htpriv.ht_option == _TRUE) && (pmlmeext->chandef.chan > 14)
2882 	    && REGSTY_IS_11AC_ENABLE(pregistrypriv)
2883 	    && is_supported_vht(pregistrypriv->wireless_mode)
2884 	    && RFCTL_REG_EN_11AC(rfctl)
2885 	) {
2886 		pframe = rtw_tdls_set_aid(padapter, pframe, pattrib);
2887 		pframe = rtw_tdls_set_vht_cap(padapter, pframe, pattrib);
2888 	}
2889 #endif
2890 
2891 #ifdef CONFIG_WFD
2892 	if (padapter->wdinfo.wfd_tdls_enable == 1)
2893 		wfd_ie_tdls(padapter, pframe, &(pattrib->pktlen));
2894 #endif
2895 
2896 }
2897 
rtw_build_tdls_setup_rsp_ies(_adapter * padapter,struct xmit_frame * pxmitframe,u8 * pframe,struct tdls_txmgmt * ptxmgmt,struct sta_info * ptdls_sta)2898 void rtw_build_tdls_setup_rsp_ies(_adapter *padapter, struct xmit_frame *pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt, struct sta_info *ptdls_sta)
2899 {
2900 	struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
2901 	struct registry_priv	*pregistrypriv = &padapter->registrypriv;
2902 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
2903 	struct pkt_attrib	*pattrib = &pxmitframe->attrib;
2904 	u8 k; /* for random ANonce */
2905 	u8  *pftie = NULL, *ptimeout_ie = NULL, *plinkid_ie = NULL, *prsnie = NULL, *pftie_mic = NULL;
2906 	u32 time;
2907 	u8 *pframe_head;
2908 
2909 	if (pattrib->encrypt) {
2910 		for (k = 0; k < 8; k++) {
2911 			time = rtw_get_current_time();
2912 			_rtw_memcpy(&ptdls_sta->ANonce[4 * k], (u8 *)&time, 4);
2913 		}
2914 	}
2915 
2916 	pframe_head = pframe;
2917 
2918 	pframe = rtw_tdls_set_payload_type(pframe, pattrib);
2919 	pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS);
2920 	pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt);
2921 	pframe = rtw_tdls_set_status_code(pframe, pattrib, ptxmgmt);
2922 
2923 	if (ptxmgmt->status_code != 0) {
2924 		RTW_INFO("[%s] status_code:%04x\n", __FUNCTION__, ptxmgmt->status_code);
2925 		return;
2926 	}
2927 
2928 	pframe = rtw_tdls_set_dialog(pframe, pattrib, ptxmgmt);
2929 	pframe = rtw_tdls_set_capability(padapter, pframe, pattrib);
2930 	pframe = rtw_tdls_set_supported_rate(padapter, pframe, pattrib);
2931 	pframe = rtw_tdls_set_sup_ch(padapter, pframe, pattrib);
2932 	pframe = rtw_tdls_set_sup_reg_class(pframe, pattrib);
2933 
2934 	if (pattrib->encrypt) {
2935 		prsnie = pframe;
2936 		pframe = rtw_tdls_set_rsnie(ptxmgmt, pframe, pattrib,  _FALSE, ptdls_sta);
2937 	}
2938 
2939 	pframe = rtw_tdls_set_ext_cap(pframe, pattrib);
2940 
2941 	if (pattrib->encrypt) {
2942 		if (rtw_tdls_is_driver_setup(padapter) == _TRUE)
2943 			wpa_tdls_generate_tpk(padapter, ptdls_sta);
2944 
2945 		pftie = pframe;
2946 		pftie_mic = pframe + 4;
2947 		pframe = rtw_tdls_set_ftie(ptxmgmt
2948 					   , pframe
2949 					   , pattrib
2950 					   , ptdls_sta->ANonce
2951 					   , ptdls_sta->SNonce);
2952 
2953 		ptimeout_ie = pframe;
2954 		pframe = rtw_tdls_set_timeout_interval(ptxmgmt, pframe, pattrib, _FALSE, ptdls_sta);
2955 	}
2956 
2957 #ifdef CONFIG_80211N_HT
2958 	/* Sup_reg_classes(optional) */
2959 	if (pregistrypriv->ht_enable == _TRUE)
2960 		pframe = rtw_tdls_set_ht_cap(padapter, pframe_head, pattrib);
2961 #endif
2962 
2963 	pframe = rtw_tdls_set_bss_coexist(padapter, pframe, pattrib);
2964 
2965 	plinkid_ie = pframe;
2966 	pframe = rtw_tdls_set_linkid(padapter, pframe, pattrib, _FALSE);
2967 
2968 	/* Fill FTIE mic */
2969 	if (pattrib->encrypt && rtw_tdls_is_driver_setup(padapter) == _TRUE)
2970 		wpa_tdls_ftie_mic(ptdls_sta->tpk.kck, 2, plinkid_ie, prsnie, ptimeout_ie, pftie, pftie_mic);
2971 
2972 	if ((pregistrypriv->wmm_enable == _TRUE) || (padapter->mlmepriv.htpriv.ht_option == _TRUE))
2973 		pframe = rtw_tdls_set_qos_cap(pframe, pattrib);
2974 
2975 #ifdef CONFIG_80211AC_VHT
2976 	if ((padapter->mlmepriv.htpriv.ht_option == _TRUE) && (pmlmeext->chandef.chan > 14)
2977 	    && REGSTY_IS_11AC_ENABLE(pregistrypriv)
2978 	    && is_supported_vht(pregistrypriv->wireless_mode)
2979 	    && RFCTL_REG_EN_11AC(rfctl)
2980 	) {
2981 		pframe = rtw_tdls_set_aid(padapter, pframe, pattrib);
2982 		pframe = rtw_tdls_set_vht_cap(padapter, pframe, pattrib);
2983 		pframe = rtw_tdls_set_vht_op_mode_notify(padapter, pframe, pattrib, pmlmeext->chandef.bw);
2984 	}
2985 #endif
2986 
2987 #ifdef CONFIG_WFD
2988 	if (padapter->wdinfo.wfd_tdls_enable)
2989 		wfd_ie_tdls(padapter, pframe, &(pattrib->pktlen));
2990 #endif
2991 
2992 }
2993 
rtw_build_tdls_setup_cfm_ies(_adapter * padapter,struct xmit_frame * pxmitframe,u8 * pframe,struct tdls_txmgmt * ptxmgmt,struct sta_info * ptdls_sta)2994 void rtw_build_tdls_setup_cfm_ies(_adapter *padapter, struct xmit_frame *pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt, struct sta_info *ptdls_sta)
2995 {
2996 	struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
2997 	struct registry_priv	*pregistrypriv = &padapter->registrypriv;
2998 	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
2999 	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
3000 	struct pkt_attrib	*pattrib = &pxmitframe->attrib;
3001 
3002 	unsigned int ie_len;
3003 	unsigned char *p;
3004 	u8 wmm_param_ele[24] = {0};
3005 	u8  *pftie = NULL, *ptimeout_ie = NULL, *plinkid_ie = NULL, *prsnie = NULL, *pftie_mic = NULL;
3006 
3007 	pframe = rtw_tdls_set_payload_type(pframe, pattrib);
3008 	pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS);
3009 	pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt);
3010 	pframe = rtw_tdls_set_status_code(pframe, pattrib, ptxmgmt);
3011 	pframe = rtw_tdls_set_dialog(pframe, pattrib, ptxmgmt);
3012 
3013 	if (ptxmgmt->status_code != 0)
3014 		return;
3015 
3016 	if (pattrib->encrypt) {
3017 		prsnie = pframe;
3018 		pframe = rtw_tdls_set_rsnie(ptxmgmt, pframe, pattrib, _TRUE, ptdls_sta);
3019 	}
3020 
3021 	if (pattrib->encrypt) {
3022 		pftie = pframe;
3023 		pftie_mic = pframe + 4;
3024 		pframe = rtw_tdls_set_ftie(ptxmgmt
3025 					   , pframe
3026 					   , pattrib
3027 					   , ptdls_sta->ANonce
3028 					   , ptdls_sta->SNonce);
3029 
3030 		ptimeout_ie = pframe;
3031 		pframe = rtw_tdls_set_timeout_interval(ptxmgmt, pframe, pattrib, _TRUE, ptdls_sta);
3032 
3033 		if (rtw_tdls_is_driver_setup(padapter) == _TRUE) {
3034 			/* Start TPK timer */
3035 			ptdls_sta->TPK_count = 0;
3036 			_set_timer(&ptdls_sta->TPK_timer, ONE_SEC);
3037 		}
3038 	}
3039 
3040 	/* HT operation; todo */
3041 
3042 	plinkid_ie = pframe;
3043 	pframe = rtw_tdls_set_linkid(padapter, pframe, pattrib, _TRUE);
3044 
3045 	if (pattrib->encrypt && (rtw_tdls_is_driver_setup(padapter) == _TRUE))
3046 		wpa_tdls_ftie_mic(ptdls_sta->tpk.kck, 3, plinkid_ie, prsnie, ptimeout_ie, pftie, pftie_mic);
3047 
3048 	if (ptdls_sta->qos_option == _TRUE)
3049 		pframe = rtw_tdls_set_wmm_params(padapter, pframe, pattrib);
3050 
3051 #ifdef CONFIG_80211AC_VHT
3052 	if ((padapter->mlmepriv.htpriv.ht_option == _TRUE)
3053 	    && (ptdls_sta->vhtpriv.vht_option == _TRUE) && (pmlmeext->chandef.chan > 14)
3054 	    && REGSTY_IS_11AC_ENABLE(pregistrypriv)
3055 	    && is_supported_vht(pregistrypriv->wireless_mode)
3056 	    && RFCTL_REG_EN_11AC(rfctl)
3057 	) {
3058 		pframe = rtw_tdls_set_vht_operation(padapter, pframe, pattrib, pmlmeext->chandef.chan);
3059 		pframe = rtw_tdls_set_vht_op_mode_notify(padapter, pframe, pattrib, pmlmeext->chandef.bw);
3060 	}
3061 #endif
3062 }
3063 
rtw_build_tdls_teardown_ies(_adapter * padapter,struct xmit_frame * pxmitframe,u8 * pframe,struct tdls_txmgmt * ptxmgmt,struct sta_info * ptdls_sta)3064 void rtw_build_tdls_teardown_ies(_adapter *padapter, struct xmit_frame *pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt, struct sta_info *ptdls_sta)
3065 {
3066 	struct pkt_attrib	*pattrib = &pxmitframe->attrib;
3067 	u8  *pftie = NULL, *pftie_mic = NULL, *plinkid_ie = NULL;
3068 
3069 	pframe = rtw_tdls_set_payload_type(pframe, pattrib);
3070 	pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS);
3071 	pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt);
3072 	pframe = rtw_tdls_set_status_code(pframe, pattrib, ptxmgmt);
3073 
3074 	if (pattrib->encrypt) {
3075 		pftie = pframe;
3076 		pftie_mic = pframe + 4;
3077 		pframe = rtw_tdls_set_ftie(ptxmgmt
3078 					   , pframe
3079 					   , pattrib
3080 					   , ptdls_sta->ANonce
3081 					   , ptdls_sta->SNonce);
3082 	}
3083 
3084 	plinkid_ie = pframe;
3085 	if (ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE)
3086 		pframe = rtw_tdls_set_linkid(padapter, pframe, pattrib, _FALSE);
3087 	else if (ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE)
3088 		pframe = rtw_tdls_set_linkid(padapter, pframe, pattrib, _TRUE);
3089 
3090 	if (pattrib->encrypt && (rtw_tdls_is_driver_setup(padapter) == _TRUE))
3091 		wpa_tdls_teardown_ftie_mic(ptdls_sta->tpk.kck, plinkid_ie, ptxmgmt->status_code, 1, 4, pftie, pftie_mic);
3092 }
3093 
rtw_build_tdls_dis_req_ies(_adapter * padapter,struct xmit_frame * pxmitframe,u8 * pframe,struct tdls_txmgmt * ptxmgmt)3094 void rtw_build_tdls_dis_req_ies(_adapter *padapter, struct xmit_frame *pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt)
3095 {
3096 	struct pkt_attrib *pattrib = &pxmitframe->attrib;
3097 
3098 	pframe = rtw_tdls_set_payload_type(pframe, pattrib);
3099 	pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS);
3100 	pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt);
3101 	pframe = rtw_tdls_set_dialog(pframe, pattrib, ptxmgmt);
3102 	pframe = rtw_tdls_set_linkid(padapter, pframe, pattrib, _TRUE);
3103 
3104 }
3105 
rtw_build_tdls_dis_rsp_ies(_adapter * padapter,struct xmit_frame * pxmitframe,u8 * pframe,struct tdls_txmgmt * ptxmgmt,u8 privacy)3106 void rtw_build_tdls_dis_rsp_ies(_adapter *padapter, struct xmit_frame *pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt, u8 privacy)
3107 {
3108 	struct registry_priv	*pregistrypriv = &padapter->registrypriv;
3109 	struct mlme_ext_priv	*pmlmeext = &padapter->mlmeextpriv;
3110 	struct pkt_attrib	*pattrib = &pxmitframe->attrib;
3111 	u8 *pframe_head, pktlen_index;
3112 
3113 	pktlen_index = pattrib->pktlen;
3114 	pframe_head = pframe;
3115 
3116 	pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_PUBLIC);
3117 	pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt);
3118 	pframe = rtw_tdls_set_dialog(pframe, pattrib, ptxmgmt);
3119 	pframe = rtw_tdls_set_capability(padapter, pframe, pattrib);
3120 
3121 	pframe = rtw_tdls_set_supported_rate(padapter, pframe, pattrib);
3122 
3123 	pframe = rtw_tdls_set_sup_ch(padapter, pframe, pattrib);
3124 
3125 	if (privacy)
3126 		pframe = rtw_tdls_set_rsnie(ptxmgmt, pframe, pattrib, _TRUE, NULL);
3127 
3128 	pframe = rtw_tdls_set_ext_cap(pframe, pattrib);
3129 
3130 	if (privacy) {
3131 		pframe = rtw_tdls_set_ftie(ptxmgmt, pframe, pattrib, NULL, NULL);
3132 		pframe = rtw_tdls_set_timeout_interval(ptxmgmt, pframe, pattrib,  _TRUE, NULL);
3133 	}
3134 
3135 #ifdef CONFIG_80211N_HT
3136 	if (pregistrypriv->ht_enable == _TRUE)
3137 		pframe = rtw_tdls_set_ht_cap(padapter, pframe_head - pktlen_index, pattrib);
3138 #endif
3139 
3140 	pframe = rtw_tdls_set_bss_coexist(padapter, pframe, pattrib);
3141 	pframe = rtw_tdls_set_linkid(padapter, pframe, pattrib, _FALSE);
3142 
3143 }
3144 
3145 
rtw_build_tdls_peer_traffic_indication_ies(_adapter * padapter,struct xmit_frame * pxmitframe,u8 * pframe,struct tdls_txmgmt * ptxmgmt,struct sta_info * ptdls_sta)3146 void rtw_build_tdls_peer_traffic_indication_ies(_adapter *padapter, struct xmit_frame *pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt, struct sta_info *ptdls_sta)
3147 {
3148 
3149 	struct pkt_attrib	*pattrib = &pxmitframe->attrib;
3150 	u8 AC_queue = 0;
3151 
3152 	pframe = rtw_tdls_set_payload_type(pframe, pattrib);
3153 	pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS);
3154 	pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt);
3155 	pframe = rtw_tdls_set_dialog(pframe, pattrib, ptxmgmt);
3156 
3157 	if (ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE)
3158 		pframe = rtw_tdls_set_linkid(padapter, pframe, pattrib, _FALSE);
3159 	else if (ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE)
3160 		pframe = rtw_tdls_set_linkid(padapter, pframe, pattrib, _TRUE);
3161 
3162 	/* PTI control */
3163 	/* PU buffer status */
3164 	if (ptdls_sta->uapsd_bk & BIT(1))
3165 		AC_queue = BIT(0);
3166 	if (ptdls_sta->uapsd_be & BIT(1))
3167 		AC_queue = BIT(1);
3168 	if (ptdls_sta->uapsd_vi & BIT(1))
3169 		AC_queue = BIT(2);
3170 	if (ptdls_sta->uapsd_vo & BIT(1))
3171 		AC_queue = BIT(3);
3172 	pframe = rtw_set_ie(pframe, _PTI_BUFFER_STATUS_, 1, &AC_queue, &(pattrib->pktlen));
3173 
3174 }
3175 
rtw_build_tdls_peer_traffic_rsp_ies(_adapter * padapter,struct xmit_frame * pxmitframe,u8 * pframe,struct tdls_txmgmt * ptxmgmt,struct sta_info * ptdls_sta)3176 void rtw_build_tdls_peer_traffic_rsp_ies(_adapter *padapter, struct xmit_frame *pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt, struct sta_info *ptdls_sta)
3177 {
3178 
3179 	struct pkt_attrib	*pattrib = &pxmitframe->attrib;
3180 
3181 	pframe = rtw_tdls_set_payload_type(pframe, pattrib);
3182 	pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS);
3183 	pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt);
3184 	pframe = rtw_tdls_set_dialog(pframe, pattrib, ptxmgmt);
3185 
3186 	if (ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE)
3187 		pframe = rtw_tdls_set_linkid(padapter, pframe, pattrib, _FALSE);
3188 	else if (ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE)
3189 		pframe = rtw_tdls_set_linkid(padapter, pframe, pattrib, _TRUE);
3190 }
3191 
3192 #ifdef CONFIG_TDLS_CH_SW
rtw_build_tdls_ch_switch_req_ies(_adapter * padapter,struct xmit_frame * pxmitframe,u8 * pframe,struct tdls_txmgmt * ptxmgmt,struct sta_info * ptdls_sta)3193 void rtw_build_tdls_ch_switch_req_ies(_adapter *padapter, struct xmit_frame *pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt, struct sta_info *ptdls_sta)
3194 {
3195 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
3196 	struct pkt_attrib	*pattrib = &pxmitframe->attrib;
3197 	struct sta_priv	*pstapriv = &padapter->stapriv;
3198 	u16 switch_time = TDLS_CH_SWITCH_TIME * 1000, switch_timeout = TDLS_CH_SWITCH_TIMEOUT * 1000;
3199 
3200 	ptdls_sta->ch_switch_time = switch_time;
3201 	ptdls_sta->ch_switch_timeout = switch_timeout;
3202 
3203 	pframe = rtw_tdls_set_payload_type(pframe, pattrib);
3204 	pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS);
3205 	pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt);
3206 	pframe = rtw_tdls_set_target_ch(padapter, pframe, pattrib);
3207 	pframe = rtw_tdls_set_reg_class(pframe, pattrib, ptdls_sta);
3208 
3209 	if (ptdlsinfo->chsw_info.ch_offset != CHAN_OFFSET_NO_EXT) {
3210 		switch (ptdlsinfo->chsw_info.ch_offset) {
3211 		case CHAN_OFFSET_UPPER:
3212 			pframe = rtw_tdls_set_second_channel_offset(pframe, pattrib, IEEE80211_SCA);
3213 			break;
3214 		case CHAN_OFFSET_LOWER:
3215 			pframe = rtw_tdls_set_second_channel_offset(pframe, pattrib, IEEE80211_SCB);
3216 			break;
3217 		}
3218 	}
3219 
3220 	if (ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE)
3221 		pframe = rtw_tdls_set_linkid(padapter, pframe, pattrib, _FALSE);
3222 	else if (ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE)
3223 		pframe = rtw_tdls_set_linkid(padapter, pframe, pattrib, _TRUE);
3224 
3225 	pframe = rtw_tdls_set_ch_sw(pframe, pattrib, ptdls_sta);
3226 
3227 }
3228 
rtw_build_tdls_ch_switch_rsp_ies(_adapter * padapter,struct xmit_frame * pxmitframe,u8 * pframe,struct tdls_txmgmt * ptxmgmt,struct sta_info * ptdls_sta)3229 void rtw_build_tdls_ch_switch_rsp_ies(_adapter *padapter, struct xmit_frame *pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt, struct sta_info *ptdls_sta)
3230 {
3231 
3232 	struct pkt_attrib	*pattrib = &pxmitframe->attrib;
3233 	struct sta_priv	*pstapriv = &padapter->stapriv;
3234 
3235 	pframe = rtw_tdls_set_payload_type(pframe, pattrib);
3236 	pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS);
3237 	pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt);
3238 	pframe = rtw_tdls_set_status_code(pframe, pattrib, ptxmgmt);
3239 
3240 	if (ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE)
3241 		pframe = rtw_tdls_set_linkid(padapter, pframe, pattrib, _FALSE);
3242 	else if (ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE)
3243 		pframe = rtw_tdls_set_linkid(padapter, pframe, pattrib, _TRUE);
3244 
3245 	pframe = rtw_tdls_set_ch_sw(pframe, pattrib, ptdls_sta);
3246 }
3247 #endif
3248 
3249 #ifdef CONFIG_WFD
rtw_build_tunneled_probe_req_ies(_adapter * padapter,struct xmit_frame * pxmitframe,u8 * pframe)3250 void rtw_build_tunneled_probe_req_ies(_adapter *padapter, struct xmit_frame *pxmitframe, u8 *pframe)
3251 {
3252 	u8 i;
3253 	_adapter *iface = NULL;
3254 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
3255 	struct pkt_attrib *pattrib = &pxmitframe->attrib;
3256 	struct wifidirect_info *pwdinfo;
3257 
3258 	u8 category = RTW_WLAN_CATEGORY_P2P;
3259 	u8 WFA_OUI[3] = { 0x50, 0x6f, 0x9a};
3260 	u8 probe_req = 4;
3261 	u8 wfdielen = 0;
3262 
3263 	pframe = rtw_tdls_set_payload_type(pframe, pattrib);
3264 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
3265 	pframe = rtw_set_fixed_ie(pframe, 3, WFA_OUI, &(pattrib->pktlen));
3266 	pframe = rtw_set_fixed_ie(pframe, 1, &(probe_req), &(pattrib->pktlen));
3267 
3268 	for (i = 0; i < dvobj->iface_nums; i++) {
3269 		iface = dvobj->padapters[i];
3270 		if ((iface) && rtw_is_adapter_up(iface)) {
3271 			pwdinfo = &iface->wdinfo;
3272 			if (pwdinfo->wfd_tdls_enable) {
3273 				wfdielen = build_probe_req_wfd_ie(pwdinfo, pframe);
3274 				pframe += wfdielen;
3275 				pattrib->pktlen += wfdielen;
3276 			}
3277 		}
3278 	}
3279 }
3280 
rtw_build_tunneled_probe_rsp_ies(_adapter * padapter,struct xmit_frame * pxmitframe,u8 * pframe)3281 void rtw_build_tunneled_probe_rsp_ies(_adapter *padapter, struct xmit_frame *pxmitframe, u8 *pframe)
3282 {
3283 	u8 i;
3284 	_adapter *iface = NULL;
3285 	struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
3286 	struct pkt_attrib	*pattrib = &pxmitframe->attrib;
3287 	struct wifidirect_info *pwdinfo;
3288 	u8 category = RTW_WLAN_CATEGORY_P2P;
3289 	u8 WFA_OUI[3] = { 0x50, 0x6f, 0x9a};
3290 	u8 probe_rsp = 5;
3291 	u8 wfdielen = 0;
3292 
3293 	pframe = rtw_tdls_set_payload_type(pframe, pattrib);
3294 	pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
3295 	pframe = rtw_set_fixed_ie(pframe, 3, WFA_OUI, &(pattrib->pktlen));
3296 	pframe = rtw_set_fixed_ie(pframe, 1, &(probe_rsp), &(pattrib->pktlen));
3297 
3298 	for (i = 0; i < dvobj->iface_nums; i++) {
3299 		iface = dvobj->padapters[i];
3300 		if ((iface) && rtw_is_adapter_up(iface)) {
3301 			pwdinfo = &iface->wdinfo;
3302 			if (pwdinfo->wfd_tdls_enable) {
3303 				wfdielen = build_probe_resp_wfd_ie(pwdinfo, pframe, 1);
3304 				pframe += wfdielen;
3305 				pattrib->pktlen += wfdielen;
3306 			}
3307 		}
3308 	}
3309 }
3310 #endif /* CONFIG_WFD */
3311 
_tdls_tpk_timer_hdl(void * FunctionContext)3312 void _tdls_tpk_timer_hdl(void *FunctionContext)
3313 {
3314 	struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
3315 	struct tdls_txmgmt txmgmt;
3316 
3317 	_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
3318 	ptdls_sta->TPK_count++;
3319 	/* TPK_timer expired in a second */
3320 	/* Retry timer should set at least 301 sec. */
3321 	if (ptdls_sta->TPK_count >= (ptdls_sta->TDLS_PeerKey_Lifetime - 3)) {
3322 		RTW_INFO("[TDLS] %s, Re-Setup TDLS link with "MAC_FMT" since TPK lifetime expires!\n",
3323 			__FUNCTION__, MAC_ARG(ptdls_sta->phl_sta->mac_addr));
3324 		ptdls_sta->TPK_count = 0;
3325 		_rtw_memcpy(txmgmt.peer, ptdls_sta->phl_sta->mac_addr, ETH_ALEN);
3326 		issue_tdls_setup_req(ptdls_sta->padapter, &txmgmt, _FALSE);
3327 	}
3328 
3329 	_set_timer(&ptdls_sta->TPK_timer, ONE_SEC);
3330 }
3331 
3332 #ifdef CONFIG_TDLS_CH_SW
_tdls_ch_switch_timer_hdl(void * FunctionContext)3333 void _tdls_ch_switch_timer_hdl(void *FunctionContext)
3334 {
3335 	struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
3336 	_adapter *padapter = ptdls_sta->padapter;
3337 	struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
3338 
3339 	rtw_tdls_cmd(padapter, ptdls_sta->phl_sta->mac_addr, TDLS_CH_SW_END_TO_BASE_CHNL);
3340 	RTW_INFO("[TDLS] %s, can't get traffic from op_ch:%d\n", __func__, rtw_get_oper_ch(padapter));
3341 }
3342 
_tdls_delay_timer_hdl(void * FunctionContext)3343 void _tdls_delay_timer_hdl(void *FunctionContext)
3344 {
3345 	struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
3346 	_adapter *padapter = ptdls_sta->padapter;
3347 	struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
3348 
3349 	RTW_INFO("[TDLS] %s, op_ch:%d, tdls_state:0x%08x\n", __func__, rtw_get_oper_ch(padapter), ptdls_sta->tdls_sta_state);
3350 	pchsw_info->delay_switch_back = _TRUE;
3351 }
3352 
_tdls_stay_on_base_chnl_timer_hdl(void * FunctionContext)3353 void _tdls_stay_on_base_chnl_timer_hdl(void *FunctionContext)
3354 {
3355 	struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
3356 	_adapter *padapter = ptdls_sta->padapter;
3357 	struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
3358 
3359 	if (ptdls_sta != NULL) {
3360 		issue_tdls_ch_switch_req(padapter, ptdls_sta);
3361 		pchsw_info->ch_sw_state |= TDLS_WAIT_CH_RSP_STATE;
3362 	}
3363 }
3364 
_tdls_ch_switch_monitor_timer_hdl(void * FunctionContext)3365 void _tdls_ch_switch_monitor_timer_hdl(void *FunctionContext)
3366 {
3367 	struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
3368 	_adapter *padapter = ptdls_sta->padapter;
3369 	struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
3370 
3371 	rtw_tdls_cmd(padapter, ptdls_sta->phl_sta->mac_addr, TDLS_CH_SW_END);
3372 	RTW_INFO("[TDLS] %s, does not receive ch sw req\n", __func__);
3373 }
3374 
3375 #endif
3376 
_tdls_handshake_timer_hdl(void * FunctionContext)3377 void _tdls_handshake_timer_hdl(void *FunctionContext)
3378 {
3379 	struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
3380 	_adapter *padapter = NULL;
3381 	struct tdls_txmgmt txmgmt;
3382 
3383 	_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
3384 	_rtw_memcpy(txmgmt.peer, ptdls_sta->phl_sta->mac_addr, ETH_ALEN);
3385 	txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
3386 
3387 	if (ptdls_sta != NULL) {
3388 		padapter = ptdls_sta->padapter;
3389 
3390 		RTW_INFO("[TDLS] Handshake time out\n");
3391 		if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE)
3392 			rtw_tdls_cmd(padapter, ptdls_sta->phl_sta->mac_addr, TDLS_TEARDOWN_STA);
3393 		else
3394 			rtw_tdls_cmd(padapter, ptdls_sta->phl_sta->mac_addr, TDLS_TEARDOWN_STA_LOCALLY);
3395 	}
3396 }
3397 
_tdls_pti_timer_hdl(void * FunctionContext)3398 void _tdls_pti_timer_hdl(void *FunctionContext)
3399 {
3400 	struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
3401 	_adapter *padapter = NULL;
3402 	struct tdls_txmgmt txmgmt;
3403 
3404 	_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
3405 	_rtw_memcpy(txmgmt.peer, ptdls_sta->phl_sta->mac_addr, ETH_ALEN);
3406 	txmgmt.status_code = _RSON_TDLS_TEAR_TOOFAR_;
3407 
3408 	if (ptdls_sta != NULL) {
3409 		padapter = ptdls_sta->padapter;
3410 
3411 		if (ptdls_sta->tdls_sta_state & TDLS_WAIT_PTR_STATE) {
3412 			RTW_INFO("[TDLS] Doesn't receive PTR from peer dev:"MAC_FMT"; "
3413 				"Send TDLS Tear Down\n", MAC_ARG(ptdls_sta->phl_sta->mac_addr));
3414 			rtw_tdls_cmd(padapter, ptdls_sta->phl_sta->mac_addr, TDLS_TEARDOWN_STA);
3415 		}
3416 	}
3417 }
3418 
rtw_init_tdls_timer(_adapter * padapter,struct sta_info * psta)3419 void rtw_init_tdls_timer(_adapter *padapter, struct sta_info *psta)
3420 {
3421 	psta->padapter = padapter;
3422 	rtw_init_timer(&psta->TPK_timer, _tdls_tpk_timer_hdl, psta);
3423 #ifdef CONFIG_TDLS_CH_SW
3424 	rtw_init_timer(&psta->ch_sw_timer, _tdls_ch_switch_timer_hdl, psta);
3425 	rtw_init_timer(&psta->delay_timer, _tdls_delay_timer_hdl, psta);
3426 	rtw_init_timer(&psta->stay_on_base_chnl_timer, _tdls_stay_on_base_chnl_timer_hdl, psta);
3427 	rtw_init_timer(&psta->ch_sw_monitor_timer, _tdls_ch_switch_monitor_timer_hdl, psta);
3428 #endif
3429 	rtw_init_timer(&psta->handshake_timer, _tdls_handshake_timer_hdl, psta);
3430 	rtw_init_timer(&psta->pti_timer, _tdls_pti_timer_hdl, psta);
3431 }
3432 
rtw_cancel_tdls_timer(struct sta_info * psta)3433 void rtw_cancel_tdls_timer(struct sta_info *psta)
3434 {
3435 	_cancel_timer_ex(&psta->TPK_timer);
3436 #ifdef CONFIG_TDLS_CH_SW
3437 	_cancel_timer_ex(&psta->ch_sw_timer);
3438 	_cancel_timer_ex(&psta->delay_timer);
3439 	_cancel_timer_ex(&psta->stay_on_base_chnl_timer);
3440 	_cancel_timer_ex(&psta->ch_sw_monitor_timer);
3441 #endif
3442 	_cancel_timer_ex(&psta->handshake_timer);
3443 	_cancel_timer_ex(&psta->pti_timer);
3444 }
3445 
rtw_tdls_teardown_pre_hdl(_adapter * padapter,struct sta_info * psta)3446 void rtw_tdls_teardown_pre_hdl(_adapter *padapter, struct sta_info *psta)
3447 {
3448 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
3449 	struct sta_priv *pstapriv = &padapter->stapriv;
3450 
3451 	rtw_cancel_tdls_timer(psta);
3452 
3453 	_rtw_spinlock_bh(&(pstapriv->sta_hash_lock));
3454 	if (ptdlsinfo->sta_cnt != 0)
3455 		ptdlsinfo->sta_cnt--;
3456 	_rtw_spinunlock_bh(&(pstapriv->sta_hash_lock));
3457 
3458 	if (ptdlsinfo->sta_cnt < MAX_ALLOWED_TDLS_STA_NUM) {
3459 		ptdlsinfo->sta_maximum = _FALSE;
3460 		_rtw_memset(&ptdlsinfo->ss_record, 0x00, sizeof(struct tdls_ss_record));
3461 	}
3462 
3463 	if (ptdlsinfo->sta_cnt == 0)
3464 		rtw_tdls_set_link_established(padapter, _FALSE);
3465 	else
3466 		RTW_INFO("Remain tdls sta:%02x\n", ptdlsinfo->sta_cnt);
3467 }
3468 
rtw_tdls_teardown_post_hdl(_adapter * padapter,struct sta_info * psta,u8 enqueue_cmd)3469 void rtw_tdls_teardown_post_hdl(_adapter *padapter, struct sta_info *psta, u8 enqueue_cmd)
3470 {
3471 	struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
3472 
3473 	/* Clear cam */
3474 	rtw_clearstakey_cmd(padapter, psta, enqueue_cmd);
3475 
3476 	/* Update sta media status */
3477 	if (enqueue_cmd)
3478 		rtw_sta_media_status_rpt_cmd(padapter, psta, 0);
3479 	else
3480 		rtw_sta_media_status_rpt(padapter, psta, 0);
3481 
3482 	/* Set RCR if necessary */
3483 	if (ptdlsinfo->sta_cnt == 0) {
3484 		if (enqueue_cmd)
3485 			rtw_tdls_cmd(padapter, NULL, TDLS_RS_RCR);
3486 		else
3487 			rtw_hal_rcr_set_chk_bssid(padapter, MLME_TDLS_NOLINK);
3488 	}
3489 
3490 	/* Free tdls sta info */
3491 	rtw_free_stainfo(padapter,  psta);
3492 }
3493 
rtw_tdls_is_driver_setup(_adapter * padapter)3494 int rtw_tdls_is_driver_setup(_adapter *padapter)
3495 {
3496 	return padapter->tdlsinfo.driver_setup;
3497 }
3498 
rtw_tdls_action_txt(enum TDLS_ACTION_FIELD action)3499 const char *rtw_tdls_action_txt(enum TDLS_ACTION_FIELD action)
3500 {
3501 	switch (action) {
3502 	case TDLS_SETUP_REQUEST:
3503 		return "TDLS_SETUP_REQUEST";
3504 	case TDLS_SETUP_RESPONSE:
3505 		return "TDLS_SETUP_RESPONSE";
3506 	case TDLS_SETUP_CONFIRM:
3507 		return "TDLS_SETUP_CONFIRM";
3508 	case TDLS_TEARDOWN:
3509 		return "TDLS_TEARDOWN";
3510 	case TDLS_PEER_TRAFFIC_INDICATION:
3511 		return "TDLS_PEER_TRAFFIC_INDICATION";
3512 	case TDLS_CHANNEL_SWITCH_REQUEST:
3513 		return "TDLS_CHANNEL_SWITCH_REQUEST";
3514 	case TDLS_CHANNEL_SWITCH_RESPONSE:
3515 		return "TDLS_CHANNEL_SWITCH_RESPONSE";
3516 	case TDLS_PEER_PSM_REQUEST:
3517 		return "TDLS_PEER_PSM_REQUEST";
3518 	case TDLS_PEER_PSM_RESPONSE:
3519 		return "TDLS_PEER_PSM_RESPONSE";
3520 	case TDLS_PEER_TRAFFIC_RESPONSE:
3521 		return "TDLS_PEER_TRAFFIC_RESPONSE";
3522 	case TDLS_DISCOVERY_REQUEST:
3523 		return "TDLS_DISCOVERY_REQUEST";
3524 	case TDLS_DISCOVERY_RESPONSE:
3525 		return "TDLS_DISCOVERY_RESPONSE";
3526 	default:
3527 		return "UNKNOWN";
3528 	}
3529 }
3530 
3531 #endif /* CONFIG_TDLS */
3532