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 void process_wmmps_data(_adapter *padapter, union recv_frame *precv_frame);
\r
27 void rtw_reset_tdls_info(_adapter* padapter)
\r
29 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
\r
31 ptdlsinfo->ap_prohibited = _FALSE;
\r
32 ptdlsinfo->link_established = _FALSE;
\r
33 ptdlsinfo->sta_cnt = 0;
\r
34 ptdlsinfo->sta_maximum = _FALSE;
\r
35 ptdlsinfo->ch_sensing = 0;
\r
36 ptdlsinfo->cur_channel = 0;
\r
37 ptdlsinfo->candidate_ch = 1; //when inplement channel switching, default candidate channel is 1
\r
38 ptdlsinfo->watchdog_count = 0;
\r
39 ptdlsinfo->dev_discovered = 0;
\r
42 ptdlsinfo->wfd_info = &padapter->wfd_info;
\r
46 int rtw_init_tdls_info(_adapter* padapter)
\r
49 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
\r
51 ptdlsinfo->tdls_enable = _TRUE;
\r
52 rtw_reset_tdls_info(padapter);
\r
54 _rtw_spinlock_init(&ptdlsinfo->cmd_lock);
\r
55 _rtw_spinlock_init(&ptdlsinfo->hdl_lock);
\r
61 void rtw_free_tdls_info(struct tdls_info *ptdlsinfo)
\r
63 _rtw_spinlock_free(&ptdlsinfo->cmd_lock);
\r
64 _rtw_spinlock_free(&ptdlsinfo->hdl_lock);
\r
66 _rtw_memset(ptdlsinfo, 0, sizeof(struct tdls_info) );
\r
70 int _issue_nulldata_to_TDLS_peer_STA(_adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack)
\r
73 struct xmit_frame *pmgntframe;
\r
74 struct pkt_attrib *pattrib;
\r
75 unsigned char *pframe;
\r
76 struct rtw_ieee80211_hdr *pwlanhdr;
\r
77 unsigned short *fctrl;
\r
78 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
79 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
80 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
82 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
88 pattrib = &pmgntframe->attrib;
\r
89 update_mgntframe_attrib(padapter, pattrib);
\r
90 pattrib->retry_ctrl = _FALSE;
\r
92 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
94 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
95 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
97 fctrl = &(pwlanhdr->frame_ctl);
\r
107 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
\r
108 _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
109 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
\r
111 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
\r
112 pmlmeext->mgnt_seq++;
\r
113 SetFrameSubType(pframe, WIFI_DATA_NULL);
\r
115 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
\r
116 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
\r
118 pattrib->last_txcmdsz = pattrib->pktlen;
\r
122 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
\r
126 dump_mgntframe(padapter, pmgntframe);
\r
135 int issue_nulldata_to_TDLS_peer_STA(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
\r
139 u32 start = rtw_get_current_time();
\r
140 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
141 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
143 //[TDLS] UAPSD : merge this from issue_nulldata() and mark it first.
\r
145 psta = rtw_get_stainfo(&padapter->stapriv, da);
\r
148 rtw_hal_macid_sleep(padapter, psta->mac_id);
\r
150 rtw_hal_macid_wakeup(padapter, psta->mac_id);
\r
152 DBG_871X(FUNC_ADPT_FMT ": Can't find sta info for " MAC_FMT ", skip macid %s!!\n",
\r
153 FUNC_ADPT_ARG(padapter), MAC_ARG(da), power_mode?"sleep":"wakeup");
\r
160 ret = _issue_nulldata_to_TDLS_peer_STA(padapter, da, power_mode, wait_ms>0 ? _TRUE : _FALSE);
\r
164 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
\r
167 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
\r
168 rtw_msleep_os(wait_ms);
\r
170 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
\r
172 if (ret != _FAIL) {
\r
174 #ifndef DBG_XMIT_ACK
\r
179 if (try_cnt && wait_ms) {
\r
181 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
\r
182 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
\r
183 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
\r
185 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
\r
186 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
\r
187 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
\r
193 void free_tdls_sta(_adapter *padapter, struct sta_info *ptdls_sta)
\r
195 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
\r
196 struct sta_priv *pstapriv = &padapter->stapriv;
\r
199 //free peer sta_info
\r
200 _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
\r
201 if(ptdlsinfo->sta_cnt != 0)
\r
202 ptdlsinfo->sta_cnt--;
\r
203 _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
\r
204 if( ptdlsinfo->sta_cnt < (NUM_STA - 2 - 4) ) // -2: AP + BC/MC sta, -4: default key
\r
206 ptdlsinfo->sta_maximum = _FALSE;
\r
207 _rtw_memset( &ptdlsinfo->ss_record, 0x00, sizeof(struct tdls_ss_record) );
\r
211 rtw_clearstakey_cmd(padapter, ptdls_sta, _TRUE);
\r
213 if(ptdlsinfo->sta_cnt==0){
\r
214 rtw_tdls_cmd(padapter, myid(&(padapter->eeprompriv)), TDLS_RS_RCR);
\r
215 ptdlsinfo->link_established = _FALSE;
\r
218 DBG_871X("Remain tdls sta:%02x\n", ptdlsinfo->sta_cnt);
\r
220 rtw_free_stainfo(padapter, ptdls_sta);
\r
225 //TDLS encryption(if needed) will always be CCMP
\r
226 void rtw_tdls_set_key(_adapter *padapter, struct rx_pkt_attrib *prx_pkt_attrib, struct sta_info *ptdls_sta)
\r
228 if(prx_pkt_attrib->encrypt)
\r
230 ptdls_sta->dot118021XPrivacy=_AES_;
\r
231 rtw_setstakey_cmd(padapter, ptdls_sta, _TRUE, _TRUE);
\r
235 void rtw_tdls_process_ht_cap(_adapter *padapter, struct sta_info *ptdls_sta, u8 *data, u8 Length)
\r
237 /* save HT capabilities in the sta object */
\r
238 _rtw_memset(&ptdls_sta->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap));
\r
239 if (data && Length >= sizeof(struct rtw_ieee80211_ht_cap) )
\r
241 ptdls_sta->flags |= WLAN_STA_HT;
\r
243 ptdls_sta->flags |= WLAN_STA_WME;
\r
245 _rtw_memcpy(&ptdls_sta->htpriv.ht_cap, data, sizeof(struct rtw_ieee80211_ht_cap));
\r
248 ptdls_sta->flags &= ~WLAN_STA_HT;
\r
250 if(ptdls_sta->flags & WLAN_STA_HT)
\r
252 if(padapter->registrypriv.ht_enable == _TRUE)
\r
254 ptdls_sta->htpriv.ht_option = _TRUE;
\r
258 ptdls_sta->htpriv.ht_option = _FALSE;
\r
259 ptdls_sta->stat_code = _STATS_FAILURE_;
\r
264 if(ptdls_sta->htpriv.ht_option)
\r
266 //check if sta supports rx ampdu
\r
267 if(padapter->registrypriv.ampdu_enable==1)
\r
268 ptdls_sta->htpriv.ampdu_enable = _TRUE;
\r
270 //check if sta support s Short GI 20M
\r
271 if(ptdls_sta->htpriv.ht_cap.cap_info & cpu_to_le16(IEEE80211_HT_CAP_SGI_20))
\r
273 ptdls_sta->htpriv.sgi_20m = _TRUE;
\r
275 //check if sta support s Short GI 40M
\r
276 if(ptdls_sta->htpriv.ht_cap.cap_info & cpu_to_le16(IEEE80211_HT_CAP_SGI_40))
\r
278 ptdls_sta->htpriv.sgi_40m = _TRUE;
\r
281 // bwmode would still followed AP's setting
\r
282 if(ptdls_sta->htpriv.ht_cap.cap_info & cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH))
\r
284 if (padapter->mlmeextpriv.cur_bwmode >= CHANNEL_WIDTH_40)
\r
285 ptdls_sta->bw_mode = CHANNEL_WIDTH_40;
\r
286 ptdls_sta->htpriv.ch_offset = padapter->mlmeextpriv.cur_ch_offset;
\r
292 int rtw_tdls_set_ht_cap(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib)
\r
296 rtw_ht_use_default_setting(padapter);
\r
298 tmplen = pattrib->pktlen;
\r
299 rtw_restructure_ht_ie(padapter, NULL, pframe, 0, &(pattrib->pktlen), padapter->mlmeextpriv.cur_channel);
\r
301 return (pattrib->pktlen - tmplen);
\r
305 u8 *rtw_tdls_set_sup_ch(struct mlme_ext_priv *pmlmeext, u8 *pframe, struct pkt_attrib *pattrib)
\r
307 u8 sup_ch[ 30 * 2 ] = { 0x00 }, ch_set_idx = 0; //For supported channel
\r
308 u8 ch_24g = 0, b1 = 0, b4 = 0;
\r
309 u8 bit_table = 0, sup_ch_idx = 0;
\r
312 if( pmlmeext->channel_set[ch_set_idx].ChannelNum >= 1 &&
\r
313 pmlmeext->channel_set[ch_set_idx].ChannelNum <= 14 )
\r
315 ch_24g = 1; // 2.4 G channels
\r
317 else if( pmlmeext->channel_set[ch_set_idx].ChannelNum >= 36 &&
\r
318 pmlmeext->channel_set[ch_set_idx].ChannelNum <= 48)
\r
320 b1 = 1; // 5 G band1
\r
322 else if( pmlmeext->channel_set[ch_set_idx].ChannelNum >= 149 &&
\r
323 pmlmeext->channel_set[ch_set_idx].ChannelNum <= 165)
\r
325 b4 = 1; // 5 G band4
\r
329 ch_set_idx++; // We don't claim that we support DFS channels.
\r
333 sup_ch_idx = (ch_24g + b1 + b4 - 1) * 2;
\r
334 if( sup_ch_idx >= 0)
\r
336 if(sup_ch[sup_ch_idx] == 0)
\r
337 sup_ch[sup_ch_idx] = pmlmeext->channel_set[ch_set_idx].ChannelNum;
\r
338 sup_ch[sup_ch_idx+1]++; //Number of channel
\r
343 while( pmlmeext->channel_set[ch_set_idx].ChannelNum != 0 && ch_set_idx < MAX_CHANNEL_NUM );
\r
345 return(rtw_set_ie(pframe, _SUPPORTED_CH_IE_, sup_ch_idx+2, sup_ch, &(pattrib->pktlen)));
\r
349 void rtw_tdls_process_wfd_ie(struct tdls_info *ptdlsinfo, u8 *ptr, u8 length)
\r
351 u8 wfd_ie[ 128 ] = { 0x00 };
\r
353 u32 wfd_offset = 0;
\r
354 // Try to get the TCP port information when receiving the negotiation response.
\r
358 wfd_offset = rtw_get_wfd_ie( ptr + wfd_offset, length - wfd_offset, wfd_ie, &wfd_ielen );
\r
359 while( wfd_offset )
\r
361 u8 attr_content[ 10 ] = { 0x00 };
\r
362 u32 attr_contentlen = 0;
\r
365 DBG_871X( "[%s] WFD IE Found!!\n", __FUNCTION__ );
\r
366 rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen);
\r
367 if ( attr_contentlen )
\r
369 ptdlsinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16( attr_content + 2 );
\r
370 DBG_871X( "[%s] Peer PORT NUM = %d\n", __FUNCTION__, ptdlsinfo->wfd_info->peer_rtsp_ctrlport );
\r
373 _rtw_memset( attr_content, 0x00, 10);
\r
374 attr_contentlen = 0;
\r
375 rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_LOCAL_IP_ADDR, attr_content, &attr_contentlen);
\r
376 if ( attr_contentlen )
\r
378 _rtw_memcpy(ptdlsinfo->wfd_info->peer_ip_address, ( attr_content + 1 ), 4);
\r
379 DBG_871X( "[%s] Peer IP = %02u.%02u.%02u.%02u \n", __FUNCTION__,
\r
380 ptdlsinfo->wfd_info->peer_ip_address[0], ptdlsinfo->wfd_info->peer_ip_address[1],
\r
381 ptdlsinfo->wfd_info->peer_ip_address[2], ptdlsinfo->wfd_info->peer_ip_address[3]
\r
384 wfd_offset = rtw_get_wfd_ie( ptr + wfd_offset, length - wfd_offset, wfd_ie, &wfd_ielen );
\r
388 int issue_tunneled_probe_req(_adapter *padapter)
\r
390 struct xmit_frame *pmgntframe;
\r
391 struct pkt_attrib *pattrib;
\r
392 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
393 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
394 u8 baddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
\r
395 struct tdls_txmgmt txmgmt;
\r
398 DBG_871X("[%s]\n", __FUNCTION__);
\r
400 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
401 txmgmt.action_code = TUNNELED_PROBE_REQ;
\r
403 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
409 pattrib = &pmgntframe->attrib;
\r
411 pmgntframe->frame_tag = DATA_FRAMETAG;
\r
412 pattrib->ether_type = 0x890d;
\r
414 _rtw_memcpy(pattrib->dst, baddr, ETH_ALEN);
\r
415 _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
416 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
\r
417 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
\r
419 update_tdls_attrib(padapter, pattrib);
\r
420 pattrib->qsel = pattrib->priority;
\r
421 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, &txmgmt) != _SUCCESS) {
\r
422 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
\r
423 rtw_free_xmitframe(pxmitpriv, pmgntframe);
\r
426 dump_mgntframe(padapter, pmgntframe);
\r
433 int issue_tunneled_probe_rsp(_adapter *padapter, union recv_frame *precv_frame)
\r
435 struct xmit_frame *pmgntframe;
\r
436 struct pkt_attrib *pattrib;
\r
437 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
438 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
439 struct tdls_txmgmt txmgmt;
\r
442 DBG_871X("[%s]\n", __FUNCTION__);
\r
444 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
445 txmgmt.action_code = TUNNELED_PROBE_RSP;
\r
447 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
453 pattrib = &pmgntframe->attrib;
\r
455 pmgntframe->frame_tag = DATA_FRAMETAG;
\r
456 pattrib->ether_type = 0x890d;
\r
458 _rtw_memcpy(pattrib->dst, precv_frame->u.hdr.attrib.src, ETH_ALEN);
\r
459 _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
460 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
\r
461 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
\r
463 update_tdls_attrib(padapter, pattrib);
\r
464 pattrib->qsel = pattrib->priority;
\r
465 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, &txmgmt) != _SUCCESS) {
\r
466 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
\r
467 rtw_free_xmitframe(pxmitpriv, pmgntframe);
\r
470 dump_mgntframe(padapter, pmgntframe);
\r
476 #endif //CONFIG_WFD
\r
478 int issue_tdls_setup_req(_adapter *padapter, struct tdls_txmgmt *ptxmgmt, int wait_ack)
\r
480 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
\r
481 struct xmit_frame *pmgntframe;
\r
482 struct pkt_attrib *pattrib;
\r
483 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
484 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
485 struct sta_priv *pstapriv = &padapter->stapriv;
\r
486 struct sta_info *ptdls_sta= NULL;
\r
488 static u8 dialogtoken = 0;
\r
490 u32 timeout_interval= TPK_RESEND_COUNT * 1000; //retry timer should set at least 301 sec, using TPK_count counting 301 times.
\r
492 ptxmgmt->action_code = TDLS_SETUP_REQUEST;
\r
493 if(ptdlsinfo->ap_prohibited == _TRUE)
\r
496 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
502 pattrib = &pmgntframe->attrib;
\r
503 pmgntframe->frame_tag = DATA_FRAMETAG;
\r
504 pattrib->ether_type = 0x890d;
\r
506 _rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN);
\r
507 _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
508 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
\r
509 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
\r
511 update_tdls_attrib(padapter, pattrib);
\r
513 //init peer sta_info
\r
514 ptdls_sta = rtw_get_stainfo(pstapriv, ptxmgmt->peer);
\r
515 if(ptdls_sta==NULL)
\r
517 ptdls_sta = rtw_alloc_stainfo(pstapriv, ptxmgmt->peer);
\r
518 if(ptdls_sta==NULL)
\r
520 DBG_871X("[%s] rtw_alloc_stainfo fail\n", __FUNCTION__);
\r
521 rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf);
\r
522 rtw_free_xmitframe(pxmitpriv, pmgntframe);
\r
527 if(!(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE))
\r
528 ptdlsinfo->sta_cnt++;
\r
529 if( ptdlsinfo->sta_cnt == (NUM_STA - 2 - 4) ) // -2: AP + BC/MC sta, -4: default key
\r
531 ptdlsinfo->sta_maximum = _TRUE;
\r
534 ptdls_sta->tdls_sta_state |= TDLS_RESPONDER_STATE;
\r
535 //for tdls; ptdls_sta->aid is used to fill dialogtoken
\r
536 ptdls_sta->dialog = dialogtoken;
\r
537 dialogtoken = (dialogtoken+1)%256;
\r
538 ptdls_sta->TDLS_PeerKey_Lifetime = timeout_interval;
\r
539 _set_timer( &ptdls_sta->handshake_timer, TDLS_HANDSHAKE_TIME );
\r
541 pattrib->qsel = pattrib->priority;
\r
543 if(rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) !=_SUCCESS ){
\r
544 rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf);
\r
545 rtw_free_xmitframe(pxmitpriv, pmgntframe);
\r
550 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
\r
552 dump_mgntframe(padapter, pmgntframe);
\r
563 int issue_tdls_teardown(_adapter *padapter, struct tdls_txmgmt *ptxmgmt, u8 wait_ack)
\r
565 struct xmit_frame *pmgntframe;
\r
566 struct pkt_attrib *pattrib;
\r
567 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
568 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
569 struct sta_priv *pstapriv = &padapter->stapriv;
\r
570 struct sta_info *ptdls_sta=NULL;
\r
574 ptxmgmt->action_code = TDLS_TEARDOWN;
\r
575 ptdls_sta = rtw_get_stainfo(pstapriv, ptxmgmt->peer);
\r
576 if(ptdls_sta==NULL){
\r
577 DBG_871X("Np tdls_sta for tearing down\n");
\r
581 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
587 pattrib = &pmgntframe->attrib;
\r
589 pmgntframe->frame_tag = DATA_FRAMETAG;
\r
590 pattrib->ether_type = 0x890d;
\r
592 _rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN);
\r
593 _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
594 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
\r
595 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
\r
597 update_tdls_attrib(padapter, pattrib);
\r
598 pattrib->qsel = pattrib->priority;
\r
599 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) != _SUCCESS) {
\r
600 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
\r
601 rtw_free_xmitframe(pxmitpriv, pmgntframe);
\r
606 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
\r
608 dump_mgntframe(padapter, pmgntframe);
\r
612 if(ret == _SUCCESS)
\r
614 if(ptdls_sta->tdls_sta_state & TDLS_CH_SWITCH_ON_STATE){
\r
615 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CS_OFF);
\r
618 if( ptdls_sta->timer_flag == 1 )
\r
620 _enter_critical_bh(&(padapter->tdlsinfo.hdl_lock), &irqL);
\r
621 ptdls_sta->timer_flag = 2;
\r
622 _exit_critical_bh(&(padapter->tdlsinfo.hdl_lock), &irqL);
\r
625 rtw_tdls_cmd(padapter, ptxmgmt->peer, TDLS_TEAR_STA );
\r
633 int issue_tdls_dis_req(_adapter *padapter, struct tdls_txmgmt *ptxmgmt)
\r
635 struct xmit_frame *pmgntframe;
\r
636 struct pkt_attrib *pattrib;
\r
637 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
638 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
641 ptxmgmt->action_code = TDLS_DISCOVERY_REQUEST;
\r
642 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
648 pattrib = &pmgntframe->attrib;
\r
649 pmgntframe->frame_tag = DATA_FRAMETAG;
\r
650 pattrib->ether_type = 0x890d;
\r
652 _rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN);
\r
653 _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
654 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
\r
655 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
\r
657 update_tdls_attrib(padapter, pattrib);
\r
658 pattrib->qsel = pattrib->priority;
\r
659 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) != _SUCCESS) {
\r
660 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
\r
661 rtw_free_xmitframe(pxmitpriv, pmgntframe);
\r
664 dump_mgntframe(padapter, pmgntframe);
\r
665 DBG_871X("issue tdls dis req\n");
\r
673 int issue_tdls_setup_rsp(_adapter *padapter, struct tdls_txmgmt *ptxmgmt)
\r
675 struct xmit_frame *pmgntframe;
\r
676 struct pkt_attrib *pattrib;
\r
677 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
680 ptxmgmt->action_code = TDLS_SETUP_RESPONSE;
\r
681 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
687 pattrib = &pmgntframe->attrib;
\r
688 pmgntframe->frame_tag = DATA_FRAMETAG;
\r
689 pattrib->ether_type = 0x890d;
\r
691 _rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN);
\r
692 _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
693 _rtw_memcpy(pattrib->ra, get_bssid(&(padapter->mlmepriv)), ETH_ALEN);
\r
694 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
\r
696 update_tdls_attrib(padapter, pattrib);
\r
697 pattrib->qsel = pattrib->priority;
\r
698 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) != _SUCCESS) {
\r
699 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
\r
700 rtw_free_xmitframe(pxmitpriv, pmgntframe);
\r
704 dump_mgntframe(padapter, pmgntframe);
\r
713 int issue_tdls_setup_cfm(_adapter *padapter, struct tdls_txmgmt *ptxmgmt)
\r
715 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
\r
716 struct xmit_frame *pmgntframe;
\r
717 struct pkt_attrib *pattrib;
\r
718 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
721 ptxmgmt->action_code = TDLS_SETUP_CONFIRM;
\r
722 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
728 pattrib = &pmgntframe->attrib;
\r
729 pmgntframe->frame_tag = DATA_FRAMETAG;
\r
730 pattrib->ether_type = 0x890d;
\r
732 _rtw_memcpy(pattrib->dst, ptxmgmt->peer, ETH_ALEN);
\r
733 _rtw_memcpy(pattrib->src, myid(&padapter->eeprompriv), ETH_ALEN);
\r
734 _rtw_memcpy(pattrib->ra, get_bssid(&padapter->mlmepriv), ETH_ALEN);
\r
735 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
\r
737 update_tdls_attrib(padapter, pattrib);
\r
738 pattrib->qsel = pattrib->priority;
\r
739 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, ptxmgmt) != _SUCCESS) {
\r
740 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
\r
741 rtw_free_xmitframe(pxmitpriv, pmgntframe);
\r
745 dump_mgntframe(padapter, pmgntframe);
\r
754 //TDLS Discovery Response frame is a management action frame
\r
755 int issue_tdls_dis_rsp(_adapter *padapter, struct tdls_txmgmt *ptxmgmt, u8 privacy)
\r
757 struct xmit_frame *pmgntframe;
\r
758 struct pkt_attrib *pattrib;
\r
759 unsigned char *pframe;
\r
760 struct rtw_ieee80211_hdr *pwlanhdr;
\r
761 unsigned short *fctrl;
\r
762 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
763 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
766 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
772 pattrib = &pmgntframe->attrib;
\r
773 update_mgntframe_attrib(padapter, pattrib);
\r
775 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
777 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
778 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
780 fctrl = &(pwlanhdr->frame_ctl);
\r
783 // unicast probe request frame
\r
784 _rtw_memcpy(pwlanhdr->addr1, ptxmgmt->peer, ETH_ALEN);
\r
785 _rtw_memcpy(pattrib->dst, pwlanhdr->addr1, ETH_ALEN);
\r
786 _rtw_memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
\r
787 _rtw_memcpy(pattrib->src, pwlanhdr->addr2, ETH_ALEN);
\r
788 _rtw_memcpy(pwlanhdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN);
\r
789 _rtw_memcpy(pattrib->ra, pwlanhdr->addr3, ETH_ALEN);
\r
791 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
\r
792 pmlmeext->mgnt_seq++;
\r
793 SetFrameSubType(pframe, WIFI_ACTION);
\r
795 pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
\r
796 pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
\r
798 rtw_build_tdls_dis_rsp_ies(padapter, pmgntframe, pframe, ptxmgmt->dialog_token, privacy);
\r
800 pattrib->nr_frags = 1;
\r
801 pattrib->last_txcmdsz = pattrib->pktlen;
\r
803 dump_mgntframe(padapter, pmgntframe);
\r
810 int issue_tdls_peer_traffic_rsp(_adapter *padapter, struct sta_info *ptdls_sta)
\r
812 struct xmit_frame *pmgntframe;
\r
813 struct pkt_attrib *pattrib;
\r
814 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
815 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
816 struct tdls_txmgmt txmgmt;
\r
819 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
820 txmgmt.action_code = TDLS_PEER_TRAFFIC_RESPONSE;
\r
822 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
828 pattrib = &pmgntframe->attrib;
\r
830 pmgntframe->frame_tag = DATA_FRAMETAG;
\r
831 pattrib->ether_type = 0x890d;
\r
833 _rtw_memcpy(pattrib->dst, ptdls_sta->hwaddr, ETH_ALEN);
\r
834 _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
835 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
\r
836 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
\r
838 update_tdls_attrib(padapter, pattrib);
\r
839 pattrib->qsel = pattrib->priority;
\r
841 if(rtw_xmit_tdls_coalesce(padapter, pmgntframe, &txmgmt) !=_SUCCESS ){
\r
842 rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf);
\r
843 rtw_free_xmitframe(pxmitpriv, pmgntframe);
\r
847 dump_mgntframe(padapter, pmgntframe);
\r
855 int issue_tdls_peer_traffic_indication(_adapter *padapter, struct sta_info *ptdls_sta)
\r
857 struct xmit_frame *pmgntframe;
\r
858 struct pkt_attrib *pattrib;
\r
859 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
860 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
861 struct tdls_txmgmt txmgmt;
\r
863 static u8 dialogtoken=0;
\r
865 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
866 txmgmt.action_code = TDLS_PEER_TRAFFIC_INDICATION;
\r
868 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
874 pattrib = &pmgntframe->attrib;
\r
876 pmgntframe->frame_tag = DATA_FRAMETAG;
\r
877 pattrib->ether_type = 0x890d;
\r
879 _rtw_memcpy(pattrib->dst, ptdls_sta->hwaddr, ETH_ALEN);
\r
880 _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
881 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
\r
882 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
\r
884 //for tdls; pattrib->nr_frags is used to fill dialogtoken
\r
885 ptdls_sta->dialog = dialogtoken;
\r
886 dialogtoken = (dialogtoken+1)%256;
\r
887 //PTI frame's priority should be AC_VO
\r
888 pattrib->priority = 7;
\r
890 update_tdls_attrib(padapter, pattrib);
\r
891 pattrib->qsel = pattrib->priority;
\r
892 if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, &txmgmt) != _SUCCESS) {
\r
893 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
\r
894 rtw_free_xmitframe(pxmitpriv, pmgntframe);
\r
898 dump_mgntframe(padapter, pmgntframe);
\r
906 int issue_tdls_ch_switch_req(_adapter *padapter, u8 *mac_addr)
\r
908 struct xmit_frame *pmgntframe;
\r
909 struct pkt_attrib *pattrib;
\r
910 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
911 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
912 struct tdls_txmgmt txmgmt;
\r
915 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
916 txmgmt.action_code = TDLS_CHANNEL_SWITCH_REQUEST;
\r
918 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
924 pattrib = &pmgntframe->attrib;
\r
926 pmgntframe->frame_tag = DATA_FRAMETAG;
\r
927 pattrib->ether_type = 0x890d;
\r
929 _rtw_memcpy(pattrib->dst, mac_addr, ETH_ALEN);
\r
930 _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
931 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
\r
932 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
\r
934 update_tdls_attrib(padapter, pattrib);
\r
935 pattrib->qsel = pattrib->priority;
\r
936 if(rtw_xmit_tdls_coalesce(padapter, pmgntframe, &txmgmt) !=_SUCCESS ){
\r
937 rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf);
\r
938 rtw_free_xmitframe(pxmitpriv, pmgntframe);
\r
942 dump_mgntframe(padapter, pmgntframe);
\r
949 int issue_tdls_ch_switch_rsp(_adapter *padapter, u8 *mac_addr)
\r
951 struct xmit_frame *pmgntframe;
\r
952 struct pkt_attrib *pattrib;
\r
953 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
954 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
955 struct tdls_txmgmt txmgmt;
\r
958 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
959 txmgmt.action_code = TDLS_CHANNEL_SWITCH_RESPONSE;
\r
961 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
967 pattrib = &pmgntframe->attrib;
\r
969 pmgntframe->frame_tag = DATA_FRAMETAG;
\r
970 pattrib->ether_type = 0x890d;
\r
972 _rtw_memcpy(pattrib->dst, mac_addr, ETH_ALEN);
\r
973 _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
974 _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
\r
975 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
\r
977 update_tdls_attrib(padapter, pattrib);
\r
978 pattrib->qsel = pattrib->priority;
\r
980 _enter_critical_bh(&pxmitpriv->lock, &irqL);
\r
981 if(xmitframe_enqueue_for_tdls_sleeping_sta(padapter, pmgntframe)==_TRUE){
\r
982 _exit_critical_bh(&pxmitpriv->lock, &irqL);
\r
986 if(rtw_xmit_tdls_coalesce(padapter, pmgntframe, &txmgmt) !=_SUCCESS ){
\r
987 rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf);
\r
988 rtw_free_xmitframe(pxmitpriv, pmgntframe);
\r
991 dump_mgntframe(padapter, pmgntframe);
\r
998 int On_TDLS_Dis_Rsp(_adapter *padapter, union recv_frame *precv_frame)
\r
1000 struct sta_info *ptdls_sta = NULL, *psta = rtw_get_stainfo(&(padapter->stapriv), get_bssid(&(padapter->mlmepriv)));
\r
1001 struct recv_priv *precvpriv = &(padapter->recvpriv);
\r
1002 u8 *ptr = precv_frame->u.hdr.rx_data, *psa;
\r
1003 struct rx_pkt_attrib *pattrib = &(precv_frame->u.hdr.attrib);
\r
1004 struct tdls_info *ptdlsinfo = &(padapter->tdlsinfo);
\r
1005 u8 empty_addr[ETH_ALEN] = { 0x00 };
\r
1006 int UndecoratedSmoothedPWDB;
\r
1007 struct tdls_txmgmt txmgmt;
\r
1008 int ret = _SUCCESS;
\r
1010 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
1011 //WFDTDLS: for sigma test, not to setup direct link automatically
\r
1012 ptdlsinfo->dev_discovered = 1;
\r
1014 #ifdef CONFIG_TDLS_AUTOSETUP
\r
1015 psa = get_sa(ptr);
\r
1016 ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), psa);
\r
1018 if(ptdls_sta != NULL)
\r
1020 ptdls_sta->tdls_sta_state |= TDLS_ALIVE_STATE;
\r
1022 //Record the tdls sta with lowest signal strength
\r
1023 if( (ptdlsinfo->sta_maximum == _TRUE) && (ptdls_sta->alive_count >= 1) )
\r
1025 if( _rtw_memcmp(ptdlsinfo->ss_record.macaddr, empty_addr, ETH_ALEN) )
\r
1027 _rtw_memcpy(ptdlsinfo->ss_record.macaddr, psa, ETH_ALEN);
\r
1028 ptdlsinfo->ss_record.RxPWDBAll = pattrib->RxPWDBAll;
\r
1032 if( ptdlsinfo->ss_record.RxPWDBAll < pattrib->RxPWDBAll )
\r
1034 _rtw_memcpy(ptdlsinfo->ss_record.macaddr, psa, ETH_ALEN);
\r
1035 ptdlsinfo->ss_record.RxPWDBAll = pattrib->RxPWDBAll;
\r
1043 if( ptdlsinfo->sta_maximum == _TRUE)
\r
1045 if( _rtw_memcmp( ptdlsinfo->ss_record.macaddr, empty_addr, ETH_ALEN ) )
\r
1047 //All traffics are busy, do not set up another direct link.
\r
1053 if( pattrib->RxPWDBAll > ptdlsinfo->ss_record.RxPWDBAll )
\r
1055 _rtw_memcpy(txmgmt.peer, ptdlsinfo->ss_record.macaddr, ETH_ALEN);
\r
1056 //issue_tdls_teardown(padapter, ptdlsinfo->ss_record.macaddr, _FALSE);
\r
1066 padapter->HalFunc.GetHalDefVarHandler(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
\r
1068 if( pattrib->RxPWDBAll + TDLS_SIGNAL_THRESH >= UndecoratedSmoothedPWDB);
\r
1070 DBG_871X("pattrib->RxPWDBAll=%d, pdmpriv->UndecoratedSmoothedPWDB=%d\n", pattrib->RxPWDBAll, UndecoratedSmoothedPWDB);
\r
1071 _rtw_memcpy(txmgmt.peer, psa, ETH_ALEN);
\r
1072 issue_tdls_setup_req(padapter, &txmgmt, _FALSE);
\r
1075 #endif //CONFIG_TDLS_AUTOSETUP
\r
1082 sint On_TDLS_Setup_Req(_adapter *padapter, union recv_frame *precv_frame)
\r
1084 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
\r
1086 struct sta_info *ptdls_sta= NULL;
\r
1087 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1088 u8 *ptr = precv_frame->u.hdr.rx_data;
\r
1089 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
1090 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
1092 struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
\r
1093 u8 *prsnie, *ppairwise_cipher;
\r
1095 u8 ccmp_included=0, rsnie_included=0;
\r
1096 u16 j, pairwise_count;
\r
1098 u32 *timeout_interval=NULL;
\r
1099 sint parsing_length; //frame body length, without icv_len
\r
1100 PNDIS_802_11_VARIABLE_IEs pIE;
\r
1102 unsigned char supportRate[16];
\r
1103 int supportRateNum = 0;
\r
1104 struct tdls_txmgmt txmgmt;
\r
1106 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
1107 psa = get_sa(ptr);
\r
1108 ptdls_sta = rtw_get_stainfo(pstapriv, psa);
\r
1110 pmyid=myid(&(padapter->eeprompriv));
\r
1111 ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1;
\r
1112 parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
\r
1113 -prx_pkt_attrib->hdrlen
\r
1114 -prx_pkt_attrib->iv_len
\r
1115 -prx_pkt_attrib->icv_len
\r
1121 if(ptdlsinfo->ap_prohibited == _TRUE)
\r
1126 if(ptdls_sta==NULL){
\r
1127 ptdls_sta = rtw_alloc_stainfo(pstapriv, psa);
\r
1129 if(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE){
\r
1130 //If the direct link is already set up
\r
1131 //Process as re-setup after tear down
\r
1132 DBG_871X("re-setup a direct link\n");
\r
1134 //already receiving TDLS setup request
\r
1135 else if(ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE){
\r
1136 DBG_871X("receive duplicated TDLS setup request frame in handshaking\n");
\r
1139 //When receiving and sending setup_req to the same link at the same time, STA with higher MAC_addr would be initiator
\r
1140 //following is to check out MAC_addr
\r
1141 else if(ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE){
\r
1142 DBG_871X("receive setup_req after sending setup_req\n");
\r
1143 for (i=0;i<6;i++){
\r
1144 if(*(pmyid+i)==*(psa+i)){
\r
1146 else if(*(pmyid+i)>*(psa+i)){
\r
1147 ptdls_sta->tdls_sta_state=TDLS_INITIATOR_STATE;
\r
1149 }else if(*(pmyid+i)<*(psa+i)){
\r
1158 ptdls_sta->dialog = *(ptr+2); //copy dialog token
\r
1159 ptdls_sta->stat_code = 0;
\r
1161 //parsing information element
\r
1162 for(j=FIXED_IE; j<parsing_length;){
\r
1164 pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
\r
1166 switch (pIE->ElementID)
\r
1168 case _SUPPORTEDRATES_IE_:
\r
1169 _rtw_memcpy(supportRate, pIE->data, pIE->Length);
\r
1170 supportRateNum = pIE->Length;
\r
1172 case _COUNTRY_IE_:
\r
1174 case _EXT_SUPPORTEDRATES_IE_:
\r
1175 if(supportRateNum<=sizeof(supportRate))
\r
1177 _rtw_memcpy(supportRate+supportRateNum, pIE->data, pIE->Length);
\r
1178 supportRateNum += pIE->Length;
\r
1181 case _SUPPORTED_CH_IE_:
\r
1185 if(prx_pkt_attrib->encrypt){
\r
1187 //check whether initiator STA has CCMP pairwise_cipher.
\r
1188 ppairwise_cipher=prsnie+10;
\r
1189 _rtw_memcpy(ptdls_sta->TDLS_RSNIE, pIE->data, pIE->Length);
\r
1190 pairwise_count = *(u16*)(ppairwise_cipher-2);
\r
1191 for(k=0;k<pairwise_count;k++){
\r
1192 if(_rtw_memcmp( ppairwise_cipher+4*k, RSN_CIPHER_SUITE_CCMP, 4)==_TRUE)
\r
1195 if(ccmp_included==0){
\r
1196 //invalid contents of RSNIE
\r
1197 ptdls_sta->stat_code=72;
\r
1201 case _EXT_CAP_IE_:
\r
1203 case _VENDOR_SPECIFIC_IE_:
\r
1206 if(prx_pkt_attrib->encrypt)
\r
1207 _rtw_memcpy(SNonce, (ptr+j+52), 32);
\r
1209 case _TIMEOUT_ITVL_IE_:
\r
1210 if(prx_pkt_attrib->encrypt)
\r
1211 timeout_interval = (u32 *)(ptr+j+3);
\r
1213 case _RIC_Descriptor_IE_:
\r
1215 case _HT_CAPABILITY_IE_:
\r
1216 rtw_tdls_process_ht_cap(padapter, ptdls_sta, pIE->data, pIE->Length);
\r
1218 case EID_BSSCoexistence:
\r
1220 case _LINK_ID_IE_:
\r
1221 if(_rtw_memcmp(get_bssid(pmlmepriv), pIE->data, 6) == _FALSE)
\r
1223 //not in the same BSS
\r
1224 ptdls_sta->stat_code=7;
\r
1231 j += (pIE->Length + 2);
\r
1235 //check status code
\r
1236 //if responder STA has/hasn't security on AP, but request hasn't/has RSNIE, it should reject
\r
1237 if(ptdls_sta->stat_code == 0 )
\r
1239 if(rsnie_included && (prx_pkt_attrib->encrypt==0)){
\r
1240 //security disabled
\r
1241 ptdls_sta->stat_code = 5;
\r
1242 }else if(rsnie_included==0 && (prx_pkt_attrib->encrypt)){
\r
1243 //request haven't RSNIE
\r
1244 ptdls_sta->stat_code = 38;
\r
1248 //WFD test plan version 0.18.2 test item 5.1.5
\r
1249 //SoUT does not use TDLS if AP uses weak security
\r
1250 if ( padapter->wdinfo.wfd_tdls_enable )
\r
1252 if(rsnie_included && (prx_pkt_attrib->encrypt != _AES_))
\r
1254 ptdls_sta->stat_code = 5;
\r
1257 #endif //CONFIG_WFD
\r
1260 ptdls_sta->tdls_sta_state|= TDLS_INITIATOR_STATE;
\r
1261 if(prx_pkt_attrib->encrypt){
\r
1262 _rtw_memcpy(ptdls_sta->SNonce, SNonce, 32);
\r
1263 _rtw_memcpy(&(ptdls_sta->TDLS_PeerKey_Lifetime), timeout_interval, 4);
\r
1266 //update station supportRate
\r
1267 ptdls_sta->bssratelen = supportRateNum;
\r
1268 _rtw_memcpy(ptdls_sta->bssrateset, supportRate, supportRateNum);
\r
1270 if(!(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE))
\r
1271 ptdlsinfo->sta_cnt++;
\r
1272 if( ptdlsinfo->sta_cnt == (NUM_STA - 2 - 4) ) // -2: AP + BC/MC sta, -4: default key
\r
1274 ptdlsinfo->sta_maximum = _TRUE;
\r
1278 rtw_tdls_process_wfd_ie(ptdlsinfo, ptr + FIXED_IE, parsing_length - FIXED_IE);
\r
1279 #endif // CONFIG_WFD
\r
1287 _rtw_memcpy(txmgmt.peer, prx_pkt_attrib->src, ETH_ALEN);
\r
1288 issue_tdls_setup_rsp(padapter, &txmgmt);
\r
1290 if(ptdls_sta->stat_code==0)
\r
1292 _set_timer( &ptdls_sta->handshake_timer, TDLS_HANDSHAKE_TIME);
\r
1294 else //status code!=0 ; setup unsuccess
\r
1296 free_tdls_sta(padapter, ptdls_sta);
\r
1304 int On_TDLS_Setup_Rsp(_adapter *padapter, union recv_frame *precv_frame)
\r
1306 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
\r
1307 struct sta_info *ptdls_sta= NULL;
\r
1308 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1309 u8 *ptr = precv_frame->u.hdr.rx_data;
\r
1311 struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
\r
1314 sint parsing_length; //frame body length, without icv_len
\r
1315 PNDIS_802_11_VARIABLE_IEs pIE;
\r
1318 u8 *pftie=NULL, *ptimeout_ie=NULL, *plinkid_ie=NULL, *prsnie=NULL, *pftie_mic=NULL, *ppairwise_cipher=NULL;
\r
1319 u16 pairwise_count, j, k;
\r
1321 unsigned char supportRate[16];
\r
1322 int supportRateNum = 0;
\r
1323 struct tdls_txmgmt txmgmt;
\r
1324 int ret = _SUCCESS;
\r
1326 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
1327 psa = get_sa(ptr);
\r
1328 ptdls_sta = rtw_get_stainfo(pstapriv, psa);
\r
1330 if ( NULL == ptdls_sta )
\r
1336 ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1;
\r
1337 parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
\r
1338 -prx_pkt_attrib->hdrlen
\r
1339 -prx_pkt_attrib->iv_len
\r
1340 -prx_pkt_attrib->icv_len
\r
1342 -TYPE_LENGTH_FIELD_SIZE
\r
1346 _rtw_memcpy(&stat_code, ptr+2, 2);
\r
1350 DBG_871X( "[%s] status_code = %d, free_tdls_sta\n", __FUNCTION__, stat_code );
\r
1351 free_tdls_sta(padapter, ptdls_sta);
\r
1358 //parsing information element
\r
1359 for(j=FIXED_IE; j<parsing_length;)
\r
1361 pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
\r
1363 switch (pIE->ElementID)
\r
1365 case _SUPPORTEDRATES_IE_:
\r
1366 _rtw_memcpy(supportRate, pIE->data, pIE->Length);
\r
1367 supportRateNum = pIE->Length;
\r
1369 case _COUNTRY_IE_:
\r
1371 case _EXT_SUPPORTEDRATES_IE_:
\r
1372 if(supportRateNum<=sizeof(supportRate))
\r
1374 _rtw_memcpy(supportRate+supportRateNum, pIE->data, pIE->Length);
\r
1375 supportRateNum += pIE->Length;
\r
1378 case _SUPPORTED_CH_IE_:
\r
1382 //check whether responder STA has CCMP pairwise_cipher.
\r
1383 ppairwise_cipher=prsnie+10;
\r
1384 _rtw_memcpy(&pairwise_count, (u16*)(ppairwise_cipher-2), 2);
\r
1385 for(k=0;k<pairwise_count;k++){
\r
1386 if(_rtw_memcmp( ppairwise_cipher+4*k, RSN_CIPHER_SUITE_CCMP, 4)==_TRUE)
\r
1389 case _EXT_CAP_IE_:
\r
1391 case _VENDOR_SPECIFIC_IE_:
\r
1395 //_rtw_memcpy(ptdls_sta->ANonce, (ptr+j+20), 32);
\r
1396 _rtw_memcpy(ANonce, (ptr+j+20), 32);
\r
1398 case _TIMEOUT_ITVL_IE_:
\r
1399 ptimeout_ie=(u8*)pIE;
\r
1401 case _RIC_Descriptor_IE_:
\r
1403 case _HT_CAPABILITY_IE_:
\r
1404 rtw_tdls_process_ht_cap(padapter, ptdls_sta, pIE->data, pIE->Length);
\r
1406 case EID_BSSCoexistence:
\r
1408 case _LINK_ID_IE_:
\r
1409 plinkid_ie=(u8*)pIE;
\r
1415 j += (pIE->Length + 2);
\r
1419 //update station's supportRate
\r
1420 ptdls_sta->bssratelen = supportRateNum;
\r
1421 _rtw_memcpy(ptdls_sta->bssrateset, supportRate, supportRateNum);
\r
1423 _rtw_memcpy(ptdls_sta->ANonce, ANonce, 32);
\r
1426 rtw_tdls_process_wfd_ie(ptdlsinfo, ptr + FIXED_IE, parsing_length - FIXED_IE);
\r
1427 #endif // CONFIG_WFD
\r
1429 if(stat_code != 0)
\r
1431 ptdls_sta->stat_code = stat_code;
\r
1435 if(prx_pkt_attrib->encrypt)
\r
1437 if(verify_ccmp==1)
\r
1439 wpa_tdls_generate_tpk(padapter, ptdls_sta);
\r
1440 ptdls_sta->stat_code=0;
\r
1441 if(tdls_verify_mic(ptdls_sta->tpk.kck, 2, plinkid_ie, prsnie, ptimeout_ie, pftie)==0) //0: Invalid, 1: valid
\r
1443 free_tdls_sta(padapter, ptdls_sta);
\r
1450 ptdls_sta->stat_code=72; //invalide contents of RSNIE
\r
1454 ptdls_sta->stat_code=0;
\r
1458 DBG_871X("issue_tdls_setup_cfm\n");
\r
1459 _rtw_memcpy(txmgmt.peer, prx_pkt_attrib->src, ETH_ALEN);
\r
1460 issue_tdls_setup_cfm(padapter, &txmgmt);
\r
1462 if(ptdls_sta->stat_code==0)
\r
1464 ptdlsinfo->link_established = _TRUE;
\r
1466 if( ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE )
\r
1468 ptdls_sta->tdls_sta_state |= TDLS_LINKED_STATE;
\r
1469 _cancel_timer_ex( &ptdls_sta->handshake_timer);
\r
1472 rtw_tdls_set_key(padapter, prx_pkt_attrib, ptdls_sta);
\r
1474 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_ESTABLISHED);
\r
1483 int On_TDLS_Setup_Cfm(_adapter *padapter, union recv_frame *precv_frame)
\r
1485 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
\r
1486 struct sta_info *ptdls_sta= NULL;
\r
1487 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1488 u8 *ptr = precv_frame->u.hdr.rx_data;
\r
1490 struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
\r
1493 sint parsing_length;
\r
1494 PNDIS_802_11_VARIABLE_IEs pIE;
\r
1496 u8 *pftie=NULL, *ptimeout_ie=NULL, *plinkid_ie=NULL, *prsnie=NULL, *pftie_mic=NULL, *ppairwise_cipher=NULL;
\r
1497 u16 j, pairwise_count;
\r
1498 int ret = _SUCCESS;
\r
1500 psa = get_sa(ptr);
\r
1501 ptdls_sta = rtw_get_stainfo(pstapriv, psa);
\r
1503 if(ptdls_sta == NULL)
\r
1505 DBG_871X( "[%s] Direct Link Peer = "MAC_FMT" not found\n", __FUNCTION__, MAC_ARG(psa) );
\r
1510 ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1;
\r
1511 parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
\r
1512 -prx_pkt_attrib->hdrlen
\r
1513 -prx_pkt_attrib->iv_len
\r
1514 -prx_pkt_attrib->icv_len
\r
1519 _rtw_memcpy(&stat_code, ptr+2, 2);
\r
1522 DBG_871X( "[%s] stat_code = %d\n, free_tdls_sta", __FUNCTION__, stat_code );
\r
1523 free_tdls_sta(padapter, ptdls_sta);
\r
1528 if(prx_pkt_attrib->encrypt){
\r
1529 //parsing information element
\r
1530 for(j=FIXED_IE; j<parsing_length;){
\r
1532 pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
\r
1534 switch (pIE->ElementID)
\r
1539 case _VENDOR_SPECIFIC_IE_:
\r
1544 case _TIMEOUT_ITVL_IE_:
\r
1545 ptimeout_ie=(u8*)pIE;
\r
1547 case _HT_EXTRA_INFO_IE_:
\r
1549 case _LINK_ID_IE_:
\r
1550 plinkid_ie=(u8*)pIE;
\r
1556 j += (pIE->Length + 2);
\r
1560 //verify mic in FTIE MIC field
\r
1561 if(tdls_verify_mic(ptdls_sta->tpk.kck, 3, plinkid_ie, prsnie, ptimeout_ie, pftie)==0){ //0: Invalid, 1: Valid
\r
1562 free_tdls_sta(padapter, ptdls_sta);
\r
1569 ptdlsinfo->link_established = _TRUE;
\r
1570 if( ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE )
\r
1572 ptdls_sta->tdls_sta_state|=TDLS_LINKED_STATE;
\r
1573 _cancel_timer_ex( &ptdls_sta->handshake_timer);
\r
1576 rtw_tdls_set_key(padapter, prx_pkt_attrib, ptdls_sta);
\r
1578 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_ESTABLISHED);
\r
1585 int On_TDLS_Dis_Req(_adapter *padapter, union recv_frame *precv_frame)
\r
1587 struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
\r
1588 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1589 struct sta_info *psta_ap;
\r
1590 u8 *ptr = precv_frame->u.hdr.rx_data;
\r
1591 sint parsing_length; //frame body length, without icv_len
\r
1592 PNDIS_802_11_VARIABLE_IEs pIE;
\r
1593 u8 FIXED_IE = 3, *dst;
\r
1595 struct tdls_txmgmt txmgmt;
\r
1596 int ret = _SUCCESS;
\r
1598 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
1599 ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len + LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE + 1;
\r
1600 txmgmt.dialog_token = *(ptr+2);
\r
1601 _rtw_memcpy(&txmgmt.peer, precv_frame->u.hdr.attrib.src, ETH_ALEN);
\r
1602 txmgmt.action_code = TDLS_DISCOVERY_RESPONSE;
\r
1603 parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
\r
1604 -prx_pkt_attrib->hdrlen
\r
1605 -prx_pkt_attrib->iv_len
\r
1606 -prx_pkt_attrib->icv_len
\r
1608 -TYPE_LENGTH_FIELD_SIZE
\r
1612 //parsing information element
\r
1613 for(j=FIXED_IE; j<parsing_length;){
\r
1615 pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
\r
1617 switch (pIE->ElementID)
\r
1619 case _LINK_ID_IE_:
\r
1620 psta_ap = rtw_get_stainfo(pstapriv, pIE->data);
\r
1621 if(psta_ap == NULL)
\r
1625 dst = pIE->data + 12;
\r
1626 if( (MacAddr_isBcst(dst) == _FALSE) && (_rtw_memcmp(myid(&(padapter->eeprompriv)), dst, 6) == _FALSE) )
\r
1635 j += (pIE->Length + 2);
\r
1639 issue_tdls_dis_rsp(padapter, &txmgmt, prx_pkt_attrib->privacy);
\r
1646 int On_TDLS_Teardown(_adapter *padapter, union recv_frame *precv_frame)
\r
1649 u8 *ptr = precv_frame->u.hdr.rx_data;
\r
1650 struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
\r
1651 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
1652 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
1653 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1654 struct sta_info *ptdls_sta= NULL;
\r
1657 psa = get_sa(ptr);
\r
1659 ptdls_sta = rtw_get_stainfo(pstapriv, psa);
\r
1660 if(ptdls_sta!=NULL){
\r
1661 if(ptdls_sta->tdls_sta_state & TDLS_CH_SWITCH_ON_STATE){
\r
1662 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CS_OFF);
\r
1664 free_tdls_sta(padapter, ptdls_sta);
\r
1671 u8 TDLS_check_ch_state(uint state){
\r
1672 if( (state & TDLS_CH_SWITCH_ON_STATE) &&
\r
1673 (state & TDLS_AT_OFF_CH_STATE) &&
\r
1674 (state & TDLS_PEER_AT_OFF_STATE) ){
\r
1676 if(state & TDLS_PEER_SLEEP_STATE)
\r
1677 return 2; //U-APSD + ch. switch
\r
1679 return 1; //ch. switch
\r
1684 int On_TDLS_Peer_Traffic_Indication(_adapter *padapter, union recv_frame *precv_frame)
\r
1686 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
\r
1687 struct sta_info *ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->src);
\r
1688 u8 *ptr = precv_frame->u.hdr.rx_data;
\r
1690 ptr +=pattrib->hdrlen + pattrib->iv_len + LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE + 1;
\r
1692 if(ptdls_sta != NULL)
\r
1694 ptdls_sta->dialog = *(ptr+2);
\r
1695 issue_tdls_peer_traffic_rsp(padapter, ptdls_sta);
\r
1697 //issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->hwaddr, 0, 0, 0);
\r
1701 DBG_871X("from unknown sta:"MAC_FMT"\n", MAC_ARG(pattrib->src));
\r
1708 //we process buffered data for 1. U-APSD, 2. ch. switch, 3. U-APSD + ch. switch here
\r
1709 int On_TDLS_Peer_Traffic_Rsp(_adapter *padapter, union recv_frame *precv_frame)
\r
1711 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
\r
1712 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
1713 struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib;
\r
1714 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1715 //get peer sta infomation
\r
1716 struct sta_info *ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->src);
\r
1717 u8 wmmps_ac=0, state=TDLS_check_ch_state(ptdls_sta->tdls_sta_state);
\r
1720 ptdls_sta->sta_stats.rx_data_pkts++;
\r
1722 ptdls_sta->tdls_sta_state &= ~(TDLS_WAIT_PTR_STATE);
\r
1724 //receive peer traffic response frame, sleeping STA wakes up
\r
1725 //ptdls_sta->tdls_sta_state &= ~(TDLS_PEER_SLEEP_STATE);
\r
1726 //process_wmmps_data( padapter, precv_frame);
\r
1728 // if noticed peer STA wakes up by receiving peer traffic response
\r
1729 // and we want to do channel swtiching, then we will transmit channel switch request first
\r
1730 if(ptdls_sta->tdls_sta_state & TDLS_APSD_CHSW_STATE){
\r
1731 issue_tdls_ch_switch_req(padapter, pattrib->src);
\r
1732 ptdls_sta->tdls_sta_state &= ~(TDLS_APSD_CHSW_STATE);
\r
1736 //check 4-AC queue bit
\r
1737 if(ptdls_sta->uapsd_vo || ptdls_sta->uapsd_vi || ptdls_sta->uapsd_be || ptdls_sta->uapsd_bk)
\r
1740 //if it's a direct link and have buffered frame
\r
1741 if(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE){
\r
1743 //if(wmmps_ac && state)
\r
1747 _list *xmitframe_plist, *xmitframe_phead;
\r
1748 struct xmit_frame *pxmitframe=NULL;
\r
1750 _enter_critical_bh(&ptdls_sta->sleep_q.lock, &irqL);
\r
1752 xmitframe_phead = get_list_head(&ptdls_sta->sleep_q);
\r
1753 xmitframe_plist = get_next(xmitframe_phead);
\r
1755 //transmit buffered frames
\r
1756 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE)
\r
1758 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
\r
1759 xmitframe_plist = get_next(xmitframe_plist);
\r
1760 rtw_list_delete(&pxmitframe->list);
\r
1762 ptdls_sta->sleepq_len--;
\r
1763 ptdls_sta->sleepq_ac_len--;
\r
1764 if(ptdls_sta->sleepq_len>0){
\r
1765 pxmitframe->attrib.mdata = 1;
\r
1766 pxmitframe->attrib.eosp = 0;
\r
1768 pxmitframe->attrib.mdata = 0;
\r
1769 pxmitframe->attrib.eosp = 1;
\r
1771 pxmitframe->attrib.triggered = 1;
\r
1773 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
\r
1778 if(ptdls_sta->sleepq_len==0)
\r
1780 DBG_871X("no buffered packets for tdls to xmit\n");
\r
1781 //on U-APSD + CH. switch state, when there is no buffered date to xmit,
\r
1782 // we should go back to base channel
\r
1784 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CS_OFF);
\r
1785 }else if(ptdls_sta->tdls_sta_state&TDLS_SW_OFF_STATE){
\r
1786 ptdls_sta->tdls_sta_state &= ~(TDLS_SW_OFF_STATE);
\r
1787 ptdlsinfo->candidate_ch= pmlmeext->cur_channel;
\r
1788 issue_tdls_ch_switch_req(padapter, pattrib->src);
\r
1789 DBG_871X("issue tdls ch switch req back to base channel\n");
\r
1795 DBG_871X("error!psta->sleepq_len=%d\n", ptdls_sta->sleepq_len);
\r
1796 ptdls_sta->sleepq_len=0;
\r
1799 _exit_critical_bh(&ptdls_sta->sleep_q.lock, &irqL);
\r
1808 sint On_TDLS_Ch_Switch_Req(_adapter *padapter, union recv_frame *precv_frame)
\r
1810 struct sta_info *ptdls_sta= NULL;
\r
1811 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1812 u8 *ptr = precv_frame->u.hdr.rx_data;
\r
1813 struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
\r
1815 sint parsing_length;
\r
1816 PNDIS_802_11_VARIABLE_IEs pIE;
\r
1819 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
1821 psa = get_sa(ptr);
\r
1822 ptdls_sta = rtw_get_stainfo(pstapriv, psa);
\r
1824 ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1;
\r
1825 parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
\r
1826 -prx_pkt_attrib->hdrlen
\r
1827 -prx_pkt_attrib->iv_len
\r
1828 -prx_pkt_attrib->icv_len
\r
1834 ptdls_sta->off_ch = *(ptr+2);
\r
1836 //parsing information element
\r
1837 for(j=FIXED_IE; j<parsing_length;){
\r
1839 pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
\r
1841 switch (pIE->ElementID)
\r
1843 case _COUNTRY_IE_:
\r
1845 case _CH_SWTICH_ANNOUNCE_:
\r
1847 case _LINK_ID_IE_:
\r
1849 case _CH_SWITCH_TIMING_:
\r
1850 _rtw_memcpy(&ptdls_sta->ch_switch_time, pIE->data, 2);
\r
1851 _rtw_memcpy(&ptdls_sta->ch_switch_timeout, pIE->data+2, 2);
\r
1856 j += (pIE->Length + 2);
\r
1860 //todo: check status
\r
1861 ptdls_sta->stat_code=0;
\r
1862 ptdls_sta->tdls_sta_state |= TDLS_CH_SWITCH_ON_STATE;
\r
1864 issue_nulldata(padapter, NULL, 1, 0, 0);
\r
1866 issue_tdls_ch_switch_rsp(padapter, psa);
\r
1868 DBG_871X("issue tdls channel switch response\n");
\r
1870 if((ptdls_sta->tdls_sta_state & TDLS_CH_SWITCH_ON_STATE) && ptdls_sta->off_ch==pmlmeext->cur_channel){
\r
1871 DBG_871X("back to base channel %x\n", pmlmeext->cur_channel);
\r
1872 ptdls_sta->option=TDLS_BASE_CH;
\r
1873 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_BASE_CH);
\r
1875 ptdls_sta->option=TDLS_OFF_CH;
\r
1876 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_OFF_CH);
\r
1881 sint On_TDLS_Ch_Switch_Rsp(_adapter *padapter, union recv_frame *precv_frame)
\r
1883 struct sta_info *ptdls_sta= NULL;
\r
1884 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1885 u8 *ptr = precv_frame->u.hdr.rx_data;
\r
1886 struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
\r
1888 sint parsing_length;
\r
1889 PNDIS_802_11_VARIABLE_IEs pIE;
\r
1891 u16 stat_code, j, switch_time, switch_timeout;
\r
1892 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
1893 int ret = _SUCCESS;
\r
1895 psa = get_sa(ptr);
\r
1896 ptdls_sta = rtw_get_stainfo(pstapriv, psa);
\r
1898 //if channel switch is running and receiving Unsolicited TDLS Channel Switch Response,
\r
1899 //it will go back to base channel and terminate this channel switch procedure
\r
1900 if(ptdls_sta->tdls_sta_state & TDLS_CH_SWITCH_ON_STATE ){
\r
1901 if(pmlmeext->cur_channel==ptdls_sta->off_ch){
\r
1902 DBG_871X("back to base channel %x\n", pmlmeext->cur_channel);
\r
1903 ptdls_sta->option=TDLS_BASE_CH;
\r
1904 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_BASE_CH);
\r
1906 DBG_871X("receive unsolicited channel switch response \n");
\r
1907 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CS_OFF);
\r
1913 //avoiding duplicated or unconditional ch. switch. rsp
\r
1914 if(!(ptdls_sta->tdls_sta_state & TDLS_CH_SW_INITIATOR_STATE))
\r
1920 ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1;
\r
1921 parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
\r
1922 -prx_pkt_attrib->hdrlen
\r
1923 -prx_pkt_attrib->iv_len
\r
1924 -prx_pkt_attrib->icv_len
\r
1930 _rtw_memcpy(&stat_code, ptr+2, 2);
\r
1937 //parsing information element
\r
1938 for(j=FIXED_IE; j<parsing_length;){
\r
1940 pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
\r
1942 switch (pIE->ElementID)
\r
1944 case _LINK_ID_IE_:
\r
1946 case _CH_SWITCH_TIMING_:
\r
1947 _rtw_memcpy(&switch_time, pIE->data, 2);
\r
1948 if(switch_time > ptdls_sta->ch_switch_time)
\r
1949 _rtw_memcpy(&ptdls_sta->ch_switch_time, &switch_time, 2);
\r
1951 _rtw_memcpy(&switch_timeout, pIE->data+2, 2);
\r
1952 if(switch_timeout > ptdls_sta->ch_switch_timeout)
\r
1953 _rtw_memcpy(&ptdls_sta->ch_switch_timeout, &switch_timeout, 2);
\r
1959 j += (pIE->Length + 2);
\r
1963 ptdls_sta->tdls_sta_state &= ~(TDLS_CH_SW_INITIATOR_STATE);
\r
1964 ptdls_sta->tdls_sta_state |=TDLS_CH_SWITCH_ON_STATE;
\r
1966 //goto set_channel_workitem_callback()
\r
1967 ptdls_sta->option=TDLS_OFF_CH;
\r
1968 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_OFF_CH);
\r
1975 void wfd_ie_tdls(_adapter * padapter, u8 *pframe, u32 *pktlen )
\r
1977 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1978 struct wifi_display_info *pwfd_info = padapter->tdlsinfo.wfd_info;
\r
1979 u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
\r
1984 wfdie[ wfdielen++ ] = 0x50;
\r
1985 wfdie[ wfdielen++ ] = 0x6F;
\r
1986 wfdie[ wfdielen++ ] = 0x9A;
\r
1987 wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
\r
1989 // Commented by Albert 20110825
\r
1990 // According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes
\r
1991 // 1. WFD Device Information
\r
1992 // 2. Associated BSSID ( Optional )
\r
1993 // 3. Local IP Adress ( Optional )
\r
1995 // WFD Device Information ATTR
\r
1997 wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
\r
2000 // Note: In the WFD specification, the size of length field is 2.
\r
2001 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
\r
2005 // WFD device information
\r
2006 // available for WFD session + Preferred TDLS + WSD ( WFD Service Discovery )
\r
2007 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL
\r
2008 | WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_WSD);
\r
2012 // Session Management Control Port
\r
2013 // Default TCP port for RTSP messages is 554
\r
2014 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
\r
2018 // WFD Device Maximum Throughput
\r
2019 // 300Mbps is the maximum throughput
\r
2020 RTW_PUT_BE16(wfdie + wfdielen, 300);
\r
2023 // Associated BSSID ATTR
\r
2025 wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
\r
2028 // Note: In the WFD specification, the size of length field is 2.
\r
2029 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
\r
2033 // Associated BSSID
\r
2034 if ( check_fwstate( pmlmepriv, _FW_LINKED) == _TRUE )
\r
2036 _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
\r
2040 _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
\r
2043 // Local IP Address ATTR
\r
2044 wfdie[ wfdielen++ ] = WFD_ATTR_LOCAL_IP_ADDR;
\r
2047 // Note: In the WFD specification, the size of length field is 2.
\r
2048 RTW_PUT_BE16(wfdie + wfdielen, 0x0005);
\r
2052 // 0x01: Version1;IPv4
\r
2053 wfdie[ wfdielen++ ] = 0x01;
\r
2056 _rtw_memcpy( wfdie + wfdielen, pwfd_info->ip_address, 4 );
\r
2059 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, pktlen);
\r
2062 #endif //CONFIG_WFD
\r
2064 void rtw_build_tdls_setup_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt)
\r
2066 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
2067 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
\r
2068 struct pkt_attrib *pattrib = &pxmitframe->attrib;
\r
2069 struct registry_priv *pregistrypriv = &padapter->registrypriv;
\r
2070 struct sta_info *ptdls_sta=rtw_get_stainfo( (&padapter->stapriv) , pattrib->dst);
\r
2072 u8 payload_type = 0x02;
\r
2073 u8 category = RTW_WLAN_CATEGORY_TDLS;
\r
2074 u8 action = TDLS_SETUP_REQUEST;
\r
2075 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
2076 int bssrate_len = 0, i = 0 ;
\r
2077 u8 more_supportedrates = 0;
\r
2078 unsigned int ie_len;
\r
2079 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
2080 u8 link_id_addr[18] = {0};
\r
2082 u8 sup_ch[ 30 * 2 ] = {0x00 }, sup_ch_idx = 0, idx_5g = 2; //For supported channel
\r
2083 u8 timeout_itvl[5]; //set timeout interval to maximum value
\r
2088 if(pattrib->encrypt){
\r
2090 time=rtw_get_current_time();
\r
2091 _rtw_memcpy(&ptdls_sta->SNonce[4*i], (u8 *)&time, 4);
\r
2095 pframe_head = pframe; // For rtw_tdls_set_ht_cap()
\r
2098 pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
\r
2099 //category, action, dialog token
\r
2100 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
2101 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
2102 pframe = rtw_set_fixed_ie(pframe, 1, &(ptdls_sta->dialog), &(pattrib->pktlen));
\r
2105 _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
\r
2107 if(pattrib->encrypt)
\r
2108 *pframe =*pframe | cap_Privacy;
\r
2110 pattrib->pktlen += 2;
\r
2113 if(pmlmeext->cur_channel < 14 )
\r
2115 rtw_set_supported_rate(bssrate, WIRELESS_11BG_24N);
\r
2116 bssrate_len = IEEE80211_CCK_RATE_LEN + IEEE80211_NUM_OFDM_RATESLEN;
\r
2120 rtw_set_supported_rate(bssrate, WIRELESS_11A_5N);
\r
2121 bssrate_len = IEEE80211_NUM_OFDM_RATESLEN;
\r
2124 //country(optional)
\r
2126 if (bssrate_len > 8)
\r
2128 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
\r
2129 more_supportedrates = 1;
\r
2133 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
\r
2136 //extended supported rates
\r
2137 if(more_supportedrates==1){
\r
2138 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
\r
2141 //supported channels
\r
2142 pframe = rtw_tdls_set_sup_ch(pmlmeext, pframe, pattrib);
\r
2145 pframe = rtw_set_ie( pframe, _SRC_IE_, sizeof(TDLS_SRC), TDLS_SRC, &(pattrib->pktlen));
\r
2148 if(pattrib->encrypt)
\r
2149 pframe = rtw_set_ie(pframe, _RSN_IE_2_, sizeof(TDLS_RSNIE), TDLS_RSNIE, &(pattrib->pktlen));
\r
2151 //extended capabilities
\r
2152 pframe = rtw_set_ie(pframe, _EXT_CAP_IE_ , sizeof(TDLS_EXT_CAPIE), TDLS_EXT_CAPIE, &(pattrib->pktlen));
\r
2154 //QoS capability(WMM_IE)
\r
2155 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(TDLS_WMMIE), TDLS_WMMIE, &(pattrib->pktlen));
\r
2158 if(pattrib->encrypt){
\r
2160 _rtw_memset(pframe, 0, 84); //All fields except SNonce shall be set to 0
\r
2161 _rtw_memset(pframe, _FTIE_, 1); //version
\r
2162 _rtw_memset((pframe+1), 82, 1); //length
\r
2163 _rtw_memcpy((pframe+52), ptdls_sta->SNonce, 32);
\r
2165 pattrib->pktlen += 84;
\r
2167 //Timeout interval
\r
2168 timeout_itvl[0]=0x02;
\r
2169 _rtw_memcpy(timeout_itvl+1, (u8 *)(&ptdls_sta->TDLS_PeerKey_Lifetime), 4);
\r
2170 pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
\r
2173 //Sup_reg_classes(optional)
\r
2175 pframe += rtw_tdls_set_ht_cap(padapter, pframe_head, pattrib);
\r
2177 //20/40 BSS coexistence
\r
2178 if(pmlmepriv->num_FortyMHzIntolerant>0)
\r
2179 iedata |= BIT(2);//20 MHz BSS Width Request
\r
2180 pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
\r
2183 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2184 _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
\r
2185 _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
\r
2186 pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
\r
2189 wfd_ie_tdls( padapter, pframe, &(pattrib->pktlen) );
\r
2190 #endif //CONFIG_WFD
\r
2194 void rtw_build_tdls_setup_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt)
\r
2196 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
2197 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
2198 struct pkt_attrib *pattrib = &pxmitframe->attrib;
\r
2199 struct sta_info *ptdls_sta;
\r
2200 struct registry_priv *pregistrypriv = &padapter->registrypriv;
\r
2202 u8 payload_type = 0x02;
\r
2203 unsigned char category = RTW_WLAN_CATEGORY_TDLS;
\r
2204 unsigned char action = TDLS_SETUP_RESPONSE;
\r
2205 unsigned char bssrate[NDIS_802_11_LENGTH_RATES_EX];
\r
2206 int bssrate_len = 0;
\r
2207 u8 more_supportedrates = 0;
\r
2208 unsigned int ie_len;
\r
2210 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
2211 u8 link_id_addr[18] = {0};
\r
2213 u8 timeout_itvl[5]; //setup response timeout interval will copy from request
\r
2214 u8 ANonce[32]; //maybe it can put in ontdls_req
\r
2215 u8 k; //for random ANonce
\r
2216 u8 *pftie=NULL, *ptimeout_ie=NULL, *plinkid_ie=NULL, *prsnie=NULL, *pftie_mic=NULL;
\r
2220 ptdls_sta = rtw_get_stainfo( &(padapter->stapriv) , pattrib->dst);
\r
2222 if(ptdls_sta == NULL )
\r
2224 DBG_871X("[%s] %d\n", __FUNCTION__, __LINE__);
\r
2228 if(pattrib->encrypt){
\r
2230 time=rtw_get_current_time();
\r
2231 _rtw_memcpy(&ptdls_sta->ANonce[4*k], (u8*)&time, 4);
\r
2235 pframe_head = pframe;
\r
2238 pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
\r
2239 //category, action, status code
\r
2240 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
2241 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
2242 pframe = rtw_set_fixed_ie(pframe, 2, (u8 *)&ptdls_sta->stat_code, &(pattrib->pktlen));
\r
2244 if(ptdls_sta->stat_code!=0) //invalid setup request
\r
2246 DBG_871X("ptdls_sta->stat_code:%04x \n", ptdls_sta->stat_code);
\r
2251 pframe = rtw_set_fixed_ie(pframe, 1, &(ptdls_sta->dialog), &(pattrib->pktlen));
\r
2254 _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
\r
2256 if(pattrib->encrypt )
\r
2257 *pframe =*pframe | cap_Privacy;
\r
2259 pattrib->pktlen += 2;
\r
2263 if(pmlmeext->cur_channel < 14 )
\r
2265 rtw_set_supported_rate(bssrate, WIRELESS_11BG_24N);
\r
2266 bssrate_len = IEEE80211_CCK_RATE_LEN + IEEE80211_NUM_OFDM_RATESLEN;
\r
2270 rtw_set_supported_rate(bssrate, WIRELESS_11A_5N);
\r
2271 bssrate_len = IEEE80211_NUM_OFDM_RATESLEN;
\r
2274 if (bssrate_len > 8)
\r
2276 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
\r
2277 more_supportedrates = 1;
\r
2281 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
\r
2284 //country(optional)
\r
2285 //extended supported rates
\r
2286 if(more_supportedrates==1){
\r
2287 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
\r
2290 //supported channels
\r
2291 pframe = rtw_tdls_set_sup_ch(pmlmeext, pframe, pattrib);
\r
2294 pframe = rtw_set_ie(pframe, _SRC_IE_ , sizeof(TDLS_SRC), TDLS_SRC, &(pattrib->pktlen));
\r
2297 if(pattrib->encrypt){
\r
2299 pframe = rtw_set_ie(pframe, _RSN_IE_2_, sizeof(ptdls_sta->TDLS_RSNIE), ptdls_sta->TDLS_RSNIE, &(pattrib->pktlen));
\r
2302 //extended capabilities
\r
2303 pframe = rtw_set_ie(pframe, _EXT_CAP_IE_ , sizeof(TDLS_EXT_CAPIE), TDLS_EXT_CAPIE, &(pattrib->pktlen));
\r
2305 //QoS capability(WMM_IE)
\r
2306 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(TDLS_WMMIE), TDLS_WMMIE, &(pattrib->pktlen));
\r
2308 if(pattrib->encrypt){
\r
2309 wpa_tdls_generate_tpk(padapter, ptdls_sta);
\r
2313 pftie_mic = pframe+4;
\r
2314 _rtw_memset(pframe, 0, 84); //All fields except SNonce shall be set to 0
\r
2315 _rtw_memset(pframe, _FTIE_, 1); //version
\r
2316 _rtw_memset((pframe+1), 82, 1); //length
\r
2317 _rtw_memcpy((pframe+20), ptdls_sta->ANonce, 32);
\r
2318 _rtw_memcpy((pframe+52), ptdls_sta->SNonce, 32);
\r
2320 pattrib->pktlen += 84;
\r
2322 //Timeout interval
\r
2323 ptimeout_ie = pframe;
\r
2324 timeout_itvl[0]=0x02;
\r
2325 _rtw_memcpy(timeout_itvl+1, (u8 *)(&ptdls_sta->TDLS_PeerKey_Lifetime), 4);
\r
2326 pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
\r
2329 //Sup_reg_classes(optional)
\r
2331 pframe += rtw_tdls_set_ht_cap(padapter, pframe_head, pattrib);
\r
2333 //20/40 BSS coexistence
\r
2334 if(pmlmepriv->num_FortyMHzIntolerant>0)
\r
2335 iedata |= BIT(2);//20 MHz BSS Width Request
\r
2336 pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
\r
2339 plinkid_ie = pframe;
\r
2340 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2341 _rtw_memcpy((link_id_addr+6), pattrib->dst, 6);
\r
2342 _rtw_memcpy((link_id_addr+12), pattrib->src, 6);
\r
2343 pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
\r
2346 if(pattrib->encrypt)
\r
2347 wpa_tdls_ftie_mic(ptdls_sta->tpk.kck, 2, plinkid_ie, prsnie, ptimeout_ie, pftie, pftie_mic);
\r
2350 wfd_ie_tdls( padapter, pframe, &(pattrib->pktlen) );
\r
2351 #endif //CONFIG_WFD
\r
2355 void rtw_build_tdls_setup_cfm_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt)
\r
2358 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
2359 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
2360 struct pkt_attrib *pattrib = &pxmitframe->attrib;
\r
2361 struct sta_info *ptdls_sta=rtw_get_stainfo( (&padapter->stapriv) , pattrib->dst);
\r
2363 u8 payload_type = 0x02;
\r
2364 unsigned char category = RTW_WLAN_CATEGORY_TDLS;
\r
2365 unsigned char action = TDLS_SETUP_CONFIRM;
\r
2366 u8 more_supportedrates = 0;
\r
2367 unsigned int ie_len;
\r
2369 u8 timeout_itvl[5]; //set timeout interval to maximum value
\r
2370 u8 wmm_param_ele[24] = {0};
\r
2371 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
2372 u8 link_id_addr[18] = {0};
\r
2373 u8 *pftie=NULL, *ptimeout_ie=NULL, *plinkid_ie=NULL, *prsnie=NULL, *pftie_mic=NULL;
\r
2376 pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
\r
2377 //category, action, status code, dialog token
\r
2378 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
2379 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
2380 pframe = rtw_set_fixed_ie(pframe, 2, (u8 *)&ptdls_sta->stat_code, &(pattrib->pktlen));
\r
2381 pframe = rtw_set_fixed_ie(pframe, 1, &(ptdls_sta->dialog), &(pattrib->pktlen));
\r
2383 if(ptdls_sta->stat_code!=0) //invalid setup request
\r
2387 if(pattrib->encrypt){
\r
2389 pframe = rtw_set_ie(pframe, _RSN_IE_2_, sizeof(TDLS_RSNIE), TDLS_RSNIE, &(pattrib->pktlen));
\r
2392 //EDCA param set; WMM param ele.
\r
2393 if(pattrib->encrypt){
\r
2396 pftie_mic = pframe+4;
\r
2397 _rtw_memset(pframe, 0, 84); //All fields except SNonce shall be set to 0
\r
2398 _rtw_memset(pframe, _FTIE_, 1); //version
\r
2399 _rtw_memset((pframe+1), 82, 1); //length
\r
2400 _rtw_memcpy((pframe+20), ptdls_sta->ANonce, 32);
\r
2401 _rtw_memcpy((pframe+52), ptdls_sta->SNonce, 32);
\r
2403 pattrib->pktlen += 84;
\r
2405 //Timeout interval
\r
2406 ptimeout_ie = pframe;
\r
2407 timeout_itvl[0]=0x02;
\r
2408 _rtw_memcpy(timeout_itvl+1, (u8 *)(&ptdls_sta->TDLS_PeerKey_Lifetime), 4);
\r
2409 ptdls_sta->TPK_count=0;
\r
2410 _set_timer(&ptdls_sta->TPK_timer, ptdls_sta->TDLS_PeerKey_Lifetime/TPK_RESEND_COUNT);
\r
2411 pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
\r
2414 //HT operation; todo
\r
2416 plinkid_ie = pframe;
\r
2417 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2418 _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
\r
2419 _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
\r
2420 pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
\r
2423 if(pattrib->encrypt)
\r
2424 wpa_tdls_ftie_mic(ptdls_sta->tpk.kck, 3, plinkid_ie, prsnie, ptimeout_ie, pftie, pftie_mic);
\r
2426 //WMM Parameter Set
\r
2427 if(&pmlmeinfo->WMM_param)
\r
2429 _rtw_memcpy(wmm_param_ele, WMM_PARA_OUI, 6);
\r
2430 _rtw_memcpy(wmm_param_ele+6, (u8 *)&pmlmeinfo->WMM_param, sizeof(pmlmeinfo->WMM_param));
\r
2431 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 24, wmm_param_ele, &(pattrib->pktlen));
\r
2436 void rtw_build_tdls_teardown_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt)
\r
2439 struct pkt_attrib *pattrib = &pxmitframe->attrib;
\r
2440 u8 payload_type = 0x02;
\r
2441 unsigned char category = RTW_WLAN_CATEGORY_TDLS;
\r
2442 u8 action = ptxmgmt->action_code;
\r
2443 u8 link_id_addr[18] = {0};
\r
2444 struct sta_info *ptdls_sta = rtw_get_stainfo( &(padapter->stapriv) , pattrib->dst);
\r
2447 pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
\r
2448 //category, action, reason code
\r
2449 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
2450 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
2451 pframe = rtw_set_fixed_ie(pframe, 2, (u8 *)&ptxmgmt->status_code, &(pattrib->pktlen));
\r
2454 if(ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE){
\r
2455 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2456 _rtw_memcpy((link_id_addr+6), pattrib->dst, 6);
\r
2457 _rtw_memcpy((link_id_addr+12), pattrib->src, 6);
\r
2458 }else if(ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE){
\r
2459 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2460 _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
\r
2461 _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
\r
2463 pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
\r
2467 void rtw_build_tdls_dis_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, struct tdls_txmgmt *ptxmgmt)
\r
2470 struct pkt_attrib *pattrib = &pxmitframe->attrib;
\r
2471 u8 payload_type = 0x02;
\r
2472 u8 category = RTW_WLAN_CATEGORY_TDLS;
\r
2473 u8 action = TDLS_DISCOVERY_REQUEST;
\r
2474 u8 link_id_addr[18] = {0};
\r
2475 static u8 dialogtoken=0;
\r
2478 pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
\r
2479 //category, action, reason code
\r
2480 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
2481 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
2482 if(ptxmgmt->external_support == _TRUE) {
\r
2483 pframe = rtw_set_fixed_ie(pframe, 1, &(ptxmgmt->dialog_token), &(pattrib->pktlen));
\r
2485 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogtoken), &(pattrib->pktlen));
\r
2486 dialogtoken = (dialogtoken+1)%256;
\r
2490 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2491 _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
\r
2492 _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
\r
2493 pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
\r
2497 void rtw_build_tdls_dis_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, u8 dialog, u8 privacy)
\r
2499 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
2500 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
\r
2501 struct pkt_attrib *pattrib = &pxmitframe->attrib;
\r
2502 struct registry_priv *pregistrypriv = &padapter->registrypriv;
\r
2504 u8 category = RTW_WLAN_CATEGORY_PUBLIC;
\r
2505 u8 action = TDLS_DISCOVERY_RESPONSE;
\r
2506 u8 bssrate[NDIS_802_11_LENGTH_RATES_EX];
\r
2507 int bssrate_len = 0;
\r
2508 u8 more_supportedrates = 0;
\r
2510 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
2511 u8 link_id_addr[18] = {0};
\r
2513 u8 timeout_itvl[5]; //set timeout interval to maximum value
\r
2514 u32 timeout_interval= TPK_RESEND_COUNT * 1000;
\r
2515 u8 *pframe_head, pktlen_index;
\r
2517 pktlen_index = pattrib->pktlen; // For mgmt frame, pattrib->pktlen would count frame header
\r
2518 pframe_head = pframe;
\r
2520 //category, action, dialog token
\r
2521 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
2522 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
2523 pframe = rtw_set_fixed_ie(pframe, 1, &(dialog), &(pattrib->pktlen));
\r
2526 _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
\r
2529 *pframe =*pframe | cap_Privacy;
\r
2531 pattrib->pktlen += 2;
\r
2534 rtw_set_supported_rate(bssrate, WIRELESS_11BG_24N);
\r
2535 bssrate_len = IEEE80211_CCK_RATE_LEN + IEEE80211_NUM_OFDM_RATESLEN;
\r
2537 if (bssrate_len > 8)
\r
2539 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
\r
2540 more_supportedrates = 1;
\r
2544 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
\r
2547 //extended supported rates
\r
2548 if(more_supportedrates==1){
\r
2549 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
\r
2552 //supported channels
\r
2553 pframe = rtw_tdls_set_sup_ch(pmlmeext, pframe, pattrib);
\r
2557 pframe = rtw_set_ie(pframe, _RSN_IE_2_, sizeof(TDLS_RSNIE), TDLS_RSNIE, &(pattrib->pktlen));
\r
2559 //extended capability
\r
2560 pframe = rtw_set_ie(pframe, _EXT_CAP_IE_ , sizeof(TDLS_EXT_CAPIE), TDLS_EXT_CAPIE, &(pattrib->pktlen));
\r
2564 _rtw_memset(pframe, 0, 84); //All fields shall be set to 0
\r
2565 _rtw_memset(pframe, _FTIE_, 1); //version
\r
2566 _rtw_memset((pframe+1), 82, 1); //length
\r
2568 pattrib->pktlen += 84;
\r
2570 //Timeout interval
\r
2571 timeout_itvl[0]=0x02;
\r
2572 _rtw_memcpy(timeout_itvl+1, &timeout_interval, 4);
\r
2573 pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
\r
2576 //Sup_reg_classes(optional)
\r
2578 pframe += rtw_tdls_set_ht_cap(padapter, pframe_head - pktlen_index, pattrib);
\r
2580 //20/40 BSS coexistence
\r
2581 if(pmlmepriv->num_FortyMHzIntolerant>0)
\r
2582 iedata |= BIT(2);//20 MHz BSS Width Request
\r
2583 pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
\r
2586 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2587 _rtw_memcpy((link_id_addr+6), pattrib->dst, 6);
\r
2588 _rtw_memcpy((link_id_addr+12), pattrib->src, 6);
\r
2589 pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
\r
2593 void rtw_build_tdls_peer_traffic_indication_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
\r
2596 struct pkt_attrib *pattrib = &pxmitframe->attrib;
\r
2597 u8 payload_type = 0x02;
\r
2598 unsigned char category = RTW_WLAN_CATEGORY_TDLS;
\r
2599 unsigned char action = TDLS_PEER_TRAFFIC_INDICATION;
\r
2601 u8 link_id_addr[18] = {0};
\r
2603 struct sta_info *ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->dst);
\r
2606 pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
\r
2607 //category, action, reason code
\r
2608 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
2609 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
2610 pframe = rtw_set_fixed_ie(pframe, 1, &(ptdls_sta->dialog), &(pattrib->pktlen));
\r
2613 if(ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE){
\r
2614 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2615 _rtw_memcpy((link_id_addr+6), pattrib->dst, 6);
\r
2616 _rtw_memcpy((link_id_addr+12), pattrib->src, 6);
\r
2617 }else if(ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE){
\r
2618 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2619 _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
\r
2620 _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
\r
2622 pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
\r
2625 //PU buffer status
\r
2626 if(ptdls_sta->uapsd_bk&BIT(1))
\r
2628 if(ptdls_sta->uapsd_be&BIT(1))
\r
2630 if(ptdls_sta->uapsd_vi&BIT(1))
\r
2632 if(ptdls_sta->uapsd_vo&BIT(1))
\r
2634 pframe = rtw_set_ie(pframe, _PTI_BUFFER_STATUS_, 1, &AC_queue, &(pattrib->pktlen));
\r
2638 void rtw_build_tdls_peer_traffic_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
\r
2641 struct pkt_attrib *pattrib = &pxmitframe->attrib;
\r
2642 u8 payload_type = 0x02;
\r
2643 u8 category = RTW_WLAN_CATEGORY_TDLS;
\r
2644 u8 action = TDLS_PEER_TRAFFIC_RESPONSE;
\r
2645 u8 link_id_addr[18] = {0};
\r
2646 struct sta_info *ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->dst);
\r
2647 static u8 dialogtoken=0;
\r
2650 pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
\r
2651 //category, action, reason code
\r
2652 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
2653 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
2654 pframe = rtw_set_fixed_ie(pframe, 1, &ptdls_sta->dialog, &(pattrib->pktlen));
\r
2657 if(ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE){
\r
2658 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2659 _rtw_memcpy((link_id_addr+6), pattrib->dst, 6);
\r
2660 _rtw_memcpy((link_id_addr+12), pattrib->src, 6);
\r
2661 }else if(ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE){
\r
2662 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2663 _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
\r
2664 _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
\r
2666 pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
\r
2670 void rtw_build_tdls_ch_switch_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
\r
2673 struct pkt_attrib *pattrib = &pxmitframe->attrib;
\r
2674 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
\r
2675 u8 payload_type = 0x02;
\r
2676 unsigned char category = RTW_WLAN_CATEGORY_TDLS;
\r
2677 unsigned char action = TDLS_CHANNEL_SWITCH_REQUEST;
\r
2678 u8 link_id_addr[18] = {0};
\r
2679 struct sta_priv *pstapriv = &padapter->stapriv;
\r
2680 struct sta_info *ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst);
\r
2681 u8 ch_switch_timing[4] = {0};
\r
2682 u16 switch_time= CH_SWITCH_TIME, switch_timeout=CH_SWITCH_TIMEOUT;
\r
2685 pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
\r
2686 //category, action, target_ch
\r
2687 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
2688 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
2689 pframe = rtw_set_fixed_ie(pframe, 1, &(ptdlsinfo->candidate_ch), &(pattrib->pktlen));
\r
2692 if(ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE){
\r
2693 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2694 _rtw_memcpy((link_id_addr+6), pattrib->dst, 6);
\r
2695 _rtw_memcpy((link_id_addr+12), pattrib->src, 6);
\r
2696 }else if(ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE){
\r
2697 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2698 _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
\r
2699 _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
\r
2701 pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
\r
2703 //ch switch timing
\r
2704 _rtw_memcpy(ch_switch_timing, &switch_time, 2);
\r
2705 _rtw_memcpy(ch_switch_timing+2, &switch_timeout, 2);
\r
2706 pframe = rtw_set_ie(pframe, _CH_SWITCH_TIMING_, 4, ch_switch_timing, &(pattrib->pktlen));
\r
2708 //update ch switch attrib to sta_info
\r
2709 ptdls_sta->off_ch=ptdlsinfo->candidate_ch;
\r
2710 ptdls_sta->ch_switch_time=switch_time;
\r
2711 ptdls_sta->ch_switch_timeout=switch_timeout;
\r
2715 void rtw_build_tdls_ch_switch_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
\r
2718 struct pkt_attrib *pattrib = &pxmitframe->attrib;
\r
2719 u8 payload_type = 0x02;
\r
2720 unsigned char category = RTW_WLAN_CATEGORY_TDLS;
\r
2721 unsigned char action = TDLS_CHANNEL_SWITCH_RESPONSE;
\r
2722 u8 link_id_addr[18] = {0};
\r
2723 struct sta_priv *pstapriv = &padapter->stapriv;
\r
2724 struct sta_info *ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst);
\r
2725 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
2726 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
\r
2727 u8 ch_switch_timing[4] = {0};
\r
2730 pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
\r
2731 //category, action, status_code
\r
2732 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
2733 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
2734 pframe = rtw_set_fixed_ie(pframe, 2, (u8 *)&ptdls_sta->stat_code, &(pattrib->pktlen));
\r
2737 if(ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE){
\r
2738 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2739 _rtw_memcpy((link_id_addr+6), pattrib->dst, 6);
\r
2740 _rtw_memcpy((link_id_addr+12), pattrib->src, 6);
\r
2741 }else if(ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE){
\r
2742 _rtw_memcpy(link_id_addr, pattrib->ra, 6);
\r
2743 _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
\r
2744 _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
\r
2746 pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
\r
2748 //ch switch timing
\r
2749 _rtw_memcpy(ch_switch_timing, &ptdls_sta->ch_switch_time, 2);
\r
2750 _rtw_memcpy(ch_switch_timing+2, &ptdls_sta->ch_switch_timeout, 2);
\r
2751 pframe = rtw_set_ie(pframe, _CH_SWITCH_TIMING_, 4, ch_switch_timing, &(pattrib->pktlen));
\r
2756 void rtw_build_tunneled_probe_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
\r
2759 struct pkt_attrib *pattrib = &pxmitframe->attrib;
\r
2760 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
\r
2761 struct wifidirect_info *pbuddy_wdinfo = &padapter->pbuddy_adapter->wdinfo;
\r
2762 u8 payload_type = 0x02;
\r
2763 u8 category = RTW_WLAN_CATEGORY_P2P;
\r
2764 u8 WFA_OUI[3] = { 0x50, 0x6f, 0x9a};
\r
2769 pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
\r
2770 //category, OUI, frame_body_type
\r
2771 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
2772 pframe = rtw_set_fixed_ie(pframe, 3, WFA_OUI, &(pattrib->pktlen));
\r
2773 pframe = rtw_set_fixed_ie(pframe, 1, &(probe_req), &(pattrib->pktlen));
\r
2775 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
2777 wfdielen = build_probe_req_wfd_ie(pwdinfo, pframe);
\r
2778 pframe += wfdielen;
\r
2779 pattrib->pktlen += wfdielen;
\r
2781 else if(!rtw_p2p_chk_state(pbuddy_wdinfo, P2P_STATE_NONE))
\r
2783 wfdielen = build_probe_req_wfd_ie(pbuddy_wdinfo, pframe);
\r
2784 pframe += wfdielen;
\r
2785 pattrib->pktlen += wfdielen;
\r
2790 void rtw_build_tunneled_probe_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
\r
2793 struct pkt_attrib *pattrib = &pxmitframe->attrib;
\r
2794 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
\r
2795 struct wifidirect_info *pbuddy_wdinfo = &padapter->pbuddy_adapter->wdinfo;
\r
2796 u8 payload_type = 0x02;
\r
2797 u8 category = RTW_WLAN_CATEGORY_P2P;
\r
2798 u8 WFA_OUI[3] = { 0x50, 0x6f, 0x9a};
\r
2803 pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
\r
2804 //category, OUI, frame_body_type
\r
2805 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
2806 pframe = rtw_set_fixed_ie(pframe, 3, WFA_OUI, &(pattrib->pktlen));
\r
2807 pframe = rtw_set_fixed_ie(pframe, 1, &(probe_rsp), &(pattrib->pktlen));
\r
2809 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
2811 wfdielen = build_probe_resp_wfd_ie(pwdinfo, pframe, 1);
\r
2812 pframe += wfdielen;
\r
2813 pattrib->pktlen += wfdielen;
\r
2815 else if(!rtw_p2p_chk_state(pbuddy_wdinfo, P2P_STATE_NONE))
\r
2817 wfdielen = build_probe_resp_wfd_ie(pbuddy_wdinfo, pframe, 1);
\r
2818 pframe += wfdielen;
\r
2819 pattrib->pktlen += wfdielen;
\r
2823 #endif //CONFIG_WFD
\r
2825 void _tdls_tpk_timer_hdl(void *FunctionContext)
\r
2827 struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
\r
2828 struct tdls_txmgmt txmgmt;
\r
2830 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
2831 ptdls_sta->TPK_count++;
\r
2832 //TPK_timer set 1000 as default
\r
2833 //retry timer should set at least 301 sec.
\r
2834 if(ptdls_sta->TPK_count==TPK_RESEND_COUNT){
\r
2835 ptdls_sta->TPK_count=0;
\r
2836 _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN);
\r
2837 issue_tdls_setup_req(ptdls_sta->padapter, &txmgmt, _FALSE);
\r
2840 _set_timer(&ptdls_sta->TPK_timer, ptdls_sta->TDLS_PeerKey_Lifetime/TPK_RESEND_COUNT);
\r
2843 // TDLS_DONE_CH_SEN: channel sensing and report candidate channel
\r
2844 // TDLS_OFF_CH: first time set channel to off channel
\r
2845 // TDLS_BASE_CH: when go back to the channel linked with AP, send null data to peer STA as an indication
\r
2846 void _tdls_ch_switch_timer_hdl(void *FunctionContext)
\r
2849 struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
\r
2850 _adapter *padapter = ptdls_sta->padapter;
\r
2852 if( ptdls_sta->option == TDLS_DONE_CH_SEN ){
\r
2853 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_DONE_CH_SEN);
\r
2854 }else if( ptdls_sta->option == TDLS_OFF_CH ){
\r
2855 issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta->hwaddr, 0, 0, 0);
\r
2856 _set_timer(&ptdls_sta->base_ch_timer, 500);
\r
2857 }else if( ptdls_sta->option == TDLS_BASE_CH){
\r
2858 issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta->hwaddr, 0, 0, 0);
\r
2862 void _tdls_base_ch_timer_hdl(void *FunctionContext)
\r
2864 struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
\r
2865 rtw_tdls_cmd(ptdls_sta->padapter, ptdls_sta->hwaddr, TDLS_P_OFF_CH);
\r
2868 void _tdls_off_ch_timer_hdl(void *FunctionContext)
\r
2870 struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
\r
2871 rtw_tdls_cmd(ptdls_sta->padapter, ptdls_sta->hwaddr, TDLS_P_BASE_CH );
\r
2874 void _tdls_handshake_timer_hdl(void *FunctionContext)
\r
2876 struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
\r
2878 if(ptdls_sta != NULL)
\r
2880 if( !(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) )
\r
2882 DBG_871X("tdls handshake time out\n");
\r
2883 rtw_tdls_cmd(ptdls_sta->padapter, ptdls_sta->hwaddr, TDLS_TEAR_STA );
\r
2888 void _tdls_pti_timer_hdl(void *FunctionContext)
\r
2890 struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
\r
2891 _adapter *padapter = ptdls_sta->padapter;
\r
2892 struct tdls_txmgmt txmgmt;
\r
2894 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
2895 _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN);
\r
2896 txmgmt.status_code = _RSON_TDLS_TEAR_TOOFAR_;
\r
2898 if(ptdls_sta != NULL)
\r
2900 if( ptdls_sta->tdls_sta_state & TDLS_WAIT_PTR_STATE )
\r
2902 DBG_871X("Doesn't receive PTR from peer dev:"MAC_FMT"; Send TDLS Tear Down\n", MAC_ARG(ptdls_sta->hwaddr));
\r
2903 issue_tdls_teardown(padapter, &txmgmt, _FALSE);
\r
2908 void rtw_init_tdls_timer(_adapter *padapter, struct sta_info *psta)
\r
2910 psta->padapter=padapter;
\r
2911 _init_timer(&psta->TPK_timer, padapter->pnetdev, _tdls_tpk_timer_hdl, psta);
\r
2912 _init_timer(&psta->option_timer, padapter->pnetdev, _tdls_ch_switch_timer_hdl, psta);
\r
2913 _init_timer(&psta->base_ch_timer, padapter->pnetdev, _tdls_base_ch_timer_hdl, psta);
\r
2914 _init_timer(&psta->off_ch_timer, padapter->pnetdev, _tdls_off_ch_timer_hdl, psta);
\r
2915 _init_timer(&psta->handshake_timer, padapter->pnetdev, _tdls_handshake_timer_hdl, psta);
\r
2916 _init_timer(&psta->pti_timer, padapter->pnetdev, _tdls_pti_timer_hdl, psta);
\r
2919 void rtw_free_tdls_timer(struct sta_info *psta)
\r
2921 _cancel_timer_ex(&psta->TPK_timer);
\r
2922 _cancel_timer_ex(&psta->option_timer);
\r
2923 _cancel_timer_ex(&psta->base_ch_timer);
\r
2924 _cancel_timer_ex(&psta->off_ch_timer);
\r
2925 _cancel_timer_ex(&psta->handshake_timer);
\r
2926 _cancel_timer_ex(&psta->pti_timer);
\r
2929 u8 update_sgi_tdls(_adapter *padapter, struct sta_info *psta)
\r
2931 return query_ra_short_GI(psta);
\r
2934 u32 update_mask_tdls(_adapter *padapter, struct sta_info *psta)
\r
2936 unsigned char sta_band = 0;
\r
2937 unsigned int tx_ra_bitmap=0;
\r
2938 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2939 WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
\r
2941 rtw_hal_update_sta_rate_mask(padapter, psta);
\r
2942 tx_ra_bitmap = psta->ra_mask;
\r
2944 if ( pcur_network->Configuration.DSConfig > 14 ) {
\r
2946 if (tx_ra_bitmap & 0xffff000)
\r
2947 sta_band |= WIRELESS_11_5N | WIRELESS_11A;
\r
2949 sta_band |= WIRELESS_11A;
\r
2951 if (tx_ra_bitmap & 0xffff000)
\r
2952 sta_band |= WIRELESS_11_24N | WIRELESS_11G | WIRELESS_11B;
\r
2953 else if (tx_ra_bitmap & 0xff0)
\r
2954 sta_band |= WIRELESS_11G |WIRELESS_11B;
\r
2956 sta_band |= WIRELESS_11B;
\r
2959 psta->wireless_mode = sta_band;
\r
2961 psta->raid = rtw_hal_networktype_to_raid(padapter,psta);
\r
2962 tx_ra_bitmap |= ((psta->raid<<28)&0xf0000000);
\r
2963 return tx_ra_bitmap;
\r
2966 #endif //CONFIG_TDLS
\r