1 /******************************************************************************
\r
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
\r
5 * This program is free software; you can redistribute it and/or modify it
\r
6 * under the terms of version 2 of the GNU General Public License as
\r
7 * published by the Free Software Foundation.
\r
9 * This program is distributed in the hope that it will be useful, but WITHOUT
\r
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
\r
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
\r
14 * You should have received a copy of the GNU General Public License along with
\r
15 * this program; if not, write to the Free Software Foundation, Inc.,
\r
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
\r
19 ******************************************************************************/
\r
20 #define _RTW_TDLS_C_
\r
22 #include <drv_types.h>
\r
25 extern unsigned char MCS_rate_2R[16];
\r
26 extern unsigned char MCS_rate_1R[16];
\r
27 extern void process_wmmps_data(_adapter *padapter, union recv_frame *precv_frame);
\r
29 void rtw_reset_tdls_info(_adapter* padapter)
\r
31 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
\r
33 ptdlsinfo->ap_prohibited = _FALSE;
\r
34 ptdlsinfo->link_established = _FALSE;
\r
35 ptdlsinfo->sta_cnt = 0;
\r
36 ptdlsinfo->sta_maximum = _FALSE;
\r
37 ptdlsinfo->ch_sensing = 0;
\r
38 ptdlsinfo->cur_channel = 0;
\r
39 ptdlsinfo->candidate_ch = 1; //when inplement channel switching, default candidate channel is 1
\r
40 ptdlsinfo->watchdog_count = 0;
\r
41 ptdlsinfo->dev_discovered = 0;
\r
44 ptdlsinfo->wfd_info = &padapter->wfd_info;
\r
48 int rtw_init_tdls_info(_adapter* padapter)
\r
51 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
\r
53 ptdlsinfo->tdls_enable = _TRUE;
\r
54 rtw_reset_tdls_info(padapter);
\r
56 _rtw_spinlock_init(&ptdlsinfo->cmd_lock);
\r
57 _rtw_spinlock_init(&ptdlsinfo->hdl_lock);
\r
63 void rtw_free_tdls_info(struct tdls_info *ptdlsinfo)
\r
65 _rtw_spinlock_free(&ptdlsinfo->cmd_lock);
\r
66 _rtw_spinlock_free(&ptdlsinfo->hdl_lock);
\r
68 _rtw_memset(ptdlsinfo, 0, sizeof(struct tdls_info) );
\r
72 int _issue_nulldata_to_TDLS_peer_STA(_adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack)
\r
75 struct xmit_frame *pmgntframe;
\r
76 struct pkt_attrib *pattrib;
\r
77 unsigned char *pframe;
\r
78 struct rtw_ieee80211_hdr *pwlanhdr;
\r
79 unsigned short *fctrl;
\r
80 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
81 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
82 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
84 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
90 pattrib = &pmgntframe->attrib;
\r
91 update_mgntframe_attrib(padapter, pattrib);
\r
92 pattrib->retry_ctrl = _FALSE;
\r
94 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
96 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
97 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
99 fctrl = &(pwlanhdr->frame_ctl);
\r
109 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
\r
110 _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
111 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
\r
113 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
\r
114 pmlmeext->mgnt_seq++;
\r
115 SetFrameSubType(pframe, WIFI_DATA_NULL);
\r
117 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
\r
118 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
\r
120 pattrib->last_txcmdsz = pattrib->pktlen;
\r
124 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
\r
128 dump_mgntframe(padapter, pmgntframe);
\r
137 int issue_nulldata_to_TDLS_peer_STA(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
\r
141 u32 start = rtw_get_current_time();
\r
142 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
143 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
145 //[TDLS] UAPSD : merge this from issue_nulldata() and mark it first.
\r
147 psta = rtw_get_stainfo(&padapter->stapriv, da);
\r
150 rtw_hal_macid_sleep(padapter, psta->mac_id);
\r
152 rtw_hal_macid_wakeup(padapter, psta->mac_id);
\r
154 DBG_871X(FUNC_ADPT_FMT ": Can't find sta info for " MAC_FMT ", skip macid %s!!\n",
\r
155 FUNC_ADPT_ARG(padapter), MAC_ARG(da), power_mode?"sleep":"wakeup");
\r
162 ret = _issue_nulldata_to_TDLS_peer_STA(padapter, da, power_mode, wait_ms>0 ? _TRUE : _FALSE);
\r
166 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
\r
169 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
\r
170 rtw_msleep_os(wait_ms);
\r
172 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
\r
174 if (ret != _FAIL) {
\r
176 #ifndef DBG_XMIT_ACK
\r
181 if (try_cnt && wait_ms) {
\r
183 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
\r
184 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
\r
185 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
\r
187 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
\r
188 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
\r
189 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
\r
195 void free_tdls_sta(_adapter *padapter, struct sta_info *ptdls_sta)
\r
197 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
\r
198 struct sta_priv *pstapriv = &padapter->stapriv;
\r
201 //free peer sta_info
\r
202 _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
\r
203 if(ptdlsinfo->sta_cnt != 0)
\r
204 ptdlsinfo->sta_cnt--;
\r
205 _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
\r
206 if( ptdlsinfo->sta_cnt < (NUM_STA - 2 - 4) ) // -2: AP + BC/MC sta, -4: default key
\r
208 ptdlsinfo->sta_maximum = _FALSE;
\r
209 _rtw_memset( &ptdlsinfo->ss_record, 0x00, sizeof(struct tdls_ss_record) );
\r
213 rtw_clearstakey_cmd(padapter, ptdls_sta, _TRUE);
\r
215 if(ptdlsinfo->sta_cnt==0){
\r
216 rtw_tdls_cmd(padapter, myid(&(padapter->eeprompriv)), TDLS_RS_RCR);
\r
217 ptdlsinfo->link_established = _FALSE;
\r
220 DBG_871X("Remain tdls sta:%02x\n", ptdlsinfo->sta_cnt);
\r
222 rtw_free_stainfo(padapter, ptdls_sta);
\r
227 //TDLS encryption(if needed) will always be CCMP
\r
228 void rtw_tdls_set_key(_adapter *padapter, struct rx_pkt_attrib *prx_pkt_attrib, struct sta_info *ptdls_sta)
\r
230 if(prx_pkt_attrib->encrypt)
\r
232 ptdls_sta->dot118021XPrivacy=_AES_;
\r
233 rtw_setstakey_cmd(padapter, ptdls_sta, _TRUE, _TRUE);
\r
237 void rtw_tdls_process_ht_cap(_adapter *padapter, struct sta_info *ptdls_sta, u8 *data, u8 Length)
\r
239 /* save HT capabilities in the sta object */
\r
240 _rtw_memset(&ptdls_sta->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap));
\r
241 if (data && Length >= sizeof(struct rtw_ieee80211_ht_cap) )
\r
243 ptdls_sta->flags |= WLAN_STA_HT;
\r
245 ptdls_sta->flags |= WLAN_STA_WME;
\r
247 _rtw_memcpy(&ptdls_sta->htpriv.ht_cap, data, sizeof(struct rtw_ieee80211_ht_cap));
\r
250 ptdls_sta->flags &= ~WLAN_STA_HT;
\r
252 if(ptdls_sta->flags & WLAN_STA_HT)
\r
254 if(padapter->registrypriv.ht_enable == _TRUE)
\r
256 ptdls_sta->htpriv.ht_option = _TRUE;
\r
260 ptdls_sta->htpriv.ht_option = _FALSE;
\r
261 ptdls_sta->stat_code = _STATS_FAILURE_;
\r
266 if(ptdls_sta->htpriv.ht_option)
\r
268 //check if sta supports rx ampdu
\r
269 if(padapter->registrypriv.ampdu_enable==1)
\r
270 ptdls_sta->htpriv.ampdu_enable = _TRUE;
\r
272 //check if sta support s Short GI 20M
\r
273 if(ptdls_sta->htpriv.ht_cap.cap_info & cpu_to_le16(IEEE80211_HT_CAP_SGI_20))
\r
275 ptdls_sta->htpriv.sgi_20m = _TRUE;
\r
277 //check if sta support s Short GI 40M
\r
278 if(ptdls_sta->htpriv.ht_cap.cap_info & cpu_to_le16(IEEE80211_HT_CAP_SGI_40))
\r
280 ptdls_sta->htpriv.sgi_40m = _TRUE;
\r
283 // bwmode would still followed AP's setting
\r
284 if(ptdls_sta->htpriv.ht_cap.cap_info & cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH))
\r
286 if (padapter->mlmeextpriv.cur_bwmode >= CHANNEL_WIDTH_40)
\r
287 ptdls_sta->bw_mode = CHANNEL_WIDTH_40;
\r
288 ptdls_sta->htpriv.ch_offset = padapter->mlmeextpriv.cur_ch_offset;
\r
294 int rtw_tdls_set_ht_cap(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib)
\r
298 rtw_ht_use_default_setting(padapter);
\r
300 tmplen = pattrib->pktlen;
\r
301 rtw_restructure_ht_ie(padapter, NULL, pframe, 0, &(pattrib->pktlen), padapter->mlmeextpriv.cur_channel);
\r
303 return (pattrib->pktlen - tmplen);
\r
307 u8 *rtw_tdls_set_sup_ch(struct mlme_ext_priv *pmlmeext, u8 *pframe, struct pkt_attrib *pattrib)
\r
309 u8 sup_ch[ 30 * 2 ] = { 0x00 }, ch_set_idx = 0; //For supported channel
\r
310 u8 ch_24g = 0, b1 = 0, b4 = 0;
\r
311 u8 bit_table = 0, sup_ch_idx = 0;
\r
314 if( pmlmeext->channel_set[ch_set_idx].ChannelNum >= 1 &&
\r
315 pmlmeext->channel_set[ch_set_idx].ChannelNum <= 14 )
\r
317 ch_24g = 1; // 2.4 G channels
\r
319 else if( pmlmeext->channel_set[ch_set_idx].ChannelNum >= 36 &&
\r
320 pmlmeext->channel_set[ch_set_idx].ChannelNum <= 48)
\r
322 b1 = 1; // 5 G band1
\r
324 else if( pmlmeext->channel_set[ch_set_idx].ChannelNum >= 149 &&
\r
325 pmlmeext->channel_set[ch_set_idx].ChannelNum <= 165)
\r
327 b4 = 1; // 5 G band4
\r
331 ch_set_idx++; // We don't claim that we support DFS channels.
\r
335 sup_ch_idx = (ch_24g + b1 + b4 - 1) * 2;
\r
336 if( sup_ch_idx >= 0)
\r
338 if(sup_ch[sup_ch_idx] == 0)
\r
339 sup_ch[sup_ch_idx] = pmlmeext->channel_set[ch_set_idx].ChannelNum;
\r
340 sup_ch[sup_ch_idx+1]++; //Number of channel
\r
345 while( pmlmeext->channel_set[ch_set_idx].ChannelNum != 0 && ch_set_idx < MAX_CHANNEL_NUM );
\r
347 return(rtw_set_ie(pframe, _SUPPORTED_CH_IE_, sup_ch_idx+2, sup_ch, &(pattrib->pktlen)));
\r
351 void rtw_tdls_process_wfd_ie(struct tdls_info *ptdlsinfo, u8 *ptr, u8 length)
\r
353 u8 wfd_ie[ 128 ] = { 0x00 };
\r
355 u32 wfd_offset = 0;
\r
356 // Try to get the TCP port information when receiving the negotiation response.
\r
360 wfd_offset = rtw_get_wfd_ie( ptr + wfd_offset, length - wfd_offset, wfd_ie, &wfd_ielen );
\r
361 while( wfd_offset )
\r
363 u8 attr_content[ 10 ] = { 0x00 };
\r
364 u32 attr_contentlen = 0;
\r
367 DBG_871X( "[%s] WFD IE Found!!\n", __FUNCTION__ );
\r
368 rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen);
\r
369 if ( attr_contentlen )
\r
371 ptdlsinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16( attr_content + 2 );
\r
372 DBG_871X( "[%s] Peer PORT NUM = %d\n", __FUNCTION__, ptdlsinfo->wfd_info->peer_rtsp_ctrlport );
\r
375 _rtw_memset( attr_content, 0x00, 10);
\r
376 attr_contentlen = 0;
\r
377 rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_LOCAL_IP_ADDR, attr_content, &attr_contentlen);
\r
378 if ( attr_contentlen )
\r
380 _rtw_memcpy(ptdlsinfo->wfd_info->peer_ip_address, ( attr_content + 1 ), 4);
\r
381 DBG_871X( "[%s] Peer IP = %02u.%02u.%02u.%02u \n", __FUNCTION__,
\r
382 ptdlsinfo->wfd_info->peer_ip_address[0], ptdlsinfo->wfd_info->peer_ip_address[1],
\r
383 ptdlsinfo->wfd_info->peer_ip_address[2], ptdlsinfo->wfd_info->peer_ip_address[3]
\r
386 wfd_offset = rtw_get_wfd_ie( ptr + wfd_offset, length - wfd_offset, wfd_ie, &wfd_ielen );
\r
390 int issue_tunneled_probe_req(_adapter *padapter)
\r
392 struct xmit_frame *pmgntframe;
\r
393 struct pkt_attrib *pattrib;
\r
394 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
395 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
396 u8 baddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
\r
397 struct tdls_txmgmt txmgmt;
\r
400 DBG_871X("[%s]\n", __FUNCTION__);
\r
402 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
403 txmgmt.action_code = TUNNELED_PROBE_REQ;
\r
405 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
411 pattrib = &pmgntframe->attrib;
\r
413 pmgntframe->frame_tag = DATA_FRAMETAG;
\r
414 pattrib->ether_type = 0x890d;
\r
416 _rtw_memcpy(pattrib->dst, baddr, ETH_ALEN);
\r
417 _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
418 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
\r
419 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
\r
421 update_tdls_attrib(padapter, pattrib);
\r
422 pattrib->qsel = pattrib->priority;
\r
423 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, &txmgmt) != _SUCCESS) {
\r
424 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
\r
425 rtw_free_xmitframe(pxmitpriv, pmgntframe);
\r
428 dump_mgntframe(padapter, pmgntframe);
\r
435 int issue_tunneled_probe_rsp(_adapter *padapter, union recv_frame *precv_frame)
\r
437 struct xmit_frame *pmgntframe;
\r
438 struct pkt_attrib *pattrib;
\r
439 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
440 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
441 struct tdls_txmgmt txmgmt;
\r
444 DBG_871X("[%s]\n", __FUNCTION__);
\r
446 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
447 txmgmt.action_code = TUNNELED_PROBE_RSP;
\r
449 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
455 pattrib = &pmgntframe->attrib;
\r
457 pmgntframe->frame_tag = DATA_FRAMETAG;
\r
458 pattrib->ether_type = 0x890d;
\r
460 _rtw_memcpy(pattrib->dst, precv_frame->u.hdr.attrib.src, ETH_ALEN);
\r
461 _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
462 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
\r
463 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
\r
465 update_tdls_attrib(padapter, pattrib);
\r
466 pattrib->qsel = pattrib->priority;
\r
467 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, &txmgmt) != _SUCCESS) {
\r
468 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
\r
469 rtw_free_xmitframe(pxmitpriv, pmgntframe);
\r
472 dump_mgntframe(padapter, pmgntframe);
\r
478 #endif //CONFIG_WFD
\r
480 int issue_tdls_setup_req(_adapter *padapter, struct tdls_txmgmt *ptxmgmt, int wait_ack)
\r
482 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
\r
483 struct xmit_frame *pmgntframe;
\r
484 struct pkt_attrib *pattrib;
\r
485 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
486 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
487 struct sta_priv *pstapriv = &padapter->stapriv;
\r
488 struct sta_info *ptdls_sta= NULL;
\r
490 static u8 dialogtoken = 0;
\r
492 u32 timeout_interval= TPK_RESEND_COUNT * 1000; //retry timer should set at least 301 sec, using TPK_count counting 301 times.
\r
494 ptxmgmt->action_code = TDLS_SETUP_REQUEST;
\r
495 if(ptdlsinfo->ap_prohibited == _TRUE)
\r
498 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
504 pattrib = &pmgntframe->attrib;
\r
505 pmgntframe->frame_tag = DATA_FRAMETAG;
\r
506 pattrib->ether_type = 0x890d;
\r
508 _rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN);
\r
509 _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
510 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
\r
511 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
\r
513 update_tdls_attrib(padapter, pattrib);
\r
515 //init peer sta_info
\r
516 ptdls_sta = rtw_get_stainfo(pstapriv, ptxmgmt->peer);
\r
517 if(ptdls_sta==NULL)
\r
519 ptdls_sta = rtw_alloc_stainfo(pstapriv, ptxmgmt->peer);
\r
520 if(ptdls_sta==NULL)
\r
522 DBG_871X("[%s] rtw_alloc_stainfo fail\n", __FUNCTION__);
\r
523 rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf);
\r
524 rtw_free_xmitframe(pxmitpriv, pmgntframe);
\r
529 if(!(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE))
\r
530 ptdlsinfo->sta_cnt++;
\r
531 if( ptdlsinfo->sta_cnt == (NUM_STA - 2 - 4) ) // -2: AP + BC/MC sta, -4: default key
\r
533 ptdlsinfo->sta_maximum = _TRUE;
\r
536 ptdls_sta->tdls_sta_state |= TDLS_RESPONDER_STATE;
\r
537 //for tdls; ptdls_sta->aid is used to fill dialogtoken
\r
538 ptdls_sta->dialog = dialogtoken;
\r
539 dialogtoken = (dialogtoken+1)%256;
\r
540 ptdls_sta->TDLS_PeerKey_Lifetime = timeout_interval;
\r
541 _set_timer( &ptdls_sta->handshake_timer, TDLS_HANDSHAKE_TIME );
\r
543 pattrib->qsel = pattrib->priority;
\r
545 if(rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) !=_SUCCESS ){
\r
546 rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf);
\r
547 rtw_free_xmitframe(pxmitpriv, pmgntframe);
\r
552 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
\r
554 dump_mgntframe(padapter, pmgntframe);
\r
565 int issue_tdls_teardown(_adapter *padapter, struct tdls_txmgmt *ptxmgmt, u8 wait_ack)
\r
567 struct xmit_frame *pmgntframe;
\r
568 struct pkt_attrib *pattrib;
\r
569 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
570 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
571 struct sta_priv *pstapriv = &padapter->stapriv;
\r
572 struct sta_info *ptdls_sta=NULL;
\r
576 ptxmgmt->action_code = TDLS_TEARDOWN;
\r
577 ptdls_sta = rtw_get_stainfo(pstapriv, ptxmgmt->peer);
\r
578 if(ptdls_sta==NULL){
\r
579 DBG_871X("Np tdls_sta for tearing down\n");
\r
583 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
589 pattrib = &pmgntframe->attrib;
\r
591 pmgntframe->frame_tag = DATA_FRAMETAG;
\r
592 pattrib->ether_type = 0x890d;
\r
594 _rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN);
\r
595 _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
596 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
\r
597 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
\r
599 update_tdls_attrib(padapter, pattrib);
\r
600 pattrib->qsel = pattrib->priority;
\r
601 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) != _SUCCESS) {
\r
602 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
\r
603 rtw_free_xmitframe(pxmitpriv, pmgntframe);
\r
608 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
\r
610 dump_mgntframe(padapter, pmgntframe);
\r
614 if(ret == _SUCCESS)
\r
616 if(ptdls_sta->tdls_sta_state & TDLS_CH_SWITCH_ON_STATE){
\r
617 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CS_OFF);
\r
620 if( ptdls_sta->timer_flag == 1 )
\r
622 _enter_critical_bh(&(padapter->tdlsinfo.hdl_lock), &irqL);
\r
623 ptdls_sta->timer_flag = 2;
\r
624 _exit_critical_bh(&(padapter->tdlsinfo.hdl_lock), &irqL);
\r
627 rtw_tdls_cmd(padapter, ptxmgmt->peer, TDLS_TEAR_STA );
\r
635 int issue_tdls_dis_req(_adapter *padapter, struct tdls_txmgmt *ptxmgmt)
\r
637 struct xmit_frame *pmgntframe;
\r
638 struct pkt_attrib *pattrib;
\r
639 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
640 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
643 ptxmgmt->action_code = TDLS_DISCOVERY_REQUEST;
\r
644 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
650 pattrib = &pmgntframe->attrib;
\r
651 pmgntframe->frame_tag = DATA_FRAMETAG;
\r
652 pattrib->ether_type = 0x890d;
\r
654 _rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN);
\r
655 _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
656 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
\r
657 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
\r
659 update_tdls_attrib(padapter, pattrib);
\r
660 pattrib->qsel = pattrib->priority;
\r
661 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) != _SUCCESS) {
\r
662 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
\r
663 rtw_free_xmitframe(pxmitpriv, pmgntframe);
\r
666 dump_mgntframe(padapter, pmgntframe);
\r
667 DBG_871X("issue tdls dis req\n");
\r
675 int issue_tdls_setup_rsp(_adapter *padapter, struct tdls_txmgmt *ptxmgmt)
\r
677 struct xmit_frame *pmgntframe;
\r
678 struct pkt_attrib *pattrib;
\r
679 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
682 ptxmgmt->action_code = TDLS_SETUP_RESPONSE;
\r
683 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
689 pattrib = &pmgntframe->attrib;
\r
690 pmgntframe->frame_tag = DATA_FRAMETAG;
\r
691 pattrib->ether_type = 0x890d;
\r
693 _rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN);
\r
694 _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
695 _rtw_memcpy(pattrib->ra, get_bssid(&(padapter->mlmepriv)), ETH_ALEN);
\r
696 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
\r
698 update_tdls_attrib(padapter, pattrib);
\r
699 pattrib->qsel = pattrib->priority;
\r
700 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) != _SUCCESS) {
\r
701 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
\r
702 rtw_free_xmitframe(pxmitpriv, pmgntframe);
\r
706 dump_mgntframe(padapter, pmgntframe);
\r
715 int issue_tdls_setup_cfm(_adapter *padapter, struct tdls_txmgmt *ptxmgmt)
\r
717 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
\r
718 struct xmit_frame *pmgntframe;
\r
719 struct pkt_attrib *pattrib;
\r
720 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
723 ptxmgmt->action_code = TDLS_SETUP_CONFIRM;
\r
724 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
730 pattrib = &pmgntframe->attrib;
\r
731 pmgntframe->frame_tag = DATA_FRAMETAG;
\r
732 pattrib->ether_type = 0x890d;
\r
734 _rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN);
\r
735 _rtw_memcpy(pattrib->src, myid(&padapter->eeprompriv), ETH_ALEN);
\r
736 _rtw_memcpy(pattrib->ra, get_bssid(&padapter->mlmepriv), ETH_ALEN);
\r
737 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
\r
739 update_tdls_attrib(padapter, pattrib);
\r
740 pattrib->qsel = pattrib->priority;
\r
741 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) != _SUCCESS) {
\r
742 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
\r
743 rtw_free_xmitframe(pxmitpriv, pmgntframe);
\r
747 dump_mgntframe(padapter, pmgntframe);
\r
756 //TDLS Discovery Response frame is a management action frame
\r
757 int issue_tdls_dis_rsp(_adapter *padapter, struct tdls_txmgmt *ptxmgmt, u8 privacy)
\r
759 struct xmit_frame *pmgntframe;
\r
760 struct pkt_attrib *pattrib;
\r
761 unsigned char *pframe;
\r
762 struct rtw_ieee80211_hdr *pwlanhdr;
\r
763 unsigned short *fctrl;
\r
764 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
765 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
768 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
774 pattrib = &pmgntframe->attrib;
\r
775 update_mgntframe_attrib(padapter, pattrib);
\r
777 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
779 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
780 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
782 fctrl = &(pwlanhdr->frame_ctl);
\r
785 // unicast probe request frame
\r
786 _rtw_memcpy(pwlanhdr->addr1, ptxmgmt->peer, ETH_ALEN);
\r
787 _rtw_memcpy(pattrib->dst, pwlanhdr->addr1, ETH_ALEN);
\r
788 _rtw_memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
\r
789 _rtw_memcpy(pattrib->src, pwlanhdr->addr2, ETH_ALEN);
\r
790 _rtw_memcpy(pwlanhdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN);
\r
791 _rtw_memcpy(pattrib->ra, pwlanhdr->addr3, ETH_ALEN);
\r
793 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
\r
794 pmlmeext->mgnt_seq++;
\r
795 SetFrameSubType(pframe, WIFI_ACTION);
\r
797 pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
\r
798 pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
\r
800 rtw_build_tdls_dis_rsp_ies(padapter, pmgntframe, pframe, ptxmgmt->dialog_token, privacy);
\r
802 pattrib->nr_frags = 1;
\r
803 pattrib->last_txcmdsz = pattrib->pktlen;
\r
805 dump_mgntframe(padapter, pmgntframe);
\r
812 int issue_tdls_peer_traffic_rsp(_adapter *padapter, struct sta_info *ptdls_sta)
\r
814 struct xmit_frame *pmgntframe;
\r
815 struct pkt_attrib *pattrib;
\r
816 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
817 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
818 struct tdls_txmgmt txmgmt;
\r
821 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
822 txmgmt.action_code = TDLS_PEER_TRAFFIC_RESPONSE;
\r
824 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
830 pattrib = &pmgntframe->attrib;
\r
832 pmgntframe->frame_tag = DATA_FRAMETAG;
\r
833 pattrib->ether_type = 0x890d;
\r
835 _rtw_memcpy(pattrib->dst, ptdls_sta->hwaddr, ETH_ALEN);
\r
836 _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
837 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
\r
838 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
\r
840 update_tdls_attrib(padapter, pattrib);
\r
841 pattrib->qsel = pattrib->priority;
\r
843 if(rtw_xmit_tdls_coalesce(padapter, pmgntframe, &txmgmt) !=_SUCCESS ){
\r
844 rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf);
\r
845 rtw_free_xmitframe(pxmitpriv, pmgntframe);
\r
849 dump_mgntframe(padapter, pmgntframe);
\r
857 int issue_tdls_peer_traffic_indication(_adapter *padapter, struct sta_info *ptdls_sta)
\r
859 struct xmit_frame *pmgntframe;
\r
860 struct pkt_attrib *pattrib;
\r
861 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
862 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
863 struct tdls_txmgmt txmgmt;
\r
865 static u8 dialogtoken=0;
\r
867 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
868 txmgmt.action_code = TDLS_PEER_TRAFFIC_INDICATION;
\r
870 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
876 pattrib = &pmgntframe->attrib;
\r
878 pmgntframe->frame_tag = DATA_FRAMETAG;
\r
879 pattrib->ether_type = 0x890d;
\r
881 _rtw_memcpy(pattrib->dst, ptdls_sta->hwaddr, ETH_ALEN);
\r
882 _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
883 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
\r
884 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
\r
886 //for tdls; pattrib->nr_frags is used to fill dialogtoken
\r
887 ptdls_sta->dialog = dialogtoken;
\r
888 dialogtoken = (dialogtoken+1)%256;
\r
889 //PTI frame's priority should be AC_VO
\r
890 pattrib->priority = 7;
\r
892 update_tdls_attrib(padapter, pattrib);
\r
893 pattrib->qsel = pattrib->priority;
\r
894 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, &txmgmt) != _SUCCESS) {
\r
895 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
\r
896 rtw_free_xmitframe(pxmitpriv, pmgntframe);
\r
900 dump_mgntframe(padapter, pmgntframe);
\r
908 int issue_tdls_ch_switch_req(_adapter *padapter, u8 *mac_addr)
\r
910 struct xmit_frame *pmgntframe;
\r
911 struct pkt_attrib *pattrib;
\r
912 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
913 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
914 struct tdls_txmgmt txmgmt;
\r
917 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
918 txmgmt.action_code = TDLS_CHANNEL_SWITCH_REQUEST;
\r
920 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
926 pattrib = &pmgntframe->attrib;
\r
928 pmgntframe->frame_tag = DATA_FRAMETAG;
\r
929 pattrib->ether_type = 0x890d;
\r
931 _rtw_memcpy(pattrib->dst, mac_addr, ETH_ALEN);
\r
932 _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
933 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
\r
934 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
\r
936 update_tdls_attrib(padapter, pattrib);
\r
937 pattrib->qsel = pattrib->priority;
\r
938 if(rtw_xmit_tdls_coalesce(padapter, pmgntframe, &txmgmt) !=_SUCCESS ){
\r
939 rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf);
\r
940 rtw_free_xmitframe(pxmitpriv, pmgntframe);
\r
944 dump_mgntframe(padapter, pmgntframe);
\r
951 int issue_tdls_ch_switch_rsp(_adapter *padapter, u8 *mac_addr)
\r
953 struct xmit_frame *pmgntframe;
\r
954 struct pkt_attrib *pattrib;
\r
955 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
956 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
957 struct tdls_txmgmt txmgmt;
\r
960 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
961 txmgmt.action_code = TDLS_CHANNEL_SWITCH_RESPONSE;
\r
963 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
969 pattrib = &pmgntframe->attrib;
\r
971 pmgntframe->frame_tag = DATA_FRAMETAG;
\r
972 pattrib->ether_type = 0x890d;
\r
974 _rtw_memcpy(pattrib->dst, mac_addr, ETH_ALEN);
\r
975 _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
976 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
\r
977 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
\r
979 update_tdls_attrib(padapter, pattrib);
\r
980 pattrib->qsel = pattrib->priority;
\r
982 _enter_critical_bh(&pxmitpriv->lock, &irqL);
\r
983 if(xmitframe_enqueue_for_tdls_sleeping_sta(padapter, pmgntframe)==_TRUE){
\r
984 _exit_critical_bh(&pxmitpriv->lock, &irqL);
\r
988 if(rtw_xmit_tdls_coalesce(padapter, pmgntframe, &txmgmt) !=_SUCCESS ){
\r
989 rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf);
\r
990 rtw_free_xmitframe(pxmitpriv, pmgntframe);
\r
993 dump_mgntframe(padapter, pmgntframe);
\r
1000 int On_TDLS_Dis_Rsp(_adapter *padapter, union recv_frame *precv_frame)
\r
1002 struct sta_info *ptdls_sta = NULL, *psta = rtw_get_stainfo(&(padapter->stapriv), get_bssid(&(padapter->mlmepriv)));
\r
1003 struct recv_priv *precvpriv = &(padapter->recvpriv);
\r
1004 u8 *ptr = precv_frame->u.hdr.rx_data, *psa;
\r
1005 struct rx_pkt_attrib *pattrib = &(precv_frame->u.hdr.attrib);
\r
1006 struct tdls_info *ptdlsinfo = &(padapter->tdlsinfo);
\r
1007 u8 empty_addr[ETH_ALEN] = { 0x00 };
\r
1008 int UndecoratedSmoothedPWDB;
\r
1009 struct tdls_txmgmt txmgmt;
\r
1010 int ret = _SUCCESS;
\r
1012 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
1013 //WFDTDLS: for sigma test, not to setup direct link automatically
\r
1014 ptdlsinfo->dev_discovered = 1;
\r
1016 #ifdef CONFIG_TDLS_AUTOSETUP
\r
1017 psa = get_sa(ptr);
\r
1018 ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), psa);
\r
1020 if(ptdls_sta != NULL)
\r
1022 ptdls_sta->tdls_sta_state |= TDLS_ALIVE_STATE;
\r
1024 //Record the tdls sta with lowest signal strength
\r
1025 if( (ptdlsinfo->sta_maximum == _TRUE) && (ptdls_sta->alive_count >= 1) )
\r
1027 if( _rtw_memcmp(ptdlsinfo->ss_record.macaddr, empty_addr, ETH_ALEN) )
\r
1029 _rtw_memcpy(ptdlsinfo->ss_record.macaddr, psa, ETH_ALEN);
\r
1030 ptdlsinfo->ss_record.RxPWDBAll = pattrib->RxPWDBAll;
\r
1034 if( ptdlsinfo->ss_record.RxPWDBAll < pattrib->RxPWDBAll )
\r
1036 _rtw_memcpy(ptdlsinfo->ss_record.macaddr, psa, ETH_ALEN);
\r
1037 ptdlsinfo->ss_record.RxPWDBAll = pattrib->RxPWDBAll;
\r
1045 if( ptdlsinfo->sta_maximum == _TRUE)
\r
1047 if( _rtw_memcmp( ptdlsinfo->ss_record.macaddr, empty_addr, ETH_ALEN ) )
\r
1049 //All traffics are busy, do not set up another direct link.
\r
1055 if( pattrib->RxPWDBAll > ptdlsinfo->ss_record.RxPWDBAll )
\r
1057 _rtw_memcpy(txmgmt.peer, ptdlsinfo->ss_record.macaddr, ETH_ALEN);
\r
1058 //issue_tdls_teardown(padapter, ptdlsinfo->ss_record.macaddr, _FALSE);
\r
1068 padapter->HalFunc.GetHalDefVarHandler(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
\r
1070 if( pattrib->RxPWDBAll + TDLS_SIGNAL_THRESH >= UndecoratedSmoothedPWDB);
\r
1072 DBG_871X("pattrib->RxPWDBAll=%d, pdmpriv->UndecoratedSmoothedPWDB=%d\n", pattrib->RxPWDBAll, UndecoratedSmoothedPWDB);
\r
1073 _rtw_memcpy(txmgmt.peer, psa, ETH_ALEN);
\r
1074 issue_tdls_setup_req(padapter, &txmgmt, _FALSE);
\r
1077 #endif //CONFIG_TDLS_AUTOSETUP
\r
1084 sint On_TDLS_Setup_Req(_adapter *padapter, union recv_frame *precv_frame)
\r
1086 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
\r
1088 struct sta_info *ptdls_sta= NULL;
\r
1089 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1090 u8 *ptr = precv_frame->u.hdr.rx_data;
\r
1091 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
1092 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
1094 struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
\r
1095 u8 *prsnie, *ppairwise_cipher;
\r
1097 u8 ccmp_included=0, rsnie_included=0;
\r
1098 u16 j, pairwise_count;
\r
1100 u32 *timeout_interval=NULL;
\r
1101 sint parsing_length; //frame body length, without icv_len
\r
1102 PNDIS_802_11_VARIABLE_IEs pIE;
\r
1104 unsigned char supportRate[16];
\r
1105 int supportRateNum = 0;
\r
1106 struct tdls_txmgmt txmgmt;
\r
1108 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
1109 psa = get_sa(ptr);
\r
1110 ptdls_sta = rtw_get_stainfo(pstapriv, psa);
\r
1112 pmyid=myid(&(padapter->eeprompriv));
\r
1113 ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1;
\r
1114 parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
\r
1115 -prx_pkt_attrib->hdrlen
\r
1116 -prx_pkt_attrib->iv_len
\r
1117 -prx_pkt_attrib->icv_len
\r
1123 if(ptdlsinfo->ap_prohibited == _TRUE)
\r
1128 if(ptdls_sta==NULL){
\r
1129 ptdls_sta = rtw_alloc_stainfo(pstapriv, psa);
\r
1131 if(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE){
\r
1132 //If the direct link is already set up
\r
1133 //Process as re-setup after tear down
\r
1134 DBG_871X("re-setup a direct link\n");
\r
1136 //already receiving TDLS setup request
\r
1137 else if(ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE){
\r
1138 DBG_871X("receive duplicated TDLS setup request frame in handshaking\n");
\r
1141 //When receiving and sending setup_req to the same link at the same time, STA with higher MAC_addr would be initiator
\r
1142 //following is to check out MAC_addr
\r
1143 else if(ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE){
\r
1144 DBG_871X("receive setup_req after sending setup_req\n");
\r
1145 for (i=0;i<6;i++){
\r
1146 if(*(pmyid+i)==*(psa+i)){
\r
1148 else if(*(pmyid+i)>*(psa+i)){
\r
1149 ptdls_sta->tdls_sta_state=TDLS_INITIATOR_STATE;
\r
1151 }else if(*(pmyid+i)<*(psa+i)){
\r
1160 ptdls_sta->dialog = *(ptr+2); //copy dialog token
\r
1161 ptdls_sta->stat_code = 0;
\r
1163 //parsing information element
\r
1164 for(j=FIXED_IE; j<parsing_length;){
\r
1166 pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
\r
1168 switch (pIE->ElementID)
\r
1170 case _SUPPORTEDRATES_IE_:
\r
1171 _rtw_memcpy(supportRate, pIE->data, pIE->Length);
\r
1172 supportRateNum = pIE->Length;
\r
1174 case _COUNTRY_IE_:
\r
1176 case _EXT_SUPPORTEDRATES_IE_:
\r
1177 if(supportRateNum<=sizeof(supportRate))
\r
1179 _rtw_memcpy(supportRate+supportRateNum, pIE->data, pIE->Length);
\r
1180 supportRateNum += pIE->Length;
\r
1183 case _SUPPORTED_CH_IE_:
\r
1187 if(prx_pkt_attrib->encrypt){
\r
1189 //check whether initiator STA has CCMP pairwise_cipher.
\r
1190 ppairwise_cipher=prsnie+10;
\r
1191 _rtw_memcpy(ptdls_sta->TDLS_RSNIE, pIE->data, pIE->Length);
\r
1192 pairwise_count = *(u16*)(ppairwise_cipher-2);
\r
1193 for(k=0;k<pairwise_count;k++){
\r
1194 if(_rtw_memcmp( ppairwise_cipher+4*k, RSN_CIPHER_SUITE_CCMP, 4)==_TRUE)
\r
1197 if(ccmp_included==0){
\r
1198 //invalid contents of RSNIE
\r
1199 ptdls_sta->stat_code=72;
\r
1203 case _EXT_CAP_IE_:
\r
1205 case _VENDOR_SPECIFIC_IE_:
\r
1208 if(prx_pkt_attrib->encrypt)
\r
1209 _rtw_memcpy(SNonce, (ptr+j+52), 32);
\r
1211 case _TIMEOUT_ITVL_IE_:
\r
1212 if(prx_pkt_attrib->encrypt)
\r
1213 timeout_interval = (u32 *)(ptr+j+3);
\r
1215 case _RIC_Descriptor_IE_:
\r
1217 case _HT_CAPABILITY_IE_:
\r
1218 rtw_tdls_process_ht_cap(padapter, ptdls_sta, pIE->data, pIE->Length);
\r
1220 case EID_BSSCoexistence:
\r
1222 case _LINK_ID_IE_:
\r
1223 if(_rtw_memcmp(get_bssid(pmlmepriv), pIE->data, 6) == _FALSE)
\r
1225 //not in the same BSS
\r
1226 ptdls_sta->stat_code=7;
\r
1233 j += (pIE->Length + 2);
\r
1237 //check status code
\r
1238 //if responder STA has/hasn't security on AP, but request hasn't/has RSNIE, it should reject
\r
1239 if(ptdls_sta->stat_code == 0 )
\r
1241 if(rsnie_included && (prx_pkt_attrib->encrypt==0)){
\r
1242 //security disabled
\r
1243 ptdls_sta->stat_code = 5;
\r
1244 }else if(rsnie_included==0 && (prx_pkt_attrib->encrypt)){
\r
1245 //request haven't RSNIE
\r
1246 ptdls_sta->stat_code = 38;
\r
1250 //WFD test plan version 0.18.2 test item 5.1.5
\r
1251 //SoUT does not use TDLS if AP uses weak security
\r
1252 if ( padapter->wdinfo.wfd_tdls_enable )
\r
1254 if(rsnie_included && (prx_pkt_attrib->encrypt != _AES_))
\r
1256 ptdls_sta->stat_code = 5;
\r
1259 #endif //CONFIG_WFD
\r
1262 ptdls_sta->tdls_sta_state|= TDLS_INITIATOR_STATE;
\r
1263 if(prx_pkt_attrib->encrypt){
\r
1264 _rtw_memcpy(ptdls_sta->SNonce, SNonce, 32);
\r
1265 _rtw_memcpy(&(ptdls_sta->TDLS_PeerKey_Lifetime), timeout_interval, 4);
\r
1268 //update station supportRate
\r
1269 ptdls_sta->bssratelen = supportRateNum;
\r
1270 _rtw_memcpy(ptdls_sta->bssrateset, supportRate, supportRateNum);
\r
1272 if(!(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE))
\r
1273 ptdlsinfo->sta_cnt++;
\r
1274 if( ptdlsinfo->sta_cnt == (NUM_STA - 2 - 4) ) // -2: AP + BC/MC sta, -4: default key
\r
1276 ptdlsinfo->sta_maximum = _TRUE;
\r
1280 rtw_tdls_process_wfd_ie(ptdlsinfo, ptr + FIXED_IE, parsing_length - FIXED_IE);
\r
1281 #endif // CONFIG_WFD
\r
1289 _rtw_memcpy(txmgmt.peer, prx_pkt_attrib->src, ETH_ALEN);
\r
1290 issue_tdls_setup_rsp(padapter, &txmgmt);
\r
1292 if(ptdls_sta->stat_code==0)
\r
1294 _set_timer( &ptdls_sta->handshake_timer, TDLS_HANDSHAKE_TIME);
\r
1296 else //status code!=0 ; setup unsuccess
\r
1298 free_tdls_sta(padapter, ptdls_sta);
\r
1306 int On_TDLS_Setup_Rsp(_adapter *padapter, union recv_frame *precv_frame)
\r
1308 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
\r
1309 struct sta_info *ptdls_sta= NULL;
\r
1310 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1311 u8 *ptr = precv_frame->u.hdr.rx_data;
\r
1313 struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
\r
1316 sint parsing_length; //frame body length, without icv_len
\r
1317 PNDIS_802_11_VARIABLE_IEs pIE;
\r
1320 u8 *pftie=NULL, *ptimeout_ie=NULL, *plinkid_ie=NULL, *prsnie=NULL, *pftie_mic=NULL, *ppairwise_cipher=NULL;
\r
1321 u16 pairwise_count, j, k;
\r
1323 unsigned char supportRate[16];
\r
1324 int supportRateNum = 0;
\r
1325 struct tdls_txmgmt txmgmt;
\r
1326 int ret = _SUCCESS;
\r
1328 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
1329 psa = get_sa(ptr);
\r
1330 ptdls_sta = rtw_get_stainfo(pstapriv, psa);
\r
1332 if ( NULL == ptdls_sta )
\r
1338 ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1;
\r
1339 parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
\r
1340 -prx_pkt_attrib->hdrlen
\r
1341 -prx_pkt_attrib->iv_len
\r
1342 -prx_pkt_attrib->icv_len
\r
1344 -TYPE_LENGTH_FIELD_SIZE
\r
1348 _rtw_memcpy(&stat_code, ptr+2, 2);
\r
1352 DBG_871X( "[%s] status_code = %d, free_tdls_sta\n", __FUNCTION__, stat_code );
\r
1353 free_tdls_sta(padapter, ptdls_sta);
\r
1360 //parsing information element
\r
1361 for(j=FIXED_IE; j<parsing_length;)
\r
1363 pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
\r
1365 switch (pIE->ElementID)
\r
1367 case _SUPPORTEDRATES_IE_:
\r
1368 _rtw_memcpy(supportRate, pIE->data, pIE->Length);
\r
1369 supportRateNum = pIE->Length;
\r
1371 case _COUNTRY_IE_:
\r
1373 case _EXT_SUPPORTEDRATES_IE_:
\r
1374 if(supportRateNum<=sizeof(supportRate))
\r
1376 _rtw_memcpy(supportRate+supportRateNum, pIE->data, pIE->Length);
\r
1377 supportRateNum += pIE->Length;
\r
1380 case _SUPPORTED_CH_IE_:
\r
1384 //check whether responder STA has CCMP pairwise_cipher.
\r
1385 ppairwise_cipher=prsnie+10;
\r
1386 _rtw_memcpy(&pairwise_count, (u16*)(ppairwise_cipher-2), 2);
\r
1387 for(k=0;k<pairwise_count;k++){
\r
1388 if(_rtw_memcmp( ppairwise_cipher+4*k, RSN_CIPHER_SUITE_CCMP, 4)==_TRUE)
\r
1391 case _EXT_CAP_IE_:
\r
1393 case _VENDOR_SPECIFIC_IE_:
\r
1397 //_rtw_memcpy(ptdls_sta->ANonce, (ptr+j+20), 32);
\r
1398 _rtw_memcpy(ANonce, (ptr+j+20), 32);
\r
1400 case _TIMEOUT_ITVL_IE_:
\r
1401 ptimeout_ie=(u8*)pIE;
\r
1403 case _RIC_Descriptor_IE_:
\r
1405 case _HT_CAPABILITY_IE_:
\r
1406 rtw_tdls_process_ht_cap(padapter, ptdls_sta, pIE->data, pIE->Length);
\r
1408 case EID_BSSCoexistence:
\r
1410 case _LINK_ID_IE_:
\r
1411 plinkid_ie=(u8*)pIE;
\r
1417 j += (pIE->Length + 2);
\r
1421 //update station's supportRate
\r
1422 ptdls_sta->bssratelen = supportRateNum;
\r
1423 _rtw_memcpy(ptdls_sta->bssrateset, supportRate, supportRateNum);
\r
1425 _rtw_memcpy(ptdls_sta->ANonce, ANonce, 32);
\r
1428 rtw_tdls_process_wfd_ie(ptdlsinfo, ptr + FIXED_IE, parsing_length - FIXED_IE);
\r
1429 #endif // CONFIG_WFD
\r
1431 if(stat_code != 0)
\r
1433 ptdls_sta->stat_code = stat_code;
\r
1437 if(prx_pkt_attrib->encrypt)
\r
1439 if(verify_ccmp==1)
\r
1441 wpa_tdls_generate_tpk(padapter, ptdls_sta);
\r
1442 ptdls_sta->stat_code=0;
\r
1443 if(tdls_verify_mic(ptdls_sta->tpk.kck, 2, plinkid_ie, prsnie, ptimeout_ie, pftie)==0) //0: Invalid, 1: valid
\r
1445 free_tdls_sta(padapter, ptdls_sta);
\r
1452 ptdls_sta->stat_code=72; //invalide contents of RSNIE
\r
1456 ptdls_sta->stat_code=0;
\r
1460 DBG_871X("issue_tdls_setup_cfm\n");
\r
1461 _rtw_memcpy(txmgmt.peer, prx_pkt_attrib->src, ETH_ALEN);
\r
1462 issue_tdls_setup_cfm(padapter, &txmgmt);
\r
1464 if(ptdls_sta->stat_code==0)
\r
1466 ptdlsinfo->link_established = _TRUE;
\r
1468 if( ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE )
\r
1470 ptdls_sta->tdls_sta_state |= TDLS_LINKED_STATE;
\r
1471 _cancel_timer_ex( &ptdls_sta->handshake_timer);
\r
1474 rtw_tdls_set_key(padapter, prx_pkt_attrib, ptdls_sta);
\r
1476 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_ESTABLISHED);
\r
1485 int On_TDLS_Setup_Cfm(_adapter *padapter, union recv_frame *precv_frame)
\r
1487 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
\r
1488 struct sta_info *ptdls_sta= NULL;
\r
1489 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1490 u8 *ptr = precv_frame->u.hdr.rx_data;
\r
1492 struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
\r
1495 sint parsing_length;
\r
1496 PNDIS_802_11_VARIABLE_IEs pIE;
\r
1498 u8 *pftie=NULL, *ptimeout_ie=NULL, *plinkid_ie=NULL, *prsnie=NULL, *pftie_mic=NULL, *ppairwise_cipher=NULL;
\r
1499 u16 j, pairwise_count;
\r
1500 int ret = _SUCCESS;
\r
1502 psa = get_sa(ptr);
\r
1503 ptdls_sta = rtw_get_stainfo(pstapriv, psa);
\r
1505 if(ptdls_sta == NULL)
\r
1507 DBG_871X( "[%s] Direct Link Peer = "MAC_FMT" not found\n", __FUNCTION__, MAC_ARG(psa) );
\r
1512 ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1;
\r
1513 parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
\r
1514 -prx_pkt_attrib->hdrlen
\r
1515 -prx_pkt_attrib->iv_len
\r
1516 -prx_pkt_attrib->icv_len
\r
1521 _rtw_memcpy(&stat_code, ptr+2, 2);
\r
1524 DBG_871X( "[%s] stat_code = %d\n, free_tdls_sta", __FUNCTION__, stat_code );
\r
1525 free_tdls_sta(padapter, ptdls_sta);
\r
1530 if(prx_pkt_attrib->encrypt){
\r
1531 //parsing information element
\r
1532 for(j=FIXED_IE; j<parsing_length;){
\r
1534 pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
\r
1536 switch (pIE->ElementID)
\r
1541 case _VENDOR_SPECIFIC_IE_:
\r
1546 case _TIMEOUT_ITVL_IE_:
\r
1547 ptimeout_ie=(u8*)pIE;
\r
1549 case _HT_EXTRA_INFO_IE_:
\r
1551 case _LINK_ID_IE_:
\r
1552 plinkid_ie=(u8*)pIE;
\r
1558 j += (pIE->Length + 2);
\r
1562 //verify mic in FTIE MIC field
\r
1563 if(tdls_verify_mic(ptdls_sta->tpk.kck, 3, plinkid_ie, prsnie, ptimeout_ie, pftie)==0){ //0: Invalid, 1: Valid
\r
1564 free_tdls_sta(padapter, ptdls_sta);
\r
1571 ptdlsinfo->link_established = _TRUE;
\r
1572 if( ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE )
\r
1574 ptdls_sta->tdls_sta_state|=TDLS_LINKED_STATE;
\r
1575 _cancel_timer_ex( &ptdls_sta->handshake_timer);
\r
1578 rtw_tdls_set_key(padapter, prx_pkt_attrib, ptdls_sta);
\r
1580 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_ESTABLISHED);
\r
1587 int On_TDLS_Dis_Req(_adapter *padapter, union recv_frame *precv_frame)
\r
1589 struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
\r
1590 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1591 struct sta_info *psta_ap;
\r
1592 u8 *ptr = precv_frame->u.hdr.rx_data;
\r
1593 sint parsing_length; //frame body length, without icv_len
\r
1594 PNDIS_802_11_VARIABLE_IEs pIE;
\r
1595 u8 FIXED_IE = 3, *dst;
\r
1597 struct tdls_txmgmt txmgmt;
\r
1598 int ret = _SUCCESS;
\r
1600 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
1601 ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len + LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE + 1;
\r
1602 txmgmt.dialog_token = *(ptr+2);
\r
1603 _rtw_memcpy(&txmgmt.peer, precv_frame->u.hdr.attrib.src, ETH_ALEN);
\r
1604 txmgmt.action_code = TDLS_DISCOVERY_RESPONSE;
\r
1605 parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
\r
1606 -prx_pkt_attrib->hdrlen
\r
1607 -prx_pkt_attrib->iv_len
\r
1608 -prx_pkt_attrib->icv_len
\r
1610 -TYPE_LENGTH_FIELD_SIZE
\r
1614 //parsing information element
\r
1615 for(j=FIXED_IE; j<parsing_length;){
\r
1617 pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
\r
1619 switch (pIE->ElementID)
\r
1621 case _LINK_ID_IE_:
\r
1622 psta_ap = rtw_get_stainfo(pstapriv, pIE->data);
\r
1623 if(psta_ap == NULL)
\r
1627 dst = pIE->data + 12;
\r
1628 if( (MacAddr_isBcst(dst) == _FALSE) && (_rtw_memcmp(myid(&(padapter->eeprompriv)), dst, 6) == _FALSE) )
\r
1637 j += (pIE->Length + 2);
\r
1641 issue_tdls_dis_rsp(padapter, &txmgmt, prx_pkt_attrib->privacy);
\r
1648 int On_TDLS_Teardown(_adapter *padapter, union recv_frame *precv_frame)
\r
1651 u8 *ptr = precv_frame->u.hdr.rx_data;
\r
1652 struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
\r
1653 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
1654 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
1655 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1656 struct sta_info *ptdls_sta= NULL;
\r
1659 psa = get_sa(ptr);
\r
1661 ptdls_sta = rtw_get_stainfo(pstapriv, psa);
\r
1662 if(ptdls_sta!=NULL){
\r
1663 if(ptdls_sta->tdls_sta_state & TDLS_CH_SWITCH_ON_STATE){
\r
1664 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CS_OFF);
\r
1666 free_tdls_sta(padapter, ptdls_sta);
\r
1673 u8 TDLS_check_ch_state(uint state){
\r
1674 if( (state & TDLS_CH_SWITCH_ON_STATE) &&
\r
1675 (state & TDLS_AT_OFF_CH_STATE) &&
\r
1676 (state & TDLS_PEER_AT_OFF_STATE) ){
\r
1678 if(state & TDLS_PEER_SLEEP_STATE)
\r
1679 return 2; //U-APSD + ch. switch
\r
1681 return 1; //ch. switch
\r
1686 int On_TDLS_Peer_Traffic_Indication(_adapter *padapter, union recv_frame *precv_frame)
\r
1688 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
\r
1689 struct sta_info *ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->src);
\r
1690 u8 *ptr = precv_frame->u.hdr.rx_data;
\r
1692 ptr +=pattrib->hdrlen + pattrib->iv_len + LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE + 1;
\r
1694 if(ptdls_sta != NULL)
\r
1696 ptdls_sta->dialog = *(ptr+2);
\r
1697 issue_tdls_peer_traffic_rsp(padapter, ptdls_sta);
\r
1699 //issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->hwaddr, 0, 0, 0);
\r
1703 DBG_871X("from unknown sta:"MAC_FMT"\n", MAC_ARG(pattrib->src));
\r
1710 //we process buffered data for 1. U-APSD, 2. ch. switch, 3. U-APSD + ch. switch here
\r
1711 int On_TDLS_Peer_Traffic_Rsp(_adapter *padapter, union recv_frame *precv_frame)
\r
1713 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
\r
1714 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
1715 struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib;
\r
1716 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1717 //get peer sta infomation
\r
1718 struct sta_info *ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->src);
\r
1719 u8 wmmps_ac=0, state=TDLS_check_ch_state(ptdls_sta->tdls_sta_state);
\r
1722 ptdls_sta->sta_stats.rx_data_pkts++;
\r
1724 ptdls_sta->tdls_sta_state &= ~(TDLS_WAIT_PTR_STATE);
\r
1726 //receive peer traffic response frame, sleeping STA wakes up
\r
1727 //ptdls_sta->tdls_sta_state &= ~(TDLS_PEER_SLEEP_STATE);
\r
1728 //process_wmmps_data( padapter, precv_frame);
\r
1730 // if noticed peer STA wakes up by receiving peer traffic response
\r
1731 // and we want to do channel swtiching, then we will transmit channel switch request first
\r
1732 if(ptdls_sta->tdls_sta_state & TDLS_APSD_CHSW_STATE){
\r
1733 issue_tdls_ch_switch_req(padapter, pattrib->src);
\r
1734 ptdls_sta->tdls_sta_state &= ~(TDLS_APSD_CHSW_STATE);
\r
1738 //check 4-AC queue bit
\r
1739 if(ptdls_sta->uapsd_vo || ptdls_sta->uapsd_vi || ptdls_sta->uapsd_be || ptdls_sta->uapsd_bk)
\r
1742 //if it's a direct link and have buffered frame
\r
1743 if(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE){
\r
1745 //if(wmmps_ac && state)
\r
1749 _list *xmitframe_plist, *xmitframe_phead;
\r
1750 struct xmit_frame *pxmitframe=NULL;
\r
1752 _enter_critical_bh(&ptdls_sta->sleep_q.lock, &irqL);
\r
1754 xmitframe_phead = get_list_head(&ptdls_sta->sleep_q);
\r
1755 xmitframe_plist = get_next(xmitframe_phead);
\r
1757 //transmit buffered frames
\r
1758 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE)
\r
1760 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
\r
1761 xmitframe_plist = get_next(xmitframe_plist);
\r
1762 rtw_list_delete(&pxmitframe->list);
\r
1764 ptdls_sta->sleepq_len--;
\r
1765 ptdls_sta->sleepq_ac_len--;
\r
1766 if(ptdls_sta->sleepq_len>0){
\r
1767 pxmitframe->attrib.mdata = 1;
\r
1768 pxmitframe->attrib.eosp = 0;
\r
1770 pxmitframe->attrib.mdata = 0;
\r
1771 pxmitframe->attrib.eosp = 1;
\r
1773 pxmitframe->attrib.triggered = 1;
\r
1775 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
\r
1780 if(ptdls_sta->sleepq_len==0)
\r
1782 DBG_871X("no buffered packets for tdls to xmit\n");
\r
1783 //on U-APSD + CH. switch state, when there is no buffered date to xmit,
\r
1784 // we should go back to base channel
\r
1786 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CS_OFF);
\r
1787 }else if(ptdls_sta->tdls_sta_state&TDLS_SW_OFF_STATE){
\r
1788 ptdls_sta->tdls_sta_state &= ~(TDLS_SW_OFF_STATE);
\r
1789 ptdlsinfo->candidate_ch= pmlmeext->cur_channel;
\r
1790 issue_tdls_ch_switch_req(padapter, pattrib->src);
\r
1791 DBG_871X("issue tdls ch switch req back to base channel\n");
\r
1797 DBG_871X("error!psta->sleepq_len=%d\n", ptdls_sta->sleepq_len);
\r
1798 ptdls_sta->sleepq_len=0;
\r
1801 _exit_critical_bh(&ptdls_sta->sleep_q.lock, &irqL);
\r
1810 sint On_TDLS_Ch_Switch_Req(_adapter *padapter, union recv_frame *precv_frame)
\r
1812 struct sta_info *ptdls_sta= NULL;
\r
1813 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1814 u8 *ptr = precv_frame->u.hdr.rx_data;
\r
1815 struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
\r
1817 sint parsing_length;
\r
1818 PNDIS_802_11_VARIABLE_IEs pIE;
\r
1821 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
1823 psa = get_sa(ptr);
\r
1824 ptdls_sta = rtw_get_stainfo(pstapriv, psa);
\r
1826 ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1;
\r
1827 parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
\r
1828 -prx_pkt_attrib->hdrlen
\r
1829 -prx_pkt_attrib->iv_len
\r
1830 -prx_pkt_attrib->icv_len
\r
1836 ptdls_sta->off_ch = *(ptr+2);
\r
1838 //parsing information element
\r
1839 for(j=FIXED_IE; j<parsing_length;){
\r
1841 pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
\r
1843 switch (pIE->ElementID)
\r
1845 case _COUNTRY_IE_:
\r
1847 case _CH_SWTICH_ANNOUNCE_:
\r
1849 case _LINK_ID_IE_:
\r
1851 case _CH_SWITCH_TIMING_:
\r
1852 _rtw_memcpy(&ptdls_sta->ch_switch_time, pIE->data, 2);
\r
1853 _rtw_memcpy(&ptdls_sta->ch_switch_timeout, pIE->data+2, 2);
\r
1858 j += (pIE->Length + 2);
\r
1862 //todo: check status
\r
1863 ptdls_sta->stat_code=0;
\r
1864 ptdls_sta->tdls_sta_state |= TDLS_CH_SWITCH_ON_STATE;
\r
1866 issue_nulldata(padapter, NULL, 1, 0, 0);
\r
1868 issue_tdls_ch_switch_rsp(padapter, psa);
\r
1870 DBG_871X("issue tdls channel switch response\n");
\r
1872 if((ptdls_sta->tdls_sta_state & TDLS_CH_SWITCH_ON_STATE) && ptdls_sta->off_ch==pmlmeext->cur_channel){
\r
1873 DBG_871X("back to base channel %x\n", pmlmeext->cur_channel);
\r
1874 ptdls_sta->option=TDLS_BASE_CH;
\r
1875 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_BASE_CH);
\r
1877 ptdls_sta->option=TDLS_OFF_CH;
\r
1878 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_OFF_CH);
\r
1883 sint On_TDLS_Ch_Switch_Rsp(_adapter *padapter, union recv_frame *precv_frame)
\r
1885 struct sta_info *ptdls_sta= NULL;
\r
1886 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1887 u8 *ptr = precv_frame->u.hdr.rx_data;
\r
1888 struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
\r
1890 sint parsing_length;
\r
1891 PNDIS_802_11_VARIABLE_IEs pIE;
\r
1893 u16 stat_code, j, switch_time, switch_timeout;
\r
1894 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
1895 int ret = _SUCCESS;
\r
1897 psa = get_sa(ptr);
\r
1898 ptdls_sta = rtw_get_stainfo(pstapriv, psa);
\r
1900 //if channel switch is running and receiving Unsolicited TDLS Channel Switch Response,
\r
1901 //it will go back to base channel and terminate this channel switch procedure
\r
1902 if(ptdls_sta->tdls_sta_state & TDLS_CH_SWITCH_ON_STATE ){
\r
1903 if(pmlmeext->cur_channel==ptdls_sta->off_ch){
\r
1904 DBG_871X("back to base channel %x\n", pmlmeext->cur_channel);
\r
1905 ptdls_sta->option=TDLS_BASE_CH;
\r
1906 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_BASE_CH);
\r
1908 DBG_871X("receive unsolicited channel switch response \n");
\r
1909 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CS_OFF);
\r
1915 //avoiding duplicated or unconditional ch. switch. rsp
\r
1916 if(!(ptdls_sta->tdls_sta_state & TDLS_CH_SW_INITIATOR_STATE))
\r
1922 ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1;
\r
1923 parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
\r
1924 -prx_pkt_attrib->hdrlen
\r
1925 -prx_pkt_attrib->iv_len
\r
1926 -prx_pkt_attrib->icv_len
\r
1932 _rtw_memcpy(&stat_code, ptr+2, 2);
\r
1939 //parsing information element
\r
1940 for(j=FIXED_IE; j<parsing_length;){
\r
1942 pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
\r
1944 switch (pIE->ElementID)
\r
1946 case _LINK_ID_IE_:
\r
1948 case _CH_SWITCH_TIMING_:
\r
1949 _rtw_memcpy(&switch_time, pIE->data, 2);
\r
1950 if(switch_time > ptdls_sta->ch_switch_time)
\r
1951 _rtw_memcpy(&ptdls_sta->ch_switch_time, &switch_time, 2);
\r
1953 _rtw_memcpy(&switch_timeout, pIE->data+2, 2);
\r
1954 if(switch_timeout > ptdls_sta->ch_switch_timeout)
\r
1955 _rtw_memcpy(&ptdls_sta->ch_switch_timeout, &switch_timeout, 2);
\r
1961 j += (pIE->Length + 2);
\r
1965 ptdls_sta->tdls_sta_state &= ~(TDLS_CH_SW_INITIATOR_STATE);
\r
1966 ptdls_sta->tdls_sta_state |=TDLS_CH_SWITCH_ON_STATE;
\r
1968 //goto set_channel_workitem_callback()
\r
1969 ptdls_sta->option=TDLS_OFF_CH;
\r
1970 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_OFF_CH);
\r
1977 void wfd_ie_tdls(_adapter * padapter, u8 *pframe, u32 *pktlen )
\r
1979 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1980 struct wifi_display_info *pwfd_info = padapter->tdlsinfo.wfd_info;
\r
1981 u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
\r
1986 wfdie[ wfdielen++ ] = 0x50;
\r
1987 wfdie[ wfdielen++ ] = 0x6F;
\r
1988 wfdie[ wfdielen++ ] = 0x9A;
\r
1989 wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
\r
1991 // Commented by Albert 20110825
\r
1992 // According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes
\r
1993 // 1. WFD Device Information
\r
1994 // 2. Associated BSSID ( Optional )
\r
1995 // 3. Local IP Adress ( Optional )
\r
1997 // WFD Device Information ATTR
\r
1999 wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
\r
2002 // Note: In the WFD specification, the size of length field is 2.
\r
2003 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
\r
2007 // WFD device information
\r
2008 // available for WFD session + Preferred TDLS + WSD ( WFD Service Discovery )
\r
2009 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL
\r
2010 | WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_WSD);
\r
2014 // Session Management Control Port
\r
2015 // Default TCP port for RTSP messages is 554
\r
2016 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
\r
2020 // WFD Device Maximum Throughput
\r
2021 // 300Mbps is the maximum throughput
\r
2022 RTW_PUT_BE16(wfdie + wfdielen, 300);
\r
2025 // Associated BSSID ATTR
\r
2027 wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
\r
2030 // Note: In the WFD specification, the size of length field is 2.
\r
2031 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
\r
2035 // Associated BSSID
\r
2036 if ( check_fwstate( pmlmepriv, _FW_LINKED) == _TRUE )
\r
2038 _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
\r
2042 _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
\r
2045 // Local IP Address ATTR
\r
2046 wfdie[ wfdielen++ ] = WFD_ATTR_LOCAL_IP_ADDR;
\r
2049 // Note: In the WFD specification, the size of length field is 2.
\r
2050 RTW_PUT_BE16(wfdie + wfdielen, 0x0005);
\r
2054 // 0x01: Version1;IPv4
\r
2055 wfdie[ wfdielen++ ] = 0x01;
\r
2058 _rtw_memcpy( wfdie + wfdielen, pwfd_info->ip_address, 4 );
\r
2061 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, pktlen);
\r
2064 #endif //CONFIG_WFD
\r
2066 void rtw_build_tdls_setup_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt)
\r
2068 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
2069 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
\r
2070 struct pkt_attrib *pattrib = &pxmitframe->attrib;
\r
2071 struct registry_priv *pregistrypriv = &padapter->registrypriv;
\r
2072 struct sta_info *ptdls_sta=rtw_get_stainfo( (&padapter->stapriv) , pattrib->dst);
\r
2074 u8 payload_type = 0x02;
\r
2075 u8 category = RTW_WLAN_CATEGORY_TDLS;
\r
2076 u8 action = TDLS_SETUP_REQUEST;
\r
2077 u8 bssrate[NDIS_802_11_LENGTH_RATES_EX]; //Use NDIS_802_11_LENGTH_RATES_EX in order to call func.rtw_set_supported_rate
\r
2078 int bssrate_len = 0, i = 0 ;
\r
2079 u8 more_supportedrates = 0;
\r
2080 unsigned int ie_len;
\r
2081 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
2082 u8 link_id_addr[18] = {0};
\r
2084 u8 sup_ch[ 30 * 2 ] = {0x00 }, sup_ch_idx = 0, idx_5g = 2; //For supported channel
\r
2085 u8 timeout_itvl[5]; //set timeout interval to maximum value
\r
2090 if(pattrib->encrypt){
\r
2092 time=rtw_get_current_time();
\r
2093 _rtw_memcpy(&ptdls_sta->SNonce[4*i], (u8 *)&time, 4);
\r
2097 pframe_head = pframe; // For rtw_tdls_set_ht_cap()
\r
2100 pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
\r
2101 //category, action, dialog token
\r
2102 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
2103 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
2104 pframe = rtw_set_fixed_ie(pframe, 1, &(ptdls_sta->dialog), &(pattrib->pktlen));
\r
2107 _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
\r
2109 if(pattrib->encrypt)
\r
2110 *pframe =*pframe | cap_Privacy;
\r
2112 pattrib->pktlen += 2;
\r
2115 if(pmlmeext->cur_channel < 14 )
\r
2117 rtw_set_supported_rate(bssrate, WIRELESS_11BG_24N);
\r
2118 bssrate_len = IEEE80211_CCK_RATE_LEN + IEEE80211_NUM_OFDM_RATESLEN;
\r
2122 rtw_set_supported_rate(bssrate, WIRELESS_11A_5N);
\r
2123 bssrate_len = IEEE80211_NUM_OFDM_RATESLEN;
\r
2126 //country(optional)
\r
2128 if (bssrate_len > 8)
\r
2130 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
\r
2131 more_supportedrates = 1;
\r
2135 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
\r
2138 //extended supported rates
\r
2139 if(more_supportedrates==1){
\r
2140 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
\r
2143 //supported channels
\r
2144 pframe = rtw_tdls_set_sup_ch(pmlmeext, pframe, pattrib);
\r
2147 pframe = rtw_set_ie( pframe, _SRC_IE_, sizeof(TDLS_SRC), TDLS_SRC, &(pattrib->pktlen));
\r
2150 if(pattrib->encrypt)
\r
2151 pframe = rtw_set_ie(pframe, _RSN_IE_2_, sizeof(TDLS_RSNIE), TDLS_RSNIE, &(pattrib->pktlen));
\r
2153 //extended capabilities
\r
2154 pframe = rtw_set_ie(pframe, _EXT_CAP_IE_ , sizeof(TDLS_EXT_CAPIE), TDLS_EXT_CAPIE, &(pattrib->pktlen));
\r
2156 //QoS capability(WMM_IE)
\r
2157 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(TDLS_WMMIE), TDLS_WMMIE, &(pattrib->pktlen));
\r
2160 if(pattrib->encrypt){
\r
2162 _rtw_memset(pframe, 0, 84); //All fields except SNonce shall be set to 0
\r
2163 _rtw_memset(pframe, _FTIE_, 1); //version
\r
2164 _rtw_memset((pframe+1), 82, 1); //length
\r
2165 _rtw_memcpy((pframe+52), ptdls_sta->SNonce, 32);
\r
2167 pattrib->pktlen += 84;
\r
2169 //Timeout interval
\r
2170 timeout_itvl[0]=0x02;
\r
2171 _rtw_memcpy(timeout_itvl+1, (u8 *)(&ptdls_sta->TDLS_PeerKey_Lifetime), 4);
\r
2172 pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
\r
2175 //Sup_reg_classes(optional)
\r
2177 pframe += rtw_tdls_set_ht_cap(padapter, pframe_head, pattrib);
\r
2179 //20/40 BSS coexistence
\r
2180 if(pmlmepriv->num_FortyMHzIntolerant>0)
\r
2181 iedata |= BIT(2);//20 MHz BSS Width Request
\r
2182 pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
\r
2185 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2186 _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
\r
2187 _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
\r
2188 pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
\r
2191 wfd_ie_tdls( padapter, pframe, &(pattrib->pktlen) );
\r
2192 #endif //CONFIG_WFD
\r
2196 void rtw_build_tdls_setup_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt)
\r
2198 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
2199 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
2200 struct pkt_attrib *pattrib = &pxmitframe->attrib;
\r
2201 struct sta_info *ptdls_sta;
\r
2202 struct registry_priv *pregistrypriv = &padapter->registrypriv;
\r
2204 u8 payload_type = 0x02;
\r
2205 unsigned char category = RTW_WLAN_CATEGORY_TDLS;
\r
2206 unsigned char action = TDLS_SETUP_RESPONSE;
\r
2207 unsigned char bssrate[NDIS_802_11_LENGTH_RATES_EX];
\r
2208 int bssrate_len = 0;
\r
2209 u8 more_supportedrates = 0;
\r
2210 unsigned int ie_len;
\r
2212 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
2213 u8 link_id_addr[18] = {0};
\r
2215 u8 timeout_itvl[5]; //setup response timeout interval will copy from request
\r
2216 u8 ANonce[32]; //maybe it can put in ontdls_req
\r
2217 u8 k; //for random ANonce
\r
2218 u8 *pftie=NULL, *ptimeout_ie=NULL, *plinkid_ie=NULL, *prsnie=NULL, *pftie_mic=NULL;
\r
2222 ptdls_sta = rtw_get_stainfo( &(padapter->stapriv) , pattrib->dst);
\r
2224 if(ptdls_sta == NULL )
\r
2226 DBG_871X("[%s] %d\n", __FUNCTION__, __LINE__);
\r
2230 if(pattrib->encrypt){
\r
2232 time=rtw_get_current_time();
\r
2233 _rtw_memcpy(&ptdls_sta->ANonce[4*k], (u8*)&time, 4);
\r
2237 pframe_head = pframe;
\r
2240 pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
\r
2241 //category, action, status code
\r
2242 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
2243 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
2244 pframe = rtw_set_fixed_ie(pframe, 2, (u8 *)&ptdls_sta->stat_code, &(pattrib->pktlen));
\r
2246 if(ptdls_sta->stat_code!=0) //invalid setup request
\r
2248 DBG_871X("ptdls_sta->stat_code:%04x \n", ptdls_sta->stat_code);
\r
2253 pframe = rtw_set_fixed_ie(pframe, 1, &(ptdls_sta->dialog), &(pattrib->pktlen));
\r
2256 _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
\r
2258 if(pattrib->encrypt )
\r
2259 *pframe =*pframe | cap_Privacy;
\r
2261 pattrib->pktlen += 2;
\r
2265 if(pmlmeext->cur_channel < 14 )
\r
2267 rtw_set_supported_rate(bssrate, WIRELESS_11BG_24N);
\r
2268 bssrate_len = IEEE80211_CCK_RATE_LEN + IEEE80211_NUM_OFDM_RATESLEN;
\r
2272 rtw_set_supported_rate(bssrate, WIRELESS_11A_5N);
\r
2273 bssrate_len = IEEE80211_NUM_OFDM_RATESLEN;
\r
2276 if (bssrate_len > 8)
\r
2278 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
\r
2279 more_supportedrates = 1;
\r
2283 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
\r
2286 //country(optional)
\r
2287 //extended supported rates
\r
2288 if(more_supportedrates==1){
\r
2289 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
\r
2292 //supported channels
\r
2293 pframe = rtw_tdls_set_sup_ch(pmlmeext, pframe, pattrib);
\r
2296 pframe = rtw_set_ie(pframe, _SRC_IE_ , sizeof(TDLS_SRC), TDLS_SRC, &(pattrib->pktlen));
\r
2299 if(pattrib->encrypt){
\r
2301 pframe = rtw_set_ie(pframe, _RSN_IE_2_, sizeof(ptdls_sta->TDLS_RSNIE), ptdls_sta->TDLS_RSNIE, &(pattrib->pktlen));
\r
2304 //extended capabilities
\r
2305 pframe = rtw_set_ie(pframe, _EXT_CAP_IE_ , sizeof(TDLS_EXT_CAPIE), TDLS_EXT_CAPIE, &(pattrib->pktlen));
\r
2307 //QoS capability(WMM_IE)
\r
2308 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(TDLS_WMMIE), TDLS_WMMIE, &(pattrib->pktlen));
\r
2310 if(pattrib->encrypt){
\r
2311 wpa_tdls_generate_tpk(padapter, ptdls_sta);
\r
2315 pftie_mic = pframe+4;
\r
2316 _rtw_memset(pframe, 0, 84); //All fields except SNonce shall be set to 0
\r
2317 _rtw_memset(pframe, _FTIE_, 1); //version
\r
2318 _rtw_memset((pframe+1), 82, 1); //length
\r
2319 _rtw_memcpy((pframe+20), ptdls_sta->ANonce, 32);
\r
2320 _rtw_memcpy((pframe+52), ptdls_sta->SNonce, 32);
\r
2322 pattrib->pktlen += 84;
\r
2324 //Timeout interval
\r
2325 ptimeout_ie = pframe;
\r
2326 timeout_itvl[0]=0x02;
\r
2327 _rtw_memcpy(timeout_itvl+1, (u8 *)(&ptdls_sta->TDLS_PeerKey_Lifetime), 4);
\r
2328 pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
\r
2331 //Sup_reg_classes(optional)
\r
2333 pframe += rtw_tdls_set_ht_cap(padapter, pframe_head, pattrib);
\r
2335 //20/40 BSS coexistence
\r
2336 if(pmlmepriv->num_FortyMHzIntolerant>0)
\r
2337 iedata |= BIT(2);//20 MHz BSS Width Request
\r
2338 pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
\r
2341 plinkid_ie = pframe;
\r
2342 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2343 _rtw_memcpy((link_id_addr+6), pattrib->dst, 6);
\r
2344 _rtw_memcpy((link_id_addr+12), pattrib->src, 6);
\r
2345 pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
\r
2348 if(pattrib->encrypt)
\r
2349 wpa_tdls_ftie_mic(ptdls_sta->tpk.kck, 2, plinkid_ie, prsnie, ptimeout_ie, pftie, pftie_mic);
\r
2352 wfd_ie_tdls( padapter, pframe, &(pattrib->pktlen) );
\r
2353 #endif //CONFIG_WFD
\r
2357 void rtw_build_tdls_setup_cfm_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt)
\r
2360 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
2361 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
2362 struct pkt_attrib *pattrib = &pxmitframe->attrib;
\r
2363 struct sta_info *ptdls_sta=rtw_get_stainfo( (&padapter->stapriv) , pattrib->dst);
\r
2365 u8 payload_type = 0x02;
\r
2366 unsigned char category = RTW_WLAN_CATEGORY_TDLS;
\r
2367 unsigned char action = TDLS_SETUP_CONFIRM;
\r
2368 u8 more_supportedrates = 0;
\r
2369 unsigned int ie_len;
\r
2371 u8 timeout_itvl[5]; //set timeout interval to maximum value
\r
2372 u8 wmm_param_ele[24] = {0};
\r
2373 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
2374 u8 link_id_addr[18] = {0};
\r
2375 u8 *pftie=NULL, *ptimeout_ie=NULL, *plinkid_ie=NULL, *prsnie=NULL, *pftie_mic=NULL;
\r
2378 pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
\r
2379 //category, action, status code, dialog token
\r
2380 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
2381 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
2382 pframe = rtw_set_fixed_ie(pframe, 2, (u8 *)&ptdls_sta->stat_code, &(pattrib->pktlen));
\r
2383 pframe = rtw_set_fixed_ie(pframe, 1, &(ptdls_sta->dialog), &(pattrib->pktlen));
\r
2385 if(ptdls_sta->stat_code!=0) //invalid setup request
\r
2389 if(pattrib->encrypt){
\r
2391 pframe = rtw_set_ie(pframe, _RSN_IE_2_, sizeof(TDLS_RSNIE), TDLS_RSNIE, &(pattrib->pktlen));
\r
2394 //EDCA param set; WMM param ele.
\r
2395 if(pattrib->encrypt){
\r
2398 pftie_mic = pframe+4;
\r
2399 _rtw_memset(pframe, 0, 84); //All fields except SNonce shall be set to 0
\r
2400 _rtw_memset(pframe, _FTIE_, 1); //version
\r
2401 _rtw_memset((pframe+1), 82, 1); //length
\r
2402 _rtw_memcpy((pframe+20), ptdls_sta->ANonce, 32);
\r
2403 _rtw_memcpy((pframe+52), ptdls_sta->SNonce, 32);
\r
2405 pattrib->pktlen += 84;
\r
2407 //Timeout interval
\r
2408 ptimeout_ie = pframe;
\r
2409 timeout_itvl[0]=0x02;
\r
2410 _rtw_memcpy(timeout_itvl+1, (u8 *)(&ptdls_sta->TDLS_PeerKey_Lifetime), 4);
\r
2411 ptdls_sta->TPK_count=0;
\r
2412 _set_timer(&ptdls_sta->TPK_timer, ptdls_sta->TDLS_PeerKey_Lifetime/TPK_RESEND_COUNT);
\r
2413 pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
\r
2416 //HT operation; todo
\r
2418 plinkid_ie = pframe;
\r
2419 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2420 _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
\r
2421 _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
\r
2422 pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
\r
2425 if(pattrib->encrypt)
\r
2426 wpa_tdls_ftie_mic(ptdls_sta->tpk.kck, 3, plinkid_ie, prsnie, ptimeout_ie, pftie, pftie_mic);
\r
2428 //WMM Parameter Set
\r
2429 if(&pmlmeinfo->WMM_param)
\r
2431 _rtw_memcpy(wmm_param_ele, WMM_PARA_OUI, 6);
\r
2432 _rtw_memcpy(wmm_param_ele+6, (u8 *)&pmlmeinfo->WMM_param, sizeof(pmlmeinfo->WMM_param));
\r
2433 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 24, wmm_param_ele, &(pattrib->pktlen));
\r
2438 void rtw_build_tdls_teardown_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt)
\r
2441 struct pkt_attrib *pattrib = &pxmitframe->attrib;
\r
2442 u8 payload_type = 0x02;
\r
2443 unsigned char category = RTW_WLAN_CATEGORY_TDLS;
\r
2444 u8 action = ptxmgmt->action_code;
\r
2445 u8 link_id_addr[18] = {0};
\r
2446 struct sta_info *ptdls_sta = rtw_get_stainfo( &(padapter->stapriv) , pattrib->dst);
\r
2449 pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
\r
2450 //category, action, reason code
\r
2451 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
2452 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
2453 pframe = rtw_set_fixed_ie(pframe, 2, (u8 *)&ptxmgmt->status_code, &(pattrib->pktlen));
\r
2456 if(ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE){
\r
2457 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2458 _rtw_memcpy((link_id_addr+6), pattrib->dst, 6);
\r
2459 _rtw_memcpy((link_id_addr+12), pattrib->src, 6);
\r
2460 }else if(ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE){
\r
2461 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2462 _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
\r
2463 _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
\r
2465 pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
\r
2469 void rtw_build_tdls_dis_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt)
\r
2472 struct pkt_attrib *pattrib = &pxmitframe->attrib;
\r
2473 u8 payload_type = 0x02;
\r
2474 u8 category = RTW_WLAN_CATEGORY_TDLS;
\r
2475 u8 action = TDLS_DISCOVERY_REQUEST;
\r
2476 u8 link_id_addr[18] = {0};
\r
2477 static u8 dialogtoken=0;
\r
2480 pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
\r
2481 //category, action, reason code
\r
2482 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
2483 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
2484 if(ptxmgmt->external_support == _TRUE) {
\r
2485 pframe = rtw_set_fixed_ie(pframe, 1, &(ptxmgmt->dialog_token), &(pattrib->pktlen));
\r
2487 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogtoken), &(pattrib->pktlen));
\r
2488 dialogtoken = (dialogtoken+1)%256;
\r
2492 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2493 _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
\r
2494 _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
\r
2495 pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
\r
2499 void rtw_build_tdls_dis_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, u8 dialog, u8 privacy)
\r
2501 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
2502 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
\r
2503 struct pkt_attrib *pattrib = &pxmitframe->attrib;
\r
2504 struct registry_priv *pregistrypriv = &padapter->registrypriv;
\r
2506 u8 category = RTW_WLAN_CATEGORY_PUBLIC;
\r
2507 u8 action = TDLS_DISCOVERY_RESPONSE;
\r
2508 u8 bssrate[NDIS_802_11_LENGTH_RATES_EX];
\r
2509 int bssrate_len = 0;
\r
2510 u8 more_supportedrates = 0;
\r
2512 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
2513 u8 link_id_addr[18] = {0};
\r
2515 u8 timeout_itvl[5]; //set timeout interval to maximum value
\r
2516 u32 timeout_interval= TPK_RESEND_COUNT * 1000;
\r
2517 u8 *pframe_head, pktlen_index;
\r
2519 pktlen_index = pattrib->pktlen; // For mgmt frame, pattrib->pktlen would count frame header
\r
2520 pframe_head = pframe;
\r
2522 //category, action, dialog token
\r
2523 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
2524 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
2525 pframe = rtw_set_fixed_ie(pframe, 1, &(dialog), &(pattrib->pktlen));
\r
2528 _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
\r
2531 *pframe =*pframe | cap_Privacy;
\r
2533 pattrib->pktlen += 2;
\r
2536 rtw_set_supported_rate(bssrate, WIRELESS_11BG_24N);
\r
2537 bssrate_len = IEEE80211_CCK_RATE_LEN + IEEE80211_NUM_OFDM_RATESLEN;
\r
2539 if (bssrate_len > 8)
\r
2541 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
\r
2542 more_supportedrates = 1;
\r
2546 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
\r
2549 //extended supported rates
\r
2550 if(more_supportedrates==1){
\r
2551 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
\r
2554 //supported channels
\r
2555 pframe = rtw_tdls_set_sup_ch(pmlmeext, pframe, pattrib);
\r
2559 pframe = rtw_set_ie(pframe, _RSN_IE_2_, sizeof(TDLS_RSNIE), TDLS_RSNIE, &(pattrib->pktlen));
\r
2561 //extended capability
\r
2562 pframe = rtw_set_ie(pframe, _EXT_CAP_IE_ , sizeof(TDLS_EXT_CAPIE), TDLS_EXT_CAPIE, &(pattrib->pktlen));
\r
2566 _rtw_memset(pframe, 0, 84); //All fields shall be set to 0
\r
2567 _rtw_memset(pframe, _FTIE_, 1); //version
\r
2568 _rtw_memset((pframe+1), 82, 1); //length
\r
2570 pattrib->pktlen += 84;
\r
2572 //Timeout interval
\r
2573 timeout_itvl[0]=0x02;
\r
2574 _rtw_memcpy(timeout_itvl+1, &timeout_interval, 4);
\r
2575 pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
\r
2578 //Sup_reg_classes(optional)
\r
2580 pframe += rtw_tdls_set_ht_cap(padapter, pframe_head - pktlen_index, pattrib);
\r
2582 //20/40 BSS coexistence
\r
2583 if(pmlmepriv->num_FortyMHzIntolerant>0)
\r
2584 iedata |= BIT(2);//20 MHz BSS Width Request
\r
2585 pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
\r
2588 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2589 _rtw_memcpy((link_id_addr+6), pattrib->dst, 6);
\r
2590 _rtw_memcpy((link_id_addr+12), pattrib->src, 6);
\r
2591 pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
\r
2595 void rtw_build_tdls_peer_traffic_indication_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
\r
2598 struct pkt_attrib *pattrib = &pxmitframe->attrib;
\r
2599 u8 payload_type = 0x02;
\r
2600 unsigned char category = RTW_WLAN_CATEGORY_TDLS;
\r
2601 unsigned char action = TDLS_PEER_TRAFFIC_INDICATION;
\r
2603 u8 link_id_addr[18] = {0};
\r
2605 struct sta_info *ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->dst);
\r
2608 pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
\r
2609 //category, action, reason code
\r
2610 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
2611 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
2612 pframe = rtw_set_fixed_ie(pframe, 1, &(ptdls_sta->dialog), &(pattrib->pktlen));
\r
2615 if(ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE){
\r
2616 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2617 _rtw_memcpy((link_id_addr+6), pattrib->dst, 6);
\r
2618 _rtw_memcpy((link_id_addr+12), pattrib->src, 6);
\r
2619 }else if(ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE){
\r
2620 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2621 _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
\r
2622 _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
\r
2624 pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
\r
2627 //PU buffer status
\r
2628 if(ptdls_sta->uapsd_bk&BIT(1))
\r
2630 if(ptdls_sta->uapsd_be&BIT(1))
\r
2632 if(ptdls_sta->uapsd_vi&BIT(1))
\r
2634 if(ptdls_sta->uapsd_vo&BIT(1))
\r
2636 pframe = rtw_set_ie(pframe, _PTI_BUFFER_STATUS_, 1, &AC_queue, &(pattrib->pktlen));
\r
2640 void rtw_build_tdls_peer_traffic_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
\r
2643 struct pkt_attrib *pattrib = &pxmitframe->attrib;
\r
2644 u8 payload_type = 0x02;
\r
2645 u8 category = RTW_WLAN_CATEGORY_TDLS;
\r
2646 u8 action = TDLS_PEER_TRAFFIC_RESPONSE;
\r
2647 u8 link_id_addr[18] = {0};
\r
2648 struct sta_info *ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->dst);
\r
2649 static u8 dialogtoken=0;
\r
2652 pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
\r
2653 //category, action, reason code
\r
2654 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
2655 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
2656 pframe = rtw_set_fixed_ie(pframe, 1, &ptdls_sta->dialog, &(pattrib->pktlen));
\r
2659 if(ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE){
\r
2660 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2661 _rtw_memcpy((link_id_addr+6), pattrib->dst, 6);
\r
2662 _rtw_memcpy((link_id_addr+12), pattrib->src, 6);
\r
2663 }else if(ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE){
\r
2664 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2665 _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
\r
2666 _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
\r
2668 pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
\r
2672 void rtw_build_tdls_ch_switch_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
\r
2675 struct pkt_attrib *pattrib = &pxmitframe->attrib;
\r
2676 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
\r
2677 u8 payload_type = 0x02;
\r
2678 unsigned char category = RTW_WLAN_CATEGORY_TDLS;
\r
2679 unsigned char action = TDLS_CHANNEL_SWITCH_REQUEST;
\r
2680 u8 link_id_addr[18] = {0};
\r
2681 struct sta_priv *pstapriv = &padapter->stapriv;
\r
2682 struct sta_info *ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst);
\r
2683 u8 ch_switch_timing[4] = {0};
\r
2684 u16 switch_time= CH_SWITCH_TIME, switch_timeout=CH_SWITCH_TIMEOUT;
\r
2687 pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
\r
2688 //category, action, target_ch
\r
2689 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
2690 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
2691 pframe = rtw_set_fixed_ie(pframe, 1, &(ptdlsinfo->candidate_ch), &(pattrib->pktlen));
\r
2694 if(ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE){
\r
2695 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2696 _rtw_memcpy((link_id_addr+6), pattrib->dst, 6);
\r
2697 _rtw_memcpy((link_id_addr+12), pattrib->src, 6);
\r
2698 }else if(ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE){
\r
2699 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2700 _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
\r
2701 _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
\r
2703 pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
\r
2705 //ch switch timing
\r
2706 _rtw_memcpy(ch_switch_timing, &switch_time, 2);
\r
2707 _rtw_memcpy(ch_switch_timing+2, &switch_timeout, 2);
\r
2708 pframe = rtw_set_ie(pframe, _CH_SWITCH_TIMING_, 4, ch_switch_timing, &(pattrib->pktlen));
\r
2710 //update ch switch attrib to sta_info
\r
2711 ptdls_sta->off_ch=ptdlsinfo->candidate_ch;
\r
2712 ptdls_sta->ch_switch_time=switch_time;
\r
2713 ptdls_sta->ch_switch_timeout=switch_timeout;
\r
2717 void rtw_build_tdls_ch_switch_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
\r
2720 struct pkt_attrib *pattrib = &pxmitframe->attrib;
\r
2721 u8 payload_type = 0x02;
\r
2722 unsigned char category = RTW_WLAN_CATEGORY_TDLS;
\r
2723 unsigned char action = TDLS_CHANNEL_SWITCH_RESPONSE;
\r
2724 u8 link_id_addr[18] = {0};
\r
2725 struct sta_priv *pstapriv = &padapter->stapriv;
\r
2726 struct sta_info *ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst);
\r
2727 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
2728 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
\r
2729 u8 ch_switch_timing[4] = {0};
\r
2732 pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
\r
2733 //category, action, status_code
\r
2734 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
2735 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
2736 pframe = rtw_set_fixed_ie(pframe, 2, (u8 *)&ptdls_sta->stat_code, &(pattrib->pktlen));
\r
2739 if(ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE){
\r
2740 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2741 _rtw_memcpy((link_id_addr+6), pattrib->dst, 6);
\r
2742 _rtw_memcpy((link_id_addr+12), pattrib->src, 6);
\r
2743 }else if(ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE){
\r
2744 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2745 _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
\r
2746 _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
\r
2748 pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
\r
2750 //ch switch timing
\r
2751 _rtw_memcpy(ch_switch_timing, &ptdls_sta->ch_switch_time, 2);
\r
2752 _rtw_memcpy(ch_switch_timing+2, &ptdls_sta->ch_switch_timeout, 2);
\r
2753 pframe = rtw_set_ie(pframe, _CH_SWITCH_TIMING_, 4, ch_switch_timing, &(pattrib->pktlen));
\r
2758 void rtw_build_tunneled_probe_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
\r
2761 struct pkt_attrib *pattrib = &pxmitframe->attrib;
\r
2762 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
\r
2763 struct wifidirect_info *pbuddy_wdinfo = &padapter->pbuddy_adapter->wdinfo;
\r
2764 u8 payload_type = 0x02;
\r
2765 u8 category = RTW_WLAN_CATEGORY_P2P;
\r
2766 u8 WFA_OUI[3] = { 0x50, 0x6f, 0x9a};
\r
2771 pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
\r
2772 //category, OUI, frame_body_type
\r
2773 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
2774 pframe = rtw_set_fixed_ie(pframe, 3, WFA_OUI, &(pattrib->pktlen));
\r
2775 pframe = rtw_set_fixed_ie(pframe, 1, &(probe_req), &(pattrib->pktlen));
\r
2777 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
2779 wfdielen = build_probe_req_wfd_ie(pwdinfo, pframe);
\r
2780 pframe += wfdielen;
\r
2781 pattrib->pktlen += wfdielen;
\r
2783 else if(!rtw_p2p_chk_state(pbuddy_wdinfo, P2P_STATE_NONE))
\r
2785 wfdielen = build_probe_req_wfd_ie(pbuddy_wdinfo, pframe);
\r
2786 pframe += wfdielen;
\r
2787 pattrib->pktlen += wfdielen;
\r
2792 void rtw_build_tunneled_probe_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
\r
2795 struct pkt_attrib *pattrib = &pxmitframe->attrib;
\r
2796 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
\r
2797 struct wifidirect_info *pbuddy_wdinfo = &padapter->pbuddy_adapter->wdinfo;
\r
2798 u8 payload_type = 0x02;
\r
2799 u8 category = RTW_WLAN_CATEGORY_P2P;
\r
2800 u8 WFA_OUI[3] = { 0x50, 0x6f, 0x9a};
\r
2805 pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
\r
2806 //category, OUI, frame_body_type
\r
2807 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
2808 pframe = rtw_set_fixed_ie(pframe, 3, WFA_OUI, &(pattrib->pktlen));
\r
2809 pframe = rtw_set_fixed_ie(pframe, 1, &(probe_rsp), &(pattrib->pktlen));
\r
2811 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
2813 wfdielen = build_probe_resp_wfd_ie(pwdinfo, pframe, 1);
\r
2814 pframe += wfdielen;
\r
2815 pattrib->pktlen += wfdielen;
\r
2817 else if(!rtw_p2p_chk_state(pbuddy_wdinfo, P2P_STATE_NONE))
\r
2819 wfdielen = build_probe_resp_wfd_ie(pbuddy_wdinfo, pframe, 1);
\r
2820 pframe += wfdielen;
\r
2821 pattrib->pktlen += wfdielen;
\r
2825 #endif //CONFIG_WFD
\r
2827 void _tdls_tpk_timer_hdl(void *FunctionContext)
\r
2829 struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
\r
2830 struct tdls_txmgmt txmgmt;
\r
2832 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
2833 ptdls_sta->TPK_count++;
\r
2834 //TPK_timer set 1000 as default
\r
2835 //retry timer should set at least 301 sec.
\r
2836 if(ptdls_sta->TPK_count==TPK_RESEND_COUNT){
\r
2837 ptdls_sta->TPK_count=0;
\r
2838 _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN);
\r
2839 issue_tdls_setup_req(ptdls_sta->padapter, &txmgmt, _FALSE);
\r
2842 _set_timer(&ptdls_sta->TPK_timer, ptdls_sta->TDLS_PeerKey_Lifetime/TPK_RESEND_COUNT);
\r
2845 // TDLS_DONE_CH_SEN: channel sensing and report candidate channel
\r
2846 // TDLS_OFF_CH: first time set channel to off channel
\r
2847 // TDLS_BASE_CH: when go back to the channel linked with AP, send null data to peer STA as an indication
\r
2848 void _tdls_ch_switch_timer_hdl(void *FunctionContext)
\r
2851 struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
\r
2852 _adapter *padapter = ptdls_sta->padapter;
\r
2854 if( ptdls_sta->option == TDLS_DONE_CH_SEN ){
\r
2855 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_DONE_CH_SEN);
\r
2856 }else if( ptdls_sta->option == TDLS_OFF_CH ){
\r
2857 issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta->hwaddr, 0, 0, 0);
\r
2858 _set_timer(&ptdls_sta->base_ch_timer, 500);
\r
2859 }else if( ptdls_sta->option == TDLS_BASE_CH){
\r
2860 issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta->hwaddr, 0, 0, 0);
\r
2864 void _tdls_base_ch_timer_hdl(void *FunctionContext)
\r
2866 struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
\r
2867 rtw_tdls_cmd(ptdls_sta->padapter, ptdls_sta->hwaddr, TDLS_P_OFF_CH);
\r
2870 void _tdls_off_ch_timer_hdl(void *FunctionContext)
\r
2872 struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
\r
2873 rtw_tdls_cmd(ptdls_sta->padapter, ptdls_sta->hwaddr, TDLS_P_BASE_CH );
\r
2876 void _tdls_handshake_timer_hdl(void *FunctionContext)
\r
2878 struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
\r
2880 if(ptdls_sta != NULL)
\r
2882 if( !(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) )
\r
2884 DBG_871X("tdls handshake time out\n");
\r
2885 rtw_tdls_cmd(ptdls_sta->padapter, ptdls_sta->hwaddr, TDLS_TEAR_STA );
\r
2890 void _tdls_pti_timer_hdl(void *FunctionContext)
\r
2892 struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
\r
2893 _adapter *padapter = ptdls_sta->padapter;
\r
2894 struct tdls_txmgmt txmgmt;
\r
2896 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
2897 _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN);
\r
2898 txmgmt.status_code = _RSON_TDLS_TEAR_TOOFAR_;
\r
2900 if(ptdls_sta != NULL)
\r
2902 if( ptdls_sta->tdls_sta_state & TDLS_WAIT_PTR_STATE )
\r
2904 DBG_871X("Doesn't receive PTR from peer dev:"MAC_FMT"; Send TDLS Tear Down\n", MAC_ARG(ptdls_sta->hwaddr));
\r
2905 issue_tdls_teardown(padapter, &txmgmt, _FALSE);
\r
2910 void rtw_init_tdls_timer(_adapter *padapter, struct sta_info *psta)
\r
2912 psta->padapter=padapter;
\r
2913 _init_timer(&psta->TPK_timer, padapter->pnetdev, _tdls_tpk_timer_hdl, psta);
\r
2914 _init_timer(&psta->option_timer, padapter->pnetdev, _tdls_ch_switch_timer_hdl, psta);
\r
2915 _init_timer(&psta->base_ch_timer, padapter->pnetdev, _tdls_base_ch_timer_hdl, psta);
\r
2916 _init_timer(&psta->off_ch_timer, padapter->pnetdev, _tdls_off_ch_timer_hdl, psta);
\r
2917 _init_timer(&psta->handshake_timer, padapter->pnetdev, _tdls_handshake_timer_hdl, psta);
\r
2918 _init_timer(&psta->pti_timer, padapter->pnetdev, _tdls_pti_timer_hdl, psta);
\r
2921 void rtw_free_tdls_timer(struct sta_info *psta)
\r
2923 _cancel_timer_ex(&psta->TPK_timer);
\r
2924 _cancel_timer_ex(&psta->option_timer);
\r
2925 _cancel_timer_ex(&psta->base_ch_timer);
\r
2926 _cancel_timer_ex(&psta->off_ch_timer);
\r
2927 _cancel_timer_ex(&psta->handshake_timer);
\r
2928 _cancel_timer_ex(&psta->pti_timer);
\r
2931 u8 update_sgi_tdls(_adapter *padapter, struct sta_info *psta)
\r
2933 return query_ra_short_GI(psta);
\r
2936 u32 update_mask_tdls(_adapter *padapter, struct sta_info *psta)
\r
2938 unsigned char sta_band = 0;
\r
2939 unsigned int tx_ra_bitmap=0;
\r
2940 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2941 WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
\r
2943 rtw_hal_update_sta_rate_mask(padapter, psta);
\r
2944 tx_ra_bitmap = psta->ra_mask;
\r
2946 if ( pcur_network->Configuration.DSConfig > 14 ) {
\r
2948 if (tx_ra_bitmap & 0xffff000)
\r
2949 sta_band |= WIRELESS_11_5N | WIRELESS_11A;
\r
2951 sta_band |= WIRELESS_11A;
\r
2953 if (tx_ra_bitmap & 0xffff000)
\r
2954 sta_band |= WIRELESS_11_24N | WIRELESS_11G | WIRELESS_11B;
\r
2955 else if (tx_ra_bitmap & 0xff0)
\r
2956 sta_band |= WIRELESS_11G |WIRELESS_11B;
\r
2958 sta_band |= WIRELESS_11B;
\r
2961 psta->wireless_mode = sta_band;
\r
2963 psta->raid = rtw_hal_networktype_to_raid(padapter,psta);
\r
2964 tx_ra_bitmap |= ((psta->raid<<28)&0xf0000000);
\r
2965 return tx_ra_bitmap;
\r
2968 #endif //CONFIG_TDLS
\r