9960be55478ae98dd61c30e50b0814ac69a09dfb
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / combo_mt66xx / mt6620 / wlan / os / linux / gl_p2p.c
1 /*
2 ** $Id: @(#) gl_p2p.c@@
3 */
4
5 /*! \file   gl_p2p.c
6     \brief  Main routines of Linux driver interface for Wi-Fi Direct
7
8     This file contains the main routines of Linux driver for MediaTek Inc. 802.11
9     Wireless LAN Adapters.
10 */
11
12
13
14 /*
15 ** $Log: gl_p2p.c $
16 ** 
17 ** 09 12 2012 wcpadmin
18 ** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages
19 ** .
20 ** 
21 ** 08 17 2012 yuche.tsai
22 ** NULL
23 ** Fix compile warning.
24 ** 
25 ** 08 16 2012 yuche.tsai
26 ** NULL
27 ** Fix compile warning.
28 ** 
29 ** 08 14 2012 yuche.tsai
30 ** NULL
31 ** FPB from ALPS.JB to phase 2 release.
32 ** 
33 ** 07 26 2012 yuche.tsai
34 ** [ALPS00324337] [ALPS.JB][Hot-Spot] Driver update for Hot-Spot
35 ** Update driver code of ALPS.JB for hot-spot.
36 **
37 ** 07 19 2012 yuche.tsai
38 ** NULL
39 ** Code update for JB.
40  *
41  * 07 17 2012 yuche.tsai
42  * NULL
43  * Fix compile error for JB.
44  *
45  * 07 17 2012 yuche.tsai
46  * NULL
47  * Let netdev bring up.
48  *
49  * 07 17 2012 yuche.tsai
50  * NULL
51  * Compile no error before trial run.
52  *
53  * 01 09 2012 terry.wu
54  * [WCXRP00001166] [Wi-Fi] [Driver] cfg80211 integration for p2p newtork
55  * cfg80211 integration for p2p network.
56  *
57  * 12 19 2011 terry.wu
58  * [WCXRP00001142] [Wi-Fi] [P2P Driver] XOR local admin bit to generate p2p net device MAC
59  * XOR local administrated bit to generate net device MAC of p2p network.
60  *
61  * 12 02 2011 yuche.tsai
62  * NULL
63  * Fix possible KE when unload p2p.
64  *
65  * 11 24 2011 yuche.tsai
66  * NULL
67  * Fix P2P IOCTL of multicast address bug, add low power driver stop control.
68  *
69  * 11 22 2011 yuche.tsai
70  * NULL
71  * Update RSSI link quality of P2P Network query method. (Bug fix)
72  *
73  * 11 19 2011 yuche.tsai
74  * NULL
75  * Add RSSI support for P2P network.
76  *
77  * 11 16 2011 yuche.tsai
78  * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue.
79  * Avoid using work thread in set p2p multicast address callback.
80  *
81  * 11 11 2011 yuche.tsai
82  * NULL
83  * Fix work thread cancel issue.
84  *
85  * 11 11 2011 yuche.tsai
86  * NULL
87  * Fix default device name issue.
88  *
89  * 11 08 2011 yuche.tsai
90  * [WCXRP00001094] [Volunteer Patch][Driver] Driver version & supplicant version query & set support for service discovery version check.
91  * Add support for driver version query & p2p supplicant verseion set.
92  * For new service discovery mechanism sync.
93  *
94  * 11 07 2011 yuche.tsai
95  * NULL
96  * [ALPS 00087243] KE in worker thread.
97  * The multicast address list is scheduled in worker thread.
98  * Before the worker thread is excuted, if P2P is unloaded, a KE may occur.
99  *
100  * 10 26 2011 terry.wu
101  * [WCXRP00001066] [MT6620 Wi-Fi] [P2P Driver] Fix P2P Oid Issue
102  * Fix some P2P OID functions didn't raise its flag "fgIsP2pOid" issue.
103  *
104  * 10 25 2011 cm.chang
105  * [WCXRP00001058] [All Wi-Fi][Driver] Fix sta_rec's phyTypeSet and OBSS scan in AP mode
106  * .
107  *
108  * 10 18 2011 yuche.tsai
109  * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch.
110  * Support Channle Query.
111  *
112  * 10 18 2011 yuche.tsai
113  * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch.
114  * New 2.1 branch
115
116  *
117  * 08 26 2011 yuche.tsai
118  * NULL
119  * Fix bug of parsing secondary device list type issue.
120  *
121  * 08 24 2011 yuche.tsai
122  * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature.
123  * Invitation Abort.
124  *
125  * 08 23 2011 yuche.tsai
126  * NULL
127  * Fix multicast address list issue of P2P.
128  *
129  * 08 22 2011 chinglan.wang
130  * NULL
131  * Fix invitation indication bug..
132  *
133  * 08 16 2011 cp.wu
134  * [WCXRP00000934] [MT6620 Wi-Fi][Driver][P2P] Wi-Fi hot spot with auto sparse channel residence
135  * auto channel decision for 2.4GHz hot spot mode
136  *
137  * 08 16 2011 chinglan.wang
138  * NULL
139  * Add the group id information in the invitation indication.
140  *
141  * 08 09 2011 yuche.tsai
142  * [WCXRP00000919] [Volunteer Patch][WiFi Direct][Driver] Invitation New Feature.
143  * Invitation Feature add on.
144  *
145  * 08 05 2011 yuche.tsai
146  * [WCXRP00000856] [Volunteer Patch][WiFi Direct][Driver] MT6620 WiFi Direct IOT Issue with BCM solution.
147  * Add Password ID check for quick connection.
148  * Also modify some connection policy.
149  *
150  * 07 18 2011 chinglan.wang
151  * NULL
152  * Add IOC_P2P_GO_WSC_IE (p2p capability).
153  *
154  * 06 14 2011 yuche.tsai
155  * NULL
156  * Add compile flag to disable persistent group support.
157  *
158  * 05 04 2011 chinglan.wang
159  * [WCXRP00000698] [MT6620 Wi-Fi][P2P][Driver] Add p2p invitation command for the p2p driver
160  * .
161  *
162  * 05 02 2011 yuche.tsai
163  * [WCXRP00000693] [Volunteer Patch][MT6620][Driver] Clear Formation Flag after TX lifetime timeout.
164  * Clear formation flag after formation timeout.
165  *
166  * 04 22 2011 george.huang
167  * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode
168  * .
169  *
170  * 04 21 2011 george.huang
171  * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode
172  * 1. Revise P2P power mode setting.
173  * 2. Revise fast-PS for concurrent
174  *
175  * 04 19 2011 wh.su
176  * NULL
177  * Adding length check before doing WPA RSN IE parsing for scan results indicate.
178  *
179  * 04 14 2011 yuche.tsai
180  * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case.
181  * Connection flow refine for Sigma test.
182  *
183  * 04 08 2011 yuche.tsai
184  * [WCXRP00000624] [Volunteer Patch][MT6620][Driver] Add device discoverability support for GO.
185  * Add device discoverability support.
186  *
187  * 04 08 2011 george.huang
188  * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode
189  * separate settings of P2P and AIS
190  *
191  * 04 07 2011 terry.wu
192  * [WCXRP00000619] [MT6620 Wi-Fi][Driver] fix kernel panic may occur when removing wlan
193  * Fix kernel panic may occur when removing wlan driver.
194  *
195  * 03 31 2011 wh.su
196  * [WCXRP00000614] [MT6620 Wi-Fi][Driver] P2P: Update beacon content while setting WSC IE
197  * Update the wsc ie to beacon content.
198  *
199  * 03 25 2011 wh.su
200  * NULL
201  * add the sample code for set power mode and get power mode.
202  *
203  * 03 25 2011 yuche.tsai
204  * NULL
205  * Improve some error handleing.
206  *
207  * 03 22 2011 george.huang
208  * [WCXRP00000504] [MT6620 Wi-Fi][FW] Support Sigma CAPI for power saving related command
209  * link with supplicant commands
210  *
211  * 03 22 2011 yuche.tsai
212  * [WCXRP00000584] [Volunteer Patch][MT6620][Driver] Add beacon timeout support for WiFi Direct.
213  * Modify formation policy.
214  *
215  * 03 22 2011 yuche.tsai
216  * NULL
217  * Modify formation policy setting.
218  *
219  * 03 18 2011 yuche.tsai
220  * [WCXRP00000574] [Volunteer Patch][MT6620][Driver] Modify P2P FSM Connection Flow
221  * Modify connection flow after Group Formation Complete, or device connect to a GO.
222  * Instead of request channel & connect directly, we use scan to allocate channel bandwidth & connect after RX BCN.
223  *
224  * 03 15 2011 wh.su
225  * [WCXRP00000563] [MT6620 Wi-Fi] [P2P] Set local config method while set password Id ready
226  * set lccal config method method while set password Id ready.
227  *
228  * 03 15 2011 yuche.tsai
229  * [WCXRP00000560] [Volunteer Patch][MT6620][Driver] P2P Connection from UI using KEY/DISPLAY issue
230  * Fix some configure method issue.
231  *
232  * 03 15 2011 jeffrey.chang
233  * [WCXRP00000558] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] refine the queue selection algorithm for WMM
234  * refine queue_select function
235  *
236  * 03 13 2011 wh.su
237  * [WCXRP00000530] [MT6620 Wi-Fi] [Driver] skip doing p2pRunEventAAAComplete after send assoc response Tx Done
238  * add code for avoid compiling warning.
239  *
240  * 03 10 2011 yuche.tsai
241  * NULL
242  * Add P2P API.
243  *
244  * 03 10 2011 terry.wu
245  * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration
246  * Remove unnecessary assert and message.
247  *
248  * 03 08 2011 wh.su
249  * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver
250  * support the power save related p2p setting.
251  *
252  * 03 07 2011 wh.su
253  * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
254  * rename the define to anti_pviracy.
255  *
256  * 03 05 2011 wh.su
257  * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
258  * add the code to get the check rsponse and indicate to app.
259  *
260  * 03 03 2011 jeffrey.chang
261  * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
262  * support concurrent network
263  *
264  * 03 03 2011 jeffrey.chang
265  * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
266  * modify P2P's netdevice  functions to support multiple H/W queues
267  *
268  * 03 03 2011 cp.wu
269  * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service Discovery
270  * for get request, the buffer length to be copied is header + payload.
271  *
272  * 03 02 2011 wh.su
273  * [WCXRP00000506] [MT6620 Wi-Fi][Driver][FW] Add Security check related code
274  * add code to let the beacon and probe response for Auto GO WSC .
275  *
276  * 03 02 2011 cp.wu
277  * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service Discovery
278  * add a missed break.
279  *
280  * 03 01 2011 yuche.tsai
281  * [WCXRP00000501] [Volunteer Patch][MT6620][Driver] No common channel issue when doing GO formation
282  * Update channel issue when doing GO formation..
283  *
284  * 02 25 2011 wh.su
285  * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver
286  * add the Operation channel setting.
287  *
288  * 02 23 2011 wh.su
289  * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver
290  * fixed the set int ioctl set index and value map to driver issue.
291  *
292  * 02 22 2011 wh.su
293  * [WCXRP00000488] [MT6620 Wi-Fi][Driver] Support the SIGMA set p2p parameter to driver
294  * adding the ioctl set int from supplicant, and can used to set the p2p paramters
295  *
296  * 02 21 2011 terry.wu
297  * [WCXRP00000476] [MT6620 Wi-Fi][Driver] Clean P2P scan list while removing P2P
298  * Clean P2P scan list while removing P2P.
299  *
300  * 02 18 2011 wh.su
301  * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE
302  * fixed the ioctl setting that index not map to spec defined config method.
303  *
304  * 02 17 2011 wh.su
305  * [WCXRP00000471] [MT6620 Wi-Fi][Driver] Add P2P Provison discovery append Config Method attribute at WSC IE
306  * append the WSC IE config method attribute at provision discovery request.
307  *
308  * 02 17 2011 wh.su
309  * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request
310  * modify the structure pointer for set WSC IE.
311  *
312  * 02 16 2011 wh.su
313  * [WCXRP00000448] [MT6620 Wi-Fi][Driver] Fixed WSC IE not send out at probe request
314  * fixed the probe request send out without WSC IE issue (at P2P).
315  *
316  * 02 09 2011 cp.wu
317  * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service Discovery
318  * fix typo
319  *
320  * 02 09 2011 yuche.tsai
321  * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
322  * Add Support for MLME deauthentication for Hot-Spot.
323  *
324  * 01 25 2011 terry.wu
325  * [WCXRP00000393] [MT6620 Wi-Fi][Driver] Add new module insert parameter
326  * Add a new module parameter to indicate current runnig mode, P2P or AP.
327  *
328  * 01 12 2011 yuche.tsai
329  * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
330  * 1. Modify Channel Acquire Time of AP mode from 5s to 1s.
331  * 2. Call cnmP2pIsPermit() before active P2P network.
332  * 3. Add channel selection support for AP mode.
333  *
334  * 01 05 2011 cp.wu
335  * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service Discovery
336  * ioctl implementations for P2P Service Discovery
337  *
338  * 01 04 2011 cp.wu
339  * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease physically continous memory demands
340  * separate kalMemAlloc() into virtually-continous and physically-continous type to ease slab system pressure
341  *
342  * 12 22 2010 cp.wu
343  * [WCXRP00000283] [MT6620 Wi-Fi][Driver][Wi-Fi Direct] Implementation of interface for supporting Wi-Fi Direct Service Discovery
344  * 1. header file restructure for more clear module isolation
345  * 2. add function interface definition for implementing Service Discovery callbacks
346  *
347  * 12 15 2010 cp.wu
348  * NULL
349  * invoke nicEnableInterrupt() before leaving from wlanAdapterStart()
350  *
351  * 12 08 2010 yuche.tsai
352  * [WCXRP00000245] [MT6620][Driver] Invitation & Provision Discovery Feature Check-in
353  * [WCXRP000000245][MT6620][Driver] Invitation Request Feature Add
354  *
355  * 11 30 2010 yuche.tsai
356  * NULL
357  * Invitation & Provision Discovery Indication.
358  *
359  * 11 17 2010 wh.su
360  * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID[WCXRP00000179] [MT6620 Wi-Fi][FW] Set the Tx lowest rate at wlan table for normal operation
361  * fixed some ASSERT check.
362  *
363  * 11 04 2010 wh.su
364  * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID
365  * adding the p2p random ssid support.
366  *
367  * 10 20 2010 wh.su
368  * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group
369  * Add the code to support disconnect p2p group
370  *
371  * 10 04 2010 wh.su
372  * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P
373  * add a kal function for set cipher.
374  *
375  * 10 04 2010 wh.su
376  * [WCXRP00000081] [MT6620][Driver] Fix the compiling error at WinXP while enable P2P
377  * fixed compiling error while enable p2p.
378  *
379  * 09 28 2010 wh.su
380  * NULL
381  * [WCXRP00000069][MT6620 Wi-Fi][Driver] Fix some code for phase 1 P2P Demo.
382  *
383  * 09 21 2010 kevin.huang
384  * [WCXRP00000054] [MT6620 Wi-Fi][Driver] Restructure driver for second Interface
385  * Isolate P2P related function for Hardware Software Bundle
386  *
387  * 09 21 2010 kevin.huang
388  * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
389  * Eliminate Linux Compile Warning
390  *
391  * 09 10 2010 george.huang
392  * NULL
393  * update iwpriv LP related
394  *
395  * 09 10 2010 wh.su
396  * NULL
397  * fixed the compiling error at win XP.
398  *
399  * 09 09 2010 cp.wu
400  * NULL
401  * add WPS/WPA/RSN IE for Wi-Fi Direct scanning result.
402  *
403  * 09 07 2010 wh.su
404  * NULL
405  * adding the code for beacon/probe req/ probe rsp wsc ie at p2p.
406  *
407  * 09 06 2010 wh.su
408  * NULL
409  * let the p2p can set the privacy bit at beacon and rsn ie at assoc req at key handshake state.
410  *
411  * 08 25 2010 cp.wu
412  * NULL
413  * add netdev_ops(NDO) for linux kernel 2.6.31 or greater
414  *
415  * 08 23 2010 cp.wu
416  * NULL
417  * revise constant definitions to be matched with implementation (original cmd-event definition is deprecated)
418  *
419  * 08 20 2010 cp.wu
420  * NULL
421  * correct typo.
422  *
423  * 08 20 2010 yuche.tsai
424  * NULL
425  * Invert Connection request provision status parameter.
426  *
427  * 08 19 2010 cp.wu
428  * NULL
429  * add set mac address interface for further possibilities of wpa_supplicant overriding interface address.
430  *
431  * 08 18 2010 cp.wu
432  * NULL
433  * modify pwp ioctls attribution by removing FIXED_SIZE.
434  *
435  * 08 18 2010 jeffrey.chang
436  * NULL
437  * support multi-function sdio
438  *
439  * 08 17 2010 cp.wu
440  * NULL
441  * correct p2p net device registration with NULL pointer access issue.
442  *
443  * 08 16 2010 cp.wu
444  * NULL
445  * P2P packets are now marked when being queued into driver, and identified later without checking MAC address
446  *
447  * 08 16 2010 cp.wu
448  * NULL
449  * add subroutines for P2P to set multicast list.
450  *
451  * 08 16 2010 george.huang
452  * NULL
453  * add wext handlers to link P2P set PS profile/ network address function (TBD)
454  *
455  * 08 16 2010 cp.wu
456  * NULL
457  * revised implementation of Wi-Fi Direct io controls.
458  *
459  * 08 12 2010 cp.wu
460  * NULL
461  * follow-up with ioctl interface update for Wi-Fi Direct application
462  *
463  * 08 06 2010 cp.wu
464  * NULL
465  * driver hook modifications corresponding to ioctl interface change.
466  *
467  * 08 03 2010 cp.wu
468  * NULL
469  * add basic support for ioctl of getting scan result. (only address and SSID are reporterd though)
470  *
471  * 08 03 2010 cp.wu
472  * NULL
473  * [Wi-Fi Direct Driver Hook] change event indication API to be consistent with supplicant
474  *
475  * 08 03 2010 cp.wu
476  * NULL
477  * surpress compilation warning.
478  *
479  * 08 03 2010 cp.wu
480  * NULL
481  * [Wi-Fi Direct] add framework for driver hooks
482  *
483  * 07 08 2010 cp.wu
484  *
485  * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
486  *
487  * 06 23 2010 cp.wu
488  * [WPD00003833][MT6620 and MT5931] Driver migration
489  * p2p interface revised to be sync. with HAL
490  *
491  * 06 06 2010 kevin.huang
492  * [WPD00003832][MT6620 5931] Create driver base
493  * [MT6620 5931] Create driver base
494  *
495  * 06 01 2010 cp.wu
496  * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
497  * add ioctl to configure scan mode for p2p connection
498  *
499  * 05 31 2010 cp.wu
500  * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
501  * add cfg80211 interface, which is to replace WE, for further extension
502  *
503  * 05 17 2010 cp.wu
504  * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
505  * implement private io controls for Wi-Fi Direct
506  *
507  * 05 17 2010 cp.wu
508  * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
509  * implement get scan result.
510  *
511  * 05 17 2010 cp.wu
512  * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
513  * add basic handling framework for wireless extension ioctls.
514  *
515  * 05 17 2010 cp.wu
516  * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
517  * 1) add timeout handler mechanism for pending command packets
518  * 2) add p2p add/removal key
519  *
520  * 05 14 2010 cp.wu
521  * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
522  * implement wireless extension ioctls in iw_handler form.
523  *
524  * 05 14 2010 cp.wu
525  * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
526  * add ioctl framework for Wi-Fi Direct by reusing wireless extension ioctls as well
527  *
528  * 05 11 2010 cp.wu
529  * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
530  * p2p ioctls revised.
531  *
532  * 05 11 2010 cp.wu
533  * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
534  * add ioctl for controlling p2p scan phase parameters
535  *
536  * 05 10 2010 cp.wu
537  * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
538  * implement basic wi-fi direct framework
539  *
540  * 05 07 2010 cp.wu
541  * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
542  * add basic framework for implementating P2P driver hook.
543  *
544 **
545 */
546
547 /*******************************************************************************
548 *                         C O M P I L E R   F L A G S
549 ********************************************************************************
550 */
551
552 /*******************************************************************************
553 *                    E X T E R N A L   R E F E R E N C E S
554 ********************************************************************************
555 */
556 #include "gl_os.h"
557 #include "debug.h"
558 #include "wlan_lib.h"
559 #include "gl_wext.h"
560 #include <linux/poll.h>
561
562 #include <linux/kmod.h>
563 //#include <net/cfg80211.h>
564 #include "gl_p2p_ioctl.h"
565
566 #include "precomp.h"
567
568 /*******************************************************************************
569 *                              C O N S T A N T S
570 ********************************************************************************
571 */
572 #define ARGV_MAX_NUM        (4)
573
574 /*For CFG80211 - wiphy parameters*/
575 #define MAX_SCAN_LIST_NUM   (1)
576 #define MAX_SCAN_IE_LEN     (512)
577 #define LEGACY_IN_AP_MODE "legacy_wlan%d"
578
579
580 /*******************************************************************************
581 *                             D A T A   T Y P E S
582 ********************************************************************************
583 */
584
585 /*******************************************************************************
586 *                            P U B L I C   D A T A
587 ********************************************************************************
588 */
589
590 /*******************************************************************************
591 *                           P R I V A T E   D A T A
592 ********************************************************************************
593 */
594
595 #if CFG_ENABLE_WIFI_DIRECT_CFG_80211
596 /* for cfg80211 - frequency table */
597 static struct ieee80211_channel mtk_2ghz_channels[] = {
598     CHAN2G(1, 2412, 0),
599     CHAN2G(2, 2417, 0),
600     CHAN2G(3, 2422, 0),
601     CHAN2G(4, 2427, 0),
602     CHAN2G(5, 2432, 0),
603     CHAN2G(6, 2437, 0),
604     CHAN2G(7, 2442, 0),
605     CHAN2G(8, 2447, 0),
606     CHAN2G(9, 2452, 0),
607     CHAN2G(10, 2457, 0),
608     CHAN2G(11, 2462, 0),
609     CHAN2G(12, 2467, 0),
610     CHAN2G(13, 2472, 0),
611     CHAN2G(14, 2484, 0),
612 };
613
614 static struct ieee80211_channel mtk_5ghz_a_channels[] = {
615     CHAN5G(34, 0),      CHAN5G(36, 0),
616     CHAN5G(38, 0),      CHAN5G(40, 0),
617     CHAN5G(42, 0),      CHAN5G(44, 0),
618     CHAN5G(46, 0),      CHAN5G(48, 0),
619     CHAN5G(52, 0),      CHAN5G(56, 0),
620     CHAN5G(60, 0),      CHAN5G(64, 0),
621     CHAN5G(100, 0),     CHAN5G(104, 0),
622     CHAN5G(108, 0),     CHAN5G(112, 0),
623     CHAN5G(116, 0),     CHAN5G(120, 0),
624     CHAN5G(124, 0),     CHAN5G(128, 0),
625     CHAN5G(132, 0),     CHAN5G(136, 0),
626     CHAN5G(140, 0),     CHAN5G(149, 0),
627     CHAN5G(153, 0),     CHAN5G(157, 0),
628     CHAN5G(161, 0),     CHAN5G(165, 0),
629     CHAN5G(169, 0),     CHAN5G(173, 0),
630     CHAN5G(184, 0),     CHAN5G(188, 0),
631     CHAN5G(192, 0),     CHAN5G(196, 0),
632     CHAN5G(200, 0),     CHAN5G(204, 0),
633     CHAN5G(208, 0),     CHAN5G(212, 0),
634     CHAN5G(216, 0),
635 };
636
637 /* for cfg80211 - rate table */
638 static struct ieee80211_rate mtk_rates[] = {
639     RATETAB_ENT(10,   0x1000,   0),
640     RATETAB_ENT(20,   0x1001,   0),
641     RATETAB_ENT(55,   0x1002,   0),
642     RATETAB_ENT(110,  0x1003,   0), /* 802.11b */
643     RATETAB_ENT(60,   0x2000,   0),
644     RATETAB_ENT(90,   0x2001,   0),
645     RATETAB_ENT(120,  0x2002,   0),
646     RATETAB_ENT(180,  0x2003,   0),
647     RATETAB_ENT(240,  0x2004,   0),
648     RATETAB_ENT(360,  0x2005,   0),
649     RATETAB_ENT(480,  0x2006,   0),
650     RATETAB_ENT(540,  0x2007,   0), /* 802.11a/g */
651 };
652
653 #define mtk_a_rates         (mtk_rates + 4)
654 #define mtk_a_rates_size    (sizeof(mtk_rates) / sizeof(mtk_rates[0]) - 4)
655 #define mtk_g_rates         (mtk_rates + 0)
656 #define mtk_g_rates_size    (sizeof(mtk_rates) / sizeof(mtk_rates[0]) - 0)
657
658 #define MT6620_MCS_INFO                                     \
659 {                                                           \
660         /* MCS1~7*/                                        \
661         .rx_mask        = {0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0},\
662         .rx_highest     = 0,                                \
663         .tx_params      = IEEE80211_HT_MCS_TX_DEFINED,      \
664 }
665
666 #if 0
667 /*Bandwidth 20Mhz Only*/
668 #define MT6620_HT_CAP                                       \
669 {                                                           \
670         .ht_supported   = true,                             \
671         .cap            = IEEE80211_HT_CAP_SM_PS            \
672                         | IEEE80211_HT_CAP_GRN_FLD          \
673                         | IEEE80211_HT_CAP_SGI_20,          \
674         .ampdu_factor   = IEEE80211_HT_MAX_AMPDU_64K,       \
675         .ampdu_density  = IEEE80211_HT_MPDU_DENSITY_NONE,   \
676         .mcs            = MT6620_MCS_INFO,                  \
677 }
678 #else
679 /*Bandwidth 20/40Mhz*/
680 #define MT6620_HT_CAP                                       \
681 {                                                           \
682         .ht_supported   = true,                             \
683         .cap            = IEEE80211_HT_CAP_SUP_WIDTH_20_40  \
684                         | IEEE80211_HT_CAP_SM_PS            \
685                         | IEEE80211_HT_CAP_GRN_FLD          \
686                         | IEEE80211_HT_CAP_SGI_20           \
687                         | IEEE80211_HT_CAP_SGI_40,          \
688         .ampdu_factor   = IEEE80211_HT_MAX_AMPDU_64K,       \
689         .ampdu_density  = IEEE80211_HT_MPDU_DENSITY_NONE,   \
690         .mcs            = MT6620_MCS_INFO,                  \
691 }
692 #endif
693
694 static struct ieee80211_supported_band mtk_band_2ghz = {
695     .band       = IEEE80211_BAND_2GHZ,
696     .channels   = mtk_2ghz_channels,
697     .n_channels = ARRAY_SIZE(mtk_2ghz_channels),
698     .bitrates   = mtk_g_rates,
699     .n_bitrates = mtk_g_rates_size,
700     .ht_cap     = MT6620_HT_CAP,
701 };
702
703 static struct ieee80211_supported_band mtk_band_5ghz = {
704     .band       = IEEE80211_BAND_5GHZ,
705     .channels   = mtk_5ghz_a_channels,
706     .n_channels = ARRAY_SIZE(mtk_5ghz_a_channels),
707     .bitrates   = mtk_a_rates,
708     .n_bitrates = mtk_a_rates_size,
709     .ht_cap     = MT6620_HT_CAP,
710 };
711
712 static const UINT_32 cipher_suites[] = {
713         /* keep WEP first, it may be removed below */
714         WLAN_CIPHER_SUITE_WEP40,
715         WLAN_CIPHER_SUITE_WEP104,
716         WLAN_CIPHER_SUITE_TKIP,
717         WLAN_CIPHER_SUITE_CCMP,
718
719         /* keep last -- depends on hw flags! */
720         WLAN_CIPHER_SUITE_AES_CMAC
721 };
722
723 static struct cfg80211_ops mtk_p2p_config_ops = {
724 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) && (CFG_ENABLE_WIFI_DIRECT_CFG_80211 != 0)
725     /* Froyo */
726     .change_virtual_intf    = mtk_p2p_cfg80211_change_iface,      // 1 st
727     .change_bss = mtk_p2p_cfg80211_change_bss,
728     .scan = mtk_p2p_cfg80211_scan,
729     .remain_on_channel = mtk_p2p_cfg80211_remain_on_channel,
730     .cancel_remain_on_channel = mtk_p2p_cfg80211_cancel_remain_on_channel,
731     .mgmt_tx = mtk_p2p_cfg80211_mgmt_tx,
732     //[AOSP]
733     .mgmt_tx_cancel_wait  = mtk_p2p_cfg80211_mgmt_tx_cancel_wait,
734     .connect = mtk_p2p_cfg80211_connect,
735     .disconnect = mtk_p2p_cfg80211_disconnect,
736     .deauth = mtk_p2p_cfg80211_deauth,
737     .disassoc = mtk_p2p_cfg80211_disassoc,
738 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
739     .start_ap = mtk_p2p_cfg80211_start_ap,
740     .change_beacon = mtk_p2p_cfg80211_change_beacon,
741     .stop_ap = mtk_p2p_cfg80211_stop_ap,
742 #else
743     .add_beacon = mtk_p2p_cfg80211_add_set_beacon,
744     .set_beacon = mtk_p2p_cfg80211_add_set_beacon,
745     .del_beacon = mtk_p2p_cfg80211_stop_ap,
746 #endif
747     .set_wiphy_params = mtk_p2p_cfg80211_set_wiphy_params,
748     .del_station = mtk_p2p_cfg80211_del_station,
749     .set_channel = mtk_p2p_cfg80211_set_channel,
750     .set_bitrate_mask = mtk_p2p_cfg80211_set_bitrate_mask,
751     .mgmt_frame_register = mtk_p2p_cfg80211_mgmt_frame_register,
752     .get_station            = mtk_p2p_cfg80211_get_station,
753     // ================
754     .add_key                = mtk_p2p_cfg80211_add_key,
755     .get_key                = mtk_p2p_cfg80211_get_key,
756     .del_key                = mtk_p2p_cfg80211_del_key,
757     .set_default_key        = mtk_p2p_cfg80211_set_default_key,
758     .join_ibss              = mtk_p2p_cfg80211_join_ibss,
759     .leave_ibss             = mtk_p2p_cfg80211_leave_ibss,
760     .set_tx_power           = mtk_p2p_cfg80211_set_txpower,
761     .get_tx_power           = mtk_p2p_cfg80211_get_txpower,
762     .set_power_mgmt         = mtk_p2p_cfg80211_set_power_mgmt,
763     #ifdef CONFIG_NL80211_TESTMODE
764     .testmode_cmd           = mtk_p2p_cfg80211_testmode_cmd,
765     #endif
766 #endif
767 };
768
769
770
771 /* There isn't a lot of sense in it, but you can transmit anything you like */
772 static const struct ieee80211_txrx_stypes
773 mtk_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
774         [NL80211_IFTYPE_ADHOC] = {
775                 .tx = 0xffff,
776                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
777         },
778         [NL80211_IFTYPE_STATION] = {
779                 .tx = 0xffff,
780                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
781                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
782         },
783         [NL80211_IFTYPE_AP] = {
784                 .tx = 0xffff,
785                 .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
786                 BIT(IEEE80211_STYPE_ACTION >> 4)
787         },
788         [NL80211_IFTYPE_AP_VLAN] = {
789                 /* copy AP */
790                 .tx = 0xffff,
791                 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
792                 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
793                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
794                 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
795                 BIT(IEEE80211_STYPE_AUTH >> 4) |
796                 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
797                 BIT(IEEE80211_STYPE_ACTION >> 4)
798         },
799         [NL80211_IFTYPE_P2P_CLIENT] = {
800                 .tx = 0xffff,
801                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
802                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
803         },
804         [NL80211_IFTYPE_P2P_GO] = {
805                 .tx = 0xffff,
806                 .rx = BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
807                 BIT(IEEE80211_STYPE_ACTION >> 4)
808         }
809 };
810
811
812
813 #endif
814
815 /* the legacy wireless extension stuff */
816 static const iw_handler rP2PIwStandardHandler[] = {
817     [SIOCGIWPRIV        - SIOCIWFIRST]  = mtk_p2p_wext_get_priv,
818     [SIOCGIWSCAN        - SIOCIWFIRST]  = mtk_p2p_wext_discovery_results,
819     [SIOCSIWESSID       - SIOCIWFIRST]  = mtk_p2p_wext_reconnect,
820     [SIOCSIWAUTH        - SIOCIWFIRST]  = mtk_p2p_wext_set_auth,
821     [SIOCSIWENCODEEXT   - SIOCIWFIRST]  = mtk_p2p_wext_set_key,
822     [SIOCSIWPOWER       - SIOCIWFIRST]  = mtk_p2p_wext_set_powermode,
823     [SIOCGIWPOWER       - SIOCIWFIRST]  = mtk_p2p_wext_get_powermode,
824     [SIOCSIWTXPOW       - SIOCIWFIRST]  = mtk_p2p_wext_set_txpow,
825 #if CFG_SUPPORT_P2P_RSSI_QUERY
826     [SIOCGIWSTATS       - SIOCIWFIRST]  = mtk_p2p_wext_get_rssi,
827 #endif
828     [SIOCSIWMLME        - SIOCIWFIRST]  = mtk_p2p_wext_mlme_handler,
829 };
830
831 static const iw_handler rP2PIwPrivHandler[] = {
832     [IOC_P2P_CFG_DEVICE                 - SIOCIWFIRSTPRIV]  = mtk_p2p_wext_set_local_dev_info,
833     [IOC_P2P_PROVISION_COMPLETE         - SIOCIWFIRSTPRIV]  = mtk_p2p_wext_set_provision_complete,
834     [IOC_P2P_START_STOP_DISCOVERY       - SIOCIWFIRSTPRIV]  = mtk_p2p_wext_start_stop_discovery,
835     [IOC_P2P_DISCOVERY_RESULTS          - SIOCIWFIRSTPRIV]  = mtk_p2p_wext_discovery_results,
836     [IOC_P2P_WSC_BEACON_PROBE_RSP_IE    - SIOCIWFIRSTPRIV]  = mtk_p2p_wext_wsc_ie,
837     [IOC_P2P_CONNECT_DISCONNECT         - SIOCIWFIRSTPRIV]  = mtk_p2p_wext_connect_disconnect,
838     [IOC_P2P_PASSWORD_READY             - SIOCIWFIRSTPRIV]  = mtk_p2p_wext_password_ready,
839 //    [IOC_P2P_SET_PWR_MGMT_PARAM         - SIOCIWFIRSTPRIV]  = mtk_p2p_wext_set_pm_param,
840     [IOC_P2P_SET_INT                    - SIOCIWFIRSTPRIV]  = mtk_p2p_wext_set_int,
841     [IOC_P2P_GET_STRUCT                 - SIOCIWFIRSTPRIV]  = mtk_p2p_wext_get_struct,
842     [IOC_P2P_SET_STRUCT                 - SIOCIWFIRSTPRIV]  = mtk_p2p_wext_set_struct,
843     [IOC_P2P_GET_REQ_DEVICE_INFO        - SIOCIWFIRSTPRIV]  = mtk_p2p_wext_request_dev_info,
844 };
845
846
847 static const struct iw_priv_args rP2PIwPrivTable[] = {
848     {
849         .cmd = IOC_P2P_CFG_DEVICE,
850         .set_args = IW_PRIV_TYPE_BYTE | (__u16)sizeof(IW_P2P_CFG_DEVICE_TYPE),
851         .get_args = IW_PRIV_TYPE_NONE,
852         .name = "P2P_CFG_DEVICE"
853     },
854     {
855         .cmd = IOC_P2P_START_STOP_DISCOVERY,
856         .set_args = IW_PRIV_TYPE_BYTE | (__u16)sizeof(IW_P2P_REQ_DEVICE_TYPE),
857         .get_args = IW_PRIV_TYPE_NONE,
858         .name = "P2P_DISCOVERY"
859     },
860     {
861         .cmd = IOC_P2P_DISCOVERY_RESULTS,
862         .set_args = IW_PRIV_TYPE_NONE,
863         .get_args = IW_PRIV_TYPE_NONE,
864         .name = "P2P_RESULT"
865     },
866     {
867         .cmd = IOC_P2P_WSC_BEACON_PROBE_RSP_IE,
868         .set_args = IW_PRIV_TYPE_BYTE | (__u16)sizeof(IW_P2P_HOSTAPD_PARAM),
869         .get_args = IW_PRIV_TYPE_NONE,
870         .name = "P2P_WSC_IE"
871     },
872     {
873         .cmd = IOC_P2P_CONNECT_DISCONNECT,
874         .set_args = IW_PRIV_TYPE_BYTE | (__u16)sizeof(IW_P2P_CONNECT_DEVICE),
875         .get_args = IW_PRIV_TYPE_NONE,
876         .name = "P2P_CONNECT"
877     },
878     {
879         .cmd = IOC_P2P_PASSWORD_READY,
880         .set_args = IW_PRIV_TYPE_BYTE | (__u16)sizeof(IW_P2P_PASSWORD_READY),
881         .get_args = IW_PRIV_TYPE_NONE,
882         .name = "P2P_PASSWD_RDY"
883     },
884     {
885         .cmd = IOC_P2P_GET_STRUCT,
886         .set_args = IW_PRIV_TYPE_NONE,
887         .get_args = 256,
888         .name = "P2P_GET_STRUCT"
889     },
890     {
891         .cmd = IOC_P2P_SET_STRUCT,
892         .set_args = 256,
893         .get_args = IW_PRIV_TYPE_NONE,
894         .name = "P2P_SET_STRUCT"
895     },
896     {
897         .cmd = IOC_P2P_GET_REQ_DEVICE_INFO,
898         .set_args = IW_PRIV_TYPE_NONE,
899         .get_args = IW_PRIV_TYPE_BYTE | (__u16)sizeof(IW_P2P_DEVICE_REQ),
900         .name = "P2P_GET_REQDEV"
901     },
902     {
903         /* SET STRUCT sub-ioctls commands */
904         .cmd = PRIV_CMD_OID,
905         .set_args = 256,
906         .get_args = IW_PRIV_TYPE_NONE,
907         .name = "set_oid"
908     },
909     {
910         /* GET STRUCT sub-ioctls commands */
911         .cmd = PRIV_CMD_OID,
912         .set_args = IW_PRIV_TYPE_NONE,
913         .get_args = 256,
914         .name = "get_oid"
915     }
916 };
917
918 const struct iw_handler_def mtk_p2p_wext_handler_def = {
919     .num_standard       = (__u16)sizeof(rP2PIwStandardHandler)/sizeof(iw_handler),
920     .num_private        = (__u16)sizeof(rP2PIwPrivHandler)/sizeof(iw_handler),
921     .num_private_args   = (__u16)sizeof(rP2PIwPrivTable)/sizeof(struct iw_priv_args),
922     .standard           = rP2PIwStandardHandler,
923     .private            = rP2PIwPrivHandler,
924     .private_args       = rP2PIwPrivTable,
925 #if CFG_SUPPORT_P2P_RSSI_QUERY
926     .get_wireless_stats = mtk_p2p_wext_get_wireless_stats,
927 #else
928     .get_wireless_stats = NULL,
929 #endif
930 };
931
932 /*******************************************************************************
933 *                                 M A C R O S
934 ********************************************************************************
935 */
936
937 /*******************************************************************************
938 *                   F U N C T I O N   D E C L A R A T I O N S
939 ********************************************************************************
940 */
941 /* for IE Searching */
942 extern BOOLEAN
943 wextSrchDesiredWPAIE (
944     IN  PUINT_8         pucIEStart,
945     IN  INT_32          i4TotalIeLen,
946     IN  UINT_8          ucDesiredElemId,
947     OUT PUINT_8         *ppucDesiredIE
948     );
949
950 #if CFG_SUPPORT_WPS
951 extern BOOLEAN
952 wextSrchDesiredWPSIE (
953     IN PUINT_8 pucIEStart,
954     IN INT_32 i4TotalIeLen,
955     IN UINT_8 ucDesiredElemId,
956     OUT PUINT_8 *ppucDesiredIE
957     );
958 #endif
959
960 /* Net Device Hooks */
961 static int
962 p2pOpen(
963     IN struct net_device *prDev
964     );
965
966 static int
967 p2pStop(
968     IN struct net_device *prDev
969     );
970
971 static struct net_device_stats *
972 p2pGetStats (
973     IN struct net_device *prDev
974     );
975
976 static void
977 p2pSetMulticastList(
978     IN struct net_device *prDev
979     );
980
981 static int
982 p2pHardStartXmit(
983     IN struct sk_buff *prSkb,
984     IN struct net_device *prDev
985     );
986
987 static int
988 p2pDoIOCTL(
989     struct net_device *prDev,
990     struct ifreq *prIFReq,
991     int i4Cmd
992     );
993
994 static int
995 p2pSetMACAddress(
996     IN struct net_device *prDev,
997     void *addr
998     );
999
1000
1001 /*----------------------------------------------------------------------------*/
1002 /*!
1003 * \brief Override the implementation of select queue
1004 *
1005 * \param[in] dev Pointer to struct net_device
1006 * \param[in] skb Pointer to struct skb_buff
1007 *
1008 * \return (none)
1009 */
1010 /*----------------------------------------------------------------------------*/
1011
1012 unsigned int _p2p_cfg80211_classify8021d(struct sk_buff *skb)
1013 {
1014     unsigned int dscp = 0;
1015
1016     /* skb->priority values from 256->263 are magic values
1017      * directly indicate a specific 802.1d priority.  This is
1018      * to allow 802.1d priority to be passed directly in from
1019      * tags
1020      */
1021
1022     if (skb->priority >= 256 && skb->priority <= 263) {
1023         return skb->priority - 256;
1024     }
1025     switch (skb->protocol) {
1026         case htons(ETH_P_IP):
1027             dscp = ip_hdr(skb)->tos & 0xfc;
1028             break;
1029     }
1030     return dscp >> 5;
1031 }
1032
1033
1034 static const UINT_16 au16Wlan1dToQueueIdx[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
1035
1036 static UINT_16
1037 p2pSelectQueue(
1038     struct net_device *dev,
1039     struct sk_buff *skb)
1040 {
1041     skb->priority = _p2p_cfg80211_classify8021d(skb);
1042
1043     return au16Wlan1dToQueueIdx[skb->priority];
1044 }
1045
1046 static struct net_device *g_P2pPrDev;
1047
1048
1049 /*----------------------------------------------------------------------------*/
1050 /*!
1051 * \brief A function for prDev->init
1052 *
1053 * \param[in] prDev      Pointer to struct net_device.
1054 *
1055 * \retval 0         The execution of wlanInit succeeds.
1056 * \retval -ENXIO    No such device.
1057 */
1058 /*----------------------------------------------------------------------------*/
1059 static int
1060 p2pInit(
1061     struct net_device *prDev
1062     )
1063 {
1064     if (!prDev) {
1065         return -ENXIO;
1066     }
1067
1068     return 0; /* success */
1069 } /* end of p2pInit() */
1070
1071
1072 /*----------------------------------------------------------------------------*/
1073 /*!
1074 * \brief A function for prDev->uninit
1075 *
1076 * \param[in] prDev      Pointer to struct net_device.
1077 *
1078 * \return (none)
1079 */
1080 /*----------------------------------------------------------------------------*/
1081 static void
1082 p2pUninit (
1083     IN struct net_device *prDev
1084     )
1085 {
1086
1087
1088     return;
1089 } /* end of p2pUninit() */
1090
1091
1092
1093
1094
1095
1096 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
1097 static const struct net_device_ops p2p_netdev_ops = {
1098     .ndo_open               = p2pOpen,
1099     .ndo_stop               = p2pStop,
1100     .ndo_set_mac_address    = p2pSetMACAddress,
1101 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
1102     .ndo_set_rx_mode = p2pSetMulticastList,
1103 #else
1104     .ndo_set_multicast_list = p2pSetMulticastList,
1105 #endif
1106     .ndo_get_stats          = p2pGetStats,
1107     .ndo_do_ioctl           = p2pDoIOCTL,
1108     .ndo_start_xmit         = p2pHardStartXmit,
1109     .ndo_select_queue =  p2pSelectQueue,
1110     .ndo_init           = p2pInit,
1111     .ndo_uninit         = p2pUninit,
1112 };
1113
1114
1115 #endif
1116
1117
1118 /*******************************************************************************
1119 *                              F U N C T I O N S
1120 ********************************************************************************
1121 */
1122
1123 /*----------------------------------------------------------------------------*/
1124 /*!
1125 * \brief Allocate memory for P2P_INFO, GL_P2P_INFO, P2P_CONNECTION_SETTINGS
1126 *                                          P2P_SPECIFIC_BSS_INFO, P2P_FSM_INFO
1127 *
1128 * \param[in] prGlueInfo      Pointer to glue info
1129 *
1130 * \return   TRUE
1131 *           FALSE
1132 */
1133 /*----------------------------------------------------------------------------*/
1134 BOOLEAN
1135 p2PAllocInfo (
1136     IN P_GLUE_INFO_T prGlueInfo
1137     )
1138 {
1139     P_ADAPTER_T prAdapter = NULL;
1140     P_WIFI_VAR_T prWifiVar = NULL;
1141
1142     ASSERT(prGlueInfo);
1143
1144     prAdapter = prGlueInfo->prAdapter;
1145     prWifiVar = &(prAdapter->rWifiVar);
1146
1147     ASSERT(prAdapter);
1148     ASSERT(prWifiVar);
1149
1150     do {
1151         if (prGlueInfo == NULL) {
1152             break;
1153         }
1154
1155         if (prGlueInfo->prP2PInfo == NULL) {
1156             /*alloc memory for p2p info */
1157             prGlueInfo->prP2PInfo =
1158                 kalMemAlloc(sizeof(GL_P2P_INFO_T), VIR_MEM_TYPE);
1159             prAdapter->prP2pInfo =
1160                 kalMemAlloc(sizeof(P2P_INFO_T), VIR_MEM_TYPE);
1161             prWifiVar->prP2PConnSettings =
1162                 kalMemAlloc(sizeof(P2P_CONNECTION_SETTINGS_T),VIR_MEM_TYPE);
1163             prWifiVar->prP2pFsmInfo =
1164                 kalMemAlloc(sizeof(P2P_FSM_INFO_T),VIR_MEM_TYPE);
1165             prWifiVar->prP2pSpecificBssInfo =
1166                 kalMemAlloc(sizeof(P2P_SPECIFIC_BSS_INFO_T),VIR_MEM_TYPE);
1167         }
1168         else {
1169             ASSERT(prAdapter->prP2pInfo != NULL);
1170             ASSERT(prWifiVar->prP2PConnSettings != NULL);
1171             ASSERT(prWifiVar->prP2pFsmInfo != NULL);
1172             ASSERT(prWifiVar->prP2pSpecificBssInfo != NULL);
1173         }
1174         /*MUST set memory to 0 */
1175         kalMemZero(prGlueInfo->prP2PInfo, sizeof(GL_P2P_INFO_T));
1176         kalMemZero(prAdapter->prP2pInfo, sizeof(P2P_INFO_T));
1177         kalMemZero(prWifiVar->prP2PConnSettings, sizeof(P2P_CONNECTION_SETTINGS_T));
1178         kalMemZero(prWifiVar->prP2pFsmInfo, sizeof(P2P_FSM_INFO_T));
1179         kalMemZero(prWifiVar->prP2pSpecificBssInfo, sizeof(P2P_SPECIFIC_BSS_INFO_T));
1180         
1181     } while (FALSE);
1182         
1183
1184     /* chk if alloc successful or not*/
1185     if (prGlueInfo->prP2PInfo &&
1186             prAdapter->prP2pInfo &&
1187             prWifiVar->prP2PConnSettings &&
1188             prWifiVar->prP2pFsmInfo &&
1189             prWifiVar->prP2pSpecificBssInfo) {
1190         return TRUE;
1191     }
1192     else {
1193
1194         if (prWifiVar->prP2pSpecificBssInfo) {
1195             kalMemFree(prWifiVar->prP2pSpecificBssInfo, VIR_MEM_TYPE, sizeof(P2P_SPECIFIC_BSS_INFO_T));
1196
1197             prWifiVar->prP2pSpecificBssInfo = NULL;
1198         }
1199         if (prWifiVar->prP2pFsmInfo) {
1200             kalMemFree(prWifiVar->prP2pFsmInfo, VIR_MEM_TYPE, sizeof(P2P_FSM_INFO_T));
1201
1202             prWifiVar->prP2pFsmInfo = NULL;
1203         }
1204         if (prWifiVar->prP2PConnSettings) {
1205             kalMemFree(prWifiVar->prP2PConnSettings, VIR_MEM_TYPE, sizeof(P2P_CONNECTION_SETTINGS_T));
1206
1207             prWifiVar->prP2PConnSettings = NULL;
1208         }
1209         if (prGlueInfo->prP2PInfo) {
1210             kalMemFree(prGlueInfo->prP2PInfo, VIR_MEM_TYPE, sizeof(GL_P2P_INFO_T));
1211
1212             prGlueInfo->prP2PInfo = NULL;
1213         }
1214         if (prAdapter->prP2pInfo) {
1215             kalMemFree(prAdapter->prP2pInfo, VIR_MEM_TYPE, sizeof(P2P_INFO_T));
1216
1217             prAdapter->prP2pInfo = NULL;
1218         }
1219         return FALSE;
1220     }
1221
1222 }
1223
1224
1225 /*----------------------------------------------------------------------------*/
1226 /*!
1227 * \brief Free memory for P2P_INFO, GL_P2P_INFO, P2P_CONNECTION_SETTINGS
1228 *                                          P2P_SPECIFIC_BSS_INFO, P2P_FSM_INFO
1229 *
1230 * \param[in] prGlueInfo      Pointer to glue info
1231 *
1232 * \return   TRUE
1233 *           FALSE
1234 */
1235 /*----------------------------------------------------------------------------*/
1236 BOOLEAN
1237 p2PFreeInfo(
1238     P_GLUE_INFO_T prGlueInfo
1239     )
1240 {
1241
1242     ASSERT(prGlueInfo);
1243     ASSERT(prGlueInfo->prAdapter);
1244
1245     /* free memory after p2p module is ALREADY unregistered */
1246     if(prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) {
1247
1248         kalMemFree(prGlueInfo->prAdapter->prP2pInfo, VIR_MEM_TYPE, sizeof(P2P_INFO_T));
1249         kalMemFree(prGlueInfo->prP2PInfo, VIR_MEM_TYPE, sizeof(GL_P2P_INFO_T));
1250         kalMemFree(prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings, VIR_MEM_TYPE, sizeof(P2P_CONNECTION_SETTINGS_T));
1251         kalMemFree(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo, VIR_MEM_TYPE, sizeof(P2P_FSM_INFO_T));
1252         kalMemFree(prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo, VIR_MEM_TYPE, sizeof(P2P_SPECIFIC_BSS_INFO_T));
1253
1254         /*Reomve p2p bss scan list*/
1255         scanRemoveAllP2pBssDesc(prGlueInfo->prAdapter);
1256
1257         /*reset all pointer to NULL */
1258         prGlueInfo->prP2PInfo = NULL;
1259         prGlueInfo->prAdapter->prP2pInfo = NULL;
1260         prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings = NULL;
1261         prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo = NULL;
1262         prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo = NULL;
1263
1264         return TRUE;
1265     }
1266     else {
1267         return FALSE;
1268     }
1269
1270 }
1271
1272 /*----------------------------------------------------------------------------*/
1273 /*!
1274 * \brief Enable Channel  for cfg80211 for Wi-Fi Direct based on current country code
1275 *
1276 * \param[in] prGlueInfo      Pointer to glue info
1277 *
1278 * \return   TRUE
1279 *           FALSE
1280 */
1281 /*----------------------------------------------------------------------------*/
1282 VOID
1283 p2pEnableChannel(
1284     PUINT_8 pucChIdx,
1285     UINT_8 ucChannelNum,
1286     struct ieee80211_channel *mtk_channels,
1287     UINT_8 mtk_channel_sz
1288 )
1289 {
1290     UINT_8 ucCurChIdx = *pucChIdx;
1291
1292     while(TRUE) {
1293         (*pucChIdx)++;
1294         (*pucChIdx) %= mtk_channel_sz;
1295
1296         if(ucChannelNum == mtk_channels[*pucChIdx].hw_value) {
1297             mtk_channels[*pucChIdx].flags &= ~IEEE80211_CHAN_DISABLED;
1298             break;
1299         }
1300
1301         if(*pucChIdx == ucCurChIdx) {
1302             printk(KERN_ALERT DRV_NAME "Orphan channel [%d]\n", ucChannelNum);
1303             break;
1304         }
1305     }
1306 }
1307
1308
1309 BOOLEAN
1310 p2pNetRegister(
1311     P_GLUE_INFO_T prGlueInfo,
1312     BOOLEAN fgIsRtnlLockAcquired
1313     )
1314 {
1315     BOOLEAN fgDoRegister = FALSE;
1316     BOOLEAN fgRollbackRtnlLock = FALSE;
1317     BOOLEAN ret;
1318
1319     GLUE_SPIN_LOCK_DECLARATION();
1320
1321     ASSERT(prGlueInfo);
1322     ASSERT(prGlueInfo->prAdapter);
1323
1324
1325     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
1326     if(prGlueInfo->prAdapter->rP2PNetRegState == ENUM_NET_REG_STATE_UNREGISTERED) {
1327         prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_REGISTERING;
1328         fgDoRegister = TRUE;
1329     }
1330     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
1331
1332     if(!fgDoRegister) {
1333         return TRUE;
1334     }
1335
1336     if(fgIsRtnlLockAcquired && rtnl_is_locked()) {
1337         fgRollbackRtnlLock = TRUE;
1338         rtnl_unlock();
1339     }
1340
1341     /* Here are functions which need rtnl_lock */
1342     wiphy_register(prGlueInfo->prP2PInfo->wdev.wiphy);
1343
1344     /* net device initialize */
1345     netif_carrier_off(prGlueInfo->prP2PInfo->prDevHandler);
1346     netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler);
1347
1348     /* register for net device */
1349     if (register_netdev(prGlueInfo->prP2PInfo->prDevHandler) < 0) {
1350         printk(KERN_ALERT DRV_NAME "unable to register netdevice for p2p\n");
1351
1352         free_netdev(prGlueInfo->prP2PInfo->prDevHandler);
1353
1354         ret = FALSE;
1355     }
1356     else {
1357         prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_REGISTERED;
1358         ret = TRUE;
1359     }
1360
1361     if(fgRollbackRtnlLock) {
1362         rtnl_lock();
1363     }
1364
1365     return ret;
1366 }
1367
1368 BOOLEAN
1369 p2pNetUnregister(
1370     P_GLUE_INFO_T prGlueInfo,
1371     BOOLEAN fgIsRtnlLockAcquired
1372     )
1373 {
1374     BOOLEAN fgDoUnregister = FALSE;
1375     BOOLEAN fgRollbackRtnlLock = FALSE;
1376
1377     GLUE_SPIN_LOCK_DECLARATION();
1378
1379     ASSERT(prGlueInfo);
1380     ASSERT(prGlueInfo->prAdapter);
1381
1382     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
1383     if(prGlueInfo->prAdapter->rP2PNetRegState == ENUM_NET_REG_STATE_REGISTERED) {
1384         prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_UNREGISTERING;
1385         fgDoUnregister = TRUE;
1386     }
1387     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
1388
1389     if(!fgDoUnregister) {
1390         return TRUE;
1391     }
1392
1393     /* prepare for removal */
1394     if(netif_carrier_ok(prGlueInfo->prP2PInfo->prDevHandler)) {
1395         netif_carrier_off(prGlueInfo->prP2PInfo->prDevHandler);
1396     }
1397
1398     netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler);
1399
1400     if(fgIsRtnlLockAcquired && rtnl_is_locked()) {
1401         fgRollbackRtnlLock = TRUE;
1402         rtnl_unlock();
1403     }
1404     /* Here are functions which need rtnl_lock */
1405
1406     unregister_netdev(prGlueInfo->prP2PInfo->prDevHandler);
1407
1408     wiphy_unregister(prGlueInfo->prP2PInfo->wdev.wiphy);
1409
1410     if(fgRollbackRtnlLock) {
1411         rtnl_lock();
1412     }
1413
1414     prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_UNREGISTERED;
1415
1416     return TRUE;
1417 }
1418
1419
1420 /*----------------------------------------------------------------------------*/
1421 /*!
1422 * \brief Update Channel table for cfg80211 for Wi-Fi Direct based on current country code
1423 *
1424 * \param[in] prGlueInfo      Pointer to glue info
1425 *
1426 * \return   TRUE
1427 *           FALSE
1428 */
1429 /*----------------------------------------------------------------------------*/
1430 VOID
1431 p2pUpdateChannelTableByDomain(
1432     P_GLUE_INFO_T prGlueInfo
1433     )
1434 {
1435     UINT_8 i, uc2gChIdx, uc5gChIdx;
1436     UINT_8 ucMaxChannelNum = ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_a_channels);
1437     UINT_8 ucNumOfChannel = ucMaxChannelNum;
1438     RF_CHANNEL_INFO_T aucChannelList[ucMaxChannelNum];
1439
1440     uc2gChIdx = uc5gChIdx = 0;
1441
1442     // 1. Disable all channel
1443     for(i = 0; i < ARRAY_SIZE(mtk_2ghz_channels); i++) {
1444         mtk_2ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED;
1445     }
1446     for(i = 0; i < ARRAY_SIZE(mtk_5ghz_a_channels); i++) {
1447         mtk_5ghz_a_channels[i].flags |= IEEE80211_CHAN_DISABLED;
1448     }
1449
1450     // 2. Get current domain channel list
1451     rlmDomainGetChnlList(prGlueInfo->prAdapter, BAND_NULL, ucMaxChannelNum, &ucNumOfChannel, aucChannelList);
1452
1453     // 3. Enable specific channel based on domain channel list
1454     for(i = 0; i < ucNumOfChannel; i++) {
1455         switch(aucChannelList[i].eBand) {
1456             case BAND_2G4:
1457                 p2pEnableChannel(&uc2gChIdx, aucChannelList[i].ucChannelNum, mtk_2ghz_channels, ARRAY_SIZE(mtk_2ghz_channels));
1458                 break;
1459
1460             case BAND_5G:
1461                 p2pEnableChannel(&uc5gChIdx, aucChannelList[i].ucChannelNum, mtk_5ghz_a_channels, ARRAY_SIZE(mtk_5ghz_a_channels));
1462                 break;
1463
1464             default:
1465                 printk(KERN_ALERT DRV_NAME "Unknow band.\n");
1466                 break;
1467
1468         }
1469     }
1470
1471 }
1472
1473 /*----------------------------------------------------------------------------*/
1474 /*!
1475 * \brief Register for cfg80211 for Wi-Fi Direct
1476 *
1477 * \param[in] prGlueInfo      Pointer to glue info
1478 *
1479 * \return   TRUE
1480 *           FALSE
1481 */
1482 /*----------------------------------------------------------------------------*/
1483 BOOLEAN
1484 glRegisterP2P(
1485     P_GLUE_INFO_T prGlueInfo,
1486     const char *prDevName,
1487     BOOLEAN fgIsApMode
1488     )
1489 {
1490     P_ADAPTER_T prAdapter = NULL;
1491     P_GL_HIF_INFO_T prHif = NULL;
1492     PARAM_MAC_ADDRESS rMacAddr;
1493 #if CFG_ENABLE_WIFI_DIRECT_CFG_80211
1494     struct device *prDev;
1495 #endif
1496
1497     ASSERT(prGlueInfo);
1498
1499     prAdapter = prGlueInfo->prAdapter;
1500     ASSERT(prAdapter);
1501
1502     prHif = &prGlueInfo->rHifInfo;
1503     ASSERT(prHif);
1504
1505     printk("glRegisterP2P\n");
1506
1507     /*0. allocate p2pinfo */
1508     if(!p2PAllocInfo(prGlueInfo)) {
1509         printk(KERN_ALERT DRV_NAME "Allocate memory for p2p FAILED\n");
1510         ASSERT(0);
1511         return FALSE;
1512     }
1513 #if CFG_ENABLE_WIFI_DIRECT_CFG_80211
1514     /* 1. allocate WIPHY */
1515     prGlueInfo->prP2PInfo->wdev.wiphy = wiphy_new(&mtk_p2p_config_ops, sizeof(P_GLUE_INFO_T));
1516     if (!prGlueInfo->prP2PInfo->wdev.wiphy) {
1517         printk(KERN_ALERT DRV_NAME "unable to allocate wiphy for p2p\n");
1518
1519         goto err_alloc_wiphy;
1520     }
1521
1522     /* 1.1 fill wiphy parameters */
1523 #if MTK_WCN_HIF_SDIO
1524     mtk_wcn_hif_sdio_get_dev(prHif->cltCtx, &prDev);
1525     if(!prDev) {
1526         printk(KERN_ALERT DRV_NAME "unable to get struct dev for p2p\n");
1527     }
1528 #else
1529     prDev = &(prHif->func->dev);
1530 #endif
1531     set_wiphy_dev(prGlueInfo->prP2PInfo->wdev.wiphy, prDev);
1532
1533     prGlueInfo->prP2PInfo->wdev.wiphy->interface_modes = BIT(NL80211_IFTYPE_AP)
1534                                                        | BIT(NL80211_IFTYPE_P2P_CLIENT)
1535                                                        | BIT(NL80211_IFTYPE_P2P_GO)
1536                                                        | BIT(NL80211_IFTYPE_STATION);
1537
1538     p2pUpdateChannelTableByDomain(prGlueInfo);
1539     prGlueInfo->prP2PInfo->wdev.wiphy->bands[IEEE80211_BAND_2GHZ] = &mtk_band_2ghz;
1540     if(prAdapter->fgEnable5GBand) {
1541         prGlueInfo->prP2PInfo->wdev.wiphy->bands[IEEE80211_BAND_5GHZ] = &mtk_band_5ghz;
1542     }
1543
1544     prGlueInfo->prP2PInfo->wdev.wiphy->mgmt_stypes = mtk_cfg80211_default_mgmt_stypes;
1545     prGlueInfo->prP2PInfo->wdev.wiphy->max_remain_on_channel_duration = 5000;
1546     prGlueInfo->prP2PInfo->wdev.wiphy->n_cipher_suites = 5;
1547         prGlueInfo->prP2PInfo->wdev.wiphy->cipher_suites = (const u32*)cipher_suites;
1548 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
1549         prGlueInfo->prP2PInfo->wdev.wiphy->flags = WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
1550 #else
1551         prGlueInfo->prP2PInfo->wdev.wiphy->flags = WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_HAVE_AP_SME;
1552 #endif
1553
1554 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
1555     prGlueInfo->prP2PInfo->wdev.wiphy->max_scan_ssids = MAX_SCAN_LIST_NUM;
1556     prGlueInfo->prP2PInfo->wdev.wiphy->max_scan_ie_len = MAX_SCAN_IE_LEN;
1557     prGlueInfo->prP2PInfo->wdev.wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1558 #endif
1559
1560 #if 0
1561     /* 2. Register WIPHY */
1562     if(wiphy_register(prGlueInfo->prP2PInfo->wdev.wiphy) < 0) {
1563         printk(KERN_ALERT DRV_NAME "Couldn't register wiphy device for p2p\n");
1564
1565         goto err_reg_wiphy;
1566     }
1567 #endif
1568
1569     /* 2.1 set priv as pointer to glue structure */
1570     *((P_GLUE_INFO_T *) wiphy_priv(prGlueInfo->prP2PInfo->wdev.wiphy)) = prGlueInfo;
1571
1572     /* 2.2 wdev initialization */
1573     if(fgIsApMode) {
1574         prGlueInfo->prP2PInfo->wdev.iftype = NL80211_IFTYPE_AP;
1575     } else {
1576         prGlueInfo->prP2PInfo->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT;
1577     }
1578
1579 #endif /* CFG_ENABLE_WIFI_DIRECT_CFG_80211 */
1580
1581     /* 3. allocate netdev */
1582     prGlueInfo->prP2PInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), prDevName, ether_setup, CFG_MAX_TXQ_NUM);
1583     if (!prGlueInfo->prP2PInfo->prDevHandler) {
1584         printk(KERN_ALERT DRV_NAME "unable to allocate netdevice for p2p\n");
1585
1586         printk("unable to allocate netdevice for p2p\n");
1587
1588         goto err_alloc_netdev;
1589     }
1590
1591     /* 4. setup netdev */
1592     /* 4.1 Point to shared glue structure */
1593     *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->prP2PInfo->prDevHandler)) = prGlueInfo;
1594
1595     /* 4.2 fill hardware address */
1596     COPY_MAC_ADDR(rMacAddr, prAdapter->rMyMacAddr);
1597     rMacAddr[0] ^= 0x2; // change to local administrated address
1598     memcpy(prGlueInfo->prP2PInfo->prDevHandler->dev_addr, rMacAddr, ETH_ALEN);
1599     memcpy(prGlueInfo->prP2PInfo->prDevHandler->perm_addr, prGlueInfo->prP2PInfo->prDevHandler->dev_addr, ETH_ALEN);
1600
1601     /* 4.3 register callback functions */
1602 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
1603     prGlueInfo->prP2PInfo->prDevHandler->netdev_ops           = &p2p_netdev_ops;
1604 #else
1605     prGlueInfo->prP2PInfo->prDevHandler->open                 = p2pOpen;
1606     prGlueInfo->prP2PInfo->prDevHandler->stop                 = p2pStop;
1607     prGlueInfo->prP2PInfo->prDevHandler->get_stats            = p2pGetStats;
1608     prGlueInfo->prP2PInfo->prDevHandler->set_multicast_list   = p2pSetMulticastList;
1609     prGlueInfo->prP2PInfo->prDevHandler->hard_start_xmit      = p2pHardStartXmit;
1610     prGlueInfo->prP2PInfo->prDevHandler->do_ioctl             = p2pDoIOCTL;
1611     prGlueInfo->prP2PInfo->prDevHandler->set_mac_address      = p2pSetMACAddress;
1612 #endif
1613 //    prGlueInfo->prP2PInfo->prDevHandler->wireless_handlers    = &mtk_p2p_wext_handler_def;
1614
1615
1616 #if (MTK_WCN_HIF_SDIO == 0)
1617     SET_NETDEV_DEV(prGlueInfo->prP2PInfo->prDevHandler, &(prHif->func->dev));
1618 #endif
1619
1620
1621 #if CFG_ENABLE_WIFI_DIRECT_CFG_80211
1622     prGlueInfo->prP2PInfo->prDevHandler->ieee80211_ptr        = &(prGlueInfo->prP2PInfo->wdev);
1623     prGlueInfo->prP2PInfo->wdev.netdev                        = prGlueInfo->prP2PInfo->prDevHandler;
1624 #endif
1625
1626 #if CFG_TCP_IP_CHKSUM_OFFLOAD
1627     prGlueInfo->prP2PInfo->prDevHandler->features = NETIF_F_IP_CSUM;
1628 #endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
1629
1630 #if 0
1631     /* 7. net device initialize */
1632     netif_carrier_off(prGlueInfo->prP2PInfo->prDevHandler);
1633     netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler);
1634
1635     /* 8. register for net device */
1636     if (register_netdev(prGlueInfo->prP2PInfo->prDevHandler) < 0) {
1637         printk(KERN_ALERT DRV_NAME "unable to register netdevice for p2p\n");
1638
1639         goto err_reg_netdev;
1640     }
1641 #endif
1642
1643     /* 8. set p2p net device register state */
1644     prGlueInfo->prAdapter->rP2PNetRegState = ENUM_NET_REG_STATE_UNREGISTERED;
1645
1646     /* 9. setup running mode*/
1647     prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode = fgIsApMode;
1648
1649     /* 10. finish */
1650     p2pFsmInit(prAdapter);
1651
1652     p2pFuncInitConnectionSettings(prAdapter, prAdapter->rWifiVar.prP2PConnSettings);
1653
1654     /* Active network too early would cause HW not able to sleep. 
1655          * Defer the network active time.
1656          */
1657 //    nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX);
1658
1659     return TRUE;
1660 #if 0
1661 err_reg_netdev:
1662     free_netdev(prGlueInfo->prP2PInfo->prDevHandler);
1663 #endif
1664 err_alloc_netdev:
1665 #if CFG_ENABLE_WIFI_DIRECT_CFG_80211
1666 //    wiphy_unregister(prGlueInfo->prP2PInfo->wdev.wiphy);
1667
1668 //err_reg_wiphy:
1669     wiphy_free(prGlueInfo->prP2PInfo->wdev.wiphy);
1670     prGlueInfo->prP2PInfo->wdev.wiphy = NULL;
1671
1672 err_alloc_wiphy:
1673 #endif
1674
1675     return FALSE;
1676 } /* end of glRegisterP2P() */
1677
1678
1679 /*----------------------------------------------------------------------------*/
1680 /*!
1681 * \brief Unregister Net Device for Wi-Fi Direct
1682 *
1683 * \param[in] prGlueInfo      Pointer to glue info
1684 *
1685 * \return   TRUE
1686 *           FALSE
1687 */
1688 /*----------------------------------------------------------------------------*/
1689 BOOLEAN
1690 glUnregisterP2P(
1691     P_GLUE_INFO_T prGlueInfo
1692     )
1693 {
1694     ASSERT(prGlueInfo);
1695
1696     p2pFsmUninit(prGlueInfo->prAdapter);
1697
1698     nicDeactivateNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_P2P_INDEX);
1699
1700 #if 0
1701     /* Release command, mgmt and security frame belong to P2P network in
1702          *   prGlueInfo->prCmdQue
1703          *   prAdapter->rPendingCmdQueue
1704          *   prAdapter->rTxCtrl.rTxMgmtTxingQueue
1705          *  To ensure there is no pending CmdDone/TxDone handler to be executed after p2p module is removed.
1706          */
1707
1708     /* Clear CmdQue*/
1709     kalClearMgmtFramesByNetType(prGlueInfo, NETWORK_TYPE_P2P_INDEX);
1710     kalClearSecurityFramesByNetType(prGlueInfo, NETWORK_TYPE_P2P_INDEX);
1711     /* Clear PendingCmdQue*/
1712     wlanReleasePendingCMDbyNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_P2P_INDEX);
1713     /* Clear PendingTxMsdu */
1714     nicFreePendingTxMsduInfoByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_P2P_INDEX);
1715 #endif
1716
1717 #if 0
1718     /* prepare for removal */
1719     if(netif_carrier_ok(prGlueInfo->prP2PInfo->prDevHandler)) {
1720         netif_carrier_off(prGlueInfo->prP2PInfo->prDevHandler);
1721     }
1722
1723     netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler);
1724
1725     /* netdevice unregistration & free */
1726     unregister_netdev(prGlueInfo->prP2PInfo->prDevHandler);
1727 #endif
1728     free_netdev(prGlueInfo->prP2PInfo->prDevHandler);
1729     prGlueInfo->prP2PInfo->prDevHandler = NULL;
1730
1731 #if CFG_ENABLE_WIFI_DIRECT_CFG_80211
1732 #if 0
1733     wiphy_unregister(prGlueInfo->prP2PInfo->wdev.wiphy);
1734 #endif
1735     wiphy_free(prGlueInfo->prP2PInfo->wdev.wiphy);
1736     prGlueInfo->prP2PInfo->wdev.wiphy = NULL;
1737 #endif
1738
1739     /* Free p2p memory */
1740 #if 1
1741     if(!p2PFreeInfo(prGlueInfo)) {
1742         printk(KERN_ALERT DRV_NAME "Free memory for p2p FAILED\n");
1743         ASSERT(0);
1744         return FALSE;
1745     }
1746 #endif
1747     return TRUE;
1748
1749 } /* end of glUnregisterP2P() */
1750
1751
1752 /*----------------------------------------------------------------------------*/
1753 /*!
1754  * \brief A function for stop p2p fsm immediate
1755  *
1756  * \param[in] prGlueInfo      Pointer to struct P_GLUE_INFO_T.
1757  *
1758  * \retval TRUE     The execution succeeds.
1759  * \retval FALSE   The execution failed.
1760  */
1761 /*----------------------------------------------------------------------------*/
1762 BOOLEAN
1763 p2pStopImmediate(
1764     P_GLUE_INFO_T prGlueInfo
1765     )
1766 {
1767 //    P_ADAPTER_T prAdapter = NULL;
1768 //    P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch;
1769
1770     ASSERT(prGlueInfo);
1771
1772 //    prAdapter = prGlueInfo->prAdapter;
1773 //    ASSERT(prAdapter);
1774
1775     /* 1. stop TX queue */
1776     netif_tx_stop_all_queues(prGlueInfo->prP2PInfo->prDevHandler);
1777
1778
1779 #if 0
1780     /* 2. switch P2P-FSM off */
1781     /* 2.1 allocate for message */
1782     prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(
1783             prAdapter,
1784             RAM_TYPE_MSG,
1785             sizeof(MSG_P2P_FUNCTION_SWITCH_T));
1786
1787     if (!prFuncSwitch) {
1788         ASSERT(0); // Can't trigger P2P FSM
1789         printk(KERN_ALERT DRV_NAME "Allocate for p2p mesasage FAILED\n");
1790         //return -ENOMEM;
1791     }
1792
1793     /* 2.2 fill message */
1794     prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH;
1795     prFuncSwitch->fgIsFuncOn = FALSE;
1796
1797     /* 2.3 send message */
1798     mboxSendMsg(prAdapter,
1799             MBOX_ID_0,
1800             (P_MSG_HDR_T) prFuncSwitch,
1801             MSG_SEND_METHOD_UNBUF);
1802
1803 #endif
1804
1805     /* 3. stop queue and turn off carrier */
1806     prGlueInfo->prP2PInfo->eState = PARAM_MEDIA_STATE_DISCONNECTED;
1807
1808     return TRUE;
1809 } /* end of p2pStop() */
1810
1811
1812 /* Net Device Hooks */
1813 /*----------------------------------------------------------------------------*/
1814 /*!
1815  * \brief A function for net_device open (ifup)
1816  *
1817  * \param[in] prDev      Pointer to struct net_device.
1818  *
1819  * \retval 0     The execution succeeds.
1820  * \retval < 0   The execution failed.
1821  */
1822 /*----------------------------------------------------------------------------*/
1823 static int
1824 p2pOpen(
1825     IN struct net_device *prDev
1826     )
1827 {
1828 //    P_GLUE_INFO_T prGlueInfo = NULL;
1829 //    P_ADAPTER_T prAdapter = NULL;
1830 //    P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch;
1831
1832     ASSERT(prDev);
1833
1834 #if 0   // Move after device name set. (mtk_p2p_set_local_dev_info)
1835     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
1836     ASSERT(prGlueInfo);
1837
1838     prAdapter = prGlueInfo->prAdapter;
1839     ASSERT(prAdapter);
1840
1841     /* 1. switch P2P-FSM on */
1842     /* 1.1 allocate for message */
1843     prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter,
1844             RAM_TYPE_MSG,
1845             sizeof(MSG_P2P_FUNCTION_SWITCH_T));
1846
1847     if (!prFuncSwitch) {
1848         ASSERT(0); // Can't trigger P2P FSM
1849         return -ENOMEM;
1850     }
1851
1852     /* 1.2 fill message */
1853     prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH;
1854     prFuncSwitch->fgIsFuncOn = TRUE;
1855
1856     /* 1.3 send message */
1857     mboxSendMsg(prAdapter,
1858             MBOX_ID_0,
1859             (P_MSG_HDR_T) prFuncSwitch,
1860             MSG_SEND_METHOD_BUF);
1861 #endif
1862
1863     /* 2. carrier on & start TX queue */
1864     netif_carrier_on(prDev);
1865     netif_tx_start_all_queues(prDev);
1866
1867     return 0; /* success */
1868 } /* end of p2pOpen() */
1869
1870
1871 /*----------------------------------------------------------------------------*/
1872 /*!
1873  * \brief A function for net_device stop (ifdown)
1874  *
1875  * \param[in] prDev      Pointer to struct net_device.
1876  *
1877  * \retval 0     The execution succeeds.
1878  * \retval < 0   The execution failed.
1879  */
1880 /*----------------------------------------------------------------------------*/
1881 static int
1882 p2pStop(
1883     IN struct net_device *prDev
1884     )
1885 {
1886     P_GLUE_INFO_T prGlueInfo = NULL;
1887  //   P_ADAPTER_T prAdapter = NULL;
1888 //    P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch;
1889         P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T)NULL;
1890
1891     struct cfg80211_scan_request *prScanRequest = NULL;
1892     GLUE_SPIN_LOCK_DECLARATION();
1893     ASSERT(prDev);
1894
1895     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
1896     ASSERT(prGlueInfo);
1897
1898         prGlueP2pInfo = prGlueInfo->prP2PInfo;
1899         ASSERT(prGlueP2pInfo);
1900
1901         /* CFG80211 down */
1902                 GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
1903                 if(prGlueP2pInfo->prScanRequest != NULL) {
1904                         prScanRequest = prGlueP2pInfo->prScanRequest;
1905                         prGlueP2pInfo->prScanRequest = NULL;
1906                 }
1907                 GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
1908         
1909                 if(prScanRequest) {
1910                         cfg80211_scan_done(prScanRequest, TRUE);
1911                 }
1912         
1913 #if 0
1914
1915     /* 1. stop TX queue */
1916     netif_tx_stop_all_queues(prDev);
1917
1918     /* 2. switch P2P-FSM off */
1919     /* 2.1 allocate for message */
1920     prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter,
1921             RAM_TYPE_MSG,
1922             sizeof(MSG_P2P_FUNCTION_SWITCH_T));
1923
1924     if (!prFuncSwitch) {
1925         ASSERT(0); // Can't trigger P2P FSM
1926         return -ENOMEM;
1927     }
1928
1929     /* 2.2 fill message */
1930     prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH;
1931     prFuncSwitch->fgIsFuncOn = FALSE;
1932
1933     /* 2.3 send message */
1934     mboxSendMsg(prAdapter,
1935             MBOX_ID_0,
1936             (P_MSG_HDR_T) prFuncSwitch,
1937             MSG_SEND_METHOD_BUF);
1938 #endif
1939     /* 3. stop queue and turn off carrier */
1940     prGlueInfo->prP2PInfo->eState = PARAM_MEDIA_STATE_DISCONNECTED;
1941
1942     netif_tx_stop_all_queues(prDev);
1943     if(netif_carrier_ok(prDev)) {
1944         netif_carrier_off(prDev);
1945     }
1946
1947     return 0;
1948 } /* end of p2pStop() */
1949
1950
1951 /*----------------------------------------------------------------------------*/
1952 /*!
1953  * \brief A method of struct net_device, to get the network interface statistical
1954  *        information.
1955  *
1956  * Whenever an application needs to get statistics for the interface, this method
1957  * is called. This happens, for example, when ifconfig or netstat -i is run.
1958  *
1959  * \param[in] prDev      Pointer to struct net_device.
1960  *
1961  * \return net_device_stats buffer pointer.
1962  */
1963 /*----------------------------------------------------------------------------*/
1964 struct net_device_stats *
1965 p2pGetStats (
1966     IN struct net_device *prDev
1967     )
1968 {
1969     P_GLUE_INFO_T prGlueInfo = NULL;
1970     ASSERT(prDev);
1971
1972     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
1973
1974 #if 0 // frog temp fix
1975     //@FIXME
1976     //prDev->stats.rx_packets = 0;
1977     //prDev->stats.tx_packets = 0;
1978     prDev->stats.tx_errors = 0;
1979     prDev->stats.rx_errors = 0;
1980     //prDev->stats.rx_bytes = 0;
1981     //prDev->stats.tx_bytes = 0;
1982     prDev->stats.multicast = 0;
1983
1984     return &prDev->stats;
1985
1986 #else
1987     //prGlueInfo->prP2PInfo->rNetDevStats.rx_packets = 0;
1988     //prGlueInfo->prP2PInfo->rNetDevStats.tx_packets = 0;
1989     prGlueInfo->prP2PInfo->rNetDevStats.tx_errors  = 0;
1990     prGlueInfo->prP2PInfo->rNetDevStats.rx_errors  = 0;
1991     //prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes   = 0;
1992     //prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes   = 0;
1993     //prGlueInfo->prP2PInfo->rNetDevStats.rx_errors  = 0;
1994     prGlueInfo->prP2PInfo->rNetDevStats.multicast  = 0;
1995
1996     return &prGlueInfo->prP2PInfo->rNetDevStats;
1997 #endif
1998 } /* end of p2pGetStats() */
1999
2000
2001
2002
2003 static void
2004 p2pSetMulticastList (
2005     IN struct net_device *prDev
2006     )
2007 {
2008     P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T)NULL;
2009
2010     prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL;
2011
2012     ASSERT(prDev);
2013     ASSERT(prGlueInfo);
2014     if (!prDev || !prGlueInfo) {
2015         printk(KERN_WARNING DRV_NAME" abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", prDev, prGlueInfo);
2016         return;
2017     }
2018
2019
2020     g_P2pPrDev = prDev;
2021
2022     //4  Mark HALT, notify main thread to finish current job
2023     prGlueInfo->u4Flag |= GLUE_FLAG_SUB_MOD_MULTICAST;
2024     /* wake up main thread */
2025     wake_up_interruptible(&prGlueInfo->waitq);
2026
2027 } /* p2pSetMulticastList */
2028
2029
2030 /*----------------------------------------------------------------------------*/
2031 /*!
2032  * \brief This function is to set multicast list and set rx mode.
2033  *
2034  * \param[in] prDev  Pointer to struct net_device
2035  *
2036  * \return (none)
2037  */
2038 /*----------------------------------------------------------------------------*/
2039 void
2040 mtk_p2p_wext_set_Multicastlist (
2041     P_GLUE_INFO_T prGlueInfo
2042     )
2043 {
2044     UINT_32 u4SetInfoLen = 0;
2045     struct net_device *prDev = g_P2pPrDev;
2046
2047     prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL;
2048
2049     ASSERT(prDev);
2050     ASSERT(prGlueInfo);
2051     if (!prDev || !prGlueInfo) {
2052         printk(KERN_WARNING DRV_NAME" abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n", prDev, prGlueInfo);
2053         return;
2054     }
2055
2056
2057     if (prDev->flags & IFF_PROMISC) {
2058         prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_PROMISCUOUS;
2059     }
2060
2061     if (prDev->flags & IFF_BROADCAST) {
2062         prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_BROADCAST;
2063     }
2064
2065     if (prDev->flags & IFF_MULTICAST) {
2066         if ((prDev->flags & IFF_ALLMULTI) ||
2067 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
2068                 (netdev_mc_count(prDev) > MAX_NUM_GROUP_ADDR)) {
2069 #else
2070                 (prDev->mc_count > MAX_NUM_GROUP_ADDR)) {
2071 #endif
2072             prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_ALL_MULTICAST;
2073         }
2074         else {
2075             prGlueInfo->prP2PInfo->u4PacketFilter |= PARAM_PACKET_FILTER_MULTICAST;
2076         }
2077     }
2078
2079     if (prGlueInfo->prP2PInfo->u4PacketFilter & PARAM_PACKET_FILTER_MULTICAST) {
2080         /* Prepare multicast address list */
2081 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
2082         struct netdev_hw_addr *ha;
2083 #else
2084         struct dev_mc_list *prMcList;
2085 #endif
2086         UINT_32 i = 0;
2087
2088 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
2089                 netdev_for_each_mc_addr(ha, prDev) {
2090                     if(i < MAX_NUM_GROUP_ADDR) {
2091                         COPY_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucMCAddrList[i]), ha->addr);
2092                         i++;
2093                     }
2094                 }
2095 #else
2096                 for (i = 0, prMcList = prDev->mc_list;
2097                      (prMcList) && (i < prDev->mc_count) && (i < MAX_NUM_GROUP_ADDR);
2098                      i++, prMcList = prMcList->next) {
2099                     COPY_MAC_ADDR(&(prGlueInfo->prP2PInfo->aucMCAddrList[i]), prMcList->dmi_addr);
2100                 }
2101 #endif
2102
2103                 DBGLOG(P2P, TRACE, ("SEt Multicast Address List\n"));
2104
2105                 if (i >= MAX_NUM_GROUP_ADDR) {
2106                     return;
2107                 }
2108                 wlanoidSetP2PMulticastList(prGlueInfo->prAdapter,
2109                                 &(prGlueInfo->prP2PInfo->aucMCAddrList[0]),
2110                                 (i * ETH_ALEN),
2111                                 &u4SetInfoLen);
2112
2113     }
2114
2115     return;
2116 } /* end of p2pSetMulticastList() */
2117
2118
2119 /*----------------------------------------------------------------------------*/
2120 /*!
2121  * * \brief This function is TX entry point of NET DEVICE.
2122  * *
2123  * * \param[in] prSkb  Pointer of the sk_buff to be sent
2124  * * \param[in] prDev  Pointer to struct net_device
2125  * *
2126  * * \retval NETDEV_TX_OK - on success.
2127  * * \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer.
2128  * */
2129 /*----------------------------------------------------------------------------*/
2130 int
2131 p2pHardStartXmit(
2132     IN struct sk_buff *prSkb,
2133     IN struct net_device *prDev
2134     )
2135 {
2136     P_QUE_ENTRY_T prQueueEntry = NULL;
2137     P_QUE_T prTxQueue = NULL;
2138     P_GLUE_INFO_T prGlueInfo = NULL;
2139     UINT_16 u2QueueIdx = 0;
2140
2141     GLUE_SPIN_LOCK_DECLARATION();
2142
2143     ASSERT(prSkb);
2144     ASSERT(prDev);
2145
2146     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
2147
2148     if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) {
2149         printk(KERN_INFO DRV_NAME"GLUE_FLAG_HALT skip tx\n");
2150         dev_kfree_skb(prSkb);
2151         return NETDEV_TX_OK;
2152     }
2153
2154     // mark as P2P packets
2155     GLUE_SET_PKT_FLAG_P2P(prSkb);
2156
2157     prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb);
2158     prTxQueue = &prGlueInfo->rTxQueue;
2159
2160     if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) {
2161
2162         u2QueueIdx = skb_get_queue_mapping(prSkb);
2163         ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM);
2164
2165         if (u2QueueIdx >= CFG_MAX_TXQ_NUM) {
2166             printk(KERN_INFO DRV_NAME"Incorrect queue index, skip this frame\n");
2167             dev_kfree_skb(prSkb);
2168             return NETDEV_TX_OK;
2169         }
2170         GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
2171         QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry);
2172         GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
2173
2174         GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum);
2175         GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_P2P_INDEX][u2QueueIdx]);
2176
2177         if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_P2P_INDEX][u2QueueIdx] >= CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) {
2178             netif_stop_subqueue(prDev, u2QueueIdx);
2179         }
2180     }
2181     else {
2182         GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum);
2183     }
2184
2185     kalSetEvent(prGlueInfo);
2186
2187     /* Statistic usage. */
2188     prGlueInfo->prP2PInfo->rNetDevStats.tx_bytes += prSkb->len;
2189         prGlueInfo->prP2PInfo->rNetDevStats.tx_packets++;
2190     //prDev->stats.tx_packets++;
2191
2192     return NETDEV_TX_OK;
2193 } /* end of p2pHardStartXmit() */
2194
2195
2196 /*----------------------------------------------------------------------------*/
2197 /*!
2198  * \brief A method of struct net_device, a primary SOCKET interface to configure
2199  *        the interface lively. Handle an ioctl call on one of our devices.
2200  *        Everything Linux ioctl specific is done here. Then we pass the contents
2201  *        of the ifr->data to the request message handler.
2202  *
2203  * \param[in] prDev      Linux kernel netdevice
2204  *
2205  * \param[in] prIFReq    Our private ioctl request structure, typed for the generic
2206  *                       struct ifreq so we can use ptr to function
2207  *
2208  * \param[in] cmd        Command ID
2209  *
2210  * \retval WLAN_STATUS_SUCCESS The IOCTL command is executed successfully.
2211  * \retval OTHER The execution of IOCTL command is failed.
2212  */
2213 /*----------------------------------------------------------------------------*/
2214 int
2215 p2pDoIOCTL(
2216     struct net_device *prDev,
2217     struct ifreq *prIFReq,
2218     int i4Cmd
2219     )
2220 {
2221     P_GLUE_INFO_T prGlueInfo = NULL;
2222     int ret = 0;
2223     char *prExtraBuf = NULL;
2224     UINT_32 u4ExtraSize = 0;
2225     struct iwreq *prIwReq = (struct iwreq *)prIFReq;
2226     struct iw_request_info rIwReqInfo;
2227
2228     ASSERT(prDev);
2229
2230     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
2231
2232     if (prGlueInfo->u4ReadyFlag == 0) {
2233         // adapter not ready yet
2234         return -EINVAL;
2235     }
2236
2237     // fill rIwReqInfo
2238     rIwReqInfo.cmd = (__u16)i4Cmd;
2239     rIwReqInfo.flags = 0;
2240
2241     switch(i4Cmd) {
2242     case SIOCSIWENCODEEXT:
2243         /* Set Encryption Material after 4-way handshaking is done */
2244         if (prIwReq->u.encoding.pointer) {
2245             u4ExtraSize = prIwReq->u.encoding.length;
2246             prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE);
2247
2248             if (!prExtraBuf) {
2249                 ret = -ENOMEM;
2250                 break;
2251             }
2252
2253             if (copy_from_user(prExtraBuf,
2254                         prIwReq->u.encoding.pointer,
2255                         prIwReq->u.encoding.length)) {
2256                 ret = -EFAULT;
2257             }
2258         }
2259         else if (prIwReq->u.encoding.length != 0) {
2260             ret = -EINVAL;
2261             break;
2262         }
2263
2264         if(ret == 0) {
2265             ret = mtk_p2p_wext_set_key(prDev, &rIwReqInfo, &(prIwReq->u), prExtraBuf);
2266         }
2267
2268         kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize);
2269         prExtraBuf = NULL;
2270         break;
2271
2272     case SIOCSIWMLME:
2273         /* IW_MLME_DISASSOC used for disconnection*/
2274         if (prIwReq->u.data.length != sizeof(struct iw_mlme)) {
2275             printk(KERN_INFO "MLME buffer strange:%d\n", prIwReq->u.data.length);
2276             ret = -EINVAL;
2277             break;
2278         }
2279
2280         if (!prIwReq->u.data.pointer) {
2281             ret = -EINVAL;
2282             break;
2283         }
2284
2285         prExtraBuf = kalMemAlloc(sizeof(struct iw_mlme), VIR_MEM_TYPE);
2286         if (!prExtraBuf) {
2287             ret = - ENOMEM;
2288             break;
2289         }
2290
2291         if (copy_from_user(prExtraBuf, prIwReq->u.data.pointer, sizeof(struct iw_mlme))) {
2292             ret = -EFAULT;
2293         }
2294         else {
2295             ret = mtk_p2p_wext_mlme_handler(prDev, &rIwReqInfo, &(prIwReq->u), prExtraBuf);
2296         }
2297
2298         kalMemFree(prExtraBuf, VIR_MEM_TYPE, sizeof(struct iw_mlme));
2299         prExtraBuf = NULL;
2300         break;
2301
2302     case SIOCGIWPRIV:
2303         /* This ioctl is used to list all IW privilege ioctls */
2304         ret = mtk_p2p_wext_get_priv(prDev, &rIwReqInfo, &(prIwReq->u), NULL);
2305         break;
2306
2307     case SIOCGIWSCAN:
2308         ret = mtk_p2p_wext_discovery_results(prDev, &rIwReqInfo, &(prIwReq->u), NULL);
2309         break;
2310
2311     case SIOCSIWAUTH:
2312         ret = mtk_p2p_wext_set_auth(prDev, &rIwReqInfo, &(prIwReq->u), NULL);
2313         break;
2314
2315     case IOC_P2P_CFG_DEVICE:
2316     case IOC_P2P_PROVISION_COMPLETE:
2317     case IOC_P2P_START_STOP_DISCOVERY:
2318     case IOC_P2P_DISCOVERY_RESULTS:
2319     case IOC_P2P_WSC_BEACON_PROBE_RSP_IE:
2320     case IOC_P2P_CONNECT_DISCONNECT:
2321     case IOC_P2P_PASSWORD_READY:
2322     case IOC_P2P_GET_STRUCT:
2323     case IOC_P2P_SET_STRUCT:
2324     case IOC_P2P_GET_REQ_DEVICE_INFO:
2325         ret = rP2PIwPrivHandler[i4Cmd - SIOCIWFIRSTPRIV](prDev, &rIwReqInfo, &(prIwReq->u), (char *)&(prIwReq->u));
2326         break;
2327 #if CFG_SUPPORT_P2P_RSSI_QUERY
2328     case SIOCGIWSTATS:
2329         ret = mtk_p2p_wext_get_rssi(prDev, &rIwReqInfo, &(prIwReq->u), NULL);
2330         break;
2331 #endif
2332     default:
2333         ret = -ENOTTY;
2334     }
2335
2336     return ret;
2337 } /* end of p2pDoIOCTL() */
2338
2339
2340 /*----------------------------------------------------------------------------*/
2341 /*!
2342  * \brief To report the private supported IOCTLs table to user space.
2343  *
2344  * \param[in] prDev Net device requested.
2345  * \param[out] prIfReq Pointer to ifreq structure, content is copied back to
2346  *                  user space buffer in gl_iwpriv_table.
2347  *
2348  * \retval 0 For success.
2349  * \retval -E2BIG For user's buffer size is too small.
2350  * \retval -EFAULT For fail.
2351  *
2352  */
2353 /*----------------------------------------------------------------------------*/
2354 int
2355 mtk_p2p_wext_get_priv (
2356     IN struct net_device *prDev,
2357     IN struct iw_request_info *info,
2358     IN OUT union iwreq_data *wrqu,
2359     IN OUT char *extra
2360     )
2361 {
2362     struct iw_point *prData= (struct iw_point *)&wrqu->data;
2363     UINT_16 u2BufferSize = 0;
2364
2365     ASSERT(prDev);
2366
2367     u2BufferSize = prData->length;
2368
2369     /* update our private table size */
2370     prData->length = (__u16)sizeof(rP2PIwPrivTable)/sizeof(struct iw_priv_args);
2371
2372     if (u2BufferSize < prData->length) {
2373         return -E2BIG;
2374     }
2375
2376     if (prData->length) {
2377         if (copy_to_user(prData->pointer, rP2PIwPrivTable, sizeof(rP2PIwPrivTable))) {
2378             return -EFAULT;
2379         }
2380     }
2381
2382     return 0;
2383 } /* end of mtk_p2p_wext_get_priv() */
2384
2385
2386 /*----------------------------------------------------------------------------*/
2387 /*!
2388  * \brief To indicate P2P-FSM for re-associate to the connecting device
2389  *
2390  * \param[in] prDev      Net device requested.
2391  * \param[inout] wrqu    Pointer to iwreq_data
2392  *
2393  * \retval 0 For success.
2394  * \retval -EFAULT For fail.
2395  *
2396  */
2397 /*----------------------------------------------------------------------------*/
2398 int
2399 mtk_p2p_wext_reconnect (
2400     IN struct net_device *prDev,
2401     IN struct iw_request_info *info,
2402     IN OUT union iwreq_data *wrqu,
2403     IN OUT char *extra
2404     )
2405 {
2406 #if 0
2407     P_ADAPTER_T prAdapter = NULL;
2408     P_GLUE_INFO_T prGlueInfo = NULL;
2409     P_MSG_HDR_T prMsgHdr;
2410
2411     ASSERT(prDev);
2412
2413     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
2414     ASSERT(prGlueInfo);
2415
2416     prAdapter = prGlueInfo->prAdapter;
2417     ASSERT(prAdapter);
2418
2419     prMsgHdr = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_HDR_T));
2420     if (!prMsgHdr) {
2421         ASSERT(0); // Can't trigger P2P FSM
2422         return -ENOMEM;
2423     }
2424
2425     /* 1.2 fill message */
2426
2427     DBGLOG(P2P, TRACE, ("mtk_p2p_wext_reconnect: P2P Reconnect\n"));
2428
2429     /* 1.3 send message */
2430     mboxSendMsg(prAdapter,
2431             MBOX_ID_0,
2432             (P_MSG_HDR_T) prMsgHdr,
2433             MSG_SEND_METHOD_BUF);
2434 #endif
2435     return 0;
2436 } /* end of mtk_p2p_wext_reconnect() */
2437
2438
2439
2440
2441 /*----------------------------------------------------------------------------*/
2442 /*!
2443 * \brief MLME command handler
2444 *
2445 * \param[in] prDev      Net device requested.
2446 * \param[inout] wrqu    Pointer to iwreq_data
2447 *
2448 * \retval 0 Success.
2449 * \retval -EFAULT Setting parameters to driver fail.
2450 * \retval -EOPNOTSUPP Key size not supported.
2451 *
2452 * \note
2453 */
2454 /*----------------------------------------------------------------------------*/
2455 int
2456 mtk_p2p_wext_mlme_handler(
2457     IN struct net_device *prDev,
2458     IN struct iw_request_info *info,
2459     IN OUT union iwreq_data *wrqu,
2460     IN OUT char *extra
2461     )
2462 {
2463 #if 0
2464     P_ADAPTER_T prAdapter = NULL;
2465     P_GLUE_INFO_T prGlueInfo = NULL;
2466     struct iw_mlme *mlme = (struct iw_mlme *)extra;
2467     P_MSG_P2P_CONNECTION_ABORT_T prMsgP2PConnAbt = (P_MSG_P2P_CONNECTION_ABORT_T)NULL;
2468     P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T)NULL;
2469
2470     ASSERT(prDev);
2471
2472     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
2473     ASSERT(prGlueInfo);
2474
2475     prAdapter = prGlueInfo->prAdapter;
2476     ASSERT(prAdapter);
2477
2478     prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
2479
2480     DBGLOG(P2P, TRACE, ("mtk_p2p_wext_mlme_handler:\n"));
2481
2482     switch (mlme->cmd) {
2483     case IW_MLME_DISASSOC:
2484         prMsgP2PConnAbt = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_CONNECTION_ABORT_T));
2485         if (!prMsgP2PConnAbt) {
2486             ASSERT(0); // Can't trigger P2P FSM
2487             return -ENOMEM;
2488         }
2489
2490         COPY_MAC_ADDR(prMsgP2PConnAbt->aucTargetID, mlme->addr.sa_data);
2491
2492         prMsgP2PConnAbt->u2ReasonCode = mlme->reason_code;
2493
2494
2495         if (EQUAL_MAC_ADDR(prMsgP2PConnAbt->aucTargetID, prP2pBssInfo->aucOwnMacAddr)) {
2496             DBGLOG(P2P, TRACE, ("P2P Connection Abort:\n"));
2497
2498             /* 1.2 fill message */
2499             prMsgP2PConnAbt->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT;
2500         }
2501         else {
2502             DBGLOG(P2P, TRACE, ("P2P Connection Pause:\n"));
2503
2504             /* 1.2 fill message */
2505         }
2506
2507         /* 1.3 send message */
2508         mboxSendMsg(prAdapter,
2509             MBOX_ID_0,
2510             (P_MSG_HDR_T) prMsgP2PConnAbt,
2511             MSG_SEND_METHOD_BUF);
2512
2513         break;
2514
2515     default:
2516         return -EOPNOTSUPP;
2517     }
2518 #endif
2519     return 0;
2520 } /* end of mtk_p2p_wext_mlme_handler() */
2521
2522
2523 /*----------------------------------------------------------------------------*/
2524 /*!
2525 * \brief P2P Private I/O Control handler (IOC_P2P_PROVISION_COMPLETE)
2526 *
2527 * \param[in] prDev      Net device requested.
2528 * \param[inout] wrqu    Pointer to iwreq_data
2529 *
2530 * \retval 0 Success.
2531 * \retval -EFAULT Setting parameters to driver fail.
2532 * \retval -EOPNOTSUPP Key size not supported.
2533 *
2534 * \note
2535 */
2536 /*----------------------------------------------------------------------------*/
2537 int
2538 mtk_p2p_wext_set_provision_complete(
2539     IN struct net_device *prDev,
2540     IN struct iw_request_info *info,
2541     IN OUT union iwreq_data *wrqu,
2542     IN OUT char *extra
2543     )
2544 {
2545 #if 0
2546     P_ADAPTER_T prAdapter = NULL;
2547     P_GLUE_INFO_T prGlueInfo = NULL;
2548     struct iw_point *prData= (struct iw_point *)&wrqu->data;
2549     P_MSG_HDR_T prMsgHdr;
2550
2551     ASSERT(prDev);
2552
2553     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
2554     ASSERT(prGlueInfo);
2555
2556     prAdapter = prGlueInfo->prAdapter;
2557     ASSERT(prAdapter);
2558
2559     switch(prData->flags) {
2560     case P2P_PROVISIONING_SUCCESS:
2561         prMsgHdr = (P_MSG_HDR_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_HDR_T));
2562         if (!prMsgHdr) {
2563             ASSERT(0); // Can't trigger P2P FSM
2564             return -ENOMEM;
2565         }
2566
2567         /* 1.2 fill message */
2568
2569         prGlueInfo->prP2PInfo->u4CipherPairwise = IW_AUTH_CIPHER_CCMP;
2570
2571         /* 1.3 send message */
2572         mboxSendMsg(prAdapter,
2573             MBOX_ID_0,
2574             (P_MSG_HDR_T) prMsgHdr,
2575             MSG_SEND_METHOD_BUF);
2576
2577         break;
2578
2579     case P2P_PROVISIONING_FAIL:
2580
2581         break;
2582
2583     default:
2584         return -EOPNOTSUPP;
2585     }
2586 #endif
2587
2588     return 0;
2589 } /* end of mtk_p2p_wext_set_provision_complete() */
2590
2591
2592
2593 /*----------------------------------------------------------------------------*/
2594 /*!
2595 * \brief P2P Private I/O Control handler (IOC_P2P_START_STOP_DISCOVERY)
2596 *
2597 * \param[in] prDev      Net device requested.
2598 * \param[inout] wrqu    Pointer to iwreq_data
2599 *
2600 * \retval 0 Success.
2601 * \retval -EFAULT Setting parameters to driver fail.
2602 * \retval -EOPNOTSUPP Key size not supported.
2603 *
2604 * \note
2605 */
2606 /*----------------------------------------------------------------------------*/
2607 int
2608 mtk_p2p_wext_start_stop_discovery(
2609     IN struct net_device *prDev,
2610     IN struct iw_request_info *info,
2611     IN OUT union iwreq_data *wrqu,
2612     IN OUT char *extra
2613     )
2614 {
2615 #if 0
2616     P_ADAPTER_T prAdapter = NULL;
2617     P_GLUE_INFO_T prGlueInfo = NULL;
2618     struct iw_point *prData= (struct iw_point *)&wrqu->data;
2619     P_IW_P2P_REQ_DEVICE_TYPE prReqDeviceType = (P_IW_P2P_REQ_DEVICE_TYPE) extra;
2620     UINT_8 au4IeBuf[MAX_IE_LENGTH];
2621     P_MSG_HDR_T prMsgHdr;
2622     P_MSG_P2P_DEVICE_DISCOVER_T prDiscoverMsg;
2623     P_P2P_CONNECTION_SETTINGS_T prConnSettings;
2624     UINT_8 aucNullAddr[] = NULL_MAC_ADDR;
2625
2626     ASSERT(prDev);
2627
2628     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
2629     ASSERT(prGlueInfo);
2630
2631     prAdapter = prGlueInfo->prAdapter;
2632     ASSERT(prAdapter);
2633
2634     prConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
2635
2636     if(prData->flags == P2P_STOP_DISCOVERY) {
2637         prMsgHdr = (P_MSG_HDR_T) cnmMemAlloc(prAdapter,
2638             RAM_TYPE_MSG,
2639             sizeof(MSG_HDR_T));
2640
2641         if (!prMsgHdr) {
2642             ASSERT(0); // Can't trigger P2P FSM
2643             return -ENOMEM;
2644         }
2645
2646
2647         mboxSendMsg(prAdapter,
2648                 MBOX_ID_0,
2649                 (P_MSG_HDR_T) prMsgHdr,
2650                 MSG_SEND_METHOD_BUF);
2651     }
2652     else if(prData->flags == P2P_START_DISCOVERY) {
2653
2654         /* retrieve IE for Probe Response */
2655         if(prReqDeviceType->probe_rsp_len > 0) {
2656             if(prReqDeviceType->probe_rsp_len <= MAX_IE_LENGTH) {
2657                 if(copy_from_user(prGlueInfo->prP2PInfo->aucWSCIE[2], prReqDeviceType->probe_rsp_ie, prReqDeviceType->probe_rsp_len)) {
2658                     return -EFAULT;
2659                 }
2660                 prGlueInfo->prP2PInfo->u2WSCIELen[2] = prReqDeviceType->probe_rsp_len;
2661             }
2662             else {
2663                 return -E2BIG;
2664             }
2665         }
2666
2667         /* retrieve IE for Probe Request */
2668         if(prReqDeviceType->probe_req_len > 0) {
2669             if(prReqDeviceType->probe_req_len <= MAX_IE_LENGTH) {
2670                 if(copy_from_user(prGlueInfo->prP2PInfo->aucWSCIE[1], prReqDeviceType->probe_req_ie, prReqDeviceType->probe_req_len)) {
2671                     return -EFAULT;
2672                 }
2673                 prGlueInfo->prP2PInfo->u2WSCIELen[1] = prReqDeviceType->probe_req_len;
2674             }
2675             else {
2676                 return -E2BIG;
2677             }
2678         }
2679         /* update IE for Probe Request */
2680
2681         if(prReqDeviceType->scan_type == P2P_LISTEN) {
2682             /* update listening parameter */
2683
2684             /* @TODO: update prConnSettings for Probe Response IE */
2685         }
2686         else {
2687             // indicate P2P-FSM with MID_MNY_P2P_DEVICE_DISCOVERY
2688             prDiscoverMsg = (P_MSG_P2P_DEVICE_DISCOVER_T) cnmMemAlloc(prAdapter,
2689                     RAM_TYPE_MSG,
2690                     sizeof(MSG_P2P_DEVICE_DISCOVER_T));
2691
2692             if (!prDiscoverMsg) {
2693                 ASSERT(0); // Can't trigger P2P FSM
2694                 return -ENOMEM;
2695             }
2696
2697             prDiscoverMsg->rMsgHdr.eMsgId = MID_MNY_P2P_DEVICE_DISCOVERY;
2698             prDiscoverMsg->u4DevDiscoverTime = 0; // unlimited
2699             prDiscoverMsg->fgIsSpecificType = TRUE;
2700             prDiscoverMsg->rTargetDeviceType.u2CategoryID = *(PUINT_16)(&(prReqDeviceType->pri_device_type[0]));
2701             prDiscoverMsg->rTargetDeviceType.u2SubCategoryID = *(PUINT_16)(&(prReqDeviceType->pri_device_type[6]));;
2702             COPY_MAC_ADDR(prDiscoverMsg->aucTargetDeviceID, aucNullAddr);
2703
2704             /* @FIXME: parameter to be refined, where to pass IE buffer ? */
2705             mboxSendMsg(prAdapter,
2706                     MBOX_ID_0,
2707                     (P_MSG_HDR_T) prDiscoverMsg,
2708                     MSG_SEND_METHOD_BUF);
2709         }
2710     }
2711     else {
2712         return -EINVAL;
2713     }
2714 #endif
2715
2716     return 0;
2717 } /* end of mtk_p2p_wext_start_stop_discovery() */
2718
2719
2720
2721 /*----------------------------------------------------------------------------*/
2722 /*!
2723 * \brief P2P Private I/O Control handler (IOC_P2P_SET_INT)
2724 *
2725 * \param[in] prDev      Net device requested.
2726 * \param[inout] wrqu    Pointer to iwreq_data
2727 *
2728 * \retval 0 Success.
2729 * \retval -EFAULT Setting parameters to driver fail.
2730 * \retval -EOPNOTSUPP Setting parameters not support.
2731 *
2732 * \note
2733 */
2734 /*----------------------------------------------------------------------------*/
2735 int
2736 mtk_p2p_wext_invitation_request (
2737     IN struct net_device *prDev,
2738     IN struct iw_request_info *info,
2739     IN OUT union iwreq_data *wrqu,
2740     IN OUT char *extra
2741     )
2742 {
2743     int i4Status = 0;
2744 #if 0
2745     P_ADAPTER_T prAdapter = (P_ADAPTER_T)NULL;
2746     P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T)NULL;
2747     struct iw_point *prData = (struct iw_point*)&wrqu->data;
2748     P_IW_P2P_IOCTL_INVITATION_STRUCT prIoctlInvitation = (P_IW_P2P_IOCTL_INVITATION_STRUCT)NULL;
2749
2750     do {
2751         if ((prDev == NULL) || (extra == NULL)) {
2752             ASSERT(FALSE);
2753             i4Status = -EINVAL;
2754             break;
2755         }
2756
2757
2758         prGlueInfo = *((P_GLUE_INFO_T *)netdev_priv(prDev));
2759         prIoctlInvitation = (P_IW_P2P_IOCTL_INVITATION_STRUCT)extra;
2760
2761         if (prGlueInfo == NULL) {
2762             i4Status = -EINVAL;
2763             break;
2764         }
2765
2766
2767         prAdapter = prGlueInfo->prAdapter;
2768
2769         if (prAdapter == NULL) {
2770             i4Status = -EINVAL;
2771             break;
2772         }
2773
2774
2775         if (prIoctlInvitation->ucReinvoke == 1) {
2776             // TODO: Set Group ID
2777             p2pFuncSetGroupID(prAdapter, prIoctlInvitation->aucGroupID, prIoctlInvitation->aucSsid, prIoctlInvitation->u4SsidLen);
2778         }
2779
2780         else {
2781             P_MSG_P2P_INVITATION_REQUEST_T prMsgP2PInvitationReq = (P_MSG_P2P_INVITATION_REQUEST_T)NULL;
2782
2783             // TODO: Do Invitation.
2784             prMsgP2PInvitationReq = (P_MSG_P2P_INVITATION_REQUEST_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_INVITATION_REQUEST_T));
2785             if (!prMsgP2PInvitationReq) {
2786                 ASSERT(0); // Can't trigger P2P FSM
2787                 i4Status = -ENOMEM;
2788                 break;
2789             }
2790
2791             /* 1.2 fill message */
2792             kalMemCopy(prMsgP2PInvitationReq->aucDeviceID, prIoctlInvitation->aucDeviceID, MAC_ADDR_LEN);
2793
2794             DBGLOG(P2P, TRACE, ("mtk_p2p_wext_invitation_request: P2P Invitation Req\n"));
2795
2796             /* 1.3 send message */
2797             mboxSendMsg(prAdapter,
2798                     MBOX_ID_0,
2799                     (P_MSG_HDR_T)prMsgP2PInvitationReq,
2800                     MSG_SEND_METHOD_BUF);
2801
2802         }
2803
2804
2805
2806     } while (FALSE);
2807 #endif
2808
2809     return i4Status;
2810
2811 }
2812 /* mtk_p2p_wext_invitation_request */
2813
2814
2815 /*----------------------------------------------------------------------------*/
2816 /*!
2817 * \brief P2P Private I/O Control handler (IOC_P2P_SET_INT)
2818 *
2819 * \param[in] prDev      Net device requested.
2820 * \param[inout] wrqu    Pointer to iwreq_data
2821 *
2822 * \retval 0 Success.
2823 * \retval -EFAULT Setting parameters to driver fail.
2824 * \retval -EOPNOTSUPP Setting parameters not support.
2825 *
2826 * \note
2827 */
2828 /*----------------------------------------------------------------------------*/
2829 int
2830 mtk_p2p_wext_invitation_abort (
2831     IN struct net_device *prDev,
2832     IN struct iw_request_info *info,
2833     IN OUT union iwreq_data *wrqu,
2834     IN OUT char *extra
2835     )
2836 {
2837     int i4Status = 0;
2838 #if 0
2839     P_ADAPTER_T prAdapter = (P_ADAPTER_T)NULL;
2840     P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T)NULL;
2841     struct iw_point *prData = (struct iw_point*)&wrqu->data;
2842     P_IW_P2P_IOCTL_ABORT_INVITATION prIoctlInvitationAbort = (P_IW_P2P_IOCTL_ABORT_INVITATION)NULL;
2843
2844     UINT_8 bssid[MAC_ADDR_LEN];
2845
2846     do {
2847         if ((prDev == NULL) || (extra == NULL)) {
2848             ASSERT(FALSE);
2849             i4Status = -EINVAL;
2850             break;
2851         }
2852
2853
2854         prGlueInfo = *((P_GLUE_INFO_T *)netdev_priv(prDev));
2855         prIoctlInvitationAbort = (P_IW_P2P_IOCTL_ABORT_INVITATION)extra;
2856
2857         if (prGlueInfo == NULL) {
2858             i4Status = -EINVAL;
2859             break;
2860         }
2861
2862
2863         prAdapter = prGlueInfo->prAdapter;
2864
2865         if (prAdapter == NULL) {
2866             i4Status = -EINVAL;
2867             break;
2868         }
2869         else {
2870             P_MSG_P2P_INVITATION_REQUEST_T prMsgP2PInvitationAbort = (P_MSG_P2P_INVITATION_REQUEST_T)NULL;
2871
2872             prMsgP2PInvitationAbort = (P_MSG_P2P_INVITATION_REQUEST_T) cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_INVITATION_REQUEST_T));
2873
2874             if (!prMsgP2PInvitationAbort) {
2875                 ASSERT(0); // Can't trigger P2P FSM
2876                 i4Status = -ENOMEM;
2877                 break;
2878             }
2879
2880
2881             /* 1.2 fill message */
2882             kalMemCopy(prMsgP2PInvitationAbort->aucDeviceID, prIoctlInvitationAbort->dev_addr, MAC_ADDR_LEN);
2883
2884             DBGLOG(P2P, TRACE, ("mtk_p2p_wext_invitation_request: P2P Invitation Req\n"));
2885
2886             /* 1.3 send message */
2887             mboxSendMsg(prAdapter,
2888                             MBOX_ID_0,
2889                             (P_MSG_HDR_T)prMsgP2PInvitationAbort,
2890                             MSG_SEND_METHOD_BUF);
2891
2892         }
2893
2894
2895     } while (FALSE);
2896 #endif
2897
2898     return i4Status;
2899
2900 }
2901 /* mtk_p2p_wext_invitation_abort */
2902
2903
2904
2905 /*----------------------------------------------------------------------------*/
2906 /*!
2907  * \brief To override p2p interface address
2908  *
2909  * \param[in] prDev Net device requested.
2910  * \param[in] addr  Pointer to address
2911  *
2912  * \retval 0 For success.
2913  * \retval -E2BIG For user's buffer size is too small.
2914  * \retval -EFAULT For fail.
2915  *
2916  */
2917 /*----------------------------------------------------------------------------*/
2918 int
2919 p2pSetMACAddress(
2920     IN struct net_device *prDev,
2921     void *addr
2922     )
2923 {
2924     P_ADAPTER_T prAdapter = NULL;
2925     P_GLUE_INFO_T prGlueInfo = NULL;
2926
2927     ASSERT(prDev);
2928
2929     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
2930     ASSERT(prGlueInfo);
2931
2932     prAdapter = prGlueInfo->prAdapter;
2933     ASSERT(prAdapter);
2934
2935     //@FIXME
2936     return eth_mac_addr(prDev, addr);
2937 }
2938
2939
2940
2941
2942
2943
2944
2945 /*----------------------------------------------------------------------------*/
2946 /*!
2947 * \brief To set encryption cipher suite
2948 *
2949 * \param[in] prDev Net device requested.
2950 * \param[out]
2951 *
2952 * \retval 0 Success.
2953 * \retval -EINVAL Invalid parameter
2954 * \retval -EOPNOTSUPP Key size not supported.
2955 *
2956 * \note
2957 */
2958 /*----------------------------------------------------------------------------*/
2959 int
2960 mtk_p2p_wext_set_auth (
2961     IN struct net_device *prDev,
2962     IN struct iw_request_info *info,
2963     IN OUT union iwreq_data *wrqu,
2964     IN OUT char *extra
2965     )
2966 {
2967     P_GLUE_INFO_T prGlueInfo = NULL;
2968     struct iw_param *prAuth = (struct iw_param *)wrqu;
2969
2970     ASSERT(prDev);
2971     ASSERT(prAuth);
2972     if (FALSE == GLUE_CHK_PR2(prDev, prAuth)) {
2973         return -EINVAL;
2974     }
2975
2976     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
2977
2978     /* Save information to glue info and process later when ssid is set. */
2979     switch(prAuth->flags & IW_AUTH_INDEX) {
2980     case IW_AUTH_WPA_VERSION:
2981         break;
2982     case IW_AUTH_CIPHER_PAIRWISE:
2983         prGlueInfo->prP2PInfo->u4CipherPairwise = prAuth->value;
2984        break;
2985     case IW_AUTH_CIPHER_GROUP:
2986     case IW_AUTH_KEY_MGMT:
2987     case IW_AUTH_TKIP_COUNTERMEASURES:
2988     case IW_AUTH_DROP_UNENCRYPTED:
2989     case IW_AUTH_80211_AUTH_ALG:
2990     case IW_AUTH_WPA_ENABLED:
2991     case IW_AUTH_RX_UNENCRYPTED_EAPOL:
2992     case IW_AUTH_ROAMING_CONTROL:
2993     case IW_AUTH_PRIVACY_INVOKED:
2994     default:
2995         //@TODO
2996         break;
2997     }
2998
2999     return 0;
3000 } /* end of mtk_p2p_wext_set_auth() */
3001
3002
3003 /*----------------------------------------------------------------------------*/
3004 /*!
3005 * \brief To set encryption cipher and key.
3006 *
3007 * \param[in] prDev Net device requested.
3008 * \param[out] prIfReq Pointer to ifreq structure, content is copied back to
3009 *                  user space buffer in gl_iwpriv_table.
3010 *
3011 * \retval 0 Success.
3012 * \retval -EFAULT Setting parameters to driver fail.
3013 * \retval -EOPNOTSUPP Key size not supported.
3014 *
3015 * \note Securiry information is stored in pEnc.
3016 */
3017 /*----------------------------------------------------------------------------*/
3018 int
3019 mtk_p2p_wext_set_key(
3020     IN struct net_device *prDev,
3021     IN struct iw_request_info *info,
3022     IN OUT union iwreq_data *wrqu,
3023     IN OUT char *extra
3024     )
3025 {
3026     int ret = 0;
3027     struct iw_encode_ext *prIWEncExt;
3028     struct iw_point *prEnc;
3029     char *prExtraBuf = NULL;
3030     UINT_32 u4ExtraSize = 0;
3031     UINT_8 keyStructBuf[100];
3032     P_PARAM_REMOVE_KEY_T prRemoveKey = (P_PARAM_REMOVE_KEY_T) keyStructBuf;
3033     P_PARAM_KEY_T prKey = (P_PARAM_KEY_T) keyStructBuf;
3034     P_GLUE_INFO_T prGlueInfo;
3035     WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
3036     UINT_32 u4BufLen = 0;
3037
3038     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
3039
3040     do {
3041         if (wrqu->encoding.pointer) {
3042             u4ExtraSize = wrqu->encoding.length;
3043             prExtraBuf = kalMemAlloc(u4ExtraSize, VIR_MEM_TYPE);
3044
3045             if (!prExtraBuf) {
3046                 ret = -ENOMEM;
3047                 break;
3048             }
3049
3050             if (copy_from_user(prExtraBuf,
3051                         wrqu->encoding.pointer,
3052                         wrqu->encoding.length)) {
3053                 ret = -EFAULT;
3054                 break;
3055             }
3056         }
3057         else if (wrqu->encoding.length != 0) {
3058             ret = -EINVAL;
3059             break;
3060         }
3061
3062         prEnc =  &wrqu->encoding;
3063         prIWEncExt = (struct iw_encode_ext *) prExtraBuf;
3064
3065         if (GLUE_CHK_PR3(prDev, prEnc, prExtraBuf) == TRUE) {
3066             memset(keyStructBuf, 0, sizeof(keyStructBuf));
3067
3068             if ((prEnc->flags & IW_ENCODE_MODE) == IW_ENCODE_DISABLED) { // Key Removal
3069                 prRemoveKey->u4Length = sizeof(*prRemoveKey);
3070                 memcpy(prRemoveKey->arBSSID, prIWEncExt->addr.sa_data, 6);
3071
3072                 rStatus = kalIoctl(prGlueInfo,
3073                         wlanoidSetRemoveP2PKey,
3074                         prRemoveKey,
3075                         prRemoveKey->u4Length,
3076                         FALSE,
3077                         FALSE,
3078                         TRUE,
3079                         TRUE,
3080                         &u4BufLen);
3081
3082                 if(rStatus != WLAN_STATUS_SUCCESS)
3083                     ret = -EFAULT;
3084             }
3085             else {
3086                 if(prIWEncExt->alg == IW_ENCODE_ALG_CCMP) {
3087                     /* KeyID */
3088                     prKey->u4KeyIndex = (prEnc->flags & IW_ENCODE_INDEX) ?
3089                         ((prEnc->flags & IW_ENCODE_INDEX) - 1) : 0;
3090                     if (prKey->u4KeyIndex <= 3) {
3091                         /* bit(31) and bit(30) are shared by pKey and pRemoveKey */
3092                         /* Tx Key Bit(31)*/
3093                         if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
3094                             prKey->u4KeyIndex |= 0x1UL << 31;
3095                         }
3096
3097                         /* Pairwise Key Bit(30) */
3098                         if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
3099                             /* group key */
3100                         }
3101                         else {
3102                             /* pairwise key */
3103                             prKey->u4KeyIndex |= 0x1UL << 30;
3104                         }
3105
3106                         /* Rx SC Bit(29) */
3107                         if (prIWEncExt->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
3108                             prKey->u4KeyIndex |= 0x1UL << 29;
3109                             memcpy(&prKey->rKeyRSC, prIWEncExt->rx_seq, IW_ENCODE_SEQ_MAX_SIZE);
3110                         }
3111
3112                         /* BSSID */
3113                         memcpy(prKey->arBSSID, prIWEncExt->addr.sa_data, 6);
3114                         memcpy(prKey->aucKeyMaterial, prIWEncExt->key, prIWEncExt->key_len);
3115
3116                         prKey->u4KeyLength = prIWEncExt->key_len;
3117                         prKey->u4Length = ((UINT_32)&(((P_PARAM_KEY_T)0)->aucKeyMaterial)) + prKey->u4KeyLength;
3118
3119                         rStatus = kalIoctl(prGlueInfo,
3120                                 wlanoidSetAddP2PKey,
3121                                 prKey,
3122                                 prKey->u4Length,
3123                                 FALSE,
3124                                 FALSE,
3125                                 TRUE,
3126                                 TRUE,
3127                                 &u4BufLen);
3128
3129                         if (rStatus != WLAN_STATUS_SUCCESS) {
3130                             ret = -EFAULT;
3131                         }
3132                     }
3133                     else {
3134                         ret = -EINVAL;
3135                     }
3136                 }
3137                 else {
3138                     ret = -EINVAL;
3139                 }
3140             }
3141         }
3142         else
3143             ret = -EINVAL;
3144
3145     } while(FALSE);
3146
3147     if (prExtraBuf) {
3148         kalMemFree(prExtraBuf, VIR_MEM_TYPE, u4ExtraSize);
3149         prExtraBuf = NULL;
3150     }
3151
3152     return ret;
3153 } /* end of mtk_p2p_wext_set_key() */
3154
3155
3156
3157
3158 /*----------------------------------------------------------------------------*/
3159 /*!
3160 * \brief set the p2p gc power mode
3161 *
3162 * \param[in] prDev      Net device requested.
3163 * \param[inout] wrqu    Pointer to iwreq_data
3164 *
3165 * \retval 0 Success.
3166 * \retval -EFAULT Setting parameters to driver fail.
3167 * \retval -EOPNOTSUPP Key size not supported.
3168 *
3169 * \note
3170 */
3171 /*----------------------------------------------------------------------------*/
3172 int
3173 mtk_p2p_wext_set_powermode(
3174     IN struct net_device *prNetDev,
3175     IN struct iw_request_info *info,
3176     IN OUT union iwreq_data *wrqu,
3177     IN OUT char *extra
3178     )
3179 {
3180     //printk("set_powermode = %d, value = %d\n", wrqu->power.disabled, wrqu->power.value);
3181     struct iw_param *prPower = (struct iw_param*)&wrqu->power;
3182 #if 1
3183     PARAM_POWER_MODE ePowerMode;
3184     INT_32 i4PowerValue;
3185
3186     P_GLUE_INFO_T prGlueInfo = NULL;
3187     WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
3188     UINT_32 u4BufLen = 0;
3189
3190     ASSERT(prNetDev);
3191     ASSERT(prPower);
3192     if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) {
3193         return -EINVAL;
3194     }
3195     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
3196
3197     //printk(KERN_INFO "wext_set_power value(%d) disabled(%d) flag(0x%x)\n",
3198     //  prPower->value, prPower->disabled, prPower->flags);
3199
3200     if(prPower->disabled){
3201         ePowerMode = Param_PowerModeCAM;
3202     }
3203     else {
3204         i4PowerValue = prPower->value;
3205 #if WIRELESS_EXT < 21
3206         i4PowerValue /= 1000000;
3207 #endif
3208         if (i4PowerValue == 0) {
3209             ePowerMode = Param_PowerModeCAM;
3210         } else if (i4PowerValue == 1) {
3211             ePowerMode = Param_PowerModeMAX_PSP;
3212         } else if (i4PowerValue == 2) {
3213             ePowerMode = Param_PowerModeFast_PSP;
3214         }
3215         else {
3216             printk(KERN_DEBUG "%s(): unsupported power management mode value = %d.\n",
3217                 __FUNCTION__,
3218                 prPower->value);
3219
3220             return -EINVAL;
3221     }
3222     }
3223
3224
3225     rStatus = kalIoctl(prGlueInfo,
3226         wlanoidSetP2pPowerSaveProfile,
3227         &ePowerMode,
3228         sizeof(ePowerMode),
3229         FALSE,
3230         FALSE,
3231         TRUE,
3232         TRUE,
3233         &u4BufLen);
3234
3235     if (rStatus != WLAN_STATUS_SUCCESS) {
3236         //printk(KERN_INFO DRV_NAME"wlanoidSet802dot11PowerSaveProfile fail 0x%lx\n", rStatus);
3237         return -EFAULT;
3238     }
3239
3240 #endif
3241
3242     return 0;
3243 }
3244
3245
3246 /*----------------------------------------------------------------------------*/
3247 /*!
3248 * \brief get the p2p gc power mode
3249 *
3250 * \param[in] prDev      Net device requested.
3251 * \param[inout] wrqu    Pointer to iwreq_data
3252 *
3253 * \retval 0 Success.
3254 * \retval -EFAULT Setting parameters to driver fail.
3255 * \retval -EOPNOTSUPP Key size not supported.
3256 *
3257 * \note
3258 */
3259 /*----------------------------------------------------------------------------*/
3260 int
3261 mtk_p2p_wext_get_powermode(
3262     IN struct net_device *prNetDev,
3263     IN struct iw_request_info *info,
3264     IN OUT union iwreq_data *wrqu,
3265     IN OUT char *extra
3266     )
3267 {
3268     //printk("mtk_p2p_wext_get_powermode\n");
3269     //wrqu->power.disabled = 0;
3270     //wrqu->power.value = 1;
3271
3272     struct iw_param *prPower = (struct iw_param*)&wrqu->power;
3273     PARAM_POWER_MODE ePowerMode;
3274
3275     P_GLUE_INFO_T prGlueInfo = NULL;
3276     WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
3277     UINT_32 u4BufLen = 0;
3278
3279     ASSERT(prNetDev);
3280     ASSERT(prPower);
3281     if (FALSE == GLUE_CHK_PR2(prNetDev, prPower)) {
3282         return -EINVAL;
3283     }
3284
3285     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prNetDev));
3286     ASSERT(prGlueInfo);
3287
3288
3289 #if 1
3290     rStatus = kalIoctl(prGlueInfo,
3291             wlanoidQueryP2pPowerSaveProfile,
3292             &ePowerMode,
3293             sizeof(ePowerMode),
3294             TRUE,
3295             FALSE,
3296             FALSE,
3297             TRUE,
3298             &u4BufLen);
3299 #else
3300     rStatus = wlanQueryInformation(prGlueInfo->prAdapter,
3301         wlanoidQueryP2pPowerSaveProfile,
3302         &ePowerMode,
3303         sizeof(ePowerMode),
3304         &u4BufLen);
3305 #endif
3306
3307     prPower->value = 0;
3308     prPower->disabled = 1;
3309
3310     if (Param_PowerModeCAM == ePowerMode) {
3311         prPower->value = 0;
3312         prPower->disabled = 1;
3313     }
3314     else if (Param_PowerModeMAX_PSP == ePowerMode ) {
3315         prPower->value = 1;
3316         prPower->disabled = 0;
3317     }
3318     else if (Param_PowerModeFast_PSP == ePowerMode ) {
3319         prPower->value = 2;
3320         prPower->disabled = 0;
3321     }
3322
3323     prPower->flags = IW_POWER_PERIOD | IW_POWER_RELATIVE;
3324 #if WIRELESS_EXT < 21
3325     prPower->value *= 1000000;
3326 #endif
3327
3328
3329     return 0;
3330 }
3331
3332
3333 /*----------------------------------------------------------------------------*/
3334 /*!
3335 * \brief P2P Private I/O Control handler (IOC_P2P_CFG_DEVICE)
3336 *
3337 * \param[in] prDev      Net device requested.
3338 * \param[inout] wrqu    Pointer to iwreq_data
3339 *
3340 * \retval 0 Success.
3341 * \retval -EFAULT Setting parameters to driver fail.
3342 * \retval -EOPNOTSUPP Key size not supported.
3343 *
3344 * \note
3345 */
3346 /*----------------------------------------------------------------------------*/
3347 int
3348 mtk_p2p_wext_set_local_dev_info(
3349     IN struct net_device *prDev,
3350     IN struct iw_request_info *info,
3351     IN OUT union iwreq_data *wrqu,
3352     IN OUT char *extra
3353     )
3354 {
3355     P_ADAPTER_T prAdapter = NULL;
3356     P_GLUE_INFO_T prGlueInfo = NULL;
3357     P_IW_P2P_CFG_DEVICE_TYPE prDeviceCfg = (P_IW_P2P_CFG_DEVICE_TYPE) extra;
3358     P_P2P_CONNECTION_SETTINGS_T prConnSettings;
3359     P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T)NULL;
3360     //P_MSG_P2P_FUNCTION_SWITCH_T prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T)NULL;
3361
3362     ASSERT(prDev);
3363
3364     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
3365     ASSERT(prGlueInfo);
3366
3367     prAdapter = prGlueInfo->prAdapter;
3368     ASSERT(prAdapter);
3369
3370     prConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
3371     prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
3372
3373     // update connection settings for P2P-FSM
3374     // 1. update SSID
3375     if(prDeviceCfg->ssid_len > ELEM_MAX_LEN_SSID) {
3376         prConnSettings->ucSSIDLen = ELEM_MAX_LEN_SSID;
3377     }
3378     else {
3379         prConnSettings->ucSSIDLen = prDeviceCfg->ssid_len;
3380     }
3381
3382     if(copy_from_user(prConnSettings->aucSSID, prDeviceCfg->ssid, prConnSettings->ucSSIDLen)) {
3383         return -EFAULT;
3384     }
3385
3386     // 2. update device type (WPS IE)
3387     kalMemCopy(&(prConnSettings->rPrimaryDevTypeBE), &(prDeviceCfg->pri_device_type), sizeof(DEVICE_TYPE_T));
3388 #if P2P_MAX_SUPPORTED_SEC_DEV_TYPE_COUNT
3389     kalMemCopy(&(prConnSettings->arSecondaryDevTypeBE[0]), &(prDeviceCfg->snd_device_type), sizeof(DEVICE_TYPE_T));
3390 #endif
3391
3392     // 3. update device name
3393     if(prDeviceCfg->device_name_len > WPS_ATTRI_MAX_LEN_DEVICE_NAME) {
3394         prConnSettings->ucDevNameLen = WPS_ATTRI_MAX_LEN_DEVICE_NAME;
3395     }
3396     else {
3397         prConnSettings->ucDevNameLen = prDeviceCfg->device_name_len;
3398     }
3399     if(copy_from_user(prConnSettings->aucDevName, prDeviceCfg->device_name, prConnSettings->ucDevNameLen)) {
3400         return -EFAULT;
3401     }
3402
3403     // 4. update GO intent
3404     prConnSettings->ucGoIntent = prDeviceCfg->intend;
3405
3406
3407     /* Preferred channel bandwidth */
3408     prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode =
3409         prDeviceCfg->ch_width ? CONFIG_BW_20_40M : CONFIG_BW_20M;
3410     prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode =
3411         prDeviceCfg->ch_width ? CONFIG_BW_20_40M : CONFIG_BW_20M;
3412
3413 #if 0
3414     /* 1. switch P2P-FSM on */
3415     /* 1.1 allocate for message */
3416     prFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T) cnmMemAlloc(prAdapter,
3417             RAM_TYPE_MSG,
3418             sizeof(MSG_P2P_FUNCTION_SWITCH_T));
3419
3420     if (!prFuncSwitch) {
3421         ASSERT(0); // Can't trigger P2P FSM
3422         return -ENOMEM;
3423     }
3424
3425     /* 1.2 fill message */
3426     prFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH;
3427     prFuncSwitch->fgIsFuncOn = TRUE;
3428
3429     /* 1.3 send message */
3430     mboxSendMsg(prAdapter,
3431                 MBOX_ID_0,
3432                 (P_MSG_HDR_T) prFuncSwitch,
3433                 MSG_SEND_METHOD_BUF);
3434 #endif
3435     return 0;
3436 } /* end of mtk_p2p_wext_set_local_dev_info() */
3437
3438
3439
3440
3441
3442
3443 /*----------------------------------------------------------------------------*/
3444 /*!
3445  * \brief I/O Control handler for both
3446  *          IOC_P2P_START_STOP_DISCOVERY & SIOCGIWSCAN
3447  *
3448  * \param[in] prDev      Net device requested.
3449  * \param[inout] wrqu    Pointer to iwreq_data
3450  *
3451  * \retval 0 Success.
3452  * \retval -EFAULT Setting parameters to driver fail.
3453  * \retval -EOPNOTSUPP Key size not supported.
3454  *
3455  * \note
3456  */
3457 /*----------------------------------------------------------------------------*/
3458 int
3459 mtk_p2p_wext_discovery_results(
3460     IN struct net_device *prDev,
3461     IN struct iw_request_info *info,
3462     IN OUT union iwreq_data *wrqu,
3463     IN OUT char *extra
3464     )
3465 {
3466     struct iw_event iwe;
3467     char *current_ev = extra;
3468     UINT_32 i;
3469     P_GLUE_INFO_T prGlueInfo = NULL;
3470     P_ADAPTER_T prAdapter = NULL;
3471     P_P2P_INFO_T prP2PInfo = (P_P2P_INFO_T)NULL;
3472     P_EVENT_P2P_DEV_DISCOVER_RESULT_T prTargetResult = (P_EVENT_P2P_DEV_DISCOVER_RESULT_T)NULL;
3473     P_PARAM_VARIABLE_IE_T prDesiredIE = NULL;
3474
3475     ASSERT(prDev);
3476
3477     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
3478     ASSERT(prGlueInfo);
3479
3480     prAdapter = prGlueInfo->prAdapter;
3481     ASSERT(prAdapter);
3482
3483     prP2PInfo = prAdapter->prP2pInfo;
3484
3485     for(i = 0 ; i < prP2PInfo->u4DeviceNum ; i++) {
3486         prTargetResult = &prP2PInfo->arP2pDiscoverResult[i];
3487
3488         /* SIOCGIWAP */
3489         iwe.cmd = SIOCGIWAP;
3490         iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
3491         memcpy(iwe.u.ap_addr.sa_data,
3492                 prTargetResult->aucInterfaceAddr,
3493                 6);
3494
3495         current_ev = iwe_stream_add_event(info, current_ev,
3496                 extra + IW_SCAN_MAX_DATA,
3497                 &iwe, IW_EV_ADDR_LEN);
3498
3499
3500         /* SIOCGIWESSID */
3501         iwe.cmd = SIOCGIWESSID;
3502         iwe.u.data.flags = 1;
3503         iwe.u.data.length = prTargetResult->u2NameLength;
3504
3505         current_ev = iwe_stream_add_point(info, current_ev,
3506                 extra + IW_SCAN_MAX_DATA,
3507                 &iwe, prTargetResult->aucName);
3508
3509         /* IWEVGENIE for WPA IE */
3510         if(prTargetResult->u2IELength <= 600 && wextSrchDesiredWPAIE(prTargetResult->pucIeBuf,
3511                     prTargetResult->u2IELength,
3512                     0xDD,
3513                     (PUINT_8 *)&prDesiredIE)) {
3514
3515             iwe.cmd = IWEVGENIE;
3516             iwe.u.data.flags = 1;
3517             iwe.u.data.length = 2 + (__u16)prDesiredIE->ucLength;
3518
3519             current_ev = iwe_stream_add_point(info, current_ev,
3520                     extra + IW_SCAN_MAX_DATA,
3521                     &iwe, (char *)prDesiredIE);
3522         }
3523
3524 #if CFG_SUPPORT_WPS
3525
3526         /* IWEVGENIE for WPS IE */
3527         if((prTargetResult->u2IELength <= 600) && wextSrchDesiredWPSIE(prTargetResult->pucIeBuf,
3528                     prTargetResult->u2IELength,
3529                     0xDD,
3530                     (PUINT_8 *)&prDesiredIE)) {
3531
3532             iwe.cmd = IWEVGENIE;
3533             iwe.u.data.flags = 1;
3534             iwe.u.data.length = 2 + (__u16)prDesiredIE->ucLength;
3535
3536             current_ev = iwe_stream_add_point(info, current_ev,
3537                     extra + IW_SCAN_MAX_DATA,
3538                     &iwe, (char *)prDesiredIE);
3539         }
3540
3541 #endif
3542
3543         /* IWEVGENIE for RSN IE */
3544         if((prTargetResult->u2IELength <= 600) && wextSrchDesiredWPAIE(prTargetResult->pucIeBuf,
3545                     prTargetResult->u2IELength,
3546                     0x30,
3547                     (PUINT_8 *)&prDesiredIE)) {
3548
3549             iwe.cmd = IWEVGENIE;
3550             iwe.u.data.flags = 1;
3551             iwe.u.data.length = 2 + (__u16)prDesiredIE->ucLength;
3552
3553             current_ev = iwe_stream_add_point(info, current_ev,
3554                     extra + IW_SCAN_MAX_DATA,
3555                     &iwe, (char *)prDesiredIE);
3556         }
3557
3558         /* IOC_P2P_GO_WSC_IE */
3559 #if 1
3560         /* device capability */
3561         if (1) {
3562             UINT_8 data[40];
3563
3564             iwe.cmd = IWEVCUSTOM;
3565             iwe.u.data.flags = 0;
3566             iwe.u.data.length = 8 + sizeof("p2p_cap=");
3567
3568             snprintf(data, iwe.u.data.length, "p2p_cap=%02x%02x%02x%02x%c",
3569                 prTargetResult->ucDeviceCapabilityBitmap, prTargetResult->ucGroupCapabilityBitmap,
3570                 (UINT_8)prTargetResult->u2ConfigMethod, (UINT_8)(prTargetResult->u2ConfigMethod >> 8), '\0' );
3571                 current_ev = iwe_stream_add_point(info, current_ev,
3572                         extra + IW_SCAN_MAX_DATA,
3573                         &iwe, (char *)data);
3574
3575             //printk("%s\n", data);
3576             kalMemZero(data, 40);
3577
3578             iwe.cmd = IWEVCUSTOM;
3579             iwe.u.data.flags = 0;
3580             iwe.u.data.length = 12 + sizeof("p2p_dev_type=");
3581
3582             snprintf(data, iwe.u.data.length, "p2p_dev_type=%02x%02x%02x%02x%02x%02x%c",
3583                 (UINT_8)prTargetResult->rPriDevType.u2CategoryID,(UINT_8)prTargetResult->rPriDevType.u2SubCategoryID,
3584                 (UINT_8)prTargetResult->arSecDevType[0].u2CategoryID,(UINT_8)prTargetResult->arSecDevType[0].u2SubCategoryID,
3585                 (UINT_8)prTargetResult->arSecDevType[1].u2CategoryID,(UINT_8)prTargetResult->arSecDevType[1].u2SubCategoryID,
3586                 '\0');
3587                 current_ev = iwe_stream_add_point(info, current_ev,
3588                         extra + IW_SCAN_MAX_DATA,
3589                         &iwe, (char *)data);
3590             //printk("%s\n", data);
3591
3592                         kalMemZero(data, 40);
3593
3594             iwe.cmd = IWEVCUSTOM;
3595             iwe.u.data.flags = 0;
3596             iwe.u.data.length = 17 + sizeof("p2p_grp_bssid=");
3597
3598             snprintf(data, iwe.u.data.length, "p2p_grp_bssid="MACSTR"%c",
3599                 MAC2STR(prTargetResult->aucBSSID), '\0');
3600                 current_ev = iwe_stream_add_point(info, current_ev,
3601                         extra + IW_SCAN_MAX_DATA,
3602                         &iwe, (char *)data);
3603             //printk("%s\n", data);
3604
3605         }
3606 #endif
3607     }
3608
3609     /* Length of data */
3610     wrqu->data.length = (current_ev - extra);
3611     wrqu->data.flags = 0;
3612
3613     return 0;
3614 } /* end of mtk_p2p_wext_discovery_results() */
3615
3616
3617 /*----------------------------------------------------------------------------*/
3618 /*!
3619 * \brief P2P Private I/O Control handler (IOC_P2P_WSC_BEACON_PROBE_RSP_IE)
3620 *
3621 * \param[in] prDev      Net device requested.
3622 * \param[inout] wrqu    Pointer to iwreq_data
3623 *
3624 * \retval 0 Success.
3625 * \retval -EFAULT Setting parameters to driver fail.
3626 * \retval -EOPNOTSUPP Key size not supported.
3627 *
3628 * \note
3629 */
3630 /*----------------------------------------------------------------------------*/
3631 int
3632 mtk_p2p_wext_wsc_ie(
3633     IN struct net_device *prDev,
3634     IN struct iw_request_info *info,
3635     IN OUT union iwreq_data *wrqu,
3636     IN OUT char *extra
3637     )
3638 {
3639     P_ADAPTER_T prAdapter = NULL;
3640     P_GLUE_INFO_T prGlueInfo = NULL;
3641     P_IW_P2P_HOSTAPD_PARAM prHostapdParam = (P_IW_P2P_HOSTAPD_PARAM)extra;
3642
3643     ASSERT(prDev);
3644
3645     prGlueInfo = *((P_GLUE_INFO_T *)netdev_priv(prDev));
3646     ASSERT(prGlueInfo);
3647
3648     if (prHostapdParam->len > 0) {
3649         if (prHostapdParam->len <= MAX_WSC_IE_LENGTH) {
3650             if (copy_from_user(prGlueInfo->prP2PInfo->aucWSCIE[0], prHostapdParam->data, prHostapdParam->len)) {
3651                 return -EFAULT;
3652             }
3653             if (copy_from_user(prGlueInfo->prP2PInfo->aucWSCIE[2], prHostapdParam->data, prHostapdParam->len)) {
3654                 return -EFAULT;
3655             }
3656         }
3657         else {
3658             return -E2BIG;
3659         }
3660     }
3661
3662     prGlueInfo->prP2PInfo->u2WSCIELen[0] = prHostapdParam->len;
3663     prGlueInfo->prP2PInfo->u2WSCIELen[2] = prHostapdParam->len;
3664
3665     prAdapter = prGlueInfo->prAdapter;
3666     ASSERT(prAdapter);
3667
3668     bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX);
3669
3670     //@TODO: send message to P2P-FSM
3671
3672     return 0;
3673 } /* end of mtk_p2p_wext_wsc_ie() */
3674
3675
3676 /*----------------------------------------------------------------------------*/
3677 /*!
3678 * \brief P2P Private I/O Control handler (IOC_P2P_CONNECT_DISCONNECT)
3679 *
3680 * \param[in] prDev      Net device requested.
3681 * \param[inout] wrqu    Pointer to iwreq_data
3682 *
3683 * \retval 0 Success.
3684 * \retval -EFAULT Setting parameters to driver fail.
3685 * \retval -EOPNOTSUPP Key size not supported.
3686 *
3687 * \note
3688 */
3689 /*----------------------------------------------------------------------------*/
3690 int
3691 mtk_p2p_wext_connect_disconnect(
3692     IN struct net_device *prDev,
3693     IN struct iw_request_info *info,
3694     IN OUT union iwreq_data *wrqu,
3695     IN OUT char *extra
3696     )
3697 {
3698     P_ADAPTER_T prAdapter = NULL;
3699     P_GLUE_INFO_T prGlueInfo = NULL;
3700     struct iw_point *prData= (struct iw_point *)&wrqu->data;
3701 //    P_IW_P2P_CONNECT_DEVICE prConnectDevice = (P_IW_P2P_CONNECT_DEVICE)extra;
3702 //    P_MSG_HDR_T prMsgHdr;
3703 //    P_MSG_P2P_CONNECTION_REQUEST_T prMsgP2PConnReq;
3704 //    P_MSG_P2P_CONNECTION_ABORT_T prMsgP2PConnAbt;
3705 //    UINT_8 aucBCAddr[] = BC_MAC_ADDR;
3706
3707     ASSERT(prDev);
3708
3709     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
3710     ASSERT(prGlueInfo);
3711
3712     prAdapter = prGlueInfo->prAdapter;
3713     ASSERT(prAdapter);
3714
3715     if (prData->flags == P2P_CONNECT) {
3716 #if 0
3717         // indicate P2P-FSM with MID_MNY_P2P_CONNECTION_REQ
3718         prMsgP2PConnReq = (P_MSG_P2P_CONNECTION_REQUEST_T) cnmMemAlloc(prAdapter,
3719             RAM_TYPE_MSG,
3720             sizeof(MSG_P2P_CONNECTION_REQUEST_T));
3721
3722         if (!prMsgP2PConnReq) {
3723             ASSERT(0); // Can't trigger P2P FSM
3724             return -ENOMEM;
3725         }
3726
3727
3728         mboxSendMsg(prAdapter,
3729                 MBOX_ID_0,
3730                 (P_MSG_HDR_T) prMsgP2PConnReq,
3731                 MSG_SEND_METHOD_BUF);
3732 #endif
3733     }
3734     else if(prData->flags == P2P_DISCONNECT) {
3735 #if 0
3736         // indicate P2P-FSM with MID_MNY_P2P_CONNECTION_ABORT
3737         prMsgP2PConnAbt = (P_MSG_HDR_T) cnmMemAlloc(prAdapter,
3738             RAM_TYPE_MSG,
3739             sizeof(MSG_P2P_CONNECTION_ABORT_T));
3740
3741         if (!prMsgP2PConnAbt) {
3742             ASSERT(0); // Can't trigger P2P FSM
3743             return -ENOMEM;
3744         }
3745
3746         COPY_MAC_ADDR(prMsgP2PConnAbt->aucTargetID, prConnectDevice->sta_addr);
3747
3748         prMsgP2PConnAbt->rMsgHdr.eMsgId = MID_MNY_P2P_CONNECTION_ABORT;
3749
3750         mboxSendMsg(prAdapter,
3751                 MBOX_ID_0,
3752                 (P_MSG_HDR_T) prMsgP2PConnAbt,
3753                 MSG_SEND_METHOD_BUF);
3754 #endif
3755     }
3756     else {
3757         return -EINVAL;
3758     }
3759
3760     return 0;
3761 } /* end of mtk_p2p_wext_connect_disconnect() */
3762
3763
3764 /*----------------------------------------------------------------------------*/
3765 /*!
3766 * \brief P2P Private I/O Control handler (IOC_P2P_PASSWORD_READY)
3767 *
3768 * \param[in] prDev      Net device requested.
3769 * \param[inout] wrqu    Pointer to iwreq_data
3770 *
3771 * \retval 0 Success.
3772 * \retval -EFAULT Setting parameters to driver fail.
3773 * \retval -EOPNOTSUPP Key size not supported.
3774 *
3775 * \note
3776 */
3777 /*----------------------------------------------------------------------------*/
3778 int
3779 mtk_p2p_wext_password_ready(
3780     IN struct net_device *prDev,
3781     IN struct iw_request_info *info,
3782     IN OUT union iwreq_data *wrqu,
3783     IN OUT char *extra
3784     )
3785 {
3786     P_ADAPTER_T prAdapter = NULL;
3787     P_GLUE_INFO_T prGlueInfo = NULL;
3788     P_IW_P2P_PASSWORD_READY prPasswordReady = (P_IW_P2P_PASSWORD_READY)extra;
3789     P_P2P_CONNECTION_SETTINGS_T prConnSettings;
3790
3791     ASSERT(prDev);
3792
3793     prGlueInfo = *((P_GLUE_INFO_T *)netdev_priv(prDev));
3794     ASSERT(prGlueInfo);
3795
3796     prAdapter = prGlueInfo->prAdapter;
3797     ASSERT(prAdapter);
3798
3799     prConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
3800
3801     /* retrieve IE for Probe Request */
3802     if (prPasswordReady->probe_req_len > 0) {
3803         if (prPasswordReady->probe_req_len <= MAX_WSC_IE_LENGTH) {
3804             if (copy_from_user(prGlueInfo->prP2PInfo->aucWSCIE[1], prPasswordReady->probe_req_ie, prPasswordReady->probe_req_len)) {
3805                 return -EFAULT;
3806             }
3807         }
3808         else {
3809             return -E2BIG;
3810         }
3811     }
3812
3813     prGlueInfo->prP2PInfo->u2WSCIELen[1] = prPasswordReady->probe_req_len;
3814
3815     /* retrieve IE for Probe Response */
3816     if (prPasswordReady->probe_rsp_len > 0) {
3817         if (prPasswordReady->probe_rsp_len <= MAX_WSC_IE_LENGTH) {
3818             if (copy_from_user(prGlueInfo->prP2PInfo->aucWSCIE[2], prPasswordReady->probe_rsp_ie, prPasswordReady->probe_rsp_len)) {
3819                 return -EFAULT;
3820             }
3821         }
3822         else {
3823             return -E2BIG;
3824         }
3825     }
3826
3827     prGlueInfo->prP2PInfo->u2WSCIELen[2] = prPasswordReady->probe_rsp_len;
3828
3829     switch (prPasswordReady->active_config_method) {
3830       case 1:
3831           prConnSettings->u2LocalConfigMethod = WPS_ATTRI_CFG_METHOD_PUSH_BUTTON;
3832           break;
3833       case 2:
3834           prConnSettings->u2LocalConfigMethod = WPS_ATTRI_CFG_METHOD_KEYPAD;
3835           break;
3836       case 3:
3837           prConnSettings->u2LocalConfigMethod = WPS_ATTRI_CFG_METHOD_DISPLAY;
3838           break;
3839       default:
3840          break;
3841     }
3842
3843     prConnSettings->fgIsPasswordIDRdy = TRUE;
3844     return 0;
3845 } /* end of mtk_p2p_wext_password_ready() */
3846
3847
3848 /*----------------------------------------------------------------------------*/
3849 /*!
3850 * \brief P2P Private I/O Control handler (IOC_P2P_GET_REQ_DEVICE_INFO)
3851 *
3852 * \param[in] prDev      Net device requested.
3853 * \param[inout] wrqu    Pointer to iwreq_data
3854 *
3855 * \retval 0 Success.
3856 * \retval -EFAULT Setting parameters to driver fail.
3857 * \retval -EOPNOTSUPP Key size not supported.
3858 *
3859 * \note
3860 */
3861 /*----------------------------------------------------------------------------*/
3862 int
3863 mtk_p2p_wext_request_dev_info(
3864     IN struct net_device *prDev,
3865     IN struct iw_request_info *info,
3866     IN OUT union iwreq_data *wrqu,
3867     IN OUT char *extra
3868     )
3869 {
3870     P_ADAPTER_T prAdapter = NULL;
3871     P_GLUE_INFO_T prGlueInfo = NULL;
3872     P_IW_P2P_DEVICE_REQ prDeviceReq = (P_IW_P2P_DEVICE_REQ)extra;
3873
3874     ASSERT(prDev);
3875
3876     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
3877     ASSERT(prGlueInfo);
3878
3879     prAdapter = prGlueInfo->prAdapter;
3880     ASSERT(prAdapter);
3881
3882     // specify data length
3883     wrqu->data.length = sizeof(IW_P2P_DEVICE_REQ);
3884
3885     // copy to upper-layer supplied buffer
3886     kalMemCopy(prDeviceReq->name, prGlueInfo->prP2PInfo->aucConnReqDevName, prGlueInfo->prP2PInfo->u4ConnReqNameLength);
3887     prDeviceReq->name_len = prGlueInfo->prP2PInfo->u4ConnReqNameLength;
3888     prDeviceReq->name[prDeviceReq->name_len]='\0';
3889     COPY_MAC_ADDR(prDeviceReq->device_addr, prGlueInfo->prP2PInfo->rConnReqPeerAddr);
3890     prDeviceReq->device_type = prGlueInfo->prP2PInfo->ucConnReqDevType;
3891     prDeviceReq->config_method = prGlueInfo->prP2PInfo->i4ConnReqConfigMethod;
3892     prDeviceReq->active_config_method = prGlueInfo->prP2PInfo->i4ConnReqActiveConfigMethod;
3893
3894     return 0;
3895 } /* end of mtk_p2p_wext_request_dev_info() */
3896
3897
3898 /*----------------------------------------------------------------------------*/
3899 /*!
3900 * \brief P2P Private I/O Control handler (IOC_P2P_GET_STRUCT)
3901 *
3902 * \param[in] prDev      Net device requested.
3903 * \param[inout] wrqu    Pointer to iwreq_data
3904 *
3905 * \retval 0 Success.
3906 * \retval -EFAULT Setting parameters to driver fail.
3907 * \retval -EOPNOTSUPP Key size not supported.
3908 *
3909 * \note
3910 */
3911 /*----------------------------------------------------------------------------*/
3912 int
3913 mtk_p2p_wext_invitation_indicate(
3914     IN struct net_device *prDev,
3915     IN struct iw_request_info *info,
3916     IN OUT union iwreq_data *wrqu,
3917     IN OUT char *extra
3918     )
3919 {
3920     P_ADAPTER_T prAdapter = NULL;
3921     P_GLUE_INFO_T prGlueInfo = NULL;
3922     P_IW_P2P_IOCTL_INVITATION_INDICATE prInvIndicate = (P_IW_P2P_IOCTL_INVITATION_INDICATE)extra;
3923
3924     ASSERT(prDev);
3925
3926     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
3927     ASSERT(prGlueInfo);
3928
3929     prAdapter = prGlueInfo->prAdapter;
3930     ASSERT(prAdapter);
3931
3932     // specify data length
3933     wrqu->data.length = sizeof(IW_P2P_IOCTL_INVITATION_INDICATE);
3934
3935     // copy to upper-layer supplied buffer
3936     kalMemCopy(prInvIndicate->dev_name, prGlueInfo->prP2PInfo->aucConnReqDevName, prGlueInfo->prP2PInfo->u4ConnReqNameLength);
3937     kalMemCopy(prInvIndicate->group_bssid, prGlueInfo->prP2PInfo->rConnReqGroupAddr, MAC_ADDR_LEN);
3938     prInvIndicate->name_len = prGlueInfo->prP2PInfo->u4ConnReqNameLength;
3939     prInvIndicate->dev_name[prInvIndicate->name_len]='\0';
3940     COPY_MAC_ADDR(prInvIndicate->dev_addr, prGlueInfo->prP2PInfo->rConnReqPeerAddr);
3941     prInvIndicate->config_method = prGlueInfo->prP2PInfo->i4ConnReqConfigMethod;
3942     prInvIndicate->operating_channel = prGlueInfo->prP2PInfo->ucOperatingChnl;
3943     prInvIndicate->invitation_type = prGlueInfo->prP2PInfo->ucInvitationType;
3944
3945     return 0;
3946 } /* end of mtk_p2p_wext_invitation_indicate() */
3947
3948
3949 /*----------------------------------------------------------------------------*/
3950 /*!
3951 * \brief P2P Private I/O Control handler (IOC_P2P_GET_STRUCT)
3952 *
3953 * \param[in] prDev      Net device requested.
3954 * \param[inout] wrqu    Pointer to iwreq_data
3955 *
3956 * \retval 0 Success.
3957 * \retval -EFAULT Setting parameters to driver fail.
3958 * \retval -EOPNOTSUPP Key size not supported.
3959 *
3960 * \note
3961 */
3962 /*----------------------------------------------------------------------------*/
3963 int
3964 mtk_p2p_wext_invitation_status(
3965     IN struct net_device *prDev,
3966     IN struct iw_request_info *info,
3967     IN OUT union iwreq_data *wrqu,
3968     IN OUT char *extra
3969     )
3970 {
3971     P_ADAPTER_T prAdapter = NULL;
3972     P_GLUE_INFO_T prGlueInfo = NULL;
3973     P_IW_P2P_IOCTL_INVITATION_STATUS prInvStatus = (P_IW_P2P_IOCTL_INVITATION_STATUS)extra;
3974
3975     ASSERT(prDev);
3976
3977     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
3978     ASSERT(prGlueInfo);
3979
3980     prAdapter = prGlueInfo->prAdapter;
3981     ASSERT(prAdapter);
3982
3983     // specify data length
3984     wrqu->data.length = sizeof(IW_P2P_IOCTL_INVITATION_STATUS);
3985
3986     // copy to upper-layer supplied buffer
3987     prInvStatus->status_code = prGlueInfo->prP2PInfo->u4InvStatus;
3988
3989     return 0;
3990 } /* end of mtk_p2p_wext_invitation_status() */
3991
3992
3993 /*----------------------------------------------------------------------------*/
3994 /*!
3995 * \brief indicate an event to supplicant for device found
3996 *
3997 * \param[in] prGlueInfo Pointer of GLUE_INFO_T
3998 *
3999 * \retval TRUE  Success.
4000 * \retval FALSE Failure
4001 */
4002 /*----------------------------------------------------------------------------*/
4003 BOOLEAN
4004 kalP2PIndicateFound(
4005     IN P_GLUE_INFO_T    prGlueInfo
4006     )
4007 {
4008     union iwreq_data evt;
4009     UINT_8 aucBuffer[IW_CUSTOM_MAX];
4010
4011     ASSERT(prGlueInfo);
4012
4013     memset(&evt, 0, sizeof(evt));
4014
4015     snprintf(aucBuffer, IW_CUSTOM_MAX-1, "P2P_DVC_FND");
4016     evt.data.length = strlen(aucBuffer);
4017
4018     /* indicate IWEVP2PDVCFND event */
4019     wireless_send_event(prGlueInfo->prP2PInfo->prDevHandler,
4020             IWEVCUSTOM,
4021             &evt,
4022             aucBuffer);
4023
4024     return FALSE;
4025 } /* end of kalP2PIndicateFound() */
4026
4027 int
4028 mtk_p2p_wext_set_network_address (
4029     IN struct net_device *prDev,
4030     IN struct iw_request_info *info,
4031     IN OUT union iwreq_data *wrqu,
4032     IN OUT char *extra
4033     )
4034 {
4035     P_ADAPTER_T prAdapter = NULL;
4036     P_GLUE_INFO_T prGlueInfo = NULL;
4037
4038     ASSERT(prDev);
4039
4040     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
4041     ASSERT(prGlueInfo);
4042
4043     prAdapter = prGlueInfo->prAdapter;
4044     ASSERT(prAdapter);
4045
4046     //@TODO: invoke wlan_p2p functions
4047 #if 0
4048                         rStatus = kalIoctl(prGlueInfo,
4049                                 (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetP2pNetworkAddress,
4050                                 prKey,
4051                                 prKey->u4Length,
4052                                 FALSE,
4053                                 FALSE,
4054                                 TRUE,
4055                                 &u4BufLen);
4056 #endif
4057
4058     return 0;
4059
4060 }
4061
4062 int
4063 mtk_p2p_wext_set_ps_profile (
4064     IN struct net_device *prDev,
4065     IN struct iw_request_info *info,
4066     IN OUT union iwreq_data *wrqu,
4067     IN OUT char *extra
4068     )
4069 {
4070     P_ADAPTER_T prAdapter = NULL;
4071     P_GLUE_INFO_T prGlueInfo = NULL;
4072
4073     ASSERT(prDev);
4074
4075     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
4076     ASSERT(prGlueInfo);
4077
4078     prAdapter = prGlueInfo->prAdapter;
4079     ASSERT(prAdapter);
4080
4081     //@TODO: invoke wlan_p2p functions
4082 #if 0
4083                         rStatus = kalIoctl(prGlueInfo,
4084                                 (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetP2pPowerSaveProfile,
4085                                 prKey,
4086                                 prKey->u4Length,
4087                                 FALSE,
4088                                 FALSE,
4089                                 TRUE,
4090                                 &u4BufLen);
4091 #endif
4092
4093     return 0;
4094
4095 }
4096
4097 int
4098 mtk_p2p_wext_set_pm_param (
4099     IN struct net_device *prDev,
4100     IN struct iw_request_info *info,
4101     IN OUT union iwreq_data *wrqu,
4102     IN OUT char *extra
4103     )
4104 {
4105     P_ADAPTER_T prAdapter = NULL;
4106     P_GLUE_INFO_T prGlueInfo = NULL;
4107
4108     ASSERT(prDev);
4109
4110     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
4111     ASSERT(prGlueInfo);
4112
4113     prAdapter = prGlueInfo->prAdapter;
4114     ASSERT(prAdapter);
4115
4116     //@TODO: invoke wlan_p2p functions
4117 #if 0
4118                         rStatus = kalIoctl(prGlueInfo,
4119                                 (PFN_OID_HANDLER_FUNC_REQ)wlanoidSetP2pPowerSaveProfile,
4120                                 prKey,
4121                                 prKey->u4Length,
4122                                 FALSE,
4123                                 FALSE,
4124                                 TRUE,
4125                                 &u4BufLen);
4126 #endif
4127
4128     return 0;
4129
4130 }
4131
4132
4133
4134 /*----------------------------------------------------------------------------*/
4135 /*!
4136 * \brief P2P Private I/O Control handler (IOC_P2P_SET_INT)
4137 *
4138 * \param[in] prDev      Net device requested.
4139 * \param[inout] wrqu    Pointer to iwreq_data
4140 *
4141 * \retval 0 Success.
4142 * \retval -EFAULT Setting parameters to driver fail.
4143 * \retval -EOPNOTSUPP Setting parameters not support.
4144 *
4145 * \note
4146 */
4147 /*----------------------------------------------------------------------------*/
4148 int
4149 mtk_p2p_wext_start_formation (
4150     IN struct net_device *prDev,
4151     IN struct iw_request_info *info,
4152     IN OUT union iwreq_data *wrqu,
4153     IN OUT char *extra
4154     )
4155 {
4156     int i4Status = 0;
4157     P_ADAPTER_T prAdapter = (P_ADAPTER_T)NULL;
4158     P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T)NULL;
4159 //    struct iw_point *prData = (struct iw_point*)&wrqu->data;
4160     P_IW_P2P_IOCTL_START_FORMATION prIoctlStartFormation = (P_IW_P2P_IOCTL_START_FORMATION)NULL;
4161
4162     do {
4163         if ((prDev == NULL) || (extra == NULL)) {
4164             ASSERT(FALSE);
4165             i4Status = -EINVAL;
4166             break;
4167         }
4168
4169
4170         prGlueInfo = *((P_GLUE_INFO_T *)netdev_priv(prDev));
4171         prIoctlStartFormation = (P_IW_P2P_IOCTL_START_FORMATION)extra;
4172
4173         if (prGlueInfo == NULL) {
4174             i4Status = -EINVAL;
4175             break;
4176         }
4177
4178
4179         prAdapter = prGlueInfo->prAdapter;
4180
4181         if (prAdapter == NULL) {
4182             i4Status = -EINVAL;
4183             break;
4184         }
4185
4186
4187     } while (FALSE);
4188
4189     return i4Status;
4190
4191 }
4192 /* mtk_p2p_wext_start_formation */
4193
4194
4195 /*----------------------------------------------------------------------------*/
4196 /*!
4197 * \brief P2P Private I/O Control handler (IOC_P2P_SET_INT)
4198 *
4199 * \param[in] prDev      Net device requested.
4200 * \param[inout] wrqu    Pointer to iwreq_data
4201 *
4202 * \retval 0 Success.
4203 * \retval -EFAULT Setting parameters to driver fail.
4204 * \retval -EOPNOTSUPP Setting parameters not support.
4205 *
4206 * \note
4207 */
4208 /*----------------------------------------------------------------------------*/
4209 int
4210 mtk_p2p_wext_set_int (
4211     IN struct net_device *prDev,
4212     IN struct iw_request_info *info,
4213     IN OUT union iwreq_data *wrqu,
4214     IN OUT char *extra
4215     )
4216 {
4217     int                         status = 0;
4218     UINT_32                     u4SubCmd = 0;
4219     P_GLUE_INFO_T               prGlueInfo = NULL;
4220     UINT_32                     index;
4221     INT_32                      value;
4222     PUINT_32                    pu4IntBuf;
4223     P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T)NULL;
4224     P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T)NULL;
4225     P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T)NULL;
4226     UINT_32 u4Leng;
4227
4228     ASSERT(prDev);
4229     ASSERT(wrqu);
4230
4231     //printk("mtk_p2p_wext_set_int\n");
4232     pu4IntBuf = (PUINT_32) extra;
4233
4234     if (FALSE == GLUE_CHK_PR2(prDev, wrqu)) {
4235         return -EINVAL;
4236     }
4237
4238     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
4239     ASSERT(prGlueInfo);
4240
4241     prP2pSpecificBssInfo = prGlueInfo->prAdapter->rWifiVar.prP2pSpecificBssInfo;
4242     prP2pConnSettings = prGlueInfo->prAdapter->rWifiVar.prP2PConnSettings;
4243     prP2pFsmInfo =  prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo;
4244
4245     u4SubCmd = (UINT_32) wrqu->mode;
4246     index = pu4IntBuf[1];
4247     value = pu4IntBuf[2];
4248
4249     printk("set parameter, u4SubCmd=%d idx=%d value=%lu\n", (INT_16)u4SubCmd, (INT_16)index, value);
4250
4251     switch (u4SubCmd) {
4252       case PRIV_CMD_INT_P2P_SET:
4253         switch (index) {
4254           case 0: /* Listen CH */
4255             {
4256                 UINT_8 ucSuggestChnl = 0;
4257
4258                 prP2pConnSettings->ucListenChnl = value;
4259
4260               // 20110920 - frog: User configurations are placed in ConnSettings.
4261               if (rlmFuncFindAvailableChannel(prGlueInfo->prAdapter, value, &ucSuggestChnl, TRUE, TRUE)) {
4262                  prP2pSpecificBssInfo->ucListenChannel = value;
4263               }
4264               else {
4265                  prP2pSpecificBssInfo->ucListenChannel = ucSuggestChnl;
4266               }
4267
4268
4269               break;
4270             }
4271           case 1: /* P2p mode */
4272               break;
4273           case 4: /* Noa duration */
4274                 prP2pSpecificBssInfo->rNoaParam.u4NoaDurationMs = value;
4275                 // only to apply setting when setting NOA count
4276                 //status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam);
4277               break;
4278           case 5: /* Noa interval */
4279                 prP2pSpecificBssInfo->rNoaParam.u4NoaIntervalMs = value;
4280                 // only to apply setting when setting NOA count
4281                 //status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam);
4282               break;
4283           case 6: /* Noa count */
4284                 prP2pSpecificBssInfo->rNoaParam.u4NoaCount = value;
4285                 status = mtk_p2p_wext_set_noa_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rNoaParam);
4286               break;
4287           case 100: /* Oper CH */
4288               // 20110920 - frog: User configurations are placed in ConnSettings.
4289               prP2pConnSettings->ucOperatingChnl = value;
4290               break;
4291           case 101: /* Local config Method, for P2P SDK */
4292               //prP2pConnSettings->u2LocalConfigMethod;
4293               break;
4294           case 102: /* Sigma P2p reset */
4295               kalMemZero(prP2pConnSettings->aucTargetDevAddr, MAC_ADDR_LEN);
4296               //prP2pConnSettings->eConnectionPolicy = ENUM_P2P_CONNECTION_POLICY_AUTO;
4297               break;
4298           case 103: /* WPS MODE */
4299               kalP2PSetWscMode(prGlueInfo, value);
4300               break;
4301           case 104: /* P2p send persence, duration */
4302               break;
4303           case 105: /* P2p send persence, interval */
4304               break;
4305           case 106: /* P2P set sleep  */
4306                 value = 1;
4307                 kalIoctl(prGlueInfo,
4308                     wlanoidSetP2pPowerSaveProfile,
4309                     &value,
4310                     sizeof(value),
4311                     FALSE,
4312                     FALSE,
4313                     TRUE,
4314                     TRUE,
4315                     &u4Leng);
4316               break;
4317           case 107: /* P2P set opps, CTWindowl */
4318                 prP2pSpecificBssInfo->rOppPsParam.u4CTwindowMs = value;
4319                 status = mtk_p2p_wext_set_oppps_param(prDev, info, wrqu, (char *)&prP2pSpecificBssInfo->rOppPsParam);
4320               break;
4321           case 108: /* p2p_set_power_save */
4322                 kalIoctl(prGlueInfo,
4323                     wlanoidSetP2pPowerSaveProfile,
4324                     &value,
4325                     sizeof(value),
4326                     FALSE,
4327                     FALSE,
4328                     TRUE,
4329                     TRUE,
4330                     &u4Leng);
4331
4332               break;
4333
4334           default:
4335               break;
4336         }
4337         break;
4338       default:
4339         break;
4340     }
4341
4342     return status;
4343 }
4344
4345 /*----------------------------------------------------------------------------*/
4346 /*!
4347 * \brief P2P Private I/O Control handler (IOC_P2P_SET_STRUCT)
4348 *
4349 * \param[in] prDev      Net device requested.
4350 * \param[inout] wrqu    Pointer to iwreq_data
4351 *
4352 * \retval 0 Success.
4353 * \retval -EFAULT Setting parameters to driver fail.
4354 * \retval -EOPNOTSUPP Key size not supported.
4355 *
4356 * \note
4357 */
4358 /*----------------------------------------------------------------------------*/
4359 int
4360 mtk_p2p_wext_set_struct (
4361     IN struct net_device *prDev,
4362     IN struct iw_request_info *info,
4363     IN OUT union iwreq_data *wrqu,
4364     IN OUT char *extra
4365     )
4366 {
4367     int                         status = 0;
4368     UINT_32                     u4SubCmd = 0;
4369     P_GLUE_INFO_T               prGlueInfo = NULL;
4370     P_IW_P2P_TRANSPORT_STRUCT   prP2PReq = NULL;
4371
4372     ASSERT(prDev);
4373     ASSERT(wrqu);
4374
4375     if (FALSE == GLUE_CHK_PR2(prDev, wrqu)) {
4376         return -EINVAL;
4377     }
4378
4379     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
4380     ASSERT(prGlueInfo);
4381
4382     u4SubCmd = (UINT_32) wrqu->data.flags;
4383
4384     kalMemZero(&prGlueInfo->prP2PInfo->aucOidBuf[0],
4385         sizeof(prGlueInfo->prP2PInfo->aucOidBuf));
4386
4387     switch (u4SubCmd) {
4388     case PRIV_CMD_OID:
4389         if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]),
4390                     wrqu->data.pointer,
4391                     wrqu->data.length)) {
4392             status = -EFAULT;
4393             break;
4394         }
4395
4396         if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), extra, wrqu->data.length)) {
4397             printk(KERN_INFO DRV_NAME"extra buffer is valid\n");
4398         }
4399         else {
4400             printk(KERN_INFO DRV_NAME"extra 0x%p\n", extra);
4401         }
4402
4403         prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0]));
4404         switch(prP2PReq->u4CmdId) {
4405         case P2P_CMD_ID_SEND_SD_RESPONSE:
4406             status = mtk_p2p_wext_send_service_discovery_response(prDev, info, wrqu, (char *)prP2PReq);
4407             break;
4408
4409         case P2P_CMD_ID_SEND_SD_REQUEST:
4410             status = mtk_p2p_wext_send_service_discovery_request(prDev, info, wrqu, (char *)prP2PReq);
4411             break;
4412
4413         case P2P_CMD_ID_TERMINATE_SD_PHASE:
4414             status = mtk_p2p_wext_terminate_service_discovery_phase(prDev, info, wrqu, (char *)prP2PReq);
4415             break;
4416
4417         case P2P_CMD_ID_INVITATION:
4418             if (prP2PReq->inBufferLength == sizeof(IW_P2P_IOCTL_INVITATION_STRUCT)) {
4419 //                status = mtk_p2p_wext_invitation_request(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer));
4420             }
4421             break;
4422
4423         case P2P_CMD_ID_INVITATION_ABORT:
4424             if (prP2PReq->inBufferLength == sizeof(IW_P2P_IOCTL_ABORT_INVITATION)) {
4425 //                status = mtk_p2p_wext_invitation_abort(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer));
4426             }
4427             break;
4428
4429         case P2P_CMD_ID_START_FORMATION:
4430             if (prP2PReq->inBufferLength == sizeof(IW_P2P_IOCTL_START_FORMATION)) {
4431                 status = mtk_p2p_wext_start_formation(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer));
4432             }
4433             break;
4434         default:
4435             status = -EOPNOTSUPP;
4436         }
4437
4438         break;
4439 #if CFG_SUPPORT_ANTI_PIRACY
4440     case PRIV_SEC_CHECK_OID:
4441         if (wrqu->data.length > 256) {
4442             status = -EOPNOTSUPP;
4443             break;
4444         }
4445         if (copy_from_user(&(prGlueInfo->prP2PInfo->aucSecCheck[0]),
4446                     wrqu->data.pointer,
4447                     wrqu->data.length)) {
4448             status = -EFAULT;
4449             break;
4450         }
4451
4452         if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucSecCheck[0]), extra, wrqu->data.length)) {
4453             printk(KERN_INFO DRV_NAME"extra buffer is valid\n");
4454         }
4455         else {
4456             printk(KERN_INFO DRV_NAME"extra 0x%p\n", extra);
4457         }
4458         prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucSecCheck[0]));
4459
4460         switch(prP2PReq->u4CmdId) {
4461         case P2P_CMD_ID_SEC_CHECK:
4462             status = mtk_p2p_wext_set_sec_check_request(prDev, info, wrqu, (char *)prP2PReq);
4463             break;
4464         default:
4465             status = -EOPNOTSUPP;
4466         }
4467         break;
4468 #endif
4469     case PRIV_CMD_P2P_VERSION:
4470         if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]),
4471                     wrqu->data.pointer,
4472                     wrqu->data.length)) {
4473             status = -EFAULT;
4474             break;
4475         }
4476
4477         if (!kalMemCmp(&(prGlueInfo->prP2PInfo->aucOidBuf[0]), extra, wrqu->data.length)) {
4478             printk(KERN_INFO DRV_NAME"extra buffer is valid\n");
4479         }
4480         else {
4481             printk(KERN_INFO DRV_NAME"extra 0x%p\n", extra);
4482         }
4483
4484         prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0]));
4485         switch (prP2PReq->u4CmdId) {
4486         case P2P_CMD_ID_P2P_VERSION:
4487             status = mtk_p2p_wext_set_p2p_version(prDev, info, wrqu, (char *)prP2PReq);
4488             break;
4489         default:
4490             status = -EOPNOTSUPP;
4491             break;
4492         }
4493         break;
4494     default:
4495         status = -EOPNOTSUPP;
4496         break;
4497     }
4498
4499     return status;
4500 }
4501
4502
4503 /*----------------------------------------------------------------------------*/
4504 /*!
4505 * \brief P2P Private I/O Control handler (IOC_P2P_GET_STRUCT)
4506 *
4507 * \param[in] prDev      Net device requested.
4508 * \param[inout] wrqu    Pointer to iwreq_data
4509 *
4510 * \retval 0 Success.
4511 * \retval -EFAULT Setting parameters to driver fail.
4512 * \retval -EOPNOTSUPP Key size not supported.
4513 *
4514 * \note
4515 */
4516 /*----------------------------------------------------------------------------*/
4517 int
4518 mtk_p2p_wext_get_struct (
4519     IN struct net_device *prDev,
4520     IN struct iw_request_info *info,
4521     IN OUT union iwreq_data *wrqu,
4522     IN OUT char *extra
4523     )
4524 {
4525     int                         status = 0;
4526     UINT_32                     u4SubCmd = 0;
4527     P_GLUE_INFO_T               prGlueInfo = NULL;
4528     P_IW_P2P_TRANSPORT_STRUCT   prP2PReq = NULL;
4529
4530     ASSERT(prDev);
4531     ASSERT(wrqu);
4532
4533     if (!prDev || !wrqu) {
4534         printk(KERN_INFO DRV_NAME "%s(): invalid param(0x%p, 0x%p)\n",
4535                 __func__,
4536                 prDev,
4537                 wrqu);
4538         return -EINVAL;
4539     }
4540
4541     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
4542     ASSERT(prGlueInfo);
4543
4544     u4SubCmd = (UINT_32) wrqu->data.flags;
4545
4546     kalMemZero(&(prGlueInfo->prP2PInfo->aucOidBuf[0]),
4547         sizeof(prGlueInfo->prP2PInfo->aucOidBuf));
4548
4549     switch (u4SubCmd) {
4550     case PRIV_CMD_OID:
4551         if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]),
4552                     wrqu->data.pointer,
4553                     sizeof(IW_P2P_TRANSPORT_STRUCT))) {
4554             printk(KERN_NOTICE "%s() copy_from_user oidBuf fail\n", __func__);
4555             return -EFAULT;
4556         }
4557
4558         prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0]));
4559
4560         switch(prP2PReq->u4CmdId) {
4561         case P2P_CMD_ID_GET_SD_REQUEST:
4562             status = mtk_p2p_wext_get_service_discovery_request(prDev, info, wrqu, (char *)prP2PReq);
4563             break;
4564
4565         case P2P_CMD_ID_GET_SD_RESPONSE:
4566             status = mtk_p2p_wext_get_service_discovery_response(prDev, info, wrqu, (char *)prP2PReq);
4567             break;
4568
4569         case P2P_CMD_ID_INVITATION_INDICATE:
4570         {
4571             status = mtk_p2p_wext_invitation_indicate(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer));
4572             prP2PReq->outBufferLength = wrqu->data.length;
4573             if (copy_to_user(wrqu->data.pointer,
4574                                     &(prGlueInfo->prP2PInfo->aucOidBuf[0]),
4575                                     wrqu->data.length + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) {
4576                 printk(KERN_NOTICE "%s() copy_to_user() fail\n", __func__);
4577                 return -EIO;
4578             }
4579             else {
4580                 return 0;
4581             }
4582             break;
4583         }
4584         case P2P_CMD_ID_INVITATION_STATUS:
4585         {
4586             status = mtk_p2p_wext_invitation_status(prDev, info, wrqu, (char *)(prP2PReq->aucBuffer));
4587             prP2PReq->outBufferLength = wrqu->data.length;
4588             if (copy_to_user(wrqu->data.pointer,
4589                                 &(prGlueInfo->prP2PInfo->aucOidBuf[0]),
4590                                 wrqu->data.length + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) {
4591                 printk(KERN_NOTICE "%s() copy_to_user() fail\n", __func__);
4592                 return -EIO;
4593             }
4594             else {
4595                 return 0;
4596             }
4597             break;
4598         }
4599         case P2P_CMD_ID_GET_CH_LIST:
4600         {
4601             UINT_16 i;
4602             UINT_8 NumOfChannel = 50;
4603             RF_CHANNEL_INFO_T aucChannelList[50];
4604             UINT_8 ucMaxChannelNum = 50;
4605             PUINT_8 pucChnlList = (PUINT_8)prP2PReq->aucBuffer;
4606
4607             kalGetChnlList(prGlueInfo, BAND_NULL, ucMaxChannelNum, &NumOfChannel, aucChannelList);
4608             if (NumOfChannel > 50)
4609                 NumOfChannel = 50;
4610             prP2PReq->outBufferLength = NumOfChannel;
4611
4612             for (i=0; i<NumOfChannel; i++) {
4613 #if 0
4614                 // 20120208 frog: modify to avoid clockwork warning.
4615                 prP2PReq->aucBuffer[i] = aucChannelList[i].ucChannelNum;
4616 #else
4617                 *pucChnlList = aucChannelList[i].ucChannelNum;
4618                 pucChnlList++;
4619 #endif
4620             }
4621             if(copy_to_user(wrqu->data.pointer,
4622                         &(prGlueInfo->prP2PInfo->aucOidBuf[0]),
4623                         NumOfChannel + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) {
4624                 printk(KERN_NOTICE "%s() copy_to_user() fail\n", __func__);
4625                 return -EIO;
4626             }
4627             else {
4628                 return 0;
4629             }
4630             break;
4631         }
4632
4633         case P2P_CMD_ID_GET_OP_CH:
4634         {
4635             prP2PReq->inBufferLength = 4;
4636
4637             status = wlanoidQueryP2pOpChannel(prGlueInfo->prAdapter,
4638                                         prP2PReq->aucBuffer,
4639                                         prP2PReq->inBufferLength,
4640                                         &prP2PReq->outBufferLength);
4641
4642             if (status == 0) { // WLAN_STATUS_SUCCESS
4643                 if (copy_to_user(wrqu->data.pointer,
4644                         &(prGlueInfo->prP2PInfo->aucOidBuf[0]),
4645                         prP2PReq->outBufferLength + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) {
4646                     printk(KERN_NOTICE "%s() copy_to_user() fail\n", __func__);
4647                     return -EIO;
4648                 }
4649             }
4650             else {
4651                 if (copy_to_user(wrqu->data.pointer,
4652                         &(prGlueInfo->prP2PInfo->aucOidBuf[0]),
4653                         OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) {
4654                     printk(KERN_NOTICE "%s() copy_to_user() fail\n", __func__);
4655                     return -EIO;
4656                 }
4657             }
4658             break;
4659         }
4660
4661         default:
4662             status = -EOPNOTSUPP;
4663         }
4664
4665         break;
4666 #if CFG_SUPPORT_ANTI_PIRACY
4667     case PRIV_SEC_CHECK_OID:
4668         if (wrqu->data.length > 256) {
4669             status = -EOPNOTSUPP;
4670             break;
4671         }
4672         if (copy_from_user(&(prGlueInfo->prP2PInfo->aucSecCheck[0]),
4673                     wrqu->data.pointer,
4674                     sizeof(IW_P2P_TRANSPORT_STRUCT))) {
4675             printk(KERN_NOTICE "%s() copy_from_user oidBuf fail\n", __func__);
4676             return -EFAULT;
4677         }
4678
4679         prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucSecCheck[0]));
4680
4681         switch(prP2PReq->u4CmdId) {
4682             case P2P_CMD_ID_SEC_CHECK:
4683                 status = mtk_p2p_wext_get_sec_check_response(prDev, info, wrqu, (char *)prP2PReq);
4684                 break;
4685             default:
4686                 status = -EOPNOTSUPP;
4687         }
4688         break;
4689 #endif
4690     case PRIV_CMD_P2P_VERSION:
4691         if (copy_from_user(&(prGlueInfo->prP2PInfo->aucOidBuf[0]),
4692                     wrqu->data.pointer,
4693                     sizeof(IW_P2P_TRANSPORT_STRUCT))) {
4694             printk(KERN_NOTICE "%s() copy_from_user oidBuf fail\n", __func__);
4695             return -EFAULT;
4696         }
4697
4698         prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT) (&(prGlueInfo->prP2PInfo->aucOidBuf[0]));
4699
4700         switch (prP2PReq->u4CmdId) {
4701         case P2P_CMD_ID_P2P_VERSION:
4702             status = mtk_p2p_wext_get_p2p_version(prDev, info, wrqu, (char *)prP2PReq);
4703             break;
4704         default:
4705             status = -EOPNOTSUPP;
4706             break;
4707         }
4708
4709
4710         /* Copy queried data to user. */
4711         if (status == 0) {  // WLAN_STATUS_SUCCESS
4712             if(copy_to_user(wrqu->data.pointer,
4713                         &(prGlueInfo->prP2PInfo->aucOidBuf[0]),
4714                         prP2PReq->outBufferLength + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) {
4715                 printk(KERN_NOTICE "%s() copy_to_user() fail\n", __func__);
4716                 return -EIO;
4717             }
4718         }
4719
4720         else {
4721             if(copy_to_user(wrqu->data.pointer,
4722                         &(prGlueInfo->prP2PInfo->aucOidBuf[0]),
4723                         OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) {
4724                 printk(KERN_NOTICE "%s() copy_to_user() fail\n", __func__);
4725                 return -EIO;
4726             }
4727         }
4728
4729         break;
4730     default:
4731         return -EOPNOTSUPP;
4732     }
4733
4734     return status;
4735 }
4736
4737
4738 /*----------------------------------------------------------------------------*/
4739 /*!
4740 * \brief P2P Private I/O Control handler for
4741 *        getting service discovery request frame from driver
4742 *
4743 * \param[in] prDev      Net device requested.
4744 * \param[inout] wrqu    Pointer to iwreq_data
4745 *
4746 * \retval 0 Success.
4747 * \retval -EFAULT Setting parameters to driver fail.
4748 * \retval -EOPNOTSUPP Key size not supported.
4749 *
4750 * \note
4751 */
4752 /*----------------------------------------------------------------------------*/
4753 int
4754 mtk_p2p_wext_get_service_discovery_request (
4755     IN struct net_device *prDev,
4756     IN struct iw_request_info *info,
4757     IN OUT union iwreq_data *wrqu,
4758     IN OUT char *extra
4759     )
4760 {
4761     WLAN_STATUS                 rStatus = WLAN_STATUS_SUCCESS;
4762     UINT_32                     u4QueryInfoLen;
4763     P_IW_P2P_TRANSPORT_STRUCT   prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT)extra;
4764     P_GLUE_INFO_T               prGlueInfo = NULL;
4765
4766     ASSERT(prDev);
4767
4768     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
4769     ASSERT(prGlueInfo);
4770
4771     rStatus = kalIoctl(prGlueInfo,
4772             wlanoidGetP2PSDRequest,
4773             prP2PReq->aucBuffer,
4774             prP2PReq->outBufferLength,
4775             TRUE,
4776             FALSE,
4777             TRUE,
4778             TRUE,
4779             &u4QueryInfoLen);
4780
4781     if (rStatus != WLAN_STATUS_SUCCESS) {
4782         return -EFAULT;
4783     }
4784     else {
4785         prP2PReq->outBufferLength = u4QueryInfoLen;
4786
4787         if(copy_to_user(wrqu->data.pointer,
4788                     &(prGlueInfo->prP2PInfo->aucOidBuf[0]),
4789                     u4QueryInfoLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) {
4790             printk(KERN_NOTICE "%s() copy_to_user() fail\n", __func__);
4791             return -EIO;
4792         }
4793         else {
4794             return 0;
4795         }
4796     }
4797 }
4798
4799
4800 /*----------------------------------------------------------------------------*/
4801 /*!
4802 * \brief P2P Private I/O Control handler for
4803 *        getting service discovery response frame from driver
4804 *
4805 * \param[in] prDev      Net device requested.
4806 * \param[inout] wrqu    Pointer to iwreq_data
4807 *
4808 * \retval 0 Success.
4809 * \retval -EFAULT Setting parameters to driver fail.
4810 * \retval -EOPNOTSUPP Key size not supported.
4811 *
4812 * \note
4813 */
4814 /*----------------------------------------------------------------------------*/
4815 int
4816 mtk_p2p_wext_get_service_discovery_response (
4817     IN struct net_device *prDev,
4818     IN struct iw_request_info *info,
4819     IN OUT union iwreq_data *wrqu,
4820     IN OUT char *extra
4821     )
4822 {
4823     WLAN_STATUS                 rStatus = WLAN_STATUS_SUCCESS;
4824     UINT_32                     u4QueryInfoLen;
4825     P_IW_P2P_TRANSPORT_STRUCT   prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT)extra;
4826     P_GLUE_INFO_T               prGlueInfo = NULL;
4827
4828     ASSERT(prDev);
4829
4830     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
4831     ASSERT(prGlueInfo);
4832
4833     rStatus = kalIoctl(prGlueInfo,
4834             wlanoidGetP2PSDResponse,
4835             prP2PReq->aucBuffer,
4836             prP2PReq->outBufferLength,
4837             TRUE,
4838             FALSE,
4839             TRUE,
4840             TRUE,
4841             &u4QueryInfoLen);
4842
4843     if (rStatus != WLAN_STATUS_SUCCESS) {
4844         return -EFAULT;
4845     }
4846     else {
4847         prP2PReq->outBufferLength = u4QueryInfoLen;
4848
4849         if(copy_to_user(wrqu->data.pointer,
4850                     &(prGlueInfo->prP2PInfo->aucOidBuf[0]),
4851                     u4QueryInfoLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) {
4852             printk(KERN_NOTICE "%s() copy_to_user() fail\n", __func__);
4853             return -EIO;
4854         }
4855         else {
4856             return 0;
4857         }
4858     }
4859 }
4860
4861
4862 /*----------------------------------------------------------------------------*/
4863 /*!
4864 * \brief P2P Private I/O Control handler for
4865 *        sending service discovery request frame
4866 *
4867 * \param[in] prDev      Net device requested.
4868 * \param[inout] wrqu    Pointer to iwreq_data
4869 *
4870 * \retval 0 Success.
4871 * \retval -EFAULT Setting parameters to driver fail.
4872 * \retval -EOPNOTSUPP Key size not supported.
4873 *
4874 * \note
4875 */
4876 /*----------------------------------------------------------------------------*/
4877 int
4878 mtk_p2p_wext_send_service_discovery_request (
4879     IN struct net_device *prDev,
4880     IN struct iw_request_info *info,
4881     IN OUT union iwreq_data *wrqu,
4882     IN OUT char *extra
4883     )
4884 {
4885     WLAN_STATUS                 rStatus = WLAN_STATUS_SUCCESS;
4886     UINT_32                     u4SetInfoLen;
4887     P_IW_P2P_TRANSPORT_STRUCT   prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT)extra;
4888     P_GLUE_INFO_T               prGlueInfo = NULL;
4889
4890     ASSERT(prDev);
4891
4892     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
4893     ASSERT(prGlueInfo);
4894
4895     rStatus = kalIoctl(prGlueInfo,
4896             wlanoidSendP2PSDRequest,
4897             prP2PReq->aucBuffer,
4898             prP2PReq->inBufferLength,
4899             FALSE,
4900             FALSE,
4901             TRUE,
4902             TRUE,
4903             &u4SetInfoLen);
4904
4905     if (rStatus != WLAN_STATUS_SUCCESS) {
4906         return -EFAULT;
4907     }
4908     else {
4909         return 0;
4910     }
4911 }
4912
4913
4914 /*----------------------------------------------------------------------------*/
4915 /*!
4916 * \brief P2P Private I/O Control handler for
4917 *        sending service discovery response frame
4918 *
4919 * \param[in] prDev      Net device requested.
4920 * \param[inout] wrqu    Pointer to iwreq_data
4921 *
4922 * \retval 0 Success.
4923 * \retval -EFAULT Setting parameters to driver fail.
4924 * \retval -EOPNOTSUPP Key size not supported.
4925 *
4926 * \note
4927 */
4928 /*----------------------------------------------------------------------------*/
4929 int
4930 mtk_p2p_wext_send_service_discovery_response (
4931     IN struct net_device *prDev,
4932     IN struct iw_request_info *info,
4933     IN OUT union iwreq_data *wrqu,
4934     IN OUT char *extra
4935     )
4936 {
4937     WLAN_STATUS                 rStatus = WLAN_STATUS_SUCCESS;
4938     UINT_32                     u4SetInfoLen;
4939     P_IW_P2P_TRANSPORT_STRUCT   prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT)extra;
4940     P_GLUE_INFO_T               prGlueInfo = NULL;
4941
4942     ASSERT(prDev);
4943
4944     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
4945     ASSERT(prGlueInfo);
4946
4947     rStatus = kalIoctl(prGlueInfo,
4948             wlanoidSendP2PSDResponse,
4949             prP2PReq->aucBuffer,
4950             prP2PReq->inBufferLength,
4951             FALSE,
4952             FALSE,
4953             TRUE,
4954             TRUE,
4955             &u4SetInfoLen);
4956
4957     if (rStatus != WLAN_STATUS_SUCCESS) {
4958         return -EFAULT;
4959     }
4960     else {
4961         return 0;
4962     }
4963 }
4964
4965 #if CFG_SUPPORT_ANTI_PIRACY
4966 /*----------------------------------------------------------------------------*/
4967 /*!
4968 * \brief P2P Private I/O Control handler for
4969 *
4970 * \param[in] prDev      Net device requested.
4971 * \param[inout] wrqu    Pointer to iwreq_data
4972 *
4973 * \retval 0 Success.
4974 * \retval -EFAULT Setting parameters to driver fail.
4975 * \retval -EOPNOTSUPP Key size not supported.
4976 *
4977 * \note
4978 */
4979 /*----------------------------------------------------------------------------*/
4980 int
4981 mtk_p2p_wext_set_sec_check_request (
4982     IN struct net_device *prDev,
4983     IN struct iw_request_info *info,
4984     IN OUT union iwreq_data *wrqu,
4985     IN OUT char *extra
4986     )
4987 {
4988     WLAN_STATUS                 rStatus = WLAN_STATUS_SUCCESS;
4989     UINT_32                     u4SetInfoLen;
4990     P_IW_P2P_TRANSPORT_STRUCT   prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT)extra;
4991     P_GLUE_INFO_T               prGlueInfo = NULL;
4992
4993     ASSERT(prDev);
4994
4995     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
4996     ASSERT(prGlueInfo);
4997
4998     rStatus = kalIoctl(prGlueInfo,
4999             wlanoidSetSecCheckRequest,
5000             prP2PReq->aucBuffer,
5001             prP2PReq->inBufferLength,
5002             FALSE,
5003             FALSE,
5004             TRUE,
5005             TRUE,
5006             &u4SetInfoLen);
5007
5008     if (rStatus != WLAN_STATUS_SUCCESS) {
5009         return -EFAULT;
5010     }
5011     else {
5012         return 0;
5013     }
5014 }
5015
5016
5017 /*----------------------------------------------------------------------------*/
5018 /*!
5019 * \brief P2P Private I/O Control handler for
5020 *
5021 * \param[in] prDev      Net device requested.
5022 * \param[inout] wrqu    Pointer to iwreq_data
5023 *
5024 * \retval 0 Success.
5025 * \retval -EFAULT Setting parameters to driver fail.
5026 * \retval -EOPNOTSUPP Key size not supported.
5027 *
5028 * \note
5029 */
5030 /*----------------------------------------------------------------------------*/
5031 int
5032 mtk_p2p_wext_get_sec_check_response (
5033     IN struct net_device *prDev,
5034     IN struct iw_request_info *info,
5035     IN OUT union iwreq_data *wrqu,
5036     IN OUT char *extra
5037     )
5038 {
5039     WLAN_STATUS                 rStatus = WLAN_STATUS_SUCCESS;
5040     UINT_32                     u4QueryInfoLen;
5041     P_IW_P2P_TRANSPORT_STRUCT   prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT)extra;
5042     P_GLUE_INFO_T               prGlueInfo = NULL;
5043
5044     ASSERT(prDev);
5045
5046     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
5047     ASSERT(prGlueInfo);
5048
5049     rStatus = kalIoctl(prGlueInfo,
5050             wlanoidGetSecCheckResponse,
5051             prP2PReq->aucBuffer,
5052             prP2PReq->outBufferLength,
5053             TRUE,
5054             FALSE,
5055             TRUE,
5056             TRUE,
5057             &u4QueryInfoLen);
5058
5059     if (rStatus != WLAN_STATUS_SUCCESS) {
5060         return -EFAULT;
5061     }
5062     else {
5063         prP2PReq->outBufferLength = u4QueryInfoLen;
5064
5065         if(copy_to_user(wrqu->data.pointer,
5066                     prP2PReq->aucBuffer,
5067                     u4QueryInfoLen + OFFSET_OF(IW_P2P_TRANSPORT_STRUCT, aucBuffer))) {
5068             printk(KERN_NOTICE "%s() copy_to_user() fail\n", __func__);
5069             return -EIO;
5070         }
5071         else {
5072             return 0;
5073         }
5074     }
5075 }
5076 #endif
5077
5078 /*----------------------------------------------------------------------------*/
5079 /*!
5080 * \brief P2P Private I/O Control handler for
5081 *        terminating service discovery phase
5082 *
5083 * \param[in] prDev      Net device requested.
5084 * \param[inout] wrqu    Pointer to iwreq_data
5085 *
5086 * \retval 0 Success.
5087 * \retval -EFAULT Setting parameters to driver fail.
5088 * \retval -EOPNOTSUPP Key size not supported.
5089 *
5090 * \note
5091 */
5092 /*----------------------------------------------------------------------------*/
5093 int
5094 mtk_p2p_wext_terminate_service_discovery_phase (
5095     IN struct net_device *prDev,
5096     IN struct iw_request_info *info,
5097     IN OUT union iwreq_data *wrqu,
5098     IN OUT char *extra
5099     )
5100 {
5101     WLAN_STATUS                 rStatus = WLAN_STATUS_SUCCESS;
5102     UINT_32                     u4SetInfoLen;
5103     P_IW_P2P_TRANSPORT_STRUCT   prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT)extra;
5104     P_GLUE_INFO_T               prGlueInfo = NULL;
5105
5106     ASSERT(prDev);
5107
5108     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
5109     ASSERT(prGlueInfo);
5110
5111     rStatus = kalIoctl(prGlueInfo,
5112             wlanoidSetP2PTerminateSDPhase,
5113             prP2PReq->aucBuffer,
5114             prP2PReq->inBufferLength,
5115             FALSE,
5116             FALSE,
5117             TRUE,
5118             TRUE,
5119             &u4SetInfoLen);
5120
5121     if (rStatus != WLAN_STATUS_SUCCESS) {
5122         return -EFAULT;
5123     }
5124     else {
5125         return 0;
5126     }
5127 }
5128
5129 /*----------------------------------------------------------------------------*/
5130 /*!
5131 * \brief P2P Private I/O Control handler for
5132 *
5133 * \param[in] prDev      Net device requested.
5134 * \param[inout] wrqu    Pointer to iwreq_data
5135 *
5136 * \retval 0 Success.
5137 * \retval -EFAULT Setting parameters to driver fail.
5138 * \retval -EOPNOTSUPP Key size not supported.
5139 *
5140 * \note
5141 */
5142 /*----------------------------------------------------------------------------*/
5143 int
5144 mtk_p2p_wext_set_noa_param (
5145     IN struct net_device *prDev,
5146     IN struct iw_request_info *info,
5147     IN OUT union iwreq_data *wrqu,
5148     IN OUT char *extra
5149     )
5150 {
5151     WLAN_STATUS                 rStatus = WLAN_STATUS_SUCCESS;
5152     UINT_32                     u4SetInfoLen;
5153     //P_IW_P2P_TRANSPORT_STRUCT   prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT)extra;
5154     P_PARAM_CUSTOM_NOA_PARAM_STRUC_T prNoaParam = (P_PARAM_CUSTOM_NOA_PARAM_STRUC_T)extra;
5155     P_GLUE_INFO_T               prGlueInfo = NULL;
5156
5157     ASSERT(prDev);
5158
5159     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
5160     ASSERT(prGlueInfo);
5161
5162
5163     rStatus = kalIoctl(prGlueInfo,
5164             wlanoidSetNoaParam,
5165             prNoaParam, //prP2PReq->aucBuffer,
5166             sizeof(PARAM_CUSTOM_NOA_PARAM_STRUC_T),//prP2PReq->inBufferLength,
5167             FALSE,
5168             FALSE,
5169             TRUE,
5170             TRUE,
5171             &u4SetInfoLen);
5172
5173     if (rStatus != WLAN_STATUS_SUCCESS) {
5174         return -EFAULT;
5175     }
5176     else {
5177         return 0;
5178     }
5179 }
5180
5181 /*----------------------------------------------------------------------------*/
5182 /*!
5183 * \brief P2P Private I/O Control handler for
5184 *
5185 * \param[in] prDev      Net device requested.
5186 * \param[inout] wrqu    Pointer to iwreq_data
5187 *
5188 * \retval 0 Success.
5189 * \retval -EFAULT Setting parameters to driver fail.
5190 * \retval -EOPNOTSUPP Key size not supported.
5191 *
5192 * \note
5193 */
5194 /*----------------------------------------------------------------------------*/
5195 int
5196 mtk_p2p_wext_set_oppps_param (
5197     IN struct net_device *prDev,
5198     IN struct iw_request_info *info,
5199     IN OUT union iwreq_data *wrqu,
5200     IN OUT char *extra
5201     )
5202 {
5203     WLAN_STATUS                 rStatus = WLAN_STATUS_SUCCESS;
5204     UINT_32                     u4SetInfoLen;
5205 //    P_IW_P2P_TRANSPORT_STRUCT   prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT)extra;
5206     P_PARAM_CUSTOM_OPPPS_PARAM_STRUC_T prOppPsParam = (P_PARAM_CUSTOM_OPPPS_PARAM_STRUC_T)extra;
5207     P_GLUE_INFO_T               prGlueInfo = NULL;
5208
5209     ASSERT(prDev);
5210
5211     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
5212     ASSERT(prGlueInfo);
5213
5214
5215    rStatus = kalIoctl(prGlueInfo,
5216             wlanoidSetOppPsParam,
5217             prOppPsParam, //prP2PReq->aucBuffer,
5218             sizeof(PARAM_CUSTOM_OPPPS_PARAM_STRUC_T), //prP2PReq->inBufferLength,
5219             FALSE,
5220             FALSE,
5221             TRUE,
5222             TRUE,
5223             &u4SetInfoLen);
5224
5225     if (rStatus != WLAN_STATUS_SUCCESS) {
5226         return -EFAULT;
5227     }
5228     else {
5229         return 0;
5230     }
5231 }
5232
5233
5234 int
5235 mtk_p2p_wext_set_p2p_version (
5236     IN struct net_device *prDev,
5237     IN struct iw_request_info *info,
5238     IN OUT union iwreq_data *wrqu,
5239     IN OUT char *extra
5240     )
5241 {
5242     WLAN_STATUS    rStatus = WLAN_STATUS_SUCCESS;
5243     P_GLUE_INFO_T   prGlueInfo = NULL;
5244     P_IW_P2P_TRANSPORT_STRUCT   prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT)extra;
5245     UINT_32                     u4SetInfoLen;
5246
5247     ASSERT(prDev);
5248
5249     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
5250     ASSERT(prGlueInfo);
5251
5252     rStatus = kalIoctl(prGlueInfo,
5253                         wlanoidSetP2pSupplicantVersion,
5254                         prP2PReq->aucBuffer,
5255                         prP2PReq->inBufferLength,
5256                         FALSE,
5257                         FALSE,
5258                         TRUE,
5259                         TRUE,
5260                         &u4SetInfoLen);
5261
5262     if (rStatus != WLAN_STATUS_SUCCESS) {
5263         return -EFAULT;
5264     }
5265     else {
5266         return rStatus;
5267     }
5268
5269
5270 }
5271 /* mtk_p2p_wext_set_p2p_version */
5272
5273 int
5274 mtk_p2p_wext_get_p2p_version (
5275     IN struct net_device *prDev,
5276     IN struct iw_request_info *info,
5277     IN OUT union iwreq_data *wrqu,
5278     IN OUT char *extra
5279     )
5280 {
5281     WLAN_STATUS                 rStatus = WLAN_STATUS_SUCCESS;
5282     UINT_32                     u4QueryInfoLen;
5283     P_IW_P2P_TRANSPORT_STRUCT   prP2PReq = (P_IW_P2P_TRANSPORT_STRUCT)extra;
5284     P_GLUE_INFO_T               prGlueInfo = NULL;
5285
5286     ASSERT(prDev);
5287
5288     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
5289     ASSERT(prGlueInfo);
5290
5291     rStatus = kalIoctl(prGlueInfo,
5292                 wlanoidQueryP2pVersion,
5293                 prP2PReq->aucBuffer,
5294                 prP2PReq->outBufferLength,
5295                 TRUE,
5296                 FALSE,
5297                 TRUE,
5298                 TRUE,
5299                 &u4QueryInfoLen);
5300
5301     if (rStatus != WLAN_STATUS_SUCCESS) {
5302         return -EFAULT;
5303     }
5304     else {
5305         return rStatus;
5306     }
5307
5308
5309 } /* mtk_p2p_wext_get_p2p_version */
5310
5311 #if CFG_SUPPORT_P2P_RSSI_QUERY
5312
5313 int
5314 mtk_p2p_wext_get_rssi (
5315     IN struct net_device *prDev,
5316     IN struct iw_request_info *info,
5317     IN OUT union iwreq_data *wrqu,
5318     IN OUT char *extra
5319     )
5320 {
5321     WLAN_STATUS                 rStatus = WLAN_STATUS_SUCCESS;
5322     UINT_32                     u4QueryInfoLen;
5323     struct iw_point *prData= (struct iw_point *)&wrqu->data;
5324     UINT_16 u2BufferSize = 0;
5325     P_GLUE_INFO_T               prGlueInfo = NULL;
5326     INT_32 i4Rssi;
5327     struct iw_statistics *pStats = NULL;
5328
5329     ASSERT(prDev);
5330
5331     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
5332     ASSERT(prGlueInfo);
5333
5334     if (!prGlueInfo) {
5335         rStatus = WLAN_STATUS_FAILURE;
5336         goto stat_out;
5337     }
5338
5339     pStats = (struct iw_statistics *) (&(prGlueInfo->rP2pIwStats));
5340
5341     rStatus = kalIoctl(prGlueInfo,
5342                 wlanoidQueryP2pRssi,
5343                 &i4Rssi,
5344                 sizeof(i4Rssi),
5345                 TRUE,
5346                 TRUE,
5347                 TRUE,
5348                 TRUE,
5349                 &u4QueryInfoLen);
5350
5351     u2BufferSize = prData->length;
5352
5353     if (u2BufferSize < sizeof(struct iw_statistics)) {
5354         return -E2BIG;
5355     }
5356
5357
5358     if (copy_to_user(prData->pointer, pStats, sizeof(struct iw_statistics))) {
5359         rStatus = WLAN_STATUS_FAILURE;
5360     }
5361
5362
5363 stat_out:
5364
5365     if (rStatus != WLAN_STATUS_SUCCESS) {
5366         return -EFAULT;
5367     }
5368     else {
5369         return rStatus;
5370     }
5371
5372 } /* mtk_p2p_wext_get_rssi */
5373
5374 struct iw_statistics *
5375 mtk_p2p_wext_get_wireless_stats (
5376     struct net_device *prDev
5377     )
5378 {
5379     WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
5380     P_GLUE_INFO_T prGlueInfo = NULL;
5381     struct iw_statistics *pStats = NULL;
5382     INT_32 i4Rssi;
5383     UINT_32 bufLen = 0;
5384
5385     prGlueInfo = *((P_GLUE_INFO_T *)netdev_priv(prDev));
5386      ASSERT(prGlueInfo);
5387     if (!prGlueInfo) {
5388         goto stat_out;
5389     }
5390
5391     pStats = (struct iw_statistics *) (&(prGlueInfo->rP2pIwStats));
5392
5393     if (!prDev || !netif_carrier_ok(prDev)) {
5394         /* network not connected */
5395         goto stat_out;
5396     }
5397
5398     rStatus = kalIoctl(prGlueInfo,
5399         wlanoidQueryP2pRssi,
5400         &i4Rssi,
5401         sizeof(i4Rssi),
5402         TRUE,
5403         TRUE,
5404         TRUE,
5405         TRUE,
5406         &bufLen);
5407
5408 stat_out:
5409     return pStats;
5410 } /* mtk_p2p_wext_get_wireless_stats */
5411
5412
5413 #endif /* CFG_SUPPORT_P2P_RSSI_QUERY */
5414
5415
5416 int
5417 mtk_p2p_wext_set_txpow (
5418     IN struct net_device *prDev,
5419     IN struct iw_request_info *prIwrInfo,
5420     IN OUT union iwreq_data *prTxPow,
5421     IN char *pcExtra
5422     )
5423 {
5424     P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T)NULL;
5425     P_ADAPTER_T prAdapter = (P_ADAPTER_T)NULL;
5426 #if 0
5427     P_MSG_P2P_FUNCTION_SWITCH_T prMsgFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T)NULL;
5428 #endif
5429     int i4Ret = 0;
5430
5431     ASSERT(prDev);
5432     ASSERT(prTxPow);
5433
5434     do {
5435         if ((!prDev) || (!prTxPow)) {
5436             i4Ret = -EINVAL;
5437             break;
5438         }
5439
5440
5441         prGlueInfo = *((P_GLUE_INFO_T *)netdev_priv(prDev));
5442
5443         if (!prGlueInfo) {
5444             i4Ret = -EINVAL;
5445             break;
5446         }
5447
5448
5449         prAdapter = prGlueInfo->prAdapter;
5450 #if 0
5451         prMsgFuncSwitch = (P_MSG_P2P_FUNCTION_SWITCH_T)cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_P2P_FUNCTION_SWITCH_T));
5452         if (!prMsgFuncSwitch) {
5453             ASSERT(0);
5454             return -ENOMEM;
5455         }
5456
5457         prMsgFuncSwitch->rMsgHdr.eMsgId = MID_MNY_P2P_FUN_SWITCH;
5458
5459         if (prTxPow->disabled) {
5460             /* Dissolve. */
5461             prMsgFuncSwitch->fgIsFuncOn = FALSE;
5462         }
5463         else {
5464
5465             /* Re-enable function. */
5466             prMsgFuncSwitch->fgIsFuncOn = TRUE;
5467         }
5468
5469         /* 1.3 send message */
5470         mboxSendMsg(prAdapter,
5471             MBOX_ID_0,
5472             (P_MSG_HDR_T) prMsgFuncSwitch,
5473             MSG_SEND_METHOD_BUF);
5474 #endif
5475
5476     } while (FALSE);
5477
5478     return i4Ret;
5479 } /* mtk_p2p_wext_set_txpow */
5480
5481