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 ******************************************************************************/
17 #include <drv_types.h>
19 #include <rtl8723a_cmd.h>
22 #ifdef CONFIG_8723AU_P2P
24 static int rtw_p2p_is_channel_list_ok(u8 desired_ch
, u8
* ch_list
, u8 ch_cnt
)
28 for (i
= 0; i
< ch_cnt
; i
++)
30 if (ch_list
[ i
] == desired_ch
)
39 static int is_any_client_associated(struct rtw_adapter
*padapter
)
41 return padapter
->stapriv
.asoc_list_cnt
? true : false;
44 static u32
go_add_group_info_attr(struct wifidirect_info
*pwdinfo
, u8
*pbuf
)
46 struct list_head
*phead
, *plist
;
49 u8 tmplen
, *pdata_attr
, *pstart
, *pcur
;
50 struct sta_info
*psta
;
51 struct rtw_adapter
*padapter
= pwdinfo
->padapter
;
52 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
54 DBG_8723A("%s\n", __func__
);
56 pdata_attr
= kzalloc(MAX_P2P_IE_LEN
, GFP_ATOMIC
);
61 spin_lock_bh(&pstapriv
->asoc_list_lock
);
62 phead
= &pstapriv
->asoc_list
;
64 list_for_each(plist
, phead
) {
65 psta
= container_of(plist
, struct sta_info
, asoc_list
);
67 if (psta
->is_p2p_device
)
73 /* P2P device address */
74 memcpy(pcur
, psta
->dev_addr
, ETH_ALEN
);
77 /* P2P interface address */
78 memcpy(pcur
, psta
->hwaddr
, ETH_ALEN
);
81 *pcur
= psta
->dev_cap
;
84 /* u16*)(pcur) = cpu_to_be16(psta->config_methods); */
85 put_unaligned_be16(psta
->config_methods
, pcur
);
88 memcpy(pcur
, psta
->primary_dev_type
, 8);
91 *pcur
= psta
->num_of_secdev_type
;
94 memcpy(pcur
, psta
->secdev_types_list
, psta
->num_of_secdev_type
*8);
95 pcur
+= psta
->num_of_secdev_type
*8;
97 if (psta
->dev_name_len
>0)
99 /* u16*)(pcur) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); */
100 put_unaligned_be16(WPS_ATTR_DEVICE_NAME
, pcur
);
103 /* u16*)(pcur) = cpu_to_be16(psta->dev_name_len); */
104 put_unaligned_be16(psta
->dev_name_len
, pcur
);
107 memcpy(pcur
, psta
->dev_name
, psta
->dev_name_len
);
108 pcur
+= psta
->dev_name_len
;
111 tmplen
= (u8
)(pcur
-pstart
);
113 *pstart
= (tmplen
-1);
117 /* pstart += tmplen; */
123 spin_unlock_bh(&pstapriv
->asoc_list_lock
);
127 len
= rtw_set_p2p_attr_content23a(pbuf
, P2P_ATTR_GROUP_INFO
, attr_len
, pdata_attr
);
135 static void issue_group_disc_req(struct wifidirect_info
*pwdinfo
, u8
*da
)
137 struct xmit_frame
*pmgntframe
;
138 struct pkt_attrib
*pattrib
;
139 unsigned char *pframe
;
140 struct ieee80211_hdr
*pwlanhdr
;
141 unsigned short *fctrl
;
142 struct rtw_adapter
*padapter
= pwdinfo
->padapter
;
143 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
144 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
145 unsigned char category
= WLAN_CATEGORY_VENDOR_SPECIFIC
;/* P2P action frame */
146 u32 p2poui
= cpu_to_be32(P2POUI
);
147 u8 oui_subtype
= P2P_GO_DISC_REQUEST
;
150 DBG_8723A("[%s]\n", __func__
);
152 if ((pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
)) == NULL
)
157 /* update attribute */
158 pattrib
= &pmgntframe
->attrib
;
159 update_mgntframe_attrib23a(padapter
, pattrib
);
161 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
163 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
164 pwlanhdr
= (struct ieee80211_hdr
*)pframe
;
166 fctrl
= &pwlanhdr
->frame_control
;
169 memcpy(pwlanhdr
->addr1
, da
, ETH_ALEN
);
170 memcpy(pwlanhdr
->addr2
, pwdinfo
->interface_addr
, ETH_ALEN
);
171 memcpy(pwlanhdr
->addr3
, pwdinfo
->interface_addr
, ETH_ALEN
);
173 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
174 pmlmeext
->mgnt_seq
++;
175 SetFrameSubType(pframe
, WIFI_ACTION
);
177 pframe
+= sizeof(struct ieee80211_hdr_3addr
);
178 pattrib
->pktlen
= sizeof(struct ieee80211_hdr_3addr
);
180 /* Build P2P action frame header */
181 pframe
= rtw_set_fixed_ie23a(pframe
, 1, &category
, &pattrib
->pktlen
);
182 pframe
= rtw_set_fixed_ie23a(pframe
, 4, (unsigned char *)&p2poui
, &pattrib
->pktlen
);
183 pframe
= rtw_set_fixed_ie23a(pframe
, 1, &oui_subtype
, &pattrib
->pktlen
);
184 pframe
= rtw_set_fixed_ie23a(pframe
, 1, &dialogToken
, &pattrib
->pktlen
);
186 /* there is no IE in this P2P action frame */
188 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
190 dump_mgntframe23a(padapter
, pmgntframe
);
193 static void issue_p2p_devdisc_resp(struct wifidirect_info
*pwdinfo
, u8
*da
, u8 status
, u8 dialogToken
)
195 struct xmit_frame
*pmgntframe
;
196 struct pkt_attrib
*pattrib
;
197 unsigned char *pframe
;
198 struct ieee80211_hdr
*pwlanhdr
;
199 unsigned short *fctrl
;
200 struct rtw_adapter
*padapter
= pwdinfo
->padapter
;
201 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
202 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
203 unsigned char category
= WLAN_CATEGORY_PUBLIC
;
204 u8 action
= P2P_PUB_ACTION_ACTION
;
205 u32 p2poui
= cpu_to_be32(P2POUI
);
206 u8 oui_subtype
= P2P_DEVDISC_RESP
;
207 u8 p2pie
[8] = { 0x00 };
210 DBG_8723A("[%s]\n", __func__
);
212 if ((pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
)) == NULL
)
217 /* update attribute */
218 pattrib
= &pmgntframe
->attrib
;
219 update_mgntframe_attrib23a(padapter
, pattrib
);
221 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
223 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
224 pwlanhdr
= (struct ieee80211_hdr
*)pframe
;
226 fctrl
= &pwlanhdr
->frame_control
;
229 memcpy(pwlanhdr
->addr1
, da
, ETH_ALEN
);
230 memcpy(pwlanhdr
->addr2
, pwdinfo
->device_addr
, ETH_ALEN
);
231 memcpy(pwlanhdr
->addr3
, pwdinfo
->device_addr
, ETH_ALEN
);
233 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
234 pmlmeext
->mgnt_seq
++;
235 SetFrameSubType(pframe
, WIFI_ACTION
);
237 pframe
+= sizeof(struct ieee80211_hdr_3addr
);
238 pattrib
->pktlen
= sizeof(struct ieee80211_hdr_3addr
);
240 /* Build P2P public action frame header */
241 pframe
= rtw_set_fixed_ie23a(pframe
, 1, &category
, &pattrib
->pktlen
);
242 pframe
= rtw_set_fixed_ie23a(pframe
, 1, &action
, &pattrib
->pktlen
);
243 pframe
= rtw_set_fixed_ie23a(pframe
, 4, (unsigned char *) &p2poui
,
245 pframe
= rtw_set_fixed_ie23a(pframe
, 1, &oui_subtype
, &pattrib
->pktlen
);
246 pframe
= rtw_set_fixed_ie23a(pframe
, 1, &dialogToken
, &pattrib
->pktlen
);
251 p2pie
[ p2pielen
++ ] = 0x50;
252 p2pie
[ p2pielen
++ ] = 0x6F;
253 p2pie
[ p2pielen
++ ] = 0x9A;
254 p2pie
[ p2pielen
++ ] = 0x09; /* WFA P2P v1.0 */
256 /* P2P_ATTR_STATUS */
257 p2pielen
+= rtw_set_p2p_attr_content23a(&p2pie
[p2pielen
], P2P_ATTR_STATUS
, 1, &status
);
259 pframe
= rtw_set_ie23a(pframe
, _VENDOR_SPECIFIC_IE_
, p2pielen
, p2pie
, &pattrib
->pktlen
);
261 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
263 dump_mgntframe23a(padapter
, pmgntframe
);
266 static void issue_p2p_provision_resp(struct wifidirect_info
*pwdinfo
, u8
* raddr
, u8
* frame_body
, u16 config_method
)
268 struct rtw_adapter
*padapter
= pwdinfo
->padapter
;
269 unsigned char category
= WLAN_CATEGORY_PUBLIC
;
270 u8 action
= P2P_PUB_ACTION_ACTION
;
271 u8 dialogToken
= frame_body
[7]; /* The Dialog Token of provisioning discovery request frame. */
272 u32 p2poui
= cpu_to_be32(P2POUI
);
273 u8 oui_subtype
= P2P_PROVISION_DISC_RESP
;
274 u8 wpsie
[ 100 ] = { 0x00 };
276 #ifdef CONFIG_8723AU_P2P
278 #endif /* CONFIG_8723AU_P2P */
280 struct xmit_frame
*pmgntframe
;
281 struct pkt_attrib
*pattrib
;
282 unsigned char *pframe
;
283 struct ieee80211_hdr
*pwlanhdr
;
284 unsigned short *fctrl
;
285 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
286 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
288 if ((pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
)) == NULL
)
291 /* update attribute */
292 pattrib
= &pmgntframe
->attrib
;
293 update_mgntframe_attrib23a(padapter
, pattrib
);
295 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
297 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
298 pwlanhdr
= (struct ieee80211_hdr
*)pframe
;
300 fctrl
= &pwlanhdr
->frame_control
;
303 memcpy(pwlanhdr
->addr1
, raddr
, ETH_ALEN
);
304 memcpy(pwlanhdr
->addr2
, myid(&padapter
->eeprompriv
), ETH_ALEN
);
305 memcpy(pwlanhdr
->addr3
, myid(&padapter
->eeprompriv
), ETH_ALEN
);
307 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
308 pmlmeext
->mgnt_seq
++;
309 SetFrameSubType(pframe
, WIFI_ACTION
);
311 pframe
+= sizeof(struct ieee80211_hdr_3addr
);
312 pattrib
->pktlen
= sizeof(struct ieee80211_hdr_3addr
);
314 pframe
= rtw_set_fixed_ie23a(pframe
, 1, &category
, &pattrib
->pktlen
);
315 pframe
= rtw_set_fixed_ie23a(pframe
, 1, &action
, &pattrib
->pktlen
);
316 pframe
= rtw_set_fixed_ie23a(pframe
, 4, (unsigned char *) &p2poui
,
318 pframe
= rtw_set_fixed_ie23a(pframe
, 1, &oui_subtype
, &pattrib
->pktlen
);
319 pframe
= rtw_set_fixed_ie23a(pframe
, 1, &dialogToken
, &pattrib
->pktlen
);
323 /* u32*) (wpsie) = cpu_to_be32(WPSOUI); */
324 put_unaligned_be32(WPSOUI
, wpsie
);
329 /* u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD); */
330 put_unaligned_be16(WPS_ATTR_CONF_METHOD
, wpsie
+ wpsielen
);
334 /* u16*) (wpsie + wpsielen) = cpu_to_be16(0x0002); */
335 put_unaligned_be16(0x0002, wpsie
+ wpsielen
);
339 /* u16*) (wpsie + wpsielen) = cpu_to_be16(config_method); */
340 put_unaligned_be16(config_method
, wpsie
+ wpsielen
);
343 pframe
= rtw_set_ie23a(pframe
, _VENDOR_SPECIFIC_IE_
, wpsielen
, (unsigned char *) wpsie
, &pattrib
->pktlen
);
345 #ifdef CONFIG_8723AU_P2P
346 wfdielen
= build_provdisc_resp_wfd_ie(pwdinfo
, pframe
);
348 pattrib
->pktlen
+= wfdielen
;
349 #endif /* CONFIG_8723AU_P2P */
351 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
353 dump_mgntframe23a(padapter
, pmgntframe
);
358 static void issue_p2p_presence_resp(struct wifidirect_info
*pwdinfo
, u8
*da
, u8 status
, u8 dialogToken
)
360 struct xmit_frame
*pmgntframe
;
361 struct pkt_attrib
*pattrib
;
362 unsigned char *pframe
;
363 struct ieee80211_hdr
*pwlanhdr
;
364 unsigned short *fctrl
;
365 struct rtw_adapter
*padapter
= pwdinfo
->padapter
;
366 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
367 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
368 unsigned char category
= WLAN_CATEGORY_VENDOR_SPECIFIC
;/* P2P action frame */
369 u32 p2poui
= cpu_to_be32(P2POUI
);
370 u8 oui_subtype
= P2P_PRESENCE_RESPONSE
;
371 u8 p2pie
[ MAX_P2P_IE_LEN
] = { 0x00 };
372 u8 noa_attr_content
[32] = { 0x00 };
375 DBG_8723A("[%s]\n", __func__
);
377 if ((pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
)) == NULL
)
382 /* update attribute */
383 pattrib
= &pmgntframe
->attrib
;
384 update_mgntframe_attrib23a(padapter
, pattrib
);
386 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
388 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
389 pwlanhdr
= (struct ieee80211_hdr
*)pframe
;
391 fctrl
= &pwlanhdr
->frame_control
;
394 memcpy(pwlanhdr
->addr1
, da
, ETH_ALEN
);
395 memcpy(pwlanhdr
->addr2
, pwdinfo
->interface_addr
, ETH_ALEN
);
396 memcpy(pwlanhdr
->addr3
, pwdinfo
->interface_addr
, ETH_ALEN
);
398 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
399 pmlmeext
->mgnt_seq
++;
400 SetFrameSubType(pframe
, WIFI_ACTION
);
402 pframe
+= sizeof(struct ieee80211_hdr_3addr
);
403 pattrib
->pktlen
= sizeof(struct ieee80211_hdr_3addr
);
405 /* Build P2P action frame header */
406 pframe
= rtw_set_fixed_ie23a(pframe
, 1, &category
, &pattrib
->pktlen
);
407 pframe
= rtw_set_fixed_ie23a(pframe
, 4, (unsigned char *) &p2poui
,
409 pframe
= rtw_set_fixed_ie23a(pframe
, 1, &oui_subtype
, &pattrib
->pktlen
);
410 pframe
= rtw_set_fixed_ie23a(pframe
, 1, &dialogToken
, &pattrib
->pktlen
);
412 /* Add P2P IE header */
415 p2pie
[ p2pielen
++ ] = 0x50;
416 p2pie
[ p2pielen
++ ] = 0x6F;
417 p2pie
[ p2pielen
++ ] = 0x9A;
418 p2pie
[ p2pielen
++ ] = 0x09; /* WFA P2P v1.0 */
420 /* Add Status attribute in P2P IE */
421 p2pielen
+= rtw_set_p2p_attr_content23a(&p2pie
[p2pielen
], P2P_ATTR_STATUS
, 1, &status
);
423 /* Add NoA attribute in P2P IE */
424 noa_attr_content
[0] = 0x1;/* index */
425 noa_attr_content
[1] = 0x0;/* CTWindow and OppPS Parameters */
427 /* todo: Notice of Absence Descriptor(s) */
429 p2pielen
+= rtw_set_p2p_attr_content23a(&p2pie
[p2pielen
], P2P_ATTR_NOA
, 2, noa_attr_content
);
431 pframe
= rtw_set_ie23a(pframe
, _VENDOR_SPECIFIC_IE_
, p2pielen
, p2pie
,
434 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
436 dump_mgntframe23a(padapter
, pmgntframe
);
439 u32
build_beacon_p2p_ie23a(struct wifidirect_info
*pwdinfo
, u8
*pbuf
)
441 u8 p2pie
[ MAX_P2P_IE_LEN
] = { 0x00 };
443 u32 len
= 0, p2pielen
= 0;
447 p2pie
[ p2pielen
++ ] = 0x50;
448 p2pie
[ p2pielen
++ ] = 0x6F;
449 p2pie
[ p2pielen
++ ] = 0x9A;
450 p2pie
[ p2pielen
++ ] = 0x09; /* WFA P2P v1.0 */
452 /* According to the P2P Specification, the beacon frame should contain 3 P2P attributes */
453 /* 1. P2P Capability */
454 /* 2. P2P Device ID */
455 /* 3. Notice of Absence (NOA) */
457 /* P2P Capability ATTR */
461 /* Device Capability Bitmap, 1 byte */
462 /* Be able to participate in additional P2P Groups and */
463 /* support the P2P Invitation Procedure */
464 /* Group Capability Bitmap, 1 byte */
465 capability
= P2P_DEVCAP_INVITATION_PROC
|P2P_DEVCAP_CLIENT_DISCOVERABILITY
;
466 capability
|= ((P2P_GRPCAP_GO
| P2P_GRPCAP_INTRABSS
) << 8);
467 if (rtw_p2p_chk_state(pwdinfo
, P2P_STATE_PROVISIONING_ING
))
468 capability
|= (P2P_GRPCAP_GROUP_FORMATION
<<8);
470 capability
= cpu_to_le16(capability
);
472 p2pielen
+= rtw_set_p2p_attr_content23a(&p2pie
[p2pielen
], P2P_ATTR_CAPABILITY
, 2, (u8
*)&capability
);
474 /* P2P Device ID ATTR */
475 p2pielen
+= rtw_set_p2p_attr_content23a(&p2pie
[p2pielen
], P2P_ATTR_DEVICE_ID
, ETH_ALEN
, pwdinfo
->device_addr
);
477 /* Notice of Absence ATTR */
482 /* go_add_noa_attr(pwdinfo); */
484 pbuf
= rtw_set_ie23a(pbuf
, _VENDOR_SPECIFIC_IE_
, p2pielen
, (unsigned char *) p2pie
, &len
);
489 #ifdef CONFIG_8723AU_P2P
490 u32
build_beacon_wfd_ie(struct wifidirect_info
*pwdinfo
, u8
*pbuf
)
492 u8 wfdie
[ MAX_WFD_IE_LEN
] = { 0x00 };
493 u32 len
= 0, wfdielen
= 0;
494 struct rtw_adapter
*padapter
= pwdinfo
->padapter
;
495 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
496 struct wifi_display_info
* pwfd_info
= padapter
->wdinfo
.wfd_info
;
500 wfdie
[ wfdielen
++ ] = 0x50;
501 wfdie
[ wfdielen
++ ] = 0x6F;
502 wfdie
[ wfdielen
++ ] = 0x9A;
503 wfdie
[ wfdielen
++ ] = 0x0A; /* WFA WFD v1.0 */
505 /* Commented by Albert 20110812 */
506 /* According to the WFD Specification, the beacon frame should contain 4 WFD attributes */
507 /* 1. WFD Device Information */
508 /* 2. Associated BSSID */
509 /* 3. Coupled Sink Information */
511 /* WFD Device Information ATTR */
513 wfdie
[ wfdielen
++ ] = WFD_ATTR_DEVICE_INFO
;
516 /* Note: In the WFD specification, the size of length field is 2. */
517 put_unaligned_be16(0x0006, wfdie
+ wfdielen
);
521 /* WFD device information */
523 if (P2P_ROLE_GO
== pwdinfo
->role
)
525 if (is_any_client_associated(pwdinfo
->padapter
))
527 /* WFD primary sink + WiFi Direct mode + WSD (WFD Service Discovery) */
528 put_unaligned_be16(pwfd_info
->wfd_device_type
|
529 WFD_DEVINFO_WSD
, wfdie
+ wfdielen
);
533 /* WFD primary sink + available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery) */
534 put_unaligned_be16(pwfd_info
->wfd_device_type
|
535 WFD_DEVINFO_SESSION_AVAIL
|
536 WFD_DEVINFO_WSD
, wfdie
+ wfdielen
);
542 /* WFD primary sink + available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery) */
543 put_unaligned_be16(pwfd_info
->wfd_device_type
|
544 WFD_DEVINFO_SESSION_AVAIL
|
545 WFD_DEVINFO_WSD
, wfdie
+ wfdielen
);
551 /* Session Management Control Port */
552 /* Default TCP port for RTSP messages is 554 */
553 put_unaligned_be16(pwfd_info
->rtsp_ctrlport
, wfdie
+ wfdielen
);
557 /* WFD Device Maximum Throughput */
558 /* 300Mbps is the maximum throughput */
559 put_unaligned_be16(300, wfdie
+ wfdielen
);
562 /* Associated BSSID ATTR */
564 wfdie
[ wfdielen
++ ] = WFD_ATTR_ASSOC_BSSID
;
567 /* Note: In the WFD specification, the size of length field is 2. */
568 put_unaligned_be16(0x0006, wfdie
+ wfdielen
);
572 /* Associated BSSID */
573 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == true)
575 memcpy(wfdie
+ wfdielen
, &pmlmepriv
->assoc_bssid
[ 0 ], ETH_ALEN
);
579 memset(wfdie
+ wfdielen
, 0x00, ETH_ALEN
);
582 wfdielen
+= ETH_ALEN
;
584 /* Coupled Sink Information ATTR */
586 wfdie
[ wfdielen
++ ] = WFD_ATTR_COUPLED_SINK_INFO
;
589 /* Note: In the WFD specification, the size of length field is 2. */
590 put_unaligned_be16(0x0007, wfdie
+ wfdielen
);
594 /* Coupled Sink Status bitmap */
595 /* Not coupled/available for Coupling */
596 wfdie
[ wfdielen
++ ] = 0;
598 wfdie
[ wfdielen
++ ] = 0;
599 wfdie
[ wfdielen
++ ] = 0;
600 wfdie
[ wfdielen
++ ] = 0;
601 wfdie
[ wfdielen
++ ] = 0;
602 wfdie
[ wfdielen
++ ] = 0;
603 wfdie
[ wfdielen
++ ] = 0;
605 pbuf
= rtw_set_ie23a(pbuf
, _VENDOR_SPECIFIC_IE_
, wfdielen
, (unsigned char *) wfdie
, &len
);
610 u32
build_probe_req_wfd_ie(struct wifidirect_info
*pwdinfo
, u8
*pbuf
)
612 u8 wfdie
[ MAX_WFD_IE_LEN
] = { 0x00 };
613 u32 len
= 0, wfdielen
= 0;
614 struct rtw_adapter
*padapter
= pwdinfo
->padapter
;
615 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
616 struct wifi_display_info
* pwfd_info
= padapter
->wdinfo
.wfd_info
;
620 wfdie
[ wfdielen
++ ] = 0x50;
621 wfdie
[ wfdielen
++ ] = 0x6F;
622 wfdie
[ wfdielen
++ ] = 0x9A;
623 wfdie
[ wfdielen
++ ] = 0x0A; /* WFA WFD v1.0 */
625 /* Commented by Albert 20110812 */
626 /* According to the WFD Specification, the probe request frame should contain 4 WFD attributes */
627 /* 1. WFD Device Information */
628 /* 2. Associated BSSID */
629 /* 3. Coupled Sink Information */
631 /* WFD Device Information ATTR */
633 wfdie
[ wfdielen
++ ] = WFD_ATTR_DEVICE_INFO
;
636 /* Note: In the WFD specification, the size of length field is 2. */
637 put_unaligned_be16(0x0006, wfdie
+ wfdielen
);
641 /* WFD device information */
643 if (1 == pwdinfo
->wfd_tdls_enable
)
645 /* WFD primary sink + available for WFD session + WiFi TDLS mode + WSC (WFD Service Discovery) */
646 put_unaligned_be16(pwfd_info
->wfd_device_type
|
647 WFD_DEVINFO_SESSION_AVAIL
|
649 WFD_DEVINFO_PC_TDLS
, wfdie
+ wfdielen
);
653 /* WFD primary sink + available for WFD session + WiFi Direct mode + WSC (WFD Service Discovery) */
654 put_unaligned_be16(pwfd_info
->wfd_device_type
|
655 WFD_DEVINFO_SESSION_AVAIL
|
656 WFD_DEVINFO_WSD
, wfdie
+ wfdielen
);
662 /* Session Management Control Port */
663 /* Default TCP port for RTSP messages is 554 */
664 put_unaligned_be16(pwfd_info
->rtsp_ctrlport
, wfdie
+ wfdielen
);
668 /* WFD Device Maximum Throughput */
669 /* 300Mbps is the maximum throughput */
670 put_unaligned_be16(300, wfdie
+ wfdielen
);
673 /* Associated BSSID ATTR */
675 wfdie
[ wfdielen
++ ] = WFD_ATTR_ASSOC_BSSID
;
678 /* Note: In the WFD specification, the size of length field is 2. */
679 put_unaligned_be16(0x0006, wfdie
+ wfdielen
);
683 /* Associated BSSID */
684 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == true)
686 memcpy(wfdie
+ wfdielen
, &pmlmepriv
->assoc_bssid
[ 0 ], ETH_ALEN
);
690 memset(wfdie
+ wfdielen
, 0x00, ETH_ALEN
);
693 wfdielen
+= ETH_ALEN
;
695 /* Coupled Sink Information ATTR */
697 wfdie
[ wfdielen
++ ] = WFD_ATTR_COUPLED_SINK_INFO
;
700 /* Note: In the WFD specification, the size of length field is 2. */
701 put_unaligned_be16(0x0007, wfdie
+ wfdielen
);
705 /* Coupled Sink Status bitmap */
706 /* Not coupled/available for Coupling */
707 wfdie
[ wfdielen
++ ] = 0;
709 wfdie
[ wfdielen
++ ] = 0;
710 wfdie
[ wfdielen
++ ] = 0;
711 wfdie
[ wfdielen
++ ] = 0;
712 wfdie
[ wfdielen
++ ] = 0;
713 wfdie
[ wfdielen
++ ] = 0;
714 wfdie
[ wfdielen
++ ] = 0;
716 pbuf
= rtw_set_ie23a(pbuf
, _VENDOR_SPECIFIC_IE_
, wfdielen
, (unsigned char *) wfdie
, &len
);
721 u32
build_probe_resp_wfd_ie(struct wifidirect_info
*pwdinfo
, u8
*pbuf
, u8 tunneled
)
723 u8 wfdie
[ MAX_WFD_IE_LEN
] = { 0x00 };
724 u32 len
= 0, wfdielen
= 0;
725 struct rtw_adapter
*padapter
= pwdinfo
->padapter
;
726 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
727 struct wifi_display_info
* pwfd_info
= padapter
->wdinfo
.wfd_info
;
731 wfdie
[ wfdielen
++ ] = 0x50;
732 wfdie
[ wfdielen
++ ] = 0x6F;
733 wfdie
[ wfdielen
++ ] = 0x9A;
734 wfdie
[ wfdielen
++ ] = 0x0A; /* WFA WFD v1.0 */
736 /* Commented by Albert 20110812 */
737 /* According to the WFD Specification, the probe response frame should contain 4 WFD attributes */
738 /* 1. WFD Device Information */
739 /* 2. Associated BSSID */
740 /* 3. Coupled Sink Information */
741 /* 4. WFD Session Information */
743 /* WFD Device Information ATTR */
745 wfdie
[ wfdielen
++ ] = WFD_ATTR_DEVICE_INFO
;
748 /* Note: In the WFD specification, the size of length field is 2. */
749 put_unaligned_be16(0x0006, wfdie
+ wfdielen
);
753 /* WFD device information */
754 /* WFD primary sink + available for WFD session + WiFi Direct mode */
756 if (true == pwdinfo
->session_available
)
758 if (P2P_ROLE_GO
== pwdinfo
->role
)
760 if (is_any_client_associated(pwdinfo
->padapter
))
762 if (pwdinfo
->wfd_tdls_enable
)
764 /* TDLS mode + WSD (WFD Service Discovery) */
765 put_unaligned_be16(pwfd_info
->wfd_device_type
| WFD_DEVINFO_WSD
| WFD_DEVINFO_PC_TDLS
| WFD_DEVINFO_HDCP_SUPPORT
, wfdie
+ wfdielen
);
769 /* WiFi Direct mode + WSD (WFD Service Discovery) */
770 put_unaligned_be16(pwfd_info
->wfd_device_type
| WFD_DEVINFO_WSD
| WFD_DEVINFO_HDCP_SUPPORT
, wfdie
+ wfdielen
);
775 if (pwdinfo
->wfd_tdls_enable
)
777 /* available for WFD session + TDLS mode + WSD (WFD Service Discovery) */
778 put_unaligned_be16(pwfd_info
->wfd_device_type
| WFD_DEVINFO_SESSION_AVAIL
| WFD_DEVINFO_WSD
| WFD_DEVINFO_PC_TDLS
| WFD_DEVINFO_HDCP_SUPPORT
, wfdie
+ wfdielen
);
782 /* available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery) */
783 put_unaligned_be16(pwfd_info
->wfd_device_type
| WFD_DEVINFO_SESSION_AVAIL
| WFD_DEVINFO_WSD
| WFD_DEVINFO_HDCP_SUPPORT
, wfdie
+ wfdielen
);
789 if (pwdinfo
->wfd_tdls_enable
)
791 /* available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery) */
792 put_unaligned_be16(pwfd_info
->wfd_device_type
|
793 WFD_DEVINFO_SESSION_AVAIL
|
795 WFD_DEVINFO_PC_TDLS
|
796 WFD_DEVINFO_HDCP_SUPPORT
,
802 /* available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery) */
803 put_unaligned_be16(pwfd_info
->wfd_device_type
|
804 WFD_DEVINFO_SESSION_AVAIL
|
806 WFD_DEVINFO_HDCP_SUPPORT
,
813 if (pwdinfo
->wfd_tdls_enable
)
815 put_unaligned_be16(pwfd_info
->wfd_device_type
|
817 WFD_DEVINFO_PC_TDLS
|
818 WFD_DEVINFO_HDCP_SUPPORT
,
823 put_unaligned_be16(pwfd_info
->wfd_device_type
|
825 WFD_DEVINFO_HDCP_SUPPORT
,
834 /* Session Management Control Port */
835 /* Default TCP port for RTSP messages is 554 */
836 put_unaligned_be16(pwfd_info
->rtsp_ctrlport
, wfdie
+ wfdielen
);
840 /* WFD Device Maximum Throughput */
841 /* 300Mbps is the maximum throughput */
842 put_unaligned_be16(300, wfdie
+ wfdielen
);
845 /* Associated BSSID ATTR */
847 wfdie
[ wfdielen
++ ] = WFD_ATTR_ASSOC_BSSID
;
850 /* Note: In the WFD specification, the size of length field is 2. */
851 put_unaligned_be16(0x0006, wfdie
+ wfdielen
);
855 /* Associated BSSID */
856 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == true)
858 memcpy(wfdie
+ wfdielen
, &pmlmepriv
->assoc_bssid
[ 0 ], ETH_ALEN
);
862 memset(wfdie
+ wfdielen
, 0x00, ETH_ALEN
);
865 wfdielen
+= ETH_ALEN
;
867 /* Coupled Sink Information ATTR */
869 wfdie
[ wfdielen
++ ] = WFD_ATTR_COUPLED_SINK_INFO
;
872 /* Note: In the WFD specification, the size of length field is 2. */
873 put_unaligned_be16(0x0007, wfdie
+ wfdielen
);
877 /* Coupled Sink Status bitmap */
878 /* Not coupled/available for Coupling */
879 wfdie
[ wfdielen
++ ] = 0;
881 wfdie
[ wfdielen
++ ] = 0;
882 wfdie
[ wfdielen
++ ] = 0;
883 wfdie
[ wfdielen
++ ] = 0;
884 wfdie
[ wfdielen
++ ] = 0;
885 wfdie
[ wfdielen
++ ] = 0;
886 wfdie
[ wfdielen
++ ] = 0;
888 if (rtw_p2p_chk_role(pwdinfo
, P2P_ROLE_GO
))
890 /* WFD Session Information ATTR */
892 wfdie
[ wfdielen
++ ] = WFD_ATTR_SESSION_INFO
;
895 /* Note: In the WFD specification, the size of length field is 2. */
896 put_unaligned_be16(0x0000, wfdie
+ wfdielen
);
899 /* Todo: to add the list of WFD device info descriptor in WFD group. */
903 pbuf
= rtw_set_ie23a(pbuf
, _VENDOR_SPECIFIC_IE_
, wfdielen
, (unsigned char *) wfdie
, &len
);
908 u32
build_assoc_req_wfd_ie(struct wifidirect_info
*pwdinfo
, u8
*pbuf
)
910 u8 wfdie
[ MAX_WFD_IE_LEN
] = { 0x00 };
911 u32 len
= 0, wfdielen
= 0;
912 struct rtw_adapter
*padapter
= NULL
;
913 struct mlme_priv
*pmlmepriv
= NULL
;
914 struct wifi_display_info
*pwfd_info
= NULL
;
917 if (rtw_p2p_chk_state(pwdinfo
, P2P_STATE_NONE
) || rtw_p2p_chk_state(pwdinfo
, P2P_STATE_IDLE
))
922 padapter
= pwdinfo
->padapter
;
923 pmlmepriv
= &padapter
->mlmepriv
;
924 pwfd_info
= padapter
->wdinfo
.wfd_info
;
927 wfdie
[ wfdielen
++ ] = 0x50;
928 wfdie
[ wfdielen
++ ] = 0x6F;
929 wfdie
[ wfdielen
++ ] = 0x9A;
930 wfdie
[ wfdielen
++ ] = 0x0A; /* WFA WFD v1.0 */
932 /* Commented by Albert 20110812 */
933 /* According to the WFD Specification, the probe request frame should contain 4 WFD attributes */
934 /* 1. WFD Device Information */
935 /* 2. Associated BSSID */
936 /* 3. Coupled Sink Information */
938 /* WFD Device Information ATTR */
940 wfdie
[ wfdielen
++ ] = WFD_ATTR_DEVICE_INFO
;
943 /* Note: In the WFD specification, the size of length field is 2. */
944 put_unaligned_be16(0x0006, wfdie
+ wfdielen
);
948 /* WFD device information */
949 /* WFD primary sink + available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery) */
950 put_unaligned_be16(pwfd_info
->wfd_device_type
|
951 WFD_DEVINFO_SESSION_AVAIL
|
952 WFD_DEVINFO_WSD
, wfdie
+ wfdielen
);
956 /* Session Management Control Port */
957 /* Default TCP port for RTSP messages is 554 */
958 put_unaligned_be16(pwfd_info
->rtsp_ctrlport
, wfdie
+ wfdielen
);
962 /* WFD Device Maximum Throughput */
963 /* 300Mbps is the maximum throughput */
964 put_unaligned_be16(300, wfdie
+ wfdielen
);
967 /* Associated BSSID ATTR */
969 wfdie
[ wfdielen
++ ] = WFD_ATTR_ASSOC_BSSID
;
972 /* Note: In the WFD specification, the size of length field is 2. */
973 put_unaligned_be16(0x0006, wfdie
+ wfdielen
);
977 /* Associated BSSID */
978 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == true)
980 memcpy(wfdie
+ wfdielen
, &pmlmepriv
->assoc_bssid
[ 0 ], ETH_ALEN
);
984 memset(wfdie
+ wfdielen
, 0x00, ETH_ALEN
);
987 wfdielen
+= ETH_ALEN
;
989 /* Coupled Sink Information ATTR */
991 wfdie
[ wfdielen
++ ] = WFD_ATTR_COUPLED_SINK_INFO
;
994 /* Note: In the WFD specification, the size of length field is 2. */
995 put_unaligned_be16(0x0007, wfdie
+ wfdielen
);
999 /* Coupled Sink Status bitmap */
1000 /* Not coupled/available for Coupling */
1001 wfdie
[ wfdielen
++ ] = 0;
1003 wfdie
[ wfdielen
++ ] = 0;
1004 wfdie
[ wfdielen
++ ] = 0;
1005 wfdie
[ wfdielen
++ ] = 0;
1006 wfdie
[ wfdielen
++ ] = 0;
1007 wfdie
[ wfdielen
++ ] = 0;
1008 wfdie
[ wfdielen
++ ] = 0;
1010 pbuf
= rtw_set_ie23a(pbuf
, _VENDOR_SPECIFIC_IE_
, wfdielen
, (unsigned char *) wfdie
, &len
);
1015 u32
build_assoc_resp_wfd_ie(struct wifidirect_info
*pwdinfo
, u8
*pbuf
)
1017 u8 wfdie
[ MAX_WFD_IE_LEN
] = { 0x00 };
1018 u32 len
= 0, wfdielen
= 0;
1019 struct rtw_adapter
*padapter
= pwdinfo
->padapter
;
1020 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1021 struct wifi_display_info
* pwfd_info
= padapter
->wdinfo
.wfd_info
;
1025 wfdie
[ wfdielen
++ ] = 0x50;
1026 wfdie
[ wfdielen
++ ] = 0x6F;
1027 wfdie
[ wfdielen
++ ] = 0x9A;
1028 wfdie
[ wfdielen
++ ] = 0x0A; /* WFA WFD v1.0 */
1030 /* Commented by Albert 20110812 */
1031 /* According to the WFD Specification, the probe request frame should contain 4 WFD attributes */
1032 /* 1. WFD Device Information */
1033 /* 2. Associated BSSID */
1034 /* 3. Coupled Sink Information */
1036 /* WFD Device Information ATTR */
1038 wfdie
[ wfdielen
++ ] = WFD_ATTR_DEVICE_INFO
;
1041 /* Note: In the WFD specification, the size of length field is 2. */
1042 put_unaligned_be16(0x0006, wfdie
+ wfdielen
);
1046 /* WFD device information */
1047 /* WFD primary sink + available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery) */
1048 put_unaligned_be16(pwfd_info
->wfd_device_type
|
1049 WFD_DEVINFO_SESSION_AVAIL
|
1050 WFD_DEVINFO_WSD
, wfdie
+ wfdielen
);
1054 /* Session Management Control Port */
1055 /* Default TCP port for RTSP messages is 554 */
1056 put_unaligned_be16(pwfd_info
->rtsp_ctrlport
, wfdie
+ wfdielen
);
1060 /* WFD Device Maximum Throughput */
1061 /* 300Mbps is the maximum throughput */
1062 put_unaligned_be16(300, wfdie
+ wfdielen
);
1065 /* Associated BSSID ATTR */
1067 wfdie
[ wfdielen
++ ] = WFD_ATTR_ASSOC_BSSID
;
1070 /* Note: In the WFD specification, the size of length field is 2. */
1071 put_unaligned_be16(0x0006, wfdie
+ wfdielen
);
1075 /* Associated BSSID */
1076 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == true)
1078 memcpy(wfdie
+ wfdielen
, &pmlmepriv
->assoc_bssid
[ 0 ], ETH_ALEN
);
1082 memset(wfdie
+ wfdielen
, 0x00, ETH_ALEN
);
1085 wfdielen
+= ETH_ALEN
;
1087 /* Coupled Sink Information ATTR */
1089 wfdie
[ wfdielen
++ ] = WFD_ATTR_COUPLED_SINK_INFO
;
1092 /* Note: In the WFD specification, the size of length field is 2. */
1093 put_unaligned_be16(0x0007, wfdie
+ wfdielen
);
1097 /* Coupled Sink Status bitmap */
1098 /* Not coupled/available for Coupling */
1099 wfdie
[ wfdielen
++ ] = 0;
1101 wfdie
[ wfdielen
++ ] = 0;
1102 wfdie
[ wfdielen
++ ] = 0;
1103 wfdie
[ wfdielen
++ ] = 0;
1104 wfdie
[ wfdielen
++ ] = 0;
1105 wfdie
[ wfdielen
++ ] = 0;
1106 wfdie
[ wfdielen
++ ] = 0;
1108 pbuf
= rtw_set_ie23a(pbuf
, _VENDOR_SPECIFIC_IE_
, wfdielen
, (unsigned char *) wfdie
, &len
);
1113 u32
build_nego_req_wfd_ie(struct wifidirect_info
*pwdinfo
, u8
*pbuf
)
1115 u8 wfdie
[ MAX_WFD_IE_LEN
] = { 0x00 };
1116 u32 len
= 0, wfdielen
= 0;
1117 struct rtw_adapter
*padapter
= pwdinfo
->padapter
;
1118 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1119 struct wifi_display_info
* pwfd_info
= padapter
->wdinfo
.wfd_info
;
1123 wfdie
[ wfdielen
++ ] = 0x50;
1124 wfdie
[ wfdielen
++ ] = 0x6F;
1125 wfdie
[ wfdielen
++ ] = 0x9A;
1126 wfdie
[ wfdielen
++ ] = 0x0A; /* WFA WFD v1.0 */
1128 /* Commented by Albert 20110825 */
1129 /* According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes */
1130 /* 1. WFD Device Information */
1131 /* 2. Associated BSSID (Optional) */
1132 /* 3. Local IP Adress (Optional) */
1134 /* WFD Device Information ATTR */
1136 wfdie
[ wfdielen
++ ] = WFD_ATTR_DEVICE_INFO
;
1139 /* Note: In the WFD specification, the size of length field is 2. */
1140 put_unaligned_be16(0x0006, wfdie
+ wfdielen
);
1144 /* WFD device information */
1145 /* WFD primary sink + WiFi Direct mode + WSD (WFD Service Discovery) + WFD Session Available */
1146 put_unaligned_be16(pwfd_info
->wfd_device_type
|
1147 WFD_DEVINFO_WSD
| WFD_DEVINFO_SESSION_AVAIL
,
1152 /* Session Management Control Port */
1153 /* Default TCP port for RTSP messages is 554 */
1154 put_unaligned_be16(pwfd_info
->rtsp_ctrlport
, wfdie
+ wfdielen
);
1158 /* WFD Device Maximum Throughput */
1159 /* 300Mbps is the maximum throughput */
1160 put_unaligned_be16(300, wfdie
+ wfdielen
);
1163 /* Associated BSSID ATTR */
1165 wfdie
[ wfdielen
++ ] = WFD_ATTR_ASSOC_BSSID
;
1168 /* Note: In the WFD specification, the size of length field is 2. */
1169 put_unaligned_be16(0x0006, wfdie
+ wfdielen
);
1173 /* Associated BSSID */
1174 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == true)
1176 memcpy(wfdie
+ wfdielen
, &pmlmepriv
->assoc_bssid
[ 0 ], ETH_ALEN
);
1180 memset(wfdie
+ wfdielen
, 0x00, ETH_ALEN
);
1183 wfdielen
+= ETH_ALEN
;
1185 /* Coupled Sink Information ATTR */
1187 wfdie
[ wfdielen
++ ] = WFD_ATTR_COUPLED_SINK_INFO
;
1190 /* Note: In the WFD specification, the size of length field is 2. */
1191 put_unaligned_be16(0x0007, wfdie
+ wfdielen
);
1195 /* Coupled Sink Status bitmap */
1196 /* Not coupled/available for Coupling */
1197 wfdie
[ wfdielen
++ ] = 0;
1199 wfdie
[ wfdielen
++ ] = 0;
1200 wfdie
[ wfdielen
++ ] = 0;
1201 wfdie
[ wfdielen
++ ] = 0;
1202 wfdie
[ wfdielen
++ ] = 0;
1203 wfdie
[ wfdielen
++ ] = 0;
1204 wfdie
[ wfdielen
++ ] = 0;
1206 pbuf
= rtw_set_ie23a(pbuf
, _VENDOR_SPECIFIC_IE_
, wfdielen
, (unsigned char *) wfdie
, &len
);
1211 u32
build_nego_resp_wfd_ie(struct wifidirect_info
*pwdinfo
, u8
*pbuf
)
1213 u8 wfdie
[ MAX_WFD_IE_LEN
] = { 0x00 };
1214 u32 len
= 0, wfdielen
= 0;
1215 struct rtw_adapter
*padapter
= pwdinfo
->padapter
;
1216 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1217 struct wifi_display_info
* pwfd_info
= padapter
->wdinfo
.wfd_info
;
1221 wfdie
[ wfdielen
++ ] = 0x50;
1222 wfdie
[ wfdielen
++ ] = 0x6F;
1223 wfdie
[ wfdielen
++ ] = 0x9A;
1224 wfdie
[ wfdielen
++ ] = 0x0A; /* WFA WFD v1.0 */
1226 /* Commented by Albert 20110825 */
1227 /* According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes */
1228 /* 1. WFD Device Information */
1229 /* 2. Associated BSSID (Optional) */
1230 /* 3. Local IP Adress (Optional) */
1232 /* WFD Device Information ATTR */
1234 wfdie
[ wfdielen
++ ] = WFD_ATTR_DEVICE_INFO
;
1237 /* Note: In the WFD specification, the size of length field is 2. */
1238 put_unaligned_be16(0x0006, wfdie
+ wfdielen
);
1242 /* WFD device information */
1243 /* WFD primary sink + WiFi Direct mode + WSD (WFD Service Discovery) + WFD Session Available */
1244 put_unaligned_be16(pwfd_info
->wfd_device_type
|
1245 WFD_DEVINFO_WSD
| WFD_DEVINFO_SESSION_AVAIL
,
1250 /* Session Management Control Port */
1251 /* Default TCP port for RTSP messages is 554 */
1252 put_unaligned_be16(pwfd_info
->rtsp_ctrlport
, wfdie
+ wfdielen
);
1256 /* WFD Device Maximum Throughput */
1257 /* 300Mbps is the maximum throughput */
1258 put_unaligned_be16(300, wfdie
+ wfdielen
);
1261 /* Associated BSSID ATTR */
1263 wfdie
[ wfdielen
++ ] = WFD_ATTR_ASSOC_BSSID
;
1266 /* Note: In the WFD specification, the size of length field is 2. */
1267 put_unaligned_be16(0x0006, wfdie
+ wfdielen
);
1271 /* Associated BSSID */
1272 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == true)
1274 memcpy(wfdie
+ wfdielen
, &pmlmepriv
->assoc_bssid
[ 0 ], ETH_ALEN
);
1278 memset(wfdie
+ wfdielen
, 0x00, ETH_ALEN
);
1281 wfdielen
+= ETH_ALEN
;
1283 /* Coupled Sink Information ATTR */
1285 wfdie
[ wfdielen
++ ] = WFD_ATTR_COUPLED_SINK_INFO
;
1288 /* Note: In the WFD specification, the size of length field is 2. */
1289 put_unaligned_be16(0x0007, wfdie
+ wfdielen
);
1293 /* Coupled Sink Status bitmap */
1294 /* Not coupled/available for Coupling */
1295 wfdie
[ wfdielen
++ ] = 0;
1297 wfdie
[ wfdielen
++ ] = 0;
1298 wfdie
[ wfdielen
++ ] = 0;
1299 wfdie
[ wfdielen
++ ] = 0;
1300 wfdie
[ wfdielen
++ ] = 0;
1301 wfdie
[ wfdielen
++ ] = 0;
1302 wfdie
[ wfdielen
++ ] = 0;
1304 pbuf
= rtw_set_ie23a(pbuf
, _VENDOR_SPECIFIC_IE_
, wfdielen
, (unsigned char *) wfdie
, &len
);
1309 u32
build_nego_confirm_wfd_ie(struct wifidirect_info
*pwdinfo
, u8
*pbuf
)
1311 u8 wfdie
[ MAX_WFD_IE_LEN
] = { 0x00 };
1312 u32 len
= 0, wfdielen
= 0;
1313 struct rtw_adapter
*padapter
= pwdinfo
->padapter
;
1314 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1315 struct wifi_display_info
* pwfd_info
= padapter
->wdinfo
.wfd_info
;
1319 wfdie
[ wfdielen
++ ] = 0x50;
1320 wfdie
[ wfdielen
++ ] = 0x6F;
1321 wfdie
[ wfdielen
++ ] = 0x9A;
1322 wfdie
[ wfdielen
++ ] = 0x0A; /* WFA WFD v1.0 */
1324 /* Commented by Albert 20110825 */
1325 /* According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes */
1326 /* 1. WFD Device Information */
1327 /* 2. Associated BSSID (Optional) */
1328 /* 3. Local IP Adress (Optional) */
1330 /* WFD Device Information ATTR */
1332 wfdie
[ wfdielen
++ ] = WFD_ATTR_DEVICE_INFO
;
1335 /* Note: In the WFD specification, the size of length field is 2. */
1336 put_unaligned_be16(0x0006, wfdie
+ wfdielen
);
1340 /* WFD device information */
1341 /* WFD primary sink + WiFi Direct mode + WSD (WFD Service Discovery) + WFD Session Available */
1342 put_unaligned_be16(pwfd_info
->wfd_device_type
| WFD_DEVINFO_WSD
|
1343 WFD_DEVINFO_SESSION_AVAIL
, wfdie
+ wfdielen
);
1347 /* Session Management Control Port */
1348 /* Default TCP port for RTSP messages is 554 */
1349 put_unaligned_be16(pwfd_info
->rtsp_ctrlport
, wfdie
+ wfdielen
);
1353 /* WFD Device Maximum Throughput */
1354 /* 300Mbps is the maximum throughput */
1355 put_unaligned_be16(300, wfdie
+ wfdielen
);
1358 /* Associated BSSID ATTR */
1360 wfdie
[ wfdielen
++ ] = WFD_ATTR_ASSOC_BSSID
;
1363 /* Note: In the WFD specification, the size of length field is 2. */
1364 put_unaligned_be16(0x0006, wfdie
+ wfdielen
);
1368 /* Associated BSSID */
1369 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == true)
1371 memcpy(wfdie
+ wfdielen
, &pmlmepriv
->assoc_bssid
[ 0 ], ETH_ALEN
);
1375 memset(wfdie
+ wfdielen
, 0x00, ETH_ALEN
);
1378 wfdielen
+= ETH_ALEN
;
1380 /* Coupled Sink Information ATTR */
1382 wfdie
[ wfdielen
++ ] = WFD_ATTR_COUPLED_SINK_INFO
;
1385 /* Note: In the WFD specification, the size of length field is 2. */
1386 put_unaligned_be16(0x0007, wfdie
+ wfdielen
);
1390 /* Coupled Sink Status bitmap */
1391 /* Not coupled/available for Coupling */
1392 wfdie
[ wfdielen
++ ] = 0;
1394 wfdie
[ wfdielen
++ ] = 0;
1395 wfdie
[ wfdielen
++ ] = 0;
1396 wfdie
[ wfdielen
++ ] = 0;
1397 wfdie
[ wfdielen
++ ] = 0;
1398 wfdie
[ wfdielen
++ ] = 0;
1399 wfdie
[ wfdielen
++ ] = 0;
1401 pbuf
= rtw_set_ie23a(pbuf
, _VENDOR_SPECIFIC_IE_
, wfdielen
, (unsigned char *) wfdie
, &len
);
1406 u32
build_invitation_req_wfd_ie(struct wifidirect_info
*pwdinfo
, u8
*pbuf
)
1408 u8 wfdie
[ MAX_WFD_IE_LEN
] = { 0x00 };
1409 u32 len
= 0, wfdielen
= 0;
1410 struct rtw_adapter
*padapter
= pwdinfo
->padapter
;
1411 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1412 struct wifi_display_info
* pwfd_info
= padapter
->wdinfo
.wfd_info
;
1416 wfdie
[ wfdielen
++ ] = 0x50;
1417 wfdie
[ wfdielen
++ ] = 0x6F;
1418 wfdie
[ wfdielen
++ ] = 0x9A;
1419 wfdie
[ wfdielen
++ ] = 0x0A; /* WFA WFD v1.0 */
1421 /* Commented by Albert 20110825 */
1422 /* According to the WFD Specification, the provision discovery request frame should contain 3 WFD attributes */
1423 /* 1. WFD Device Information */
1424 /* 2. Associated BSSID (Optional) */
1425 /* 3. Local IP Adress (Optional) */
1427 /* WFD Device Information ATTR */
1429 wfdie
[ wfdielen
++ ] = WFD_ATTR_DEVICE_INFO
;
1432 /* Note: In the WFD specification, the size of length field is 2. */
1433 put_unaligned_be16(0x0006, wfdie
+ wfdielen
);
1437 /* WFD device information */
1438 /* WFD primary sink + available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery) */
1439 put_unaligned_be16(pwfd_info
->wfd_device_type
|
1440 WFD_DEVINFO_SESSION_AVAIL
| WFD_DEVINFO_WSD
,
1445 /* Session Management Control Port */
1446 /* Default TCP port for RTSP messages is 554 */
1447 put_unaligned_be16(pwfd_info
->rtsp_ctrlport
, wfdie
+ wfdielen
);
1451 /* WFD Device Maximum Throughput */
1452 /* 300Mbps is the maximum throughput */
1453 put_unaligned_be16(300, wfdie
+ wfdielen
);
1456 /* Associated BSSID ATTR */
1458 wfdie
[ wfdielen
++ ] = WFD_ATTR_ASSOC_BSSID
;
1461 /* Note: In the WFD specification, the size of length field is 2. */
1462 put_unaligned_be16(0x0006, wfdie
+ wfdielen
);
1466 /* Associated BSSID */
1467 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == true)
1469 memcpy(wfdie
+ wfdielen
, &pmlmepriv
->assoc_bssid
[ 0 ], ETH_ALEN
);
1473 memset(wfdie
+ wfdielen
, 0x00, ETH_ALEN
);
1476 wfdielen
+= ETH_ALEN
;
1478 /* Coupled Sink Information ATTR */
1480 wfdie
[ wfdielen
++ ] = WFD_ATTR_COUPLED_SINK_INFO
;
1483 /* Note: In the WFD specification, the size of length field is 2. */
1484 put_unaligned_be16(0x0007, wfdie
+ wfdielen
);
1488 /* Coupled Sink Status bitmap */
1489 /* Not coupled/available for Coupling */
1490 wfdie
[ wfdielen
++ ] = 0;
1492 wfdie
[ wfdielen
++ ] = 0;
1493 wfdie
[ wfdielen
++ ] = 0;
1494 wfdie
[ wfdielen
++ ] = 0;
1495 wfdie
[ wfdielen
++ ] = 0;
1496 wfdie
[ wfdielen
++ ] = 0;
1497 wfdie
[ wfdielen
++ ] = 0;
1499 if (P2P_ROLE_GO
== pwdinfo
->role
)
1501 /* WFD Session Information ATTR */
1503 wfdie
[ wfdielen
++ ] = WFD_ATTR_SESSION_INFO
;
1506 /* Note: In the WFD specification, the size of length field is 2. */
1507 put_unaligned_be16(0x0000, wfdie
+ wfdielen
);
1510 /* Todo: to add the list of WFD device info descriptor in WFD group. */
1514 pbuf
= rtw_set_ie23a(pbuf
, _VENDOR_SPECIFIC_IE_
, wfdielen
, (unsigned char *) wfdie
, &len
);
1519 u32
build_invitation_resp_wfd_ie(struct wifidirect_info
*pwdinfo
, u8
*pbuf
)
1521 u8 wfdie
[ MAX_WFD_IE_LEN
] = { 0x00 };
1522 u32 len
= 0, wfdielen
= 0;
1523 struct rtw_adapter
*padapter
= pwdinfo
->padapter
;
1524 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1525 struct wifi_display_info
* pwfd_info
= padapter
->wdinfo
.wfd_info
;
1529 wfdie
[ wfdielen
++ ] = 0x50;
1530 wfdie
[ wfdielen
++ ] = 0x6F;
1531 wfdie
[ wfdielen
++ ] = 0x9A;
1532 wfdie
[ wfdielen
++ ] = 0x0A; /* WFA WFD v1.0 */
1534 /* Commented by Albert 20110825 */
1535 /* According to the WFD Specification, the provision discovery request frame should contain 3 WFD attributes */
1536 /* 1. WFD Device Information */
1537 /* 2. Associated BSSID (Optional) */
1538 /* 3. Local IP Adress (Optional) */
1540 /* WFD Device Information ATTR */
1542 wfdie
[ wfdielen
++ ] = WFD_ATTR_DEVICE_INFO
;
1545 /* Note: In the WFD specification, the size of length field is 2. */
1546 put_unaligned_be16(0x0006, wfdie
+ wfdielen
);
1550 /* WFD device information */
1551 /* WFD primary sink + available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery) */
1552 put_unaligned_be16(pwfd_info
->wfd_device_type
|
1553 WFD_DEVINFO_SESSION_AVAIL
| WFD_DEVINFO_WSD
,
1558 /* Session Management Control Port */
1559 /* Default TCP port for RTSP messages is 554 */
1560 put_unaligned_be16(pwfd_info
->rtsp_ctrlport
, wfdie
+ wfdielen
);
1564 /* WFD Device Maximum Throughput */
1565 /* 300Mbps is the maximum throughput */
1566 put_unaligned_be16(300, wfdie
+ wfdielen
);
1569 /* Associated BSSID ATTR */
1571 wfdie
[ wfdielen
++ ] = WFD_ATTR_ASSOC_BSSID
;
1574 /* Note: In the WFD specification, the size of length field is 2. */
1575 put_unaligned_be16(0x0006, wfdie
+ wfdielen
);
1579 /* Associated BSSID */
1580 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == true)
1582 memcpy(wfdie
+ wfdielen
, &pmlmepriv
->assoc_bssid
[ 0 ], ETH_ALEN
);
1586 memset(wfdie
+ wfdielen
, 0x00, ETH_ALEN
);
1589 wfdielen
+= ETH_ALEN
;
1591 /* Coupled Sink Information ATTR */
1593 wfdie
[ wfdielen
++ ] = WFD_ATTR_COUPLED_SINK_INFO
;
1596 /* Note: In the WFD specification, the size of length field is 2. */
1597 put_unaligned_be16(0x0007, wfdie
+ wfdielen
);
1601 /* Coupled Sink Status bitmap */
1602 /* Not coupled/available for Coupling */
1603 wfdie
[ wfdielen
++ ] = 0;
1605 wfdie
[ wfdielen
++ ] = 0;
1606 wfdie
[ wfdielen
++ ] = 0;
1607 wfdie
[ wfdielen
++ ] = 0;
1608 wfdie
[ wfdielen
++ ] = 0;
1609 wfdie
[ wfdielen
++ ] = 0;
1610 wfdie
[ wfdielen
++ ] = 0;
1612 if (P2P_ROLE_GO
== pwdinfo
->role
)
1614 /* WFD Session Information ATTR */
1616 wfdie
[ wfdielen
++ ] = WFD_ATTR_SESSION_INFO
;
1619 /* Note: In the WFD specification, the size of length field is 2. */
1620 put_unaligned_be16(0x0000, wfdie
+ wfdielen
);
1623 /* Todo: to add the list of WFD device info descriptor in WFD group. */
1627 pbuf
= rtw_set_ie23a(pbuf
, _VENDOR_SPECIFIC_IE_
, wfdielen
, (unsigned char *) wfdie
, &len
);
1632 u32
build_provdisc_req_wfd_ie(struct wifidirect_info
*pwdinfo
, u8
*pbuf
)
1634 u8 wfdie
[ MAX_WFD_IE_LEN
] = { 0x00 };
1635 u32 len
= 0, wfdielen
= 0;
1636 struct rtw_adapter
*padapter
= pwdinfo
->padapter
;
1637 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1638 struct wifi_display_info
* pwfd_info
= padapter
->wdinfo
.wfd_info
;
1642 wfdie
[ wfdielen
++ ] = 0x50;
1643 wfdie
[ wfdielen
++ ] = 0x6F;
1644 wfdie
[ wfdielen
++ ] = 0x9A;
1645 wfdie
[ wfdielen
++ ] = 0x0A; /* WFA WFD v1.0 */
1647 /* Commented by Albert 20110825 */
1648 /* According to the WFD Specification, the provision discovery request frame should contain 3 WFD attributes */
1649 /* 1. WFD Device Information */
1650 /* 2. Associated BSSID (Optional) */
1651 /* 3. Local IP Adress (Optional) */
1653 /* WFD Device Information ATTR */
1655 wfdie
[ wfdielen
++ ] = WFD_ATTR_DEVICE_INFO
;
1658 /* Note: In the WFD specification, the size of length field is 2. */
1659 put_unaligned_be16(0x0006, wfdie
+ wfdielen
);
1663 /* WFD device information */
1664 /* WFD primary sink + available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery) */
1665 put_unaligned_be16(pwfd_info
->wfd_device_type
|
1666 WFD_DEVINFO_SESSION_AVAIL
| WFD_DEVINFO_WSD
,
1671 /* Session Management Control Port */
1672 /* Default TCP port for RTSP messages is 554 */
1673 put_unaligned_be16(pwfd_info
->rtsp_ctrlport
, wfdie
+ wfdielen
);
1677 /* WFD Device Maximum Throughput */
1678 /* 300Mbps is the maximum throughput */
1679 put_unaligned_be16(300, wfdie
+ wfdielen
);
1682 /* Associated BSSID ATTR */
1684 wfdie
[ wfdielen
++ ] = WFD_ATTR_ASSOC_BSSID
;
1687 /* Note: In the WFD specification, the size of length field is 2. */
1688 put_unaligned_be16(0x0006, wfdie
+ wfdielen
);
1692 /* Associated BSSID */
1693 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == true)
1695 memcpy(wfdie
+ wfdielen
, &pmlmepriv
->assoc_bssid
[ 0 ], ETH_ALEN
);
1699 memset(wfdie
+ wfdielen
, 0x00, ETH_ALEN
);
1702 wfdielen
+= ETH_ALEN
;
1704 /* Coupled Sink Information ATTR */
1706 wfdie
[ wfdielen
++ ] = WFD_ATTR_COUPLED_SINK_INFO
;
1709 /* Note: In the WFD specification, the size of length field is 2. */
1710 put_unaligned_be16(0x0007, wfdie
+ wfdielen
);
1714 /* Coupled Sink Status bitmap */
1715 /* Not coupled/available for Coupling */
1716 wfdie
[ wfdielen
++ ] = 0;
1718 wfdie
[ wfdielen
++ ] = 0;
1719 wfdie
[ wfdielen
++ ] = 0;
1720 wfdie
[ wfdielen
++ ] = 0;
1721 wfdie
[ wfdielen
++ ] = 0;
1722 wfdie
[ wfdielen
++ ] = 0;
1723 wfdie
[ wfdielen
++ ] = 0;
1725 pbuf
= rtw_set_ie23a(pbuf
, _VENDOR_SPECIFIC_IE_
, wfdielen
, (unsigned char *) wfdie
, &len
);
1730 u32
build_provdisc_resp_wfd_ie(struct wifidirect_info
*pwdinfo
, u8
*pbuf
)
1732 u8 wfdie
[ MAX_WFD_IE_LEN
] = { 0x00 };
1733 u32 len
= 0, wfdielen
= 0;
1734 struct rtw_adapter
*padapter
= pwdinfo
->padapter
;
1735 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1736 struct wifi_display_info
* pwfd_info
= padapter
->wdinfo
.wfd_info
;
1740 wfdie
[ wfdielen
++ ] = 0x50;
1741 wfdie
[ wfdielen
++ ] = 0x6F;
1742 wfdie
[ wfdielen
++ ] = 0x9A;
1743 wfdie
[ wfdielen
++ ] = 0x0A; /* WFA WFD v1.0 */
1745 /* Commented by Albert 20110825 */
1746 /* According to the WFD Specification, the provision discovery response frame should contain 3 WFD attributes */
1747 /* 1. WFD Device Information */
1748 /* 2. Associated BSSID (Optional) */
1749 /* 3. Local IP Adress (Optional) */
1751 /* WFD Device Information ATTR */
1753 wfdie
[ wfdielen
++ ] = WFD_ATTR_DEVICE_INFO
;
1756 /* Note: In the WFD specification, the size of length field is 2. */
1757 put_unaligned_be16(0x0006, wfdie
+ wfdielen
);
1761 /* WFD device information */
1762 /* WFD primary sink + available for WFD session + WiFi Direct mode + WSD (WFD Service Discovery) */
1763 put_unaligned_be16(pwfd_info
->wfd_device_type
|
1764 WFD_DEVINFO_SESSION_AVAIL
| WFD_DEVINFO_WSD
,
1769 /* Session Management Control Port */
1770 /* Default TCP port for RTSP messages is 554 */
1771 put_unaligned_be16(pwfd_info
->rtsp_ctrlport
, wfdie
+ wfdielen
);
1775 /* WFD Device Maximum Throughput */
1776 /* 300Mbps is the maximum throughput */
1777 put_unaligned_be16(300, wfdie
+ wfdielen
);
1780 /* Associated BSSID ATTR */
1782 wfdie
[ wfdielen
++ ] = WFD_ATTR_ASSOC_BSSID
;
1785 /* Note: In the WFD specification, the size of length field is 2. */
1786 put_unaligned_be16(0x0006, wfdie
+ wfdielen
);
1790 /* Associated BSSID */
1791 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == true)
1793 memcpy(wfdie
+ wfdielen
, &pmlmepriv
->assoc_bssid
[ 0 ], ETH_ALEN
);
1797 memset(wfdie
+ wfdielen
, 0x00, ETH_ALEN
);
1800 wfdielen
+= ETH_ALEN
;
1802 /* Coupled Sink Information ATTR */
1804 wfdie
[ wfdielen
++ ] = WFD_ATTR_COUPLED_SINK_INFO
;
1807 /* Note: In the WFD specification, the size of length field is 2. */
1808 put_unaligned_be16(0x0007, wfdie
+ wfdielen
);
1812 /* Coupled Sink Status bitmap */
1813 /* Not coupled/available for Coupling */
1814 wfdie
[ wfdielen
++ ] = 0;
1816 wfdie
[ wfdielen
++ ] = 0;
1817 wfdie
[ wfdielen
++ ] = 0;
1818 wfdie
[ wfdielen
++ ] = 0;
1819 wfdie
[ wfdielen
++ ] = 0;
1820 wfdie
[ wfdielen
++ ] = 0;
1821 wfdie
[ wfdielen
++ ] = 0;
1823 pbuf
= rtw_set_ie23a(pbuf
, _VENDOR_SPECIFIC_IE_
, wfdielen
, (unsigned char *) wfdie
, &len
);
1828 #endif /* CONFIG_8723AU_P2P */
1830 u32
build_probe_resp_p2p_ie23a(struct wifidirect_info
*pwdinfo
, u8
*pbuf
)
1832 u8 p2pie
[ MAX_P2P_IE_LEN
] = { 0x00 };
1833 u32 len
= 0, p2pielen
= 0;
1837 p2pie
[ p2pielen
++ ] = 0x50;
1838 p2pie
[ p2pielen
++ ] = 0x6F;
1839 p2pie
[ p2pielen
++ ] = 0x9A;
1840 p2pie
[ p2pielen
++ ] = 0x09; /* WFA P2P v1.0 */
1842 /* Commented by Albert 20100907 */
1843 /* According to the P2P Specification, the probe response frame should contain 5 P2P attributes */
1844 /* 1. P2P Capability */
1845 /* 2. Extended Listen Timing */
1846 /* 3. Notice of Absence (NOA) (Only GO needs this) */
1847 /* 4. Device Info */
1848 /* 5. Group Info (Only GO need this) */
1850 /* P2P Capability ATTR */
1852 p2pie
[ p2pielen
++ ] = P2P_ATTR_CAPABILITY
;
1855 /* u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002); */
1856 put_unaligned_le16(0x0002, p2pie
+ p2pielen
);
1860 /* Device Capability Bitmap, 1 byte */
1861 p2pie
[ p2pielen
++ ] = DMP_P2P_DEVCAP_SUPPORT
;
1863 /* Group Capability Bitmap, 1 byte */
1864 if (rtw_p2p_chk_role(pwdinfo
, P2P_ROLE_GO
))
1866 p2pie
[ p2pielen
] = (P2P_GRPCAP_GO
| P2P_GRPCAP_INTRABSS
);
1868 if (rtw_p2p_chk_state(pwdinfo
, P2P_STATE_PROVISIONING_ING
))
1869 p2pie
[ p2pielen
] |= P2P_GRPCAP_GROUP_FORMATION
;
1873 else if (rtw_p2p_chk_role(pwdinfo
, P2P_ROLE_DEVICE
))
1875 /* Group Capability Bitmap, 1 byte */
1876 if (pwdinfo
->persistent_supported
)
1877 p2pie
[ p2pielen
++ ] = P2P_GRPCAP_PERSISTENT_GROUP
| DMP_P2P_GRPCAP_SUPPORT
;
1879 p2pie
[ p2pielen
++ ] = DMP_P2P_GRPCAP_SUPPORT
;
1882 /* Extended Listen Timing ATTR */
1884 p2pie
[ p2pielen
++ ] = P2P_ATTR_EX_LISTEN_TIMING
;
1887 /* u16*) (p2pie + p2pielen) = cpu_to_le16(0x0004); */
1888 put_unaligned_le16(0x0004, p2pie
+ p2pielen
);
1892 /* Availability Period */
1893 /* u16*) (p2pie + p2pielen) = cpu_to_le16(0xFFFF); */
1894 put_unaligned_le16(0xFFFF, p2pie
+ p2pielen
);
1897 /* Availability Interval */
1898 /* u16*) (p2pie + p2pielen) = cpu_to_le16(0xFFFF); */
1899 put_unaligned_le16(0xFFFF, p2pie
+ p2pielen
);
1902 /* Notice of Absence ATTR */
1906 if (rtw_p2p_chk_role(pwdinfo
, P2P_ROLE_GO
))
1908 /* go_add_noa_attr(pwdinfo); */
1911 /* Device Info ATTR */
1913 p2pie
[ p2pielen
++ ] = P2P_ATTR_DEVICE_INFO
;
1916 /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
1917 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
1918 /* u16*) (p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len); */
1919 put_unaligned_le16(21 + pwdinfo
->device_name_len
, p2pie
+ p2pielen
);
1923 /* P2P Device Address */
1924 memcpy(p2pie
+ p2pielen
, pwdinfo
->device_addr
, ETH_ALEN
);
1925 p2pielen
+= ETH_ALEN
;
1928 /* This field should be big endian. Noted by P2P specification. */
1929 /* u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm); */
1930 put_unaligned_be16(pwdinfo
->supported_wps_cm
, p2pie
+ p2pielen
);
1933 /* Primary Device Type */
1935 /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA); */
1936 put_unaligned_be16(WPS_PDT_CID_MULIT_MEDIA
, p2pie
+ p2pielen
);
1940 /* u32*) (p2pie + p2pielen) = cpu_to_be32(WPSOUI); */
1941 put_unaligned_be32(WPSOUI
, p2pie
+ p2pielen
);
1944 /* Sub Category ID */
1945 /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER); */
1946 put_unaligned_be16(WPS_PDT_SCID_MEDIA_SERVER
, p2pie
+ p2pielen
);
1949 /* Number of Secondary Device Types */
1950 p2pie
[ p2pielen
++ ] = 0x00; /* No Secondary Device Type List */
1954 /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); */
1955 put_unaligned_be16(WPS_ATTR_DEVICE_NAME
, p2pie
+ p2pielen
);
1959 /* u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len); */
1960 put_unaligned_be16(pwdinfo
->device_name_len
, p2pie
+ p2pielen
);
1964 memcpy(p2pie
+ p2pielen
, pwdinfo
->device_name
, pwdinfo
->device_name_len
);
1965 p2pielen
+= pwdinfo
->device_name_len
;
1967 /* Group Info ATTR */
1971 if (rtw_p2p_chk_role(pwdinfo
, P2P_ROLE_GO
))
1973 p2pielen
+= go_add_group_info_attr(pwdinfo
, p2pie
+ p2pielen
);
1976 pbuf
= rtw_set_ie23a(pbuf
, _VENDOR_SPECIFIC_IE_
, p2pielen
, (unsigned char *) p2pie
, &len
);
1981 u32
build_prov_disc_request_p2p_ie23a(struct wifidirect_info
*pwdinfo
, u8
*pbuf
, u8
* pssid
, u8 ussidlen
, u8
* pdev_raddr
)
1983 u8 p2pie
[ MAX_P2P_IE_LEN
] = { 0x00 };
1984 u32 len
= 0, p2pielen
= 0;
1988 p2pie
[ p2pielen
++ ] = 0x50;
1989 p2pie
[ p2pielen
++ ] = 0x6F;
1990 p2pie
[ p2pielen
++ ] = 0x9A;
1991 p2pie
[ p2pielen
++ ] = 0x09; /* WFA P2P v1.0 */
1993 /* Commented by Albert 20110301 */
1994 /* According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes */
1995 /* 1. P2P Capability */
1996 /* 2. Device Info */
1997 /* 3. Group ID (When joining an operating P2P Group) */
1999 /* P2P Capability ATTR */
2001 p2pie
[ p2pielen
++ ] = P2P_ATTR_CAPABILITY
;
2004 /* u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002); */
2005 put_unaligned_le16(0x0002, p2pie
+ p2pielen
);
2009 /* Device Capability Bitmap, 1 byte */
2010 p2pie
[ p2pielen
++ ] = DMP_P2P_DEVCAP_SUPPORT
;
2012 /* Group Capability Bitmap, 1 byte */
2013 if (pwdinfo
->persistent_supported
)
2014 p2pie
[ p2pielen
++ ] = P2P_GRPCAP_PERSISTENT_GROUP
| DMP_P2P_GRPCAP_SUPPORT
;
2016 p2pie
[ p2pielen
++ ] = DMP_P2P_GRPCAP_SUPPORT
;
2018 /* Device Info ATTR */
2020 p2pie
[ p2pielen
++ ] = P2P_ATTR_DEVICE_INFO
;
2023 /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
2024 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
2025 /* u16*) (p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len); */
2026 put_unaligned_le16(21 + pwdinfo
->device_name_len
, p2pie
+ p2pielen
);
2030 /* P2P Device Address */
2031 memcpy(p2pie
+ p2pielen
, pwdinfo
->device_addr
, ETH_ALEN
);
2032 p2pielen
+= ETH_ALEN
;
2035 /* This field should be big endian. Noted by P2P specification. */
2036 if (pwdinfo
->ui_got_wps_info
== P2P_GOT_WPSINFO_PBC
)
2038 /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_PBC); */
2039 put_unaligned_be16(WPS_CONFIG_METHOD_PBC
, p2pie
+ p2pielen
);
2043 /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY); */
2044 put_unaligned_be16(WPS_CONFIG_METHOD_DISPLAY
, p2pie
+ p2pielen
);
2049 /* Primary Device Type */
2051 /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA); */
2052 put_unaligned_be16(WPS_PDT_CID_MULIT_MEDIA
, p2pie
+ p2pielen
);
2056 /* u32*) (p2pie + p2pielen) = cpu_to_be32(WPSOUI); */
2057 put_unaligned_be32(WPSOUI
, p2pie
+ p2pielen
);
2060 /* Sub Category ID */
2061 /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER); */
2062 put_unaligned_be16(WPS_PDT_SCID_MEDIA_SERVER
, p2pie
+ p2pielen
);
2065 /* Number of Secondary Device Types */
2066 p2pie
[ p2pielen
++ ] = 0x00; /* No Secondary Device Type List */
2070 /* u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME); */
2071 put_unaligned_be16(WPS_ATTR_DEVICE_NAME
, p2pie
+ p2pielen
);
2075 /* u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len); */
2076 put_unaligned_be16(pwdinfo
->device_name_len
, p2pie
+ p2pielen
);
2080 memcpy(p2pie
+ p2pielen
, pwdinfo
->device_name
, pwdinfo
->device_name_len
);
2081 p2pielen
+= pwdinfo
->device_name_len
;
2083 if (rtw_p2p_chk_role(pwdinfo
, P2P_ROLE_CLIENT
))
2085 /* Added by Albert 2011/05/19 */
2086 /* In this case, the pdev_raddr is the device address of the group owner. */
2088 /* P2P Group ID ATTR */
2090 p2pie
[ p2pielen
++ ] = P2P_ATTR_GROUP_ID
;
2093 /* u16*) (p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + ussidlen); */
2094 put_unaligned_le16(ETH_ALEN
+ ussidlen
, p2pie
+ p2pielen
);
2098 memcpy(p2pie
+ p2pielen
, pdev_raddr
, ETH_ALEN
);
2099 p2pielen
+= ETH_ALEN
;
2101 memcpy(p2pie
+ p2pielen
, pssid
, ussidlen
);
2102 p2pielen
+= ussidlen
;
2106 pbuf
= rtw_set_ie23a(pbuf
, _VENDOR_SPECIFIC_IE_
, p2pielen
, (unsigned char *) p2pie
, &len
);
2111 u32
build_assoc_resp_p2p_ie23a(struct wifidirect_info
*pwdinfo
, u8
*pbuf
, u8 status_code
)
2113 u8 p2pie
[ MAX_P2P_IE_LEN
] = { 0x00 };
2114 u32 len
= 0, p2pielen
= 0;
2118 p2pie
[ p2pielen
++ ] = 0x50;
2119 p2pie
[ p2pielen
++ ] = 0x6F;
2120 p2pie
[ p2pielen
++ ] = 0x9A;
2121 p2pie
[ p2pielen
++ ] = 0x09; /* WFA P2P v1.0 */
2123 /* According to the P2P Specification, the Association response frame should contain 2 P2P attributes */
2125 /* 2. Extended Listen Timing (optional) */
2128 p2pielen
+= rtw_set_p2p_attr_content23a(&p2pie
[p2pielen
], P2P_ATTR_STATUS
, 1, &status_code
);
2130 /* Extended Listen Timing ATTR */
2135 pbuf
= rtw_set_ie23a(pbuf
, _VENDOR_SPECIFIC_IE_
, p2pielen
, (unsigned char *) p2pie
, &len
);
2140 u32
build_deauth_p2p_ie23a(struct wifidirect_info
*pwdinfo
, u8
*pbuf
)
2147 u32
process_probe_req_p2p_ie23a(struct wifidirect_info
*pwdinfo
, u8
*pframe
, uint len
)
2153 int ssid_len
= 0, rate_cnt
= 0;
2155 p
= rtw_get_ie23a(pframe
+ sizeof(struct ieee80211_hdr_3addr
) + _PROBEREQ_IE_OFFSET_
, _SUPPORTEDRATES_IE_
, (int *)&rate_cnt
,
2156 len
- sizeof(struct ieee80211_hdr_3addr
) - _PROBEREQ_IE_OFFSET_
);
2162 for (i
= 0; i
< rate_cnt
; i
++)
2164 if (((*(p
+ 2 + i
) & 0xff) != 0x02) &&
2165 ((*(p
+ 2 + i
) & 0xff) != 0x04) &&
2166 ((*(p
+ 2 + i
) & 0xff) != 0x0B) &&
2167 ((*(p
+ 2 + i
) & 0xff) != 0x16))
2175 /* There is no OFDM rate included in SupportedRates IE of this probe request frame */
2176 /* The driver should response this probe request. */
2182 /* rate_cnt > 4 means the SupportRates IE contains the OFDM rate because the count of CCK rates are 4. */
2183 /* We should proceed the following check for this probe request. */
2186 /* Added comments by Albert 20100906 */
2187 /* There are several items we should check here. */
2188 /* 1. This probe request frame must contain the P2P IE. (Done) */
2189 /* 2. This probe request frame must contain the wildcard SSID. (Done) */
2190 /* 3. Wildcard BSSID. (Todo) */
2191 /* 4. Destination Address. (Done in mgt_dispatcher23a function) */
2192 /* 5. Requested Device Type in WSC IE. (Todo) */
2193 /* 6. Device ID attribute in P2P IE. (Todo) */
2195 p
= rtw_get_ie23a(pframe
+ sizeof(struct ieee80211_hdr_3addr
) + _PROBEREQ_IE_OFFSET_
, _SSID_IE_
, (int *)&ssid_len
,
2196 len
- sizeof(struct ieee80211_hdr_3addr
) - _PROBEREQ_IE_OFFSET_
);
2198 ssid_len
&= 0xff; /* Just last 1 byte is valid for ssid len of the probe request */
2199 if (rtw_p2p_chk_role(pwdinfo
, P2P_ROLE_DEVICE
) || rtw_p2p_chk_role(pwdinfo
, P2P_ROLE_GO
))
2201 if ((p2pie
= rtw_get_p2p_ie23a(pframe
+ sizeof(struct ieee80211_hdr_3addr
) + _PROBEREQ_IE_OFFSET_
, len
- sizeof(struct ieee80211_hdr_3addr
) - _PROBEREQ_IE_OFFSET_
, NULL
, &p2pielen
)))
2203 if ((p
) && !memcmp((void *)(p
+2), (void *)pwdinfo
->p2p_wildcard_ssid
, 7))
2206 /* Check Requested Device Type attributes in WSC IE. */
2207 /* Check Device ID attribute in P2P IE */
2211 else if ((p
!= NULL
) && (ssid_len
== 0))
2218 /* non -p2p device */
2226 u32
process_assoc_req_p2p_ie23a(struct wifidirect_info
*pwdinfo
, u8
*pframe
, uint len
, struct sta_info
*psta
)
2228 u8 status_code
= P2P_STATUS_SUCCESS
;
2229 u8
*pbuf
, *pattr_content
= NULL
;
2230 u32 attr_contentlen
= 0;
2232 unsigned short ie_offset
;
2237 struct ieee80211_hdr
*hdr
= (struct ieee80211_hdr
*)pframe
;
2239 if (!rtw_p2p_chk_role(pwdinfo
, P2P_ROLE_GO
))
2240 return P2P_STATUS_FAIL_REQUEST_UNABLE
;
2242 if (ieee80211_is_assoc_req(hdr
->frame_control
))
2243 ie_offset
= _ASOCREQ_IE_OFFSET_
;
2244 else /* WIFI_REASSOCREQ */
2245 ie_offset
= _REASOCREQ_IE_OFFSET_
;
2247 ies
= pframe
+ sizeof(struct ieee80211_hdr_3addr
) + ie_offset
;
2248 ies_len
= len
- sizeof(struct ieee80211_hdr_3addr
) - ie_offset
;
2250 p2p_ie
= rtw_get_p2p_ie23a(ies
, ies_len
, NULL
, &p2p_ielen
);
2254 DBG_8723A("[%s] P2P IE not Found!!\n", __func__
);
2255 status_code
= P2P_STATUS_FAIL_INVALID_PARAM
;
2259 DBG_8723A("[%s] P2P IE Found!!\n", __func__
);
2264 /* Check P2P Capability ATTR */
2265 if (rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_CAPABILITY
, (u8
*)&cap_attr
, (uint
*) &attr_contentlen
))
2267 DBG_8723A("[%s] Got P2P Capability Attr!!\n", __func__
);
2268 cap_attr
= le16_to_cpu(cap_attr
);
2269 psta
->dev_cap
= cap_attr
&0xff;
2272 /* Check Extended Listen Timing ATTR */
2274 /* Check P2P Device Info ATTR */
2275 if (rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_DEVICE_INFO
, NULL
, (uint
*)&attr_contentlen
))
2277 DBG_8723A("[%s] Got P2P DEVICE INFO Attr!!\n", __func__
);
2278 pattr_content
= pbuf
= kzalloc(attr_contentlen
,
2280 if (pattr_content
) {
2281 u8 num_of_secdev_type
;
2284 rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_DEVICE_INFO
, pattr_content
, (uint
*)&attr_contentlen
);
2286 memcpy(psta
->dev_addr
, pattr_content
, ETH_ALEN
);/* P2P Device Address */
2288 pattr_content
+= ETH_ALEN
;
2290 memcpy(&psta
->config_methods
, pattr_content
, 2);/* Config Methods */
2291 psta
->config_methods
= be16_to_cpu(psta
->config_methods
);
2295 memcpy(psta
->primary_dev_type
, pattr_content
, 8);
2299 num_of_secdev_type
= *pattr_content
;
2302 if (num_of_secdev_type
== 0)
2304 psta
->num_of_secdev_type
= 0;
2310 psta
->num_of_secdev_type
= num_of_secdev_type
;
2312 len
= (sizeof(psta
->secdev_types_list
)<(num_of_secdev_type
*8)) ? (sizeof(psta
->secdev_types_list
)) : (num_of_secdev_type
*8);
2314 memcpy(psta
->secdev_types_list
, pattr_content
, len
);
2316 pattr_content
+= (num_of_secdev_type
*8);
2319 /* dev_name_len = attr_contentlen - ETH_ALEN - 2 - 8 - 1 - (num_of_secdev_type*8); */
2320 psta
->dev_name_len
= 0;
2321 if (WPS_ATTR_DEVICE_NAME
== be16_to_cpu(*(u16
*)pattr_content
))
2323 dev_name_len
= be16_to_cpu(*(u16
*)(pattr_content
+2));
2325 psta
->dev_name_len
= (sizeof(psta
->dev_name
)<dev_name_len
) ? sizeof(psta
->dev_name
):dev_name_len
;
2327 memcpy(psta
->dev_name
, pattr_content
+4, psta
->dev_name_len
);
2336 /* Get the next P2P IE */
2337 p2p_ie
= rtw_get_p2p_ie23a(p2p_ie
+p2p_ielen
, ies_len
-(p2p_ie
-ies
+ p2p_ielen
), NULL
, &p2p_ielen
);
2344 u32
process_p2p_devdisc_req23a(struct wifidirect_info
*pwdinfo
, u8
*pframe
,
2348 u8 status
, dialogToken
;
2349 struct sta_info
*psta
= NULL
;
2350 struct rtw_adapter
*padapter
= pwdinfo
->padapter
;
2351 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2354 struct ieee80211_hdr
*hdr
= (struct ieee80211_hdr
*) pframe
;
2356 frame_body
= (unsigned char *)
2357 (pframe
+ sizeof(struct ieee80211_hdr_3addr
));
2359 dialogToken
= frame_body
[7];
2360 status
= P2P_STATUS_FAIL_UNKNOWN_P2PGROUP
;
2362 if ((p2p_ie
= rtw_get_p2p_ie23a(frame_body
+ _PUBLIC_ACTION_IE_OFFSET_
,
2363 len
- _PUBLIC_ACTION_IE_OFFSET_
, NULL
,
2365 u8 groupid
[38] = { 0x00 };
2366 u8 dev_addr
[ETH_ALEN
] = { 0x00 };
2367 u32 attr_contentlen
= 0;
2369 if (rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
,
2370 P2P_ATTR_GROUP_ID
, groupid
,
2371 &attr_contentlen
)) {
2372 if (!memcmp(pwdinfo
->device_addr
, groupid
, ETH_ALEN
) &&
2373 !memcmp(pwdinfo
->p2p_group_ssid
, groupid
+ ETH_ALEN
,
2374 pwdinfo
->p2p_group_ssid_len
)) {
2375 attr_contentlen
= 0;
2377 if (rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
,
2380 &attr_contentlen
)) {
2381 struct list_head
*phead
, *plist
, *ptmp
;
2383 spin_lock_bh(&pstapriv
->asoc_list_lock
);
2384 phead
= &pstapriv
->asoc_list
;
2386 list_for_each_safe(plist
, ptmp
, phead
) {
2387 psta
= container_of(plist
, struct sta_info
, asoc_list
);
2389 if (psta
->is_p2p_device
&& (psta
->dev_cap
&P2P_DEVCAP_CLIENT_DISCOVERABILITY
) &&
2390 !memcmp(psta
->dev_addr
, dev_addr
, ETH_ALEN
))
2392 /* spin_unlock_bh(&pstapriv->asoc_list_lock); */
2393 /* issue GO Discoverability Request */
2394 issue_group_disc_req(pwdinfo
, psta
->hwaddr
);
2395 /* spin_lock_bh(&pstapriv->asoc_list_lock); */
2396 status
= P2P_STATUS_SUCCESS
;
2399 status
= P2P_STATUS_FAIL_INFO_UNAVAILABLE
;
2402 spin_unlock_bh(&pstapriv
->asoc_list_lock
);
2404 status
= P2P_STATUS_FAIL_INVALID_PARAM
;
2407 status
= P2P_STATUS_FAIL_INVALID_PARAM
;
2412 /* issue Device Discoverability Response */
2413 issue_p2p_devdisc_resp(pwdinfo
, hdr
->addr2
, status
, dialogToken
);
2415 return (status
== P2P_STATUS_SUCCESS
) ? true:false;
2418 u32
process_p2p_devdisc_resp23a(struct wifidirect_info
*pwdinfo
, u8
*pframe
, uint len
)
2423 u8
process_p2p_provdisc_req23a(struct wifidirect_info
*pwdinfo
,
2424 u8
*pframe
, uint len
)
2429 uint wps_ielen
= 0, attr_contentlen
= 0;
2430 u16 uconfig_method
= 0;
2431 struct ieee80211_hdr
*hdr
= (struct ieee80211_hdr
*)pframe
;
2433 frame_body
= (pframe
+ sizeof(struct ieee80211_hdr_3addr
));
2435 wpsie
= rtw_get_wps_ie23a(frame_body
+ _PUBLIC_ACTION_IE_OFFSET_
,
2436 len
- _PUBLIC_ACTION_IE_OFFSET_
, NULL
,
2441 if (!rtw_get_wps_attr_content23a(wpsie
, wps_ielen
, WPS_ATTR_CONF_METHOD
,
2442 (u8
*)&uconfig_method
, &attr_contentlen
))
2445 uconfig_method
= be16_to_cpu(uconfig_method
);
2446 ptr
= pwdinfo
->rx_prov_disc_info
.strconfig_method_desc_of_prov_disc_req
;
2448 switch (uconfig_method
)
2450 case WPS_CM_DISPLYA
:
2451 memcpy(ptr
, "dis", 3);
2455 memcpy(ptr
, "lab", 3);
2458 case WPS_CM_PUSH_BUTTON
:
2459 memcpy(ptr
, "pbc", 3);
2463 memcpy(ptr
, "pad", 3);
2466 issue_p2p_provision_resp(pwdinfo
, hdr
->addr2
, frame_body
,
2470 DBG_8723A("[%s] config method = %s\n", __func__
, ptr
);
2475 u8
process_p2p_provdisc_resp23a(struct wifidirect_info
*pwdinfo
, u8
*pframe
)
2481 static u8
rtw_p2p_get_peer_ch_list(struct wifidirect_info
*pwdinfo
, u8
*ch_content
, u8 ch_cnt
, u8
*peer_ch_list
)
2494 for (i
= 0 ; i
< temp
; i
++, j
++)
2496 peer_ch_list
[j
] = *(ch_content
+ 1 + i
);
2498 ch_content
+= (temp
+ 1);
2499 ch_cnt
-= (temp
+ 1);
2506 static u8
rtw_p2p_ch_inclusion(struct mlme_ext_priv
*pmlmeext
, u8
*peer_ch_list
, u8 peer_ch_num
, u8
*ch_list_inclusioned
)
2508 int i
= 0, j
= 0, temp
= 0;
2511 for (i
= 0; i
< peer_ch_num
; i
++)
2513 for (j
= temp
; j
< pmlmeext
->max_chan_nums
; j
++)
2515 if (*(peer_ch_list
+ i
) == pmlmeext
->channel_set
[ j
].ChannelNum
)
2517 ch_list_inclusioned
[ ch_no
++ ] = *(peer_ch_list
+ i
);
2527 u8
process_p2p_group_negotation_req23a(struct wifidirect_info
*pwdinfo
, u8
*pframe
, uint len
)
2529 struct rtw_adapter
*padapter
= pwdinfo
->padapter
;
2530 u8 result
= P2P_STATUS_SUCCESS
;
2531 u32 p2p_ielen
= 0, wps_ielen
= 0;
2536 u16 wps_devicepassword_id
= 0x0000;
2537 uint wps_devicepassword_id_len
= 0;
2538 #ifdef CONFIG_8723AU_P2P
2539 u8 wfd_ie
[ 128 ] = { 0x00 };
2541 #endif /* CONFIG_8723AU_P2P */
2543 if ((wpsie
= rtw_get_wps_ie23a(pframe
+ _PUBLIC_ACTION_IE_OFFSET_
, len
- _PUBLIC_ACTION_IE_OFFSET_
, NULL
, &wps_ielen
)))
2545 /* Commented by Kurt 20120113 */
2546 /* If some device wants to do p2p handshake without sending prov_disc_req */
2547 /* We have to get peer_req_cm from here. */
2548 if (!memcmp(pwdinfo
->rx_prov_disc_info
.strconfig_method_desc_of_prov_disc_req
, "000", 3))
2550 rtw_get_wps_attr_content23a(wpsie
, wps_ielen
, WPS_ATTR_DEVICE_PWID
, (u8
*) &wps_devicepassword_id
, &wps_devicepassword_id_len
);
2551 wps_devicepassword_id
= be16_to_cpu(wps_devicepassword_id
);
2553 if (wps_devicepassword_id
== WPS_DPID_USER_SPEC
)
2555 memcpy(pwdinfo
->rx_prov_disc_info
.strconfig_method_desc_of_prov_disc_req
, "dis", 3);
2557 else if (wps_devicepassword_id
== WPS_DPID_REGISTRAR_SPEC
)
2559 memcpy(pwdinfo
->rx_prov_disc_info
.strconfig_method_desc_of_prov_disc_req
, "pad", 3);
2563 memcpy(pwdinfo
->rx_prov_disc_info
.strconfig_method_desc_of_prov_disc_req
, "pbc", 3);
2569 DBG_8723A("[%s] WPS IE not Found!!\n", __func__
);
2570 result
= P2P_STATUS_FAIL_INCOMPATIBLE_PARAM
;
2571 rtw_p2p_set_state(pwdinfo
, P2P_STATE_GONEGO_FAIL
);
2575 if (pwdinfo
->ui_got_wps_info
== P2P_NO_WPSINFO
)
2577 result
= P2P_STATUS_FAIL_INFO_UNAVAILABLE
;
2578 rtw_p2p_set_state(pwdinfo
, P2P_STATE_TX_INFOR_NOREADY
);
2582 ies
= pframe
+ _PUBLIC_ACTION_IE_OFFSET_
;
2583 ies_len
= len
- _PUBLIC_ACTION_IE_OFFSET_
;
2585 p2p_ie
= rtw_get_p2p_ie23a(ies
, ies_len
, NULL
, &p2p_ielen
);
2589 DBG_8723A("[%s] P2P IE not Found!!\n", __func__
);
2590 result
= P2P_STATUS_FAIL_INCOMPATIBLE_PARAM
;
2591 rtw_p2p_set_state(pwdinfo
, P2P_STATE_GONEGO_FAIL
);
2596 u8 attr_content
= 0x00;
2597 u32 attr_contentlen
= 0;
2598 u8 ch_content
[50] = { 0x00 };
2600 u8 peer_ch_list
[50] = { 0x00 };
2602 u8 ch_list_inclusioned
[50] = { 0x00 };
2603 u8 ch_num_inclusioned
= 0;
2606 rtw_p2p_set_state(pwdinfo
, P2P_STATE_GONEGO_ING
);
2608 /* Check P2P Capability ATTR */
2609 if (rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_CAPABILITY
, (u8
*)&cap_attr
, (uint
*)&attr_contentlen
))
2610 cap_attr
= le16_to_cpu(cap_attr
);
2612 if (rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_GO_INTENT
, &attr_content
, &attr_contentlen
))
2614 DBG_8723A("[%s] GO Intent = %d, tie = %d\n", __func__
, attr_content
>> 1, attr_content
& 0x01);
2615 pwdinfo
->peer_intent
= attr_content
; /* include both intent and tie breaker values. */
2617 if (pwdinfo
->intent
== (pwdinfo
->peer_intent
>> 1))
2619 /* Try to match the tie breaker value */
2620 if (pwdinfo
->intent
== P2P_MAX_INTENT
)
2622 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_DEVICE
);
2623 result
= P2P_STATUS_FAIL_BOTH_GOINTENT_15
;
2627 if (attr_content
& 0x01)
2629 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_CLIENT
);
2633 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_GO
);
2637 else if (pwdinfo
->intent
> (pwdinfo
->peer_intent
>> 1))
2639 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_GO
);
2643 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_CLIENT
);
2646 if (rtw_p2p_chk_role(pwdinfo
, P2P_ROLE_GO
))
2648 /* Store the group id information. */
2649 memcpy(pwdinfo
->groupid_info
.go_device_addr
, pwdinfo
->device_addr
, ETH_ALEN
);
2650 memcpy(pwdinfo
->groupid_info
.ssid
, pwdinfo
->nego_ssid
, pwdinfo
->nego_ssidlen
);
2654 attr_contentlen
= 0;
2655 if (rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_INTENTED_IF_ADDR
, pwdinfo
->p2p_peer_interface_addr
, &attr_contentlen
))
2657 if (attr_contentlen
!= ETH_ALEN
)
2659 memset(pwdinfo
->p2p_peer_interface_addr
, 0x00, ETH_ALEN
);
2663 if (rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_CH_LIST
, ch_content
, &ch_cnt
))
2665 peer_ch_num
= rtw_p2p_get_peer_ch_list(pwdinfo
, ch_content
, ch_cnt
, peer_ch_list
);
2666 ch_num_inclusioned
= rtw_p2p_ch_inclusion(&padapter
->mlmeextpriv
, peer_ch_list
, peer_ch_num
, ch_list_inclusioned
);
2668 if (ch_num_inclusioned
== 0)
2670 DBG_8723A("[%s] No common channel in channel list!\n", __func__
);
2671 result
= P2P_STATUS_FAIL_NO_COMMON_CH
;
2672 rtw_p2p_set_state(pwdinfo
, P2P_STATE_GONEGO_FAIL
);
2676 if (rtw_p2p_chk_role(pwdinfo
, P2P_ROLE_GO
))
2678 if (!rtw_p2p_is_channel_list_ok(pwdinfo
->operating_channel
,
2679 ch_list_inclusioned
, ch_num_inclusioned
))
2682 u8 operatingch_info
[5] = { 0x00 }, peer_operating_ch
= 0;
2683 attr_contentlen
= 0;
2685 if (rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_OPERATING_CH
, operatingch_info
, &attr_contentlen
))
2687 peer_operating_ch
= operatingch_info
[4];
2690 if (rtw_p2p_is_channel_list_ok(peer_operating_ch
,
2691 ch_list_inclusioned
, ch_num_inclusioned
))
2694 * Change our operating channel as peer's for compatibility.
2696 pwdinfo
->operating_channel
= peer_operating_ch
;
2697 DBG_8723A("[%s] Change op ch to %02x as peer's\n", __func__
, pwdinfo
->operating_channel
);
2701 /* Take first channel of ch_list_inclusioned as operating channel */
2702 pwdinfo
->operating_channel
= ch_list_inclusioned
[0];
2703 DBG_8723A("[%s] Change op ch to %02x\n", __func__
, pwdinfo
->operating_channel
);
2711 /* Get the next P2P IE */
2712 p2p_ie
= rtw_get_p2p_ie23a(p2p_ie
+p2p_ielen
, ies_len
-(p2p_ie
-ies
+ p2p_ielen
), NULL
, &p2p_ielen
);
2715 #ifdef CONFIG_8723AU_P2P
2716 /* Added by Albert 20110823 */
2717 /* Try to get the TCP port information when receiving the negotiation request. */
2718 if (rtw_get_wfd_ie(pframe
+ _PUBLIC_ACTION_IE_OFFSET_
, len
- _PUBLIC_ACTION_IE_OFFSET_
, wfd_ie
, &wfd_ielen
))
2720 u8 attr_content
[ 10 ] = { 0x00 };
2721 u32 attr_contentlen
= 0;
2723 DBG_8723A("[%s] WFD IE Found!!\n", __func__
);
2724 rtw_get_wfd_attr_content(wfd_ie
, wfd_ielen
, WFD_ATTR_DEVICE_INFO
, attr_content
, &attr_contentlen
);
2725 if (attr_contentlen
)
2727 pwdinfo
->wfd_info
->peer_rtsp_ctrlport
= get_unaligned_be16(attr_content
+ 2);
2728 DBG_8723A("[%s] Peer PORT NUM = %d\n", __func__
, pwdinfo
->wfd_info
->peer_rtsp_ctrlport
);
2731 #endif /* CONFIG_8723AU_P2P */
2736 u8
process_p2p_group_negotation_resp23a(struct wifidirect_info
*pwdinfo
, u8
*pframe
, uint len
)
2738 struct rtw_adapter
*padapter
= pwdinfo
->padapter
;
2739 u8 result
= P2P_STATUS_SUCCESS
;
2740 u32 p2p_ielen
, wps_ielen
;
2744 #ifdef CONFIG_8723AU_P2P
2745 u8 wfd_ie
[ 128 ] = { 0x00 };
2747 #endif /* CONFIG_8723AU_P2P */
2749 ies
= pframe
+ _PUBLIC_ACTION_IE_OFFSET_
;
2750 ies_len
= len
- _PUBLIC_ACTION_IE_OFFSET_
;
2752 /* Be able to know which one is the P2P GO and which one is P2P client. */
2754 if (rtw_get_wps_ie23a(ies
, ies_len
, NULL
, &wps_ielen
))
2760 DBG_8723A("[%s] WPS IE not Found!!\n", __func__
);
2761 result
= P2P_STATUS_FAIL_INCOMPATIBLE_PARAM
;
2762 rtw_p2p_set_state(pwdinfo
, P2P_STATE_GONEGO_FAIL
);
2765 p2p_ie
= rtw_get_p2p_ie23a(ies
, ies_len
, NULL
, &p2p_ielen
);
2768 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_DEVICE
);
2769 rtw_p2p_set_state(pwdinfo
, P2P_STATE_GONEGO_FAIL
);
2770 result
= P2P_STATUS_FAIL_INCOMPATIBLE_PARAM
;
2775 u8 attr_content
= 0x00;
2776 u32 attr_contentlen
= 0;
2777 u8 operatingch_info
[5] = { 0x00 };
2780 u8 peer_ch_list
[50] = { 0x00 };
2782 u8 ch_list_inclusioned
[50] = { 0x00 };
2783 u8 ch_num_inclusioned
= 0;
2785 while (p2p_ie
) /* Found the P2P IE. */
2788 /* Check P2P Capability ATTR */
2789 if (rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_CAPABILITY
, (u8
*)&cap_attr
, (uint
*)&attr_contentlen
))
2790 cap_attr
= le16_to_cpu(cap_attr
);
2792 rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_STATUS
, &attr_content
, &attr_contentlen
);
2793 if (attr_contentlen
== 1)
2795 DBG_8723A("[%s] Status = %d\n", __func__
, attr_content
);
2796 if (attr_content
== P2P_STATUS_SUCCESS
)
2802 if (P2P_STATUS_FAIL_INFO_UNAVAILABLE
== attr_content
) {
2803 rtw_p2p_set_state(pwdinfo
, P2P_STATE_RX_INFOR_NOREADY
);
2805 rtw_p2p_set_state(pwdinfo
, P2P_STATE_GONEGO_FAIL
);
2807 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_DEVICE
);
2808 result
= attr_content
;
2813 /* Try to get the peer's interface address */
2814 attr_contentlen
= 0;
2815 if (rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_INTENTED_IF_ADDR
, pwdinfo
->p2p_peer_interface_addr
, &attr_contentlen
))
2817 if (attr_contentlen
!= ETH_ALEN
)
2819 memset(pwdinfo
->p2p_peer_interface_addr
, 0x00, ETH_ALEN
);
2823 /* Try to get the peer's intent and tie breaker value. */
2824 attr_content
= 0x00;
2825 attr_contentlen
= 0;
2826 if (rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_GO_INTENT
, &attr_content
, &attr_contentlen
))
2828 DBG_8723A("[%s] GO Intent = %d, tie = %d\n", __func__
, attr_content
>> 1, attr_content
& 0x01);
2829 pwdinfo
->peer_intent
= attr_content
; /* include both intent and tie breaker values. */
2831 if (pwdinfo
->intent
== (pwdinfo
->peer_intent
>> 1))
2833 /* Try to match the tie breaker value */
2834 if (pwdinfo
->intent
== P2P_MAX_INTENT
)
2836 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_DEVICE
);
2837 result
= P2P_STATUS_FAIL_BOTH_GOINTENT_15
;
2838 rtw_p2p_set_state(pwdinfo
, P2P_STATE_GONEGO_FAIL
);
2842 rtw_p2p_set_state(pwdinfo
, P2P_STATE_GONEGO_OK
);
2843 rtw_p2p_set_pre_state(pwdinfo
, P2P_STATE_GONEGO_OK
);
2844 if (attr_content
& 0x01)
2846 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_CLIENT
);
2850 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_GO
);
2854 else if (pwdinfo
->intent
> (pwdinfo
->peer_intent
>> 1))
2856 rtw_p2p_set_state(pwdinfo
, P2P_STATE_GONEGO_OK
);
2857 rtw_p2p_set_pre_state(pwdinfo
, P2P_STATE_GONEGO_OK
);
2858 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_GO
);
2862 rtw_p2p_set_state(pwdinfo
, P2P_STATE_GONEGO_OK
);
2863 rtw_p2p_set_pre_state(pwdinfo
, P2P_STATE_GONEGO_OK
);
2864 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_CLIENT
);
2867 if (rtw_p2p_chk_role(pwdinfo
, P2P_ROLE_GO
))
2869 /* Store the group id information. */
2870 memcpy(pwdinfo
->groupid_info
.go_device_addr
, pwdinfo
->device_addr
, ETH_ALEN
);
2871 memcpy(pwdinfo
->groupid_info
.ssid
, pwdinfo
->nego_ssid
, pwdinfo
->nego_ssidlen
);
2876 /* Try to get the operation channel information */
2878 attr_contentlen
= 0;
2879 if (rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_OPERATING_CH
, operatingch_info
, &attr_contentlen
))
2881 DBG_8723A("[%s] Peer's operating channel = %d\n", __func__
, operatingch_info
[4]);
2882 pwdinfo
->peer_operating_ch
= operatingch_info
[4];
2885 /* Try to get the channel list information */
2886 if (rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_CH_LIST
, pwdinfo
->channel_list_attr
, &pwdinfo
->channel_list_attr_len
))
2888 DBG_8723A("[%s] channel list attribute found, len = %d\n", __func__
, pwdinfo
->channel_list_attr_len
);
2890 peer_ch_num
= rtw_p2p_get_peer_ch_list(pwdinfo
, pwdinfo
->channel_list_attr
, pwdinfo
->channel_list_attr_len
, peer_ch_list
);
2891 ch_num_inclusioned
= rtw_p2p_ch_inclusion(&padapter
->mlmeextpriv
, peer_ch_list
, peer_ch_num
, ch_list_inclusioned
);
2893 if (ch_num_inclusioned
== 0)
2895 DBG_8723A("[%s] No common channel in channel list!\n", __func__
);
2896 result
= P2P_STATUS_FAIL_NO_COMMON_CH
;
2897 rtw_p2p_set_state(pwdinfo
, P2P_STATE_GONEGO_FAIL
);
2901 if (rtw_p2p_chk_role(pwdinfo
, P2P_ROLE_GO
))
2903 if (!rtw_p2p_is_channel_list_ok(pwdinfo
->operating_channel
,
2904 ch_list_inclusioned
, ch_num_inclusioned
))
2907 u8 operatingch_info
[5] = { 0x00 }, peer_operating_ch
= 0;
2908 attr_contentlen
= 0;
2910 if (rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_OPERATING_CH
, operatingch_info
, &attr_contentlen
))
2912 peer_operating_ch
= operatingch_info
[4];
2915 if (rtw_p2p_is_channel_list_ok(peer_operating_ch
,
2916 ch_list_inclusioned
, ch_num_inclusioned
))
2919 * Change our operating channel as peer's for compatibility.
2921 pwdinfo
->operating_channel
= peer_operating_ch
;
2922 DBG_8723A("[%s] Change op ch to %02x as peer's\n", __func__
, pwdinfo
->operating_channel
);
2926 /* Take first channel of ch_list_inclusioned as operating channel */
2927 pwdinfo
->operating_channel
= ch_list_inclusioned
[0];
2928 DBG_8723A("[%s] Change op ch to %02x\n", __func__
, pwdinfo
->operating_channel
);
2938 DBG_8723A("[%s] channel list attribute not found!\n", __func__
);
2941 /* Try to get the group id information if peer is GO */
2942 attr_contentlen
= 0;
2943 memset(groupid
, 0x00, 38);
2944 if (rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_GROUP_ID
, groupid
, &attr_contentlen
))
2946 memcpy(pwdinfo
->groupid_info
.go_device_addr
, &groupid
[0], ETH_ALEN
);
2947 memcpy(pwdinfo
->groupid_info
.ssid
, &groupid
[6], attr_contentlen
- ETH_ALEN
);
2950 /* Get the next P2P IE */
2951 p2p_ie
= rtw_get_p2p_ie23a(p2p_ie
+p2p_ielen
, ies_len
-(p2p_ie
-ies
+ p2p_ielen
), NULL
, &p2p_ielen
);
2956 #ifdef CONFIG_8723AU_P2P
2957 /* Added by Albert 20111122 */
2958 /* Try to get the TCP port information when receiving the negotiation response. */
2959 if (rtw_get_wfd_ie(pframe
+ _PUBLIC_ACTION_IE_OFFSET_
, len
- _PUBLIC_ACTION_IE_OFFSET_
, wfd_ie
, &wfd_ielen
))
2961 u8 attr_content
[ 10 ] = { 0x00 };
2962 u32 attr_contentlen
= 0;
2964 DBG_8723A("[%s] WFD IE Found!!\n", __func__
);
2965 rtw_get_wfd_attr_content(wfd_ie
, wfd_ielen
, WFD_ATTR_DEVICE_INFO
, attr_content
, &attr_contentlen
);
2966 if (attr_contentlen
)
2968 pwdinfo
->wfd_info
->peer_rtsp_ctrlport
= get_unaligned_be16(attr_content
+ 2);
2969 DBG_8723A("[%s] Peer PORT NUM = %d\n", __func__
, pwdinfo
->wfd_info
->peer_rtsp_ctrlport
);
2972 #endif /* CONFIG_8723AU_P2P */
2977 u8
process_p2p_group_negotation_confirm23a(struct wifidirect_info
*pwdinfo
, u8
*pframe
, uint len
)
2983 u8 result
= P2P_STATUS_SUCCESS
;
2984 ies
= pframe
+ _PUBLIC_ACTION_IE_OFFSET_
;
2985 ies_len
= len
- _PUBLIC_ACTION_IE_OFFSET_
;
2987 p2p_ie
= rtw_get_p2p_ie23a(ies
, ies_len
, NULL
, &p2p_ielen
);
2988 while (p2p_ie
) /* Found the P2P IE. */
2990 u8 attr_content
= 0x00, operatingch_info
[5] = { 0x00 };
2991 u8 groupid
[ 38 ] = { 0x00 };
2992 u32 attr_contentlen
= 0;
2994 pwdinfo
->negotiation_dialog_token
= 1;
2995 rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_STATUS
, &attr_content
, &attr_contentlen
);
2996 if (attr_contentlen
== 1)
2998 DBG_8723A("[%s] Status = %d\n", __func__
, attr_content
);
2999 result
= attr_content
;
3001 if (attr_content
== P2P_STATUS_SUCCESS
)
3003 del_timer_sync(&pwdinfo
->restore_p2p_state_timer
);
3005 /* Commented by Albert 20100911 */
3006 /* Todo: Need to handle the case which both Intents are the same. */
3007 rtw_p2p_set_state(pwdinfo
, P2P_STATE_GONEGO_OK
);
3008 rtw_p2p_set_pre_state(pwdinfo
, P2P_STATE_GONEGO_OK
);
3009 if ((pwdinfo
->intent
) > (pwdinfo
->peer_intent
>> 1))
3011 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_GO
);
3013 else if ((pwdinfo
->intent
) < (pwdinfo
->peer_intent
>> 1))
3015 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_CLIENT
);
3019 /* Have to compare the Tie Breaker */
3020 if (pwdinfo
->peer_intent
& 0x01)
3022 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_CLIENT
);
3026 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_GO
);
3032 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_DEVICE
);
3033 rtw_p2p_set_state(pwdinfo
, P2P_STATE_GONEGO_FAIL
);
3038 /* Try to get the group id information */
3039 attr_contentlen
= 0;
3040 memset(groupid
, 0x00, 38);
3041 if (rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_GROUP_ID
, groupid
, &attr_contentlen
))
3043 DBG_8723A("[%s] Ssid = %s, ssidlen = %zu\n", __func__
, &groupid
[ETH_ALEN
], strlen(&groupid
[ETH_ALEN
]));
3044 memcpy(pwdinfo
->groupid_info
.go_device_addr
, &groupid
[0], ETH_ALEN
);
3045 memcpy(pwdinfo
->groupid_info
.ssid
, &groupid
[6], attr_contentlen
- ETH_ALEN
);
3048 attr_contentlen
= 0;
3049 if (rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_OPERATING_CH
, operatingch_info
, &attr_contentlen
))
3051 DBG_8723A("[%s] Peer's operating channel = %d\n", __func__
, operatingch_info
[4]);
3052 pwdinfo
->peer_operating_ch
= operatingch_info
[4];
3055 /* Get the next P2P IE */
3056 p2p_ie
= rtw_get_p2p_ie23a(p2p_ie
+p2p_ielen
, ies_len
-(p2p_ie
-ies
+ p2p_ielen
), NULL
, &p2p_ielen
);
3063 u8
process_p2p_presence_req23a(struct wifidirect_info
*pwdinfo
, u8
*pframe
, uint len
)
3067 u8 status
= P2P_STATUS_SUCCESS
;
3068 struct ieee80211_hdr
*hdr
= (struct ieee80211_hdr
*) pframe
;
3070 frame_body
= (unsigned char *)(pframe
+ sizeof(struct ieee80211_hdr_3addr
));
3072 dialogToken
= frame_body
[6];
3074 /* todo: check NoA attribute */
3076 issue_p2p_presence_resp(pwdinfo
, hdr
->addr2
, status
, dialogToken
);
3081 static void find_phase_handler(struct rtw_adapter
*padapter
)
3083 struct wifidirect_info
*pwdinfo
= &padapter
->wdinfo
;
3084 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
3085 struct cfg80211_ssid ssid
;
3090 memset((unsigned char*)&ssid
, 0, sizeof(struct cfg80211_ssid
));
3091 memcpy(ssid
.ssid
, pwdinfo
->p2p_wildcard_ssid
, P2P_WILDCARD_SSID_LEN
);
3092 ssid
.ssid_len
= P2P_WILDCARD_SSID_LEN
;
3094 rtw_p2p_set_state(pwdinfo
, P2P_STATE_FIND_PHASE_SEARCH
);
3096 spin_lock_bh(&pmlmepriv
->lock
);
3097 _status
= rtw_sitesurvey_cmd23a(padapter
, &ssid
, 1, NULL
, 0);
3098 spin_unlock_bh(&pmlmepriv
->lock
);
3103 void p2p_concurrent_handler(struct rtw_adapter
* padapter
);
3105 static void restore_p2p_state_handler(struct rtw_adapter
*padapter
)
3107 struct wifidirect_info
*pwdinfo
= &padapter
->wdinfo
;
3109 if (rtw_p2p_chk_state(pwdinfo
, P2P_STATE_GONEGO_ING
) || rtw_p2p_chk_state(pwdinfo
, P2P_STATE_GONEGO_FAIL
))
3110 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_DEVICE
);
3112 rtw_p2p_set_state(pwdinfo
, rtw_p2p_pre_state(pwdinfo
));
3114 if (rtw_p2p_chk_role(pwdinfo
, P2P_ROLE_DEVICE
)) {
3115 /* In the P2P client mode, the driver should not switch back to its listen channel */
3116 /* because this P2P client should stay at the operating channel of P2P GO. */
3117 set_channel_bwmode23a(padapter
, pwdinfo
->listen_channel
, HAL_PRIME_CHNL_OFFSET_DONT_CARE
, HT_CHANNEL_WIDTH_20
);
3121 static void pre_tx_invitereq_handler(struct rtw_adapter
*padapter
)
3123 struct wifidirect_info
*pwdinfo
= &padapter
->wdinfo
;
3125 set_channel_bwmode23a(padapter
, pwdinfo
->invitereq_info
.peer_ch
, HAL_PRIME_CHNL_OFFSET_DONT_CARE
, HT_CHANNEL_WIDTH_20
);
3126 rtl8723a_mlme_sitesurvey(padapter
, 1);
3127 issue23a_probereq_p2p(padapter
, NULL
);
3128 mod_timer(&pwdinfo
->pre_tx_scan_timer
,
3129 jiffies
+ msecs_to_jiffies(P2P_TX_PRESCAN_TIMEOUT
));
3132 static void pre_tx_provdisc_handler(struct rtw_adapter
*padapter
)
3134 struct wifidirect_info
*pwdinfo
= &padapter
->wdinfo
;
3136 set_channel_bwmode23a(padapter
,
3137 pwdinfo
->tx_prov_disc_info
.peer_channel_num
[0],
3138 HAL_PRIME_CHNL_OFFSET_DONT_CARE
,
3139 HT_CHANNEL_WIDTH_20
);
3140 rtl8723a_mlme_sitesurvey(padapter
, 1);
3141 issue23a_probereq_p2p(padapter
, NULL
);
3142 mod_timer(&pwdinfo
->pre_tx_scan_timer
,
3143 jiffies
+ msecs_to_jiffies(P2P_TX_PRESCAN_TIMEOUT
));
3146 static void pre_tx_negoreq_handler(struct rtw_adapter
*padapter
)
3148 struct wifidirect_info
*pwdinfo
= &padapter
->wdinfo
;
3150 set_channel_bwmode23a(padapter
,
3151 pwdinfo
->nego_req_info
.peer_channel_num
[0],
3152 HAL_PRIME_CHNL_OFFSET_DONT_CARE
,
3153 HT_CHANNEL_WIDTH_20
);
3154 rtl8723a_mlme_sitesurvey(padapter
, 1);
3155 issue23a_probereq_p2p(padapter
, NULL
);
3156 mod_timer(&pwdinfo
->pre_tx_scan_timer
,
3157 jiffies
+ msecs_to_jiffies(P2P_TX_PRESCAN_TIMEOUT
));
3160 static void ro_ch_handler(struct rtw_adapter
*padapter
)
3162 struct cfg80211_wifidirect_info
*pcfg80211_wdinfo
= &padapter
->cfg80211_wdinfo
;
3163 struct wifidirect_info
*pwdinfo
= &padapter
->wdinfo
;
3164 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
3166 if (pcfg80211_wdinfo
->restore_channel
!= pmlmeext
->cur_channel
) {
3167 if (!check_fwstate(&padapter
->mlmepriv
, _FW_LINKED
))
3168 pmlmeext
->cur_channel
= pcfg80211_wdinfo
->restore_channel
;
3170 set_channel_bwmode23a(padapter
, pmlmeext
->cur_channel
,
3171 HAL_PRIME_CHNL_OFFSET_DONT_CARE
,
3172 HT_CHANNEL_WIDTH_20
);
3175 rtw_p2p_set_state(pwdinfo
, rtw_p2p_pre_state(pwdinfo
));
3177 pcfg80211_wdinfo
->is_ro_ch
= false;
3179 DBG_8723A("cfg80211_remain_on_channel_expired\n");
3181 rtw_cfg80211_remain_on_channel_expired(padapter
,
3182 pcfg80211_wdinfo
->remain_on_ch_cookie
,
3183 &pcfg80211_wdinfo
->remain_on_ch_channel
,
3184 pcfg80211_wdinfo
->remain_on_ch_type
, GFP_KERNEL
);
3187 static void ro_ch_timer_process (unsigned long data
)
3189 struct rtw_adapter
*adapter
= (struct rtw_adapter
*)data
;
3191 p2p_protocol_wk_cmd23a(adapter
, P2P_RO_CH_WK
);
3194 #ifdef CONFIG_8723AU_P2P
3195 void rtw_append_wfd_ie(struct rtw_adapter
*padapter
, u8
*buf
, u32
* len
)
3197 unsigned char *frame_body
;
3198 u8 category
, action
, OUI_Subtype
, dialogToken
= 0;
3201 frame_body
= (unsigned char *)(buf
+ sizeof(struct ieee80211_hdr_3addr
));
3202 category
= frame_body
[0];
3204 if (category
== WLAN_CATEGORY_PUBLIC
) {
3205 action
= frame_body
[1];
3206 if (action
== ACT_PUBLIC_VENDOR
&&
3207 !memcmp(frame_body
+2, P2P_OUI23A
, 4)) {
3208 OUI_Subtype
= frame_body
[6];
3209 dialogToken
= frame_body
[7];
3210 switch (OUI_Subtype
)/* OUI Subtype */ {
3211 case P2P_GO_NEGO_REQ
:
3212 wfdielen
= build_nego_req_wfd_ie(&padapter
->wdinfo
, buf
+ (*len
));
3215 case P2P_GO_NEGO_RESP
:
3216 wfdielen
= build_nego_resp_wfd_ie(&padapter
->wdinfo
, buf
+ (*len
));
3219 case P2P_GO_NEGO_CONF
:
3220 wfdielen
= build_nego_confirm_wfd_ie(&padapter
->wdinfo
, buf
+ (*len
));
3224 wfdielen
= build_invitation_req_wfd_ie(&padapter
->wdinfo
, buf
+ (*len
));
3227 case P2P_INVIT_RESP
:
3228 wfdielen
= build_invitation_resp_wfd_ie(&padapter
->wdinfo
, buf
+ (*len
));
3231 case P2P_DEVDISC_REQ
:
3233 case P2P_DEVDISC_RESP
:
3235 case P2P_PROVISION_DISC_REQ
:
3236 wfdielen
= build_provdisc_req_wfd_ie(&padapter
->wdinfo
, buf
+ (*len
));
3239 case P2P_PROVISION_DISC_RESP
:
3240 wfdielen
= build_provdisc_resp_wfd_ie(&padapter
->wdinfo
, buf
+ (*len
));
3247 } else if (category
== WLAN_CATEGORY_VENDOR_SPECIFIC
) {
3248 OUI_Subtype
= frame_body
[5];
3249 dialogToken
= frame_body
[6];
3251 DBG_8723A("%s, action frame category =%d\n", __func__
, category
);
3256 int rtw_p2p_check_frames(struct rtw_adapter
*padapter
, const u8
*buf
, u32 len
, u8 tx
)
3258 int is_p2p_frame
= (-1);
3259 unsigned char *frame_body
;
3260 u8 category
, action
, OUI_Subtype
, dialogToken
= 0;
3263 struct rtw_wdev_priv
*pwdev_priv
= wdev_to_priv(padapter
->rtw_wdev
);
3265 frame_body
= (unsigned char *)(buf
+ sizeof(struct ieee80211_hdr_3addr
));
3266 category
= frame_body
[0];
3267 /* just for check */
3268 if (category
== WLAN_CATEGORY_PUBLIC
)
3270 action
= frame_body
[1];
3271 if (action
== ACT_PUBLIC_VENDOR
&&
3272 !memcmp(frame_body
+2, P2P_OUI23A
, 4)) {
3273 OUI_Subtype
= frame_body
[6];
3274 dialogToken
= frame_body
[7];
3275 is_p2p_frame
= OUI_Subtype
;
3276 p2p_ie
= rtw_get_p2p_ie23a(
3277 (u8
*)buf
+sizeof(struct ieee80211_hdr_3addr
)+_PUBLIC_ACTION_IE_OFFSET_
,
3278 len
-sizeof(struct ieee80211_hdr_3addr
)-_PUBLIC_ACTION_IE_OFFSET_
,
3281 switch (OUI_Subtype
) {/* OUI Subtype */
3284 case P2P_GO_NEGO_REQ
:
3285 DBG_8723A("RTW_%s:P2P_GO_NEGO_REQ, dialogToken =%d\n", (tx
== true)?"Tx":"Rx", dialogToken
);
3287 case P2P_GO_NEGO_RESP
:
3288 cont
= rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_STATUS
, NULL
, &cont_len
);
3289 DBG_8723A("RTW_%s:P2P_GO_NEGO_RESP, dialogToken =%d, status:%d\n", (tx
== true)?"Tx":"Rx", dialogToken
, cont
?*cont
:-1);
3292 pwdev_priv
->provdisc_req_issued
= false;
3294 case P2P_GO_NEGO_CONF
:
3295 cont
= rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_STATUS
, NULL
, &cont_len
);
3296 DBG_8723A("RTW_%s:P2P_GO_NEGO_CONF, dialogToken =%d, status:%d\n",
3297 (tx
== true)?"Tx":"Rx", dialogToken
, cont
?*cont
:-1);
3301 struct rtw_wdev_invit_info
* invit_info
= &pwdev_priv
->invit_info
;
3305 if ((cont
= rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_INVITATION_FLAGS
, NULL
, &cont_len
)))
3307 if ((cont
= rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_OPERATING_CH
, NULL
, &cont_len
)))
3310 if (invit_info
->token
!= dialogToken
)
3311 rtw_wdev_invit_info_init(invit_info
);
3313 invit_info
->token
= dialogToken
;
3314 invit_info
->flags
= (flags
==-1) ? 0x0 : flags
;
3315 invit_info
->req_op_ch
= op_ch
;
3317 DBG_8723A("RTW_%s:P2P_INVIT_REQ, dialogToken =%d, flags:0x%02x, op_ch:%d\n",
3318 (tx
) ? "Tx" : "Rx", dialogToken
, flags
, op_ch
);
3321 case P2P_INVIT_RESP
:
3323 struct rtw_wdev_invit_info
* invit_info
= &pwdev_priv
->invit_info
;
3327 if ((cont
= rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_STATUS
, NULL
, &cont_len
)))
3329 if ((cont
= rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_OPERATING_CH
, NULL
, &cont_len
)))
3332 if (invit_info
->token
!= dialogToken
) {
3333 rtw_wdev_invit_info_init(invit_info
);
3335 invit_info
->token
= 0;
3336 invit_info
->status
= (status
==-1) ? 0xff : status
;
3337 invit_info
->rsp_op_ch
= op_ch
;
3340 DBG_8723A("RTW_%s:P2P_INVIT_RESP, dialogToken =%d, status:%d, op_ch:%d\n",
3341 (tx
== true)?"Tx":"Rx", dialogToken
, status
, op_ch
);
3344 case P2P_DEVDISC_REQ
:
3345 DBG_8723A("RTW_%s:P2P_DEVDISC_REQ, dialogToken =%d\n", (tx
== true)?"Tx":"Rx", dialogToken
);
3347 case P2P_DEVDISC_RESP
:
3348 cont
= rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_STATUS
, NULL
, &cont_len
);
3349 DBG_8723A("RTW_%s:P2P_DEVDISC_RESP, dialogToken =%d, status:%d\n", (tx
== true)?"Tx":"Rx", dialogToken
, cont
?*cont
:-1);
3351 case P2P_PROVISION_DISC_REQ
:
3353 size_t frame_body_len
= len
- sizeof(struct ieee80211_hdr_3addr
);
3356 uint contentlen
= 0;
3358 DBG_8723A("RTW_%s:P2P_PROVISION_DISC_REQ, dialogToken =%d\n", (tx
== true)?"Tx":"Rx", dialogToken
);
3360 pwdev_priv
->provdisc_req_issued
= false;
3362 p2p_ie
= rtw_get_p2p_ie23a(frame_body
+ _PUBLIC_ACTION_IE_OFFSET_
,
3363 frame_body_len
- _PUBLIC_ACTION_IE_OFFSET_
,
3366 if (rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_GROUP_ID
, NULL
, &contentlen
))
3367 pwdev_priv
->provdisc_req_issued
= false;/* case: p2p_client join p2p GO */
3369 pwdev_priv
->provdisc_req_issued
= true;/* case: p2p_devices connection before Nego req. */
3373 case P2P_PROVISION_DISC_RESP
:
3374 DBG_8723A("RTW_%s:P2P_PROVISION_DISC_RESP, dialogToken =%d\n", (tx
== true)?"Tx":"Rx", dialogToken
);
3377 DBG_8723A("RTW_%s:OUI_Subtype =%d, dialogToken =%d\n", (tx
== true)?"Tx":"Rx", OUI_Subtype
, dialogToken
);
3384 else if (category
== WLAN_CATEGORY_VENDOR_SPECIFIC
)
3386 OUI_Subtype
= frame_body
[5];
3387 dialogToken
= frame_body
[6];
3389 is_p2p_frame
= OUI_Subtype
;
3391 switch (OUI_Subtype
) {
3392 case P2P_NOTICE_OF_ABSENCE
:
3393 DBG_8723A("RTW_%s:P2P_NOTICE_OF_ABSENCE, dialogToken =%d\n", (tx
== true)?"TX":"RX", dialogToken
);
3395 case P2P_PRESENCE_REQUEST
:
3396 DBG_8723A("RTW_%s:P2P_PRESENCE_REQUEST, dialogToken =%d\n", (tx
== true)?"TX":"RX", dialogToken
);
3398 case P2P_PRESENCE_RESPONSE
:
3399 DBG_8723A("RTW_%s:P2P_PRESENCE_RESPONSE, dialogToken =%d\n", (tx
== true)?"TX":"RX", dialogToken
);
3401 case P2P_GO_DISC_REQUEST
:
3402 DBG_8723A("RTW_%s:P2P_GO_DISC_REQUEST, dialogToken =%d\n", (tx
== true)?"TX":"RX", dialogToken
);
3405 DBG_8723A("RTW_%s:OUI_Subtype =%d, dialogToken =%d\n", (tx
== true)?"TX":"RX", OUI_Subtype
, dialogToken
);
3410 DBG_8723A("RTW_%s:action frame category =%d\n", (tx
== true)?"TX":"RX", category
);
3412 return is_p2p_frame
;
3415 void rtw_init_cfg80211_wifidirect_info(struct rtw_adapter
*padapter
)
3417 struct cfg80211_wifidirect_info
*pcfg80211_wdinfo
= &padapter
->cfg80211_wdinfo
;
3419 memset(pcfg80211_wdinfo
, 0x00, sizeof(struct cfg80211_wifidirect_info
));
3421 setup_timer(&pcfg80211_wdinfo
->remain_on_ch_timer
,
3422 ro_ch_timer_process
, (unsigned long)padapter
);
3425 void p2p_protocol_wk_hdl23a(struct rtw_adapter
*padapter
, int intCmdType
)
3427 switch (intCmdType
) {
3428 case P2P_FIND_PHASE_WK
:
3429 find_phase_handler(padapter
);
3431 case P2P_RESTORE_STATE_WK
:
3432 restore_p2p_state_handler(padapter
);
3434 case P2P_PRE_TX_PROVDISC_PROCESS_WK
:
3435 pre_tx_provdisc_handler(padapter
);
3437 case P2P_PRE_TX_INVITEREQ_PROCESS_WK
:
3438 pre_tx_invitereq_handler(padapter
);
3440 case P2P_PRE_TX_NEGOREQ_PROCESS_WK
:
3441 pre_tx_negoreq_handler(padapter
);
3444 ro_ch_handler(padapter
);
3449 #ifdef CONFIG_8723AU_P2P
3450 void process_p2p_ps_ie23a(struct rtw_adapter
*padapter
, u8
*IEs
, u32 IELength
)
3456 u8 noa_attr
[MAX_P2P_IE_LEN
] = { 0x00 };/* NoA length should be n*(13) + 2 */
3457 u32 attr_contentlen
= 0;
3459 struct wifidirect_info
*pwdinfo
= &padapter
->wdinfo
;
3460 u8 find_p2p
= false, find_p2p_ps
= false;
3461 u8 noa_offset
, noa_num
, noa_index
;
3465 if (rtw_p2p_chk_state(pwdinfo
, P2P_STATE_NONE
))
3469 if (IELength
<= _BEACON_IE_OFFSET_
)
3472 ies
= IEs
+ _BEACON_IE_OFFSET_
;
3473 ies_len
= IELength
- _BEACON_IE_OFFSET_
;
3475 p2p_ie
= rtw_get_p2p_ie23a(ies
, ies_len
, NULL
, &p2p_ielen
);
3480 /* Get Notice of Absence IE. */
3481 if (rtw_get_p2p_attr23a_content(p2p_ie
, p2p_ielen
, P2P_ATTR_NOA
, noa_attr
, &attr_contentlen
))
3484 noa_index
= noa_attr
[0];
3486 if ((pwdinfo
->p2p_ps_mode
== P2P_PS_NONE
) ||
3487 (noa_index
!= pwdinfo
->noa_index
))/* if index change, driver should reconfigure related setting. */
3489 pwdinfo
->noa_index
= noa_index
;
3490 pwdinfo
->opp_ps
= noa_attr
[1] >> 7;
3491 pwdinfo
->ctwindow
= noa_attr
[1] & 0x7F;
3495 /* NoA length should be n*(13) + 2 */
3496 if (attr_contentlen
> 2)
3498 while(noa_offset
< attr_contentlen
)
3500 /* memcpy(&wifidirect_info->noa_count[noa_num], &noa_attr[noa_offset], 1); */
3501 pwdinfo
->noa_count
[noa_num
] = noa_attr
[noa_offset
];
3504 memcpy(&pwdinfo
->noa_duration
[noa_num
], &noa_attr
[noa_offset
], 4);
3507 memcpy(&pwdinfo
->noa_interval
[noa_num
], &noa_attr
[noa_offset
], 4);
3510 memcpy(&pwdinfo
->noa_start_time
[noa_num
], &noa_attr
[noa_offset
], 4);
3516 pwdinfo
->noa_num
= noa_num
;
3518 if (pwdinfo
->opp_ps
== 1)
3520 pwdinfo
->p2p_ps_mode
= P2P_PS_CTWINDOW
;
3521 /* driver should wait LPS for entering CTWindow */
3522 if (padapter
->pwrctrlpriv
.bFwCurrentInPSMode
== true)
3524 p2p_ps_wk_cmd23a(padapter
, P2P_PS_ENABLE
, 1);
3527 else if (pwdinfo
->noa_num
> 0)
3529 pwdinfo
->p2p_ps_mode
= P2P_PS_NOA
;
3530 p2p_ps_wk_cmd23a(padapter
, P2P_PS_ENABLE
, 1);
3532 else if (pwdinfo
->p2p_ps_mode
> P2P_PS_NONE
)
3534 p2p_ps_wk_cmd23a(padapter
, P2P_PS_DISABLE
, 1);
3538 break; /* find target, just break. */
3541 /* Get the next P2P IE */
3542 p2p_ie
= rtw_get_p2p_ie23a(p2p_ie
+p2p_ielen
, ies_len
-(p2p_ie
-ies
+ p2p_ielen
), NULL
, &p2p_ielen
);
3546 if (find_p2p
== true)
3548 if ((pwdinfo
->p2p_ps_mode
> P2P_PS_NONE
) && (find_p2p_ps
== false))
3550 p2p_ps_wk_cmd23a(padapter
, P2P_PS_DISABLE
, 1);
3557 void p2p_ps_wk_hdl23a(struct rtw_adapter
*padapter
, u8 p2p_ps_state
)
3559 struct pwrctrl_priv
*pwrpriv
= &padapter
->pwrctrlpriv
;
3560 struct wifidirect_info
*pwdinfo
= &padapter
->wdinfo
;
3564 /* Pre action for p2p state */
3565 switch (p2p_ps_state
)
3567 case P2P_PS_DISABLE
:
3568 pwdinfo
->p2p_ps_state
= p2p_ps_state
;
3570 rtw_hal_set_hwreg23a(padapter
, HW_VAR_H2C_FW_P2P_PS_OFFLOAD
, (u8
*)(&p2p_ps_state
));
3572 pwdinfo
->noa_index
= 0;
3573 pwdinfo
->ctwindow
= 0;
3574 pwdinfo
->opp_ps
= 0;
3575 pwdinfo
->noa_num
= 0;
3576 pwdinfo
->p2p_ps_mode
= P2P_PS_NONE
;
3577 if (padapter
->pwrctrlpriv
.bFwCurrentInPSMode
== true) {
3578 if (pwrpriv
->smart_ps
== 0) {
3579 pwrpriv
->smart_ps
= 2;
3580 rtl8723a_set_FwPwrMode_cmd(padapter
, padapter
->pwrctrlpriv
.pwr_mode
);
3585 if (pwdinfo
->p2p_ps_mode
> P2P_PS_NONE
) {
3586 pwdinfo
->p2p_ps_state
= p2p_ps_state
;
3588 if (pwdinfo
->ctwindow
> 0) {
3589 if (pwrpriv
->smart_ps
!= 0) {
3590 pwrpriv
->smart_ps
= 0;
3591 DBG_8723A("%s(): Enter CTW, change SmartPS\n", __func__
);
3592 rtl8723a_set_FwPwrMode_cmd(padapter
, padapter
->pwrctrlpriv
.pwr_mode
);
3595 rtw_hal_set_hwreg23a(padapter
, HW_VAR_H2C_FW_P2P_PS_OFFLOAD
, (u8
*)(&p2p_ps_state
));
3599 case P2P_PS_SCAN_DONE
:
3600 case P2P_PS_ALLSTASLEEP
:
3601 if (pwdinfo
->p2p_ps_mode
> P2P_PS_NONE
) {
3602 pwdinfo
->p2p_ps_state
= p2p_ps_state
;
3603 rtw_hal_set_hwreg23a(padapter
, HW_VAR_H2C_FW_P2P_PS_OFFLOAD
, (u8
*)(&p2p_ps_state
));
3613 u8
p2p_ps_wk_cmd23a(struct rtw_adapter
*padapter
, u8 p2p_ps_state
, u8 enqueue
)
3615 struct cmd_obj
*ph2c
;
3616 struct drvextra_cmd_parm
*pdrvextra_cmd_parm
;
3617 struct wifidirect_info
*pwdinfo
= &padapter
->wdinfo
;
3618 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
3623 if (rtw_p2p_chk_state(pwdinfo
, P2P_STATE_NONE
))
3627 ph2c
= (struct cmd_obj
*)kzalloc(sizeof(struct cmd_obj
),
3634 pdrvextra_cmd_parm
= (struct drvextra_cmd_parm
*)
3635 kzalloc(sizeof(struct drvextra_cmd_parm
), GFP_ATOMIC
);
3636 if (pdrvextra_cmd_parm
== NULL
) {
3642 pdrvextra_cmd_parm
->ec_id
= P2P_PS_WK_CID
;
3643 pdrvextra_cmd_parm
->type_size
= p2p_ps_state
;
3644 pdrvextra_cmd_parm
->pbuf
= NULL
;
3646 init_h2fwcmd_w_parm_no_rsp(ph2c
, pdrvextra_cmd_parm
, GEN_CMD_CODE(_Set_Drv_Extra
));
3648 res
= rtw_enqueue_cmd23a(pcmdpriv
, ph2c
);
3652 p2p_ps_wk_hdl23a(padapter
, p2p_ps_state
);
3661 #endif /* CONFIG_8723AU_P2P */
3663 static void reset_ch_sitesurvey_timer_process(unsigned long data
)
3665 struct rtw_adapter
*adapter
= (struct rtw_adapter
*)data
;
3666 struct wifidirect_info
*pwdinfo
= &adapter
->wdinfo
;
3668 if (rtw_p2p_chk_state(pwdinfo
, P2P_STATE_NONE
))
3671 DBG_8723A("[%s] In\n", __func__
);
3672 /* Reset the operation channel information */
3673 pwdinfo
->rx_invitereq_info
.operation_ch
[0] = 0;
3674 pwdinfo
->rx_invitereq_info
.scan_op_ch_only
= 0;
3677 static void reset_ch_sitesurvey_timer_process2(unsigned long data
)
3679 struct rtw_adapter
*adapter
= (struct rtw_adapter
*)data
;
3680 struct wifidirect_info
*pwdinfo
= &adapter
->wdinfo
;
3682 if (rtw_p2p_chk_state(pwdinfo
, P2P_STATE_NONE
))
3685 DBG_8723A("[%s] In\n", __func__
);
3686 /* Reset the operation channel information */
3687 pwdinfo
->p2p_info
.operation_ch
[0] = 0;
3688 pwdinfo
->p2p_info
.scan_op_ch_only
= 0;
3691 static void restore_p2p_state_timer_process (unsigned long data
)
3693 struct rtw_adapter
*adapter
= (struct rtw_adapter
*)data
;
3694 struct wifidirect_info
*pwdinfo
= &adapter
->wdinfo
;
3696 if (rtw_p2p_chk_state(pwdinfo
, P2P_STATE_NONE
))
3699 p2p_protocol_wk_cmd23a(adapter
, P2P_RESTORE_STATE_WK
);
3702 static void pre_tx_scan_timer_process (unsigned long data
)
3704 struct rtw_adapter
*adapter
= (struct rtw_adapter
*)data
;
3705 struct wifidirect_info
*pwdinfo
= &adapter
->wdinfo
;
3706 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
3708 if (rtw_p2p_chk_state(pwdinfo
, P2P_STATE_NONE
))
3711 spin_lock_bh(&pmlmepriv
->lock
);
3713 if (rtw_p2p_chk_state(pwdinfo
, P2P_STATE_TX_PROVISION_DIS_REQ
))
3715 if (true == pwdinfo
->tx_prov_disc_info
.benable
) /* the provision discovery request frame is trigger to send or not */
3717 p2p_protocol_wk_cmd23a(adapter
, P2P_PRE_TX_PROVDISC_PROCESS_WK
);
3718 /* issue23a_probereq_p2p(adapter, NULL); */
3719 /* _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT); */
3722 else if (rtw_p2p_chk_state(pwdinfo
, P2P_STATE_GONEGO_ING
))
3724 if (true == pwdinfo
->nego_req_info
.benable
)
3726 p2p_protocol_wk_cmd23a(adapter
, P2P_PRE_TX_NEGOREQ_PROCESS_WK
);
3729 else if (rtw_p2p_chk_state(pwdinfo
, P2P_STATE_TX_INVITE_REQ
))
3731 if (true == pwdinfo
->invitereq_info
.benable
)
3733 p2p_protocol_wk_cmd23a(adapter
, P2P_PRE_TX_INVITEREQ_PROCESS_WK
);
3738 DBG_8723A("[%s] p2p_state is %d, ignore!!\n", __func__
, rtw_p2p_state(pwdinfo
));
3741 spin_unlock_bh(&pmlmepriv
->lock
);
3744 static void find_phase_timer_process (unsigned long data
)
3746 struct rtw_adapter
*adapter
= (struct rtw_adapter
*)data
;
3747 struct wifidirect_info
*pwdinfo
= &adapter
->wdinfo
;
3749 if (rtw_p2p_chk_state(pwdinfo
, P2P_STATE_NONE
))
3752 adapter
->wdinfo
.find_phase_state_exchange_cnt
++;
3754 p2p_protocol_wk_cmd23a(adapter
, P2P_FIND_PHASE_WK
);
3757 void reset_global_wifidirect_info23a(struct rtw_adapter
*padapter
)
3759 struct wifidirect_info
*pwdinfo
;
3761 pwdinfo
= &padapter
->wdinfo
;
3762 pwdinfo
->persistent_supported
= 0;
3763 pwdinfo
->session_available
= true;
3764 pwdinfo
->wfd_tdls_enable
= 0;
3765 pwdinfo
->wfd_tdls_weaksec
= 0;
3768 #ifdef CONFIG_8723AU_P2P
3769 int rtw_init_wifi_display_info(struct rtw_adapter
* padapter
)
3772 struct wifi_display_info
*pwfd_info
= &padapter
->wfd_info
;
3774 /* Used in P2P and TDLS */
3775 pwfd_info
->rtsp_ctrlport
= 554;
3776 pwfd_info
->peer_rtsp_ctrlport
= 0; /* Reset to 0 */
3777 pwfd_info
->wfd_enable
= false;
3778 pwfd_info
->wfd_device_type
= WFD_DEVINFO_PSINK
;
3779 pwfd_info
->scan_result_type
= SCAN_RESULT_P2P_ONLY
;
3782 pwfd_info
->peer_session_avail
= true;
3783 pwfd_info
->wfd_pc
= false;
3786 memset(pwfd_info
->ip_address
, 0x00, 4);
3787 memset(pwfd_info
->peer_ip_address
, 0x00, 4);
3790 #endif /* CONFIG_8723AU_P2P */
3792 void rtw_init_wifidirect_timers23a(struct rtw_adapter
* padapter
)
3794 struct wifidirect_info
*pwdinfo
= &padapter
->wdinfo
;
3796 setup_timer(&pwdinfo
->find_phase_timer
, find_phase_timer_process
,
3797 (unsigned long)padapter
);
3798 setup_timer(&pwdinfo
->restore_p2p_state_timer
,
3799 restore_p2p_state_timer_process
, (unsigned long)padapter
);
3800 setup_timer(&pwdinfo
->pre_tx_scan_timer
, pre_tx_scan_timer_process
,
3801 (unsigned long)padapter
);
3802 setup_timer(&pwdinfo
->reset_ch_sitesurvey
,
3803 reset_ch_sitesurvey_timer_process
, (unsigned long)padapter
);
3804 setup_timer(&pwdinfo
->reset_ch_sitesurvey2
,
3805 reset_ch_sitesurvey_timer_process2
,
3806 (unsigned long)padapter
);
3809 void rtw_init_wifidirect_addrs23a(struct rtw_adapter
* padapter
, u8
*dev_addr
, u8
*iface_addr
)
3811 #ifdef CONFIG_8723AU_P2P
3812 struct wifidirect_info
*pwdinfo
= &padapter
->wdinfo
;
3814 /*init device&interface address */
3816 memcpy(pwdinfo
->device_addr
, dev_addr
, ETH_ALEN
);
3819 memcpy(pwdinfo
->interface_addr
, iface_addr
, ETH_ALEN
);
3824 void init_wifidirect_info23a(struct rtw_adapter
*padapter
, enum P2P_ROLE role
)
3826 struct wifidirect_info
*pwdinfo
;
3827 #ifdef CONFIG_8723AU_P2P
3828 struct wifi_display_info
*pwfd_info
= &padapter
->wfd_info
;
3831 pwdinfo
= &padapter
->wdinfo
;
3833 pwdinfo
->padapter
= padapter
;
3835 /* 1, 6, 11 are the social channel defined in the WiFi Direct specification. */
3836 pwdinfo
->social_chan
[0] = 1;
3837 pwdinfo
->social_chan
[1] = 6;
3838 pwdinfo
->social_chan
[2] = 11;
3839 pwdinfo
->social_chan
[3] = 0; /* channel 0 for scanning ending in site survey function. */
3841 /* Use the channel 11 as the listen channel */
3842 pwdinfo
->listen_channel
= 11;
3844 if (role
== P2P_ROLE_DEVICE
)
3846 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_DEVICE
);
3847 rtw_p2p_set_state(pwdinfo
, P2P_STATE_LISTEN
);
3848 pwdinfo
->intent
= 1;
3849 rtw_p2p_set_pre_state(pwdinfo
, P2P_STATE_LISTEN
);
3851 else if (role
== P2P_ROLE_CLIENT
)
3853 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_CLIENT
);
3854 rtw_p2p_set_state(pwdinfo
, P2P_STATE_GONEGO_OK
);
3855 pwdinfo
->intent
= 1;
3856 rtw_p2p_set_pre_state(pwdinfo
, P2P_STATE_GONEGO_OK
);
3858 else if (role
== P2P_ROLE_GO
)
3860 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_GO
);
3861 rtw_p2p_set_state(pwdinfo
, P2P_STATE_GONEGO_OK
);
3862 pwdinfo
->intent
= 15;
3863 rtw_p2p_set_pre_state(pwdinfo
, P2P_STATE_GONEGO_OK
);
3866 /* Use the OFDM rate in the P2P probe response frame. (6(B), 9(B), 12, 18, 24, 36, 48, 54) */
3867 pwdinfo
->support_rate
[0] = 0x8c; /* 6(B) */
3868 pwdinfo
->support_rate
[1] = 0x92; /* 9(B) */
3869 pwdinfo
->support_rate
[2] = 0x18; /* 12 */
3870 pwdinfo
->support_rate
[3] = 0x24; /* 18 */
3871 pwdinfo
->support_rate
[4] = 0x30; /* 24 */
3872 pwdinfo
->support_rate
[5] = 0x48; /* 36 */
3873 pwdinfo
->support_rate
[6] = 0x60; /* 48 */
3874 pwdinfo
->support_rate
[7] = 0x6c; /* 54 */
3876 memcpy((void*) pwdinfo
->p2p_wildcard_ssid
, "DIRECT-", 7);
3878 memset(pwdinfo
->device_name
, 0x00, WPS_MAX_DEVICE_NAME_LEN
);
3879 pwdinfo
->device_name_len
= 0;
3881 memset(&pwdinfo
->invitereq_info
, 0x00, sizeof(struct tx_invite_req_info
));
3882 pwdinfo
->invitereq_info
.token
= 3; /* Token used for P2P invitation request frame. */
3884 memset(&pwdinfo
->inviteresp_info
, 0x00, sizeof(struct tx_invite_resp_info
));
3885 pwdinfo
->inviteresp_info
.token
= 0;
3887 pwdinfo
->profileindex
= 0;
3888 memset(&pwdinfo
->profileinfo
[ 0 ], 0x00, sizeof(struct profile_info
) * P2P_MAX_PERSISTENT_GROUP_NUM
);
3890 rtw_p2p_findphase_ex_set(pwdinfo
, P2P_FINDPHASE_EX_NONE
);
3892 pwdinfo
->listen_dwell
= (u8
) ((jiffies
% 3) + 1);
3893 /* DBG_8723A("[%s] listen_dwell time is %d00ms\n", __func__, pwdinfo->listen_dwell); */
3895 memset(&pwdinfo
->tx_prov_disc_info
, 0x00, sizeof(struct tx_provdisc_req_info
));
3896 pwdinfo
->tx_prov_disc_info
.wps_config_method_request
= WPS_CM_NONE
;
3898 memset(&pwdinfo
->nego_req_info
, 0x00, sizeof(struct tx_nego_req_info
));
3900 pwdinfo
->device_password_id_for_nego
= WPS_DPID_PBC
;
3901 pwdinfo
->negotiation_dialog_token
= 1;
3903 memset(pwdinfo
->nego_ssid
, 0x00, IEEE80211_MAX_SSID_LEN
);
3904 pwdinfo
->nego_ssidlen
= 0;
3906 pwdinfo
->ui_got_wps_info
= P2P_NO_WPSINFO
;
3907 #ifdef CONFIG_8723AU_P2P
3908 pwdinfo
->supported_wps_cm
= WPS_CONFIG_METHOD_DISPLAY
| WPS_CONFIG_METHOD_PBC
;
3909 pwdinfo
->wfd_info
= pwfd_info
;
3911 pwdinfo
->supported_wps_cm
= WPS_CONFIG_METHOD_DISPLAY
| WPS_CONFIG_METHOD_PBC
| WPS_CONFIG_METHOD_KEYPAD
;
3912 #endif /* CONFIG_8723AU_P2P */
3913 pwdinfo
->channel_list_attr_len
= 0;
3914 memset(pwdinfo
->channel_list_attr
, 0x00, 100);
3916 memset(pwdinfo
->rx_prov_disc_info
.strconfig_method_desc_of_prov_disc_req
, 0x00, 4);
3917 memset(pwdinfo
->rx_prov_disc_info
.strconfig_method_desc_of_prov_disc_req
, '0', 3);
3918 memset(&pwdinfo
->groupid_info
, 0x00, sizeof(struct group_id_info
));
3919 pwdinfo
->wfd_tdls_enable
= 0;
3920 memset(pwdinfo
->p2p_peer_interface_addr
, 0x00, ETH_ALEN
);
3921 memset(pwdinfo
->p2p_peer_device_addr
, 0x00, ETH_ALEN
);
3923 pwdinfo
->rx_invitereq_info
.operation_ch
[0] = 0;
3924 pwdinfo
->rx_invitereq_info
.operation_ch
[1] = 0; /* Used to indicate the scan end in site survey function */
3925 pwdinfo
->rx_invitereq_info
.scan_op_ch_only
= 0;
3926 pwdinfo
->p2p_info
.operation_ch
[0] = 0;
3927 pwdinfo
->p2p_info
.operation_ch
[1] = 0; /* Used to indicate the scan end in site survey function */
3928 pwdinfo
->p2p_info
.scan_op_ch_only
= 0;
3931 int rtw_p2p_enable23a(struct rtw_adapter
*padapter
, enum P2P_ROLE role
)
3933 struct wifidirect_info
*pwdinfo
= &padapter
->wdinfo
;
3936 if (role
== P2P_ROLE_DEVICE
|| role
== P2P_ROLE_CLIENT
||
3937 role
== P2P_ROLE_GO
) {
3938 /* leave IPS/Autosuspend */
3939 if (_FAIL
== rtw_pwr_wakeup(padapter
)) {
3944 /* Added by Albert 2011/03/22 */
3945 /* In the P2P mode, the driver should not support the b mode. */
3946 /* So, the Tx packet shouldn't use the CCK rate */
3947 update_tx_basic_rate23a(padapter
, WIRELESS_11AGN
);
3949 /* Enable P2P function */
3950 init_wifidirect_info23a(padapter
, role
);
3952 rtw_hal_set_odm_var23a(padapter
, HAL_ODM_P2P_STATE
, NULL
, true);
3953 #ifdef CONFIG_8723AU_P2P
3954 rtw_hal_set_odm_var23a(padapter
, HAL_ODM_WIFI_DISPLAY_STATE
, NULL
, true);
3958 else if (role
== P2P_ROLE_DISABLE
)
3960 if (_FAIL
== rtw_pwr_wakeup(padapter
)) {
3965 /* Disable P2P function */
3966 if (!rtw_p2p_chk_state(pwdinfo
, P2P_STATE_NONE
))
3968 del_timer_sync(&pwdinfo
->find_phase_timer
);
3969 del_timer_sync(&pwdinfo
->restore_p2p_state_timer
);
3970 del_timer_sync(&pwdinfo
->pre_tx_scan_timer
);
3971 del_timer_sync(&pwdinfo
->reset_ch_sitesurvey
);
3972 del_timer_sync(&pwdinfo
->reset_ch_sitesurvey2
);
3973 reset_ch_sitesurvey_timer_process((unsigned long)padapter
);
3974 reset_ch_sitesurvey_timer_process2((unsigned long)padapter
);
3975 rtw_p2p_set_state(pwdinfo
, P2P_STATE_NONE
);
3976 rtw_p2p_set_role(pwdinfo
, P2P_ROLE_DISABLE
);
3977 memset(&pwdinfo
->rx_prov_disc_info
, 0x00, sizeof(struct rx_provdisc_req_info
));
3980 rtw_hal_set_odm_var23a(padapter
, HAL_ODM_P2P_STATE
, NULL
, false);
3981 #ifdef CONFIG_8723AU_P2P
3982 rtw_hal_set_odm_var23a(padapter
, HAL_ODM_WIFI_DISPLAY_STATE
, NULL
, false);
3985 /* Restore to initial setting. */
3986 update_tx_basic_rate23a(padapter
, padapter
->registrypriv
.wireless_mode
);
3993 #endif /* CONFIG_8723AU_P2P */