1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
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.
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
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
19 ******************************************************************************/
22 #include <drv_types.h>
25 #define ONE_SEC 1000 /* 1000 ms */
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);
31 void rtw_reset_tdls_info(_adapter* padapter)
33 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
35 ptdlsinfo->ap_prohibited = _FALSE;
37 /* For TDLS channel switch, currently we only allow it to work in wifi logo test mode */
38 if (padapter->registrypriv.wifi_spec == 1)
40 ptdlsinfo->ch_switch_prohibited = _FALSE;
44 ptdlsinfo->ch_switch_prohibited = _TRUE;
47 ptdlsinfo->link_established = _FALSE;
48 ptdlsinfo->sta_cnt = 0;
49 ptdlsinfo->sta_maximum = _FALSE;
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 = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
56 ptdlsinfo->chsw_info.cur_time = 0;
57 ptdlsinfo->chsw_info.delay_switch_back = _FALSE;
58 ptdlsinfo->chsw_info.dump_stack = _FALSE;
61 ptdlsinfo->ch_sensing = 0;
62 ptdlsinfo->watchdog_count = 0;
63 ptdlsinfo->dev_discovered = _FALSE;
66 ptdlsinfo->wfd_info = &padapter->wfd_info;
70 int rtw_init_tdls_info(_adapter* padapter)
73 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
75 rtw_reset_tdls_info(padapter);
77 ptdlsinfo->tdls_enable = _TRUE;
78 #ifdef CONFIG_TDLS_DRIVER_SETUP
79 ptdlsinfo->driver_setup = _TRUE;
81 ptdlsinfo->driver_setup = _FALSE;
82 #endif /* CONFIG_TDLS_DRIVER_SETUP */
84 _rtw_spinlock_init(&ptdlsinfo->cmd_lock);
85 _rtw_spinlock_init(&ptdlsinfo->hdl_lock);
91 void rtw_free_tdls_info(struct tdls_info *ptdlsinfo)
93 _rtw_spinlock_free(&ptdlsinfo->cmd_lock);
94 _rtw_spinlock_free(&ptdlsinfo->hdl_lock);
96 _rtw_memset(ptdlsinfo, 0, sizeof(struct tdls_info) );
100 int check_ap_tdls_prohibited(u8 *pframe, u8 pkt_len)
102 u8 tdls_prohibited_bit = 0x40; /* bit(38); TDLS_prohibited */
109 if ((*pframe) & tdls_prohibited_bit)
115 int check_ap_tdls_ch_switching_prohibited(u8 *pframe, u8 pkt_len)
117 u8 tdls_ch_swithcing_prohibited_bit = 0x80; /* bit(39); TDLS_channel_switching prohibited */
124 if ((*pframe) & tdls_ch_swithcing_prohibited_bit)
130 u8 rtw_tdls_is_setup_allowed(_adapter *padapter)
132 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
134 if (ptdlsinfo->ap_prohibited == _TRUE)
140 #ifdef CONFIG_TDLS_CH_SW
141 u8 rtw_tdls_is_chsw_allowed(_adapter *padapter)
143 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
145 if (ptdlsinfo->ch_switch_prohibited == _TRUE)
148 if (padapter->registrypriv.wifi_spec == 0)
155 int _issue_nulldata_to_TDLS_peer_STA(_adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack)
158 struct xmit_frame *pmgntframe;
159 struct pkt_attrib *pattrib;
160 unsigned char *pframe;
161 struct rtw_ieee80211_hdr *pwlanhdr;
162 unsigned short *fctrl, *qc;
163 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
164 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
165 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
167 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
170 pattrib = &pmgntframe->attrib;
171 update_mgntframe_attrib(padapter, pattrib);
174 pattrib->qos_en = _TRUE;
176 pattrib->ack_policy = 0;
178 pattrib->retry_ctrl = _FALSE;
180 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
182 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
183 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
185 fctrl = &(pwlanhdr->frame_ctl);
191 qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
193 SetPriority(qc, 7); /* Set priority to VO */
195 SetEOSP(qc, pattrib->eosp);
197 SetAckpolicy(qc, pattrib->ack_policy);
199 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
200 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
201 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
203 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
204 pmlmeext->mgnt_seq++;
205 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
207 pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos);
208 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
210 pattrib->last_txcmdsz = pattrib->pktlen;
213 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
215 dump_mgntframe(padapter, pmgntframe);
225 *wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
226 *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
227 *try_cnt means the maximal TX count to try
229 int issue_nulldata_to_TDLS_peer_STA(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
233 u32 start = rtw_get_current_time();
234 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
235 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
238 psta = rtw_get_stainfo(&padapter->stapriv, da);
241 rtw_hal_macid_sleep(padapter, psta->mac_id);
243 rtw_hal_macid_wakeup(padapter, psta->mac_id);
245 DBG_871X(FUNC_ADPT_FMT ": Can't find sta info for " MAC_FMT ", skip macid %s!!\n",
246 FUNC_ADPT_ARG(padapter), MAC_ARG(da), power_mode?"sleep":"wakeup");
252 ret = _issue_nulldata_to_TDLS_peer_STA(padapter, da, power_mode, wait_ms>0 ? _TRUE : _FALSE);
256 if (RTW_CANNOT_RUN(padapter))
259 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
260 rtw_msleep_os(wait_ms);
262 } while ((i < try_cnt) && (ret==_FAIL || wait_ms==0));
271 if (try_cnt && wait_ms) {
273 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
274 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
275 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
277 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
278 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
279 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
285 void free_tdls_sta(_adapter *padapter, struct sta_info *ptdls_sta)
287 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
288 struct sta_priv *pstapriv = &padapter->stapriv;
291 /* free peer sta_info */
292 _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
293 if (ptdlsinfo->sta_cnt != 0)
294 ptdlsinfo->sta_cnt--;
295 _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
296 /* -2: AP + BC/MC sta, -4: default key */
297 if (ptdlsinfo->sta_cnt < MAX_ALLOWED_TDLS_STA_NUM) {
298 ptdlsinfo->sta_maximum = _FALSE;
299 _rtw_memset( &ptdlsinfo->ss_record, 0x00, sizeof(struct tdls_ss_record) );
303 rtw_clearstakey_cmd(padapter, ptdls_sta, _TRUE);
305 if (ptdlsinfo->sta_cnt == 0) {
306 rtw_tdls_cmd(padapter, NULL, TDLS_RS_RCR);
307 ptdlsinfo->link_established = _FALSE;
310 DBG_871X("Remain tdls sta:%02x\n", ptdlsinfo->sta_cnt);
312 rtw_free_stainfo(padapter, ptdls_sta);
317 /* TDLS encryption(if needed) will always be CCMP */
318 void rtw_tdls_set_key(_adapter *padapter, struct sta_info *ptdls_sta)
320 ptdls_sta->dot118021XPrivacy=_AES_;
321 rtw_setstakey_cmd(padapter, ptdls_sta, TDLS_KEY, _TRUE);
324 #ifdef CONFIG_80211N_HT
325 void rtw_tdls_process_ht_cap(_adapter *padapter, struct sta_info *ptdls_sta, u8 *data, u8 Length)
327 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
328 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
329 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
330 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
331 u8 max_AMPDU_len, min_MPDU_spacing;
332 u8 cur_ldpc_cap = 0, cur_stbc_cap = 0, cur_beamform_cap = 0;
334 /* Save HT capabilities in the sta object */
335 _rtw_memset(&ptdls_sta->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap));
336 if (data && Length >= sizeof(struct rtw_ieee80211_ht_cap)) {
337 ptdls_sta->flags |= WLAN_STA_HT;
338 ptdls_sta->flags |= WLAN_STA_WME;
340 _rtw_memcpy(&ptdls_sta->htpriv.ht_cap, data, sizeof(struct rtw_ieee80211_ht_cap));
342 ptdls_sta->flags &= ~WLAN_STA_HT;
344 if (ptdls_sta->flags & WLAN_STA_HT) {
345 if (padapter->registrypriv.ht_enable == _TRUE) {
346 ptdls_sta->htpriv.ht_option = _TRUE;
347 ptdls_sta->qos_option = _TRUE;
349 ptdls_sta->htpriv.ht_option = _FALSE;
350 ptdls_sta->qos_option = _FALSE;
355 if (ptdls_sta->htpriv.ht_option) {
356 /* Check if sta supports rx ampdu */
357 if (padapter->registrypriv.ampdu_enable == 1)
358 ptdls_sta->htpriv.ampdu_enable = _TRUE;
360 /* AMPDU Parameters field */
361 /* Get MIN of MAX AMPDU Length Exp */
362 if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3) > (data[2] & 0x3))
363 max_AMPDU_len = (data[2] & 0x3);
365 max_AMPDU_len = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x3);
366 /* Get MAX of MIN MPDU Start Spacing */
367 if ((pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) > (data[2] & 0x1c))
368 min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c);
370 min_MPDU_spacing = (data[2] & 0x1c);
371 ptdls_sta->htpriv.rx_ampdu_min_spacing = max_AMPDU_len | min_MPDU_spacing;
373 /* Check if sta support s Short GI 20M */
374 if (ptdls_sta->htpriv.ht_cap.cap_info & cpu_to_le16(IEEE80211_HT_CAP_SGI_20))
375 ptdls_sta->htpriv.sgi_20m = _TRUE;
377 /* Check if sta support s Short GI 40M */
378 if (ptdls_sta->htpriv.ht_cap.cap_info & cpu_to_le16(IEEE80211_HT_CAP_SGI_40))
379 ptdls_sta->htpriv.sgi_40m = _TRUE;
381 /* Bwmode would still followed AP's setting */
382 if (ptdls_sta->htpriv.ht_cap.cap_info & cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH)) {
383 if (padapter->mlmeextpriv.cur_bwmode >= CHANNEL_WIDTH_40)
384 ptdls_sta->bw_mode = CHANNEL_WIDTH_40;
385 ptdls_sta->htpriv.ch_offset = padapter->mlmeextpriv.cur_ch_offset;
388 /* Config LDPC Coding Capability */
389 if (TEST_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_TX) && GET_HT_CAP_ELE_LDPC_CAP(data)) {
390 SET_FLAG(cur_ldpc_cap, (LDPC_HT_ENABLE_TX | LDPC_HT_CAP_TX));
391 DBG_871X("Enable HT Tx LDPC!\n");
393 ptdls_sta->htpriv.ldpc_cap = cur_ldpc_cap;
395 /* Config STBC setting */
396 if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX) && GET_HT_CAP_ELE_RX_STBC(data)) {
397 SET_FLAG(cur_stbc_cap, (STBC_HT_ENABLE_TX | STBC_HT_CAP_TX));
398 DBG_871X("Enable HT Tx STBC!\n");
400 ptdls_sta->htpriv.stbc_cap = cur_stbc_cap;
406 u8 *rtw_tdls_set_ht_cap(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib)
408 rtw_ht_use_default_setting(padapter);
410 rtw_restructure_ht_ie(padapter, NULL, pframe, 0, &(pattrib->pktlen), padapter->mlmeextpriv.cur_channel);
412 return pframe + pattrib->pktlen;
416 u8 *rtw_tdls_set_sup_ch(struct mlme_ext_priv *pmlmeext, u8 *pframe, struct pkt_attrib *pattrib)
418 u8 sup_ch[30 * 2] = {0x00}, ch_set_idx = 0, sup_ch_idx = 2;
421 if (pmlmeext->channel_set[ch_set_idx].ChannelNum <= 14) {
422 sup_ch[0] = 1; /* First channel number */
423 sup_ch[1] = pmlmeext->channel_set[ch_set_idx].ChannelNum; /* Number of channel */
425 sup_ch[sup_ch_idx++] = pmlmeext->channel_set[ch_set_idx].ChannelNum;
426 sup_ch[sup_ch_idx++] = 1;
429 } while (pmlmeext->channel_set[ch_set_idx].ChannelNum != 0 && ch_set_idx < MAX_CHANNEL_NUM);
431 return rtw_set_ie(pframe, _SUPPORTED_CH_IE_, sup_ch_idx, sup_ch, &(pattrib->pktlen));
434 u8 *rtw_tdls_set_rsnie(struct tdls_txmgmt *ptxmgmt, u8 *pframe, struct pkt_attrib *pattrib, int init, struct sta_info *ptdls_sta)
439 if (ptxmgmt->len > 0)
440 p = rtw_get_ie(ptxmgmt->buf, _RSN_IE_2_, &len, ptxmgmt->len);
443 return rtw_set_ie(pframe, _RSN_IE_2_, len, p+2, &(pattrib->pktlen));
446 return rtw_set_ie(pframe, _RSN_IE_2_, sizeof(TDLS_RSNIE), TDLS_RSNIE, &(pattrib->pktlen));
448 return rtw_set_ie(pframe, _RSN_IE_2_, sizeof(ptdls_sta->TDLS_RSNIE), ptdls_sta->TDLS_RSNIE, &(pattrib->pktlen));
451 u8 *rtw_tdls_set_ext_cap(u8 *pframe, struct pkt_attrib *pattrib)
453 return rtw_set_ie(pframe, _EXT_CAP_IE_ , sizeof(TDLS_EXT_CAPIE), TDLS_EXT_CAPIE, &(pattrib->pktlen));
456 u8 *rtw_tdls_set_qos_cap(u8 *pframe, struct pkt_attrib *pattrib)
458 return rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(TDLS_WMMIE), TDLS_WMMIE, &(pattrib->pktlen));
461 u8 *rtw_tdls_set_ftie(struct tdls_txmgmt *ptxmgmt, u8 *pframe, struct pkt_attrib *pattrib, u8 *ANonce, u8 *SNonce)
463 struct wpa_tdls_ftie FTIE = {0};
467 if (ptxmgmt->len > 0)
468 p = rtw_get_ie(ptxmgmt->buf, _FTIE_, &len, ptxmgmt->len);
471 return rtw_set_ie(pframe, _FTIE_, len, p+2, &(pattrib->pktlen));
474 _rtw_memcpy(FTIE.Anonce, ANonce, WPA_NONCE_LEN);
476 _rtw_memcpy(FTIE.Snonce, SNonce, WPA_NONCE_LEN);
477 return rtw_set_ie(pframe, _FTIE_ , 82, (u8 *)FTIE.mic_ctrl, &(pattrib->pktlen));
481 u8 *rtw_tdls_set_timeout_interval(struct tdls_txmgmt *ptxmgmt, u8 *pframe, struct pkt_attrib *pattrib, int init, struct sta_info *ptdls_sta)
483 u8 timeout_itvl[5]; /* set timeout interval to maximum value */
484 u32 timeout_interval = TDLS_TPK_RESEND_COUNT;
488 if (ptxmgmt->len > 0)
489 p = rtw_get_ie(ptxmgmt->buf, _TIMEOUT_ITVL_IE_, &len, ptxmgmt->len);
492 return rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, len, p+2, &(pattrib->pktlen));
494 /* Timeout interval */
495 timeout_itvl[0]=0x02;
497 _rtw_memcpy(timeout_itvl+1, &timeout_interval, 4);
499 _rtw_memcpy(timeout_itvl+1, (u8 *)(&ptdls_sta->TDLS_PeerKey_Lifetime), 4);
501 return rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
505 u8 *rtw_tdls_set_bss_coexist(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib)
509 if (padapter->mlmepriv.num_FortyMHzIntolerant > 0)
510 iedata |= BIT(2); /* 20 MHz BSS Width Request */
512 /* Information Bit should be set by TDLS test plan 5.9 */
514 return rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
517 u8 *rtw_tdls_set_payload_type(u8 *pframe, struct pkt_attrib *pattrib)
519 u8 payload_type = 0x02;
520 return rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
523 u8 *rtw_tdls_set_category(u8 *pframe, struct pkt_attrib *pattrib, u8 category)
525 return rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
528 u8 *rtw_tdls_set_action(u8 *pframe, struct pkt_attrib *pattrib, struct tdls_txmgmt *ptxmgmt)
530 return rtw_set_fixed_ie(pframe, 1, &(ptxmgmt->action_code), &(pattrib->pktlen));
533 u8 *rtw_tdls_set_status_code(u8 *pframe, struct pkt_attrib *pattrib, struct tdls_txmgmt *ptxmgmt)
535 return rtw_set_fixed_ie(pframe, 2, (u8 *)&(ptxmgmt->status_code), &(pattrib->pktlen));
538 u8 *rtw_tdls_set_dialog(u8 *pframe, struct pkt_attrib *pattrib, struct tdls_txmgmt *ptxmgmt)
541 if (ptxmgmt->dialog_token)
542 return rtw_set_fixed_ie(pframe, 1, &(ptxmgmt->dialog_token), &(pattrib->pktlen));
544 return rtw_set_fixed_ie(pframe, 1, &(dialogtoken), &(pattrib->pktlen));
547 u8 *rtw_tdls_set_reg_class(u8 *pframe, struct pkt_attrib *pattrib, struct sta_info *ptdls_sta)
550 return rtw_set_fixed_ie(pframe, 1, &(reg_class), &(pattrib->pktlen));
553 u8 *rtw_tdls_set_second_channel_offset(u8 *pframe, struct pkt_attrib *pattrib, u8 ch_offset)
555 return rtw_set_ie(pframe, EID_SecondaryChnlOffset , 1, &ch_offset, &(pattrib->pktlen));
558 u8 *rtw_tdls_set_capability(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib)
560 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
561 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
562 u8 cap_from_ie[2] = {0};
564 _rtw_memcpy(cap_from_ie, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
566 return rtw_set_fixed_ie(pframe, 2, cap_from_ie, &(pattrib->pktlen));
569 u8 *rtw_tdls_set_supported_rate(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib)
571 u8 bssrate[NDIS_802_11_LENGTH_RATES_EX];
573 u8 more_supportedrates = 0;
575 rtw_set_supported_rate(bssrate, (padapter->registrypriv.wireless_mode == WIRELESS_MODE_MAX) ? padapter->mlmeextpriv.cur_wireless_mode : padapter->registrypriv.wireless_mode);
576 bssrate_len = rtw_get_rateset_len(bssrate);
578 if (bssrate_len > 8) {
579 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
580 more_supportedrates = 1;
582 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
585 /* extended supported rates */
586 if (more_supportedrates == 1) {
587 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
593 u8 *rtw_tdls_set_sup_reg_class(u8 *pframe, struct pkt_attrib *pattrib)
595 return rtw_set_ie(pframe, _SRC_IE_ , sizeof(TDLS_SRC), TDLS_SRC, &(pattrib->pktlen));
598 u8 *rtw_tdls_set_linkid(u8 *pframe, struct pkt_attrib *pattrib, u8 init)
600 u8 link_id_addr[18] = {0};
602 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
603 _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
604 _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
606 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
607 _rtw_memcpy((link_id_addr+6), pattrib->dst, 6);
608 _rtw_memcpy((link_id_addr+12), pattrib->src, 6);
610 return rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
613 #ifdef CONFIG_TDLS_CH_SW
614 u8 *rtw_tdls_set_target_ch(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib)
617 if (padapter->tdlsinfo.chsw_info.off_ch_num)
618 return rtw_set_fixed_ie(pframe, 1, &(padapter->tdlsinfo.chsw_info.off_ch_num), &(pattrib->pktlen));
620 return rtw_set_fixed_ie(pframe, 1, &(target_ch), &(pattrib->pktlen));
623 u8 *rtw_tdls_set_ch_sw(u8 *pframe, struct pkt_attrib *pattrib, struct sta_info *ptdls_sta)
625 u8 ch_switch_timing[4] = {0};
626 u16 switch_time = (ptdls_sta->ch_switch_time >= TDLS_CH_SWITCH_TIME * 1000) ?
627 ptdls_sta->ch_switch_time : TDLS_CH_SWITCH_TIME;
628 u16 switch_timeout = (ptdls_sta->ch_switch_timeout >= TDLS_CH_SWITCH_TIMEOUT * 1000) ?
629 ptdls_sta->ch_switch_timeout : TDLS_CH_SWITCH_TIMEOUT;
631 _rtw_memcpy(ch_switch_timing, &switch_time, 2);
632 _rtw_memcpy(ch_switch_timing + 2, &switch_timeout, 2);
634 return rtw_set_ie(pframe, _CH_SWITCH_TIMING_, 4, ch_switch_timing, &(pattrib->pktlen));
637 void rtw_tdls_set_ch_sw_oper_control(_adapter *padapter, u8 enable)
639 if (ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on) != enable)
640 ATOMIC_SET(&padapter->tdlsinfo.chsw_info.chsw_on, enable);
642 rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_BCN_EARLY_C2H_RPT, &enable);
643 DBG_871X("[TDLS] %s Bcn Early C2H Report\n", (enable == _TRUE) ? "Start" : "Stop");
646 void rtw_tdls_ch_sw_back_to_base_chnl(_adapter *padapter)
648 struct mlme_priv *pmlmepriv;
649 struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
651 pmlmepriv = &padapter->mlmepriv;
653 if ((ATOMIC_READ(&pchsw_info->chsw_on) == _TRUE) &&
654 (padapter->mlmeextpriv.cur_channel != rtw_get_oper_ch(padapter)))
655 rtw_tdls_cmd(padapter, pchsw_info->addr, TDLS_CH_SW_TO_BASE_CHNL_UNSOLICITED);
658 static void rtw_tdls_chsw_oper_init(_adapter *padapter, u32 timeout_ms)
660 struct submit_ctx *chsw_sctx = &padapter->tdlsinfo.chsw_info.chsw_sctx;
662 rtw_sctx_init(chsw_sctx, timeout_ms);
665 static int rtw_tdls_chsw_oper_wait(_adapter *padapter)
667 struct submit_ctx *chsw_sctx = &padapter->tdlsinfo.chsw_info.chsw_sctx;
669 return rtw_sctx_wait(chsw_sctx, __func__);
672 void rtw_tdls_chsw_oper_done(_adapter *padapter)
674 struct submit_ctx *chsw_sctx = &padapter->tdlsinfo.chsw_info.chsw_sctx;
676 rtw_sctx_done(&chsw_sctx);
679 s32 rtw_tdls_do_ch_sw(_adapter *padapter, u8 chnl_type, u8 channel, u8 channel_offset, u16 bwmode, u16 ch_switch_time)
681 u32 ch_sw_time_start, ch_sw_time_spent, wait_time;
685 ch_sw_time_start = rtw_systime_to_ms(rtw_get_current_time());
687 rtw_tdls_chsw_oper_init(padapter, TDLS_CH_SWITCH_OPER_OFFLOAD_TIMEOUT);
689 /* channel switch IOs offload to FW */
690 if (rtw_hal_ch_sw_oper_offload(padapter, channel, channel_offset, bwmode) == _SUCCESS) {
691 if (rtw_tdls_chsw_oper_wait(padapter) == _SUCCESS) {
692 /* set channel and bw related variables in driver */
693 _enter_critical_mutex(&(adapter_to_dvobj(padapter)->setch_mutex), NULL);
694 rtw_set_oper_ch(padapter, channel);
695 rtw_set_oper_choffset(padapter, channel_offset);
696 rtw_set_oper_bw(padapter, bwmode);
697 _exit_critical_mutex(&(adapter_to_dvobj(padapter)->setch_mutex), NULL);
699 rtw_hal_get_hwreg(padapter, HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO, &take_care_iqk);
700 if (take_care_iqk == _TRUE)
701 rtw_hal_ch_sw_iqk_info_restore(padapter, CH_SW_USE_CASE_TDLS);
703 ch_sw_time_spent = rtw_systime_to_ms(rtw_get_current_time()) - ch_sw_time_start;
705 if (chnl_type == TDLS_CH_SW_OFF_CHNL) {
706 if ((u32)ch_switch_time / 1000 > ch_sw_time_spent)
707 wait_time = (u32)ch_switch_time / 1000 - ch_sw_time_spent;
712 rtw_msleep_os(wait_time);
717 DBG_871X("[TDLS] chsw oper wait fail !!\n");
724 u8 *rtw_tdls_set_wmm_params(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib)
726 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
727 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
728 u8 wmm_param_ele[24] = {0};
730 if (&pmlmeinfo->WMM_param) {
731 _rtw_memcpy(wmm_param_ele, WMM_PARA_OUI, 6);
732 if (_rtw_memcmp(&pmlmeinfo->WMM_param, &wmm_param_ele[6], 18) == _TRUE)
733 /* Use default WMM Param */
734 _rtw_memcpy(wmm_param_ele + 6, (u8 *)&TDLS_WMM_PARAM_IE, sizeof(TDLS_WMM_PARAM_IE));
736 _rtw_memcpy(wmm_param_ele + 6, (u8 *)&pmlmeinfo->WMM_param, sizeof(pmlmeinfo->WMM_param));
737 return rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 24, wmm_param_ele, &(pattrib->pktlen));
744 void rtw_tdls_process_wfd_ie(struct tdls_info *ptdlsinfo, u8 *ptr, u8 length)
749 if (!hal_chk_wl_func(tdls_info_to_adapter(ptdlsinfo), WL_FUNC_MIRACAST))
752 /* Try to get the TCP port information when receiving the negotiation response. */
754 wfd_ie = rtw_get_wfd_ie(ptr, length, NULL, &wfd_ielen);
757 u32 attr_contentlen = 0;
760 DBG_871X( "[%s] WFD IE Found!!\n", __FUNCTION__ );
761 attr_content = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &attr_contentlen);
762 if (attr_content && attr_contentlen) {
763 ptdlsinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16( attr_content + 2 );
764 DBG_871X( "[%s] Peer PORT NUM = %d\n", __FUNCTION__, ptdlsinfo->wfd_info->peer_rtsp_ctrlport );
767 attr_content = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_LOCAL_IP_ADDR, NULL, &attr_contentlen);
768 if (attr_content && attr_contentlen) {
769 _rtw_memcpy(ptdlsinfo->wfd_info->peer_ip_address, ( attr_content + 1 ), 4);
770 DBG_871X("[%s] Peer IP = %02u.%02u.%02u.%02u\n", __FUNCTION__,
771 ptdlsinfo->wfd_info->peer_ip_address[0], ptdlsinfo->wfd_info->peer_ip_address[1],
772 ptdlsinfo->wfd_info->peer_ip_address[2], ptdlsinfo->wfd_info->peer_ip_address[3]);
775 wfd_ie = rtw_get_wfd_ie(wfd_ie + wfd_ielen, (ptr + length) - (wfd_ie + wfd_ielen), NULL, &wfd_ielen);
779 int issue_tunneled_probe_req(_adapter *padapter)
781 struct xmit_frame *pmgntframe;
782 struct pkt_attrib *pattrib;
783 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
784 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
785 u8 baddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
786 struct tdls_txmgmt txmgmt;
789 DBG_871X("[%s]\n", __FUNCTION__);
791 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
792 txmgmt.action_code = TUNNELED_PROBE_REQ;
794 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
797 pattrib = &pmgntframe->attrib;
799 pmgntframe->frame_tag = DATA_FRAMETAG;
800 pattrib->ether_type = 0x890d;
802 _rtw_memcpy(pattrib->dst, baddr, ETH_ALEN);
803 _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
804 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
805 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
807 update_tdls_attrib(padapter, pattrib);
808 pattrib->qsel = pattrib->priority;
809 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, &txmgmt) != _SUCCESS) {
810 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
811 rtw_free_xmitframe(pxmitpriv, pmgntframe);
814 dump_mgntframe(padapter, pmgntframe);
821 int issue_tunneled_probe_rsp(_adapter *padapter, union recv_frame *precv_frame)
823 struct xmit_frame *pmgntframe;
824 struct pkt_attrib *pattrib;
825 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
826 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
827 struct tdls_txmgmt txmgmt;
830 DBG_871X("[%s]\n", __FUNCTION__);
832 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
833 txmgmt.action_code = TUNNELED_PROBE_RSP;
835 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
838 pattrib = &pmgntframe->attrib;
840 pmgntframe->frame_tag = DATA_FRAMETAG;
841 pattrib->ether_type = 0x890d;
843 _rtw_memcpy(pattrib->dst, precv_frame->u.hdr.attrib.src, ETH_ALEN);
844 _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
845 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
846 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
848 update_tdls_attrib(padapter, pattrib);
849 pattrib->qsel = pattrib->priority;
850 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, &txmgmt) != _SUCCESS) {
851 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
852 rtw_free_xmitframe(pxmitpriv, pmgntframe);
855 dump_mgntframe(padapter, pmgntframe);
861 #endif /* CONFIG_WFD */
863 int issue_tdls_setup_req(_adapter *padapter, struct tdls_txmgmt *ptxmgmt, int wait_ack)
865 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
866 struct xmit_frame *pmgntframe;
867 struct pkt_attrib *pattrib;
868 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
869 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
870 struct sta_priv *pstapriv = &padapter->stapriv;
871 struct sta_info *ptdls_sta= NULL;
874 /* Retry timer should be set at least 301 sec, using TPK_count counting 301 times. */
875 u32 timeout_interval = TDLS_TPK_RESEND_COUNT;
877 DBG_871X("[TDLS] %s\n", __FUNCTION__);
879 ptxmgmt->action_code = TDLS_SETUP_REQUEST;
880 if (rtw_tdls_is_setup_allowed(padapter) == _FALSE)
883 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
886 pattrib = &pmgntframe->attrib;
887 pmgntframe->frame_tag = DATA_FRAMETAG;
888 pattrib->ether_type = 0x890d;
890 _rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN);
891 _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
892 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
893 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
895 update_tdls_attrib(padapter, pattrib);
897 /* init peer sta_info */
898 ptdls_sta = rtw_get_stainfo(pstapriv, ptxmgmt->peer);
899 if (ptdls_sta == NULL) {
900 ptdls_sta = rtw_alloc_stainfo(pstapriv, ptxmgmt->peer);
901 if (ptdls_sta == NULL) {
902 DBG_871X("[%s] rtw_alloc_stainfo fail\n", __FUNCTION__);
903 rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf);
904 rtw_free_xmitframe(pxmitpriv, pmgntframe);
909 if(!(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE))
910 ptdlsinfo->sta_cnt++;
912 if (ptdlsinfo->sta_cnt == MAX_ALLOWED_TDLS_STA_NUM)
913 ptdlsinfo->sta_maximum = _TRUE;
915 ptdls_sta->tdls_sta_state |= TDLS_RESPONDER_STATE;
917 if (rtw_tdls_is_driver_setup(padapter) == _TRUE) {
918 ptdls_sta->TDLS_PeerKey_Lifetime = timeout_interval;
919 _set_timer(&ptdls_sta->handshake_timer, TDLS_HANDSHAKE_TIME);
922 pattrib->qsel = pattrib->priority;
924 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) !=_SUCCESS) {
925 rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf);
926 rtw_free_xmitframe(pxmitpriv, pmgntframe);
931 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
933 dump_mgntframe(padapter, pmgntframe);
942 int _issue_tdls_teardown(_adapter *padapter, struct tdls_txmgmt *ptxmgmt, u8 wait_ack)
944 struct xmit_frame *pmgntframe;
945 struct pkt_attrib *pattrib;
946 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
947 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
948 struct sta_priv *pstapriv = &padapter->stapriv;
949 struct sta_info *ptdls_sta=NULL;
953 DBG_871X("[TDLS] %s\n", __FUNCTION__);
955 ptxmgmt->action_code = TDLS_TEARDOWN;
956 ptdls_sta = rtw_get_stainfo(pstapriv, ptxmgmt->peer);
957 if (ptdls_sta == NULL) {
958 DBG_871X("Np tdls_sta for tearing down\n");
962 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
965 rtw_set_scan_deny(padapter, 550);
967 rtw_scan_abort(padapter);
968 #ifdef CONFIG_CONCURRENT_MODE
969 if (rtw_buddy_adapter_up(padapter))
970 rtw_scan_abort(padapter->pbuddy_adapter);
971 #endif /* CONFIG_CONCURRENT_MODE */
973 pattrib = &pmgntframe->attrib;
975 pmgntframe->frame_tag = DATA_FRAMETAG;
976 pattrib->ether_type = 0x890d;
978 _rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN);
979 _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
980 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
981 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
983 update_tdls_attrib(padapter, pattrib);
984 pattrib->qsel = pattrib->priority;
985 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) != _SUCCESS) {
986 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
987 rtw_free_xmitframe(pxmitpriv, pmgntframe);
991 if (rtw_tdls_is_driver_setup(padapter) == _TRUE)
992 if(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE)
993 if (pattrib->encrypt)
994 _cancel_timer_ex(&ptdls_sta->TPK_timer);
997 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
999 dump_mgntframe(padapter, pmgntframe);
1003 if (rtw_tdls_is_driver_setup(padapter))
1004 rtw_tdls_cmd(padapter, ptxmgmt->peer, TDLS_TEARDOWN_STA_LOCALLY);
1011 int issue_tdls_teardown(_adapter *padapter, struct tdls_txmgmt *ptxmgmt, u8 wait_ack)
1015 ret = _issue_tdls_teardown(padapter, ptxmgmt, wait_ack);
1016 if ((ptxmgmt->status_code == _RSON_TDLS_TEAR_UN_RSN_) && (ret == _FAIL)) {
1017 /* Change status code and send teardown again via AP */
1018 ptxmgmt->status_code = _RSON_TDLS_TEAR_TOOFAR_;
1019 ret = _issue_tdls_teardown(padapter, ptxmgmt, wait_ack);
1025 int issue_tdls_dis_req(_adapter *padapter, struct tdls_txmgmt *ptxmgmt)
1027 struct xmit_frame *pmgntframe;
1028 struct pkt_attrib *pattrib;
1029 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1030 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
1033 DBG_871X("[TDLS] %s\n", __FUNCTION__);
1035 ptxmgmt->action_code = TDLS_DISCOVERY_REQUEST;
1036 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
1039 pattrib = &pmgntframe->attrib;
1040 pmgntframe->frame_tag = DATA_FRAMETAG;
1041 pattrib->ether_type = 0x890d;
1043 _rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN);
1044 _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
1045 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
1046 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1048 update_tdls_attrib(padapter, pattrib);
1049 pattrib->qsel = pattrib->priority;
1050 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) != _SUCCESS) {
1051 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
1052 rtw_free_xmitframe(pxmitpriv, pmgntframe);
1055 dump_mgntframe(padapter, pmgntframe);
1056 DBG_871X("issue tdls dis req\n");
1064 int issue_tdls_setup_rsp(_adapter *padapter, struct tdls_txmgmt *ptxmgmt)
1066 struct xmit_frame *pmgntframe;
1067 struct pkt_attrib *pattrib;
1068 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
1071 DBG_871X("[TDLS] %s\n", __FUNCTION__);
1073 ptxmgmt->action_code = TDLS_SETUP_RESPONSE;
1074 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
1077 pattrib = &pmgntframe->attrib;
1078 pmgntframe->frame_tag = DATA_FRAMETAG;
1079 pattrib->ether_type = 0x890d;
1081 _rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN);
1082 _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
1083 _rtw_memcpy(pattrib->ra, get_bssid(&(padapter->mlmepriv)), ETH_ALEN);
1084 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1086 update_tdls_attrib(padapter, pattrib);
1087 pattrib->qsel = pattrib->priority;
1088 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) != _SUCCESS) {
1089 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
1090 rtw_free_xmitframe(pxmitpriv, pmgntframe);
1094 dump_mgntframe(padapter, pmgntframe);
1103 int issue_tdls_setup_cfm(_adapter *padapter, struct tdls_txmgmt *ptxmgmt)
1105 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
1106 struct xmit_frame *pmgntframe;
1107 struct pkt_attrib *pattrib;
1108 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
1111 DBG_871X("[TDLS] %s\n", __FUNCTION__);
1113 ptxmgmt->action_code = TDLS_SETUP_CONFIRM;
1114 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
1117 pattrib = &pmgntframe->attrib;
1118 pmgntframe->frame_tag = DATA_FRAMETAG;
1119 pattrib->ether_type = 0x890d;
1121 _rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN);
1122 _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
1123 _rtw_memcpy(pattrib->ra, get_bssid(&padapter->mlmepriv), ETH_ALEN);
1124 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1126 update_tdls_attrib(padapter, pattrib);
1127 pattrib->qsel = pattrib->priority;
1128 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) != _SUCCESS) {
1129 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
1130 rtw_free_xmitframe(pxmitpriv, pmgntframe);
1134 dump_mgntframe(padapter, pmgntframe);
1143 /* TDLS Discovery Response frame is a management action frame */
1144 int issue_tdls_dis_rsp(_adapter *padapter, struct tdls_txmgmt *ptxmgmt, u8 privacy)
1146 struct xmit_frame *pmgntframe;
1147 struct pkt_attrib *pattrib;
1148 unsigned char *pframe;
1149 struct rtw_ieee80211_hdr *pwlanhdr;
1150 unsigned short *fctrl;
1151 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
1152 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1155 DBG_871X("[TDLS] %s\n", __FUNCTION__);
1157 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
1160 pattrib = &pmgntframe->attrib;
1161 update_mgntframe_attrib(padapter, pattrib);
1163 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
1165 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
1166 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
1168 fctrl = &(pwlanhdr->frame_ctl);
1171 /* unicast probe request frame */
1172 _rtw_memcpy(pwlanhdr->addr1, ptxmgmt->peer, ETH_ALEN);
1173 _rtw_memcpy(pattrib->dst, pwlanhdr->addr1, ETH_ALEN);
1174 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
1175 _rtw_memcpy(pattrib->src, pwlanhdr->addr2, ETH_ALEN);
1176 _rtw_memcpy(pwlanhdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN);
1177 _rtw_memcpy(pattrib->ra, pwlanhdr->addr3, ETH_ALEN);
1179 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
1180 pmlmeext->mgnt_seq++;
1181 SetFrameSubType(pframe, WIFI_ACTION);
1183 pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
1184 pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
1186 rtw_build_tdls_dis_rsp_ies(padapter, pmgntframe, pframe, ptxmgmt, privacy);
1188 pattrib->nr_frags = 1;
1189 pattrib->last_txcmdsz = pattrib->pktlen;
1191 dump_mgntframe(padapter, pmgntframe);
1198 int issue_tdls_peer_traffic_rsp(_adapter *padapter, struct sta_info *ptdls_sta, struct tdls_txmgmt *ptxmgmt)
1200 struct xmit_frame *pmgntframe;
1201 struct pkt_attrib *pattrib;
1202 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1203 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
1206 DBG_871X("[TDLS] %s\n", __FUNCTION__);
1208 ptxmgmt->action_code = TDLS_PEER_TRAFFIC_RESPONSE;
1210 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
1213 pattrib = &pmgntframe->attrib;
1215 pmgntframe->frame_tag = DATA_FRAMETAG;
1216 pattrib->ether_type = 0x890d;
1218 _rtw_memcpy(pattrib->dst, ptdls_sta->hwaddr, ETH_ALEN);
1219 _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
1220 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
1221 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1223 update_tdls_attrib(padapter, pattrib);
1224 pattrib->qsel = pattrib->priority;
1226 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) !=_SUCCESS) {
1227 rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf);
1228 rtw_free_xmitframe(pxmitpriv, pmgntframe);
1232 dump_mgntframe(padapter, pmgntframe);
1240 int issue_tdls_peer_traffic_indication(_adapter *padapter, struct sta_info *ptdls_sta)
1242 struct xmit_frame *pmgntframe;
1243 struct pkt_attrib *pattrib;
1244 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1245 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
1246 struct tdls_txmgmt txmgmt;
1249 DBG_871X("[TDLS] %s\n", __FUNCTION__);
1251 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
1252 txmgmt.action_code = TDLS_PEER_TRAFFIC_INDICATION;
1254 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
1257 pattrib = &pmgntframe->attrib;
1259 pmgntframe->frame_tag = DATA_FRAMETAG;
1260 pattrib->ether_type = 0x890d;
1262 _rtw_memcpy(pattrib->dst, ptdls_sta->hwaddr, ETH_ALEN);
1263 _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
1264 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
1265 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1267 /* PTI frame's priority should be AC_VO */
1268 pattrib->priority = 7;
1270 update_tdls_attrib(padapter, pattrib);
1271 pattrib->qsel = pattrib->priority;
1272 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, &txmgmt) != _SUCCESS) {
1273 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
1274 rtw_free_xmitframe(pxmitpriv, pmgntframe);
1278 dump_mgntframe(padapter, pmgntframe);
1286 #ifdef CONFIG_TDLS_CH_SW
1287 int issue_tdls_ch_switch_req(_adapter *padapter, struct sta_info *ptdls_sta)
1289 struct xmit_frame *pmgntframe;
1290 struct pkt_attrib *pattrib;
1291 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1292 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
1293 struct tdls_txmgmt txmgmt;
1296 DBG_871X("[TDLS] %s\n", __FUNCTION__);
1298 if (rtw_tdls_is_chsw_allowed(padapter) == _FALSE) {
1299 DBG_871X("[TDLS] Ignore %s since channel switch is not allowed\n", __func__);
1303 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
1304 txmgmt.action_code = TDLS_CHANNEL_SWITCH_REQUEST;
1306 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
1309 pattrib = &pmgntframe->attrib;
1311 pmgntframe->frame_tag = DATA_FRAMETAG;
1312 pattrib->ether_type = 0x890d;
1314 _rtw_memcpy(pattrib->dst, ptdls_sta->hwaddr, ETH_ALEN);
1315 _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
1316 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
1317 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1319 update_tdls_attrib(padapter, pattrib);
1320 pattrib->qsel = pattrib->priority;
1321 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, &txmgmt) !=_SUCCESS) {
1322 rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf);
1323 rtw_free_xmitframe(pxmitpriv, pmgntframe);
1327 dump_mgntframe(padapter, pmgntframe);
1334 int issue_tdls_ch_switch_rsp(_adapter *padapter, struct tdls_txmgmt *ptxmgmt, int wait_ack)
1336 struct xmit_frame *pmgntframe;
1337 struct pkt_attrib *pattrib;
1338 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1339 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
1342 DBG_871X("[TDLS] %s\n", __FUNCTION__);
1344 if (rtw_tdls_is_chsw_allowed(padapter) == _FALSE) {
1345 DBG_871X("[TDLS] Ignore %s since channel switch is not allowed\n", __func__);
1349 ptxmgmt->action_code = TDLS_CHANNEL_SWITCH_RESPONSE;
1351 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
1354 pattrib = &pmgntframe->attrib;
1356 pmgntframe->frame_tag = DATA_FRAMETAG;
1357 pattrib->ether_type = 0x890d;
1359 _rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN);
1360 _rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
1361 _rtw_memcpy(pattrib->ra, ptxmgmt->peer, ETH_ALEN);
1362 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1364 update_tdls_attrib(padapter, pattrib);
1365 pattrib->qsel = pattrib->priority;
1367 _enter_critical_bh(&pxmitpriv->lock, &irqL);
1368 if(xmitframe_enqueue_for_tdls_sleeping_sta(padapter, pmgntframe)==_TRUE){
1369 _exit_critical_bh(&pxmitpriv->lock, &irqL);
1373 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) !=_SUCCESS) {
1374 rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf);
1375 rtw_free_xmitframe(pxmitpriv, pmgntframe);
1380 ret = dump_mgntframe_and_wait_ack_timeout(padapter, pmgntframe, 10);
1382 dump_mgntframe(padapter, pmgntframe);
1391 int On_TDLS_Dis_Rsp(_adapter *padapter, union recv_frame *precv_frame)
1393 struct sta_info *ptdls_sta = NULL, *psta = rtw_get_stainfo(&(padapter->stapriv), get_bssid(&(padapter->mlmepriv)));
1394 struct recv_priv *precvpriv = &(padapter->recvpriv);
1395 u8 *ptr = precv_frame->u.hdr.rx_data, *psa;
1396 struct rx_pkt_attrib *pattrib = &(precv_frame->u.hdr.attrib);
1397 struct tdls_info *ptdlsinfo = &(padapter->tdlsinfo);
1398 u8 empty_addr[ETH_ALEN] = { 0x00 };
1399 int UndecoratedSmoothedPWDB;
1400 struct tdls_txmgmt txmgmt;
1403 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
1404 /* WFDTDLS: for sigma test, not to setup direct link automatically */
1405 ptdlsinfo->dev_discovered = _TRUE;
1408 ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), psa);
1409 if (ptdls_sta != NULL)
1410 ptdls_sta->sta_stats.rx_tdls_disc_rsp_pkts++;
1412 #ifdef CONFIG_TDLS_AUTOSETUP
1413 if (ptdls_sta != NULL) {
1414 /* Record the tdls sta with lowest signal strength */
1415 if (ptdlsinfo->sta_maximum == _TRUE && ptdls_sta->alive_count >= 1 ) {
1416 if (_rtw_memcmp(ptdlsinfo->ss_record.macaddr, empty_addr, ETH_ALEN)) {
1417 _rtw_memcpy(ptdlsinfo->ss_record.macaddr, psa, ETH_ALEN);
1418 ptdlsinfo->ss_record.RxPWDBAll = pattrib->phy_info.RxPWDBAll;
1420 if (ptdlsinfo->ss_record.RxPWDBAll < pattrib->phy_info.RxPWDBAll) {
1421 _rtw_memcpy(ptdlsinfo->ss_record.macaddr, psa, ETH_ALEN);
1422 ptdlsinfo->ss_record.RxPWDBAll = pattrib->phy_info.RxPWDBAll;
1427 if (ptdlsinfo->sta_maximum == _TRUE) {
1428 if (_rtw_memcmp( ptdlsinfo->ss_record.macaddr, empty_addr, ETH_ALEN)) {
1429 /* All traffics are busy, do not set up another direct link. */
1433 if (pattrib->phy_info.RxPWDBAll > ptdlsinfo->ss_record.RxPWDBAll) {
1434 _rtw_memcpy(txmgmt.peer, ptdlsinfo->ss_record.macaddr, ETH_ALEN);
1435 /* issue_tdls_teardown(padapter, ptdlsinfo->ss_record.macaddr, _FALSE); */
1443 rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
1445 if (pattrib->phy_info.RxPWDBAll + TDLS_SIGNAL_THRESH >= UndecoratedSmoothedPWDB) {
1446 DBG_871X("pattrib->RxPWDBAll=%d, pdmpriv->UndecoratedSmoothedPWDB=%d\n", pattrib->phy_info.RxPWDBAll, UndecoratedSmoothedPWDB);
1447 _rtw_memcpy(txmgmt.peer, psa, ETH_ALEN);
1448 issue_tdls_setup_req(padapter, &txmgmt, _FALSE);
1451 #endif /* CONFIG_TDLS_AUTOSETUP */
1458 sint On_TDLS_Setup_Req(_adapter *padapter, union recv_frame *precv_frame)
1460 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
1462 struct sta_info *ptdls_sta= NULL;
1463 struct sta_priv *pstapriv = &padapter->stapriv;
1464 u8 *ptr = precv_frame->u.hdr.rx_data;
1465 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1466 struct security_priv *psecuritypriv = &padapter->securitypriv;
1468 struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
1469 u8 *prsnie, *ppairwise_cipher;
1471 u8 ccmp_included=0, rsnie_included=0;
1472 u16 j, pairwise_count;
1474 u32 timeout_interval = TDLS_TPK_RESEND_COUNT;
1475 sint parsing_length; /* Frame body length, without icv_len */
1476 PNDIS_802_11_VARIABLE_IEs pIE;
1478 unsigned char supportRate[16];
1479 int supportRateNum = 0;
1480 struct tdls_txmgmt txmgmt;
1482 if (rtw_tdls_is_setup_allowed(padapter) == _FALSE)
1485 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
1487 ptdls_sta = rtw_get_stainfo(pstapriv, psa);
1489 pmyid = adapter_mac_addr(padapter);
1490 ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+ETH_TYPE_LEN+PAYLOAD_TYPE_LEN;
1491 parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
1492 -prx_pkt_attrib->hdrlen
1493 -prx_pkt_attrib->iv_len
1494 -prx_pkt_attrib->icv_len
1500 if (ptdls_sta == NULL) {
1501 ptdls_sta = rtw_alloc_stainfo(pstapriv, psa);
1503 if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) {
1504 /* If the direct link is already set up */
1505 /* Process as re-setup after tear down */
1506 DBG_871X("re-setup a direct link\n");
1508 /* Already receiving TDLS setup request */
1509 else if (ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE) {
1510 DBG_871X("receive duplicated TDLS setup request frame in handshaking\n");
1513 /* When receiving and sending setup_req to the same link at the same time */
1514 /* STA with higher MAC_addr would be initiator */
1515 else if (ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE) {
1516 DBG_871X("receive setup_req after sending setup_req\n");
1518 if(*(pmyid+i)==*(psa+i)){
1520 else if(*(pmyid+i)>*(psa+i)){
1521 ptdls_sta->tdls_sta_state = TDLS_INITIATOR_STATE;
1523 }else if(*(pmyid+i)<*(psa+i)){
1531 txmgmt.dialog_token = *(ptr+2); /* Copy dialog token */
1532 txmgmt.status_code = _STATS_SUCCESSFUL_;
1534 /* Parsing information element */
1535 for (j=FIXED_IE; j<parsing_length;) {
1537 pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
1539 switch (pIE->ElementID) {
1540 case _SUPPORTEDRATES_IE_:
1541 _rtw_memcpy(supportRate, pIE->data, pIE->Length);
1542 supportRateNum = pIE->Length;
1546 case _EXT_SUPPORTEDRATES_IE_:
1547 if (supportRateNum<=sizeof(supportRate)) {
1548 _rtw_memcpy(supportRate+supportRateNum, pIE->data, pIE->Length);
1549 supportRateNum += pIE->Length;
1552 case _SUPPORTED_CH_IE_:
1556 if (prx_pkt_attrib->encrypt) {
1558 /* Check CCMP pairwise_cipher presence. */
1559 ppairwise_cipher=prsnie+10;
1560 _rtw_memcpy(ptdls_sta->TDLS_RSNIE, pIE->data, pIE->Length);
1561 pairwise_count = *(u16*)(ppairwise_cipher-2);
1562 for (k=0; k<pairwise_count; k++) {
1563 if (_rtw_memcmp( ppairwise_cipher+4*k, RSN_CIPHER_SUITE_CCMP, 4)==_TRUE)
1567 if (ccmp_included == 0)
1568 txmgmt.status_code=_STATS_INVALID_RSNIE_;
1573 case _VENDOR_SPECIFIC_IE_:
1576 if (prx_pkt_attrib->encrypt)
1577 _rtw_memcpy(SNonce, (ptr+j+52), 32);
1579 case _TIMEOUT_ITVL_IE_:
1580 if (prx_pkt_attrib->encrypt)
1581 timeout_interval = cpu_to_le32(*(u32*)(ptr+j+3));
1583 case _RIC_Descriptor_IE_:
1585 #ifdef CONFIG_80211N_HT
1586 case _HT_CAPABILITY_IE_:
1587 rtw_tdls_process_ht_cap(padapter, ptdls_sta, pIE->data, pIE->Length);
1590 case EID_BSSCoexistence:
1593 if (_rtw_memcmp(get_bssid(pmlmepriv), pIE->data, 6) == _FALSE)
1594 txmgmt.status_code=_STATS_NOT_IN_SAME_BSS_;
1600 j += (pIE->Length + 2);
1604 /* Check status code */
1605 /* If responder STA has/hasn't security on AP, but request hasn't/has RSNIE, it should reject */
1606 if (txmgmt.status_code == _STATS_SUCCESSFUL_) {
1607 if (rsnie_included && prx_pkt_attrib->encrypt == 0)
1608 txmgmt.status_code = _STATS_SEC_DISABLED_;
1609 else if (rsnie_included==0 && prx_pkt_attrib->encrypt)
1610 txmgmt.status_code = _STATS_INVALID_PARAMETERS_;
1613 /* WFD test plan version 0.18.2 test item 5.1.5 */
1614 /* SoUT does not use TDLS if AP uses weak security */
1615 if (padapter->wdinfo.wfd_tdls_enable && (rsnie_included && prx_pkt_attrib->encrypt != _AES_))
1616 txmgmt.status_code = _STATS_SEC_DISABLED_;
1617 #endif /* CONFIG_WFD */
1620 ptdls_sta->tdls_sta_state|= TDLS_INITIATOR_STATE;
1621 if (prx_pkt_attrib->encrypt) {
1622 _rtw_memcpy(ptdls_sta->SNonce, SNonce, 32);
1624 if (timeout_interval <= 300)
1625 ptdls_sta->TDLS_PeerKey_Lifetime = TDLS_TPK_RESEND_COUNT;
1627 ptdls_sta->TDLS_PeerKey_Lifetime = timeout_interval;
1630 /* Update station supportRate */
1631 ptdls_sta->bssratelen = supportRateNum;
1632 _rtw_memcpy(ptdls_sta->bssrateset, supportRate, supportRateNum);
1634 if (!(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE))
1635 ptdlsinfo->sta_cnt++;
1636 /* -2: AP + BC/MC sta, -4: default key */
1637 if (ptdlsinfo->sta_cnt == MAX_ALLOWED_TDLS_STA_NUM)
1638 ptdlsinfo->sta_maximum = _TRUE;
1641 rtw_tdls_process_wfd_ie(ptdlsinfo, ptr + FIXED_IE, parsing_length);
1648 _rtw_memcpy(txmgmt.peer, prx_pkt_attrib->src, ETH_ALEN);
1650 if (rtw_tdls_is_driver_setup(padapter)) {
1651 issue_tdls_setup_rsp(padapter, &txmgmt);
1653 if (txmgmt.status_code==_STATS_SUCCESSFUL_) {
1654 _set_timer( &ptdls_sta->handshake_timer, TDLS_HANDSHAKE_TIME);
1656 free_tdls_sta(padapter, ptdls_sta);
1665 int On_TDLS_Setup_Rsp(_adapter *padapter, union recv_frame *precv_frame)
1667 struct registry_priv *pregistrypriv = &padapter->registrypriv;
1668 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
1669 struct sta_info *ptdls_sta= NULL;
1670 struct sta_priv *pstapriv = &padapter->stapriv;
1671 u8 *ptr = precv_frame->u.hdr.rx_data;
1673 struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
1676 sint parsing_length; /* Frame body length, without icv_len */
1677 PNDIS_802_11_VARIABLE_IEs pIE;
1680 u8 *pftie=NULL, *ptimeout_ie=NULL, *plinkid_ie=NULL, *prsnie=NULL, *pftie_mic=NULL, *ppairwise_cipher=NULL;
1681 u16 pairwise_count, j, k;
1683 unsigned char supportRate[16];
1684 int supportRateNum = 0;
1685 struct tdls_txmgmt txmgmt;
1687 u32 timeout_interval = TDLS_TPK_RESEND_COUNT;
1689 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
1691 ptdls_sta = rtw_get_stainfo(pstapriv, psa);
1693 if (ptdls_sta == NULL) {
1694 DBG_871X("[%s] Direct Link Peer = "MAC_FMT" not found\n", __func__, MAC_ARG(psa));
1699 ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+ETH_TYPE_LEN+PAYLOAD_TYPE_LEN;
1700 parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
1701 -prx_pkt_attrib->hdrlen
1702 -prx_pkt_attrib->iv_len
1703 -prx_pkt_attrib->icv_len
1709 _rtw_memcpy(&status_code, ptr+2, 2);
1711 if (status_code != 0) {
1712 DBG_871X( "[TDLS] %s status_code = %d, free_tdls_sta\n", __FUNCTION__, status_code );
1713 free_tdls_sta(padapter, ptdls_sta);
1720 /* parsing information element */
1721 for (j = FIXED_IE; j<parsing_length;) {
1722 pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
1724 switch (pIE->ElementID) {
1725 case _SUPPORTEDRATES_IE_:
1726 _rtw_memcpy(supportRate, pIE->data, pIE->Length);
1727 supportRateNum = pIE->Length;
1731 case _EXT_SUPPORTEDRATES_IE_:
1732 if (supportRateNum<=sizeof(supportRate)) {
1733 _rtw_memcpy(supportRate+supportRateNum, pIE->data, pIE->Length);
1734 supportRateNum += pIE->Length;
1737 case _SUPPORTED_CH_IE_:
1741 /* Check CCMP pairwise_cipher presence. */
1742 ppairwise_cipher=prsnie+10;
1743 _rtw_memcpy(&pairwise_count, (u16*)(ppairwise_cipher-2), 2);
1744 for (k=0;k<pairwise_count;k++) {
1745 if (_rtw_memcmp( ppairwise_cipher+4*k, RSN_CIPHER_SUITE_CCMP, 4) == _TRUE)
1750 case _VENDOR_SPECIFIC_IE_:
1751 if (_rtw_memcmp((u8 *)pIE + 2, WMM_INFO_OUI, 6) == _TRUE) {
1752 /* WMM Info ID and OUI */
1753 if ((pregistrypriv->wmm_enable == _TRUE) || (padapter->mlmepriv.htpriv.ht_option == _TRUE))
1754 ptdls_sta->qos_option = _TRUE;
1759 _rtw_memcpy(ANonce, (ptr+j+20), 32);
1761 case _TIMEOUT_ITVL_IE_:
1762 ptimeout_ie=(u8*)pIE;
1763 timeout_interval = cpu_to_le32(*(u32*)(ptimeout_ie+3));
1765 case _RIC_Descriptor_IE_:
1767 #ifdef CONFIG_80211N_HT
1768 case _HT_CAPABILITY_IE_:
1769 rtw_tdls_process_ht_cap(padapter, ptdls_sta, pIE->data, pIE->Length);
1772 case EID_BSSCoexistence:
1775 plinkid_ie=(u8*)pIE;
1781 j += (pIE->Length + 2);
1785 ptdls_sta->bssratelen = supportRateNum;
1786 _rtw_memcpy(ptdls_sta->bssrateset, supportRate, supportRateNum);
1787 _rtw_memcpy(ptdls_sta->ANonce, ANonce, 32);
1790 rtw_tdls_process_wfd_ie(ptdlsinfo, ptr + FIXED_IE, parsing_length);
1793 if (status_code != _STATS_SUCCESSFUL_) {
1794 txmgmt.status_code = status_code;
1796 if (prx_pkt_attrib->encrypt) {
1797 if (verify_ccmp == 1) {
1798 txmgmt.status_code = _STATS_SUCCESSFUL_;
1799 if (rtw_tdls_is_driver_setup(padapter) == _TRUE) {
1800 wpa_tdls_generate_tpk(padapter, ptdls_sta);
1801 if (tdls_verify_mic(ptdls_sta->tpk.kck, 2, plinkid_ie, prsnie, ptimeout_ie, pftie) == _FAIL) {
1802 DBG_871X( "[TDLS] %s tdls_verify_mic fail, free_tdls_sta\n", __FUNCTION__);
1803 free_tdls_sta(padapter, ptdls_sta);
1807 ptdls_sta->TDLS_PeerKey_Lifetime = timeout_interval;
1812 txmgmt.status_code = _STATS_INVALID_RSNIE_;
1816 txmgmt.status_code = _STATS_SUCCESSFUL_;
1820 if (rtw_tdls_is_driver_setup(padapter) == _TRUE) {
1821 _rtw_memcpy(txmgmt.peer, prx_pkt_attrib->src, ETH_ALEN);
1822 issue_tdls_setup_cfm(padapter, &txmgmt);
1824 if (txmgmt.status_code == _STATS_SUCCESSFUL_) {
1825 ptdlsinfo->link_established = _TRUE;
1827 if (ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE) {
1828 ptdls_sta->tdls_sta_state |= TDLS_LINKED_STATE;
1829 ptdls_sta->state |= _FW_LINKED;
1830 _cancel_timer_ex( &ptdls_sta->handshake_timer);
1833 if (prx_pkt_attrib->encrypt)
1834 rtw_tdls_set_key(padapter, ptdls_sta);
1836 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_ESTABLISHED);
1842 if (rtw_tdls_is_driver_setup(padapter) == _TRUE)
1849 int On_TDLS_Setup_Cfm(_adapter *padapter, union recv_frame *precv_frame)
1851 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
1852 struct sta_info *ptdls_sta= NULL;
1853 struct sta_priv *pstapriv = &padapter->stapriv;
1854 u8 *ptr = precv_frame->u.hdr.rx_data;
1856 struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
1859 sint parsing_length;
1860 PNDIS_802_11_VARIABLE_IEs pIE;
1862 u8 *pftie=NULL, *ptimeout_ie=NULL, *plinkid_ie=NULL, *prsnie=NULL, *pftie_mic=NULL, *ppairwise_cipher=NULL;
1863 u16 j, pairwise_count;
1867 ptdls_sta = rtw_get_stainfo(pstapriv, psa);
1869 if (ptdls_sta == NULL) {
1870 DBG_871X("[%s] Direct Link Peer = "MAC_FMT" not found\n", __FUNCTION__, MAC_ARG(psa));
1875 ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+ETH_TYPE_LEN+PAYLOAD_TYPE_LEN;
1876 parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
1877 -prx_pkt_attrib->hdrlen
1878 -prx_pkt_attrib->iv_len
1879 -prx_pkt_attrib->icv_len
1885 _rtw_memcpy(&status_code, ptr+2, 2);
1887 if (status_code!= 0) {
1888 DBG_871X("[%s] status_code = %d\n, free_tdls_sta", __FUNCTION__, status_code);
1889 free_tdls_sta(padapter, ptdls_sta);
1894 /* Parsing information element */
1895 for (j = FIXED_IE; j < parsing_length;) {
1897 pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr + j);
1899 switch (pIE->ElementID) {
1903 case _VENDOR_SPECIFIC_IE_:
1904 if (_rtw_memcmp((u8 *)pIE + 2, WMM_PARA_OUI, 6) == _TRUE) {
1905 /* WMM Parameter ID and OUI */
1906 ptdls_sta->qos_option = _TRUE;
1912 case _TIMEOUT_ITVL_IE_:
1913 ptimeout_ie = (u8 *)pIE;
1915 #ifdef CONFIG_80211N_HT
1916 case _HT_EXTRA_INFO_IE_:
1920 plinkid_ie = (u8 *)pIE;
1926 j += (pIE->Length + 2);
1930 if (prx_pkt_attrib->encrypt) {
1931 /* Verify mic in FTIE MIC field */
1932 if (rtw_tdls_is_driver_setup(padapter) &&
1933 (tdls_verify_mic(ptdls_sta->tpk.kck, 3, plinkid_ie, prsnie, ptimeout_ie, pftie) == _FAIL)) {
1934 free_tdls_sta(padapter, ptdls_sta);
1940 if (rtw_tdls_is_driver_setup(padapter)) {
1941 ptdlsinfo->link_established = _TRUE;
1943 if (ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE) {
1944 ptdls_sta->tdls_sta_state|=TDLS_LINKED_STATE;
1945 ptdls_sta->state |= _FW_LINKED;
1946 _cancel_timer_ex(&ptdls_sta->handshake_timer);
1949 if (prx_pkt_attrib->encrypt) {
1950 rtw_tdls_set_key(padapter, ptdls_sta);
1952 /* Start TPK timer */
1953 ptdls_sta->TPK_count = 0;
1954 _set_timer(&ptdls_sta->TPK_timer, ONE_SEC);
1957 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_ESTABLISHED);
1965 int On_TDLS_Dis_Req(_adapter *padapter, union recv_frame *precv_frame)
1967 struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
1968 struct sta_priv *pstapriv = &padapter->stapriv;
1969 struct sta_info *psta_ap;
1970 u8 *ptr = precv_frame->u.hdr.rx_data;
1971 sint parsing_length; /* Frame body length, without icv_len */
1972 PNDIS_802_11_VARIABLE_IEs pIE;
1973 u8 FIXED_IE = 3, *dst;
1975 struct tdls_txmgmt txmgmt;
1978 if (rtw_tdls_is_driver_setup(padapter) == _FALSE)
1981 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
1982 ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+ETH_TYPE_LEN+PAYLOAD_TYPE_LEN;
1983 txmgmt.dialog_token = *(ptr+2);
1984 _rtw_memcpy(&txmgmt.peer, precv_frame->u.hdr.attrib.src, ETH_ALEN);
1985 txmgmt.action_code = TDLS_DISCOVERY_RESPONSE;
1986 parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
1987 -prx_pkt_attrib->hdrlen
1988 -prx_pkt_attrib->iv_len
1989 -prx_pkt_attrib->icv_len
1995 /* Parsing information element */
1996 for (j=FIXED_IE; j<parsing_length;) {
1998 pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
2000 switch (pIE->ElementID) {
2002 psta_ap = rtw_get_stainfo(pstapriv, pIE->data);
2003 if (psta_ap == NULL)
2005 dst = pIE->data + 12;
2006 if (MacAddr_isBcst(dst) == _FALSE && (_rtw_memcmp(adapter_mac_addr(padapter), dst, 6) == _FALSE))
2013 j += (pIE->Length + 2);
2017 issue_tdls_dis_rsp(padapter, &txmgmt, prx_pkt_attrib->privacy);
2024 int On_TDLS_Teardown(_adapter *padapter, union recv_frame *precv_frame)
2027 u8 *ptr = precv_frame->u.hdr.rx_data;
2028 struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
2029 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2030 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2031 struct sta_priv *pstapriv = &padapter->stapriv;
2032 struct sta_info *ptdls_sta= NULL;
2036 reason = *(ptr + prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len + LLC_HEADER_SIZE + ETH_TYPE_LEN + PAYLOAD_TYPE_LEN + 2);
2037 DBG_871X("[TDLS] %s Reason code(%d)\n", __FUNCTION__,reason);
2041 ptdls_sta = rtw_get_stainfo(pstapriv, psa);
2042 if (ptdls_sta != NULL) {
2043 if (rtw_tdls_is_driver_setup(padapter))
2044 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_TEARDOWN_STA_LOCALLY);
2052 u8 TDLS_check_ch_state(uint state){
2053 if (state & TDLS_CH_SWITCH_ON_STATE &&
2054 state & TDLS_PEER_AT_OFF_STATE) {
2055 if (state & TDLS_PEER_SLEEP_STATE)
2056 return 2; /* U-APSD + ch. switch */
2058 return 1; /* ch. switch */
2064 int On_TDLS_Peer_Traffic_Indication(_adapter *padapter, union recv_frame *precv_frame)
2066 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
2067 struct sta_info *ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->src);
2068 u8 *ptr = precv_frame->u.hdr.rx_data;
2069 struct tdls_txmgmt txmgmt;
2071 ptr +=pattrib->hdrlen + pattrib->iv_len+LLC_HEADER_SIZE+ETH_TYPE_LEN+PAYLOAD_TYPE_LEN;
2072 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
2074 if (ptdls_sta != NULL) {
2075 txmgmt.dialog_token = *(ptr+2);
2076 issue_tdls_peer_traffic_rsp(padapter, ptdls_sta, &txmgmt);
2077 //issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->hwaddr, 0, 0, 0);
2079 DBG_871X("from unknown sta:"MAC_FMT"\n", MAC_ARG(pattrib->src));
2086 /* We process buffered data for 1. U-APSD, 2. ch. switch, 3. U-APSD + ch. switch here */
2087 int On_TDLS_Peer_Traffic_Rsp(_adapter *padapter, union recv_frame *precv_frame)
2089 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
2090 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2091 struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib;
2092 struct sta_priv *pstapriv = &padapter->stapriv;
2093 struct sta_info *ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->src);
2095 /* u8 state=TDLS_check_ch_state(ptdls_sta->tdls_sta_state); */
2098 ptdls_sta->sta_stats.rx_data_pkts++;
2100 ptdls_sta->tdls_sta_state &= ~(TDLS_WAIT_PTR_STATE);
2102 /* Check 4-AC queue bit */
2103 if (ptdls_sta->uapsd_vo || ptdls_sta->uapsd_vi || ptdls_sta->uapsd_be || ptdls_sta->uapsd_bk)
2106 /* If it's a direct link and have buffered frame */
2107 if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) {
2110 _list *xmitframe_plist, *xmitframe_phead;
2111 struct xmit_frame *pxmitframe=NULL;
2113 _enter_critical_bh(&ptdls_sta->sleep_q.lock, &irqL);
2115 xmitframe_phead = get_list_head(&ptdls_sta->sleep_q);
2116 xmitframe_plist = get_next(xmitframe_phead);
2118 /* transmit buffered frames */
2119 while (rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist) == _FALSE) {
2120 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
2121 xmitframe_plist = get_next(xmitframe_plist);
2122 rtw_list_delete(&pxmitframe->list);
2124 ptdls_sta->sleepq_len--;
2125 ptdls_sta->sleepq_ac_len--;
2126 if (ptdls_sta->sleepq_len>0) {
2127 pxmitframe->attrib.mdata = 1;
2128 pxmitframe->attrib.eosp = 0;
2130 pxmitframe->attrib.mdata = 0;
2131 pxmitframe->attrib.eosp = 1;
2133 pxmitframe->attrib.triggered = 1;
2135 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
2138 if (ptdls_sta->sleepq_len==0)
2139 DBG_871X("no buffered packets for tdls to xmit\n");
2141 DBG_871X("error!psta->sleepq_len=%d\n", ptdls_sta->sleepq_len);
2142 ptdls_sta->sleepq_len=0;
2145 _exit_critical_bh(&ptdls_sta->sleep_q.lock, &irqL);
2154 #ifdef CONFIG_TDLS_CH_SW
2155 sint On_TDLS_Ch_Switch_Req(_adapter *padapter, union recv_frame *precv_frame)
2157 struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
2158 struct sta_info *ptdls_sta= NULL;
2159 struct sta_priv *pstapriv = &padapter->stapriv;
2160 u8 *ptr = precv_frame->u.hdr.rx_data;
2161 struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
2163 sint parsing_length;
2164 PNDIS_802_11_VARIABLE_IEs pIE;
2167 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2168 struct tdls_txmgmt txmgmt;
2169 u8 zaddr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2170 u16 switch_time = TDLS_CH_SWITCH_TIME * 1000, switch_timeout = TDLS_CH_SWITCH_TIMEOUT * 1000;
2173 if (rtw_tdls_is_chsw_allowed(padapter) == _FALSE) {
2174 DBG_871X("[TDLS] Ignore %s since channel switch is not allowed\n", __func__);
2178 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
2180 ptdls_sta = rtw_get_stainfo(pstapriv, psa);
2182 if (ptdls_sta == NULL) {
2183 DBG_871X("[%s] Direct Link Peer = "MAC_FMT" not found\n", __func__, MAC_ARG(psa));
2187 ptdls_sta->ch_switch_time=switch_time;
2188 ptdls_sta->ch_switch_timeout=switch_timeout;
2190 ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+ETH_TYPE_LEN+PAYLOAD_TYPE_LEN;
2191 parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
2192 -prx_pkt_attrib->hdrlen
2193 -prx_pkt_attrib->iv_len
2194 -prx_pkt_attrib->icv_len
2200 pchsw_info->off_ch_num = *(ptr + 2);
2202 if ((*(ptr + 2) == 2) && (hal_is_band_support(padapter, BAND_ON_5G))) {
2203 pchsw_info->off_ch_num = 44;
2206 if (pchsw_info->off_ch_num != pmlmeext->cur_channel) {
2207 pchsw_info->delay_switch_back = _FALSE;
2210 /* Parsing information element */
2211 for (j=FIXED_IE; j<parsing_length;) {
2212 pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
2214 switch (pIE->ElementID) {
2215 case EID_SecondaryChnlOffset:
2216 switch (*(pIE->data)) {
2217 case EXTCHNL_OFFSET_UPPER:
2218 pchsw_info->ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
2221 case EXTCHNL_OFFSET_LOWER:
2222 pchsw_info->ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
2226 pchsw_info->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2232 case _CH_SWITCH_TIMING_:
2233 ptdls_sta->ch_switch_time = (RTW_GET_LE16(pIE->data) >= TDLS_CH_SWITCH_TIME * 1000) ?
2234 RTW_GET_LE16(pIE->data) : TDLS_CH_SWITCH_TIME * 1000;
2235 ptdls_sta->ch_switch_timeout = (RTW_GET_LE16(pIE->data + 2) >= TDLS_CH_SWITCH_TIMEOUT * 1000) ?
2236 RTW_GET_LE16(pIE->data + 2) : TDLS_CH_SWITCH_TIMEOUT * 1000;
2237 DBG_871X("[TDLS] %s ch_switch_time:%d, ch_switch_timeout:%d\n"
2238 , __FUNCTION__, RTW_GET_LE16(pIE->data), RTW_GET_LE16(pIE->data + 2));
2243 j += (pIE->Length + 2);
2246 rtw_hal_get_hwreg(padapter, HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO, &take_care_iqk);
2247 if (take_care_iqk == _TRUE) {
2251 bw_mode = (pchsw_info->ch_offset) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20;
2252 central_chnl = rtw_get_center_ch(pchsw_info->off_ch_num, bw_mode, pchsw_info->ch_offset);
2253 if (rtw_hal_ch_sw_iqk_info_search(padapter, central_chnl, bw_mode) < 0) {
2254 if (!(pchsw_info->ch_sw_state & TDLS_CH_SWITCH_PREPARE_STATE))
2255 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_PREPARE);
2261 /* cancel ch sw monitor timer for responder */
2262 if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
2263 _cancel_timer_ex(&ptdls_sta->ch_sw_monitor_timer);
2265 /* Todo: check status */
2266 txmgmt.status_code = 0;
2267 _rtw_memcpy(txmgmt.peer, psa, ETH_ALEN);
2269 if (_rtw_memcmp(pchsw_info->addr, zaddr, ETH_ALEN) == _TRUE)
2270 _rtw_memcpy(pchsw_info->addr, ptdls_sta->hwaddr, ETH_ALEN);
2272 if (ATOMIC_READ(&pchsw_info->chsw_on) == _FALSE)
2273 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_START);
2275 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_RESP);
2280 sint On_TDLS_Ch_Switch_Rsp(_adapter *padapter, union recv_frame *precv_frame)
2282 struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
2283 struct sta_info *ptdls_sta= NULL;
2284 struct sta_priv *pstapriv = &padapter->stapriv;
2285 u8 *ptr = precv_frame->u.hdr.rx_data;
2286 struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
2288 sint parsing_length;
2289 PNDIS_802_11_VARIABLE_IEs pIE;
2291 u16 status_code, j, switch_time, switch_timeout;
2292 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2295 if (rtw_tdls_is_chsw_allowed(padapter) == _FALSE) {
2296 DBG_871X("[TDLS] Ignore %s since channel switch is not allowed\n", __func__);
2301 ptdls_sta = rtw_get_stainfo(pstapriv, psa);
2303 if (ptdls_sta == NULL) {
2304 DBG_871X("[%s] Direct Link Peer = "MAC_FMT" not found\n", __func__, MAC_ARG(psa));
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("[TDLS] Rx unsolicited channel switch response\n");
2313 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_TO_BASE_CHNL);
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
2328 _rtw_memcpy(&status_code, ptr+2, 2);
2330 if (status_code != 0) {
2331 DBG_871X("[TDLS] %s status_code:%d\n", __func__, status_code);
2332 pchsw_info->ch_sw_state &= ~(TDLS_CH_SW_INITIATOR_STATE);
2333 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_END);
2338 /* Parsing information element */
2339 for (j = FIXED_IE; j < parsing_length;) {
2340 pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
2342 switch (pIE->ElementID) {
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);
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);
2358 j += (pIE->Length + 2);
2361 if ((pmlmeext->cur_channel == rtw_get_oper_ch(padapter)) &&
2362 (pchsw_info->ch_sw_state & TDLS_WAIT_CH_RSP_STATE)) {
2363 if (ATOMIC_READ(&pchsw_info->chsw_on) == _TRUE)
2364 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_TO_OFF_CHNL);
2370 #endif /* CONFIG_TDLS_CH_SW */
2373 void wfd_ie_tdls(_adapter * padapter, u8 *pframe, u32 *pktlen )
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 };
2380 if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST))
2385 wfdie[ wfdielen++ ] = 0x50;
2386 wfdie[ wfdielen++ ] = 0x6F;
2387 wfdie[ wfdielen++ ] = 0x9A;
2388 wfdie[ wfdielen++ ] = 0x0A; /* WFA WFD v1.0 */
2391 * Commented by Albert 20110825
2392 * According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes
2393 * 1. WFD Device Information
2394 * 2. Associated BSSID ( Optional )
2395 * 3. Local IP Adress ( Optional )
2398 /* WFD Device Information ATTR */
2400 wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
2403 /* Note: In the WFD specification, the size of length field is 2. */
2404 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
2408 /* WFD device information */
2409 /* available for WFD session + Preferred TDLS + WSD ( WFD Service Discovery ) */
2410 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL
2411 | WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_WSD);
2415 /* Session Management Control Port */
2416 /* Default TCP port for RTSP messages is 554 */
2417 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->tdls_rtsp_ctrlport);
2421 /* WFD Device Maximum Throughput */
2422 /* 300Mbps is the maximum throughput */
2423 RTW_PUT_BE16(wfdie + wfdielen, 300);
2426 /* Associated BSSID ATTR */
2428 wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
2431 /* Note: In the WFD specification, the size of length field is 2. */
2432 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
2436 /* Associated BSSID */
2437 if (check_fwstate( pmlmepriv, _FW_LINKED) == _TRUE)
2438 _rtw_memcpy(wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN);
2440 _rtw_memset(wfdie + wfdielen, 0x00, ETH_ALEN);
2442 /* Local IP Address ATTR */
2443 wfdie[ wfdielen++ ] = WFD_ATTR_LOCAL_IP_ADDR;
2446 /* Note: In the WFD specification, the size of length field is 2. */
2447 RTW_PUT_BE16(wfdie + wfdielen, 0x0005);
2451 /* 0x01: Version1;IPv4 */
2452 wfdie[ wfdielen++ ] = 0x01;
2455 _rtw_memcpy( wfdie + wfdielen, pwfd_info->ip_address, 4 );
2458 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, pktlen);
2461 #endif /* CONFIG_WFD */
2463 void rtw_build_tdls_setup_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt)
2465 struct registry_priv *pregistrypriv = &padapter->registrypriv;
2466 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2467 struct pkt_attrib *pattrib = &pxmitframe->attrib;
2468 struct sta_info *ptdls_sta=rtw_get_stainfo( (&padapter->stapriv) , pattrib->dst);
2475 if (pattrib->encrypt) {
2477 time=rtw_get_current_time();
2478 _rtw_memcpy(&ptdls_sta->SNonce[4*i], (u8 *)&time, 4);
2482 pframe_head = pframe; /* For rtw_tdls_set_ht_cap() */
2484 pframe = rtw_tdls_set_payload_type(pframe, pattrib);
2485 pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS);
2486 pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt);
2487 pframe = rtw_tdls_set_dialog(pframe, pattrib, ptxmgmt);
2489 pframe = rtw_tdls_set_capability(padapter, pframe, pattrib);
2490 pframe = rtw_tdls_set_supported_rate(padapter, pframe, pattrib);
2491 pframe = rtw_tdls_set_sup_ch(&(padapter->mlmeextpriv), pframe, pattrib);
2492 pframe = rtw_tdls_set_sup_reg_class(pframe, pattrib);
2494 if (pattrib->encrypt)
2495 pframe = rtw_tdls_set_rsnie(ptxmgmt, pframe, pattrib, _TRUE, ptdls_sta);
2497 pframe = rtw_tdls_set_ext_cap(pframe, pattrib);
2499 if (pattrib->encrypt) {
2500 pframe = rtw_tdls_set_ftie(ptxmgmt
2504 , ptdls_sta->SNonce);
2506 pframe = rtw_tdls_set_timeout_interval(ptxmgmt, pframe, pattrib, _TRUE, ptdls_sta);
2509 #ifdef CONFIG_80211N_HT
2510 /* Sup_reg_classes(optional) */
2511 if (pregistrypriv->ht_enable == _TRUE)
2512 pframe = rtw_tdls_set_ht_cap(padapter, pframe_head, pattrib);
2515 pframe = rtw_tdls_set_bss_coexist(padapter, pframe, pattrib);
2517 pframe = rtw_tdls_set_linkid(pframe, pattrib, _TRUE);
2519 if ((pregistrypriv->wmm_enable == _TRUE) || (padapter->mlmepriv.htpriv.ht_option == _TRUE))
2520 pframe = rtw_tdls_set_qos_cap(pframe, pattrib);
2524 if (padapter->wdinfo.wfd_tdls_enable == 1)
2525 wfd_ie_tdls(padapter, pframe, &(pattrib->pktlen));
2530 void rtw_build_tdls_setup_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt)
2532 struct registry_priv *pregistrypriv = &padapter->registrypriv;
2533 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2534 struct pkt_attrib *pattrib = &pxmitframe->attrib;
2535 struct sta_info *ptdls_sta;
2536 u8 k; /* for random ANonce */
2537 u8 *pftie=NULL, *ptimeout_ie = NULL, *plinkid_ie = NULL, *prsnie = NULL, *pftie_mic = NULL;
2541 ptdls_sta = rtw_get_stainfo( &(padapter->stapriv) , pattrib->dst);
2543 if (ptdls_sta == NULL)
2544 DBG_871X("[%s] %d ptdls_sta is NULL\n", __FUNCTION__, __LINE__);
2546 if (pattrib->encrypt && ptdls_sta != NULL) {
2548 time = rtw_get_current_time();
2549 _rtw_memcpy(&ptdls_sta->ANonce[4*k], (u8*)&time, 4);
2553 pframe_head = pframe;
2555 pframe = rtw_tdls_set_payload_type(pframe, pattrib);
2556 pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS);
2557 pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt);
2558 pframe = rtw_tdls_set_status_code(pframe, pattrib, ptxmgmt);
2560 if (ptxmgmt->status_code != 0) {
2561 DBG_871X("[%s] status_code:%04x \n", __FUNCTION__, ptxmgmt->status_code);
2565 pframe = rtw_tdls_set_dialog(pframe, pattrib, ptxmgmt);
2566 pframe = rtw_tdls_set_capability(padapter, pframe, pattrib);
2567 pframe = rtw_tdls_set_supported_rate(padapter, pframe, pattrib);
2568 pframe = rtw_tdls_set_sup_ch(&(padapter->mlmeextpriv), pframe, pattrib);
2569 pframe = rtw_tdls_set_sup_reg_class(pframe, pattrib);
2571 if (pattrib->encrypt) {
2573 pframe = rtw_tdls_set_rsnie(ptxmgmt, pframe, pattrib, _FALSE, ptdls_sta);
2576 pframe = rtw_tdls_set_ext_cap(pframe, pattrib);
2578 if (pattrib->encrypt) {
2579 if (rtw_tdls_is_driver_setup(padapter) == _TRUE)
2580 wpa_tdls_generate_tpk(padapter, ptdls_sta);
2583 pftie_mic = pframe+4;
2584 pframe = rtw_tdls_set_ftie(ptxmgmt
2588 , ptdls_sta->SNonce);
2590 ptimeout_ie = pframe;
2591 pframe = rtw_tdls_set_timeout_interval(ptxmgmt, pframe, pattrib, _FALSE, ptdls_sta);
2594 #ifdef CONFIG_80211N_HT
2595 /* Sup_reg_classes(optional) */
2596 if (pregistrypriv->ht_enable == _TRUE)
2597 pframe = rtw_tdls_set_ht_cap(padapter, pframe_head, pattrib);
2600 pframe = rtw_tdls_set_bss_coexist(padapter, pframe, pattrib);
2602 plinkid_ie = pframe;
2603 pframe = rtw_tdls_set_linkid(pframe, pattrib, _FALSE);
2606 if (pattrib->encrypt && rtw_tdls_is_driver_setup(padapter) == _TRUE)
2607 wpa_tdls_ftie_mic(ptdls_sta->tpk.kck, 2, plinkid_ie, prsnie, ptimeout_ie, pftie, pftie_mic);
2609 if ((pregistrypriv->wmm_enable == _TRUE) || (padapter->mlmepriv.htpriv.ht_option == _TRUE))
2610 pframe = rtw_tdls_set_qos_cap(pframe, pattrib);
2614 if (padapter->wdinfo.wfd_tdls_enable)
2615 wfd_ie_tdls(padapter, pframe, &(pattrib->pktlen));
2620 void rtw_build_tdls_setup_cfm_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt)
2622 struct registry_priv *pregistrypriv = &padapter->registrypriv;
2623 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2624 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2625 struct pkt_attrib *pattrib = &pxmitframe->attrib;
2626 struct sta_info *ptdls_sta=rtw_get_stainfo( (&padapter->stapriv) , pattrib->dst);
2628 unsigned int ie_len;
2630 u8 wmm_param_ele[24] = {0};
2631 u8 *pftie=NULL, *ptimeout_ie=NULL, *plinkid_ie=NULL, *prsnie=NULL, *pftie_mic=NULL;
2633 pframe = rtw_tdls_set_payload_type(pframe, pattrib);
2634 pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS);
2635 pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt);
2636 pframe = rtw_tdls_set_status_code(pframe, pattrib, ptxmgmt);
2637 pframe = rtw_tdls_set_dialog(pframe, pattrib, ptxmgmt);
2639 if (ptxmgmt->status_code!=0)
2642 if (pattrib->encrypt) {
2644 pframe = rtw_tdls_set_rsnie(ptxmgmt, pframe, pattrib, _TRUE, ptdls_sta);
2647 if (pattrib->encrypt) {
2649 pftie_mic = pframe+4;
2650 pframe = rtw_tdls_set_ftie(ptxmgmt
2654 , ptdls_sta->SNonce);
2656 ptimeout_ie = pframe;
2657 pframe = rtw_tdls_set_timeout_interval(ptxmgmt, pframe, pattrib, _TRUE, ptdls_sta);
2659 if (rtw_tdls_is_driver_setup(padapter) == _TRUE) {
2660 /* Start TPK timer */
2661 ptdls_sta->TPK_count=0;
2662 _set_timer(&ptdls_sta->TPK_timer, ONE_SEC);
2666 /* HT operation; todo */
2668 plinkid_ie = pframe;
2669 pframe = rtw_tdls_set_linkid(pframe, pattrib, _TRUE);
2671 if (pattrib->encrypt && (rtw_tdls_is_driver_setup(padapter) == _TRUE))
2672 wpa_tdls_ftie_mic(ptdls_sta->tpk.kck, 3, plinkid_ie, prsnie, ptimeout_ie, pftie, pftie_mic);
2674 if (ptdls_sta->qos_option == _TRUE)
2675 pframe = rtw_tdls_set_wmm_params(padapter, pframe, pattrib);
2679 void rtw_build_tdls_teardown_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt)
2681 struct pkt_attrib *pattrib = &pxmitframe->attrib;
2682 struct sta_info *ptdls_sta = rtw_get_stainfo( &(padapter->stapriv) , pattrib->dst);
2683 u8 *pftie = NULL, *pftie_mic = NULL, *plinkid_ie = NULL;
2685 pframe = rtw_tdls_set_payload_type(pframe, pattrib);
2686 pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS);
2687 pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt);
2688 pframe = rtw_tdls_set_status_code(pframe, pattrib, ptxmgmt);
2690 if (pattrib->encrypt) {
2692 pftie_mic = pframe + 4;
2693 pframe = rtw_tdls_set_ftie(ptxmgmt
2697 , ptdls_sta->SNonce);
2700 plinkid_ie = pframe;
2701 if (ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE)
2702 pframe = rtw_tdls_set_linkid(pframe, pattrib, _FALSE);
2703 else if (ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE)
2704 pframe = rtw_tdls_set_linkid(pframe, pattrib, _TRUE);
2706 if (pattrib->encrypt && (rtw_tdls_is_driver_setup(padapter) == _TRUE))
2707 wpa_tdls_teardown_ftie_mic(ptdls_sta->tpk.kck, plinkid_ie, ptxmgmt->status_code, 1, 4, pftie, pftie_mic);
2710 void rtw_build_tdls_dis_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt)
2712 struct pkt_attrib *pattrib = &pxmitframe->attrib;
2714 pframe = rtw_tdls_set_payload_type(pframe, pattrib);
2715 pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS);
2716 pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt);
2717 pframe = rtw_tdls_set_dialog(pframe, pattrib, ptxmgmt);
2718 pframe = rtw_tdls_set_linkid(pframe, pattrib, _TRUE);
2722 void rtw_build_tdls_dis_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt, u8 privacy)
2724 struct registry_priv *pregistrypriv = &padapter->registrypriv;
2725 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2726 struct pkt_attrib *pattrib = &pxmitframe->attrib;
2727 u8 *pframe_head, pktlen_index;
2729 pktlen_index = pattrib->pktlen;
2730 pframe_head = pframe;
2732 pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_PUBLIC);
2733 pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt);
2734 pframe = rtw_tdls_set_dialog(pframe, pattrib, ptxmgmt);
2735 pframe = rtw_tdls_set_capability(padapter, pframe, pattrib);
2737 pframe = rtw_tdls_set_supported_rate(padapter, pframe, pattrib);
2739 pframe = rtw_tdls_set_sup_ch(pmlmeext, pframe, pattrib);
2742 pframe = rtw_tdls_set_rsnie(ptxmgmt, pframe, pattrib, _TRUE, NULL);
2744 pframe = rtw_tdls_set_ext_cap(pframe, pattrib);
2747 pframe = rtw_tdls_set_ftie(ptxmgmt, pframe, pattrib, NULL, NULL);
2748 pframe = rtw_tdls_set_timeout_interval(ptxmgmt, pframe, pattrib, _TRUE, NULL);
2751 #ifdef CONFIG_80211N_HT
2752 if (pregistrypriv->ht_enable == _TRUE)
2753 pframe = rtw_tdls_set_ht_cap(padapter, pframe_head - pktlen_index, pattrib);
2756 pframe = rtw_tdls_set_bss_coexist(padapter, pframe, pattrib);
2757 pframe = rtw_tdls_set_linkid(pframe, pattrib, _FALSE);
2762 void rtw_build_tdls_peer_traffic_indication_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt)
2765 struct pkt_attrib *pattrib = &pxmitframe->attrib;
2767 struct sta_info *ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->dst);
2769 pframe = rtw_tdls_set_payload_type(pframe, pattrib);
2770 pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS);
2771 pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt);
2772 pframe = rtw_tdls_set_dialog(pframe, pattrib, ptxmgmt);
2774 if (ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE)
2775 pframe = rtw_tdls_set_linkid(pframe, pattrib, _FALSE);
2776 else if (ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE)
2777 pframe = rtw_tdls_set_linkid(pframe, pattrib, _TRUE);
2780 /* PU buffer status */
2781 if (ptdls_sta->uapsd_bk & BIT(1))
2783 if (ptdls_sta->uapsd_be & BIT(1))
2785 if (ptdls_sta->uapsd_vi & BIT(1))
2787 if (ptdls_sta->uapsd_vo & BIT(1))
2789 pframe = rtw_set_ie(pframe, _PTI_BUFFER_STATUS_, 1, &AC_queue, &(pattrib->pktlen));
2793 void rtw_build_tdls_peer_traffic_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt)
2796 struct pkt_attrib *pattrib = &pxmitframe->attrib;
2797 struct sta_info *ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->dst);
2799 pframe = rtw_tdls_set_payload_type(pframe, pattrib);
2800 pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS);
2801 pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt);
2802 pframe = rtw_tdls_set_dialog(pframe, pattrib, ptxmgmt);
2804 if (ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE)
2805 pframe = rtw_tdls_set_linkid(pframe, pattrib, _FALSE);
2806 else if (ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE)
2807 pframe = rtw_tdls_set_linkid(pframe, pattrib, _TRUE);
2810 #ifdef CONFIG_TDLS_CH_SW
2811 void rtw_build_tdls_ch_switch_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt)
2813 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
2814 struct pkt_attrib *pattrib = &pxmitframe->attrib;
2815 struct sta_priv *pstapriv = &padapter->stapriv;
2816 struct sta_info *ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst);
2817 u16 switch_time = TDLS_CH_SWITCH_TIME * 1000, switch_timeout = TDLS_CH_SWITCH_TIMEOUT * 1000;
2819 ptdls_sta->ch_switch_time=switch_time;
2820 ptdls_sta->ch_switch_timeout=switch_timeout;
2822 pframe = rtw_tdls_set_payload_type(pframe, pattrib);
2823 pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS);
2824 pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt);
2825 pframe = rtw_tdls_set_target_ch(padapter, pframe, pattrib);
2826 pframe = rtw_tdls_set_reg_class(pframe, pattrib, ptdls_sta);
2828 if (ptdlsinfo->chsw_info.ch_offset != HAL_PRIME_CHNL_OFFSET_DONT_CARE) {
2829 switch (ptdlsinfo->chsw_info.ch_offset) {
2830 case HAL_PRIME_CHNL_OFFSET_LOWER:
2831 pframe = rtw_tdls_set_second_channel_offset(pframe, pattrib, SCA);
2833 case HAL_PRIME_CHNL_OFFSET_UPPER:
2834 pframe = rtw_tdls_set_second_channel_offset(pframe, pattrib, SCB);
2839 if (ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE)
2840 pframe = rtw_tdls_set_linkid(pframe, pattrib, _FALSE);
2841 else if (ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE)
2842 pframe = rtw_tdls_set_linkid(pframe, pattrib, _TRUE);
2844 pframe = rtw_tdls_set_ch_sw(pframe, pattrib, ptdls_sta);
2848 void rtw_build_tdls_ch_switch_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt)
2851 struct pkt_attrib *pattrib = &pxmitframe->attrib;
2852 struct sta_priv *pstapriv = &padapter->stapriv;
2853 struct sta_info *ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst);
2855 pframe = rtw_tdls_set_payload_type(pframe, pattrib);
2856 pframe = rtw_tdls_set_category(pframe, pattrib, RTW_WLAN_CATEGORY_TDLS);
2857 pframe = rtw_tdls_set_action(pframe, pattrib, ptxmgmt);
2858 pframe = rtw_tdls_set_status_code(pframe, pattrib, ptxmgmt);
2860 if (ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE)
2861 pframe = rtw_tdls_set_linkid(pframe, pattrib, _FALSE);
2862 else if (ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE)
2863 pframe = rtw_tdls_set_linkid(pframe, pattrib, _TRUE);
2865 pframe = rtw_tdls_set_ch_sw(pframe, pattrib, ptdls_sta);
2870 void rtw_build_tunneled_probe_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
2873 struct pkt_attrib *pattrib = &pxmitframe->attrib;
2874 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2875 struct wifidirect_info *pbuddy_wdinfo = &padapter->pbuddy_adapter->wdinfo;
2876 u8 category = RTW_WLAN_CATEGORY_P2P;
2877 u8 WFA_OUI[3] = { 0x50, 0x6f, 0x9a};
2881 pframe = rtw_tdls_set_payload_type(pframe, pattrib);
2882 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
2883 pframe = rtw_set_fixed_ie(pframe, 3, WFA_OUI, &(pattrib->pktlen));
2884 pframe = rtw_set_fixed_ie(pframe, 1, &(probe_req), &(pattrib->pktlen));
2886 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
2887 wfdielen = build_probe_req_wfd_ie(pwdinfo, pframe);
2889 pattrib->pktlen += wfdielen;
2890 } else if (!rtw_p2p_chk_state(pbuddy_wdinfo, P2P_STATE_NONE)) {
2891 wfdielen = build_probe_req_wfd_ie(pbuddy_wdinfo, pframe);
2893 pattrib->pktlen += wfdielen;
2898 void rtw_build_tunneled_probe_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
2901 struct pkt_attrib *pattrib = &pxmitframe->attrib;
2902 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2903 struct wifidirect_info *pbuddy_wdinfo = &padapter->pbuddy_adapter->wdinfo;
2904 u8 category = RTW_WLAN_CATEGORY_P2P;
2905 u8 WFA_OUI[3] = { 0x50, 0x6f, 0x9a};
2909 pframe = rtw_tdls_set_payload_type(pframe, pattrib);
2910 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
2911 pframe = rtw_set_fixed_ie(pframe, 3, WFA_OUI, &(pattrib->pktlen));
2912 pframe = rtw_set_fixed_ie(pframe, 1, &(probe_rsp), &(pattrib->pktlen));
2914 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
2915 wfdielen = build_probe_resp_wfd_ie(pwdinfo, pframe, 1);
2917 pattrib->pktlen += wfdielen;
2918 } else if (!rtw_p2p_chk_state(pbuddy_wdinfo, P2P_STATE_NONE)) {
2919 wfdielen = build_probe_resp_wfd_ie(pbuddy_wdinfo, pframe, 1);
2921 pattrib->pktlen += wfdielen;
2925 #endif /* CONFIG_WFD */
2927 void _tdls_tpk_timer_hdl(void *FunctionContext)
2929 struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
2930 struct tdls_txmgmt txmgmt;
2932 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
2933 ptdls_sta->TPK_count++;
2934 /* TPK_timer expired in a second */
2935 /* Retry timer should set at least 301 sec. */
2936 if (ptdls_sta->TPK_count >= (ptdls_sta->TDLS_PeerKey_Lifetime - 3)) {
2937 DBG_871X("[TDLS] %s, Re-Setup TDLS link with "MAC_FMT" since TPK lifetime expires!\n", __FUNCTION__, MAC_ARG(ptdls_sta->hwaddr));
2938 ptdls_sta->TPK_count=0;
2939 _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN);
2940 issue_tdls_setup_req(ptdls_sta->padapter, &txmgmt, _FALSE);
2943 _set_timer(&ptdls_sta->TPK_timer, ONE_SEC);
2946 #ifdef CONFIG_TDLS_CH_SW
2947 void _tdls_ch_switch_timer_hdl(void *FunctionContext)
2949 struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
2950 _adapter *padapter = ptdls_sta->padapter;
2951 struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
2953 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_END_TO_BASE_CHNL);
2954 DBG_871X("[TDLS] %s, can't get traffic from op_ch:%d\n", __func__, rtw_get_oper_ch(padapter));
2957 void _tdls_delay_timer_hdl(void *FunctionContext)
2959 struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
2960 _adapter *padapter = ptdls_sta->padapter;
2961 struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
2963 DBG_871X("[TDLS] %s, op_ch:%d, tdls_state:0x%08x\n", __func__, rtw_get_oper_ch(padapter), ptdls_sta->tdls_sta_state);
2964 pchsw_info->delay_switch_back = _TRUE;
2967 void _tdls_stay_on_base_chnl_timer_hdl(void *FunctionContext)
2969 struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
2970 _adapter *padapter = ptdls_sta->padapter;
2971 struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
2973 if (ptdls_sta != NULL) {
2974 issue_tdls_ch_switch_req(padapter, ptdls_sta);
2975 pchsw_info->ch_sw_state |= TDLS_WAIT_CH_RSP_STATE;
2979 void _tdls_ch_switch_monitor_timer_hdl(void *FunctionContext)
2981 struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
2982 _adapter *padapter = ptdls_sta->padapter;
2983 struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
2985 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_END);
2986 DBG_871X("[TDLS] %s, does not receive ch sw req\n", __func__);
2991 void _tdls_handshake_timer_hdl(void *FunctionContext)
2993 struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
2994 _adapter *padapter = ptdls_sta->padapter;
2995 struct tdls_txmgmt txmgmt;
2997 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
2998 _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN);
2999 txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
3001 if (ptdls_sta != NULL) {
3002 DBG_871X("[TDLS] Handshake time out\n");
3003 if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE)
3005 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_TEARDOWN_STA);
3009 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_TEARDOWN_STA_LOCALLY);
3014 void _tdls_pti_timer_hdl(void *FunctionContext)
3016 struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
3017 _adapter *padapter = ptdls_sta->padapter;
3018 struct tdls_txmgmt txmgmt;
3020 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
3021 _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN);
3022 txmgmt.status_code = _RSON_TDLS_TEAR_TOOFAR_;
3024 if (ptdls_sta != NULL) {
3025 if (ptdls_sta->tdls_sta_state & TDLS_WAIT_PTR_STATE) {
3026 DBG_871X("[TDLS] Doesn't receive PTR from peer dev:"MAC_FMT"; "
3027 "Send TDLS Tear Down\n", MAC_ARG(ptdls_sta->hwaddr));
3028 issue_tdls_teardown(padapter, &txmgmt, _FALSE);
3033 void rtw_init_tdls_timer(_adapter *padapter, struct sta_info *psta)
3035 psta->padapter=padapter;
3036 _init_timer(&psta->TPK_timer, padapter->pnetdev, _tdls_tpk_timer_hdl, psta);
3037 #ifdef CONFIG_TDLS_CH_SW
3038 _init_timer(&psta->ch_sw_timer, padapter->pnetdev, _tdls_ch_switch_timer_hdl, psta);
3039 _init_timer(&psta->delay_timer, padapter->pnetdev, _tdls_delay_timer_hdl, psta);
3040 _init_timer(&psta->stay_on_base_chnl_timer, padapter->pnetdev, _tdls_stay_on_base_chnl_timer_hdl, psta);
3041 _init_timer(&psta->ch_sw_monitor_timer, padapter->pnetdev, _tdls_ch_switch_monitor_timer_hdl, psta);
3043 _init_timer(&psta->handshake_timer, padapter->pnetdev, _tdls_handshake_timer_hdl, psta);
3044 _init_timer(&psta->pti_timer, padapter->pnetdev, _tdls_pti_timer_hdl, psta);
3047 void rtw_free_tdls_timer(struct sta_info *psta)
3049 _cancel_timer_ex(&psta->TPK_timer);
3050 #ifdef CONFIG_TDLS_CH_SW
3051 _cancel_timer_ex(&psta->ch_sw_timer);
3052 _cancel_timer_ex(&psta->delay_timer);
3053 _cancel_timer_ex(&psta->stay_on_base_chnl_timer);
3054 _cancel_timer_ex(&psta->ch_sw_monitor_timer);
3056 _cancel_timer_ex(&psta->handshake_timer);
3057 _cancel_timer_ex(&psta->pti_timer);
3060 u8 update_sgi_tdls(_adapter *padapter, struct sta_info *psta)
3062 return query_ra_short_GI(psta);
3065 u32 update_mask_tdls(_adapter *padapter, struct sta_info *psta)
3067 unsigned char sta_band = 0;
3068 unsigned int tx_ra_bitmap=0;
3069 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3070 WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
3072 rtw_hal_update_sta_rate_mask(padapter, psta);
3073 tx_ra_bitmap = psta->ra_mask;
3075 if (pcur_network->Configuration.DSConfig > 14) {
3076 if (tx_ra_bitmap & 0xffff000)
3077 sta_band |= WIRELESS_11_5N | WIRELESS_11A;
3079 sta_band |= WIRELESS_11A;
3081 if (tx_ra_bitmap & 0xffff000)
3082 sta_band |= WIRELESS_11_24N | WIRELESS_11G | WIRELESS_11B;
3083 else if (tx_ra_bitmap & 0xff0)
3084 sta_band |= WIRELESS_11G |WIRELESS_11B;
3086 sta_band |= WIRELESS_11B;
3089 psta->wireless_mode = sta_band;
3091 psta->raid = rtw_hal_networktype_to_raid(padapter,psta);
3092 tx_ra_bitmap |= ((psta->raid<<28)&0xf0000000);
3093 return tx_ra_bitmap;
3096 int rtw_tdls_is_driver_setup(_adapter *padapter)
3098 return padapter->tdlsinfo.driver_setup;
3101 const char * rtw_tdls_action_txt(enum TDLS_ACTION_FIELD action)
3104 case TDLS_SETUP_REQUEST:
3105 return "TDLS_SETUP_REQUEST";
3106 case TDLS_SETUP_RESPONSE:
3107 return "TDLS_SETUP_RESPONSE";
3108 case TDLS_SETUP_CONFIRM:
3109 return "TDLS_SETUP_CONFIRM";
3111 return "TDLS_TEARDOWN";
3112 case TDLS_PEER_TRAFFIC_INDICATION:
3113 return "TDLS_PEER_TRAFFIC_INDICATION";
3114 case TDLS_CHANNEL_SWITCH_REQUEST:
3115 return "TDLS_CHANNEL_SWITCH_REQUEST";
3116 case TDLS_CHANNEL_SWITCH_RESPONSE:
3117 return "TDLS_CHANNEL_SWITCH_RESPONSE";
3118 case TDLS_PEER_PSM_REQUEST:
3119 return "TDLS_PEER_PSM_REQUEST";
3120 case TDLS_PEER_PSM_RESPONSE:
3121 return "TDLS_PEER_PSM_RESPONSE";
3122 case TDLS_PEER_TRAFFIC_RESPONSE:
3123 return "TDLS_PEER_TRAFFIC_RESPONSE";
3124 case TDLS_DISCOVERY_REQUEST:
3125 return "TDLS_DISCOVERY_REQUEST";
3126 case TDLS_DISCOVERY_RESPONSE:
3127 return "TDLS_DISCOVERY_RESPONSE";
3133 #endif /* CONFIG_TDLS */