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