1
2
3
4#define _RTW_P2P_C_
5
6#include "../include/drv_types.h"
7#include "../include/rtw_p2p.h"
8#include "../include/wifi.h"
9
10static int rtw_p2p_is_channel_list_ok(u8 desired_ch, u8 *ch_list, u8 ch_cnt)
11{
12 int found = 0, i = 0;
13
14 for (i = 0; i < ch_cnt; i++) {
15 if (ch_list[i] == desired_ch) {
16 found = 1;
17 break;
18 }
19 }
20 return found;
21}
22
23static u32 go_add_group_info_attr(struct wifidirect_info *pwdinfo, u8 *pbuf)
24{
25 struct list_head *phead, *plist;
26 u32 len = 0;
27 u16 attr_len = 0;
28 u8 tmplen, *pdata_attr, *pstart, *pcur;
29 struct sta_info *psta = NULL;
30 struct adapter *padapter = pwdinfo->padapter;
31 struct sta_priv *pstapriv = &padapter->stapriv;
32
33 DBG_88E("%s\n", __func__);
34
35 pdata_attr = kzalloc(MAX_P2P_IE_LEN, GFP_KERNEL);
36
37 pstart = pdata_attr;
38 pcur = pdata_attr;
39
40 spin_lock_bh(&pstapriv->asoc_list_lock);
41 phead = &pstapriv->asoc_list;
42 plist = phead->next;
43
44
45 while (phead != plist) {
46 psta = container_of(plist, struct sta_info, asoc_list);
47
48 plist = plist->next;
49
50 if (psta->is_p2p_device) {
51 tmplen = 0;
52
53 pcur++;
54
55
56 memcpy(pcur, psta->dev_addr, ETH_ALEN);
57 pcur += ETH_ALEN;
58
59
60 memcpy(pcur, psta->hwaddr, ETH_ALEN);
61 pcur += ETH_ALEN;
62
63 *pcur = psta->dev_cap;
64 pcur++;
65
66
67 RTW_PUT_BE16(pcur, psta->config_methods);
68 pcur += 2;
69
70 memcpy(pcur, psta->primary_dev_type, 8);
71 pcur += 8;
72
73 *pcur = psta->num_of_secdev_type;
74 pcur++;
75
76 memcpy(pcur, psta->secdev_types_list, psta->num_of_secdev_type * 8);
77 pcur += psta->num_of_secdev_type * 8;
78
79 if (psta->dev_name_len > 0) {
80
81 RTW_PUT_BE16(pcur, WPS_ATTR_DEVICE_NAME);
82 pcur += 2;
83
84
85 RTW_PUT_BE16(pcur, psta->dev_name_len);
86 pcur += 2;
87
88 memcpy(pcur, psta->dev_name, psta->dev_name_len);
89 pcur += psta->dev_name_len;
90 }
91
92 tmplen = (u8)(pcur - pstart);
93
94 *pstart = (tmplen - 1);
95
96 attr_len += tmplen;
97
98
99 pstart = pcur;
100 }
101 }
102 spin_unlock_bh(&pstapriv->asoc_list_lock);
103
104 if (attr_len > 0)
105 len = rtw_set_p2p_attr_content(pbuf, P2P_ATTR_GROUP_INFO, attr_len, pdata_attr);
106
107 kfree(pdata_attr);
108 return len;
109}
110
111static void issue_group_disc_req(struct wifidirect_info *pwdinfo, u8 *da)
112{
113 struct xmit_frame *pmgntframe;
114 struct pkt_attrib *pattrib;
115 unsigned char *pframe;
116 struct rtw_ieee80211_hdr *pwlanhdr;
117 __le16 *fctrl;
118 struct adapter *padapter = pwdinfo->padapter;
119 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
120 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
121 unsigned char category = RTW_WLAN_CATEGORY_P2P;
122 __be32 p2poui = cpu_to_be32(P2POUI);
123 u8 oui_subtype = P2P_GO_DISC_REQUEST;
124 u8 dialogToken = 0;
125
126 DBG_88E("[%s]\n", __func__);
127
128 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
129 if (!pmgntframe)
130 return;
131
132
133 pattrib = &pmgntframe->attrib;
134 update_mgntframe_attrib(padapter, pattrib);
135
136 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
137
138 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
139 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
140
141 fctrl = &pwlanhdr->frame_ctl;
142 *(fctrl) = 0;
143
144 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
145 memcpy(pwlanhdr->addr2, pwdinfo->interface_addr, ETH_ALEN);
146 memcpy(pwlanhdr->addr3, pwdinfo->interface_addr, ETH_ALEN);
147
148 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
149 pmlmeext->mgnt_seq++;
150 SetFrameSubType(pframe, WIFI_ACTION);
151
152 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
153 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
154
155
156 pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
157 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
158 pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen);
159 pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen);
160
161
162
163 pattrib->last_txcmdsz = pattrib->pktlen;
164
165 dump_mgntframe(padapter, pmgntframe);
166}
167
168static void issue_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 status, u8 dialogToken)
169{
170 struct xmit_frame *pmgntframe;
171 struct pkt_attrib *pattrib;
172 unsigned char *pframe;
173 struct rtw_ieee80211_hdr *pwlanhdr;
174 __le16 *fctrl;
175 struct adapter *padapter = pwdinfo->padapter;
176 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
177 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
178 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
179 u8 action = P2P_PUB_ACTION_ACTION;
180 __be32 p2poui = cpu_to_be32(P2POUI);
181 u8 oui_subtype = P2P_DEVDISC_RESP;
182 u8 p2pie[8] = { 0x00 };
183 u32 p2pielen = 0;
184
185 DBG_88E("[%s]\n", __func__);
186
187 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
188 if (!pmgntframe)
189 return;
190
191
192 pattrib = &pmgntframe->attrib;
193 update_mgntframe_attrib(padapter, pattrib);
194
195 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
196
197 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
198 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
199
200 fctrl = &pwlanhdr->frame_ctl;
201 *(fctrl) = 0;
202
203 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
204 memcpy(pwlanhdr->addr2, pwdinfo->device_addr, ETH_ALEN);
205 memcpy(pwlanhdr->addr3, pwdinfo->device_addr, ETH_ALEN);
206
207 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
208 pmlmeext->mgnt_seq++;
209 SetFrameSubType(pframe, WIFI_ACTION);
210
211 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
212 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
213
214
215 pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
216 pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
217 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
218 pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen);
219 pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen);
220
221
222
223 p2pielen = 0;
224 p2pie[p2pielen++] = 0x50;
225 p2pie[p2pielen++] = 0x6F;
226 p2pie[p2pielen++] = 0x9A;
227 p2pie[p2pielen++] = 0x09;
228
229
230 p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status);
231
232 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, p2pie, &pattrib->pktlen);
233
234 pattrib->last_txcmdsz = pattrib->pktlen;
235
236 dump_mgntframe(padapter, pmgntframe);
237}
238
239static void issue_p2p_provision_resp(struct wifidirect_info *pwdinfo, u8 *raddr, u8 *frame_body, u16 config_method)
240{
241 struct adapter *padapter = pwdinfo->padapter;
242 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
243 u8 action = P2P_PUB_ACTION_ACTION;
244 u8 dialogToken = frame_body[7];
245 __be32 p2poui = cpu_to_be32(P2POUI);
246 u8 oui_subtype = P2P_PROVISION_DISC_RESP;
247 u8 wpsie[100] = { 0x00 };
248 u8 wpsielen = 0;
249 struct xmit_frame *pmgntframe;
250 struct pkt_attrib *pattrib;
251 unsigned char *pframe;
252 struct rtw_ieee80211_hdr *pwlanhdr;
253 __le16 *fctrl;
254 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
255 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
256
257 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
258 if (!pmgntframe)
259 return;
260
261
262 pattrib = &pmgntframe->attrib;
263 update_mgntframe_attrib(padapter, pattrib);
264
265 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
266
267 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
268 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
269
270 fctrl = &pwlanhdr->frame_ctl;
271 *(fctrl) = 0;
272
273 memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
274 memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
275 memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN);
276
277 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
278 pmlmeext->mgnt_seq++;
279 SetFrameSubType(pframe, WIFI_ACTION);
280
281 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
282 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
283
284 pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
285 pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
286 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
287 pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen);
288 pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen);
289
290 wpsielen = 0;
291
292 RTW_PUT_BE32(wpsie, WPSOUI);
293 wpsielen += 4;
294
295
296
297 RTW_PUT_BE16(wpsie + wpsielen, WPS_ATTR_CONF_METHOD);
298 wpsielen += 2;
299
300
301 RTW_PUT_BE16(wpsie + wpsielen, 0x0002);
302 wpsielen += 2;
303
304
305 RTW_PUT_BE16(wpsie + wpsielen, config_method);
306 wpsielen += 2;
307
308 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *)wpsie, &pattrib->pktlen);
309
310 pattrib->last_txcmdsz = pattrib->pktlen;
311
312 dump_mgntframe(padapter, pmgntframe);
313}
314
315static void issue_p2p_presence_resp(struct wifidirect_info *pwdinfo, u8 *da, u8 status, u8 dialogToken)
316{
317 struct xmit_frame *pmgntframe;
318 struct pkt_attrib *pattrib;
319 unsigned char *pframe;
320 struct rtw_ieee80211_hdr *pwlanhdr;
321 __le16 *fctrl;
322 struct adapter *padapter = pwdinfo->padapter;
323 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
324 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
325 unsigned char category = RTW_WLAN_CATEGORY_P2P;
326 __be32 p2poui = cpu_to_be32(P2POUI);
327 u8 oui_subtype = P2P_PRESENCE_RESPONSE;
328 u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 };
329 u8 noa_attr_content[32] = { 0x00 };
330 u32 p2pielen = 0;
331
332 DBG_88E("[%s]\n", __func__);
333
334 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
335 if (!pmgntframe)
336 return;
337
338
339 pattrib = &pmgntframe->attrib;
340 update_mgntframe_attrib(padapter, pattrib);
341
342 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
343
344 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
345 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
346
347 fctrl = &pwlanhdr->frame_ctl;
348 *(fctrl) = 0;
349
350 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
351 memcpy(pwlanhdr->addr2, pwdinfo->interface_addr, ETH_ALEN);
352 memcpy(pwlanhdr->addr3, pwdinfo->interface_addr, ETH_ALEN);
353
354 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
355 pmlmeext->mgnt_seq++;
356 SetFrameSubType(pframe, WIFI_ACTION);
357
358 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
359 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
360
361
362 pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
363 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&p2poui, &pattrib->pktlen);
364 pframe = rtw_set_fixed_ie(pframe, 1, &oui_subtype, &pattrib->pktlen);
365 pframe = rtw_set_fixed_ie(pframe, 1, &dialogToken, &pattrib->pktlen);
366
367
368
369 p2pielen = 0;
370 p2pie[p2pielen++] = 0x50;
371 p2pie[p2pielen++] = 0x6F;
372 p2pie[p2pielen++] = 0x9A;
373 p2pie[p2pielen++] = 0x09;
374
375
376 p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status);
377
378
379 noa_attr_content[0] = 0x1;
380 noa_attr_content[1] = 0x0;
381
382
383
384 p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_NOA, 2, noa_attr_content);
385
386 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, p2pie, &pattrib->pktlen);
387
388 pattrib->last_txcmdsz = pattrib->pktlen;
389
390 dump_mgntframe(padapter, pmgntframe);
391}
392
393u32 build_beacon_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
394{
395 u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 };
396 u16 capability = 0;
397 u32 len = 0, p2pielen = 0;
398 __le16 le_tmp;
399
400
401 p2pielen = 0;
402 p2pie[p2pielen++] = 0x50;
403 p2pie[p2pielen++] = 0x6F;
404 p2pie[p2pielen++] = 0x9A;
405 p2pie[p2pielen++] = 0x09;
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420 capability = P2P_DEVCAP_INVITATION_PROC | P2P_DEVCAP_CLIENT_DISCOVERABILITY;
421 capability |= ((P2P_GRPCAP_GO | P2P_GRPCAP_INTRABSS) << 8);
422 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
423 capability |= (P2P_GRPCAP_GROUP_FORMATION << 8);
424
425 le_tmp = cpu_to_le16(capability);
426 p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_CAPABILITY, 2, (u8 *)&le_tmp);
427
428
429 p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_DEVICE_ID, ETH_ALEN, pwdinfo->device_addr);
430
431
432
433
434
435
436 pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &len);
437 return len;
438}
439
440u32 build_probe_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
441{
442 u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 };
443 u32 len = 0, p2pielen = 0;
444
445
446 p2pielen = 0;
447 p2pie[p2pielen++] = 0x50;
448 p2pie[p2pielen++] = 0x6F;
449 p2pie[p2pielen++] = 0x9A;
450 p2pie[p2pielen++] = 0x09;
451
452
453
454
455
456
457
458
459
460
461
462 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
463
464
465
466 RTW_PUT_LE16(p2pie + p2pielen, 0x0002);
467 p2pielen += 2;
468
469
470
471 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
472
473
474 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
475 p2pie[p2pielen] = (P2P_GRPCAP_GO | P2P_GRPCAP_INTRABSS);
476
477 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
478 p2pie[p2pielen] |= P2P_GRPCAP_GROUP_FORMATION;
479
480 p2pielen++;
481 } else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) {
482
483 if (pwdinfo->persistent_supported)
484 p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
485 else
486 p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT;
487 }
488
489
490
491 p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
492
493
494
495 RTW_PUT_LE16(p2pie + p2pielen, 0x0004);
496 p2pielen += 2;
497
498
499
500
501 RTW_PUT_LE16(p2pie + p2pielen, 0xFFFF);
502 p2pielen += 2;
503
504
505
506 RTW_PUT_LE16(p2pie + p2pielen, 0xFFFF);
507 p2pielen += 2;
508
509
510
511
512
513
514
515
516 p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
517
518
519
520
521
522 RTW_PUT_LE16(p2pie + p2pielen, 21 + pwdinfo->device_name_len);
523 p2pielen += 2;
524
525
526
527 memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN);
528 p2pielen += ETH_ALEN;
529
530
531
532
533 RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->supported_wps_cm);
534 p2pielen += 2;
535
536
537
538
539 RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_MULIT_MEDIA);
540 p2pielen += 2;
541
542
543
544 RTW_PUT_BE32(p2pie + p2pielen, WPSOUI);
545 p2pielen += 4;
546
547
548
549 RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_SCID_MEDIA_SERVER);
550 p2pielen += 2;
551
552
553 p2pie[p2pielen++] = 0x00;
554
555
556
557
558 RTW_PUT_BE16(p2pie + p2pielen, WPS_ATTR_DEVICE_NAME);
559 p2pielen += 2;
560
561
562
563 RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->device_name_len);
564 p2pielen += 2;
565
566
567 memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
568 p2pielen += pwdinfo->device_name_len;
569
570
571
572
573
574 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
575 p2pielen += go_add_group_info_attr(pwdinfo, p2pie + p2pielen);
576
577 pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &len);
578
579 return len;
580}
581
582u32 build_prov_disc_request_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 *pssid, u8 ussidlen, u8 *pdev_raddr)
583{
584 u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 };
585 u32 len = 0, p2pielen = 0;
586
587
588 p2pielen = 0;
589 p2pie[p2pielen++] = 0x50;
590 p2pie[p2pielen++] = 0x6F;
591 p2pie[p2pielen++] = 0x9A;
592 p2pie[p2pielen++] = 0x09;
593
594
595
596
597
598
599
600
601
602 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
603
604
605
606 RTW_PUT_LE16(p2pie + p2pielen, 0x0002);
607 p2pielen += 2;
608
609
610
611 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
612
613
614 if (pwdinfo->persistent_supported)
615 p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
616 else
617 p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT;
618
619
620
621 p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
622
623
624
625
626
627 RTW_PUT_LE16(p2pie + p2pielen, 21 + pwdinfo->device_name_len);
628 p2pielen += 2;
629
630
631
632 memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN);
633 p2pielen += ETH_ALEN;
634
635
636
637 if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC) {
638
639 RTW_PUT_BE16(p2pie + p2pielen, WPS_CONFIG_METHOD_PBC);
640 } else {
641
642 RTW_PUT_BE16(p2pie + p2pielen, WPS_CONFIG_METHOD_DISPLAY);
643 }
644
645 p2pielen += 2;
646
647
648
649
650 RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_MULIT_MEDIA);
651 p2pielen += 2;
652
653
654
655 RTW_PUT_BE32(p2pie + p2pielen, WPSOUI);
656 p2pielen += 4;
657
658
659
660 RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_SCID_MEDIA_SERVER);
661 p2pielen += 2;
662
663
664 p2pie[p2pielen++] = 0x00;
665
666
667
668
669 RTW_PUT_BE16(p2pie + p2pielen, WPS_ATTR_DEVICE_NAME);
670 p2pielen += 2;
671
672
673
674 RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->device_name_len);
675 p2pielen += 2;
676
677
678 memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
679 p2pielen += pwdinfo->device_name_len;
680
681 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
682
683
684
685
686
687 p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
688
689
690
691 RTW_PUT_LE16(p2pie + p2pielen, ETH_ALEN + ussidlen);
692 p2pielen += 2;
693
694
695 memcpy(p2pie + p2pielen, pdev_raddr, ETH_ALEN);
696 p2pielen += ETH_ALEN;
697
698 memcpy(p2pie + p2pielen, pssid, ussidlen);
699 p2pielen += ussidlen;
700 }
701
702 pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &len);
703
704 return len;
705}
706
707u32 build_assoc_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf, u8 status_code)
708{
709 u8 p2pie[MAX_P2P_IE_LEN] = { 0x00 };
710 u32 len = 0, p2pielen = 0;
711
712
713 p2pielen = 0;
714 p2pie[p2pielen++] = 0x50;
715 p2pie[p2pielen++] = 0x6F;
716 p2pie[p2pielen++] = 0x9A;
717 p2pie[p2pielen++] = 0x09;
718
719
720
721
722
723
724 p2pielen += rtw_set_p2p_attr_content(&p2pie[p2pielen], P2P_ATTR_STATUS, 1, &status_code);
725
726
727
728
729
730
731 pbuf = rtw_set_ie(pbuf, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *)p2pie, &len);
732
733 return len;
734}
735
736u32 process_probe_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
737{
738 u8 *p;
739 u32 ret = false;
740 u8 *p2pie;
741 u32 p2pielen = 0;
742 int ssid_len = 0, rate_cnt = 0;
743
744 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SUPPORTEDRATES_IE_, (int *)&rate_cnt,
745 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
746
747 if (rate_cnt <= 4) {
748 int i, g_rate = 0;
749
750 for (i = 0; i < rate_cnt; i++) {
751 if (((*(p + 2 + i) & 0xff) != 0x02) &&
752 ((*(p + 2 + i) & 0xff) != 0x04) &&
753 ((*(p + 2 + i) & 0xff) != 0x0B) &&
754 ((*(p + 2 + i) & 0xff) != 0x16))
755 g_rate = 1;
756 }
757
758 if (g_rate == 0) {
759
760
761 return ret;
762 }
763 } else {
764
765
766 }
767
768
769
770
771
772
773
774
775
776
777 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ssid_len,
778 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
779
780 ssid_len &= 0xff;
781 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
782 p2pie = rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_, NULL, &p2pielen);
783 if (p2pie) {
784 if (p && !memcmp((void *)(p + 2), (void *)pwdinfo->p2p_wildcard_ssid, 7)) {
785
786
787
788
789 ret = true;
790 } else if (p && ssid_len == 0) {
791 ret = true;
792 }
793 } else {
794
795 }
796 }
797
798 return ret;
799}
800
801u32 process_assoc_req_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pframe, uint len, struct sta_info *psta)
802{
803 u8 status_code = P2P_STATUS_SUCCESS;
804 u8 *pbuf, *pattr_content = NULL;
805 u32 attr_contentlen = 0;
806 u16 cap_attr = 0;
807 unsigned short frame_type, ie_offset = 0;
808 u8 *ies;
809 u32 ies_len;
810 u8 *p2p_ie;
811 u32 p2p_ielen = 0;
812 __be16 be_tmp;
813 __le16 le_tmp;
814
815 if (!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
816 return P2P_STATUS_FAIL_REQUEST_UNABLE;
817
818 frame_type = GetFrameSubType(pframe);
819 if (frame_type == WIFI_ASSOCREQ)
820 ie_offset = _ASOCREQ_IE_OFFSET_;
821 else
822 ie_offset = _REASOCREQ_IE_OFFSET_;
823
824 ies = pframe + WLAN_HDR_A3_LEN + ie_offset;
825 ies_len = len - WLAN_HDR_A3_LEN - ie_offset;
826
827 p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen);
828
829 if (!p2p_ie) {
830 DBG_88E("[%s] P2P IE not Found!!\n", __func__);
831 status_code = P2P_STATUS_FAIL_INVALID_PARAM;
832 } else {
833 DBG_88E("[%s] P2P IE Found!!\n", __func__);
834 }
835
836 while (p2p_ie) {
837
838 if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8 *)&le_tmp, (uint *)&attr_contentlen)) {
839 DBG_88E("[%s] Got P2P Capability Attr!!\n", __func__);
840 cap_attr = le16_to_cpu(le_tmp);
841 psta->dev_cap = cap_attr & 0xff;
842 }
843
844
845
846
847 if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, NULL, (uint *)&attr_contentlen)) {
848 DBG_88E("[%s] Got P2P DEVICE INFO Attr!!\n", __func__);
849 pattr_content = kzalloc(attr_contentlen, GFP_KERNEL);
850 pbuf = pattr_content;
851 if (pattr_content) {
852 u8 num_of_secdev_type;
853 u16 dev_name_len;
854
855 rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, pattr_content, (uint *)&attr_contentlen);
856
857 memcpy(psta->dev_addr, pattr_content, ETH_ALEN);
858
859 pattr_content += ETH_ALEN;
860
861 memcpy(&be_tmp, pattr_content, 2);
862 psta->config_methods = be16_to_cpu(be_tmp);
863
864 pattr_content += 2;
865
866 memcpy(psta->primary_dev_type, pattr_content, 8);
867
868 pattr_content += 8;
869
870 num_of_secdev_type = *pattr_content;
871 pattr_content += 1;
872
873 if (num_of_secdev_type == 0) {
874 psta->num_of_secdev_type = 0;
875 } else {
876 u32 len;
877
878 psta->num_of_secdev_type = num_of_secdev_type;
879
880 len = (sizeof(psta->secdev_types_list) < (num_of_secdev_type * 8)) ?
881 (sizeof(psta->secdev_types_list)) : (num_of_secdev_type * 8);
882
883 memcpy(psta->secdev_types_list, pattr_content, len);
884
885 pattr_content += (num_of_secdev_type * 8);
886 }
887
888 psta->dev_name_len = 0;
889 if (WPS_ATTR_DEVICE_NAME == be16_to_cpu(*(__be16 *)pattr_content)) {
890 dev_name_len = be16_to_cpu(*(__be16 *)(pattr_content + 2));
891
892 psta->dev_name_len = (sizeof(psta->dev_name) < dev_name_len) ? sizeof(psta->dev_name) : dev_name_len;
893
894 memcpy(psta->dev_name, pattr_content + 4, psta->dev_name_len);
895 }
896 kfree(pbuf);
897 }
898 }
899
900
901 p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen);
902 }
903
904 return status_code;
905}
906
907u32 process_p2p_devdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
908{
909 u8 *frame_body;
910 u8 status, dialogToken;
911 struct sta_info *psta = NULL;
912 struct adapter *padapter = pwdinfo->padapter;
913 struct sta_priv *pstapriv = &padapter->stapriv;
914 u8 *p2p_ie;
915 u32 p2p_ielen = 0;
916
917 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
918
919 dialogToken = frame_body[7];
920 status = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
921
922 p2p_ie = rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen);
923 if (p2p_ie) {
924 u8 groupid[38] = { 0x00 };
925 u8 dev_addr[ETH_ALEN] = { 0x00 };
926 u32 attr_contentlen = 0;
927
928 if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen)) {
929 if (!memcmp(pwdinfo->device_addr, groupid, ETH_ALEN) &&
930 !memcmp(pwdinfo->p2p_group_ssid, groupid + ETH_ALEN, pwdinfo->p2p_group_ssid_len)) {
931 attr_contentlen = 0;
932 if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_ID, dev_addr, &attr_contentlen)) {
933 struct list_head *phead, *plist;
934
935 spin_lock_bh(&pstapriv->asoc_list_lock);
936 phead = &pstapriv->asoc_list;
937 plist = phead->next;
938
939
940 while (phead != plist) {
941 psta = container_of(plist, struct sta_info, asoc_list);
942
943 plist = plist->next;
944
945 if (psta->is_p2p_device && (psta->dev_cap & P2P_DEVCAP_CLIENT_DISCOVERABILITY) &&
946 !memcmp(psta->dev_addr, dev_addr, ETH_ALEN)) {
947
948 issue_group_disc_req(pwdinfo, psta->hwaddr);
949 status = P2P_STATUS_SUCCESS;
950 break;
951 } else {
952 status = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
953 }
954 }
955 spin_unlock_bh(&pstapriv->asoc_list_lock);
956 } else {
957 status = P2P_STATUS_FAIL_INVALID_PARAM;
958 }
959 } else {
960 status = P2P_STATUS_FAIL_INVALID_PARAM;
961 }
962 }
963 }
964
965
966 issue_p2p_devdisc_resp(pwdinfo, GetAddr2Ptr(pframe), status, dialogToken);
967
968 return (status == P2P_STATUS_SUCCESS) ? true : false;
969}
970
971u32 process_p2p_devdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
972{
973 return true;
974}
975
976u8 process_p2p_provdisc_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
977{
978 u8 *frame_body;
979 u8 *wpsie;
980 uint wps_ielen = 0, attr_contentlen = 0;
981 u16 uconfig_method = 0;
982 __be16 be_tmp;
983
984 frame_body = (pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
985
986 wpsie = rtw_get_wps_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &wps_ielen);
987 if (wpsie) {
988 if (rtw_get_wps_attr_content(wpsie, wps_ielen, WPS_ATTR_CONF_METHOD, (u8 *)&be_tmp, &attr_contentlen)) {
989 uconfig_method = be16_to_cpu(be_tmp);
990 switch (uconfig_method) {
991 case WPS_CM_DISPLYA:
992 memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3);
993 break;
994 case WPS_CM_LABEL:
995 memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "lab", 3);
996 break;
997 case WPS_CM_PUSH_BUTTON:
998 memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3);
999 break;
1000 case WPS_CM_KEYPAD:
1001 memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3);
1002 break;
1003 }
1004 issue_p2p_provision_resp(pwdinfo, GetAddr2Ptr(pframe), frame_body, uconfig_method);
1005 }
1006 }
1007 DBG_88E("[%s] config method = %s\n", __func__, pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req);
1008 return true;
1009}
1010
1011u8 process_p2p_provdisc_resp(struct wifidirect_info *pwdinfo, u8 *pframe)
1012{
1013 return true;
1014}
1015
1016static u8 rtw_p2p_get_peer_ch_list(struct wifidirect_info *pwdinfo, u8 *ch_content, u8 ch_cnt, u8 *peer_ch_list)
1017{
1018 u8 i = 0, j = 0;
1019 u8 temp = 0;
1020 u8 ch_no = 0;
1021 ch_content += 3;
1022 ch_cnt -= 3;
1023
1024 while (ch_cnt > 0) {
1025 ch_content += 1;
1026 ch_cnt -= 1;
1027 temp = *ch_content;
1028 for (i = 0 ; i < temp ; i++, j++)
1029 peer_ch_list[j] = *(ch_content + 1 + i);
1030 ch_content += (temp + 1);
1031 ch_cnt -= (temp + 1);
1032 ch_no += temp;
1033 }
1034
1035 return ch_no;
1036}
1037
1038static u8 rtw_p2p_ch_inclusion(struct mlme_ext_priv *pmlmeext, u8 *peer_ch_list, u8 peer_ch_num, u8 *ch_list_inclusioned)
1039{
1040 int i = 0, j = 0, temp = 0;
1041 u8 ch_no = 0;
1042
1043 for (i = 0; i < peer_ch_num; i++) {
1044 for (j = temp; j < pmlmeext->max_chan_nums; j++) {
1045 if (*(peer_ch_list + i) == pmlmeext->channel_set[j].ChannelNum) {
1046 ch_list_inclusioned[ch_no++] = *(peer_ch_list + i);
1047 temp = j;
1048 break;
1049 }
1050 }
1051 }
1052
1053 return ch_no;
1054}
1055
1056u8 process_p2p_group_negotation_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
1057{
1058 struct adapter *padapter = pwdinfo->padapter;
1059 u8 result = P2P_STATUS_SUCCESS;
1060 u32 p2p_ielen = 0, wps_ielen = 0;
1061 u8 *ies;
1062 u32 ies_len;
1063 u8 *p2p_ie;
1064 u8 *wpsie;
1065 u16 wps_devicepassword_id = 0x0000;
1066 uint wps_devicepassword_id_len = 0;
1067 __be16 be_tmp;
1068
1069 wpsie = rtw_get_wps_ie(pframe + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &wps_ielen);
1070 if (wpsie) {
1071
1072
1073
1074 if (!memcmp(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3)) {
1075 rtw_get_wps_attr_content(wpsie, wps_ielen, WPS_ATTR_DEVICE_PWID, (u8 *)&be_tmp, &wps_devicepassword_id_len);
1076 wps_devicepassword_id = be16_to_cpu(be_tmp);
1077
1078 if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
1079 memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3);
1080 else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
1081 memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3);
1082 else
1083 memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3);
1084 }
1085 } else {
1086 DBG_88E("[%s] WPS IE not Found!!\n", __func__);
1087 result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
1088 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
1089 return result;
1090 }
1091
1092 if (pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO) {
1093 result = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
1094 rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INFOR_NOREADY);
1095 return result;
1096 }
1097
1098 ies = pframe + _PUBLIC_ACTION_IE_OFFSET_;
1099 ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
1100
1101 p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen);
1102
1103 if (!p2p_ie) {
1104 DBG_88E("[%s] P2P IE not Found!!\n", __func__);
1105 result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
1106 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
1107 }
1108
1109 while (p2p_ie) {
1110 u8 attr_content = 0x00;
1111 u32 attr_contentlen = 0;
1112 u8 ch_content[50] = { 0x00 };
1113 uint ch_cnt = 0;
1114 u8 peer_ch_list[50] = { 0x00 };
1115 u8 peer_ch_num = 0;
1116 u8 ch_list_inclusioned[50] = { 0x00 };
1117 u8 ch_num_inclusioned = 0;
1118
1119 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING);
1120
1121 if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT, &attr_content, &attr_contentlen)) {
1122 DBG_88E("[%s] GO Intent = %d, tie = %d\n", __func__, attr_content >> 1, attr_content & 0x01);
1123 pwdinfo->peer_intent = attr_content;
1124
1125 if (pwdinfo->intent == (pwdinfo->peer_intent >> 1)) {
1126
1127 if (pwdinfo->intent == P2P_MAX_INTENT) {
1128 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
1129 result = P2P_STATUS_FAIL_BOTH_GOINTENT_15;
1130 } else {
1131 if (attr_content & 0x01)
1132 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
1133 else
1134 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
1135 }
1136 } else if (pwdinfo->intent > (pwdinfo->peer_intent >> 1)) {
1137 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
1138 } else {
1139 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
1140 }
1141
1142 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
1143
1144 memcpy(pwdinfo->groupid_info.go_device_addr, pwdinfo->device_addr, ETH_ALEN);
1145 memcpy(pwdinfo->groupid_info.ssid, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
1146 }
1147 }
1148
1149 attr_contentlen = 0;
1150 if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_INTENTED_IF_ADDR, pwdinfo->p2p_peer_interface_addr, &attr_contentlen)) {
1151 if (attr_contentlen != ETH_ALEN)
1152 memset(pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN);
1153 }
1154
1155 if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, ch_content, &ch_cnt)) {
1156 peer_ch_num = rtw_p2p_get_peer_ch_list(pwdinfo, ch_content, ch_cnt, peer_ch_list);
1157 ch_num_inclusioned = rtw_p2p_ch_inclusion(&padapter->mlmeextpriv, peer_ch_list, peer_ch_num, ch_list_inclusioned);
1158
1159 if (ch_num_inclusioned == 0) {
1160 DBG_88E("[%s] No common channel in channel list!\n", __func__);
1161 result = P2P_STATUS_FAIL_NO_COMMON_CH;
1162 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
1163 break;
1164 }
1165
1166 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
1167 if (!rtw_p2p_is_channel_list_ok(pwdinfo->operating_channel,
1168 ch_list_inclusioned, ch_num_inclusioned)) {
1169 u8 operatingch_info[5] = { 0x00 }, peer_operating_ch = 0;
1170 attr_contentlen = 0;
1171
1172 if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen))
1173 peer_operating_ch = operatingch_info[4];
1174
1175 if (rtw_p2p_is_channel_list_ok(peer_operating_ch,
1176 ch_list_inclusioned, ch_num_inclusioned)) {
1177
1178
1179
1180 pwdinfo->operating_channel = peer_operating_ch;
1181 DBG_88E("[%s] Change op ch to %02x as peer's\n", __func__, pwdinfo->operating_channel);
1182 } else {
1183
1184 pwdinfo->operating_channel = ch_list_inclusioned[0];
1185 DBG_88E("[%s] Change op ch to %02x\n", __func__, pwdinfo->operating_channel);
1186 }
1187 }
1188 }
1189 }
1190
1191
1192 p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen);
1193 }
1194 return result;
1195}
1196
1197u8 process_p2p_group_negotation_resp(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
1198{
1199 struct adapter *padapter = pwdinfo->padapter;
1200 u8 result = P2P_STATUS_SUCCESS;
1201 u32 p2p_ielen, wps_ielen;
1202 u8 *ies;
1203 u32 ies_len;
1204 u8 *p2p_ie;
1205
1206 ies = pframe + _PUBLIC_ACTION_IE_OFFSET_;
1207 ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
1208
1209
1210
1211 if (rtw_get_wps_ie(ies, ies_len, NULL, &wps_ielen)) {
1212 } else {
1213 DBG_88E("[%s] WPS IE not Found!!\n", __func__);
1214 result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
1215 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
1216 }
1217
1218 p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen);
1219 if (!p2p_ie) {
1220 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
1221 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
1222 result = P2P_STATUS_FAIL_INCOMPATIBLE_PARAM;
1223 } else {
1224 u8 attr_content = 0x00;
1225 u32 attr_contentlen = 0;
1226 u8 operatingch_info[5] = { 0x00 };
1227 u8 groupid[38];
1228 u8 peer_ch_list[50] = { 0x00 };
1229 u8 peer_ch_num = 0;
1230 u8 ch_list_inclusioned[50] = { 0x00 };
1231 u8 ch_num_inclusioned = 0;
1232
1233 while (p2p_ie) {
1234 rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
1235 if (attr_contentlen == 1) {
1236 DBG_88E("[%s] Status = %d\n", __func__, attr_content);
1237 if (attr_content == P2P_STATUS_SUCCESS) {
1238
1239 } else {
1240 if (P2P_STATUS_FAIL_INFO_UNAVAILABLE == attr_content) {
1241 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INFOR_NOREADY);
1242 } else {
1243 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
1244 }
1245 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
1246 result = attr_content;
1247 break;
1248 }
1249 }
1250
1251
1252 attr_contentlen = 0;
1253 if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_INTENTED_IF_ADDR, pwdinfo->p2p_peer_interface_addr, &attr_contentlen)) {
1254 if (attr_contentlen != ETH_ALEN)
1255 memset(pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN);
1256 }
1257
1258
1259 attr_content = 0x00;
1260 attr_contentlen = 0;
1261 if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT, &attr_content, &attr_contentlen)) {
1262 DBG_88E("[%s] GO Intent = %d, tie = %d\n", __func__, attr_content >> 1, attr_content & 0x01);
1263 pwdinfo->peer_intent = attr_content;
1264
1265 if (pwdinfo->intent == (pwdinfo->peer_intent >> 1)) {
1266
1267 if (pwdinfo->intent == P2P_MAX_INTENT) {
1268 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
1269 result = P2P_STATUS_FAIL_BOTH_GOINTENT_15;
1270 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
1271 } else {
1272 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
1273 rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
1274 if (attr_content & 0x01)
1275 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
1276 else
1277 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
1278 }
1279 } else if (pwdinfo->intent > (pwdinfo->peer_intent >> 1)) {
1280 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
1281 rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
1282 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
1283 } else {
1284 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
1285 rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
1286 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
1287 }
1288
1289 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
1290
1291 memcpy(pwdinfo->groupid_info.go_device_addr, pwdinfo->device_addr, ETH_ALEN);
1292 memcpy(pwdinfo->groupid_info.ssid, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
1293 }
1294 }
1295
1296
1297
1298 attr_contentlen = 0;
1299 if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen)) {
1300 DBG_88E("[%s] Peer's operating channel = %d\n", __func__, operatingch_info[4]);
1301 pwdinfo->peer_operating_ch = operatingch_info[4];
1302 }
1303
1304
1305 if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, pwdinfo->channel_list_attr, &pwdinfo->channel_list_attr_len)) {
1306 DBG_88E("[%s] channel list attribute found, len = %d\n", __func__, pwdinfo->channel_list_attr_len);
1307
1308 peer_ch_num = rtw_p2p_get_peer_ch_list(pwdinfo, pwdinfo->channel_list_attr, pwdinfo->channel_list_attr_len, peer_ch_list);
1309 ch_num_inclusioned = rtw_p2p_ch_inclusion(&padapter->mlmeextpriv, peer_ch_list, peer_ch_num, ch_list_inclusioned);
1310
1311 if (ch_num_inclusioned == 0) {
1312 DBG_88E("[%s] No common channel in channel list!\n", __func__);
1313 result = P2P_STATUS_FAIL_NO_COMMON_CH;
1314 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
1315 break;
1316 }
1317
1318 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
1319 if (!rtw_p2p_is_channel_list_ok(pwdinfo->operating_channel,
1320 ch_list_inclusioned, ch_num_inclusioned)) {
1321 u8 operatingch_info[5] = { 0x00 }, peer_operating_ch = 0;
1322 attr_contentlen = 0;
1323
1324 if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen))
1325 peer_operating_ch = operatingch_info[4];
1326
1327 if (rtw_p2p_is_channel_list_ok(peer_operating_ch,
1328 ch_list_inclusioned, ch_num_inclusioned)) {
1329
1330
1331
1332 pwdinfo->operating_channel = peer_operating_ch;
1333 DBG_88E("[%s] Change op ch to %02x as peer's\n", __func__, pwdinfo->operating_channel);
1334 } else {
1335
1336 pwdinfo->operating_channel = ch_list_inclusioned[0];
1337 DBG_88E("[%s] Change op ch to %02x\n", __func__, pwdinfo->operating_channel);
1338 }
1339 }
1340 }
1341 } else {
1342 DBG_88E("[%s] channel list attribute not found!\n", __func__);
1343 }
1344
1345
1346 attr_contentlen = 0;
1347 memset(groupid, 0x00, 38);
1348 if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen)) {
1349 memcpy(pwdinfo->groupid_info.go_device_addr, &groupid[0], ETH_ALEN);
1350 memcpy(pwdinfo->groupid_info.ssid, &groupid[6], attr_contentlen - ETH_ALEN);
1351 }
1352
1353
1354 p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen);
1355 }
1356 }
1357 return result;
1358}
1359
1360u8 process_p2p_group_negotation_confirm(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
1361{
1362 u8 *ies;
1363 u32 ies_len;
1364 u8 *p2p_ie;
1365 u32 p2p_ielen = 0;
1366 u8 result = P2P_STATUS_SUCCESS;
1367 ies = pframe + _PUBLIC_ACTION_IE_OFFSET_;
1368 ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
1369
1370 p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen);
1371 while (p2p_ie) {
1372 u8 attr_content = 0x00, operatingch_info[5] = { 0x00 };
1373 u8 groupid[38] = { 0x00 };
1374 u32 attr_contentlen = 0;
1375
1376 pwdinfo->negotiation_dialog_token = 1;
1377 rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
1378 if (attr_contentlen == 1) {
1379 DBG_88E("[%s] Status = %d\n", __func__, attr_content);
1380 result = attr_content;
1381
1382 if (attr_content == P2P_STATUS_SUCCESS) {
1383 u8 bcancelled = 0;
1384
1385 _cancel_timer(&pwdinfo->restore_p2p_state_timer, &bcancelled);
1386
1387
1388
1389 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
1390 rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
1391 if ((pwdinfo->intent) > (pwdinfo->peer_intent >> 1)) {
1392 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
1393 } else if ((pwdinfo->intent) < (pwdinfo->peer_intent >> 1)) {
1394 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
1395 } else {
1396
1397 if (pwdinfo->peer_intent & 0x01)
1398 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
1399 else
1400 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
1401 }
1402 } else {
1403 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
1404 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_FAIL);
1405 break;
1406 }
1407 }
1408
1409
1410 attr_contentlen = 0;
1411 memset(groupid, 0x00, 38);
1412 if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, groupid, &attr_contentlen)) {
1413 DBG_88E("[%s] Ssid = %s, ssidlen = %zu\n", __func__, &groupid[ETH_ALEN], strlen(&groupid[ETH_ALEN]));
1414 memcpy(pwdinfo->groupid_info.go_device_addr, &groupid[0], ETH_ALEN);
1415 memcpy(pwdinfo->groupid_info.ssid, &groupid[6], attr_contentlen - ETH_ALEN);
1416 }
1417
1418 attr_contentlen = 0;
1419 if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen)) {
1420 DBG_88E("[%s] Peer's operating channel = %d\n", __func__, operatingch_info[4]);
1421 pwdinfo->peer_operating_ch = operatingch_info[4];
1422 }
1423
1424
1425 p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen);
1426 }
1427 return result;
1428}
1429
1430u8 process_p2p_presence_req(struct wifidirect_info *pwdinfo, u8 *pframe, uint len)
1431{
1432 u8 *frame_body;
1433 u8 dialogToken = 0;
1434 u8 status = P2P_STATUS_SUCCESS;
1435
1436 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
1437
1438 dialogToken = frame_body[6];
1439
1440
1441
1442 issue_p2p_presence_resp(pwdinfo, GetAddr2Ptr(pframe), status, dialogToken);
1443
1444 return true;
1445}
1446
1447static void find_phase_handler(struct adapter *padapter)
1448{
1449 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1450 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1451 struct ndis_802_11_ssid ssid;
1452
1453 memset((unsigned char *)&ssid, 0, sizeof(struct ndis_802_11_ssid));
1454 memcpy(ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN);
1455 ssid.SsidLength = P2P_WILDCARD_SSID_LEN;
1456
1457 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
1458
1459 spin_lock_bh(&pmlmepriv->lock);
1460 spin_unlock_bh(&pmlmepriv->lock);
1461
1462}
1463
1464void p2p_concurrent_handler(struct adapter *padapter);
1465
1466static void restore_p2p_state_handler(struct adapter *padapter)
1467{
1468 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1469
1470 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
1471 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
1472 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
1473
1474 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) {
1475
1476
1477 set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
1478 }
1479
1480}
1481
1482static void pre_tx_invitereq_handler(struct adapter *padapter)
1483{
1484 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1485 u8 val8 = 1;
1486
1487 set_channel_bwmode(padapter, pwdinfo->invitereq_info.peer_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
1488 SetHwReg8188EU(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
1489 issue_probereq_p2p(padapter, NULL);
1490 _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
1491
1492}
1493
1494static void pre_tx_provdisc_handler(struct adapter *padapter)
1495{
1496 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1497 u8 val8 = 1;
1498
1499 set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
1500 SetHwReg8188EU(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
1501 issue_probereq_p2p(padapter, NULL);
1502 _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
1503
1504}
1505
1506static void pre_tx_negoreq_handler(struct adapter *padapter)
1507{
1508 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1509 u8 val8 = 1;
1510
1511 set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
1512 SetHwReg8188EU(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
1513 issue_probereq_p2p(padapter, NULL);
1514 _set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
1515
1516}
1517
1518void p2p_protocol_wk_hdl(struct adapter *padapter, int intCmdType)
1519{
1520
1521 switch (intCmdType) {
1522 case P2P_FIND_PHASE_WK:
1523 find_phase_handler(padapter);
1524 break;
1525 case P2P_RESTORE_STATE_WK:
1526 restore_p2p_state_handler(padapter);
1527 break;
1528 case P2P_PRE_TX_PROVDISC_PROCESS_WK:
1529 pre_tx_provdisc_handler(padapter);
1530 break;
1531 case P2P_PRE_TX_INVITEREQ_PROCESS_WK:
1532 pre_tx_invitereq_handler(padapter);
1533 break;
1534 case P2P_PRE_TX_NEGOREQ_PROCESS_WK:
1535 pre_tx_negoreq_handler(padapter);
1536 break;
1537 }
1538
1539}
1540
1541void process_p2p_ps_ie(struct adapter *padapter, u8 *IEs, u32 IELength)
1542{
1543 u8 *ies;
1544 u32 ies_len;
1545 u8 *p2p_ie;
1546 u32 p2p_ielen = 0;
1547 u8 noa_attr[MAX_P2P_IE_LEN] = { 0x00 };
1548 u32 attr_contentlen = 0;
1549
1550 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1551 u8 find_p2p = false, find_p2p_ps = false;
1552 u8 noa_offset, noa_num, noa_index;
1553
1554 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
1555 return;
1556 if (IELength <= _BEACON_IE_OFFSET_)
1557 return;
1558
1559 ies = IEs + _BEACON_IE_OFFSET_;
1560 ies_len = IELength - _BEACON_IE_OFFSET_;
1561
1562 p2p_ie = rtw_get_p2p_ie(ies, ies_len, NULL, &p2p_ielen);
1563
1564 while (p2p_ie) {
1565 find_p2p = true;
1566
1567 if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_NOA, noa_attr, &attr_contentlen)) {
1568 find_p2p_ps = true;
1569 noa_index = noa_attr[0];
1570
1571 if ((pwdinfo->p2p_ps_mode == P2P_PS_NONE) ||
1572 (noa_index != pwdinfo->noa_index)) {
1573 pwdinfo->noa_index = noa_index;
1574 pwdinfo->opp_ps = noa_attr[1] >> 7;
1575 pwdinfo->ctwindow = noa_attr[1] & 0x7F;
1576
1577 noa_offset = 2;
1578 noa_num = 0;
1579
1580 if (attr_contentlen > 2) {
1581 while (noa_offset < attr_contentlen) {
1582
1583 pwdinfo->noa_count[noa_num] = noa_attr[noa_offset];
1584 noa_offset += 1;
1585
1586 memcpy(&pwdinfo->noa_duration[noa_num], &noa_attr[noa_offset], 4);
1587 noa_offset += 4;
1588
1589 memcpy(&pwdinfo->noa_interval[noa_num], &noa_attr[noa_offset], 4);
1590 noa_offset += 4;
1591
1592 memcpy(&pwdinfo->noa_start_time[noa_num], &noa_attr[noa_offset], 4);
1593 noa_offset += 4;
1594
1595 noa_num++;
1596 }
1597 }
1598 pwdinfo->noa_num = noa_num;
1599
1600 if (pwdinfo->opp_ps == 1) {
1601 pwdinfo->p2p_ps_mode = P2P_PS_CTWINDOW;
1602
1603 if (padapter->pwrctrlpriv.bFwCurrentInPSMode)
1604 p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 1);
1605 } else if (pwdinfo->noa_num > 0) {
1606 pwdinfo->p2p_ps_mode = P2P_PS_NOA;
1607 p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 1);
1608 } else if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) {
1609 p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1);
1610 }
1611 }
1612
1613 break;
1614 }
1615
1616
1617 p2p_ie = rtw_get_p2p_ie(p2p_ie + p2p_ielen, ies_len - (p2p_ie - ies + p2p_ielen), NULL, &p2p_ielen);
1618 }
1619
1620 if (find_p2p) {
1621 if ((pwdinfo->p2p_ps_mode > P2P_PS_NONE) && !find_p2p_ps)
1622 p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1);
1623 }
1624
1625}
1626
1627void p2p_ps_wk_hdl(struct adapter *padapter, u8 p2p_ps_state)
1628{
1629 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
1630 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1631
1632
1633 switch (p2p_ps_state) {
1634 case P2P_PS_DISABLE:
1635 pwdinfo->p2p_ps_state = p2p_ps_state;
1636
1637 SetHwReg8188EU(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state));
1638
1639 pwdinfo->noa_index = 0;
1640 pwdinfo->ctwindow = 0;
1641 pwdinfo->opp_ps = 0;
1642 pwdinfo->noa_num = 0;
1643 pwdinfo->p2p_ps_mode = P2P_PS_NONE;
1644 if (padapter->pwrctrlpriv.bFwCurrentInPSMode) {
1645 if (pwrpriv->smart_ps == 0) {
1646 pwrpriv->smart_ps = 2;
1647 SetHwReg8188EU(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&padapter->pwrctrlpriv.pwr_mode));
1648 }
1649 }
1650 break;
1651 case P2P_PS_ENABLE:
1652 if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) {
1653 pwdinfo->p2p_ps_state = p2p_ps_state;
1654
1655 if (pwdinfo->ctwindow > 0) {
1656 if (pwrpriv->smart_ps != 0) {
1657 pwrpriv->smart_ps = 0;
1658 DBG_88E("%s(): Enter CTW, change SmartPS\n", __func__);
1659 SetHwReg8188EU(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&padapter->pwrctrlpriv.pwr_mode));
1660 }
1661 }
1662 SetHwReg8188EU(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state));
1663 }
1664 break;
1665 case P2P_PS_SCAN:
1666 case P2P_PS_SCAN_DONE:
1667 case P2P_PS_ALLSTASLEEP:
1668 if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) {
1669 pwdinfo->p2p_ps_state = p2p_ps_state;
1670 SetHwReg8188EU(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state));
1671 }
1672 break;
1673 default:
1674 break;
1675 }
1676
1677}
1678
1679u8 p2p_ps_wk_cmd(struct adapter *padapter, u8 p2p_ps_state, u8 enqueue)
1680{
1681 struct cmd_obj *ph2c;
1682 struct drvextra_cmd_parm *pdrvextra_cmd_parm;
1683 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1684 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
1685 u8 res = _SUCCESS;
1686
1687 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
1688 return res;
1689
1690 if (enqueue) {
1691 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
1692 if (!ph2c) {
1693 res = _FAIL;
1694 goto exit;
1695 }
1696
1697 pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_ATOMIC);
1698 if (!pdrvextra_cmd_parm) {
1699 kfree(ph2c);
1700 res = _FAIL;
1701 goto exit;
1702 }
1703
1704 pdrvextra_cmd_parm->ec_id = P2P_PS_WK_CID;
1705 pdrvextra_cmd_parm->type_size = p2p_ps_state;
1706 pdrvextra_cmd_parm->pbuf = NULL;
1707
1708 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
1709
1710 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
1711 } else {
1712 p2p_ps_wk_hdl(padapter, p2p_ps_state);
1713 }
1714
1715exit:
1716
1717 return res;
1718}
1719
1720static void reset_ch_sitesurvey_timer_process(struct timer_list *t)
1721{
1722 struct adapter *adapter = from_timer(adapter, t, pwrctrlpriv.pwr_state_check_timer);
1723 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
1724
1725 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
1726 return;
1727
1728 DBG_88E("[%s] In\n", __func__);
1729
1730 pwdinfo->rx_invitereq_info.operation_ch[0] = 0;
1731 pwdinfo->rx_invitereq_info.scan_op_ch_only = 0;
1732}
1733
1734static void reset_ch_sitesurvey_timer_process2(struct timer_list *t)
1735{
1736 struct adapter *adapter = from_timer(adapter, t, pwrctrlpriv.pwr_state_check_timer);
1737 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
1738
1739 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
1740 return;
1741
1742 DBG_88E("[%s] In\n", __func__);
1743
1744 pwdinfo->p2p_info.operation_ch[0] = 0;
1745 pwdinfo->p2p_info.scan_op_ch_only = 0;
1746}
1747
1748static void restore_p2p_state_timer_process(struct timer_list *t)
1749{
1750 struct adapter *adapter = from_timer(adapter, t, wdinfo.restore_p2p_state_timer);
1751 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
1752
1753 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
1754 return;
1755
1756 p2p_protocol_wk_cmd(adapter, P2P_RESTORE_STATE_WK);
1757}
1758
1759static void pre_tx_scan_timer_process(struct timer_list *t)
1760{
1761 struct adapter *adapter = from_timer(adapter, t, wdinfo.pre_tx_scan_timer);
1762 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
1763 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1764
1765 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
1766 return;
1767
1768 spin_lock_bh(&pmlmepriv->lock);
1769
1770 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) {
1771 if (pwdinfo->tx_prov_disc_info.benable) {
1772 p2p_protocol_wk_cmd(adapter, P2P_PRE_TX_PROVDISC_PROCESS_WK);
1773
1774
1775 }
1776 } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) {
1777 if (pwdinfo->nego_req_info.benable)
1778 p2p_protocol_wk_cmd(adapter, P2P_PRE_TX_NEGOREQ_PROCESS_WK);
1779 } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ)) {
1780 if (pwdinfo->invitereq_info.benable)
1781 p2p_protocol_wk_cmd(adapter, P2P_PRE_TX_INVITEREQ_PROCESS_WK);
1782 } else {
1783 DBG_88E("[%s] p2p_state is %d, ignore!!\n", __func__, rtw_p2p_state(pwdinfo));
1784 }
1785
1786 spin_unlock_bh(&pmlmepriv->lock);
1787}
1788
1789static void find_phase_timer_process(struct timer_list *t)
1790{
1791 struct adapter *adapter = from_timer(adapter, t, wdinfo.find_phase_timer);
1792 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
1793
1794 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
1795 return;
1796
1797 adapter->wdinfo.find_phase_state_exchange_cnt++;
1798
1799 p2p_protocol_wk_cmd(adapter, P2P_FIND_PHASE_WK);
1800}
1801
1802void reset_global_wifidirect_info(struct adapter *padapter)
1803{
1804 struct wifidirect_info *pwdinfo;
1805
1806 pwdinfo = &padapter->wdinfo;
1807 pwdinfo->persistent_supported = 0;
1808 pwdinfo->session_available = true;
1809 pwdinfo->wfd_tdls_enable = 0;
1810 pwdinfo->wfd_tdls_weaksec = 0;
1811}
1812
1813void rtw_init_wifidirect_timers(struct adapter *padapter)
1814{
1815 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1816
1817 timer_setup(&pwdinfo->find_phase_timer, find_phase_timer_process, 0);
1818 timer_setup(&pwdinfo->restore_p2p_state_timer, restore_p2p_state_timer_process, 0);
1819 timer_setup(&pwdinfo->pre_tx_scan_timer, pre_tx_scan_timer_process, 0);
1820 timer_setup(&pwdinfo->reset_ch_sitesurvey, reset_ch_sitesurvey_timer_process, 0);
1821 timer_setup(&pwdinfo->reset_ch_sitesurvey2, reset_ch_sitesurvey_timer_process2, 0);
1822}
1823
1824void rtw_init_wifidirect_addrs(struct adapter *padapter, u8 *dev_addr, u8 *iface_addr)
1825{
1826 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1827
1828
1829 if (dev_addr)
1830 memcpy(pwdinfo->device_addr, dev_addr, ETH_ALEN);
1831 if (iface_addr)
1832 memcpy(pwdinfo->interface_addr, iface_addr, ETH_ALEN);
1833}
1834
1835void init_wifidirect_info(struct adapter *padapter, enum P2P_ROLE role)
1836{
1837 struct wifidirect_info *pwdinfo;
1838
1839 pwdinfo = &padapter->wdinfo;
1840 pwdinfo->padapter = padapter;
1841
1842
1843 pwdinfo->social_chan[0] = 1;
1844 pwdinfo->social_chan[1] = 6;
1845 pwdinfo->social_chan[2] = 11;
1846 pwdinfo->social_chan[3] = 0;
1847
1848
1849 pwdinfo->listen_channel = 11;
1850
1851 if (role == P2P_ROLE_DEVICE) {
1852 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
1853 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
1854 pwdinfo->intent = 1;
1855 rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_LISTEN);
1856 } else if (role == P2P_ROLE_CLIENT) {
1857 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
1858 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
1859 pwdinfo->intent = 1;
1860 rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
1861 } else if (role == P2P_ROLE_GO) {
1862 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
1863 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
1864 pwdinfo->intent = 15;
1865 rtw_p2p_set_pre_state(pwdinfo, P2P_STATE_GONEGO_OK);
1866 }
1867
1868
1869 pwdinfo->support_rate[0] = 0x8c;
1870 pwdinfo->support_rate[1] = 0x92;
1871 pwdinfo->support_rate[2] = 0x18;
1872 pwdinfo->support_rate[3] = 0x24;
1873 pwdinfo->support_rate[4] = 0x30;
1874 pwdinfo->support_rate[5] = 0x48;
1875 pwdinfo->support_rate[6] = 0x60;
1876 pwdinfo->support_rate[7] = 0x6c;
1877
1878 memcpy(pwdinfo->p2p_wildcard_ssid, "DIRECT-", 7);
1879
1880 memset(pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN);
1881 pwdinfo->device_name_len = 0;
1882
1883 memset(&pwdinfo->invitereq_info, 0x00, sizeof(struct tx_invite_req_info));
1884 pwdinfo->invitereq_info.token = 3;
1885
1886 memset(&pwdinfo->inviteresp_info, 0x00, sizeof(struct tx_invite_resp_info));
1887 pwdinfo->inviteresp_info.token = 0;
1888
1889 pwdinfo->profileindex = 0;
1890 memset(&pwdinfo->profileinfo[0], 0x00, sizeof(struct profile_info) * P2P_MAX_PERSISTENT_GROUP_NUM);
1891
1892 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
1893
1894 pwdinfo->listen_dwell = (u8)((jiffies % 3) + 1);
1895
1896 memset(&pwdinfo->tx_prov_disc_info, 0x00, sizeof(struct tx_provdisc_req_info));
1897 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_NONE;
1898
1899 memset(&pwdinfo->nego_req_info, 0x00, sizeof(struct tx_nego_req_info));
1900
1901 pwdinfo->device_password_id_for_nego = WPS_DPID_PBC;
1902 pwdinfo->negotiation_dialog_token = 1;
1903
1904 memset(pwdinfo->nego_ssid, 0x00, WLAN_SSID_MAXLEN);
1905 pwdinfo->nego_ssidlen = 0;
1906
1907 pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
1908 pwdinfo->supported_wps_cm = WPS_CONFIG_METHOD_DISPLAY | WPS_CONFIG_METHOD_PBC | WPS_CONFIG_METHOD_KEYPAD;
1909 pwdinfo->channel_list_attr_len = 0;
1910 memset(pwdinfo->channel_list_attr, 0x00, 100);
1911
1912 memset(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, 0x00, 4);
1913 memset(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, '0', 3);
1914 memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info));
1915 pwdinfo->wfd_tdls_enable = 0;
1916 memset(pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN);
1917 memset(pwdinfo->p2p_peer_device_addr, 0x00, ETH_ALEN);
1918
1919 pwdinfo->rx_invitereq_info.operation_ch[0] = 0;
1920 pwdinfo->rx_invitereq_info.operation_ch[1] = 0;
1921 pwdinfo->rx_invitereq_info.scan_op_ch_only = 0;
1922 pwdinfo->p2p_info.operation_ch[0] = 0;
1923 pwdinfo->p2p_info.operation_ch[1] = 0;
1924 pwdinfo->p2p_info.scan_op_ch_only = 0;
1925}
1926
1927int rtw_p2p_enable(struct adapter *padapter, enum P2P_ROLE role)
1928{
1929 int ret = _SUCCESS;
1930 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1931
1932 if (role == P2P_ROLE_DEVICE || role == P2P_ROLE_CLIENT || role == P2P_ROLE_GO) {
1933
1934 if (_FAIL == rtw_pwr_wakeup(padapter)) {
1935 ret = _FAIL;
1936 goto exit;
1937 }
1938
1939
1940
1941
1942 update_tx_basic_rate(padapter, (WIRELESS_11G | WIRELESS_11_24N));
1943
1944
1945 init_wifidirect_info(padapter, role);
1946
1947 rtl8188e_SetHalODMVar(padapter, HAL_ODM_P2P_STATE, NULL, true);
1948 } else if (role == P2P_ROLE_DISABLE) {
1949 if (_FAIL == rtw_pwr_wakeup(padapter)) {
1950 ret = _FAIL;
1951 goto exit;
1952 }
1953
1954
1955 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
1956 _cancel_timer_ex(&pwdinfo->find_phase_timer);
1957 _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
1958 _cancel_timer_ex(&pwdinfo->pre_tx_scan_timer);
1959 _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
1960 _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey2);
1961 rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE);
1962 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DISABLE);
1963 memset(&pwdinfo->rx_prov_disc_info, 0x00, sizeof(struct rx_provdisc_req_info));
1964 }
1965
1966 rtl8188e_SetHalODMVar(padapter, HAL_ODM_P2P_STATE, NULL, false);
1967
1968
1969 update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode);
1970 }
1971
1972exit:
1973 return ret;
1974}
1975