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