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