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