1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 ******************************************************************************/
22 #include <drv_types.h>
26 int rtw_p2p_is_channel_list_ok( u8 desired_ch, u8* ch_list, u8 ch_cnt )
30 for( i = 0; i < ch_cnt; i++ )
32 if ( ch_list[ i ] == desired_ch )
41 int is_any_client_associated(_adapter *padapter)
43 return padapter->stapriv.asoc_list_cnt ? _TRUE : _FALSE;
46 static u32 go_add_group_info_attr(struct wifidirect_info *pwdinfo, u8 *pbuf)
52 u8 tmplen, *pdata_attr, *pstart, *pcur;
53 struct sta_info *psta = NULL;
54 _adapter *padapter = pwdinfo->padapter;
55 struct sta_priv *pstapriv = &padapter->stapriv;
57 DBG_871X("%s\n", __FUNCTION__);
59 pdata_attr = rtw_zmalloc(MAX_P2P_IE_LEN);
61 if(NULL == pdata_attr){
62 DBG_871X("%s pdata_attr malloc failed \n", __FUNCTION__);
69 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
70 phead = &pstapriv->asoc_list;
71 plist = get_next(phead);
73 //look up sta asoc_queue
74 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
76 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
78 plist = get_next(plist);
81 if(psta->is_p2p_device)
88 _rtw_memcpy(pcur, psta->dev_addr, ETH_ALEN);
91 //P2P interface address
92 _rtw_memcpy(pcur, psta->hwaddr, ETH_ALEN);
95 *pcur = psta->dev_cap;
98 //*(u16*)(pcur) = cpu_to_be16(psta->config_methods);
99 RTW_PUT_BE16(pcur, psta->config_methods);
102 _rtw_memcpy(pcur, psta->primary_dev_type, 8);
105 *pcur = psta->num_of_secdev_type;
108 _rtw_memcpy(pcur, psta->secdev_types_list, psta->num_of_secdev_type*8);
109 pcur += psta->num_of_secdev_type*8;
111 if(psta->dev_name_len>0)
113 //*(u16*)(pcur) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
114 RTW_PUT_BE16(pcur, WPS_ATTR_DEVICE_NAME);
117 //*(u16*)(pcur) = cpu_to_be16( psta->dev_name_len );
118 RTW_PUT_BE16(pcur, psta->dev_name_len);
121 _rtw_memcpy(pcur, psta->dev_name, psta->dev_name_len);
122 pcur += psta->dev_name_len;
126 tmplen = (u8)(pcur-pstart);
128 *pstart = (tmplen-1);
139 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
143 len = rtw_set_p2p_attr_content(pbuf, P2P_ATTR_GROUP_INFO, attr_len, pdata_attr);
146 rtw_mfree(pdata_attr, MAX_P2P_IE_LEN);
153 static void issue_group_disc_req(struct wifidirect_info *pwdinfo, u8 *da)
155 struct xmit_frame *pmgntframe;
156 struct pkt_attrib *pattrib;
157 unsigned char *pframe;
158 struct rtw_ieee80211_hdr *pwlanhdr;
159 unsigned short *fctrl;
160 _adapter *padapter = pwdinfo->padapter;
161 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
162 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
163 unsigned char category = RTW_WLAN_CATEGORY_P2P;//P2P action frame
164 u32 p2poui = cpu_to_be32(P2POUI);
165 u8 oui_subtype = P2P_GO_DISC_REQUEST;
168 DBG_871X("[%s]\n", __FUNCTION__);
170 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
176 pattrib = &pmgntframe->attrib;
177 update_mgntframe_attrib(padapter, pattrib);
179 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
181 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
182 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
184 fctrl = &(pwlanhdr->frame_ctl);
187 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
188 _rtw_memcpy(pwlanhdr->addr2, pwdinfo->interface_addr, ETH_ALEN);
189 _rtw_memcpy(pwlanhdr->addr3, pwdinfo->interface_addr, ETH_ALEN);
191 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
192 pmlmeext->mgnt_seq++;
193 SetFrameSubType(pframe, WIFI_ACTION);
195 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
196 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
198 //Build P2P action frame header
199 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
200 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
201 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
202 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
204 //there is no IE in this P2P action frame
206 pattrib->last_txcmdsz = pattrib->pktlen;
208 dump_mgntframe(padapter, pmgntframe);
212 static void issue_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 status, u8 dialogToken)
214 struct xmit_frame *pmgntframe;
215 struct pkt_attrib *pattrib;
216 unsigned char *pframe;
217 struct rtw_ieee80211_hdr *pwlanhdr;
218 unsigned short *fctrl;
219 _adapter *padapter = pwdinfo->padapter;
220 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
221 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
222 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
223 u8 action = P2P_PUB_ACTION_ACTION;
224 u32 p2poui = cpu_to_be32(P2POUI);
225 u8 oui_subtype = P2P_DEVDISC_RESP;
226 u8 p2pie[8] = { 0x00 };
229 DBG_871X("[%s]\n", __FUNCTION__);
231 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
237 pattrib = &pmgntframe->attrib;
238 update_mgntframe_attrib(padapter, pattrib);
240 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
242 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
243 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
245 fctrl = &(pwlanhdr->frame_ctl);
248 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
249 _rtw_memcpy(pwlanhdr->addr2, pwdinfo->device_addr, ETH_ALEN);
250 _rtw_memcpy(pwlanhdr->addr3, pwdinfo->device_addr, ETH_ALEN);
252 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
253 pmlmeext->mgnt_seq++;
254 SetFrameSubType(pframe, WIFI_ACTION);
256 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
257 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
259 //Build P2P public action frame header
260 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
261 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
262 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
263 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
264 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
270 p2pie[ p2pielen++ ] = 0x50;
271 p2pie[ p2pielen++ ] = 0x6F;
272 p2pie[ p2pielen++ ] = 0x9A;
273 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
276 p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status);
278 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, p2pie, &pattrib->pktlen);
280 pattrib->last_txcmdsz = pattrib->pktlen;
282 dump_mgntframe(padapter, pmgntframe);
286 static void issue_p2p_provision_resp(struct wifidirect_info *pwdinfo, u8* raddr, u8* frame_body, u16 config_method)
288 _adapter *padapter = pwdinfo->padapter;
289 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
290 u8 action = P2P_PUB_ACTION_ACTION;
291 u8 dialogToken = frame_body[7]; // The Dialog Token of provisioning discovery request frame.
292 u32 p2poui = cpu_to_be32(P2POUI);
293 u8 oui_subtype = P2P_PROVISION_DISC_RESP;
294 u8 wpsie[ 100 ] = { 0x00 };
300 struct xmit_frame *pmgntframe;
301 struct pkt_attrib *pattrib;
302 unsigned char *pframe;
303 struct rtw_ieee80211_hdr *pwlanhdr;
304 unsigned short *fctrl;
305 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
306 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
307 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
310 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
316 pattrib = &pmgntframe->attrib;
317 update_mgntframe_attrib(padapter, pattrib);
319 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
321 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
322 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
324 fctrl = &(pwlanhdr->frame_ctl);
327 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
328 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
329 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
331 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
332 pmlmeext->mgnt_seq++;
333 SetFrameSubType(pframe, WIFI_ACTION);
335 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
336 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
338 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
339 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
340 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
341 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
342 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
346 //*(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
347 RTW_PUT_BE32(wpsie, WPSOUI);
353 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
357 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
361 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
366 //*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
367 RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
371 //*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
372 RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
376 //*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( config_method );
377 RTW_PUT_BE16(wpsie + wpsielen, config_method);
380 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
383 wfdielen = build_provdisc_resp_wfd_ie(pwdinfo, pframe);
385 pattrib->pktlen += wfdielen;
388 pattrib->last_txcmdsz = pattrib->pktlen;
390 dump_mgntframe(padapter, pmgntframe);
396 static void issue_p2p_presence_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 status, u8 dialogToken)
398 struct xmit_frame *pmgntframe;
399 struct pkt_attrib *pattrib;
400 unsigned char *pframe;
401 struct rtw_ieee80211_hdr *pwlanhdr;
402 unsigned short *fctrl;
403 _adapter *padapter = pwdinfo->padapter;
404 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
405 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
406 unsigned char category = RTW_WLAN_CATEGORY_P2P;//P2P action frame
407 u32 p2poui = cpu_to_be32(P2POUI);
408 u8 oui_subtype = P2P_PRESENCE_RESPONSE;
409 u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 };
410 u8 noa_attr_content[32] = { 0x00 };
413 DBG_871X("[%s]\n", __FUNCTION__);
415 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
421 pattrib = &pmgntframe->attrib;
422 update_mgntframe_attrib(padapter, pattrib);
424 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
426 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
427 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
429 fctrl = &(pwlanhdr->frame_ctl);
432 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
433 _rtw_memcpy(pwlanhdr->addr2, pwdinfo->interface_addr, ETH_ALEN);
434 _rtw_memcpy(pwlanhdr->addr3, pwdinfo->interface_addr, ETH_ALEN);
436 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
437 pmlmeext->mgnt_seq++;
438 SetFrameSubType(pframe, WIFI_ACTION);
440 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
441 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
443 //Build P2P action frame header
444 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
445 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
446 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
447 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
453 p2pie[ p2pielen++ ] = 0x50;
454 p2pie[ p2pielen++ ] = 0x6F;
455 p2pie[ p2pielen++ ] = 0x9A;
456 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
458 //Add Status attribute in P2P IE
459 p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status);
461 //Add NoA attribute in P2P IE
462 noa_attr_content[0] = 0x1;//index
463 noa_attr_content[1] = 0x0;//CTWindow and OppPS Parameters
465 //todo: Notice of Absence Descriptor(s)
467 p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_NOA, 2, noa_attr_content);
471 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, p2pie, &(pattrib->pktlen));
474 pattrib->last_txcmdsz = pattrib->pktlen;
476 dump_mgntframe(padapter, pmgntframe);
480 u32 build_beacon_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
482 u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 };
484 u32 len=0, p2pielen = 0;
489 p2pie[ p2pielen++ ] = 0x50;
490 p2pie[ p2pielen++ ] = 0x6F;
491 p2pie[ p2pielen++ ] = 0x9A;
492 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
495 // According to the P2P Specification, the beacon frame should contain 3 P2P attributes
498 // 3. Notice of Absence ( NOA )
500 // P2P Capability ATTR
504 // Device Capability Bitmap, 1 byte
505 // Be able to participate in additional P2P Groups and
506 // support the P2P Invitation Procedure
507 // Group Capability Bitmap, 1 byte
508 capability = P2P_DEVCAP_INVITATION_PROC|P2P_DEVCAP_CLIENT_DISCOVERABILITY;
509 capability |= ((P2P_GRPCAP_GO | P2P_GRPCAP_INTRABSS) << 8);
510 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
511 capability |= (P2P_GRPCAP_GROUP_FORMATION<<8);
513 capability = cpu_to_le16(capability);
515 p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_CAPABILITY, 2, (u8*)&capability);
518 // P2P Device ID ATTR
519 p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_DEVICE_ID, ETH_ALEN, pwdinfo->device_addr);
522 // Notice of Absence ATTR
527 //go_add_noa_attr(pwdinfo);
530 pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &len);
538 u32 build_beacon_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
540 u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
542 u32 len=0, wfdielen = 0;
543 _adapter *padapter = pwdinfo->padapter;
544 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
545 struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
547 if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST))
552 wfdie[ wfdielen++ ] = 0x50;
553 wfdie[ wfdielen++ ] = 0x6F;
554 wfdie[ wfdielen++ ] = 0x9A;
555 wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
557 // Commented by Albert 20110812
558 // According to the WFD Specification, the beacon frame should contain 4 WFD attributes
559 // 1. WFD Device Information
560 // 2. Associated BSSID
561 // 3. Coupled Sink Information
564 // WFD Device Information ATTR
566 wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
569 // Note: In the WFD specification, the size of length field is 2.
570 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
574 // WFD device information
576 if ( P2P_ROLE_GO == pwdinfo->role )
578 if ( is_any_client_associated( pwdinfo->padapter ) )
580 // WFD primary sink + WiFi Direct mode + WSD (WFD Service Discovery)
581 val16 = pwfd_info->wfd_device_type | WFD_DEVINFO_WSD;
582 RTW_PUT_BE16(wfdie + wfdielen, val16);
586 // WFD primary sink + available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery)
587 val16 = pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD;
588 RTW_PUT_BE16(wfdie + wfdielen, val16);
594 // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery )
595 val16 = pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD;
596 RTW_PUT_BE16(wfdie + wfdielen, val16);
602 // Session Management Control Port
603 // Default TCP port for RTSP messages is 554
604 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
608 // WFD Device Maximum Throughput
609 // 300Mbps is the maximum throughput
610 RTW_PUT_BE16(wfdie + wfdielen, 300);
613 // Associated BSSID ATTR
615 wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
618 // Note: In the WFD specification, the size of length field is 2.
619 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
624 if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE )
626 _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
630 _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
633 wfdielen += ETH_ALEN;
635 // Coupled Sink Information ATTR
637 wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
640 // Note: In the WFD specification, the size of length field is 2.
641 RTW_PUT_BE16(wfdie + wfdielen, 0x0007);
645 // Coupled Sink Status bitmap
646 // Not coupled/available for Coupling
647 wfdie[ wfdielen++ ] = 0;
649 wfdie[ wfdielen++ ] = 0;
650 wfdie[ wfdielen++ ] = 0;
651 wfdie[ wfdielen++ ] = 0;
652 wfdie[ wfdielen++ ] = 0;
653 wfdie[ wfdielen++ ] = 0;
654 wfdie[ wfdielen++ ] = 0;
656 rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
662 u32 build_probe_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
664 u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
666 u32 len=0, wfdielen = 0;
667 _adapter *padapter = pwdinfo->padapter;
668 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
669 struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
671 if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST))
676 wfdie[ wfdielen++ ] = 0x50;
677 wfdie[ wfdielen++ ] = 0x6F;
678 wfdie[ wfdielen++ ] = 0x9A;
679 wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
681 // Commented by Albert 20110812
682 // According to the WFD Specification, the probe request frame should contain 4 WFD attributes
683 // 1. WFD Device Information
684 // 2. Associated BSSID
685 // 3. Coupled Sink Information
688 // WFD Device Information ATTR
690 wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
693 // Note: In the WFD specification, the size of length field is 2.
694 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
698 // WFD device information
700 if ( 1 == pwdinfo->wfd_tdls_enable )
702 // WFD primary sink + available for WFD session + WiFi TDLS mode + WSC ( WFD Service Discovery )
703 val16 = pwfd_info->wfd_device_type |
704 WFD_DEVINFO_SESSION_AVAIL |
707 RTW_PUT_BE16(wfdie + wfdielen, val16 );
711 // WFD primary sink + available for WFD session + WiFi Direct mode + WSC ( WFD Service Discovery )
712 val16 = pwfd_info->wfd_device_type |
713 WFD_DEVINFO_SESSION_AVAIL |
715 RTW_PUT_BE16(wfdie + wfdielen, val16 );
721 // Session Management Control Port
722 // Default TCP port for RTSP messages is 554
723 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
727 // WFD Device Maximum Throughput
728 // 300Mbps is the maximum throughput
729 RTW_PUT_BE16(wfdie + wfdielen, 300);
732 // Associated BSSID ATTR
734 wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
737 // Note: In the WFD specification, the size of length field is 2.
738 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
743 if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE )
745 _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
749 _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
752 wfdielen += ETH_ALEN;
754 // Coupled Sink Information ATTR
756 wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
759 // Note: In the WFD specification, the size of length field is 2.
760 RTW_PUT_BE16(wfdie + wfdielen, 0x0007);
764 // Coupled Sink Status bitmap
765 // Not coupled/available for Coupling
766 wfdie[ wfdielen++ ] = 0;
768 wfdie[ wfdielen++ ] = 0;
769 wfdie[ wfdielen++ ] = 0;
770 wfdie[ wfdielen++ ] = 0;
771 wfdie[ wfdielen++ ] = 0;
772 wfdie[ wfdielen++ ] = 0;
773 wfdie[ wfdielen++ ] = 0;
775 rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
781 u32 build_probe_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 tunneled)
783 u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
784 u32 len=0, wfdielen = 0;
785 _adapter *padapter = pwdinfo->padapter;
786 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
787 struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
789 if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST))
794 wfdie[ wfdielen++ ] = 0x50;
795 wfdie[ wfdielen++ ] = 0x6F;
796 wfdie[ wfdielen++ ] = 0x9A;
797 wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
799 // Commented by Albert 20110812
800 // According to the WFD Specification, the probe response frame should contain 4 WFD attributes
801 // 1. WFD Device Information
802 // 2. Associated BSSID
803 // 3. Coupled Sink Information
804 // 4. WFD Session Information
807 // WFD Device Information ATTR
809 wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
812 // Note: In the WFD specification, the size of length field is 2.
813 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
817 // WFD device information
818 // WFD primary sink + available for WFD session + WiFi Direct mode
820 if ( _TRUE == pwdinfo->session_available )
822 if ( P2P_ROLE_GO == pwdinfo->role )
824 if ( is_any_client_associated( pwdinfo->padapter ) )
826 if ( pwdinfo->wfd_tdls_enable )
828 // TDLS mode + WSD ( WFD Service Discovery )
829 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_HDCP_SUPPORT);
833 // WiFi Direct mode + WSD ( WFD Service Discovery )
834 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_HDCP_SUPPORT);
839 if ( pwdinfo->wfd_tdls_enable )
841 // available for WFD session + TDLS mode + WSD ( WFD Service Discovery )
842 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD | WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_HDCP_SUPPORT);
846 // available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery )
847 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD | WFD_DEVINFO_HDCP_SUPPORT);
853 if ( pwdinfo->wfd_tdls_enable )
855 // available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery )
856 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD | WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_HDCP_SUPPORT);
861 // available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery )
862 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD | WFD_DEVINFO_HDCP_SUPPORT);
868 if ( pwdinfo->wfd_tdls_enable )
870 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_WSD |WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_HDCP_SUPPORT);
874 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_HDCP_SUPPORT);
882 // Session Management Control Port
883 // Default TCP port for RTSP messages is 554
884 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
888 // WFD Device Maximum Throughput
889 // 300Mbps is the maximum throughput
890 RTW_PUT_BE16(wfdie + wfdielen, 300);
893 // Associated BSSID ATTR
895 wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
898 // Note: In the WFD specification, the size of length field is 2.
899 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
904 if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE )
906 _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
910 _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
913 wfdielen += ETH_ALEN;
915 // Coupled Sink Information ATTR
917 wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
920 // Note: In the WFD specification, the size of length field is 2.
921 RTW_PUT_BE16(wfdie + wfdielen, 0x0007);
925 // Coupled Sink Status bitmap
926 // Not coupled/available for Coupling
927 wfdie[ wfdielen++ ] = 0;
929 wfdie[ wfdielen++ ] = 0;
930 wfdie[ wfdielen++ ] = 0;
931 wfdie[ wfdielen++ ] = 0;
932 wfdie[ wfdielen++ ] = 0;
933 wfdie[ wfdielen++ ] = 0;
934 wfdie[ wfdielen++ ] = 0;
936 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
938 // WFD Session Information ATTR
940 wfdie[ wfdielen++ ] = WFD_ATTR_SESSION_INFO;
943 // Note: In the WFD specification, the size of length field is 2.
944 RTW_PUT_BE16(wfdie + wfdielen, 0x0000);
947 // Todo: to add the list of WFD device info descriptor in WFD group.
950 #ifdef CONFIG_CONCURRENT_MODE
952 if ( ( tunneled == 0 ) && ( padapter->pbuddy_adapter->wdinfo.wfd_tdls_enable == 1 ) )
954 // Alternative MAC Address ATTR
956 wfdie[ wfdielen++ ] = WFD_ATTR_ALTER_MAC;
959 // Note: In the WFD specification, the size of length field is 2.
960 RTW_PUT_BE16(wfdie + wfdielen, ETH_ALEN );
964 // Alternative MAC Address
965 _rtw_memcpy(wfdie + wfdielen, adapter_mac_addr(padapter->pbuddy_adapter), ETH_ALEN);
966 // This mac address is used to make the WFD session when TDLS is enable.
968 wfdielen += ETH_ALEN;
970 #endif // CONFIG_TDLS
971 #endif // CONFIG_CONCURRENT_MODE
973 pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
979 u32 build_assoc_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
981 u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
983 u32 len=0, wfdielen = 0;
984 _adapter *padapter = NULL;
985 struct mlme_priv *pmlmepriv = NULL;
986 struct wifi_display_info *pwfd_info = NULL;
988 padapter = pwdinfo->padapter;
989 pmlmepriv = &padapter->mlmepriv;
990 pwfd_info = padapter->wdinfo.wfd_info;
992 if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST))
995 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
1000 wfdie[ wfdielen++ ] = 0x50;
1001 wfdie[ wfdielen++ ] = 0x6F;
1002 wfdie[ wfdielen++ ] = 0x9A;
1003 wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
1005 // Commented by Albert 20110812
1006 // According to the WFD Specification, the probe request frame should contain 4 WFD attributes
1007 // 1. WFD Device Information
1008 // 2. Associated BSSID
1009 // 3. Coupled Sink Information
1012 // WFD Device Information ATTR
1014 wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
1017 // Note: In the WFD specification, the size of length field is 2.
1018 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
1022 // WFD device information
1023 // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery )
1024 val16 = pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD;
1025 RTW_PUT_BE16(wfdie + wfdielen, val16);
1029 // Session Management Control Port
1030 // Default TCP port for RTSP messages is 554
1031 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
1035 // WFD Device Maximum Throughput
1036 // 300Mbps is the maximum throughput
1037 RTW_PUT_BE16(wfdie + wfdielen, 300);
1040 // Associated BSSID ATTR
1042 wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
1045 // Note: In the WFD specification, the size of length field is 2.
1046 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
1051 if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE )
1053 _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
1057 _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
1060 wfdielen += ETH_ALEN;
1062 // Coupled Sink Information ATTR
1064 wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
1067 // Note: In the WFD specification, the size of length field is 2.
1068 RTW_PUT_BE16(wfdie + wfdielen, 0x0007);
1072 // Coupled Sink Status bitmap
1073 // Not coupled/available for Coupling
1074 wfdie[ wfdielen++ ] = 0;
1076 wfdie[ wfdielen++ ] = 0;
1077 wfdie[ wfdielen++ ] = 0;
1078 wfdie[ wfdielen++ ] = 0;
1079 wfdie[ wfdielen++ ] = 0;
1080 wfdie[ wfdielen++ ] = 0;
1081 wfdie[ wfdielen++ ] = 0;
1083 rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
1089 u32 build_assoc_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
1091 u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
1092 u32 len=0, wfdielen = 0;
1094 _adapter *padapter = pwdinfo->padapter;
1095 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1096 struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
1098 if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST))
1103 wfdie[ wfdielen++ ] = 0x50;
1104 wfdie[ wfdielen++ ] = 0x6F;
1105 wfdie[ wfdielen++ ] = 0x9A;
1106 wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
1108 // Commented by Albert 20110812
1109 // According to the WFD Specification, the probe request frame should contain 4 WFD attributes
1110 // 1. WFD Device Information
1111 // 2. Associated BSSID
1112 // 3. Coupled Sink Information
1115 // WFD Device Information ATTR
1117 wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
1120 // Note: In the WFD specification, the size of length field is 2.
1121 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
1125 // WFD device information
1126 // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery )
1127 val16 = pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD;
1128 RTW_PUT_BE16(wfdie + wfdielen, val16);
1132 // Session Management Control Port
1133 // Default TCP port for RTSP messages is 554
1134 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
1138 // WFD Device Maximum Throughput
1139 // 300Mbps is the maximum throughput
1140 RTW_PUT_BE16(wfdie + wfdielen, 300);
1143 // Associated BSSID ATTR
1145 wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
1148 // Note: In the WFD specification, the size of length field is 2.
1149 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
1154 if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE )
1156 _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
1160 _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
1163 wfdielen += ETH_ALEN;
1165 // Coupled Sink Information ATTR
1167 wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
1170 // Note: In the WFD specification, the size of length field is 2.
1171 RTW_PUT_BE16(wfdie + wfdielen, 0x0007);
1175 // Coupled Sink Status bitmap
1176 // Not coupled/available for Coupling
1177 wfdie[ wfdielen++ ] = 0;
1179 wfdie[ wfdielen++ ] = 0;
1180 wfdie[ wfdielen++ ] = 0;
1181 wfdie[ wfdielen++ ] = 0;
1182 wfdie[ wfdielen++ ] = 0;
1183 wfdie[ wfdielen++ ] = 0;
1184 wfdie[ wfdielen++ ] = 0;
1186 rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
1192 u32 build_nego_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
1194 u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
1195 u32 len=0, wfdielen = 0;
1197 _adapter *padapter = pwdinfo->padapter;
1198 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1199 struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
1201 if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST))
1206 wfdie[ wfdielen++ ] = 0x50;
1207 wfdie[ wfdielen++ ] = 0x6F;
1208 wfdie[ wfdielen++ ] = 0x9A;
1209 wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
1211 // Commented by Albert 20110825
1212 // According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes
1213 // 1. WFD Device Information
1214 // 2. Associated BSSID ( Optional )
1215 // 3. Local IP Adress ( Optional )
1218 // WFD Device Information ATTR
1220 wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
1223 // Note: In the WFD specification, the size of length field is 2.
1224 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
1228 // WFD device information
1229 // WFD primary sink + WiFi Direct mode + WSD ( WFD Service Discovery ) + WFD Session Available
1230 val16 = pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_SESSION_AVAIL;
1231 RTW_PUT_BE16(wfdie + wfdielen, val16);
1235 // Session Management Control Port
1236 // Default TCP port for RTSP messages is 554
1237 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
1241 // WFD Device Maximum Throughput
1242 // 300Mbps is the maximum throughput
1243 RTW_PUT_BE16(wfdie + wfdielen, 300);
1246 // Associated BSSID ATTR
1248 wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
1251 // Note: In the WFD specification, the size of length field is 2.
1252 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
1257 if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE )
1259 _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
1263 _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
1266 wfdielen += ETH_ALEN;
1268 // Coupled Sink Information ATTR
1270 wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
1273 // Note: In the WFD specification, the size of length field is 2.
1274 RTW_PUT_BE16(wfdie + wfdielen, 0x0007);
1278 // Coupled Sink Status bitmap
1279 // Not coupled/available for Coupling
1280 wfdie[ wfdielen++ ] = 0;
1282 wfdie[ wfdielen++ ] = 0;
1283 wfdie[ wfdielen++ ] = 0;
1284 wfdie[ wfdielen++ ] = 0;
1285 wfdie[ wfdielen++ ] = 0;
1286 wfdie[ wfdielen++ ] = 0;
1287 wfdie[ wfdielen++ ] = 0;
1289 rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
1295 u32 build_nego_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
1297 u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
1298 u32 len=0, wfdielen = 0;
1300 _adapter *padapter = pwdinfo->padapter;
1301 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1302 struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
1304 if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST))
1309 wfdie[ wfdielen++ ] = 0x50;
1310 wfdie[ wfdielen++ ] = 0x6F;
1311 wfdie[ wfdielen++ ] = 0x9A;
1312 wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
1314 // Commented by Albert 20110825
1315 // According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes
1316 // 1. WFD Device Information
1317 // 2. Associated BSSID ( Optional )
1318 // 3. Local IP Adress ( Optional )
1321 // WFD Device Information ATTR
1323 wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
1326 // Note: In the WFD specification, the size of length field is 2.
1327 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
1331 // WFD device information
1332 // WFD primary sink + WiFi Direct mode + WSD ( WFD Service Discovery ) + WFD Session Available
1333 val16 = pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_SESSION_AVAIL;
1334 RTW_PUT_BE16(wfdie + wfdielen, val16);
1338 // Session Management Control Port
1339 // Default TCP port for RTSP messages is 554
1340 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
1344 // WFD Device Maximum Throughput
1345 // 300Mbps is the maximum throughput
1346 RTW_PUT_BE16(wfdie + wfdielen, 300);
1349 // Associated BSSID ATTR
1351 wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
1354 // Note: In the WFD specification, the size of length field is 2.
1355 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
1360 if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE )
1362 _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
1366 _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
1369 wfdielen += ETH_ALEN;
1371 // Coupled Sink Information ATTR
1373 wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
1376 // Note: In the WFD specification, the size of length field is 2.
1377 RTW_PUT_BE16(wfdie + wfdielen, 0x0007);
1381 // Coupled Sink Status bitmap
1382 // Not coupled/available for Coupling
1383 wfdie[ wfdielen++ ] = 0;
1385 wfdie[ wfdielen++ ] = 0;
1386 wfdie[ wfdielen++ ] = 0;
1387 wfdie[ wfdielen++ ] = 0;
1388 wfdie[ wfdielen++ ] = 0;
1389 wfdie[ wfdielen++ ] = 0;
1390 wfdie[ wfdielen++ ] = 0;
1393 rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
1399 u32 build_nego_confirm_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
1401 u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
1402 u32 len=0, wfdielen = 0;
1404 _adapter *padapter = pwdinfo->padapter;
1405 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1406 struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
1408 if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST))
1413 wfdie[ wfdielen++ ] = 0x50;
1414 wfdie[ wfdielen++ ] = 0x6F;
1415 wfdie[ wfdielen++ ] = 0x9A;
1416 wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
1418 // Commented by Albert 20110825
1419 // According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes
1420 // 1. WFD Device Information
1421 // 2. Associated BSSID ( Optional )
1422 // 3. Local IP Adress ( Optional )
1425 // WFD Device Information ATTR
1427 wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
1430 // Note: In the WFD specification, the size of length field is 2.
1431 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
1435 // WFD device information
1436 // WFD primary sink + WiFi Direct mode + WSD ( WFD Service Discovery ) + WFD Session Available
1437 val16 = pwfd_info->wfd_device_type | WFD_DEVINFO_WSD | WFD_DEVINFO_SESSION_AVAIL;
1438 RTW_PUT_BE16(wfdie + wfdielen, val16);
1442 // Session Management Control Port
1443 // Default TCP port for RTSP messages is 554
1444 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
1448 // WFD Device Maximum Throughput
1449 // 300Mbps is the maximum throughput
1450 RTW_PUT_BE16(wfdie + wfdielen, 300);
1453 // Associated BSSID ATTR
1455 wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
1458 // Note: In the WFD specification, the size of length field is 2.
1459 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
1464 if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE )
1466 _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
1470 _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
1473 wfdielen += ETH_ALEN;
1475 // Coupled Sink Information ATTR
1477 wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
1480 // Note: In the WFD specification, the size of length field is 2.
1481 RTW_PUT_BE16(wfdie + wfdielen, 0x0007);
1485 // Coupled Sink Status bitmap
1486 // Not coupled/available for Coupling
1487 wfdie[ wfdielen++ ] = 0;
1489 wfdie[ wfdielen++ ] = 0;
1490 wfdie[ wfdielen++ ] = 0;
1491 wfdie[ wfdielen++ ] = 0;
1492 wfdie[ wfdielen++ ] = 0;
1493 wfdie[ wfdielen++ ] = 0;
1494 wfdie[ wfdielen++ ] = 0;
1497 pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
1503 u32 build_invitation_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
1505 u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
1506 u32 len=0, wfdielen = 0;
1508 _adapter *padapter = pwdinfo->padapter;
1509 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1510 struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
1512 if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST))
1517 wfdie[ wfdielen++ ] = 0x50;
1518 wfdie[ wfdielen++ ] = 0x6F;
1519 wfdie[ wfdielen++ ] = 0x9A;
1520 wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
1522 // Commented by Albert 20110825
1523 // According to the WFD Specification, the provision discovery request frame should contain 3 WFD attributes
1524 // 1. WFD Device Information
1525 // 2. Associated BSSID ( Optional )
1526 // 3. Local IP Adress ( Optional )
1529 // WFD Device Information ATTR
1531 wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
1534 // Note: In the WFD specification, the size of length field is 2.
1535 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
1539 // WFD device information
1540 // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery )
1541 val16 = pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD;
1542 RTW_PUT_BE16(wfdie + wfdielen, val16);
1546 // Session Management Control Port
1547 // Default TCP port for RTSP messages is 554
1548 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
1552 // WFD Device Maximum Throughput
1553 // 300Mbps is the maximum throughput
1554 RTW_PUT_BE16(wfdie + wfdielen, 300);
1557 // Associated BSSID ATTR
1559 wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
1562 // Note: In the WFD specification, the size of length field is 2.
1563 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
1568 if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE )
1570 _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
1574 _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
1577 wfdielen += ETH_ALEN;
1579 // Coupled Sink Information ATTR
1581 wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
1584 // Note: In the WFD specification, the size of length field is 2.
1585 RTW_PUT_BE16(wfdie + wfdielen, 0x0007);
1589 // Coupled Sink Status bitmap
1590 // Not coupled/available for Coupling
1591 wfdie[ wfdielen++ ] = 0;
1593 wfdie[ wfdielen++ ] = 0;
1594 wfdie[ wfdielen++ ] = 0;
1595 wfdie[ wfdielen++ ] = 0;
1596 wfdie[ wfdielen++ ] = 0;
1597 wfdie[ wfdielen++ ] = 0;
1598 wfdie[ wfdielen++ ] = 0;
1600 if ( P2P_ROLE_GO == pwdinfo->role )
1602 // WFD Session Information ATTR
1604 wfdie[ wfdielen++ ] = WFD_ATTR_SESSION_INFO;
1607 // Note: In the WFD specification, the size of length field is 2.
1608 RTW_PUT_BE16(wfdie + wfdielen, 0x0000);
1611 // Todo: to add the list of WFD device info descriptor in WFD group.
1615 rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
1621 u32 build_invitation_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
1623 u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
1625 u32 len=0, wfdielen = 0;
1626 _adapter *padapter = pwdinfo->padapter;
1627 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1628 struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
1630 if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST))
1635 wfdie[ wfdielen++ ] = 0x50;
1636 wfdie[ wfdielen++ ] = 0x6F;
1637 wfdie[ wfdielen++ ] = 0x9A;
1638 wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
1640 // Commented by Albert 20110825
1641 // According to the WFD Specification, the provision discovery request frame should contain 3 WFD attributes
1642 // 1. WFD Device Information
1643 // 2. Associated BSSID ( Optional )
1644 // 3. Local IP Adress ( Optional )
1647 // WFD Device Information ATTR
1649 wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
1652 // Note: In the WFD specification, the size of length field is 2.
1653 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
1657 // WFD device information
1658 // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery )
1659 val16 = pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD;
1660 RTW_PUT_BE16(wfdie + wfdielen, val16);
1664 // Session Management Control Port
1665 // Default TCP port for RTSP messages is 554
1666 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
1670 // WFD Device Maximum Throughput
1671 // 300Mbps is the maximum throughput
1672 RTW_PUT_BE16(wfdie + wfdielen, 300);
1675 // Associated BSSID ATTR
1677 wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
1680 // Note: In the WFD specification, the size of length field is 2.
1681 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
1686 if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE )
1688 _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
1692 _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
1695 wfdielen += ETH_ALEN;
1697 // Coupled Sink Information ATTR
1699 wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
1702 // Note: In the WFD specification, the size of length field is 2.
1703 RTW_PUT_BE16(wfdie + wfdielen, 0x0007);
1707 // Coupled Sink Status bitmap
1708 // Not coupled/available for Coupling
1709 wfdie[ wfdielen++ ] = 0;
1711 wfdie[ wfdielen++ ] = 0;
1712 wfdie[ wfdielen++ ] = 0;
1713 wfdie[ wfdielen++ ] = 0;
1714 wfdie[ wfdielen++ ] = 0;
1715 wfdie[ wfdielen++ ] = 0;
1716 wfdie[ wfdielen++ ] = 0;
1718 if ( P2P_ROLE_GO == pwdinfo->role )
1720 // WFD Session Information ATTR
1722 wfdie[ wfdielen++ ] = WFD_ATTR_SESSION_INFO;
1725 // Note: In the WFD specification, the size of length field is 2.
1726 RTW_PUT_BE16(wfdie + wfdielen, 0x0000);
1729 // Todo: to add the list of WFD device info descriptor in WFD group.
1733 rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
1739 u32 build_provdisc_req_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
1741 u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
1742 u32 len=0, wfdielen = 0;
1744 _adapter *padapter = pwdinfo->padapter;
1745 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1746 struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
1748 if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST))
1753 wfdie[ wfdielen++ ] = 0x50;
1754 wfdie[ wfdielen++ ] = 0x6F;
1755 wfdie[ wfdielen++ ] = 0x9A;
1756 wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
1758 // Commented by Albert 20110825
1759 // According to the WFD Specification, the provision discovery request frame should contain 3 WFD attributes
1760 // 1. WFD Device Information
1761 // 2. Associated BSSID ( Optional )
1762 // 3. Local IP Adress ( Optional )
1765 // WFD Device Information ATTR
1767 wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
1770 // Note: In the WFD specification, the size of length field is 2.
1771 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
1775 // WFD device information
1776 // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery )
1777 val16 = pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD;
1778 RTW_PUT_BE16(wfdie + wfdielen, val16);
1782 // Session Management Control Port
1783 // Default TCP port for RTSP messages is 554
1784 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
1788 // WFD Device Maximum Throughput
1789 // 300Mbps is the maximum throughput
1790 RTW_PUT_BE16(wfdie + wfdielen, 300);
1793 // Associated BSSID ATTR
1795 wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
1798 // Note: In the WFD specification, the size of length field is 2.
1799 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
1804 if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE )
1806 _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
1810 _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
1813 wfdielen += ETH_ALEN;
1815 // Coupled Sink Information ATTR
1817 wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
1820 // Note: In the WFD specification, the size of length field is 2.
1821 RTW_PUT_BE16(wfdie + wfdielen, 0x0007);
1825 // Coupled Sink Status bitmap
1826 // Not coupled/available for Coupling
1827 wfdie[ wfdielen++ ] = 0;
1829 wfdie[ wfdielen++ ] = 0;
1830 wfdie[ wfdielen++ ] = 0;
1831 wfdie[ wfdielen++ ] = 0;
1832 wfdie[ wfdielen++ ] = 0;
1833 wfdie[ wfdielen++ ] = 0;
1834 wfdie[ wfdielen++ ] = 0;
1837 rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
1843 u32 build_provdisc_resp_wfd_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
1845 u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
1846 u32 len=0, wfdielen = 0;
1848 _adapter *padapter = pwdinfo->padapter;
1849 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1850 struct wifi_display_info* pwfd_info = padapter->wdinfo.wfd_info;
1852 if (!hal_chk_wl_func(padapter, WL_FUNC_MIRACAST))
1857 wfdie[ wfdielen++ ] = 0x50;
1858 wfdie[ wfdielen++ ] = 0x6F;
1859 wfdie[ wfdielen++ ] = 0x9A;
1860 wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
1862 // Commented by Albert 20110825
1863 // According to the WFD Specification, the provision discovery response frame should contain 3 WFD attributes
1864 // 1. WFD Device Information
1865 // 2. Associated BSSID ( Optional )
1866 // 3. Local IP Adress ( Optional )
1869 // WFD Device Information ATTR
1871 wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
1874 // Note: In the WFD specification, the size of length field is 2.
1875 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
1879 // WFD device information
1880 // WFD primary sink + available for WFD session + WiFi Direct mode + WSD ( WFD Service Discovery )
1881 val16 = pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL | WFD_DEVINFO_WSD;
1882 RTW_PUT_BE16(wfdie + wfdielen, val16);
1886 // Session Management Control Port
1887 // Default TCP port for RTSP messages is 554
1888 RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
1892 // WFD Device Maximum Throughput
1893 // 300Mbps is the maximum throughput
1894 RTW_PUT_BE16(wfdie + wfdielen, 300);
1897 // Associated BSSID ATTR
1899 wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
1902 // Note: In the WFD specification, the size of length field is 2.
1903 RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
1908 if ( check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE )
1910 _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
1914 _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
1917 wfdielen += ETH_ALEN;
1919 // Coupled Sink Information ATTR
1921 wfdie[ wfdielen++ ] = WFD_ATTR_COUPLED_SINK_INFO;
1924 // Note: In the WFD specification, the size of length field is 2.
1925 RTW_PUT_BE16(wfdie + wfdielen, 0x0007);
1929 // Coupled Sink Status bitmap
1930 // Not coupled/available for Coupling
1931 wfdie[ wfdielen++ ] = 0;
1933 wfdie[ wfdielen++ ] = 0;
1934 wfdie[ wfdielen++ ] = 0;
1935 wfdie[ wfdielen++ ] = 0;
1936 wfdie[ wfdielen++ ] = 0;
1937 wfdie[ wfdielen++ ] = 0;
1938 wfdie[ wfdielen++ ] = 0;
1940 rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, &len);
1945 #endif /* CONFIG_WFD */
1947 u32 build_probe_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
1949 u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 };
1950 u32 len=0, p2pielen = 0;
1951 #ifdef CONFIG_INTEL_WIDI
1952 struct mlme_priv *pmlmepriv = &(pwdinfo->padapter->mlmepriv);
1953 u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
1954 u8 widi_version = 0, i = 0;
1956 if( _rtw_memcmp( pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN ) == _FALSE )
1960 else if( pmlmepriv->num_p2p_sdt != 0 )
1964 #endif //CONFIG_INTEL_WIDI
1968 p2pie[ p2pielen++ ] = 0x50;
1969 p2pie[ p2pielen++ ] = 0x6F;
1970 p2pie[ p2pielen++ ] = 0x9A;
1971 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
1973 // Commented by Albert 20100907
1974 // According to the P2P Specification, the probe response frame should contain 5 P2P attributes
1975 // 1. P2P Capability
1976 // 2. Extended Listen Timing
1977 // 3. Notice of Absence ( NOA ) ( Only GO needs this )
1979 // 5. Group Info ( Only GO need this )
1981 // P2P Capability ATTR
1983 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
1986 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
1987 RTW_PUT_LE16(p2pie + p2pielen, 0x0002);
1991 // Device Capability Bitmap, 1 byte
1992 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
1994 // Group Capability Bitmap, 1 byte
1995 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
1997 p2pie[ p2pielen ] = (P2P_GRPCAP_GO | P2P_GRPCAP_INTRABSS);
1999 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
2000 p2pie[ p2pielen ] |= P2P_GRPCAP_GROUP_FORMATION;
2004 else if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) )
2006 // Group Capability Bitmap, 1 byte
2007 if ( pwdinfo->persistent_supported )
2008 p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
2010 p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
2013 // Extended Listen Timing ATTR
2015 p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
2018 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
2019 RTW_PUT_LE16(p2pie + p2pielen, 0x0004);
2023 // Availability Period
2024 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
2025 RTW_PUT_LE16(p2pie + p2pielen, 0xFFFF);
2028 // Availability Interval
2029 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
2030 RTW_PUT_LE16(p2pie + p2pielen, 0xFFFF);
2034 // Notice of Absence ATTR
2038 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
2040 //go_add_noa_attr(pwdinfo);
2045 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
2048 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
2049 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
2050 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
2051 #ifdef CONFIG_INTEL_WIDI
2052 if( widi_version == 35 )
2054 RTW_PUT_LE16(p2pie + p2pielen, 21 + 8 + pwdinfo->device_name_len);
2056 else if( widi_version == 40 )
2058 RTW_PUT_LE16(p2pie + p2pielen, 21 + 8 * pmlmepriv->num_p2p_sdt + pwdinfo->device_name_len);
2061 #endif //CONFIG_INTEL_WIDI
2062 RTW_PUT_LE16(p2pie + p2pielen, 21 + pwdinfo->device_name_len);
2066 // P2P Device Address
2067 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN );
2068 p2pielen += ETH_ALEN;
2071 // This field should be big endian. Noted by P2P specification.
2072 //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
2073 RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->supported_wps_cm);
2076 #ifdef CONFIG_INTEL_WIDI
2077 if( widi_version == 40 )
2079 // Primary Device Type
2081 //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
2082 RTW_PUT_BE16(p2pie + p2pielen, pmlmepriv->p2p_pdt_cid );
2086 //*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
2087 RTW_PUT_BE32(p2pie + p2pielen, WPSOUI);
2091 //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
2092 RTW_PUT_BE16(p2pie + p2pielen, pmlmepriv->p2p_pdt_scid);
2096 #endif //CONFIG_INTEL_WIDI
2098 // Primary Device Type
2100 //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
2101 RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_MULIT_MEDIA);
2105 //*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
2106 RTW_PUT_BE32(p2pie + p2pielen, WPSOUI);
2110 //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
2111 RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_SCID_MEDIA_SERVER);
2115 // Number of Secondary Device Types
2116 #ifdef CONFIG_INTEL_WIDI
2117 if( widi_version == 35 )
2119 p2pie[ p2pielen++ ] = 0x01;
2121 RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_DISPLAYS);
2124 RTW_PUT_BE32(p2pie + p2pielen, INTEL_DEV_TYPE_OUI);
2127 RTW_PUT_BE16(p2pie + p2pielen, P2P_SCID_WIDI_CONSUMER_SINK);
2130 else if( widi_version == 40 )
2132 p2pie[ p2pielen++ ] = pmlmepriv->num_p2p_sdt;
2133 for( ; i < pmlmepriv->num_p2p_sdt; i++ )
2135 RTW_PUT_BE16(p2pie + p2pielen, pmlmepriv->p2p_sdt_cid[i]);
2138 RTW_PUT_BE32(p2pie + p2pielen, INTEL_DEV_TYPE_OUI);
2141 RTW_PUT_BE16(p2pie + p2pielen, pmlmepriv->p2p_sdt_scid[i]);
2146 #endif //CONFIG_INTEL_WIDI
2147 p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
2151 //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
2152 RTW_PUT_BE16(p2pie + p2pielen, WPS_ATTR_DEVICE_NAME);
2156 //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
2157 RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->device_name_len);
2161 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
2162 p2pielen += pwdinfo->device_name_len;
2168 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
2170 p2pielen += go_add_group_info_attr(pwdinfo, p2pie + p2pielen);
2174 pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &len);
2181 u32 build_prov_disc_request_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8* pssid, u8 ussidlen, u8* pdev_raddr )
2183 u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 };
2184 u32 len=0, p2pielen = 0;
2188 p2pie[ p2pielen++ ] = 0x50;
2189 p2pie[ p2pielen++ ] = 0x6F;
2190 p2pie[ p2pielen++ ] = 0x9A;
2191 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
2193 // Commented by Albert 20110301
2194 // According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes
2195 // 1. P2P Capability
2197 // 3. Group ID ( When joining an operating P2P Group )
2199 // P2P Capability ATTR
2201 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
2204 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
2205 RTW_PUT_LE16(p2pie + p2pielen, 0x0002);
2209 // Device Capability Bitmap, 1 byte
2210 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
2212 // Group Capability Bitmap, 1 byte
2213 if ( pwdinfo->persistent_supported )
2214 p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
2216 p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
2221 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
2224 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
2225 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
2226 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
2227 RTW_PUT_LE16(p2pie + p2pielen, 21 + pwdinfo->device_name_len);
2231 // P2P Device Address
2232 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN );
2233 p2pielen += ETH_ALEN;
2236 // This field should be big endian. Noted by P2P specification.
2237 if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC )
2239 //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_PBC );
2240 RTW_PUT_BE16(p2pie + p2pielen, WPS_CONFIG_METHOD_PBC);
2244 //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
2245 RTW_PUT_BE16(p2pie + p2pielen, WPS_CONFIG_METHOD_DISPLAY);
2250 // Primary Device Type
2252 //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
2253 RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_MULIT_MEDIA);
2257 //*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
2258 RTW_PUT_BE32(p2pie + p2pielen, WPSOUI);
2262 //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
2263 RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_SCID_MEDIA_SERVER);
2266 // Number of Secondary Device Types
2267 p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
2271 //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
2272 RTW_PUT_BE16(p2pie + p2pielen, WPS_ATTR_DEVICE_NAME);
2276 //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
2277 RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->device_name_len);
2281 _rtw_memcpy( p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
2282 p2pielen += pwdinfo->device_name_len;
2284 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
2286 // Added by Albert 2011/05/19
2287 // In this case, the pdev_raddr is the device address of the group owner.
2289 // P2P Group ID ATTR
2291 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
2294 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + ussidlen );
2295 RTW_PUT_LE16(p2pie + p2pielen, ETH_ALEN + ussidlen);
2299 _rtw_memcpy( p2pie + p2pielen, pdev_raddr, ETH_ALEN );
2300 p2pielen += ETH_ALEN;
2302 _rtw_memcpy( p2pie + p2pielen, pssid, ussidlen );
2303 p2pielen += ussidlen;
2307 pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &len);
2315 u32 build_assoc_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 status_code)
2317 u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 };
2318 u32 len=0, p2pielen = 0;
2322 p2pie[ p2pielen++ ] = 0x50;
2323 p2pie[ p2pielen++ ] = 0x6F;
2324 p2pie[ p2pielen++ ] = 0x9A;
2325 p2pie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
2327 // According to the P2P Specification, the Association response frame should contain 2 P2P attributes
2329 // 2. Extended Listen Timing (optional)
2333 p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status_code);
2336 // Extended Listen Timing ATTR
2342 pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &len);
2348 u32 build_deauth_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
2355 u32 process_probe_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
2361 int ssid_len=0, rate_cnt = 0;
2363 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SUPPORTEDRATES_IE_, (int *)&rate_cnt,
2364 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
2366 if ( rate_cnt <= 4 )
2370 for( i = 0; i < rate_cnt; i++ )
2372 if ( ( ( *( p + 2 + i ) & 0xff ) != 0x02 ) &&
2373 ( ( *( p + 2 + i ) & 0xff ) != 0x04 ) &&
2374 ( ( *( p + 2 + i ) & 0xff ) != 0x0B ) &&
2375 ( ( *( p + 2 + i ) & 0xff ) != 0x16 ) )
2383 // There is no OFDM rate included in SupportedRates IE of this probe request frame
2384 // The driver should response this probe request.
2390 // rate_cnt > 4 means the SupportRates IE contains the OFDM rate because the count of CCK rates are 4.
2391 // We should proceed the following check for this probe request.
2394 // Added comments by Albert 20100906
2395 // There are several items we should check here.
2396 // 1. This probe request frame must contain the P2P IE. (Done)
2397 // 2. This probe request frame must contain the wildcard SSID. (Done)
2398 // 3. Wildcard BSSID. (Todo)
2399 // 4. Destination Address. ( Done in mgt_dispatcher function )
2400 // 5. Requested Device Type in WSC IE. (Todo)
2401 // 6. Device ID attribute in P2P IE. (Todo)
2403 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ssid_len,
2404 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
2406 ssid_len &= 0xff; // Just last 1 byte is valid for ssid len of the probe request
2407 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
2409 if((p2pie=rtw_get_p2p_ie( pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_ , len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_ , NULL, &p2pielen)))
2411 if ( (p != NULL) && _rtw_memcmp( ( void * ) ( p+2 ), ( void * ) pwdinfo->p2p_wildcard_ssid , 7 ))
2414 //Check Requested Device Type attributes in WSC IE.
2415 //Check Device ID attribute in P2P IE
2419 else if ( (p != NULL) && ( ssid_len == 0 ) )
2436 u32 process_assoc_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint len, struct sta_info *psta)
2438 u8 status_code = P2P_STATUS_SUCCESS;
2439 u8 *pbuf, *pattr_content=NULL;
2440 u32 attr_contentlen = 0;
2442 unsigned short frame_type, ie_offset=0;
2448 if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
2449 return P2P_STATUS_FAIL_REQUEST_UNABLE;
2451 frame_type = GetFrameSubType(pframe);
2452 if (frame_type == WIFI_ASSOCREQ)
2454 ie_offset = _ASOCREQ_IE_OFFSET_;
2456 else // WIFI_REASSOCREQ
2458 ie_offset = _REASOCREQ_IE_OFFSET_;
2461 ies = pframe + WLAN_HDR_A3_LEN + ie_offset;
2462 ies_len = len - WLAN_HDR_A3_LEN - ie_offset;
2464 p2p_ie = rtw_get_p2p_ie(ies , ies_len , NULL, &p2p_ielen);
2468 DBG_8192C( "[%s] P2P IE not Found!!\n", __FUNCTION__ );
2469 status_code = P2P_STATUS_FAIL_INVALID_PARAM;
2473 DBG_8192C( "[%s] P2P IE Found!!\n", __FUNCTION__ );
2478 //Check P2P Capability ATTR
2479 if( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*) &attr_contentlen) )
2481 DBG_8192C( "[%s] Got P2P Capability Attr!!\n", __FUNCTION__ );
2482 cap_attr = le16_to_cpu(cap_attr);
2483 psta->dev_cap = cap_attr&0xff;
2486 //Check Extended Listen Timing ATTR
2489 //Check P2P Device Info ATTR
2490 if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, NULL, (uint*)&attr_contentlen))
2492 DBG_8192C( "[%s] Got P2P DEVICE INFO Attr!!\n", __FUNCTION__ );
2493 pattr_content = pbuf = rtw_zmalloc(attr_contentlen);
2496 u8 num_of_secdev_type;
2500 rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO , pattr_content, (uint*)&attr_contentlen);
2502 _rtw_memcpy(psta->dev_addr, pattr_content, ETH_ALEN);//P2P Device Address
2504 pattr_content += ETH_ALEN;
2506 _rtw_memcpy(&psta->config_methods, pattr_content, 2);//Config Methods
2507 psta->config_methods = be16_to_cpu(psta->config_methods);
2511 _rtw_memcpy(psta->primary_dev_type, pattr_content, 8);
2515 num_of_secdev_type = *pattr_content;
2518 if(num_of_secdev_type==0)
2520 psta->num_of_secdev_type = 0;
2526 psta->num_of_secdev_type = num_of_secdev_type;
2528 len = (sizeof(psta->secdev_types_list)<(num_of_secdev_type*8)) ? (sizeof(psta->secdev_types_list)) : (num_of_secdev_type*8);
2530 _rtw_memcpy(psta->secdev_types_list, pattr_content, len);
2532 pattr_content += (num_of_secdev_type*8);
2536 //dev_name_len = attr_contentlen - ETH_ALEN - 2 - 8 - 1 - (num_of_secdev_type*8);
2537 psta->dev_name_len=0;
2538 if(WPS_ATTR_DEVICE_NAME == be16_to_cpu(*(u16*)pattr_content))
2540 dev_name_len = be16_to_cpu(*(u16*)(pattr_content+2));
2542 psta->dev_name_len = (sizeof(psta->dev_name)<dev_name_len) ? sizeof(psta->dev_name):dev_name_len;
2544 _rtw_memcpy(psta->dev_name, pattr_content+4, psta->dev_name_len);
2547 rtw_mfree(pbuf, attr_contentlen);
2553 //Get the next P2P IE
2554 p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
2562 u32 process_p2p_devdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
2565 u8 status, dialogToken;
2566 struct sta_info *psta = NULL;
2567 _adapter *padapter = pwdinfo->padapter;
2568 struct sta_priv *pstapriv = &padapter->stapriv;
2572 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
2574 dialogToken = frame_body[7];
2575 status = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
2577 if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
2579 u8 groupid[ 38 ] = { 0x00 };
2580 u8 dev_addr[ETH_ALEN] = { 0x00 };
2581 u32 attr_contentlen = 0;
2583 if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen))
2585 if(_rtw_memcmp(pwdinfo->device_addr, groupid, ETH_ALEN) &&
2586 _rtw_memcmp(pwdinfo->p2p_group_ssid, groupid+ETH_ALEN, pwdinfo->p2p_group_ssid_len))
2589 if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_ID, dev_addr, &attr_contentlen))
2592 _list *phead, *plist;
2594 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2595 phead = &pstapriv->asoc_list;
2596 plist = get_next(phead);
2598 //look up sta asoc_queue
2599 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
2601 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
2603 plist = get_next(plist);
2605 if(psta->is_p2p_device && (psta->dev_cap&P2P_DEVCAP_CLIENT_DISCOVERABILITY) &&
2606 _rtw_memcmp(psta->dev_addr, dev_addr, ETH_ALEN))
2609 //_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2610 //issue GO Discoverability Request
2611 issue_group_disc_req(pwdinfo, psta->hwaddr);
2612 //_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2614 status = P2P_STATUS_SUCCESS;
2620 status = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
2624 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2629 status = P2P_STATUS_FAIL_INVALID_PARAM;
2635 status = P2P_STATUS_FAIL_INVALID_PARAM;
2643 //issue Device Discoverability Response
2644 issue_p2p_devdisc_resp(pwdinfo, GetAddr2Ptr(pframe), status, dialogToken);
2647 return (status==P2P_STATUS_SUCCESS) ? _TRUE:_FALSE;
2651 u32 process_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
2656 u8 process_p2p_provdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len )
2660 uint wps_ielen = 0, attr_contentlen = 0;
2661 u16 uconfig_method = 0;
2664 frame_body = (pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
2666 if ( (wpsie=rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &wps_ielen)) )
2668 if ( rtw_get_wps_attr_content( wpsie, wps_ielen, WPS_ATTR_CONF_METHOD , ( u8* ) &uconfig_method, &attr_contentlen) )
2670 uconfig_method = be16_to_cpu( uconfig_method );
2671 switch( uconfig_method )
2673 case WPS_CM_DISPLYA:
2675 _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3 );
2680 _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "lab", 3 );
2683 case WPS_CM_PUSH_BUTTON:
2685 _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3 );
2690 _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3 );
2694 issue_p2p_provision_resp( pwdinfo, GetAddr2Ptr(pframe), frame_body, uconfig_method);
2697 DBG_871X( "[%s] config method = %s\n", __FUNCTION__, pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req );
2702 u8 process_p2p_provdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe)
2708 u8 rtw_p2p_get_peer_ch_list(struct wifidirect_info *pwdinfo, u8 *ch_content, u8 ch_cnt, u8 *peer_ch_list)
2721 for( i = 0 ; i < temp ; i++, j++ )
2723 peer_ch_list[j] = *( ch_content + 1 + i );
2725 ch_content += (temp + 1);
2726 ch_cnt -= (temp + 1);
2733 u8 rtw_p2p_check_peer_oper_ch(struct mlme_ext_priv *pmlmeext, u8 ch)
2737 for( i = 0; i < pmlmeext->max_chan_nums; i++ )
2739 if ( pmlmeext->channel_set[ i ].ChannelNum == ch )
2748 u8 rtw_p2p_ch_inclusion(struct mlme_ext_priv *pmlmeext, u8 *peer_ch_list, u8 peer_ch_num, u8 *ch_list_inclusioned)
2750 int i = 0, j = 0, temp = 0;
2753 for( i = 0; i < peer_ch_num; i++ )
2755 for( j = temp; j < pmlmeext->max_chan_nums; j++ )
2757 if( *( peer_ch_list + i ) == pmlmeext->channel_set[ j ].ChannelNum )
2759 ch_list_inclusioned[ ch_no++ ] = *( peer_ch_list + i );
2769 u8 process_p2p_group_negotation_req( struct wifidirect_info *pwdinfo, u8 *pframe, uint len )
2771 _adapter *padapter = pwdinfo->padapter;
2772 u8 result = P2P_STATUS_SUCCESS;
2773 u32 p2p_ielen = 0, wps_ielen = 0;
2778 u16 wps_devicepassword_id = 0x0000;
2779 uint wps_devicepassword_id_len = 0;
2782 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
2783 #endif // CONFIG_TDLS
2784 #endif // CONFIG_WFD
2785 #ifdef CONFIG_CONCURRENT_MODE
2786 _adapter *pbuddy_adapter = pwdinfo->padapter->pbuddy_adapter;
2787 struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
2788 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
2789 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
2792 if ( (wpsie=rtw_get_wps_ie( pframe + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &wps_ielen)) )
2794 // Commented by Kurt 20120113
2795 // If some device wants to do p2p handshake without sending prov_disc_req
2796 // We have to get peer_req_cm from here.
2797 if(_rtw_memcmp( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3) )
2799 rtw_get_wps_attr_content( wpsie, wps_ielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
2800 wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id );
2802 if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
2804 _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3 );
2806 else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
2808 _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3 );
2812 _rtw_memcpy( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3 );
2818 DBG_871X( "[%s] WPS IE not Found!!\n", __FUNCTION__ );
2819 result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
2820 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
2824 ies = pframe + _PUBLIC_ACTION_IE_OFFSET_;
2825 ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
2827 p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen );
2831 DBG_871X( "[%s] P2P IE not Found!!\n", __FUNCTION__ );
2832 result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
2833 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
2838 u8 attr_content = 0x00;
2839 u32 attr_contentlen = 0;
2840 u8 ch_content[100] = { 0x00 };
2842 u8 peer_ch_list[100] = { 0x00 };
2844 u8 ch_list_inclusioned[100] = { 0x00 };
2845 u8 ch_num_inclusioned = 0;
2847 u8 listen_ch_attr[5] = { 0x00 };
2849 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING);
2851 //Check P2P Capability ATTR
2852 if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*)&attr_contentlen) )
2854 cap_attr = le16_to_cpu(cap_attr);
2856 #if defined(CONFIG_WFD) && defined(CONFIG_TDLS)
2857 if(!(cap_attr & P2P_GRPCAP_INTRABSS) )
2858 ptdlsinfo->ap_prohibited = _TRUE;
2859 #endif //defined(CONFIG_WFD) && defined(CONFIG_TDLS)
2862 if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT , &attr_content, &attr_contentlen) )
2864 DBG_871X( "[%s] GO Intent = %d, tie = %d\n", __FUNCTION__, attr_content >> 1, attr_content & 0x01 );
2865 pwdinfo->peer_intent = attr_content; // include both intent and tie breaker values.
2867 if ( pwdinfo->intent == ( pwdinfo->peer_intent >> 1 ) )
2869 // Try to match the tie breaker value
2870 if ( pwdinfo->intent == P2P_MAX_INTENT )
2872 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
2873 result = P2P_STATUS_FAIL_BOTH_GOINTENT_15;
2877 if ( attr_content & 0x01 )
2879 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
2883 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
2887 else if ( pwdinfo->intent > ( pwdinfo->peer_intent >> 1 ) )
2889 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
2893 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
2896 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
2898 // Store the group id information.
2899 _rtw_memcpy( pwdinfo->groupid_info.go_device_addr, pwdinfo->device_addr, ETH_ALEN );
2900 _rtw_memcpy( pwdinfo->groupid_info.ssid, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
2904 if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, (u8 *)listen_ch_attr, (uint *) &attr_contentlen) && attr_contentlen == 5)
2905 pwdinfo->nego_req_info.peer_ch = listen_ch_attr[4];
2907 DBG_871X(FUNC_ADPT_FMT" listen channel :%u\n", FUNC_ADPT_ARG(padapter), pwdinfo->nego_req_info.peer_ch);
2909 attr_contentlen = 0;
2910 if ( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_INTENTED_IF_ADDR, pwdinfo->p2p_peer_interface_addr, &attr_contentlen ) )
2912 if ( attr_contentlen != ETH_ALEN )
2914 _rtw_memset( pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN );
2918 if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, ch_content, &ch_cnt) )
2920 peer_ch_num = rtw_p2p_get_peer_ch_list(pwdinfo, ch_content, ch_cnt, peer_ch_list);
2921 ch_num_inclusioned = rtw_p2p_ch_inclusion(&padapter->mlmeextpriv, peer_ch_list, peer_ch_num, ch_list_inclusioned);
2923 if( ch_num_inclusioned == 0)
2925 DBG_871X( "[%s] No common channel in channel list!\n", __FUNCTION__ );
2926 result = P2P_STATUS_FAIL_NO_COMMON_CH;
2927 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
2931 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
2933 if ( !rtw_p2p_is_channel_list_ok( pwdinfo->operating_channel,
2934 ch_list_inclusioned, ch_num_inclusioned) )
2936 #ifdef CONFIG_CONCURRENT_MODE
2937 if (check_buddy_fwstate(padapter, _FW_LINKED)
2938 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
2940 DBG_871X( "[%s] desired channel NOT Found!\n", __FUNCTION__ );
2941 result = P2P_STATUS_FAIL_NO_COMMON_CH;
2942 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
2946 #endif //CONFIG_CONCURRENT_MODE
2948 u8 operatingch_info[5] = { 0x00 }, peer_operating_ch = 0;
2949 attr_contentlen = 0;
2951 if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) )
2953 peer_operating_ch = operatingch_info[4];
2956 if ( rtw_p2p_is_channel_list_ok( peer_operating_ch,
2957 ch_list_inclusioned, ch_num_inclusioned) )
2960 * Change our operating channel as peer's for compatibility.
2962 pwdinfo->operating_channel = peer_operating_ch;
2963 DBG_871X( "[%s] Change op ch to %02x as peer's\n", __FUNCTION__, pwdinfo->operating_channel);
2967 // Take first channel of ch_list_inclusioned as operating channel
2968 pwdinfo->operating_channel = ch_list_inclusioned[0];
2969 DBG_871X( "[%s] Change op ch to %02x\n", __FUNCTION__, pwdinfo->operating_channel);
2977 //Get the next P2P IE
2978 p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
2981 if (pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO) {
2982 result = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
2983 rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INFOR_NOREADY);
2988 rtw_process_wfd_ies(padapter, pframe + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, __func__);
2994 u8 process_p2p_group_negotation_resp( struct wifidirect_info *pwdinfo, u8 *pframe, uint len )
2996 _adapter *padapter = pwdinfo->padapter;
2997 u8 result = P2P_STATUS_SUCCESS;
2998 u32 p2p_ielen, wps_ielen;
3004 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
3005 #endif // CONFIG_TDLS
3006 #endif // CONFIG_WFD
3008 ies = pframe + _PUBLIC_ACTION_IE_OFFSET_;
3009 ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
3011 // Be able to know which one is the P2P GO and which one is P2P client.
3013 if ( rtw_get_wps_ie( ies, ies_len, NULL, &wps_ielen) )
3019 DBG_871X( "[%s] WPS IE not Found!!\n", __FUNCTION__ );
3020 result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
3021 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
3024 p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen );
3027 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
3028 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
3029 result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
3034 u8 attr_content = 0x00;
3035 u32 attr_contentlen = 0;
3036 u8 operatingch_info[5] = { 0x00 };
3038 u8 ch_content[100] = { 0x00 };
3041 u8 peer_ch_list[100] = { 0x00 };
3043 u8 ch_list_inclusioned[100] = { 0x00 };
3044 u8 ch_num_inclusioned = 0;
3046 while ( p2p_ie ) // Found the P2P IE.
3049 //Check P2P Capability ATTR
3050 if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*)&attr_contentlen) )
3052 cap_attr = le16_to_cpu(cap_attr);
3054 if(!(cap_attr & P2P_GRPCAP_INTRABSS) )
3055 ptdlsinfo->ap_prohibited = _TRUE;
3056 #endif // CONFIG_TDLS
3059 rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
3060 if ( attr_contentlen == 1 )
3062 DBG_871X( "[%s] Status = %d\n", __FUNCTION__, attr_content );
3063 if ( attr_content == P2P_STATUS_SUCCESS )
3069 if ( P2P_STATUS_FAIL_INFO_UNAVAILABLE == attr_content ) {
3070 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INFOR_NOREADY);
3072 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
3074 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
3075 result = attr_content;
3080 // Try to get the peer's interface address
3081 attr_contentlen = 0;
3082 if ( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_INTENTED_IF_ADDR, pwdinfo->p2p_peer_interface_addr, &attr_contentlen ) )
3084 if ( attr_contentlen != ETH_ALEN )
3086 _rtw_memset( pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN );
3090 // Try to get the peer's intent and tie breaker value.
3091 attr_content = 0x00;
3092 attr_contentlen = 0;
3093 if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT , &attr_content, &attr_contentlen) )
3095 DBG_871X( "[%s] GO Intent = %d, tie = %d\n", __FUNCTION__, attr_content >> 1, attr_content & 0x01 );
3096 pwdinfo->peer_intent = attr_content; // include both intent and tie breaker values.
3098 if ( pwdinfo->intent == ( pwdinfo->peer_intent >> 1 ) )
3100 // Try to match the tie breaker value
3101 if ( pwdinfo->intent == P2P_MAX_INTENT )
3103 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
3104 result = P2P_STATUS_FAIL_BOTH_GOINTENT_15;
3105 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
3109 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
3110 rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
3111 if ( attr_content & 0x01 )
3113 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
3117 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
3121 else if ( pwdinfo->intent > ( pwdinfo->peer_intent >> 1 ) )
3123 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
3124 rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
3125 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
3129 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
3130 rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
3131 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
3134 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
3136 // Store the group id information.
3137 _rtw_memcpy( pwdinfo->groupid_info.go_device_addr, pwdinfo->device_addr, ETH_ALEN );
3138 _rtw_memcpy( pwdinfo->groupid_info.ssid, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
3143 // Try to get the operation channel information
3145 attr_contentlen = 0;
3146 if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen))
3148 DBG_871X( "[%s] Peer's operating channel = %d\n", __FUNCTION__, operatingch_info[4] );
3149 pwdinfo->peer_operating_ch = operatingch_info[4];
3152 // Try to get the channel list information
3153 if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, pwdinfo->channel_list_attr, &pwdinfo->channel_list_attr_len ) )
3155 DBG_871X( "[%s] channel list attribute found, len = %d\n", __FUNCTION__, pwdinfo->channel_list_attr_len );
3157 peer_ch_num = rtw_p2p_get_peer_ch_list(pwdinfo, pwdinfo->channel_list_attr, pwdinfo->channel_list_attr_len, peer_ch_list);
3158 ch_num_inclusioned = rtw_p2p_ch_inclusion(&padapter->mlmeextpriv, peer_ch_list, peer_ch_num, ch_list_inclusioned);
3160 if( ch_num_inclusioned == 0)
3162 DBG_871X( "[%s] No common channel in channel list!\n", __FUNCTION__ );
3163 result = P2P_STATUS_FAIL_NO_COMMON_CH;
3164 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
3168 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
3170 if ( !rtw_p2p_is_channel_list_ok( pwdinfo->operating_channel,
3171 ch_list_inclusioned, ch_num_inclusioned) )
3173 #ifdef CONFIG_CONCURRENT_MODE
3174 if (check_buddy_fwstate(padapter, _FW_LINKED)
3175 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
3177 DBG_871X( "[%s] desired channel NOT Found!\n", __FUNCTION__ );
3178 result = P2P_STATUS_FAIL_NO_COMMON_CH;
3179 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
3183 #endif //CONFIG_CONCURRENT_MODE
3185 u8 operatingch_info[5] = { 0x00 }, peer_operating_ch = 0;
3186 attr_contentlen = 0;
3188 if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) )
3190 peer_operating_ch = operatingch_info[4];
3193 if ( rtw_p2p_is_channel_list_ok( peer_operating_ch,
3194 ch_list_inclusioned, ch_num_inclusioned) )
3197 * Change our operating channel as peer's for compatibility.
3199 pwdinfo->operating_channel = peer_operating_ch;
3200 DBG_871X( "[%s] Change op ch to %02x as peer's\n", __FUNCTION__, pwdinfo->operating_channel);
3204 // Take first channel of ch_list_inclusioned as operating channel
3205 pwdinfo->operating_channel = ch_list_inclusioned[0];
3206 DBG_871X( "[%s] Change op ch to %02x\n", __FUNCTION__, pwdinfo->operating_channel);
3216 DBG_871X( "[%s] channel list attribute not found!\n", __FUNCTION__);
3219 // Try to get the group id information if peer is GO
3220 attr_contentlen = 0;
3221 _rtw_memset( groupid, 0x00, 38 );
3222 if ( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen) )
3224 _rtw_memcpy( pwdinfo->groupid_info.go_device_addr, &groupid[0], ETH_ALEN );
3225 _rtw_memcpy( pwdinfo->groupid_info.ssid, &groupid[6], attr_contentlen - ETH_ALEN );
3228 //Get the next P2P IE
3229 p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
3235 rtw_process_wfd_ies(padapter, pframe + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, __func__);
3242 u8 process_p2p_group_negotation_confirm( struct wifidirect_info *pwdinfo, u8 *pframe, uint len )
3244 _adapter *padapter = pwdinfo->padapter;
3249 u8 result = P2P_STATUS_SUCCESS;
3250 ies = pframe + _PUBLIC_ACTION_IE_OFFSET_;
3251 ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
3253 p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen );
3254 while ( p2p_ie ) // Found the P2P IE.
3256 u8 attr_content = 0x00, operatingch_info[5] = { 0x00 };
3257 u8 groupid[ 38 ] = { 0x00 };
3258 u32 attr_contentlen = 0;
3260 pwdinfo->negotiation_dialog_token = 1;
3261 rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
3262 if ( attr_contentlen == 1 )
3264 DBG_871X( "[%s] Status = %d\n", __FUNCTION__, attr_content );
3265 result = attr_content;
3267 if ( attr_content == P2P_STATUS_SUCCESS )
3271 _cancel_timer( &pwdinfo->restore_p2p_state_timer, &bcancelled );
3273 // Commented by Albert 20100911
3274 // Todo: Need to handle the case which both Intents are the same.
3275 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
3276 rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
3277 if ( ( pwdinfo->intent ) > ( pwdinfo->peer_intent >> 1 ) )
3279 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
3281 else if ( ( pwdinfo->intent ) < ( pwdinfo->peer_intent >> 1 ) )
3283 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
3287 // Have to compare the Tie Breaker
3288 if ( pwdinfo->peer_intent & 0x01 )
3290 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
3294 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
3298 #ifdef CONFIG_CONCURRENT_MODE
3299 if (check_buddy_fwstate(padapter , _FW_LINKED)
3300 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
3302 // Switch back to the AP channel soon.
3303 _set_timer( &pwdinfo->ap_p2p_switch_timer, 100 );
3309 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
3310 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
3315 // Try to get the group id information
3316 attr_contentlen = 0;
3317 _rtw_memset( groupid, 0x00, 38 );
3318 if ( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen) )
3320 DBG_871X( "[%s] Ssid = %s, ssidlen = %zu\n", __FUNCTION__, &groupid[ETH_ALEN], strlen(&groupid[ETH_ALEN]) );
3321 _rtw_memcpy( pwdinfo->groupid_info.go_device_addr, &groupid[0], ETH_ALEN );
3322 _rtw_memcpy( pwdinfo->groupid_info.ssid, &groupid[6], attr_contentlen - ETH_ALEN );
3325 attr_contentlen = 0;
3326 if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) )
3328 DBG_871X( "[%s] Peer's operating channel = %d\n", __FUNCTION__, operatingch_info[4] );
3329 pwdinfo->peer_operating_ch = operatingch_info[4];
3332 //Get the next P2P IE
3333 p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
3340 u8 process_p2p_presence_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
3344 u8 status = P2P_STATUS_SUCCESS;
3346 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
3348 dialogToken = frame_body[6];
3350 //todo: check NoA attribute
3352 issue_p2p_presence_resp(pwdinfo, GetAddr2Ptr(pframe), status, dialogToken);
3357 void find_phase_handler( _adapter* padapter )
3359 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3360 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3361 NDIS_802_11_SSID ssid;
3367 _rtw_memset((unsigned char*)&ssid, 0, sizeof(NDIS_802_11_SSID));
3368 _rtw_memcpy(ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN );
3369 ssid.SsidLength = P2P_WILDCARD_SSID_LEN;
3371 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
3373 _enter_critical_bh(&pmlmepriv->lock, &irqL);
3374 _status = rtw_sitesurvey_cmd(padapter, &ssid, 1, NULL, 0);
3375 _exit_critical_bh(&pmlmepriv->lock, &irqL);
3381 void p2p_concurrent_handler( _adapter* padapter );
3383 void restore_p2p_state_handler( _adapter* padapter )
3385 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3386 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3390 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
3392 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
3395 #ifdef CONFIG_CONCURRENT_MODE
3396 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
3398 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
3399 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
3400 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
3402 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP))
3404 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
3406 issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500);
3411 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
3413 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE))
3415 #ifdef CONFIG_CONCURRENT_MODE
3416 p2p_concurrent_handler( padapter );
3418 // In the P2P client mode, the driver should not switch back to its listen channel
3419 // because this P2P client should stay at the operating channel of P2P GO.
3420 set_channel_bwmode( padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
3426 void pre_tx_invitereq_handler( _adapter* padapter )
3428 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3432 set_channel_bwmode(padapter, pwdinfo->invitereq_info.peer_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
3433 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
3434 issue_probereq_p2p(padapter, NULL);
3435 _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
3440 void pre_tx_provdisc_handler( _adapter* padapter )
3442 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3446 set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
3447 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
3448 issue_probereq_p2p(padapter, NULL);
3449 _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
3454 void pre_tx_negoreq_handler( _adapter* padapter )
3456 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3460 set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
3461 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
3462 issue_probereq_p2p(padapter , NULL);
3463 /* WIN Phone only accept unicast probe request when nego back */
3464 issue_probereq_p2p(padapter , pwdinfo->nego_req_info.peerDevAddr);
3465 _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
3470 #ifdef CONFIG_CONCURRENT_MODE
3471 void p2p_concurrent_handler( _adapter* padapter )
3473 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3474 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3475 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3476 //_adapter *pbuddy_adapter = padapter->pbuddy_adapter;
3477 //struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
3478 //struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
3479 //struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
3483 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
3485 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
3486 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
3488 pwdinfo->operating_channel = pbuddy_mlmeext->cur_channel;
3490 if( pwdinfo->driver_interface == DRIVER_CFG80211 )
3492 DBG_871X("%s, switch ch back to buddy's cur_channel=%d\n", __func__, pbuddy_mlmeext->cur_channel);
3494 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
3496 if (check_buddy_fwstate(padapter, WIFI_FW_STATION_STATE))
3497 issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500);
3499 else if( pwdinfo->driver_interface == DRIVER_WEXT )
3501 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
3503 // Now, the driver stays on the AP's channel.
3504 // If the pwdinfo->ext_listen_period = 0, that means the P2P listen state is not available on listen channel.
3505 if ( pwdinfo->ext_listen_period > 0 )
3507 DBG_8192C( "[%s] P2P_STATE_IDLE, ext_listen_period = %d\n", __FUNCTION__, pwdinfo->ext_listen_period );
3509 if ( pbuddy_mlmeext->cur_channel != pwdinfo->listen_channel )
3511 // Will switch to listen channel so that need to send the NULL data with PW bit to AP.
3512 issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500);
3513 set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
3516 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
3517 if(!check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
3518 ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE))
3521 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
3523 // Todo: To check the value of pwdinfo->ext_listen_period is equal to 0 or not.
3524 _set_timer( &pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period );
3527 else if ( rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN) ||
3528 rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL) ||
3529 ( rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) && pwdinfo->nego_req_info.benable == _FALSE ) ||
3530 rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ) )
3532 // Now, the driver is in the listen state of P2P mode.
3533 DBG_8192C( "[%s] P2P_STATE_IDLE, ext_listen_interval = %d\n", __FUNCTION__, pwdinfo->ext_listen_interval );
3535 // Commented by Albert 2012/11/01
3536 // If the AP's channel is the same as the listen channel, we should still be in the listen state
3537 // Other P2P device is still able to find this device out even this device is in the AP's channel.
3538 // So, configure this device to be able to receive the probe request frame and set it to listen state.
3539 if ( pbuddy_mlmeext->cur_channel != pwdinfo->listen_channel )
3541 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
3542 if (!check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) && ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE))
3545 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
3547 rtw_p2p_set_state(pwdinfo, P2P_STATE_IDLE);
3548 issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500);
3551 // Todo: To check the value of pwdinfo->ext_listen_interval is equal to 0 or not.
3552 _set_timer( &pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_interval );
3554 else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK))
3556 // The driver had finished the P2P handshake successfully.
3558 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
3559 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
3560 issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500);
3562 else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
3565 set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
3566 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
3567 issue_probereq_p2p(padapter, NULL);
3568 _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
3570 else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) && pwdinfo->nego_req_info.benable == _TRUE)
3573 set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
3574 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
3575 issue_probereq_p2p(padapter, NULL);
3576 _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
3578 else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) && pwdinfo->invitereq_info.benable == _TRUE)
3582 set_channel_bwmode(padapter, , HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
3583 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
3584 issue_probereq_p2p(padapter, NULL);
3585 _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
3592 /* In p2p+softap. When in P2P_STATE_GONEGO_OK, not back to listen channel.*/
3593 if (!rtw_p2p_chk_state(pwdinfo , P2P_STATE_GONEGO_OK) || padapter->registrypriv.full_ch_in_p2p_handshake == 0)
3594 set_channel_bwmode(padapter , pwdinfo->listen_channel , HAL_PRIME_CHNL_OFFSET_DONT_CARE , CHANNEL_WIDTH_20);
3596 DBG_871X("%s, buddy not linked, go nego ok, not back to listen channel\n", __func__);
3603 #ifdef CONFIG_IOCTL_CFG80211
3604 static void ro_ch_handler(_adapter *padapter)
3606 struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
3607 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3608 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3612 if (rtw_get_ch_setting_union(padapter, &ch, &bw, &offset) != 0) {
3614 DBG_871X(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n",
3615 FUNC_ADPT_ARG(padapter), ch, bw, offset);
3617 else if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->listen_channel) {
3618 ch = pwdinfo->listen_channel;
3619 bw = CHANNEL_WIDTH_20;
3620 offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
3622 DBG_871X(FUNC_ADPT_FMT" back to listen ch - ch:%u, bw:%u, offset:%u\n",
3623 FUNC_ADPT_ARG(padapter), ch, bw, offset);
3626 ch = pcfg80211_wdinfo->restore_channel;
3627 bw = CHANNEL_WIDTH_20;
3628 offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
3630 DBG_871X(FUNC_ADPT_FMT" back to restore ch - ch:%u, bw:%u, offset:%u\n",
3631 FUNC_ADPT_ARG(padapter), ch, bw, offset);
3634 set_channel_bwmode(padapter, ch, offset, bw);
3636 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
3637 #ifdef CONFIG_DEBUG_CFG80211
3638 DBG_871X("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
3641 pcfg80211_wdinfo->is_ro_ch = _FALSE;
3642 pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time();
3644 DBG_871X("cfg80211_remain_on_channel_expired cookie:0x%llx, ch=%d, bw=%d, offset=%d\n"
3645 , pcfg80211_wdinfo->remain_on_ch_cookie
3646 , rtw_get_oper_ch(padapter), rtw_get_oper_bw(padapter), rtw_get_oper_choffset(padapter));
3648 rtw_cfg80211_remain_on_channel_expired(padapter,
3649 pcfg80211_wdinfo->remain_on_ch_cookie,
3650 &pcfg80211_wdinfo->remain_on_ch_channel,
3651 pcfg80211_wdinfo->remain_on_ch_type, GFP_KERNEL);
3656 static void ro_ch_timer_process (void *FunctionContext)
3658 _adapter *adapter = (_adapter *)FunctionContext;
3659 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
3661 //printk("%s \n", __FUNCTION__);
3663 #ifdef CONFIG_CONCURRENT_MODE
3664 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
3667 p2p_protocol_wk_cmd( adapter, P2P_RO_CH_WK);
3670 static void rtw_change_p2pie_op_ch(_adapter *padapter, const u8 *frame_body, u32 len, u8 ch)
3673 u32 ies_len, p2p_ielen;
3674 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
3675 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
3677 ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_);
3678 ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
3680 p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen );
3683 u32 attr_contentlen = 0;
3686 //Check P2P_ATTR_OPERATING_CH
3687 attr_contentlen = 0;
3689 if((pattr = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, (uint*)&attr_contentlen))!=NULL)
3694 //Get the next P2P IE
3695 p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
3699 static void rtw_change_p2pie_ch_list(_adapter *padapter, const u8 *frame_body, u32 len, u8 ch)
3702 u32 ies_len, p2p_ielen;
3703 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
3704 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
3706 ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_);
3707 ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
3709 p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen );
3712 u32 attr_contentlen = 0;
3715 //Check P2P_ATTR_CH_LIST
3716 if ((pattr=rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, NULL, (uint*)&attr_contentlen))!=NULL) {
3719 u8 *pattr_temp = pattr + 3 ;
3721 attr_contentlen -= 3;
3723 while (attr_contentlen>0) {
3724 num_of_ch = *(pattr_temp+1);
3726 for(i=0; i<num_of_ch; i++)
3727 *(pattr_temp+2+i) = ch;
3729 pattr_temp += (2+num_of_ch);
3730 attr_contentlen -= (2+num_of_ch);
3734 //Get the next P2P IE
3735 p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
3739 static bool rtw_chk_p2pie_ch_list_with_buddy(_adapter *padapter, const u8 *frame_body, u32 len)
3742 #ifdef CONFIG_CONCURRENT_MODE
3744 u32 ies_len, p2p_ielen;
3745 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
3746 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
3747 u8 buddy_ch = pbuddy_mlmeext->cur_channel;
3749 ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_);
3750 ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
3752 p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen );
3755 u32 attr_contentlen = 0;
3758 //Check P2P_ATTR_CH_LIST
3759 if ((pattr=rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, NULL, (uint*)&attr_contentlen))!=NULL) {
3762 u8 *pattr_temp = pattr + 3 ;
3764 attr_contentlen -= 3;
3766 while (attr_contentlen>0) {
3767 num_of_ch = *(pattr_temp+1);
3769 for(i=0; i<num_of_ch; i++) {
3770 if (*(pattr_temp+2+i) == buddy_ch) {
3771 DBG_871X(FUNC_ADPT_FMT" ch_list fit buddy_ch:%u\n", FUNC_ADPT_ARG(padapter), buddy_ch);
3777 pattr_temp += (2+num_of_ch);
3778 attr_contentlen -= (2+num_of_ch);
3782 //Get the next P2P IE
3783 p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
3789 static bool rtw_chk_p2pie_op_ch_with_buddy(_adapter *padapter, const u8 *frame_body, u32 len)
3792 #ifdef CONFIG_CONCURRENT_MODE
3794 u32 ies_len, p2p_ielen;
3795 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
3796 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
3797 u8 buddy_ch = pbuddy_mlmeext->cur_channel;
3799 ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_);
3800 ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
3802 p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen );
3805 u32 attr_contentlen = 0;
3808 //Check P2P_ATTR_OPERATING_CH
3809 attr_contentlen = 0;
3811 if((pattr = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, (uint*)&attr_contentlen))!=NULL) {
3812 if (*(pattr+4) == buddy_ch) {
3813 DBG_871X(FUNC_ADPT_FMT" op_ch fit buddy_ch:%u\n", FUNC_ADPT_ARG(padapter), buddy_ch);
3819 //Get the next P2P IE
3820 p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
3826 static void rtw_cfg80211_adjust_p2pie_channel(_adapter *padapter, const u8 *frame_body, u32 len)
3828 #ifdef CONFIG_CONCURRENT_MODE
3830 u32 ies_len, p2p_ielen;
3831 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
3832 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
3834 ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_);
3835 ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
3837 p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen );
3841 u32 attr_contentlen = 0;
3844 //Check P2P_ATTR_CH_LIST
3845 if((pattr=rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, NULL, (uint*)&attr_contentlen))!=NULL)
3849 u8 *pattr_temp = pattr + 3 ;
3851 attr_contentlen -= 3;
3853 while(attr_contentlen>0)
3855 num_of_ch = *(pattr_temp+1);
3857 for(i=0; i<num_of_ch; i++)
3858 *(pattr_temp+2+i) = pbuddy_mlmeext->cur_channel;//forcing to the same channel
3860 pattr_temp += (2+num_of_ch);
3861 attr_contentlen -= (2+num_of_ch);
3865 //Check P2P_ATTR_OPERATING_CH
3866 attr_contentlen = 0;
3868 if((pattr = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, (uint*)&attr_contentlen))!=NULL)
3870 *(pattr+4) = pbuddy_mlmeext->cur_channel;//forcing to the same channel
3873 //Get the next P2P IE
3874 p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
3882 u32 rtw_xframe_build_wfd_ie(struct xmit_frame *xframe)
3884 _adapter *adapter = xframe->padapter;
3885 struct wifidirect_info *wdinfo = &adapter->wdinfo;
3886 u8 *frame = xframe->buf_addr + TXDESC_OFFSET;
3887 u8 *frame_body = frame + sizeof(struct rtw_ieee80211_hdr_3addr);
3888 u8 *frame_tail = frame + xframe->attrib.pktlen;
3889 u8 category, action, OUI_Subtype, dialogToken = 0;
3892 category = frame_body[0];
3893 if (category == RTW_WLAN_CATEGORY_PUBLIC) {
3894 action = frame_body[1];
3895 if (action == ACT_PUBLIC_VENDOR
3896 && _rtw_memcmp(frame_body + 2, P2P_OUI, 4) == _TRUE
3898 OUI_Subtype = frame_body[6];
3899 dialogToken = frame_body[7];
3901 switch (OUI_Subtype) {
3902 case P2P_GO_NEGO_REQ:
3903 wfdielen = build_nego_req_wfd_ie(wdinfo, frame_tail);
3905 case P2P_GO_NEGO_RESP:
3906 wfdielen = build_nego_resp_wfd_ie(wdinfo, frame_tail);
3908 case P2P_GO_NEGO_CONF:
3909 wfdielen = build_nego_confirm_wfd_ie(wdinfo, frame_tail);
3912 wfdielen = build_invitation_req_wfd_ie(wdinfo, frame_tail);
3914 case P2P_INVIT_RESP:
3915 wfdielen = build_invitation_resp_wfd_ie(wdinfo, frame_tail);
3917 case P2P_PROVISION_DISC_REQ:
3918 wfdielen = build_provdisc_req_wfd_ie(wdinfo, frame_tail);
3920 case P2P_PROVISION_DISC_RESP:
3921 wfdielen = build_provdisc_resp_wfd_ie(wdinfo, frame_tail);
3923 case P2P_DEVDISC_REQ:
3924 case P2P_DEVDISC_RESP:
3930 } else if (category == RTW_WLAN_CATEGORY_P2P) {
3931 OUI_Subtype = frame_body[5];
3932 dialogToken = frame_body[6];
3934 #ifdef CONFIG_DEBUG_CFG80211
3935 DBG_871X("ACTION_CATEGORY_P2P: OUI=0x%x, OUI_Subtype=%d, dialogToken=%d\n"
3936 , cpu_to_be32(*((u32 *)(frame_body + 1))), OUI_Subtype, dialogToken);
3939 switch (OUI_Subtype) {
3940 case P2P_NOTICE_OF_ABSENCE:
3942 case P2P_PRESENCE_REQUEST:
3944 case P2P_PRESENCE_RESPONSE:
3946 case P2P_GO_DISC_REQUEST:
3952 DBG_871X("%s, action frame category=%d\n", __func__, category);
3955 xframe->attrib.pktlen += wfdielen;
3959 #endif /* CONFIG_WFD */
3961 bool rtw_xframe_del_wfd_ie(struct xmit_frame *xframe)
3963 #define DBG_XFRAME_DEL_WFD_IE 0
3965 _adapter *adapter = xframe->padapter;
3966 u8 *frame = xframe->buf_addr + TXDESC_OFFSET;
3967 u8 *frame_body = frame + sizeof(struct rtw_ieee80211_hdr_3addr);
3968 u8 *frame_tail = frame + xframe->attrib.pktlen;
3969 u8 category, action, OUI_Subtype;
3971 uint ies_len_ori = 0;
3974 category = frame_body[0];
3975 if (category == RTW_WLAN_CATEGORY_PUBLIC) {
3976 action = frame_body[1];
3977 if (action == ACT_PUBLIC_VENDOR
3978 && _rtw_memcmp(frame_body + 2, P2P_OUI, 4) == _TRUE
3980 OUI_Subtype = frame_body[6];
3982 switch (OUI_Subtype) {
3983 case P2P_GO_NEGO_REQ:
3984 case P2P_GO_NEGO_RESP:
3985 case P2P_GO_NEGO_CONF:
3987 case P2P_INVIT_RESP:
3988 case P2P_PROVISION_DISC_REQ:
3989 case P2P_PROVISION_DISC_RESP:
3990 ies = frame_body + 8;
3991 ies_len_ori = frame_tail - (frame_body + 8);
3997 if (ies && ies_len_ori) {
3998 ies_len = rtw_del_wfd_ie(ies, ies_len_ori, DBG_XFRAME_DEL_WFD_IE ? __func__ : NULL);
3999 xframe->attrib.pktlen -= (ies_len_ori - ies_len);
4002 return ies_len_ori != ies_len;
4006 * rtw_xframe_chk_wfd_ie -
4009 void rtw_xframe_chk_wfd_ie(struct xmit_frame *xframe)
4011 _adapter *adapter = xframe->padapter;
4012 u8 *frame = xframe->buf_addr + TXDESC_OFFSET;
4013 u8 *frame_body = frame + sizeof(struct rtw_ieee80211_hdr_3addr);
4014 u8 *frame_tail = frame + xframe->attrib.pktlen;
4016 struct wifidirect_info *wdinfo = &adapter->wdinfo;
4017 struct mlme_priv *mlme = &adapter->mlmepriv;
4021 if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST))
4024 #ifdef CONFIG_IOCTL_CFG80211
4025 if (_TRUE == wdinfo->wfd_info->wfd_enable)
4030 rtw_xframe_del_wfd_ie(xframe);
4034 rtw_xframe_build_wfd_ie(xframe);
4038 u8 *dump_p2p_attr_ch_list(u8 *p2p_ie, uint p2p_ielen, u8 *buf, u32 buf_len)
4040 uint attr_contentlen = 0;
4045 bool continuous = _FALSE;
4047 if ((pattr=rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, NULL, &attr_contentlen))!=NULL) {
4050 u8 *pattr_temp = pattr + 3 ;
4052 attr_contentlen -= 3;
4054 _rtw_memset(ch_list, 0, 40);
4056 while (attr_contentlen>0) {
4057 num_of_ch = *(pattr_temp+1);
4059 for(i=0; i<num_of_ch; i++) {
4060 for (j=0;j<ch_cnt;j++) {
4061 if (ch_list[j] == *(pattr_temp+2+i))
4065 ch_list[ch_cnt++] = *(pattr_temp+2+i);
4069 pattr_temp += (2+num_of_ch);
4070 attr_contentlen -= (2+num_of_ch);
4073 for (j=0;j<ch_cnt;j++) {
4075 w_sz += snprintf(buf+w_sz, buf_len-w_sz, "%u", ch_list[j]);
4076 } else if (ch_list[j] - ch_list[j-1] != 1) {
4077 w_sz += snprintf(buf+w_sz, buf_len-w_sz, ", %u", ch_list[j]);
4078 } else if (j != ch_cnt-1 && ch_list[j+1] - ch_list[j] == 1) {
4081 w_sz += snprintf(buf+w_sz, buf_len-w_sz, "-%u", ch_list[j]);
4089 * return _TRUE if requester is GO, _FALSE if responder is GO
4091 bool rtw_p2p_nego_intent_compare(u8 req, u8 resp)
4093 if (req>>1 == resp >>1)
4094 return req&0x01 ? _TRUE : _FALSE;
4095 else if (req>>1 > resp>>1)
4101 int rtw_p2p_check_frames(_adapter *padapter, const u8 *buf, u32 len, u8 tx)
4103 int is_p2p_frame = (-1);
4104 unsigned char *frame_body;
4105 u8 category, action, OUI_Subtype, dialogToken=0;
4108 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
4110 u8 ch_list_buf[128] = {'\0'};
4115 frame_body = (unsigned char *)(buf + sizeof(struct rtw_ieee80211_hdr_3addr));
4116 category = frame_body[0];
4118 if(category == RTW_WLAN_CATEGORY_PUBLIC)
4120 action = frame_body[1];
4121 if (action == ACT_PUBLIC_VENDOR
4122 && _rtw_memcmp(frame_body+2, P2P_OUI, 4) == _TRUE
4125 OUI_Subtype = frame_body[6];
4126 dialogToken = frame_body[7];
4127 is_p2p_frame = OUI_Subtype;
4128 #ifdef CONFIG_DEBUG_CFG80211
4129 DBG_871X("ACTION_CATEGORY_PUBLIC: ACT_PUBLIC_VENDOR, OUI=0x%x, OUI_Subtype=%d, dialogToken=%d\n",
4130 cpu_to_be32( *( ( u32* ) ( frame_body + 2 ) ) ), OUI_Subtype, dialogToken);
4133 p2p_ie = rtw_get_p2p_ie(
4134 (u8 *)buf+sizeof(struct rtw_ieee80211_hdr_3addr)+_PUBLIC_ACTION_IE_OFFSET_,
4135 len-sizeof(struct rtw_ieee80211_hdr_3addr)-_PUBLIC_ACTION_IE_OFFSET_,
4138 switch( OUI_Subtype )//OUI Subtype
4142 case P2P_GO_NEGO_REQ:
4144 struct rtw_wdev_nego_info* nego_info = &pwdev_priv->nego_info;
4147 #ifdef CONFIG_DRV_ISSUE_PROV_REQ // IOT FOR S2
4148 if(pwdev_priv->provdisc_req_issued == _FALSE)
4149 rtw_cfg80211_issue_p2p_provision_request(padapter, buf, len);
4150 #endif //CONFIG_DRV_ISSUE_PROV_REQ
4152 //pwdev_priv->provdisc_req_issued = _FALSE;
4154 #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT)
4155 if (check_buddy_fwstate(padapter , _FW_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4156 rtw_cfg80211_adjust_p2pie_channel(padapter , frame_body , len-sizeof(struct rtw_ieee80211_hdr_3addr));
4160 if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len)))
4162 if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, NULL, &cont_len)))
4163 listen_ch = *(cont+4);
4164 if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT, NULL, &cont_len)))
4167 if (nego_info->token != dialogToken)
4168 rtw_wdev_nego_info_init(nego_info);
4170 _rtw_memcpy(nego_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN);
4171 nego_info->active = tx ? 1 : 0;
4172 nego_info->token = dialogToken;
4173 nego_info->req_op_ch = op_ch;
4174 nego_info->req_listen_ch = listen_ch;
4175 nego_info->req_intent = intent;
4176 nego_info->state = 0;
4178 dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128);
4179 DBG_871X("RTW_%s:P2P_GO_NEGO_REQ, dialogToken=%d, intent:%u%s, listen_ch:%d, op_ch:%d, ch_list:%s, full_ch_in_p2p_handshake:%d\n" ,
4180 (tx == _TRUE)?"Tx":"Rx" , dialogToken , (intent>>1) , intent&0x1 ? "+" : "-" , listen_ch , op_ch , ch_list_buf , padapter->registrypriv.full_ch_in_p2p_handshake);
4183 #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT)
4184 if (check_buddy_fwstate(padapter, _FW_LINKED)
4185 && rtw_chk_p2pie_ch_list_with_buddy(padapter , frame_body , len-sizeof(struct rtw_ieee80211_hdr_3addr)) == _FALSE
4186 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4188 DBG_871X(FUNC_ADPT_FMT" ch_list has no intersect with buddy\n", FUNC_ADPT_ARG(padapter));
4189 rtw_change_p2pie_ch_list(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr), 0);
4196 case P2P_GO_NEGO_RESP:
4198 struct rtw_wdev_nego_info* nego_info = &pwdev_priv->nego_info;
4201 #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT)
4202 if (check_buddy_fwstate(padapter , _FW_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4203 rtw_cfg80211_adjust_p2pie_channel(padapter , frame_body , len-sizeof(struct rtw_ieee80211_hdr_3addr));
4207 if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len)))
4209 if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT, NULL, &cont_len)))
4211 if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len)))
4214 if (nego_info->token == dialogToken && nego_info->state == 0
4215 && _rtw_memcmp(nego_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN) == _TRUE
4217 nego_info->status = (status==-1) ? 0xff : status;
4218 nego_info->rsp_op_ch= op_ch;
4219 nego_info->rsp_intent = intent;
4220 nego_info->state = 1;
4222 nego_info->token = 0; /* init */
4225 dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128);
4226 DBG_871X("RTW_%s:P2P_GO_NEGO_RESP, dialogToken=%d, intent:%u%s, status:%d, op_ch:%d, ch_list:%s\n",
4227 (tx==_TRUE)?"Tx":"Rx", dialogToken, (intent>>1), intent&0x1 ? "+" : "-", status, op_ch, ch_list_buf);
4230 pwdev_priv->provdisc_req_issued = _FALSE;
4231 #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT)
4232 if (check_buddy_fwstate(padapter, _FW_LINKED)
4233 && rtw_chk_p2pie_ch_list_with_buddy(padapter , frame_body , len-sizeof(struct rtw_ieee80211_hdr_3addr)) == _FALSE
4234 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4236 DBG_871X(FUNC_ADPT_FMT" ch_list has no intersect with buddy\n", FUNC_ADPT_ARG(padapter));
4237 rtw_change_p2pie_ch_list(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr), 0);
4244 case P2P_GO_NEGO_CONF:
4246 struct rtw_wdev_nego_info* nego_info = &pwdev_priv->nego_info;
4247 bool is_go = _FALSE;
4250 #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT)
4251 if (check_buddy_fwstate(padapter, _FW_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4252 rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr));
4256 if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len)))
4258 if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len)))
4261 if (nego_info->token == dialogToken && nego_info->state == 1
4262 && _rtw_memcmp(nego_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN) == _TRUE
4264 nego_info->status = (status==-1) ? 0xff : status;
4265 nego_info->conf_op_ch = (op_ch==-1) ? 0 : op_ch;
4266 nego_info->state = 2;
4269 if (rtw_p2p_nego_intent_compare(nego_info->req_intent, nego_info->rsp_intent) ^ !tx)
4273 nego_info->token = 0; /* init */
4276 dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128);
4277 DBG_871X("RTW_%s:P2P_GO_NEGO_CONF, dialogToken=%d, status:%d, op_ch:%d, ch_list:%s\n",
4278 (tx==_TRUE)?"Tx":"Rx", dialogToken, status, op_ch, ch_list_buf);
4287 struct rtw_wdev_invit_info* invit_info = &pwdev_priv->invit_info;
4291 #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT)
4292 if (check_buddy_fwstate(padapter, _FW_LINKED)
4293 && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4294 rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr));
4298 if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_INVITATION_FLAGS, NULL, &cont_len)))
4300 if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len)))
4303 if (invit_info->token != dialogToken)
4304 rtw_wdev_invit_info_init(invit_info);
4306 _rtw_memcpy(invit_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN);
4307 invit_info->active = tx ? 1 : 0;
4308 invit_info->token = dialogToken;
4309 invit_info->flags = (flags==-1) ? 0x0 : flags;
4310 invit_info->req_op_ch= op_ch;
4311 invit_info->state = 0;
4313 dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128);
4314 DBG_871X("RTW_%s:P2P_INVIT_REQ, dialogToken=%d, flags:0x%02x, op_ch:%d, ch_list:%s\n",
4315 (tx==_TRUE)?"Tx":"Rx", dialogToken, flags, op_ch, ch_list_buf);
4318 #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT)
4319 if (check_buddy_fwstate(padapter , _FW_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0) {
4320 if (op_ch != -1 && rtw_chk_p2pie_op_ch_with_buddy(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)) == _FALSE) {
4321 DBG_871X(FUNC_ADPT_FMT" op_ch:%u has no intersect with buddy\n", FUNC_ADPT_ARG(padapter), op_ch);
4322 rtw_change_p2pie_ch_list(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr), 0);
4323 } else if (rtw_chk_p2pie_ch_list_with_buddy(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)) == _FALSE) {
4324 DBG_871X(FUNC_ADPT_FMT" ch_list has no intersect with buddy\n", FUNC_ADPT_ARG(padapter));
4325 rtw_change_p2pie_ch_list(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr), 0);
4333 case P2P_INVIT_RESP:
4335 struct rtw_wdev_invit_info* invit_info = &pwdev_priv->invit_info;
4338 #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT)
4339 if (check_buddy_fwstate(padapter , _FW_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4340 rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr));
4344 if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len)))
4346 #ifdef CONFIG_P2P_INVITE_IOT
4349 DBG_871X("TX_P2P_INVITE_RESP, status is no common channel, change to unknown group\n");
4350 *cont = 8; //unknow group status
4352 #endif //CONFIG_P2P_INVITE_IOT
4355 if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len)))
4358 if (invit_info->token == dialogToken && invit_info->state == 0
4359 && _rtw_memcmp(invit_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN) == _TRUE
4361 invit_info->status = (status==-1) ? 0xff : status;
4362 invit_info->rsp_op_ch= op_ch;
4363 invit_info->state = 1;
4364 invit_info->token = 0; /* init */
4367 dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128);
4368 DBG_871X("RTW_%s:P2P_INVIT_RESP, dialogToken=%d, status:%d, op_ch:%d, ch_list:%s\n",
4369 (tx==_TRUE)?"Tx":"Rx", dialogToken, status, op_ch, ch_list_buf);
4376 case P2P_DEVDISC_REQ:
4377 DBG_871X("RTW_%s:P2P_DEVDISC_REQ, dialogToken=%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken);
4379 case P2P_DEVDISC_RESP:
4380 cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len);
4381 DBG_871X("RTW_%s:P2P_DEVDISC_RESP, dialogToken=%d, status:%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken, cont?*cont:-1);
4383 case P2P_PROVISION_DISC_REQ:
4385 size_t frame_body_len = len - sizeof(struct rtw_ieee80211_hdr_3addr);
4388 uint contentlen = 0;
4390 DBG_871X("RTW_%s:P2P_PROVISION_DISC_REQ, dialogToken=%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken);
4394 pwdev_priv->provdisc_req_issued = _FALSE;
4396 if( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)))
4399 if(rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, NULL, &contentlen))
4401 pwdev_priv->provdisc_req_issued = _FALSE;//case: p2p_client join p2p GO
4405 #ifdef CONFIG_DEBUG_CFG80211
4406 DBG_871X("provdisc_req_issued is _TRUE\n");
4407 #endif //CONFIG_DEBUG_CFG80211
4408 pwdev_priv->provdisc_req_issued = _TRUE;//case: p2p_devices connection before Nego req.
4415 case P2P_PROVISION_DISC_RESP:
4416 DBG_871X("RTW_%s:P2P_PROVISION_DISC_RESP, dialogToken=%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken);
4419 DBG_871X("RTW_%s:OUI_Subtype=%d, dialogToken=%d\n", (tx==_TRUE)?"Tx":"Rx", OUI_Subtype, dialogToken);
4426 else if(category == RTW_WLAN_CATEGORY_P2P)
4428 OUI_Subtype = frame_body[5];
4429 dialogToken = frame_body[6];
4431 #ifdef CONFIG_DEBUG_CFG80211
4432 DBG_871X("ACTION_CATEGORY_P2P: OUI=0x%x, OUI_Subtype=%d, dialogToken=%d\n",
4433 cpu_to_be32( *( ( u32* ) ( frame_body + 1 ) ) ), OUI_Subtype, dialogToken);
4436 is_p2p_frame = OUI_Subtype;
4440 case P2P_NOTICE_OF_ABSENCE:
4441 DBG_871X("RTW_%s:P2P_NOTICE_OF_ABSENCE, dialogToken=%d\n", (tx==_TRUE)?"TX":"RX", dialogToken);
4443 case P2P_PRESENCE_REQUEST:
4444 DBG_871X("RTW_%s:P2P_PRESENCE_REQUEST, dialogToken=%d\n", (tx==_TRUE)?"TX":"RX", dialogToken);
4446 case P2P_PRESENCE_RESPONSE:
4447 DBG_871X("RTW_%s:P2P_PRESENCE_RESPONSE, dialogToken=%d\n", (tx==_TRUE)?"TX":"RX", dialogToken);
4449 case P2P_GO_DISC_REQUEST:
4450 DBG_871X("RTW_%s:P2P_GO_DISC_REQUEST, dialogToken=%d\n", (tx==_TRUE)?"TX":"RX", dialogToken);
4453 DBG_871X("RTW_%s:OUI_Subtype=%d, dialogToken=%d\n", (tx==_TRUE)?"TX":"RX", OUI_Subtype, dialogToken);
4460 DBG_871X("RTW_%s:action frame category=%d\n", (tx==_TRUE)?"TX":"RX", category);
4463 return is_p2p_frame;
4466 void rtw_init_cfg80211_wifidirect_info( _adapter* padapter)
4468 struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
4470 _rtw_memset(pcfg80211_wdinfo, 0x00, sizeof(struct cfg80211_wifidirect_info) );
4472 _init_timer( &pcfg80211_wdinfo->remain_on_ch_timer, padapter->pnetdev, ro_ch_timer_process, padapter );
4474 #endif //CONFIG_IOCTL_CFG80211
4476 void p2p_protocol_wk_hdl(_adapter *padapter, int intCmdType)
4478 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4484 case P2P_FIND_PHASE_WK:
4486 find_phase_handler( padapter );
4489 case P2P_RESTORE_STATE_WK:
4491 restore_p2p_state_handler( padapter );
4494 case P2P_PRE_TX_PROVDISC_PROCESS_WK:
4496 #ifdef CONFIG_CONCURRENT_MODE
4497 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
4499 p2p_concurrent_handler( padapter );
4503 pre_tx_provdisc_handler( padapter );
4506 pre_tx_provdisc_handler( padapter );
4510 case P2P_PRE_TX_INVITEREQ_PROCESS_WK:
4512 #ifdef CONFIG_CONCURRENT_MODE
4513 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
4515 p2p_concurrent_handler( padapter );
4519 pre_tx_invitereq_handler( padapter );
4522 pre_tx_invitereq_handler( padapter );
4526 case P2P_PRE_TX_NEGOREQ_PROCESS_WK:
4528 #ifdef CONFIG_CONCURRENT_MODE
4529 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
4531 p2p_concurrent_handler( padapter );
4535 pre_tx_negoreq_handler( padapter );
4538 pre_tx_negoreq_handler( padapter );
4543 #ifdef CONFIG_CONCURRENT_MODE
4544 case P2P_AP_P2P_CH_SWITCH_PROCESS_WK:
4546 p2p_concurrent_handler( padapter );
4551 #ifdef CONFIG_IOCTL_CFG80211
4554 ro_ch_handler( padapter );
4557 #endif //CONFIG_IOCTL_CFG80211
4564 int process_p2p_cross_connect_ie(PADAPTER padapter, u8 *IEs, u32 IELength)
4571 u8 p2p_attr[MAX_P2P_IE_LEN] = { 0x00 };// NoA length should be n*(13) + 2
4572 u32 attr_contentlen = 0;
4574 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
4578 if(IELength <= _BEACON_IE_OFFSET_)
4581 ies = IEs + _BEACON_IE_OFFSET_;
4582 ies_len = IELength - _BEACON_IE_OFFSET_;
4584 p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen);
4588 // Get P2P Manageability IE.
4589 if(rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_MANAGEABILITY, p2p_attr, &attr_contentlen))
4591 if ((p2p_attr[0]&(BIT(0)|BIT(1))) == 0x01) {
4596 //Get the next P2P IE
4597 p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
4604 #ifdef CONFIG_P2P_PS
4605 void process_p2p_ps_ie(PADAPTER padapter, u8 *IEs, u32 IELength)
4611 u8 noa_attr[MAX_P2P_IE_LEN] = { 0x00 };// NoA length should be n*(13) + 2
4612 u32 attr_contentlen = 0;
4614 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
4615 u8 find_p2p = _FALSE, find_p2p_ps = _FALSE;
4616 u8 noa_offset, noa_num, noa_index;
4620 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
4624 #ifdef CONFIG_CONCURRENT_MODE
4625 if(padapter->iface_type != IFACE_PORT0)
4628 if(IELength <= _BEACON_IE_OFFSET_)
4631 ies = IEs + _BEACON_IE_OFFSET_;
4632 ies_len = IELength - _BEACON_IE_OFFSET_;
4634 p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen);
4639 // Get Notice of Absence IE.
4640 if(rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_NOA, noa_attr, &attr_contentlen))
4642 find_p2p_ps = _TRUE;
4643 noa_index = noa_attr[0];
4645 if( (pwdinfo->p2p_ps_mode == P2P_PS_NONE) ||
4646 (noa_index != pwdinfo->noa_index) )// if index change, driver should reconfigure related setting.
4648 pwdinfo->noa_index = noa_index;
4649 pwdinfo->opp_ps = noa_attr[1] >> 7;
4650 pwdinfo->ctwindow = noa_attr[1] & 0x7F;
4654 // NoA length should be n*(13) + 2
4655 if(attr_contentlen > 2)
4657 while(noa_offset < attr_contentlen)
4659 //_rtw_memcpy(&wifidirect_info->noa_count[noa_num], &noa_attr[noa_offset], 1);
4660 pwdinfo->noa_count[noa_num] = noa_attr[noa_offset];
4663 _rtw_memcpy(&pwdinfo->noa_duration[noa_num], &noa_attr[noa_offset], 4);
4666 _rtw_memcpy(&pwdinfo->noa_interval[noa_num], &noa_attr[noa_offset], 4);
4669 _rtw_memcpy(&pwdinfo->noa_start_time[noa_num], &noa_attr[noa_offset], 4);
4675 pwdinfo->noa_num = noa_num;
4677 if( pwdinfo->opp_ps == 1 )
4679 pwdinfo->p2p_ps_mode = P2P_PS_CTWINDOW;
4680 // driver should wait LPS for entering CTWindow
4681 if(adapter_to_pwrctl(padapter)->bFwCurrentInPSMode == _TRUE)
4683 p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 1);
4686 else if( pwdinfo->noa_num > 0 )
4688 pwdinfo->p2p_ps_mode = P2P_PS_NOA;
4689 p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 1);
4691 else if( pwdinfo->p2p_ps_mode > P2P_PS_NONE)
4693 p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1);
4697 break; // find target, just break.
4700 //Get the next P2P IE
4701 p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
4705 if(find_p2p == _TRUE)
4707 if( (pwdinfo->p2p_ps_mode > P2P_PS_NONE) && (find_p2p_ps == _FALSE) )
4709 p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1);
4716 void p2p_ps_wk_hdl(_adapter *padapter, u8 p2p_ps_state)
4718 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
4719 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4723 // Pre action for p2p state
4724 switch(p2p_ps_state)
4726 case P2P_PS_DISABLE:
4727 pwdinfo->p2p_ps_state = p2p_ps_state;
4729 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state));
4731 pwdinfo->noa_index = 0;
4732 pwdinfo->ctwindow = 0;
4733 pwdinfo->opp_ps = 0;
4734 pwdinfo->noa_num = 0;
4735 pwdinfo->p2p_ps_mode = P2P_PS_NONE;
4736 if(pwrpriv->bFwCurrentInPSMode == _TRUE)
4738 if(pwrpriv->smart_ps == 0)
4740 pwrpriv->smart_ps = 2;
4741 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&(pwrpriv->pwr_mode)));
4746 if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) {
4747 pwdinfo->p2p_ps_state = p2p_ps_state;
4749 if( pwdinfo->ctwindow > 0 )
4751 if(pwrpriv->smart_ps != 0)
4753 pwrpriv->smart_ps = 0;
4754 DBG_871X("%s(): Enter CTW, change SmartPS\n", __FUNCTION__);
4755 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&(pwrpriv->pwr_mode)));
4758 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state));
4762 case P2P_PS_SCAN_DONE:
4763 case P2P_PS_ALLSTASLEEP:
4764 if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) {
4765 pwdinfo->p2p_ps_state = p2p_ps_state;
4766 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state));
4776 u8 p2p_ps_wk_cmd(_adapter*padapter, u8 p2p_ps_state, u8 enqueue)
4778 struct cmd_obj *ph2c;
4779 struct drvextra_cmd_parm *pdrvextra_cmd_parm;
4780 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
4781 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
4786 if ( rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)
4787 #ifdef CONFIG_CONCURRENT_MODE
4788 || (padapter->iface_type != IFACE_PORT0)
4797 ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
4803 pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
4804 if(pdrvextra_cmd_parm==NULL){
4805 rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
4810 pdrvextra_cmd_parm->ec_id = P2P_PS_WK_CID;
4811 pdrvextra_cmd_parm->type = p2p_ps_state;
4812 pdrvextra_cmd_parm->size = 0;
4813 pdrvextra_cmd_parm->pbuf = NULL;
4815 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
4817 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
4821 p2p_ps_wk_hdl(padapter, p2p_ps_state);
4831 #endif // CONFIG_P2P_PS
4833 static void reset_ch_sitesurvey_timer_process (void *FunctionContext)
4835 _adapter *adapter = (_adapter *)FunctionContext;
4836 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
4838 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
4841 DBG_871X( "[%s] In\n", __FUNCTION__ );
4842 // Reset the operation channel information
4843 pwdinfo->rx_invitereq_info.operation_ch[0] = 0;
4844 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
4845 pwdinfo->rx_invitereq_info.operation_ch[1] = 0;
4846 pwdinfo->rx_invitereq_info.operation_ch[2] = 0;
4847 pwdinfo->rx_invitereq_info.operation_ch[3] = 0;
4848 #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
4849 pwdinfo->rx_invitereq_info.scan_op_ch_only = 0;
4852 static void reset_ch_sitesurvey_timer_process2 (void *FunctionContext)
4854 _adapter *adapter = (_adapter *)FunctionContext;
4855 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
4857 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
4860 DBG_871X( "[%s] In\n", __FUNCTION__ );
4861 // Reset the operation channel information
4862 pwdinfo->p2p_info.operation_ch[0] = 0;
4863 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
4864 pwdinfo->p2p_info.operation_ch[1] = 0;
4865 pwdinfo->p2p_info.operation_ch[2] = 0;
4866 pwdinfo->p2p_info.operation_ch[3] = 0;
4867 #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
4868 pwdinfo->p2p_info.scan_op_ch_only = 0;
4871 static void restore_p2p_state_timer_process (void *FunctionContext)
4873 _adapter *adapter = (_adapter *)FunctionContext;
4874 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
4876 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
4879 p2p_protocol_wk_cmd( adapter, P2P_RESTORE_STATE_WK );
4882 static void pre_tx_scan_timer_process (void *FunctionContext)
4884 _adapter *adapter = (_adapter *) FunctionContext;
4885 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
4887 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
4890 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
4893 _enter_critical_bh(&pmlmepriv->lock, &irqL);
4896 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
4898 if ( _TRUE == pwdinfo->tx_prov_disc_info.benable ) // the provision discovery request frame is trigger to send or not
4900 p2p_protocol_wk_cmd( adapter, P2P_PRE_TX_PROVDISC_PROCESS_WK );
4901 //issue_probereq_p2p(adapter, NULL);
4902 //_set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
4905 else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
4907 if ( _TRUE == pwdinfo->nego_req_info.benable )
4909 p2p_protocol_wk_cmd( adapter, P2P_PRE_TX_NEGOREQ_PROCESS_WK );
4912 else if ( rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) )
4914 if ( _TRUE == pwdinfo->invitereq_info.benable )
4916 p2p_protocol_wk_cmd( adapter, P2P_PRE_TX_INVITEREQ_PROCESS_WK );
4921 DBG_8192C( "[%s] p2p_state is %d, ignore!!\n", __FUNCTION__, rtw_p2p_state(pwdinfo) );
4924 _exit_critical_bh(&pmlmepriv->lock, &irqL);
4927 static void find_phase_timer_process (void *FunctionContext)
4929 _adapter *adapter = (_adapter *)FunctionContext;
4930 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
4932 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
4935 adapter->wdinfo.find_phase_state_exchange_cnt++;
4937 p2p_protocol_wk_cmd( adapter, P2P_FIND_PHASE_WK );
4940 #ifdef CONFIG_CONCURRENT_MODE
4941 void ap_p2p_switch_timer_process (void *FunctionContext)
4943 _adapter *adapter = (_adapter *)FunctionContext;
4944 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
4945 #ifdef CONFIG_IOCTL_CFG80211
4946 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
4949 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
4952 #ifdef CONFIG_IOCTL_CFG80211
4953 ATOMIC_SET(&pwdev_priv->switch_ch_to, 1);
4956 p2p_protocol_wk_cmd( adapter, P2P_AP_P2P_CH_SWITCH_PROCESS_WK );
4960 void reset_global_wifidirect_info( _adapter* padapter )
4962 struct wifidirect_info *pwdinfo;
4964 pwdinfo = &padapter->wdinfo;
4965 pwdinfo->persistent_supported = 0;
4966 pwdinfo->session_available = _TRUE;
4967 rtw_tdls_wfd_enable(padapter, 0);
4968 pwdinfo->wfd_tdls_weaksec = _TRUE;
4972 int rtw_init_wifi_display_info(_adapter* padapter)
4975 struct wifi_display_info *pwfd_info = &padapter->wfd_info;
4977 // Used in P2P and TDLS
4978 pwfd_info->init_rtsp_ctrlport = 554;
4979 #ifdef CONFIG_IOCTL_CFG80211
4980 pwfd_info->rtsp_ctrlport = 0;
4982 pwfd_info->rtsp_ctrlport = pwfd_info->init_rtsp_ctrlport; /* set non-zero value for legacy wfd */
4984 pwfd_info->tdls_rtsp_ctrlport = 0;
4985 pwfd_info->peer_rtsp_ctrlport = 0; // Reset to 0
4986 pwfd_info->wfd_enable = _FALSE;
4987 pwfd_info->wfd_device_type = WFD_DEVINFO_PSINK;
4988 pwfd_info->scan_result_type = SCAN_RESULT_P2P_ONLY;
4991 pwfd_info->peer_session_avail = _TRUE;
4992 pwfd_info->wfd_pc = _FALSE;
4995 _rtw_memset( pwfd_info->ip_address, 0x00, 4 );
4996 _rtw_memset( pwfd_info->peer_ip_address, 0x00, 4 );
5001 inline void rtw_wfd_enable(_adapter *adapter, bool on)
5003 struct wifi_display_info *wfdinfo = &adapter->wfd_info;
5006 wfdinfo->rtsp_ctrlport = wfdinfo->init_rtsp_ctrlport;
5007 wfdinfo->wfd_enable = _TRUE;
5010 wfdinfo->wfd_enable = _FALSE;
5011 wfdinfo->rtsp_ctrlport = 0;
5015 inline void rtw_wfd_set_ctrl_port(_adapter *adapter, u16 port)
5017 struct wifi_display_info *wfdinfo = &adapter->wfd_info;
5019 wfdinfo->init_rtsp_ctrlport = port;
5020 if (wfdinfo->wfd_enable == _TRUE)
5021 wfdinfo->rtsp_ctrlport = port;
5022 if (adapter->wdinfo.wfd_tdls_enable == 1)
5023 wfdinfo->tdls_rtsp_ctrlport = port;
5026 inline void rtw_tdls_wfd_enable(_adapter *adapter, bool on)
5028 struct wifi_display_info *wfdinfo = &adapter->wfd_info;
5031 wfdinfo->tdls_rtsp_ctrlport = wfdinfo->init_rtsp_ctrlport;
5032 adapter->wdinfo.wfd_tdls_enable = 1;
5035 adapter->wdinfo.wfd_tdls_enable = 0;
5036 wfdinfo->tdls_rtsp_ctrlport = 0;
5040 u32 rtw_append_beacon_wfd_ie(_adapter *adapter, u8 *pbuf)
5042 struct wifidirect_info *wdinfo = &adapter->wdinfo;
5043 struct mlme_priv *mlme = &adapter->mlmepriv;
5044 u8 build_ie_by_self = 0;
5047 if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST))
5050 #ifdef CONFIG_IOCTL_CFG80211
5051 if (_TRUE == wdinfo->wfd_info->wfd_enable)
5053 build_ie_by_self = 1;
5055 if (build_ie_by_self)
5056 len = build_beacon_wfd_ie(wdinfo, pbuf);
5057 #ifdef CONFIG_IOCTL_CFG80211
5058 else if (mlme->wfd_beacon_ie && mlme->wfd_beacon_ie_len > 0) {
5059 len = mlme->wfd_beacon_ie_len;
5060 _rtw_memcpy(pbuf, mlme->wfd_beacon_ie, len);
5068 u32 rtw_append_probe_req_wfd_ie(_adapter *adapter, u8 *pbuf)
5070 struct wifidirect_info *wdinfo = &adapter->wdinfo;
5071 struct mlme_priv *mlme = &adapter->mlmepriv;
5072 u8 build_ie_by_self = 0;
5075 if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST))
5078 #ifdef CONFIG_IOCTL_CFG80211
5079 if (_TRUE == wdinfo->wfd_info->wfd_enable)
5081 build_ie_by_self = 1;
5083 if (build_ie_by_self)
5084 len = build_probe_req_wfd_ie(wdinfo, pbuf);
5085 #ifdef CONFIG_IOCTL_CFG80211
5086 else if (mlme->wfd_probe_req_ie && mlme->wfd_probe_req_ie_len > 0) {
5087 len = mlme->wfd_probe_req_ie_len;
5088 _rtw_memcpy(pbuf, mlme->wfd_probe_req_ie, len);
5096 u32 rtw_append_probe_resp_wfd_ie(_adapter *adapter, u8 *pbuf)
5098 struct wifidirect_info *wdinfo = &adapter->wdinfo;
5099 struct mlme_priv *mlme = &adapter->mlmepriv;
5100 u8 build_ie_by_self = 0;
5103 if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST))
5106 #ifdef CONFIG_IOCTL_CFG80211
5107 if (_TRUE == wdinfo->wfd_info->wfd_enable)
5109 build_ie_by_self = 1;
5111 if (build_ie_by_self)
5112 len = build_probe_resp_wfd_ie(wdinfo, pbuf, 0);
5113 #ifdef CONFIG_IOCTL_CFG80211
5114 else if (mlme->wfd_probe_resp_ie && mlme->wfd_probe_resp_ie_len > 0) {
5115 len = mlme->wfd_probe_resp_ie_len;
5116 _rtw_memcpy(pbuf, mlme->wfd_probe_resp_ie, len);
5124 u32 rtw_append_assoc_req_wfd_ie(_adapter *adapter, u8 *pbuf)
5126 struct wifidirect_info *wdinfo = &adapter->wdinfo;
5127 struct mlme_priv *mlme = &adapter->mlmepriv;
5128 u8 build_ie_by_self = 0;
5131 if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST))
5134 #ifdef CONFIG_IOCTL_CFG80211
5135 if (_TRUE == wdinfo->wfd_info->wfd_enable)
5137 build_ie_by_self = 1;
5139 if (build_ie_by_self)
5140 len = build_assoc_req_wfd_ie(wdinfo, pbuf);
5141 #ifdef CONFIG_IOCTL_CFG80211
5142 else if (mlme->wfd_assoc_req_ie && mlme->wfd_assoc_req_ie_len > 0) {
5143 len = mlme->wfd_assoc_req_ie_len;
5144 _rtw_memcpy(pbuf, mlme->wfd_assoc_req_ie, len);
5152 u32 rtw_append_assoc_resp_wfd_ie(_adapter *adapter, u8 *pbuf)
5154 struct wifidirect_info *wdinfo = &adapter->wdinfo;
5155 struct mlme_priv *mlme = &adapter->mlmepriv;
5156 u8 build_ie_by_self = 0;
5159 if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST))
5162 #ifdef CONFIG_IOCTL_CFG80211
5163 if (_TRUE == wdinfo->wfd_info->wfd_enable)
5165 build_ie_by_self = 1;
5167 if (build_ie_by_self)
5168 len = build_assoc_resp_wfd_ie(wdinfo, pbuf);
5169 #ifdef CONFIG_IOCTL_CFG80211
5170 else if (mlme->wfd_assoc_resp_ie && mlme->wfd_assoc_resp_ie_len > 0) {
5171 len = mlme->wfd_assoc_resp_ie_len;
5172 _rtw_memcpy(pbuf, mlme->wfd_assoc_resp_ie, len);
5180 #endif /* CONFIG_WFD */
5182 void rtw_init_wifidirect_timers(_adapter* padapter)
5184 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
5186 _init_timer( &pwdinfo->find_phase_timer, padapter->pnetdev, find_phase_timer_process, padapter );
5187 _init_timer( &pwdinfo->restore_p2p_state_timer, padapter->pnetdev, restore_p2p_state_timer_process, padapter );
5188 _init_timer( &pwdinfo->pre_tx_scan_timer, padapter->pnetdev, pre_tx_scan_timer_process, padapter );
5189 _init_timer( &pwdinfo->reset_ch_sitesurvey, padapter->pnetdev, reset_ch_sitesurvey_timer_process, padapter );
5190 _init_timer( &pwdinfo->reset_ch_sitesurvey2, padapter->pnetdev, reset_ch_sitesurvey_timer_process2, padapter );
5191 #ifdef CONFIG_CONCURRENT_MODE
5192 _init_timer( &pwdinfo->ap_p2p_switch_timer, padapter->pnetdev, ap_p2p_switch_timer_process, padapter );
5196 void rtw_init_wifidirect_addrs(_adapter* padapter, u8 *dev_addr, u8 *iface_addr)
5199 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
5201 /*init device&interface address */
5203 _rtw_memcpy(pwdinfo->device_addr, dev_addr, ETH_ALEN);
5206 _rtw_memcpy(pwdinfo->interface_addr, iface_addr, ETH_ALEN);
5211 void init_wifidirect_info( _adapter* padapter, enum P2P_ROLE role)
5213 struct wifidirect_info *pwdinfo;
5215 struct wifi_display_info *pwfd_info = &padapter->wfd_info;
5217 #ifdef CONFIG_CONCURRENT_MODE
5218 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
5219 struct wifidirect_info *pbuddy_wdinfo = NULL;
5220 struct mlme_priv *pbuddy_mlmepriv = NULL;
5221 struct mlme_ext_priv *pbuddy_mlmeext = NULL;
5224 pwdinfo = &padapter->wdinfo;
5226 pwdinfo->padapter = padapter;
5228 // 1, 6, 11 are the social channel defined in the WiFi Direct specification.
5229 pwdinfo->social_chan[0] = 1;
5230 pwdinfo->social_chan[1] = 6;
5231 pwdinfo->social_chan[2] = 11;
5232 pwdinfo->social_chan[3] = 0; // channel 0 for scanning ending in site survey function.
5234 #ifdef CONFIG_CONCURRENT_MODE
5235 if (pbuddy_adapter) {
5236 pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
5237 pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
5238 pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
5241 if ( ( check_buddy_fwstate(padapter, _FW_LINKED ) == _TRUE ) &&
5242 ( ( pbuddy_mlmeext->cur_channel == 1) || ( pbuddy_mlmeext->cur_channel == 6 ) || ( pbuddy_mlmeext->cur_channel == 11 ) )
5245 // Use the AP's channel as the listen channel
5246 // This will avoid the channel switch between AP's channel and listen channel.
5247 pwdinfo->listen_channel = pbuddy_mlmeext->cur_channel;
5250 #endif //CONFIG_CONCURRENT_MODE
5252 // Use the channel 11 as the listen channel
5253 pwdinfo->listen_channel = 11;
5256 if (role == P2P_ROLE_DEVICE)
5258 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
5259 #ifdef CONFIG_CONCURRENT_MODE
5260 if ( check_buddy_fwstate(padapter, _FW_LINKED ) == _TRUE )
5262 rtw_p2p_set_state(pwdinfo, P2P_STATE_IDLE);
5267 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
5269 pwdinfo->intent = 1;
5270 rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_LISTEN);
5272 else if (role == P2P_ROLE_CLIENT)
5274 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
5275 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
5276 pwdinfo->intent = 1;
5277 rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
5279 else if (role == P2P_ROLE_GO)
5281 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
5282 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
5283 pwdinfo->intent = 15;
5284 rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
5287 // Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 )
5288 pwdinfo->support_rate[0] = 0x8c; // 6(B)
5289 pwdinfo->support_rate[1] = 0x92; // 9(B)
5290 pwdinfo->support_rate[2] = 0x18; // 12
5291 pwdinfo->support_rate[3] = 0x24; // 18
5292 pwdinfo->support_rate[4] = 0x30; // 24
5293 pwdinfo->support_rate[5] = 0x48; // 36
5294 pwdinfo->support_rate[6] = 0x60; // 48
5295 pwdinfo->support_rate[7] = 0x6c; // 54
5297 _rtw_memcpy( ( void* ) pwdinfo->p2p_wildcard_ssid, "DIRECT-", 7 );
5299 _rtw_memset( pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN );
5300 pwdinfo->device_name_len = 0;
5302 _rtw_memset( &pwdinfo->invitereq_info, 0x00, sizeof( struct tx_invite_req_info ) );
5303 pwdinfo->invitereq_info.token = 3; // Token used for P2P invitation request frame.
5305 _rtw_memset( &pwdinfo->inviteresp_info, 0x00, sizeof( struct tx_invite_resp_info ) );
5306 pwdinfo->inviteresp_info.token = 0;
5308 pwdinfo->profileindex = 0;
5309 _rtw_memset( &pwdinfo->profileinfo[ 0 ], 0x00, sizeof( struct profile_info ) * P2P_MAX_PERSISTENT_GROUP_NUM );
5311 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
5313 pwdinfo->listen_dwell = ( u8 ) (( rtw_get_current_time() % 3 ) + 1);
5314 //DBG_8192C( "[%s] listen_dwell time is %d00ms\n", __FUNCTION__, pwdinfo->listen_dwell );
5316 _rtw_memset( &pwdinfo->tx_prov_disc_info, 0x00, sizeof( struct tx_provdisc_req_info ) );
5317 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_NONE;
5319 _rtw_memset( &pwdinfo->nego_req_info, 0x00, sizeof( struct tx_nego_req_info ) );
5321 pwdinfo->device_password_id_for_nego = WPS_DPID_PBC;
5322 pwdinfo->negotiation_dialog_token = 1;
5324 _rtw_memset( pwdinfo->nego_ssid, 0x00, WLAN_SSID_MAXLEN );
5325 pwdinfo->nego_ssidlen = 0;
5327 pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
5329 pwdinfo->supported_wps_cm = WPS_CONFIG_METHOD_DISPLAY | WPS_CONFIG_METHOD_PBC;
5330 pwdinfo->wfd_info = pwfd_info;
5332 pwdinfo->supported_wps_cm = WPS_CONFIG_METHOD_DISPLAY | WPS_CONFIG_METHOD_PBC | WPS_CONFIG_METHOD_KEYPAD;
5334 pwdinfo->channel_list_attr_len = 0;
5335 _rtw_memset( pwdinfo->channel_list_attr, 0x00, 100 );
5337 _rtw_memset( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, 0x00, 4 );
5338 _rtw_memset( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, '0', 3 );
5339 _rtw_memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) );
5340 #ifdef CONFIG_CONCURRENT_MODE
5341 #ifdef CONFIG_IOCTL_CFG80211
5342 pwdinfo->ext_listen_interval = 1000; //The interval to be available with legacy AP during p2p0-find/scan
5343 pwdinfo->ext_listen_period = 3000; //The time period to be available for P2P during nego
5344 #else //!CONFIG_IOCTL_CFG80211
5345 //pwdinfo->ext_listen_interval = 3000;
5346 //pwdinfo->ext_listen_period = 400;
5347 pwdinfo->ext_listen_interval = 1000;
5348 pwdinfo->ext_listen_period = 1000;
5349 #endif //!CONFIG_IOCTL_CFG80211
5352 // Commented by Kurt 20130319
5353 // For WiDi purpose: Use CFG80211 interface but controled WFD/RDS frame by driver itself.
5354 #ifdef CONFIG_IOCTL_CFG80211
5355 pwdinfo->driver_interface = DRIVER_CFG80211;
5357 pwdinfo->driver_interface = DRIVER_WEXT;
5358 #endif //CONFIG_IOCTL_CFG80211
5360 pwdinfo->wfd_tdls_enable = 0;
5361 _rtw_memset( pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN );
5362 _rtw_memset( pwdinfo->p2p_peer_device_addr, 0x00, ETH_ALEN );
5364 pwdinfo->rx_invitereq_info.operation_ch[0] = 0;
5365 pwdinfo->rx_invitereq_info.operation_ch[1] = 0; // Used to indicate the scan end in site survey function
5366 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
5367 pwdinfo->rx_invitereq_info.operation_ch[2] = 0;
5368 pwdinfo->rx_invitereq_info.operation_ch[3] = 0;
5369 pwdinfo->rx_invitereq_info.operation_ch[4] = 0;
5370 #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
5371 pwdinfo->rx_invitereq_info.scan_op_ch_only = 0;
5372 pwdinfo->p2p_info.operation_ch[0] = 0;
5373 pwdinfo->p2p_info.operation_ch[1] = 0; // Used to indicate the scan end in site survey function
5374 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
5375 pwdinfo->p2p_info.operation_ch[2] = 0;
5376 pwdinfo->p2p_info.operation_ch[3] = 0;
5377 pwdinfo->p2p_info.operation_ch[4] = 0;
5378 #endif //CONFIG_P2P_OP_CHK_SOCIAL_CH
5379 pwdinfo->p2p_info.scan_op_ch_only = 0;
5382 #ifdef CONFIG_DBG_P2P
5385 * rtw_p2p_role_txt - Get the p2p role name as a text string
5387 * Returns: The state name as a printable text string
5389 const char * rtw_p2p_role_txt(enum P2P_ROLE role)
5392 case P2P_ROLE_DISABLE:
5393 return "P2P_ROLE_DISABLE";
5394 case P2P_ROLE_DEVICE:
5395 return "P2P_ROLE_DEVICE";
5396 case P2P_ROLE_CLIENT:
5397 return "P2P_ROLE_CLIENT";
5399 return "P2P_ROLE_GO";
5406 * rtw_p2p_state_txt - Get the p2p state name as a text string
5408 * Returns: The state name as a printable text string
5410 const char * rtw_p2p_state_txt(enum P2P_STATE state)
5413 case P2P_STATE_NONE:
5414 return "P2P_STATE_NONE";
5415 case P2P_STATE_IDLE:
5416 return "P2P_STATE_IDLE";
5417 case P2P_STATE_LISTEN:
5418 return "P2P_STATE_LISTEN";
5419 case P2P_STATE_SCAN:
5420 return "P2P_STATE_SCAN";
5421 case P2P_STATE_FIND_PHASE_LISTEN:
5422 return "P2P_STATE_FIND_PHASE_LISTEN";
5423 case P2P_STATE_FIND_PHASE_SEARCH:
5424 return "P2P_STATE_FIND_PHASE_SEARCH";
5425 case P2P_STATE_TX_PROVISION_DIS_REQ:
5426 return "P2P_STATE_TX_PROVISION_DIS_REQ";
5427 case P2P_STATE_RX_PROVISION_DIS_RSP:
5428 return "P2P_STATE_RX_PROVISION_DIS_RSP";
5429 case P2P_STATE_RX_PROVISION_DIS_REQ:
5430 return "P2P_STATE_RX_PROVISION_DIS_REQ";
5431 case P2P_STATE_GONEGO_ING:
5432 return "P2P_STATE_GONEGO_ING";
5433 case P2P_STATE_GONEGO_OK:
5434 return "P2P_STATE_GONEGO_OK";
5435 case P2P_STATE_GONEGO_FAIL:
5436 return "P2P_STATE_GONEGO_FAIL";
5437 case P2P_STATE_RECV_INVITE_REQ_MATCH:
5438 return "P2P_STATE_RECV_INVITE_REQ_MATCH";
5439 case P2P_STATE_PROVISIONING_ING:
5440 return "P2P_STATE_PROVISIONING_ING";
5441 case P2P_STATE_PROVISIONING_DONE:
5442 return "P2P_STATE_PROVISIONING_DONE";
5443 case P2P_STATE_TX_INVITE_REQ:
5444 return "P2P_STATE_TX_INVITE_REQ";
5445 case P2P_STATE_RX_INVITE_RESP_OK:
5446 return "P2P_STATE_RX_INVITE_RESP_OK";
5447 case P2P_STATE_RECV_INVITE_REQ_DISMATCH:
5448 return "P2P_STATE_RECV_INVITE_REQ_DISMATCH";
5449 case P2P_STATE_RECV_INVITE_REQ_GO:
5450 return "P2P_STATE_RECV_INVITE_REQ_GO";
5451 case P2P_STATE_RECV_INVITE_REQ_JOIN:
5452 return "P2P_STATE_RECV_INVITE_REQ_JOIN";
5453 case P2P_STATE_RX_INVITE_RESP_FAIL:
5454 return "P2P_STATE_RX_INVITE_RESP_FAIL";
5455 case P2P_STATE_RX_INFOR_NOREADY:
5456 return "P2P_STATE_RX_INFOR_NOREADY";
5457 case P2P_STATE_TX_INFOR_NOREADY:
5458 return "P2P_STATE_TX_INFOR_NOREADY";
5464 void dbg_rtw_p2p_set_state(struct wifidirect_info *wdinfo, enum P2P_STATE state, const char *caller, int line)
5466 if(!_rtw_p2p_chk_state(wdinfo, state)) {
5467 enum P2P_STATE old_state = _rtw_p2p_state(wdinfo);
5468 _rtw_p2p_set_state(wdinfo, state);
5469 DBG_871X("[CONFIG_DBG_P2P]%s:%d set_state from %s to %s\n", caller, line
5470 , rtw_p2p_state_txt(old_state), rtw_p2p_state_txt(_rtw_p2p_state(wdinfo))
5473 DBG_871X("[CONFIG_DBG_P2P]%s:%d set_state to same state %s\n", caller, line
5474 , rtw_p2p_state_txt(_rtw_p2p_state(wdinfo))
5478 void dbg_rtw_p2p_set_pre_state(struct wifidirect_info *wdinfo, enum P2P_STATE state, const char *caller, int line)
5480 if(_rtw_p2p_pre_state(wdinfo) != state) {
5481 enum P2P_STATE old_state = _rtw_p2p_pre_state(wdinfo);
5482 _rtw_p2p_set_pre_state(wdinfo, state);
5483 DBG_871X("[CONFIG_DBG_P2P]%s:%d set_pre_state from %s to %s\n", caller, line
5484 , rtw_p2p_state_txt(old_state), rtw_p2p_state_txt(_rtw_p2p_pre_state(wdinfo))
5487 DBG_871X("[CONFIG_DBG_P2P]%s:%d set_pre_state to same state %s\n", caller, line
5488 , rtw_p2p_state_txt(_rtw_p2p_pre_state(wdinfo))
5493 void dbg_rtw_p2p_restore_state(struct wifidirect_info *wdinfo, const char *caller, int line)
5495 if(wdinfo->pre_p2p_state != -1) {
5496 DBG_871X("[CONFIG_DBG_P2P]%s:%d restore from %s to %s\n", caller, line
5497 , p2p_state_str[wdinfo->p2p_state], p2p_state_str[wdinfo->pre_p2p_state]
5499 _rtw_p2p_restore_state(wdinfo);
5501 DBG_871X("[CONFIG_DBG_P2P]%s:%d restore no pre state, cur state %s\n", caller, line
5502 , p2p_state_str[wdinfo->p2p_state]
5507 void dbg_rtw_p2p_set_role(struct wifidirect_info *wdinfo, enum P2P_ROLE role, const char *caller, int line)
5509 if(wdinfo->role != role) {
5510 enum P2P_ROLE old_role = wdinfo->role;
5511 _rtw_p2p_set_role(wdinfo, role);
5512 DBG_871X("[CONFIG_DBG_P2P]%s:%d set_role from %s to %s\n", caller, line
5513 , rtw_p2p_role_txt(old_role), rtw_p2p_role_txt(wdinfo->role)
5516 DBG_871X("[CONFIG_DBG_P2P]%s:%d set_role to same role %s\n", caller, line
5517 , rtw_p2p_role_txt(wdinfo->role)
5521 #endif //CONFIG_DBG_P2P
5524 int rtw_p2p_enable(_adapter *padapter, enum P2P_ROLE role)
5527 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
5529 if (role == P2P_ROLE_DEVICE || role == P2P_ROLE_CLIENT|| role == P2P_ROLE_GO)
5531 u8 channel, ch_offset;
5534 #ifdef CONFIG_CONCURRENT_MODE
5535 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
5536 struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
5537 // Commented by Albert 2011/12/30
5538 // The driver just supports 1 P2P group operation.
5539 // So, this function will do nothing if the buddy adapter had enabled the P2P function.
5540 if(!rtw_p2p_chk_state(pbuddy_wdinfo, P2P_STATE_NONE))
5542 // The buddy adapter had enabled the P2P function.
5545 #endif //CONFIG_CONCURRENT_MODE
5547 //leave IPS/Autosuspend
5548 if (_FAIL == rtw_pwr_wakeup(padapter)) {
5553 // Added by Albert 2011/03/22
5554 // In the P2P mode, the driver should not support the b mode.
5555 // So, the Tx packet shouldn't use the CCK rate
5556 update_tx_basic_rate(padapter, WIRELESS_11AGN);
5558 //Enable P2P function
5559 init_wifidirect_info(padapter, role);
5561 rtw_hal_set_odm_var(padapter,HAL_ODM_P2P_STATE,NULL,_TRUE);
5563 if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST))
5564 rtw_hal_set_odm_var(padapter, HAL_ODM_WIFI_DISPLAY_STATE, NULL, _TRUE);
5568 else if (role == P2P_ROLE_DISABLE)
5570 #ifdef CONFIG_INTEL_WIDI
5571 if( padapter->mlmepriv.p2p_reject_disable == _TRUE )
5573 #endif //CONFIG_INTEL_WIDI
5575 #ifdef CONFIG_IOCTL_CFG80211
5576 if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 )
5577 adapter_wdev_data(padapter)->p2p_enabled = _FALSE;
5578 #endif //CONFIG_IOCTL_CFG80211
5581 //Disable P2P function
5582 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
5584 _cancel_timer_ex( &pwdinfo->find_phase_timer );
5585 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
5586 _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer);
5587 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey);
5588 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey2);
5589 reset_ch_sitesurvey_timer_process( padapter );
5590 reset_ch_sitesurvey_timer_process2( padapter );
5591 #ifdef CONFIG_CONCURRENT_MODE
5592 _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer);
5594 rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE);
5595 rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_NONE);
5596 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DISABLE);
5597 _rtw_memset(&pwdinfo->rx_prov_disc_info, 0x00, sizeof(struct rx_provdisc_req_info));
5599 /* Remove profiles in wifidirect_info structure. */
5600 _rtw_memset( &pwdinfo->profileinfo[ 0 ], 0x00, sizeof( struct profile_info ) * P2P_MAX_PERSISTENT_GROUP_NUM );
5601 pwdinfo->profileindex = 0;
5604 rtw_hal_set_odm_var(padapter,HAL_ODM_P2P_STATE,NULL,_FALSE);
5606 if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST))
5607 rtw_hal_set_odm_var(padapter, HAL_ODM_WIFI_DISPLAY_STATE, NULL, _FALSE);
5610 if (_FAIL == rtw_pwr_wakeup(padapter)) {
5615 //Restore to initial setting.
5616 update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode);
5618 #ifdef CONFIG_INTEL_WIDI
5619 rtw_reset_widi_info(padapter);
5620 #endif //CONFIG_INTEL_WIDI
5623 #ifdef CONFIG_IOCTL_CFG80211
5624 pwdinfo->driver_interface = DRIVER_CFG80211;
5626 pwdinfo->driver_interface = DRIVER_WEXT;
5627 #endif //CONFIG_IOCTL_CFG80211