add rk3288 pinctrl dts code
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / mt5931_kk / drv_wlan / os / linux / gl_init.c
1 /*
2 ** $Id: //Department/DaVinci/BRANCHES/MT662X_593X_WIFI_DRIVER_V2_3/os/linux/gl_init.c#3 $
3 */
4
5 /*! \file   gl_init.c
6     \brief  Main routines of Linux driver
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_init.c $
56 **
57 ** 11 14 2012 cp.wu
58 ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
59 ** enable checksum offloading configuration as default
60 ** 
61 ** 09 04 2012 cp.wu
62 ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
63 ** sync for NVRAM warning scan result generation for CFG80211.
64 **
65 ** 08 24 2012 cp.wu
66 ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
67 ** .
68 **
69 ** 08 24 2012 cp.wu
70 ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
71 ** cfg80211 support merge back from ALPS.JB to DaVinci - MT6620 Driver v2.3 branch.
72  *
73  * 07 17 2012 yuche.tsai
74  * NULL
75  * Fix compile error.
76  *
77  * 07 17 2012 yuche.tsai
78  * NULL
79  * Fix compile error for JB.
80  *
81  * 07 17 2012 yuche.tsai
82  * NULL
83  * Let netdev bring up.
84  *
85  * 07 17 2012 yuche.tsai
86  * NULL
87  * Compile no error before trial run.
88  *
89  * 06 13 2012 yuche.tsai
90  * NULL
91  * Update maintrunk driver.
92  * Add support for driver compose assoc request frame.
93  *
94  * 05 25 2012 yuche.tsai
95  * NULL
96  * Fix reset KE issue.
97  *
98  * 05 11 2012 cp.wu
99  * [WCXRP00001237] [MT6620 Wi-Fi][Driver] Show MAC address and MAC address source for ACS's convenience
100  * show MAC address & source while initiliazation
101  *
102  * 03 02 2012 terry.wu
103  * NULL
104  * EXPORT_SYMBOL(rsnParseCheckForWFAInfoElem);.
105  *
106  * 03 02 2012 terry.wu
107  * NULL
108  * Snc CFG80211 modification for ICS migration from branch 2.2.
109  *
110  * 03 02 2012 terry.wu
111  * NULL
112  * Sync CFG80211 modification from branch 2,2.
113  *
114  * 03 02 2012 terry.wu
115  * NULL
116  * Enable CFG80211 Support.
117  *
118  * 12 22 2011 george.huang
119  * [WCXRP00000905] [MT6628 Wi-Fi][FW] Code refinement for ROM/ RAM module dependency
120  * using global variable instead of stack for setting wlanoidSetNetworkAddress(), due to buffer may be released before TX thread handling
121  *
122  * 11 18 2011 yuche.tsai
123  * NULL
124  * CONFIG P2P support RSSI query, default turned off.
125  *
126  * 11 14 2011 yuche.tsai
127  * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue.
128  * Fix large network type index assert in FW issue.
129  *
130  * 11 14 2011 cm.chang
131  * NULL
132  * Fix compiling warning
133  *
134  * 11 11 2011 yuche.tsai
135  * NULL
136  * Fix work thread cancel issue.
137  *
138  * 11 10 2011 cp.wu
139  * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
140  * 1. eliminaite direct calls to printk in porting layer.
141  * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
142  *
143  * 10 06 2011 eddie.chen
144  * [WCXRP00001027] [MT6628 Wi-Fi][Firmware/Driver] Tx fragmentation
145  * Add rlmDomainGetChnlList symbol.
146  *
147  * 09 22 2011 cm.chang
148  * NULL
149  * Safer writng stype to avoid unitialized regitry structure
150  *
151  * 09 21 2011 cm.chang
152  * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
153  * Avoid possible structure alignment problem
154  *
155  * 09 20 2011 chinglan.wang
156  * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test.
157  * .
158  *
159  * 09 08 2011 cm.chang
160  * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
161  * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM
162  *
163  * 08 31 2011 cm.chang
164  * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
165  * .
166  *
167  * 08 11 2011 cp.wu
168  * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time
169  * expose scnQuerySparseChannel() for P2P-FSM.
170  *
171  * 08 11 2011 cp.wu
172  * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time
173  * sparse channel detection:
174  * driver: collect sparse channel information with scan-done event
175  *
176  * 08 02 2011 yuche.tsai
177  * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a disconnecting device issue.
178  * Fix GO send deauth frame issue.
179  *
180  * 07 07 2011 wh.su
181  * [WCXRP00000839] [MT6620 Wi-Fi][Driver] Add the dumpMemory8 and dumpMemory32 EXPORT_SYMBOL
182  * Add the dumpMemory8 symbol export for debug mode.
183  *
184  * 07 06 2011 terry.wu
185  * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment
186  * Improve BoW connection establishment speed.
187  *
188  * 07 05 2011 yuche.tsai
189  * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue
190  * Export one symbol for enhancement.
191  *
192  * 06 13 2011 eddie.chen
193  * [WCXRP00000779] [MT6620 Wi-Fi][DRV]  Add tx rx statistics in linux and use netif_rx_ni
194  * Add tx rx statistics and netif_rx_ni.
195  *
196  * 05 27 2011 cp.wu
197  * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM
198  * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content.
199  *
200  * 05 18 2011 cp.wu
201  * [WCXRP00000734] [MT6620 Wi-Fi][Driver] Pass PHY_PARAM in NVRAM to firmware domain
202  * pass PHY_PARAM in NVRAM from driver to firmware.
203  *
204  * 05 09 2011 jeffrey.chang
205  * [WCXRP00000710] [MT6620 Wi-Fi] Support pattern filter update function on IP address change
206  * support ARP filter through kernel notifier
207  *
208  * 05 03 2011 chinghwa.yu
209  * [WCXRP00000065] Update BoW design and settings
210  * Use kalMemAlloc to allocate event buffer for kalIndicateBOWEvent.
211  *
212  * 04 27 2011 george.huang
213  * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter
214  * Support P2P ARP filter setting on early suspend/ late resume
215  *
216  * 04 18 2011 terry.wu
217  * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
218  * Remove flag CFG_WIFI_DIRECT_MOVED.
219  *
220  * 04 15 2011 chinghwa.yu
221  * [WCXRP00000065] Update BoW design and settings
222  * Add BOW short range mode.
223  *
224  * 04 14 2011 yuche.tsai
225  * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case.
226  * Modify some driver connection flow or behavior to pass Sigma test more easier..
227  *
228  * 04 12 2011 cm.chang
229  * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
230  * .
231  *
232  * 04 11 2011 george.huang
233  * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode
234  * export wlan functions to p2p
235  *
236  * 04 08 2011 pat.lu
237  * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver
238  * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile settting for PC Linux driver
239  *
240  * 04 08 2011 cp.wu
241  * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
242  * glBusFreeIrq() should use the same pvCookie as glBusSetIrq() or request_irq()/free_irq() won't work as a pair.
243  *
244  * 04 08 2011 eddie.chen
245  * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
246  * Fix for sigma
247  *
248  * 04 06 2011 cp.wu
249  * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
250  * 1. do not check for pvData inside wlanNetCreate() due to it is NULL for eHPI  port
251  * 2. update perm_addr as well for MAC address
252  * 3. not calling check_mem_region() anymore for eHPI
253  * 4. correct MSC_CS macro for 0-based notation
254  *
255  * 03 29 2011 cp.wu
256  * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for RESET_START and RESET_END events
257  * fix typo.
258  *
259  * 03 29 2011 cp.wu
260  * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for RESET_START and RESET_END events
261  * implement kernel-to-userspace communication via generic netlink socket for whole-chip resetting mechanism
262  *
263  * 03 23 2011 cp.wu
264  * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
265  * apply multi-queue operation only for linux kernel > 2.6.26
266  *
267  * 03 22 2011 pat.lu
268  * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build
269  * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment.
270  *
271  * 03 21 2011 cp.wu
272  * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
273  * portability for compatible with linux 2.6.12.
274  *
275  * 03 21 2011 cp.wu
276  * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
277  * improve portability for awareness of early version of linux kernel and wireless extension.
278  *
279  * 03 21 2011 cp.wu
280  * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
281  * portability improvement
282  *
283  * 03 18 2011 jeffrey.chang
284  * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
285  * remove early suspend functions
286  *
287  * 03 17 2011 cp.wu
288  * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage after system running for a long period
289  * reverse order to prevent probing racing.
290  *
291  * 03 16 2011 cp.wu
292  * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage after system running for a long period
293  * 1. pre-allocate physical continuous buffer while module is being loaded
294  * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer
295  *
296  * The windows part remained the same as before, but added similiar APIs to hide the difference.
297  *
298  * 03 15 2011 jeffrey.chang
299  * [WCXRP00000558] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] refine the queue selection algorithm for WMM
300  * refine the queue_select function
301  *
302  * 03 10 2011 cp.wu
303  * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3
304  * deprecate configuration used by MT6620 E2
305  *
306  * 03 10 2011 terry.wu
307  * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration
308  * Remove unnecessary assert and message.
309  *
310  * 03 08 2011 terry.wu
311  * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration
312  * Export nicQmUpdateWmmParms.
313  *
314  * 03 03 2011 jeffrey.chang
315  * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
316  * support concurrent network
317  *
318  * 03 03 2011 jeffrey.chang
319  * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
320  * modify net device relative functions to support multiple H/W queues
321  *
322  * 02 24 2011 george.huang
323  * [WCXRP00000495] [MT6620 Wi-Fi][FW] Support pattern filter for unwanted ARP frames
324  * Support ARP filter during suspended
325  *
326  * 02 21 2011 cp.wu
327  * [WCXRP00000482] [MT6620 Wi-Fi][Driver] Simplify logic for checking NVRAM existence in driver domain
328  * simplify logic for checking NVRAM existence only once.
329  *
330  * 02 17 2011 terry.wu
331  * [WCXRP00000459] [MT6620 Wi-Fi][Driver] Fix deference null pointer problem in wlanRemove
332  * Fix deference a null pointer problem in wlanRemove.
333  *
334  * 02 16 2011 jeffrey.chang
335  * NULL
336  * fix compilig error
337  *
338  * 02 16 2011 jeffrey.chang
339  * NULL
340  * Add query ipv4 and ipv6 address during early suspend and late resume
341  *
342  * 02 15 2011 jeffrey.chang
343  * NULL
344  * to support early suspend in android
345  *
346  * 02 11 2011 yuche.tsai
347  * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
348  * Add one more export symbol.
349  *
350  * 02 10 2011 yuche.tsai
351  * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
352  * Add RX deauthentication & disassociation process under Hot-Spot mode.
353  *
354  * 02 09 2011 terry.wu
355  * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules
356  * Halt p2p module init and exit until TxThread finished p2p register and unregister.
357  *
358  * 02 08 2011 george.huang
359  * [WCXRP00000422] [MT6620 Wi-Fi][Driver] support query power mode OID handler
360  * Support querying power mode OID.
361  *
362  * 02 08 2011 yuche.tsai
363  * [WCXRP00000421] [Volunteer Patch][MT6620][Driver] Fix incorrect SSID length Issue
364  * Export Deactivation Network.
365  *
366  * 02 01 2011 jeffrey.chang
367  * [WCXRP00000414] KAL Timer is not unregistered when driver not loaded
368  * Unregister the KAL timer during driver unloading
369  *
370  * 01 26 2011 cm.chang
371  * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
372  * Allocate system RAM if fixed message or mgmt buffer is not available
373  *
374  * 01 19 2011 cp.wu
375  * [WCXRP00000371] [MT6620 Wi-Fi][Driver] make linux glue layer portable for Android 2.3.1 with Linux 2.6.35.7
376  * add compile option to check linux version 2.6.35 for different usage of system API to improve portability
377  *
378  * 01 12 2011 cp.wu
379  * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP
380  * implementation of separate BT_OVER_WIFI data path.
381  *
382  * 01 10 2011 cp.wu
383  * [WCXRP00000349] [MT6620 Wi-Fi][Driver] make kalIoctl() of linux port as a thread safe API to avoid potential issues due to multiple access
384  * use mutex to protect kalIoctl() for thread safe.
385  *
386  * 01 04 2011 cp.wu
387  * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease physically continous memory demands
388  * separate kalMemAlloc() into virtually-continous and physically-continous type to ease slab system pressure
389  *
390  * 12 15 2010 cp.wu
391  * [WCXRP00000265] [MT6620 Wi-Fi][Driver] Remove set_mac_address routine from legacy Wi-Fi Android driver
392  * remove set MAC address. MAC address is always loaded from NVRAM instead.
393  *
394  * 12 10 2010 kevin.huang
395  * [WCXRP00000128] [MT6620 Wi-Fi][Driver] Add proc support to Android Driver for debug and driver status check
396  * Add Linux Proc Support
397  *
398  * 11 01 2010 yarco.yang
399  * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform
400  * Add GPIO debug function
401  *
402  * 11 01 2010 cp.wu
403  * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate from firmware auto rate module
404  * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
405  * 2) Remove CNM CH-RECOVER event handling
406  * 3) cfg read/write API renamed with kal prefix for unified naming rules.
407  *
408  * 10 26 2010 cp.wu
409  * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command
410  * 1) update NVRAM content template to ver 1.02
411  * 2) add compile option for querying NIC capability (default: off)
412  * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting
413  * 4) correct auto-rate compiler error under linux (treat warning as error)
414  * 5) simplify usage of NVRAM and REG_INFO_T
415  * 6) add version checking between driver and firmware
416  *
417  * 10 21 2010 chinghwa.yu
418  * [WCXRP00000065] Update BoW design and settings
419  * .
420  *
421  * 10 19 2010 jeffrey.chang
422  * [WCXRP00000120] [MT6620 Wi-Fi][Driver] Refine linux kernel module to the license of MTK propietary and enable MTK HIF by default
423  * Refine linux kernel module to the license of MTK and enable MTK HIF
424  *
425  * 10 18 2010 jeffrey.chang
426  * [WCXRP00000106] [MT6620 Wi-Fi][Driver] Enable setting multicast  callback in Android
427  * .
428  *
429  * 10 18 2010 cp.wu
430  * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android
431  * complete implementation of Android NVRAM access
432  *
433  * 09 27 2010 chinghwa.yu
434  * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings
435  * Update BCM/BoW design and settings.
436  *
437  * 09 23 2010 cp.wu
438  * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item
439  * use firmware reported mac address right after wlanAdapterStart() as permanent address
440  *
441  * 09 21 2010 kevin.huang
442  * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
443  * Eliminate Linux Compile Warning
444  *
445  * 09 03 2010 kevin.huang
446  * NULL
447  * Refine #include sequence and solve recursive/nested #include issue
448  *
449  * 09 01 2010 wh.su
450  * NULL
451  * adding the wapi support for integration test.
452  *
453  * 08 18 2010 yarco.yang
454  * NULL
455  * 1. Fixed HW checksum offload function not work under Linux issue.
456  * 2. Add debug message.
457  *
458  * 08 16 2010 yarco.yang
459  * NULL
460  * Support Linux x86
461  *
462  * 08 02 2010 jeffrey.chang
463  * NULL
464  * 1) modify tx service thread to avoid busy looping
465  * 2) add spin lock declartion for linux build
466  *
467  * 07 29 2010 jeffrey.chang
468  * NULL
469  * fix memory leak for module unloading
470  *
471  * 07 28 2010 jeffrey.chang
472  * NULL
473  * 1) remove unused spinlocks
474  * 2) enable encyption ioctls
475  * 3) fix scan ioctl which may cause supplicant to hang
476  *
477  * 07 23 2010 jeffrey.chang
478  *
479  * bug fix: allocate regInfo when disabling firmware download
480  *
481  * 07 23 2010 jeffrey.chang
482  *
483  * use glue layer api to decrease or increase counter atomically
484  *
485  * 07 22 2010 jeffrey.chang
486  *
487  * add new spinlock
488  *
489  * 07 19 2010 jeffrey.chang
490  *
491  * modify cmd/data path for new design
492  *
493  * 07 08 2010 cp.wu
494  *
495  * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
496  *
497  * 06 06 2010 kevin.huang
498  * [WPD00003832][MT6620 5931] Create driver base
499  * [MT6620 5931] Create driver base
500  *
501  * 05 26 2010 jeffrey.chang
502  * [WPD00003826]Initial import for Linux port
503  * 1) Modify set mac address code
504  * 2) remove power managment macro
505  *
506  * 05 10 2010 cp.wu
507  * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
508  * implement basic wi-fi direct framework
509  *
510  * 05 07 2010 jeffrey.chang
511  * [WPD00003826]Initial import for Linux port
512  * prevent supplicant accessing driver during resume
513  *
514  * 05 07 2010 cp.wu
515  * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
516  * add basic framework for implementating P2P driver hook.
517  *
518  * 04 27 2010 jeffrey.chang
519  * [WPD00003826]Initial import for Linux port
520  * 1) fix firmware download bug
521  * 2) remove query statistics for acelerating firmware download
522  *
523  * 04 27 2010 jeffrey.chang
524  * [WPD00003826]Initial import for Linux port
525  * follow Linux's firmware framework, and remove unused kal API
526  *
527  * 04 21 2010 jeffrey.chang
528  * [WPD00003826]Initial import for Linux port
529  * add for private ioctl support
530  *
531  * 04 19 2010 jeffrey.chang
532  * [WPD00003826]Initial import for Linux port
533  * Query statistics from firmware
534  *
535  * 04 19 2010 jeffrey.chang
536  * [WPD00003826]Initial import for Linux port
537  * modify tcp/ip checksum offload flags
538  *
539  * 04 16 2010 jeffrey.chang
540  * [WPD00003826]Initial import for Linux port
541  * fix tcp/ip checksum offload bug
542  *
543  * 04 13 2010 cp.wu
544  * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
545  * add framework for BT-over-Wi-Fi support.
546  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 1) prPendingCmdInfo is replaced by queue for multiple handler capability
547  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 2) command sequence number is now increased atomically
548  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 3) private data could be hold and taken use for other purpose
549  *
550  * 04 09 2010 jeffrey.chang
551  * [WPD00003826]Initial import for Linux port
552  * fix spinlock usage
553  *
554  * 04 07 2010 jeffrey.chang
555  * [WPD00003826]Initial import for Linux port
556  * Set MAC address from firmware
557  *
558  * 04 07 2010 cp.wu
559  * [WPD00001943]Create WiFi test driver framework on WinXP
560  * rWlanInfo should be placed at adapter rather than glue due to most operations
561  *  *  *  *  *  * are done in adapter layer.
562  *
563  * 04 07 2010 jeffrey.chang
564  * [WPD00003826]Initial import for Linux port
565  * (1)improve none-glue code portability
566  *  * (2) disable set Multicast address during atomic context
567  *
568  * 04 06 2010 jeffrey.chang
569  * [WPD00003826]Initial import for Linux port
570  * adding debug module
571  *
572  * 03 31 2010 wh.su
573  * [WPD00003816][MT6620 Wi-Fi] Adding the security support
574  * modify the wapi related code for new driver's design.
575  *
576  * 03 30 2010 jeffrey.chang
577  * [WPD00003826]Initial import for Linux port
578  * emulate NDIS Pending OID facility
579  *
580  * 03 26 2010 jeffrey.chang
581  * [WPD00003826]Initial import for Linux port
582  * fix f/w download start and load address by using config.h
583  *
584  * 03 26 2010 jeffrey.chang
585  * [WPD00003826]Initial import for Linux port
586  * [WPD00003826] Initial import for Linux port
587  * adding firmware download support
588  *
589  * 03 24 2010 jeffrey.chang
590  * [WPD00003826]Initial import for Linux port
591  * initial import for Linux port
592 **  \main\maintrunk.MT5921\52 2009-10-27 22:49:59 GMT mtk01090
593 **  Fix compile error for Linux EHPI driver
594 **  \main\maintrunk.MT5921\51 2009-10-20 17:38:22 GMT mtk01090
595 **  Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests, and then stop hw.
596 **  \main\maintrunk.MT5921\50 2009-10-08 10:33:11 GMT mtk01090
597 **  Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input parameters and pointers.
598 **  \main\maintrunk.MT5921\49 2009-09-28 20:19:05 GMT mtk01090
599 **  Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel.
600 **  \main\maintrunk.MT5921\48 2009-09-03 13:58:46 GMT mtk01088
601 **  remove non-used code
602 **  \main\maintrunk.MT5921\47 2009-09-03 11:40:25 GMT mtk01088
603 **  adding the module parameter for wapi
604 **  \main\maintrunk.MT5921\46 2009-08-18 22:56:41 GMT mtk01090
605 **  Add Linux SDIO (with mmc core) support.
606 **  Add Linux 2.6.21, 2.6.25, 2.6.26.
607 **  Fix compile warning in Linux.
608 **  \main\maintrunk.MT5921\45 2009-07-06 20:53:00 GMT mtk01088
609 **  adding the code to check the wapi 1x frame
610 **  \main\maintrunk.MT5921\44 2009-06-23 23:18:55 GMT mtk01090
611 **  Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support
612 **  \main\maintrunk.MT5921\43 2009-02-16 23:46:51 GMT mtk01461
613 **  Revise the order of increasing u4TxPendingFrameNum because of  CFG_TX_RET_TX_CTRL_EARLY
614 **  \main\maintrunk.MT5921\42 2009-01-22 13:11:59 GMT mtk01088
615 **  set the tid and 1x value at same packet reserved field
616 **  \main\maintrunk.MT5921\41 2008-10-20 22:43:53 GMT mtk01104
617 **  Fix wrong variable name "prDev" in wlanStop()
618 **  \main\maintrunk.MT5921\40 2008-10-16 15:37:10 GMT mtk01461
619 **  add handle WLAN_STATUS_SUCCESS in wlanHardStartXmit() for CFG_TX_RET_TX_CTRL_EARLY
620 **  \main\maintrunk.MT5921\39 2008-09-25 15:56:21 GMT mtk01461
621 **  Update driver for Code review
622 **  \main\maintrunk.MT5921\38 2008-09-05 17:25:07 GMT mtk01461
623 **  Update Driver for Code Review
624 **  \main\maintrunk.MT5921\37 2008-09-02 10:57:06 GMT mtk01461
625 **  Update driver for code review
626 **  \main\maintrunk.MT5921\36 2008-08-05 01:53:28 GMT mtk01461
627 **  Add support for linux statistics
628 **  \main\maintrunk.MT5921\35 2008-08-04 16:52:58 GMT mtk01461
629 **  Fix ASSERT if removing module in BG_SSID_SCAN state
630 **  \main\maintrunk.MT5921\34 2008-06-13 22:52:24 GMT mtk01461
631 **  Revise status code handling in wlanHardStartXmit() for WLAN_STATUS_SUCCESS
632 **  \main\maintrunk.MT5921\33 2008-05-30 18:56:53 GMT mtk01461
633 **  Not use wlanoidSetCurrentAddrForLinux()
634 **  \main\maintrunk.MT5921\32 2008-05-30 14:39:40 GMT mtk01461
635 **  Remove WMM Assoc Flag
636 **  \main\maintrunk.MT5921\31 2008-05-23 10:26:40 GMT mtk01084
637 **  modify wlanISR interface
638 **  \main\maintrunk.MT5921\30 2008-05-03 18:52:36 GMT mtk01461
639 **  Fix Unset Broadcast filter when setMulticast
640 **  \main\maintrunk.MT5921\29 2008-05-03 15:17:26 GMT mtk01461
641 **  Move Query Media Status to GLUE
642 **  \main\maintrunk.MT5921\28 2008-04-24 22:48:21 GMT mtk01461
643 **  Revise set multicast function by using windows oid style for LP own back
644 **  \main\maintrunk.MT5921\27 2008-04-24 12:00:08 GMT mtk01461
645 **  Fix multicast setting in Linux and add comment
646 **  \main\maintrunk.MT5921\26 2008-03-28 10:40:22 GMT mtk01461
647 **  Fix set mac address func in Linux
648 **  \main\maintrunk.MT5921\25 2008-03-26 15:37:26 GMT mtk01461
649 **  Add set MAC Address
650 **  \main\maintrunk.MT5921\24 2008-03-26 14:24:53 GMT mtk01461
651 **  For Linux, set net_device has feature with checksum offload by default
652 **  \main\maintrunk.MT5921\23 2008-03-11 14:50:52 GMT mtk01461
653 **  Fix typo
654 **  \main\maintrunk.MT5921\22 2008-02-29 15:35:20 GMT mtk01088
655 **  add 1x decide code for sw port control
656 **  \main\maintrunk.MT5921\21 2008-02-21 15:01:54 GMT mtk01461
657 **  Rearrange the set off place of GLUE spin lock in HardStartXmit
658 **  \main\maintrunk.MT5921\20 2008-02-12 23:26:50 GMT mtk01461
659 **  Add debug option - Packet Order for Linux and add debug level - Event
660 **  \main\maintrunk.MT5921\19 2007-12-11 00:11:12 GMT mtk01461
661 **  Fix SPIN_LOCK protection
662 **  \main\maintrunk.MT5921\18 2007-11-30 17:02:25 GMT mtk01425
663 **  1. Set Rx multicast packets mode before setting the address list
664 **  \main\maintrunk.MT5921\17 2007-11-26 19:44:24 GMT mtk01461
665 **  Add OS_TIMESTAMP to packet
666 **  \main\maintrunk.MT5921\16 2007-11-21 15:47:20 GMT mtk01088
667 **  fixed the unload module issue
668 **  \main\maintrunk.MT5921\15 2007-11-07 18:37:38 GMT mtk01461
669 **  Fix compile warnning
670 **  \main\maintrunk.MT5921\14 2007-11-02 01:03:19 GMT mtk01461
671 **  Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning
672 **  \main\maintrunk.MT5921\13 2007-10-30 10:42:33 GMT mtk01425
673 **  1. Refine for multicast list
674 **  \main\maintrunk.MT5921\12 2007-10-25 18:08:13 GMT mtk01461
675 **  Add VOIP SCAN Support  & Refine Roaming
676 ** Revision 1.4  2007/07/05 07:25:33  MTK01461
677 ** Add Linux initial code, modify doc, add 11BB, RF init code
678 **
679 ** Revision 1.3  2007/06/27 02:18:50  MTK01461
680 ** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API
681 **
682 ** Revision 1.2  2007/06/25 06:16:24  MTK01461
683 ** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API
684 **
685 */
686
687 /*******************************************************************************
688 *                         C O M P I L E R   F L A G S
689 ********************************************************************************
690 */
691
692 /*******************************************************************************
693 *                    E X T E R N A L   R E F E R E N C E S
694 ********************************************************************************
695 */
696 #include "gl_os.h"
697 #include "debug.h"
698 #include "wlan_lib.h"
699 #include "gl_wext.h"
700 #include "gl_cfg80211.h"
701 #include "precomp.h"
702
703 /*******************************************************************************
704 *                              C O N S T A N T S
705 ********************************************************************************
706 */
707 //#define MAX_IOREQ_NUM   10
708
709 BOOLEAN fgIsUnderEarlierSuspend = false;
710
711 struct semaphore g_halt_sem;
712 int g_u4HaltFlag = 0;
713
714
715 /*******************************************************************************
716 *                             D A T A   T Y P E S
717 ********************************************************************************
718 */
719 /* Tasklet mechanism is like buttom-half in Linux. We just want to
720  * send a signal to OS for interrupt defer processing. All resources
721  * are NOT allowed reentry, so txPacket, ISR-DPC and ioctl must avoid preempty.
722  */
723 typedef struct _WLANDEV_INFO_T {
724     struct net_device *prDev;
725 } WLANDEV_INFO_T, *P_WLANDEV_INFO_T;
726
727 /*******************************************************************************
728 *                            P U B L I C   D A T A
729 ********************************************************************************
730 */
731
732 MODULE_AUTHOR(NIC_AUTHOR);
733 MODULE_DESCRIPTION(NIC_DESC);
734 MODULE_SUPPORTED_DEVICE(NIC_NAME);
735 extern void wlanRegisterNotifier(void);
736 extern void wlanUnregisterNotifier(void);
737 extern int mt5931_power_off(void); 
738
739 #if 0
740     MODULE_LICENSE("MTK Propietary");
741 #else
742     MODULE_LICENSE("GPL");
743 #endif
744
745 #define NIC_INF_NAME    "wlan%d" /* interface name */
746 #define LEGACY_IN_AP_MODE "legacy_wlan%d" /*interface name in AP mode*/
747 extern volatile int PowerOnIFname;
748
749
750 #if DBG
751     UINT_8  aucDebugModule[DBG_MODULE_NUM];
752     UINT_32 u4DebugModule = 0;
753 #endif /* DBG */
754
755 //4 2007/06/26, mikewu, now we don't use this, we just fix the number of wlan device to 1
756 static WLANDEV_INFO_T arWlanDevInfo[CFG_MAX_WLAN_DEVICES] = {{0}};
757 static UINT_32 u4WlanDevNum = 0; /* How many NICs coexist now */
758
759 /*******************************************************************************
760 *                           P R I V A T E   D A T A
761 ********************************************************************************
762 */
763 #if CFG_ENABLE_WIFI_DIRECT
764 static SUB_MODULE_HANDLER rSubModHandler[SUB_MODULE_NUM] = {{NULL}};
765 #endif
766
767 #define CHAN2G(_channel, _freq, _flags)         \
768     {                                           \
769     .band               = IEEE80211_BAND_2GHZ,  \
770     .center_freq        = (_freq),              \
771     .hw_value           = (_channel),           \
772     .flags              = (_flags),             \
773     .max_antenna_gain   = 0,                    \
774     .max_power          = 30,                   \
775     }
776 static struct ieee80211_channel mtk_2ghz_channels[] = {
777     CHAN2G(1, 2412, 0),
778     CHAN2G(2, 2417, 0),
779     CHAN2G(3, 2422, 0),
780     CHAN2G(4, 2427, 0),
781     CHAN2G(5, 2432, 0),
782     CHAN2G(6, 2437, 0),
783     CHAN2G(7, 2442, 0),
784     CHAN2G(8, 2447, 0),
785     CHAN2G(9, 2452, 0),
786     CHAN2G(10, 2457, 0),
787     CHAN2G(11, 2462, 0),
788     CHAN2G(12, 2467, 0),
789     CHAN2G(13, 2472, 0),
790     CHAN2G(14, 2484, 0),
791 };
792
793 #define CHAN5G(_channel, _flags)                    \
794     {                                               \
795     .band               = IEEE80211_BAND_5GHZ,      \
796     .center_freq        = 5000 + (5 * (_channel)),  \
797     .hw_value           = (_channel),               \
798     .flags              = (_flags),                 \
799     .max_antenna_gain   = 0,                        \
800     .max_power          = 30,                       \
801     }
802 static struct ieee80211_channel mtk_5ghz_channels[] = {
803     CHAN5G(34, 0),      CHAN5G(36, 0),
804     CHAN5G(38, 0),      CHAN5G(40, 0),
805     CHAN5G(42, 0),      CHAN5G(44, 0),
806     CHAN5G(46, 0),      CHAN5G(48, 0),
807     CHAN5G(52, 0),      CHAN5G(56, 0),
808     CHAN5G(60, 0),      CHAN5G(64, 0),
809     CHAN5G(100, 0),     CHAN5G(104, 0),
810     CHAN5G(108, 0),     CHAN5G(112, 0),
811     CHAN5G(116, 0),     CHAN5G(120, 0),
812     CHAN5G(124, 0),     CHAN5G(128, 0),
813     CHAN5G(132, 0),     CHAN5G(136, 0),
814     CHAN5G(140, 0),     CHAN5G(149, 0),
815     CHAN5G(153, 0),     CHAN5G(157, 0),
816     CHAN5G(161, 0),     CHAN5G(165, 0),
817     CHAN5G(169, 0),     CHAN5G(173, 0),
818     CHAN5G(184, 0),     CHAN5G(188, 0),
819     CHAN5G(192, 0),     CHAN5G(196, 0),
820     CHAN5G(200, 0),     CHAN5G(204, 0),
821     CHAN5G(208, 0),     CHAN5G(212, 0),
822     CHAN5G(216, 0),
823 };
824
825 /* for cfg80211 - rate table */
826 static struct ieee80211_rate mtk_rates[] = {
827     RATETAB_ENT(10,   0x1000,   0),
828     RATETAB_ENT(20,   0x1001,   0),
829     RATETAB_ENT(55,   0x1002,   0),
830     RATETAB_ENT(110,  0x1003,   0), /* 802.11b */
831     RATETAB_ENT(60,   0x2000,   0),
832     RATETAB_ENT(90,   0x2001,   0),
833     RATETAB_ENT(120,  0x2002,   0),
834     RATETAB_ENT(180,  0x2003,   0),
835     RATETAB_ENT(240,  0x2004,   0),
836     RATETAB_ENT(360,  0x2005,   0),
837     RATETAB_ENT(480,  0x2006,   0),
838     RATETAB_ENT(540,  0x2007,   0), /* 802.11a/g */
839 };
840
841 #define mtk_a_rates         (mtk_rates + 4)
842 #define mtk_a_rates_size    (sizeof(mtk_rates) / sizeof(mtk_rates[0]) - 4)
843 #define mtk_g_rates         (mtk_rates + 0)
844 #define mtk_g_rates_size    (sizeof(mtk_rates) / sizeof(mtk_rates[0]) - 0)
845
846 #define MT6620_MCS_INFO                                 \
847 {                                                       \
848     .rx_mask        = {0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0},\
849     .rx_highest     = 0,                                \
850     .tx_params      = IEEE80211_HT_MCS_TX_DEFINED,      \
851 }
852
853 #define MT6620_HT_CAP                                   \
854 {                                                       \
855     .ht_supported   = true,                             \
856     .cap            = IEEE80211_HT_CAP_SUP_WIDTH_20_40  \
857                     | IEEE80211_HT_CAP_SM_PS            \
858                     | IEEE80211_HT_CAP_GRN_FLD          \
859                     | IEEE80211_HT_CAP_SGI_20           \
860                     | IEEE80211_HT_CAP_SGI_40,          \
861     .ampdu_factor   = IEEE80211_HT_MAX_AMPDU_64K,       \
862     .ampdu_density  = IEEE80211_HT_MPDU_DENSITY_NONE,   \
863     .mcs            = MT6620_MCS_INFO,                  \
864 }
865
866 /* public for both Legacy Wi-Fi / P2P access */
867 struct ieee80211_supported_band mtk_band_2ghz = {
868     .band       = IEEE80211_BAND_2GHZ,
869     .channels   = mtk_2ghz_channels,
870     .n_channels = ARRAY_SIZE(mtk_2ghz_channels),
871     .bitrates   = mtk_g_rates,
872     .n_bitrates = mtk_g_rates_size,
873     .ht_cap     = MT6620_HT_CAP,
874 };
875
876 /* public for both Legacy Wi-Fi / P2P access */
877 struct ieee80211_supported_band mtk_band_5ghz = {
878     .band       = IEEE80211_BAND_5GHZ,
879     .channels   = mtk_5ghz_channels,
880     .n_channels = ARRAY_SIZE(mtk_5ghz_channels),
881     .bitrates   = mtk_a_rates,
882     .n_bitrates = mtk_a_rates_size,
883     .ht_cap     = MT6620_HT_CAP,
884 };
885
886 static const UINT_32 mtk_cipher_suites[] = {
887     /* keep WEP first, it may be removed below */
888     WLAN_CIPHER_SUITE_WEP40,
889     WLAN_CIPHER_SUITE_WEP104,
890     WLAN_CIPHER_SUITE_TKIP,
891     WLAN_CIPHER_SUITE_CCMP,
892
893     /* keep last -- depends on hw flags! */
894     WLAN_CIPHER_SUITE_AES_CMAC
895 };
896
897 static struct cfg80211_ops mtk_wlan_ops = {
898     .change_virtual_intf    = mtk_cfg80211_change_iface,
899     .add_key                = mtk_cfg80211_add_key,
900     .get_key                = mtk_cfg80211_get_key,
901     .del_key                = mtk_cfg80211_del_key,
902     .set_default_key        = mtk_cfg80211_set_default_key,
903     .get_station            = mtk_cfg80211_get_station,
904     .scan                   = mtk_cfg80211_scan,
905     .connect                = mtk_cfg80211_connect,
906     .disconnect             = mtk_cfg80211_disconnect,
907     .join_ibss              = mtk_cfg80211_join_ibss,
908     .leave_ibss             = mtk_cfg80211_leave_ibss,
909     .set_power_mgmt         = mtk_cfg80211_set_power_mgmt,
910     .set_pmksa              = mtk_cfg80211_set_pmksa,
911     .del_pmksa              = mtk_cfg80211_del_pmksa,
912     .flush_pmksa            = mtk_cfg80211_flush_pmksa,
913
914     /* Action Frame TX/RX */
915     .remain_on_channel          = mtk_cfg80211_remain_on_channel,
916     .cancel_remain_on_channel   = mtk_cfg80211_cancel_remain_on_channel,
917     .mgmt_tx                    = mtk_cfg80211_mgmt_tx,
918     .mgmt_tx_cancel_wait        = mtk_cfg80211_mgmt_tx_cancel_wait,
919     #ifdef CONFIG_NL80211_TESTMODE
920     .testmode_cmd               = mtk_cfg80211_testmode_cmd,
921     #endif
922 };
923
924 /*******************************************************************************
925 *                                 M A C R O S
926 ********************************************************************************
927 */
928
929 /*******************************************************************************
930 *                   F U N C T I O N   D E C L A R A T I O N S
931 ********************************************************************************
932 */
933
934 #if defined(CONFIG_HAS_EARLYSUSPEND)
935 extern int glRegisterEarlySuspend(
936     struct early_suspend        *prDesc,
937     early_suspend_callback      wlanSuspend,
938     late_resume_callback        wlanResume);
939
940 extern int glUnregisterEarlySuspend(struct early_suspend *prDesc);
941 #endif
942
943 /*******************************************************************************
944 *                              F U N C T I O N S
945 ********************************************************************************
946 */
947
948 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
949 /*----------------------------------------------------------------------------*/
950 /*!
951 * \brief Override the implementation of select queue
952 *
953 * \param[in] dev Pointer to struct net_device
954 * \param[in] skb Pointer to struct skb_buff
955 *
956 * \return (none)
957 */
958 /*----------------------------------------------------------------------------*/
959 unsigned int _cfg80211_classify8021d(struct sk_buff *skb)
960 {
961     unsigned int dscp = 0;
962
963     /* skb->priority values from 256->263 are magic values
964      * directly indicate a specific 802.1d priority.  This is
965      * to allow 802.1d priority to be passed directly in from
966      * tags
967      */
968
969     if (skb->priority >= 256 && skb->priority <= 263) {
970         return skb->priority - 256;
971     }
972     switch (skb->protocol) {
973         case htons(ETH_P_IP):
974             dscp = ip_hdr(skb)->tos & 0xfc;
975             break;
976     }
977     return dscp >> 5;
978 }
979
980
981 static const UINT_16 au16Wlan1dToQueueIdx[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
982
983 static UINT_16
984 wlanSelectQueue(
985     struct net_device *dev,
986     struct sk_buff *skb)
987 {
988     skb->priority = _cfg80211_classify8021d(skb);
989
990     return au16Wlan1dToQueueIdx[skb->priority];
991 }
992 #endif
993
994
995 /*----------------------------------------------------------------------------*/
996 /*!
997 * \brief Load NVRAM data and translate it into REG_INFO_T
998 *
999 * \param[in]  prGlueInfo Pointer to struct GLUE_INFO_T
1000 * \param[out] prRegInfo  Pointer to struct REG_INFO_T
1001 *
1002 * \return (none)
1003 */
1004 /*----------------------------------------------------------------------------*/
1005 static void
1006 glLoadNvram (
1007     IN  P_GLUE_INFO_T   prGlueInfo,
1008     OUT P_REG_INFO_T    prRegInfo
1009     )
1010 {
1011     UINT_32 i, j;
1012     UINT_8 aucTmp[2];
1013     PUINT_8 pucDest;
1014
1015     ASSERT(prGlueInfo);
1016     ASSERT(prRegInfo);
1017
1018     if((!prGlueInfo) || (!prRegInfo)) {
1019         return;
1020     }
1021
1022     if(kalCfgDataRead16(prGlueInfo,
1023             sizeof(WIFI_CFG_PARAM_STRUCT) - sizeof(UINT_16),
1024             (PUINT_16)aucTmp) == TRUE) {
1025         prGlueInfo->fgNvramAvailable = TRUE;
1026
1027         // load MAC Address
1028         for (i = 0 ; i < sizeof(PARAM_MAC_ADDR_LEN) ; i += sizeof(UINT_16)) {
1029             kalCfgDataRead16(prGlueInfo,
1030                     OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucMacAddress) + i,
1031                     (PUINT_16) (((PUINT_8)prRegInfo->aucMacAddr) + i));
1032         }
1033
1034         // load country code
1035         kalCfgDataRead16(prGlueInfo,
1036                 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucCountryCode[0]),
1037                     (PUINT_16)aucTmp);
1038
1039         // cast to wide characters
1040         prRegInfo->au2CountryCode[0] = (UINT_16) aucTmp[0];
1041         prRegInfo->au2CountryCode[1] = (UINT_16) aucTmp[1];
1042
1043         // load default normal TX power
1044         for (i = 0 ; i < sizeof(TX_PWR_PARAM_T) ; i += sizeof(UINT_16)) {
1045             kalCfgDataRead16(prGlueInfo,
1046                     OFFSET_OF(WIFI_CFG_PARAM_STRUCT, rTxPwr) + i,
1047                     (PUINT_16) (((PUINT_8)&(prRegInfo->rTxPwr)) + i));
1048         }
1049
1050         // load feature flags
1051         kalCfgDataRead16(prGlueInfo,
1052                 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucTxPwrValid),
1053                 (PUINT_16)aucTmp);
1054         prRegInfo->ucTxPwrValid     = aucTmp[0];
1055         prRegInfo->ucSupport5GBand  = aucTmp[1];
1056
1057         kalCfgDataRead16(prGlueInfo,
1058                 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, uc2G4BwFixed20M),
1059                 (PUINT_16)aucTmp);
1060         prRegInfo->uc2G4BwFixed20M  = aucTmp[0];
1061         prRegInfo->uc5GBwFixed20M   = aucTmp[1];
1062
1063         kalCfgDataRead16(prGlueInfo,
1064                 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucEnable5GBand),
1065                 (PUINT_16)aucTmp);
1066         prRegInfo->ucEnable5GBand   = aucTmp[0];
1067
1068         /* load EFUSE overriding part */
1069         for (i = 0 ; i < sizeof(prRegInfo->aucEFUSE) ; i += sizeof(UINT_16)) {
1070             kalCfgDataRead16(prGlueInfo,
1071                     OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucEFUSE) + i,
1072                     (PUINT_16) (((PUINT_8)&(prRegInfo->aucEFUSE)) + i));
1073         }
1074
1075         /* load band edge tx power control */
1076         kalCfgDataRead16(prGlueInfo,
1077                 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, fg2G4BandEdgePwrUsed),
1078                 (PUINT_16)aucTmp);
1079         prRegInfo->fg2G4BandEdgePwrUsed = (BOOLEAN)aucTmp[0];
1080         if (aucTmp[0]) {
1081             prRegInfo->cBandEdgeMaxPwrCCK   = (INT_8)aucTmp[1];
1082
1083             kalCfgDataRead16(prGlueInfo,
1084                     OFFSET_OF(WIFI_CFG_PARAM_STRUCT, cBandEdgeMaxPwrOFDM20),
1085                     (PUINT_16)aucTmp);
1086             prRegInfo->cBandEdgeMaxPwrOFDM20    = (INT_8)aucTmp[0];
1087             prRegInfo->cBandEdgeMaxPwrOFDM40    = (INT_8)aucTmp[1];
1088         }
1089
1090         /* load regulation subbands */
1091         kalCfgDataRead16(prGlueInfo,
1092                 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucRegChannelListMap),
1093                 (PUINT_16)aucTmp);
1094         prRegInfo->eRegChannelListMap = (ENUM_REG_CH_MAP_T) aucTmp[0];
1095         prRegInfo->ucRegChannelListIndex = aucTmp[1];
1096
1097         if (prRegInfo->eRegChannelListMap == REG_CH_MAP_CUSTOMIZED) {
1098             for (i = 0 ; i < MAX_SUBBAND_NUM; i++) {
1099                 pucDest = (PUINT_8) &prRegInfo->rDomainInfo.rSubBand[i];
1100                 for (j = 0; j < 6; j += sizeof(UINT_16)) {
1101                     kalCfgDataRead16(prGlueInfo,
1102                             OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucRegSubbandInfo)
1103                             + (i * 6 + j),
1104                             (PUINT_16)aucTmp);
1105
1106                     *pucDest++ = aucTmp[0];
1107                     *pucDest++ = aucTmp[1];
1108                 }
1109             }
1110         }
1111     }
1112     else {
1113         prGlueInfo->fgNvramAvailable = FALSE;
1114     }
1115
1116     return;
1117 }
1118
1119
1120 #if CFG_ENABLE_WIFI_DIRECT
1121 /*----------------------------------------------------------------------------*/
1122 /*!
1123 * \brief called by txthread, run sub module init function
1124 *
1125 * \param[in]  prGlueInfo Pointer to struct GLUE_INFO_T
1126 *
1127 * \return (none)
1128 */
1129 /*----------------------------------------------------------------------------*/
1130 VOID
1131 wlanSubModRunInit(
1132     P_GLUE_INFO_T prGlueInfo
1133     )
1134 {
1135     /*now, we only have p2p module*/
1136     if(rSubModHandler[P2P_MODULE].fgIsInited == FALSE) {
1137         rSubModHandler[P2P_MODULE].subModInit(prGlueInfo);
1138         rSubModHandler[P2P_MODULE].fgIsInited = TRUE;
1139     }
1140
1141 }
1142
1143 /*----------------------------------------------------------------------------*/
1144 /*!
1145 * \brief called by txthread, run sub module exit function
1146 *
1147 * \param[in]  prGlueInfo Pointer to struct GLUE_INFO_T
1148 *
1149 * \return (none)
1150 */
1151 /*----------------------------------------------------------------------------*/
1152 VOID
1153 wlanSubModRunExit(
1154     P_GLUE_INFO_T prGlueInfo
1155     )
1156 {
1157     /*now, we only have p2p module*/
1158     if(rSubModHandler[P2P_MODULE].fgIsInited == TRUE) {
1159         rSubModHandler[P2P_MODULE].subModExit(prGlueInfo);
1160         rSubModHandler[P2P_MODULE].fgIsInited = FALSE;
1161     }
1162 }
1163
1164 /*----------------------------------------------------------------------------*/
1165 /*!
1166 * \brief set sub module init flag, force TxThread to run sub modle init
1167 *
1168 * \param[in]  prGlueInfo Pointer to struct GLUE_INFO_T
1169 *
1170 * \return (none)
1171 */
1172 /*----------------------------------------------------------------------------*/
1173 BOOLEAN
1174 wlanSubModInit(
1175     P_GLUE_INFO_T prGlueInfo
1176     )
1177 {
1178     //4  Mark HALT, notify main thread to finish current job
1179     prGlueInfo->u4Flag |= GLUE_FLAG_SUB_MOD_INIT;
1180     /* wake up main thread */
1181     wake_up_interruptible(&prGlueInfo->waitq);
1182     /* wait main thread  finish sub module INIT*/
1183     wait_for_completion_interruptible(&prGlueInfo->rSubModComp);
1184
1185 #if 0
1186     if(prGlueInfo->prAdapter->fgIsP2PRegistered) {
1187         p2pNetRegister(prGlueInfo);
1188     }
1189 #endif
1190
1191     return TRUE;
1192 }
1193
1194 /*----------------------------------------------------------------------------*/
1195 /*!
1196 * \brief set sub module exit flag, force TxThread to run sub modle exit
1197 *
1198 * \param[in]  prGlueInfo Pointer to struct GLUE_INFO_T
1199 *
1200 * \return (none)
1201 */
1202 /*----------------------------------------------------------------------------*/
1203 BOOLEAN
1204 wlanSubModExit(
1205     P_GLUE_INFO_T prGlueInfo
1206     )
1207 {
1208 #if 0
1209     if(prGlueInfo->prAdapter->fgIsP2PRegistered) {
1210         p2pNetUnregister(prGlueInfo);
1211     }
1212 #endif
1213
1214     //4  Mark HALT, notify main thread to finish current job
1215     prGlueInfo->u4Flag |= GLUE_FLAG_SUB_MOD_EXIT;
1216     /* wake up main thread */
1217     wake_up_interruptible(&prGlueInfo->waitq);
1218     /* wait main thread finish sub module EXIT */
1219     wait_for_completion_interruptible(&prGlueInfo->rSubModComp);
1220
1221     return TRUE;
1222 }
1223
1224
1225 /*----------------------------------------------------------------------------*/
1226 /*!
1227 * \brief set by sub module, indicate sub module is already inserted
1228 *
1229 * \param[in]  rSubModInit, function pointer point to sub module init function
1230 * \param[in]  rSubModExit,  function pointer point to sub module exit function
1231 * \param[in]  eSubModIdx,  sub module index
1232 *
1233 * \return (none)
1234 */
1235 /*----------------------------------------------------------------------------*/
1236 VOID
1237 wlanSubModRegisterInitExit(
1238     SUB_MODULE_INIT rSubModInit,
1239     SUB_MODULE_EXIT rSubModExit,
1240     ENUM_SUB_MODULE_IDX_T eSubModIdx
1241     )
1242 {
1243     rSubModHandler[eSubModIdx].subModInit = rSubModInit;
1244     rSubModHandler[eSubModIdx].subModExit = rSubModExit;
1245     rSubModHandler[eSubModIdx].fgIsInited = FALSE;
1246 }
1247
1248 #if 0
1249 /*----------------------------------------------------------------------------*/
1250 /*!
1251 * \brief check wlan is launched or not
1252 *
1253 * \param[in]  (none)
1254 *
1255 * \return TRUE, wlan is already started
1256 *             FALSE, wlan is not started yet
1257 */
1258 /*----------------------------------------------------------------------------*/
1259 BOOLEAN
1260 wlanIsLaunched(
1261     VOID
1262     )
1263 {
1264     struct net_device *prDev = NULL;
1265     P_GLUE_INFO_T prGlueInfo = NULL;
1266
1267     //4 <0> Sanity check
1268     ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES);
1269     if (0 == u4WlanDevNum) {
1270         return FALSE;
1271     }
1272
1273     prDev = arWlanDevInfo[u4WlanDevNum-1].prDev;
1274
1275     ASSERT(prDev);
1276     if (NULL == prDev) {
1277         return FALSE;
1278     }
1279
1280     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
1281     ASSERT(prGlueInfo);
1282     if (NULL == prGlueInfo) {
1283         return FALSE;
1284     }
1285
1286     return prGlueInfo->prAdapter->fgIsWlanLaunched;
1287 }
1288
1289 #endif
1290
1291 /*----------------------------------------------------------------------------*/
1292 /*!
1293 * \brief Export wlan GLUE_INFO_T pointer to p2p module
1294 *
1295 * \param[in]  prGlueInfo Pointer to struct GLUE_INFO_T
1296 *
1297 * \return TRUE: get GlueInfo pointer successfully
1298 *            FALSE: wlan is not started yet
1299 */
1300 /*---------------------------------------------------------------------------*/
1301 BOOLEAN
1302 wlanExportGlueInfo(
1303     P_GLUE_INFO_T *prGlueInfoExpAddr
1304     )
1305 {
1306     struct net_device *prDev = NULL;
1307     P_GLUE_INFO_T prGlueInfo = NULL;
1308
1309     if (0 == u4WlanDevNum) {
1310         return FALSE;
1311     }
1312
1313     prDev = arWlanDevInfo[u4WlanDevNum-1].prDev;
1314     if (NULL == prDev) {
1315         return FALSE;
1316     }
1317
1318     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
1319     if (NULL == prGlueInfo) {
1320         return FALSE;
1321     }
1322
1323     if(FALSE == prGlueInfo->prAdapter->fgIsWlanLaunched) {
1324         return FALSE;
1325     }
1326
1327     *prGlueInfoExpAddr = prGlueInfo;
1328     return TRUE;
1329 }
1330
1331 #endif
1332
1333
1334 /*----------------------------------------------------------------------------*/
1335 /*!
1336 * \brief Release prDev from wlandev_array and free tasklet object related to it.
1337 *
1338 * \param[in] prDev  Pointer to struct net_device
1339 *
1340 * \return (none)
1341 */
1342 /*----------------------------------------------------------------------------*/
1343 static void
1344 wlanClearDevIdx (
1345     struct net_device *prDev
1346     )
1347 {
1348     int i;
1349
1350     ASSERT(prDev);
1351
1352     for (i = 0; i < CFG_MAX_WLAN_DEVICES; i++) {
1353         if (arWlanDevInfo[i].prDev == prDev) {
1354             arWlanDevInfo[i].prDev = NULL;
1355             u4WlanDevNum--;
1356         }
1357     }
1358
1359     return;
1360 } /* end of wlanClearDevIdx() */
1361
1362
1363 /*----------------------------------------------------------------------------*/
1364 /*!
1365 * \brief Allocate an unique interface index, net_device::ifindex member for this
1366 *        wlan device. Store the net_device in wlandev_array, and initialize
1367 *        tasklet object related to it.
1368 *
1369 * \param[in] prDev  Pointer to struct net_device
1370 *
1371 * \retval >= 0      The device number.
1372 * \retval -1        Fail to get index.
1373 */
1374 /*----------------------------------------------------------------------------*/
1375 static int
1376 wlanGetDevIdx (
1377     struct net_device *prDev
1378     )
1379 {
1380     int i;
1381
1382     ASSERT(prDev);
1383
1384     for (i = 0; i < CFG_MAX_WLAN_DEVICES; i++) {
1385         if (arWlanDevInfo[i].prDev == (struct net_device *) NULL) {
1386             /* Reserve 2 bytes space to store one digit of
1387              * device number and NULL terminator.
1388              */
1389             arWlanDevInfo[i].prDev = prDev;
1390             u4WlanDevNum++;
1391             return i;
1392         }
1393     }
1394
1395     return -1;
1396 } /* end of wlanGetDevIdx() */
1397
1398 /*----------------------------------------------------------------------------*/
1399 /*!
1400 * \brief A method of struct net_device, a primary SOCKET interface to configure
1401 *        the interface lively. Handle an ioctl call on one of our devices.
1402 *        Everything Linux ioctl specific is done here. Then we pass the contents
1403 *        of the ifr->data to the request message handler.
1404 *
1405 * \param[in] prDev      Linux kernel netdevice
1406 *
1407 * \param[in] prIFReq    Our private ioctl request structure, typed for the generic
1408 *                       struct ifreq so we can use ptr to function
1409 *
1410 * \param[in] cmd        Command ID
1411 *
1412 * \retval WLAN_STATUS_SUCCESS The IOCTL command is executed successfully.
1413 * \retval OTHER The execution of IOCTL command is failed.
1414 */
1415 /*----------------------------------------------------------------------------*/
1416 int
1417 wlanDoIOCTL(
1418     struct net_device *prDev,
1419     struct ifreq *prIFReq,
1420     int i4Cmd
1421     )
1422 {
1423     P_GLUE_INFO_T prGlueInfo = NULL;
1424     int ret = 0;
1425
1426     /* Verify input parameters for the following functions */
1427     ASSERT(prDev && prIFReq);
1428     if (!prDev || !prIFReq) {
1429         DBGLOG(INIT, WARN, ("%s Invalid input data\n", __FUNCTION__));
1430         return -EINVAL;
1431     }
1432
1433     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
1434     ASSERT(prGlueInfo);
1435     if (!prGlueInfo) {
1436         DBGLOG(INIT, WARN, ("%s No glue info\n", __FUNCTION__));
1437         return -EFAULT;
1438     }
1439
1440     if (prGlueInfo->u4ReadyFlag == 0) {
1441         return -EINVAL;
1442     }
1443
1444     //printk ("ioctl %x\n", i4Cmd);
1445
1446     if (i4Cmd == SIOCGIWPRIV) {
1447         /* 0x8B0D, get private ioctl table */
1448         ret = wext_get_priv(prDev, prIFReq);
1449     }
1450     else if ((i4Cmd >= SIOCIWFIRST) && (i4Cmd < SIOCIWFIRSTPRIV)) {
1451         /* 0x8B00 ~ 0x8BDF, wireless extension region */
1452         ret = wext_support_ioctl(prDev, prIFReq, i4Cmd);
1453     }
1454     else if ((i4Cmd >= SIOCIWFIRSTPRIV) && (i4Cmd < SIOCIWLASTPRIV)) {
1455         /* 0x8BE0 ~ 0x8BFF, private ioctl region */
1456         ret = priv_support_ioctl(prDev, prIFReq, i4Cmd);
1457     }
1458     else {
1459         DBGLOG(INIT, WARN, ("Unexpected ioctl command: 0x%04x\n", i4Cmd));
1460         /* return 0 for safe? */
1461     }
1462
1463     return ret;
1464 } /* end of wlanDoIOCTL() */
1465
1466 /*----------------------------------------------------------------------------*/
1467 /*!
1468 * \brief This function is to set multicast list and set rx mode.
1469 *
1470 * \param[in] prDev  Pointer to struct net_device
1471 *
1472 * \return (none)
1473 */
1474 /*----------------------------------------------------------------------------*/
1475
1476 static struct delayed_work workq;
1477 static struct net_device *gPrDev;
1478
1479 static void
1480 wlanSetMulticastList (struct net_device *prDev)
1481 {
1482     gPrDev = prDev;
1483     schedule_delayed_work(&workq, 0);
1484 }
1485
1486 /* FIXME: Since we cannot sleep in the wlanSetMulticastList, we arrange
1487  * another workqueue for sleeping. We don't want to block
1488  * tx_thread, so we can't let tx_thread to do this */
1489
1490 static void
1491 wlanSetMulticastListWorkQueue (struct work_struct *work) {
1492
1493     P_GLUE_INFO_T prGlueInfo = NULL;
1494     UINT_32 u4PacketFilter = 0;
1495     UINT_32 u4SetInfoLen;
1496     struct net_device *prDev = gPrDev;
1497
1498     down(&g_halt_sem);
1499     if (g_u4HaltFlag) {
1500         up(&g_halt_sem);
1501         return;
1502     }
1503
1504     prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL;
1505     ASSERT(prDev);
1506     ASSERT(prGlueInfo);
1507     if (!prDev || !prGlueInfo) {
1508         DBGLOG(INIT, WARN, ("abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n",
1509             prDev, prGlueInfo));
1510         up(&g_halt_sem);
1511         return;
1512     }
1513
1514     if (prDev->flags & IFF_PROMISC) {
1515         u4PacketFilter |= PARAM_PACKET_FILTER_PROMISCUOUS;
1516     }
1517
1518     if (prDev->flags & IFF_BROADCAST) {
1519         u4PacketFilter |= PARAM_PACKET_FILTER_BROADCAST;
1520     }
1521
1522     if (prDev->flags & IFF_MULTICAST) {
1523         if ((prDev->flags & IFF_ALLMULTI) ||
1524 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
1525             (netdev_mc_count(prDev) > MAX_NUM_GROUP_ADDR)) {
1526 #else
1527             (prDev->mc_count > MAX_NUM_GROUP_ADDR)) {
1528 #endif
1529
1530             u4PacketFilter |= PARAM_PACKET_FILTER_ALL_MULTICAST;
1531         }
1532         else {
1533             u4PacketFilter |= PARAM_PACKET_FILTER_MULTICAST;
1534         }
1535     }
1536
1537     up(&g_halt_sem);
1538
1539     if (kalIoctl(prGlueInfo,
1540             wlanoidSetCurrentPacketFilter,
1541             &u4PacketFilter,
1542             sizeof(u4PacketFilter),
1543             FALSE,
1544             FALSE,
1545             TRUE,
1546             FALSE,
1547             &u4SetInfoLen) != WLAN_STATUS_SUCCESS) {
1548         return;
1549     }
1550
1551
1552     if (u4PacketFilter & PARAM_PACKET_FILTER_MULTICAST) {
1553         /* Prepare multicast address list */
1554 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
1555         struct netdev_hw_addr *ha;
1556 #else
1557         struct dev_mc_list *prMcList;
1558 #endif
1559         PUINT_8 prMCAddrList = NULL;
1560         UINT_32 i = 0;
1561
1562         down(&g_halt_sem);
1563         if (g_u4HaltFlag) {
1564             up(&g_halt_sem);
1565             return;
1566         }
1567
1568         prMCAddrList = kalMemAlloc(MAX_NUM_GROUP_ADDR * ETH_ALEN, VIR_MEM_TYPE);
1569
1570 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
1571         netdev_for_each_mc_addr(ha, prDev) {
1572             if(i < MAX_NUM_GROUP_ADDR) {
1573                 memcpy((prMCAddrList + i * ETH_ALEN), ha->addr, ETH_ALEN);
1574                 i++;
1575             }
1576         }
1577 #else
1578         for (i = 0, prMcList = prDev->mc_list;
1579              (prMcList) && (i < prDev->mc_count) && (i < MAX_NUM_GROUP_ADDR);
1580              i++, prMcList = prMcList->next) {
1581             memcpy((prMCAddrList + i * ETH_ALEN), prMcList->dmi_addr, ETH_ALEN);
1582         }
1583 #endif
1584
1585         up(&g_halt_sem);
1586
1587         kalIoctl(prGlueInfo,
1588             wlanoidSetMulticastList,
1589             prMCAddrList,
1590             (i * ETH_ALEN),
1591             FALSE,
1592             FALSE,
1593             TRUE,
1594             FALSE,
1595             &u4SetInfoLen);
1596
1597         kalMemFree(prMCAddrList, VIR_MEM_TYPE, MAX_NUM_GROUP_ADDR * ETH_ALEN);
1598     }
1599
1600     return;
1601 } /* end of wlanSetMulticastList() */
1602
1603
1604 /* FIXME: Since we cannot sleep in the wlanSetMulticastList, we arrange
1605  * another workqueue for sleeping. We don't want to block
1606  * tx_thread, so we can't let tx_thread to do this */
1607
1608 void
1609 p2pSetMulticastListWorkQueueWrapper (P_GLUE_INFO_T prGlueInfo) {
1610
1611     ASSERT(prGlueInfo);
1612
1613     if (!prGlueInfo) {
1614         DBGLOG(INIT, WARN, ("abnormal dev or skb: prGlueInfo(0x%p)\n",
1615             prGlueInfo));
1616         return;
1617     }
1618
1619 #if CFG_ENABLE_WIFI_DIRECT
1620     if(prGlueInfo->prAdapter->fgIsP2PRegistered) {
1621         mtk_p2p_wext_set_Multicastlist(prGlueInfo);
1622     }
1623 #endif
1624
1625     return;
1626 } /* end of p2pSetMulticastListWorkQueueWrapper() */
1627
1628
1629
1630 /*----------------------------------------------------------------------------*/
1631 /*!
1632 * \brief This function is TX entry point of NET DEVICE.
1633 *
1634 * \param[in] prSkb  Pointer of the sk_buff to be sent
1635 * \param[in] prDev  Pointer to struct net_device
1636 *
1637 * \retval NETDEV_TX_OK - on success.
1638 * \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer.
1639 */
1640 /*----------------------------------------------------------------------------*/
1641 int
1642 wlanHardStartXmit(
1643     struct sk_buff *prSkb,
1644     struct net_device *prDev
1645     )
1646 {
1647     P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
1648
1649     P_QUE_ENTRY_T prQueueEntry = NULL;
1650     P_QUE_T prTxQueue = NULL;
1651     UINT_16 u2QueueIdx = 0;
1652
1653 #if CFG_BOW_TEST
1654     UINT_32 i;
1655 #endif
1656
1657     GLUE_SPIN_LOCK_DECLARATION();
1658
1659     ASSERT(prSkb);
1660     ASSERT(prDev);
1661     ASSERT(prGlueInfo);
1662
1663     if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) {
1664         DBGLOG(INIT, INFO, ("GLUE_FLAG_HALT skip tx\n"));
1665         dev_kfree_skb(prSkb);
1666         return NETDEV_TX_OK;
1667     }
1668
1669     prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb);
1670     prTxQueue = &prGlueInfo->rTxQueue;
1671
1672 #if CFG_BOW_TEST
1673     DBGLOG(BOW, TRACE, ("sk_buff->len: %d\n", prSkb->len));
1674     DBGLOG(BOW, TRACE, ("sk_buff->data_len: %d\n", prSkb->data_len));
1675     DBGLOG(BOW, TRACE, ("sk_buff->data:\n"));
1676
1677     for(i = 0; i < prSkb->len; i++)
1678     {
1679         DBGLOG(BOW, TRACE, ("%4x", prSkb->data[i]));
1680
1681         if((i+1)%16 ==0)
1682         {
1683             DBGLOG(BOW, TRACE, ("\n"));
1684         }
1685     }
1686
1687     DBGLOG(BOW, TRACE, ("\n"));
1688 #endif
1689
1690     if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) {
1691
1692     #if CFG_DBG_GPIO_PINS
1693         {
1694             /* TX request from OS */
1695             mtk_wcn_stp_debug_gpio_assert(IDX_TX_REQ, DBG_TIE_LOW);
1696             kalUdelay(1);
1697             mtk_wcn_stp_debug_gpio_assert(IDX_TX_REQ, DBG_TIE_HIGH);
1698         }
1699     #endif
1700
1701 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26)
1702         u2QueueIdx = skb_get_queue_mapping(prSkb);
1703         ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM);
1704 #endif
1705
1706 #if CFG_ENABLE_PKT_LIFETIME_PROFILE    
1707         GLUE_SET_PKT_ARRIVAL_TIME(prSkb, kalGetTimeTick());    
1708 #endif
1709
1710         GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
1711         QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry);
1712         GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
1713
1714         GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum);
1715         GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]);
1716
1717 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26)
1718         if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx] >= CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) {
1719             netif_stop_subqueue(prDev, u2QueueIdx);
1720         }
1721 #else
1722         if (prGlueInfo->i4TxPendingFrameNum >= CFG_TX_STOP_NETIF_QUEUE_THRESHOLD) {
1723             netif_stop_queue(prDev);
1724         }
1725 #endif
1726     } else {
1727         //printk("is security frame\n");
1728
1729         GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum);
1730     }
1731
1732     DBGLOG(TX, EVENT, ("\n+++++ pending frame %d len = %d +++++\n", prGlueInfo->i4TxPendingFrameNum, prSkb->len));
1733     prGlueInfo->rNetDevStats.tx_bytes += prSkb->len;
1734     prGlueInfo->rNetDevStats.tx_packets++;
1735
1736     //pr->u4Flag |= GLUE_FLAG_TXREQ;
1737     //wake_up_interruptible(&prGlueInfo->waitq);
1738     kalSetEvent(prGlueInfo);
1739
1740
1741     /* For Linux, we'll always return OK FLAG, because we'll free this skb by ourself */
1742     return NETDEV_TX_OK;
1743 } /* end of wlanHardStartXmit() */
1744
1745
1746 /*----------------------------------------------------------------------------*/
1747 /*!
1748 * \brief A method of struct net_device, to get the network interface statistical
1749 *        information.
1750 *
1751 * Whenever an application needs to get statistics for the interface, this method
1752 * is called. This happens, for example, when ifconfig or netstat -i is run.
1753 *
1754 * \param[in] prDev      Pointer to struct net_device.
1755 *
1756 * \return net_device_stats buffer pointer.
1757 */
1758 /*----------------------------------------------------------------------------*/
1759 struct net_device_stats *
1760 wlanGetStats (
1761     IN struct net_device *prDev
1762     )
1763 {
1764     P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
1765
1766     #if 0
1767     WLAN_STATUS rStatus;
1768     UINT_32 u4XmitError = 0;
1769     UINT_32 u4XmitOk = 0;
1770     UINT_32 u4RecvError = 0;
1771     UINT_32 u4RecvOk = 0;
1772     UINT_32 u4BufLen;
1773
1774     ASSERT(prDev);
1775
1776     /* @FIX ME: need a more clear way to do this */
1777
1778
1779     rStatus = kalIoctl(prGlueInfo,
1780             wlanoidQueryXmitError,
1781             &u4XmitError,
1782             sizeof(UINT_32),
1783             TRUE,
1784             TRUE,
1785             TRUE,
1786                          &u4BufLen);
1787
1788     rStatus = kalIoctl(prGlueInfo,
1789             wlanoidQueryXmitOk,
1790             &u4XmitOk,
1791             sizeof(UINT_32),
1792             TRUE,
1793             TRUE,
1794             TRUE,
1795             &u4BufLen);
1796     rStatus = kalIoctl(prGlueInfo,
1797             wlanoidQueryRcvOk,
1798             &u4RecvOk,
1799             sizeof(UINT_32),
1800             TRUE,
1801             TRUE,
1802             TRUE,
1803             &u4BufLen);
1804     rStatus = kalIoctl(prGlueInfo,
1805             wlanoidQueryRcvError,
1806             &u4RecvError,
1807             sizeof(UINT_32),
1808             TRUE,
1809             TRUE,
1810             TRUE,
1811             &u4BufLen);
1812     prGlueInfo->rNetDevStats.rx_packets = u4RecvOk;
1813     prGlueInfo->rNetDevStats.tx_packets = u4XmitOk;
1814     prGlueInfo->rNetDevStats.tx_errors  = u4XmitError;
1815     prGlueInfo->rNetDevStats.rx_errors  = u4RecvError;
1816     //prGlueInfo->rNetDevStats.rx_bytes   = rCustomNetDevStats.u4RxBytes;
1817     //prGlueInfo->rNetDevStats.tx_bytes   = rCustomNetDevStats.u4TxBytes;
1818     //prGlueInfo->rNetDevStats.rx_errors  = rCustomNetDevStats.u4RxErrors;
1819     //prGlueInfo->rNetDevStats.multicast  = rCustomNetDevStats.u4Multicast;
1820     #endif
1821     //prGlueInfo->rNetDevStats.rx_packets = 0;
1822     //prGlueInfo->rNetDevStats.tx_packets = 0;
1823     prGlueInfo->rNetDevStats.tx_errors  = 0;
1824     prGlueInfo->rNetDevStats.rx_errors  = 0;
1825     //prGlueInfo->rNetDevStats.rx_bytes   = 0;
1826     //prGlueInfo->rNetDevStats.tx_bytes   = 0;
1827     prGlueInfo->rNetDevStats.rx_errors  = 0;
1828     prGlueInfo->rNetDevStats.multicast  = 0;
1829
1830     return &prGlueInfo->rNetDevStats;
1831
1832 } /* end of wlanGetStats() */
1833
1834 /*----------------------------------------------------------------------------*/
1835 /*!
1836 * \brief A function for prDev->init
1837 *
1838 * \param[in] prDev      Pointer to struct net_device.
1839 *
1840 * \retval 0         The execution of wlanInit succeeds.
1841 * \retval -ENXIO    No such device.
1842 */
1843 /*----------------------------------------------------------------------------*/
1844 static int
1845 wlanInit(
1846     struct net_device *prDev
1847     )
1848 {
1849     P_GLUE_INFO_T prGlueInfo = NULL;
1850
1851     if (!prDev) {
1852         return -ENXIO;
1853     }
1854
1855     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
1856 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 12)
1857     INIT_DELAYED_WORK(&workq, wlanSetMulticastListWorkQueue);
1858 #else
1859     INIT_DELAYED_WORK(&workq, wlanSetMulticastListWorkQueue, NULL);
1860 #endif
1861
1862     return 0; /* success */
1863 } /* end of wlanInit() */
1864
1865
1866 /*----------------------------------------------------------------------------*/
1867 /*!
1868 * \brief A function for prDev->uninit
1869 *
1870 * \param[in] prDev      Pointer to struct net_device.
1871 *
1872 * \return (none)
1873 */
1874 /*----------------------------------------------------------------------------*/
1875 static void
1876 wlanUninit(
1877     struct net_device *prDev
1878     )
1879 {
1880     return;
1881 } /* end of wlanUninit() */
1882
1883
1884 /*----------------------------------------------------------------------------*/
1885 /*!
1886 * \brief A function for prDev->open
1887 *
1888 * \param[in] prDev      Pointer to struct net_device.
1889 *
1890 * \retval 0     The execution of wlanOpen succeeds.
1891 * \retval < 0   The execution of wlanOpen failed.
1892 */
1893 /*----------------------------------------------------------------------------*/
1894 static int
1895 wlanOpen(
1896     struct net_device *prDev
1897     )
1898 {
1899     ASSERT(prDev);
1900
1901 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26)
1902     netif_tx_start_all_queues(prDev);
1903 #else
1904     netif_start_queue(prDev);
1905 #endif
1906
1907     return 0; /* success */
1908 } /* end of wlanOpen() */
1909
1910
1911 /*----------------------------------------------------------------------------*/
1912 /*!
1913 * \brief A function for prDev->stop
1914 *
1915 * \param[in] prDev      Pointer to struct net_device.
1916 *
1917 * \retval 0     The execution of wlanStop succeeds.
1918 * \retval < 0   The execution of wlanStop failed.
1919 */
1920 /*----------------------------------------------------------------------------*/
1921 static int
1922 wlanStop(
1923     struct net_device *prDev
1924     )
1925 {
1926     P_GLUE_INFO_T prGlueInfo = NULL;
1927     struct cfg80211_scan_request *prScanRequest = NULL;
1928     GLUE_SPIN_LOCK_DECLARATION();
1929
1930     ASSERT(prDev);
1931
1932     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
1933
1934     /* CFG80211 down */
1935     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
1936     if(prGlueInfo->prScanRequest != NULL) {
1937         prScanRequest = prGlueInfo->prScanRequest;
1938         prGlueInfo->prScanRequest = NULL;
1939     }
1940     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
1941
1942     if(prScanRequest) {
1943         cfg80211_scan_done(prScanRequest, TRUE);
1944     }
1945
1946 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26)
1947     netif_tx_stop_all_queues(prDev);
1948 #else
1949     netif_stop_queue(prDev);
1950 #endif
1951
1952     return 0; /* success */
1953 } /* end of wlanStop() */
1954
1955
1956 /*----------------------------------------------------------------------------*/
1957 /*!
1958  * \brief Update Channel table for cfg80211 for Wi-Fi Direct based on current country code
1959  *
1960  * \param[in] prGlueInfo      Pointer to glue info
1961  *
1962  * \return   none
1963  */
1964 /*----------------------------------------------------------------------------*/
1965 VOID
1966 wlanUpdateChannelTable(
1967     P_GLUE_INFO_T prGlueInfo
1968     )
1969 {
1970     UINT_8 i, j;
1971     UINT_8 ucNumOfChannel;
1972     RF_CHANNEL_INFO_T aucChannelList[ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_channels)];
1973
1974     // 1. Disable all channel
1975     for(i = 0; i < ARRAY_SIZE(mtk_2ghz_channels); i++) {
1976         mtk_2ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED;
1977     }
1978
1979     for(i = 0; i < ARRAY_SIZE(mtk_5ghz_channels); i++) {
1980         mtk_5ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED;
1981     }
1982
1983     // 2. Get current domain channel list
1984     rlmDomainGetChnlList(prGlueInfo->prAdapter,
1985             BAND_NULL,
1986             ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_channels),
1987             &ucNumOfChannel,
1988             aucChannelList);
1989
1990     // 3. Enable specific channel based on domain channel list
1991     for(i = 0; i < ucNumOfChannel; i++) {
1992         switch(aucChannelList[i].eBand) {
1993         case BAND_2G4:
1994             for(j = 0 ; j < ARRAY_SIZE(mtk_2ghz_channels) ; j++) {
1995                 if(mtk_2ghz_channels[j].hw_value == aucChannelList[i].ucChannelNum) {
1996                     mtk_2ghz_channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
1997                     break;
1998                 }
1999             }
2000             break;
2001
2002         case BAND_5G:
2003             for(j = 0 ; j < ARRAY_SIZE(mtk_5ghz_channels) ; j++) {
2004                 if(mtk_5ghz_channels[j].hw_value == aucChannelList[i].ucChannelNum) {
2005                     mtk_5ghz_channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
2006                     break;
2007                 }
2008             }
2009             break;
2010
2011         default:
2012             break;
2013         }
2014     }
2015
2016     return;
2017 }
2018
2019
2020 /*----------------------------------------------------------------------------*/
2021 /*!
2022 * \brief Register the device to the kernel and return the index.
2023 *
2024 * \param[in] prDev      Pointer to struct net_device.
2025 *
2026 * \retval 0     The execution of wlanNetRegister succeeds.
2027 * \retval < 0   The execution of wlanNetRegister failed.
2028 */
2029 /*----------------------------------------------------------------------------*/
2030 static INT_32
2031 wlanNetRegister(
2032     struct wireless_dev *prWdev
2033     )
2034 {
2035     P_GLUE_INFO_T prGlueInfo;
2036     INT_32 i4DevIdx = -1;
2037
2038     ASSERT(prWdev);
2039
2040
2041     do {
2042         if (!prWdev) {
2043             break;
2044         }
2045
2046         prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
2047
2048         if ((i4DevIdx = wlanGetDevIdx(prWdev->netdev)) < 0) {
2049             DBGLOG(INIT, ERROR, ("wlanNetRegister: net_device number exceeds.\n"));
2050             break;
2051         }
2052
2053         /* adjust channel support status */
2054         wlanUpdateChannelTable((P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy));
2055
2056         if (wiphy_register(prWdev->wiphy) < 0) {
2057             DBGLOG(INIT, ERROR, ("wlanNetRegister: wiphy context is not registered.\n"));
2058             wlanClearDevIdx(prWdev->netdev);
2059             i4DevIdx = -1;
2060         }
2061
2062         if(register_netdev(prWdev->netdev) < 0) {
2063             DBGLOG(INIT, ERROR, ("wlanNetRegister: net_device context is not registered.\n"));
2064
2065             wiphy_unregister(prWdev->wiphy);
2066             wlanClearDevIdx(prWdev->netdev);
2067             i4DevIdx = -1;
2068         }
2069
2070         if(i4DevIdx != -1) {
2071             prGlueInfo->fgIsRegistered = TRUE;
2072         }
2073     }
2074     while(FALSE);
2075
2076     return i4DevIdx; /* success */
2077 } /* end of wlanNetRegister() */
2078
2079
2080 /*----------------------------------------------------------------------------*/
2081 /*!
2082 * \brief Unregister the device from the kernel
2083 *
2084 * \param[in] prWdev      Pointer to struct net_device.
2085 *
2086 * \return (none)
2087 */
2088 /*----------------------------------------------------------------------------*/
2089 static VOID
2090 wlanNetUnregister(
2091     struct wireless_dev *prWdev
2092     )
2093 {
2094     P_GLUE_INFO_T prGlueInfo;
2095
2096     if (!prWdev) {
2097         DBGLOG(INIT, ERROR, ("wlanNetUnregister: The device context is NULL\n"));
2098         return;
2099     }
2100
2101     prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
2102
2103     wlanClearDevIdx(prWdev->netdev);
2104     unregister_netdev(prWdev->netdev);
2105     wiphy_unregister(prWdev->wiphy);
2106
2107     prGlueInfo->fgIsRegistered = FALSE;
2108
2109     DBGLOG(INIT, INFO, ("unregister wireless_dev(0x%p)\n", prWdev));
2110
2111     return;
2112 } /* end of wlanNetUnregister() */
2113
2114
2115 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
2116 static const struct net_device_ops wlan_netdev_ops = {
2117         .ndo_open               = wlanOpen,
2118         .ndo_stop               = wlanStop,
2119 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
2120     .ndo_set_rx_mode = wlanSetMulticastList,
2121 #else
2122         .ndo_set_multicast_list = wlanSetMulticastList,
2123 #endif
2124         .ndo_get_stats          = wlanGetStats,
2125         .ndo_do_ioctl           = wlanDoIOCTL,
2126         .ndo_start_xmit         = wlanHardStartXmit,
2127         .ndo_init               = wlanInit,
2128         .ndo_uninit             = wlanUninit,
2129     .ndo_select_queue = wlanSelectQueue,
2130 };
2131 #endif
2132
2133 /*----------------------------------------------------------------------------*/
2134 /*!
2135 * \brief A method for creating Linux NET4 struct net_device object and the
2136 *        private data(prGlueInfo and prAdapter). Setup the IO address to the HIF.
2137 *        Assign the function pointer to the net_device object
2138 *
2139 * \param[in] pvData     Memory address for the device
2140 *
2141 * \retval Not null      The wireless_dev object.
2142 * \retval NULL          Fail to create wireless_dev object
2143 */
2144 /*----------------------------------------------------------------------------*/
2145 static struct lock_class_key rSpinKey[SPIN_LOCK_NUM];
2146 static struct wireless_dev *
2147 wlanNetCreate(
2148     PVOID pvData
2149     )
2150 {
2151     struct wireless_dev *prWdev = NULL;
2152     P_GLUE_INFO_T prGlueInfo =  NULL;
2153     P_ADAPTER_T prAdapter = NULL;
2154     UINT_32 i;
2155     struct device *prDev;
2156
2157     //4 <1.1> Create wireless_dev
2158     prWdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2159     DBGLOG(INIT, INFO, ("wireless_dev prWdev(0x%p) allocated\n", prWdev));
2160     if (!prWdev) {
2161         DBGLOG(INIT, ERROR, ("Allocating memory to wireless_dev context failed\n"));
2162         return NULL;
2163     }
2164
2165     //4 <1.2> Create wiphy
2166     prWdev->wiphy = wiphy_new(&mtk_wlan_ops, sizeof(GLUE_INFO_T));
2167     DBGLOG(INIT, INFO, ("wiphy (0x%p) allocated\n", prWdev->wiphy));
2168     if (!prWdev->wiphy) {
2169         DBGLOG(INIT, ERROR, ("Allocating memory to wiphy device failed\n"));
2170         kfree(prWdev);
2171         return NULL;
2172     }
2173
2174     //4 <1.3> co-relate wiphy & prDev
2175 #if MTK_WCN_HIF_SDIO
2176     mtk_wcn_hif_sdio_get_dev(*((MTK_WCN_HIF_SDIO_CLTCTX *)pvData), &prDev);
2177 #else
2178     prDev = &((struct sdio_func *) pvData)->dev;
2179 #endif
2180     if (!prDev) {
2181         printk(KERN_ALERT DRV_NAME "unable to get struct dev for wlan\n");
2182     }
2183     set_wiphy_dev(prWdev->wiphy, prDev);
2184
2185     //4 <1.4> configure wireless_dev & wiphy
2186     prWdev->iftype = NL80211_IFTYPE_STATION;
2187     prWdev->wiphy->max_scan_ssids   = 1;    /* FIXME: for combo scan */
2188     prWdev->wiphy->max_scan_ie_len = 512;
2189     prWdev->wiphy->interface_modes  = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2190     prWdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mtk_band_2ghz;
2191     //for the WPS probe request suband issue
2192     //prWdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mtk_band_5ghz;
2193     prWdev->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
2194     prWdev->wiphy->signal_type      = CFG80211_SIGNAL_TYPE_MBM;
2195     prWdev->wiphy->cipher_suites    = (const u32 *)mtk_cipher_suites;
2196     prWdev->wiphy->n_cipher_suites  = ARRAY_SIZE(mtk_cipher_suites);
2197 #if LINUX_VERSION_CODE > KERNEL_VERSION(3, 2, 0)
2198     prWdev->wiphy->flags            = WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_SUPPORTS_FW_ROAM;
2199 #else
2200     prWdev->wiphy->flags            = WIPHY_FLAG_CUSTOM_REGULATORY;
2201     printk(KERN_ALERT DRV_NAME "Not support WIPHY_FLAG_SUPPORTS_FW_ROAM\n");
2202 #endif
2203
2204     //4 <2> Create Glue structure
2205     prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
2206     if (!prGlueInfo) {
2207         DBGLOG(INIT, ERROR, ("Allocating memory to glue layer failed\n"));
2208         goto netcreate_err;
2209     }
2210
2211     //4 <3> Initial Glue structure
2212     //4 <3.1> create net device
2213     if (PowerOnIFname==0){
2214     prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, ether_setup, CFG_MAX_TXQ_NUM);
2215         }
2216         else {
2217     prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), LEGACY_IN_AP_MODE, ether_setup, CFG_MAX_TXQ_NUM);
2218                 }
2219     DBGLOG(INIT, INFO, ("net_device prDev(0x%p) allocated\n", prGlueInfo->prDevHandler));
2220     if (!prGlueInfo->prDevHandler) {
2221         DBGLOG(INIT, ERROR, ("Allocating memory to net_device context failed\n"));
2222         goto netcreate_err;
2223     }
2224
2225     //4 <3.1.1> initialize net device varaiables
2226     *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->prDevHandler)) = prGlueInfo;
2227
2228     prGlueInfo->prDevHandler->netdev_ops = &wlan_netdev_ops;
2229 #ifdef CONFIG_WIRELESS_EXT
2230     prGlueInfo->prDevHandler->wireless_handlers = &wext_handler_def;
2231 #endif
2232     netif_carrier_off(prGlueInfo->prDevHandler);
2233     netif_tx_stop_all_queues(prGlueInfo->prDevHandler);
2234
2235     //4 <3.1.2> co-relate with wiphy bi-directionally
2236     prGlueInfo->prDevHandler->ieee80211_ptr = prWdev;
2237 #if CFG_TCP_IP_CHKSUM_OFFLOAD
2238     prGlueInfo->prDevHandler->features = NETIF_F_HW_CSUM;
2239 #endif
2240     prWdev->netdev = prGlueInfo->prDevHandler;
2241
2242     //4 <3.1.3> co-relate net device & prDev
2243     SET_NETDEV_DEV(prGlueInfo->prDevHandler, wiphy_dev(prWdev->wiphy));
2244
2245     //4 <3.2> initiali glue variables
2246     prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED;
2247     prGlueInfo->ePowerState = ParamDeviceStateD0;
2248     prGlueInfo->fgIsMacAddrOverride = FALSE;
2249     prGlueInfo->fgIsRegistered = FALSE;
2250     prGlueInfo->prScanRequest = NULL;
2251
2252     init_completion(&prGlueInfo->rScanComp);
2253     init_completion(&prGlueInfo->rHaltComp);
2254     init_completion(&prGlueInfo->rPendComp);
2255 #if 0//LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)
2256         init_completion(&prGlueInfo->rMgmtTxComp);
2257         atomic_set(&prGlueInfo->rMgmtTxAto, 0);
2258 #endif
2259 #if CFG_ENABLE_WIFI_DIRECT
2260     init_completion(&prGlueInfo->rSubModComp);
2261 #endif
2262
2263     /* initialize timer for OID timeout checker */
2264     kalOsTimerInitialize(prGlueInfo, kalTimeoutHandler);
2265
2266     for (i = 0; i < SPIN_LOCK_NUM; i++) {
2267         spin_lock_init(&prGlueInfo->rSpinLock[i]);
2268         lockdep_set_class(&prGlueInfo->rSpinLock[i], &rSpinKey[i]);
2269     }
2270
2271     /* initialize semaphore for ioctl */
2272     sema_init(&prGlueInfo->ioctl_sem, 1);
2273
2274     /* initialize semaphore for ioctl */
2275     sema_init(&g_halt_sem, 1);
2276     g_u4HaltFlag = 0;
2277
2278     //4 <4> Create Adapter structure
2279     prAdapter = (P_ADAPTER_T) wlanAdapterCreate(prGlueInfo);
2280
2281     if (!prAdapter) {
2282         DBGLOG(INIT, ERROR, ("Allocating memory to adapter failed\n"));
2283         goto netcreate_err;
2284     }
2285
2286     prGlueInfo->prAdapter = prAdapter;
2287
2288 #ifdef CONFIG_CFG80211_WEXT
2289     //4 <5> Use wireless extension to replace IOCTL
2290     prWdev->wiphy->wext = &wext_handler_def;
2291 #endif
2292
2293     goto netcreate_done;
2294
2295 netcreate_err:
2296     if (NULL != prAdapter) {
2297         wlanAdapterDestroy(prAdapter);
2298         prAdapter = NULL;
2299     }
2300
2301     if (NULL != prGlueInfo->prDevHandler) {
2302         free_netdev(prGlueInfo->prDevHandler);
2303         prGlueInfo->prDevHandler = NULL;
2304     }
2305
2306     if (NULL != prWdev->wiphy) {
2307         wiphy_free(prWdev->wiphy);
2308         prWdev->wiphy = NULL;
2309     }
2310
2311     if (NULL != prWdev) {
2312         /* Free net_device and private data, which are allocated by
2313          * alloc_netdev().
2314          */
2315         kfree(prWdev);
2316         prWdev = NULL;
2317     }
2318
2319 netcreate_done:
2320
2321     return prWdev;
2322 } /* end of wlanNetCreate() */
2323
2324
2325 /*----------------------------------------------------------------------------*/
2326 /*!
2327 * \brief Destroying the struct net_device object and the private data.
2328 *
2329 * \param[in] prWdev      Pointer to struct wireless_dev.
2330 *
2331 * \return (none)
2332 */
2333 /*----------------------------------------------------------------------------*/
2334 static VOID
2335 wlanNetDestroy(
2336     struct wireless_dev *prWdev
2337     )
2338 {
2339     P_GLUE_INFO_T prGlueInfo = NULL;
2340
2341     ASSERT(prWdev);
2342
2343     if (!prWdev) {
2344         DBGLOG(INIT, ERROR, ("wlanNetDestroy: The device context is NULL\n"));
2345         return;
2346     }
2347
2348     /* prGlueInfo is allocated with net_device */
2349     prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
2350     ASSERT(prGlueInfo);
2351
2352     /* destroy kal OS timer */
2353     kalCancelTimer(prGlueInfo);
2354
2355     glClearHifInfo(prGlueInfo);
2356
2357     wlanAdapterDestroy(prGlueInfo->prAdapter);
2358     prGlueInfo->prAdapter = NULL;
2359
2360     /* Free net_device and private data, which are allocated by alloc_netdev().
2361      */
2362     free_netdev(prWdev->netdev);
2363     wiphy_free(prWdev->wiphy);
2364
2365     kfree(prWdev);
2366
2367     return;
2368 } /* end of wlanNetDestroy() */
2369
2370 #ifndef CONFIG_X86
2371 UINT_8 g_aucBufIpAddr[32] = {0};
2372
2373 static void wlanEarlySuspend(void)
2374 {
2375     struct net_device *prDev = NULL;
2376     P_GLUE_INFO_T prGlueInfo = NULL;
2377     UINT_8  ip[4] = { 0 };
2378     UINT_32 u4NumIPv4 = 0;
2379 #ifdef  CONFIG_IPV6
2380     UINT_8  ip6[16] = { 0 };     // FIX ME: avoid to allocate large memory in stack
2381     UINT_32 u4NumIPv6 = 0;
2382 #endif
2383     UINT_32 i;
2384     P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr;
2385
2386     DBGLOG(INIT, INFO, ("*********wlanEarlySuspend************\n"));
2387
2388     // <1> Sanity check and acquire the net_device
2389     ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES);
2390     prDev = arWlanDevInfo[u4WlanDevNum-1].prDev;
2391     ASSERT(prDev);
2392
2393 fgIsUnderEarlierSuspend = true;
2394
2395     // <2> get the IPv4 address
2396     if(!prDev || !(prDev->ip_ptr)||\
2397         !((struct in_device *)(prDev->ip_ptr))->ifa_list||\
2398         !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))){
2399         DBGLOG(INIT, INFO, ("ip is not avaliable.\n"));
2400         return;
2401     }
2402
2403     // <3> acquire the prGlueInfo
2404     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
2405     ASSERT(prGlueInfo);
2406
2407     // <4> copy the IPv4 address
2408     kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip));
2409     DBGLOG(INIT, INFO, ("ip is %d.%d.%d.%d\n",
2410             ip[0],ip[1],ip[2],ip[3]));
2411
2412     // todo: traverse between list to find whole sets of IPv4 addresses
2413     if (!((ip[0] == 0) &&
2414          (ip[1] == 0) &&
2415          (ip[2] == 0) &&
2416          (ip[3] == 0))) {
2417         u4NumIPv4++;
2418     }
2419
2420 #ifdef  CONFIG_IPV6
2421     // <5> get the IPv6 address
2422     if(!prDev || !(prDev->ip6_ptr)||\
2423         !((struct in_device *)(prDev->ip6_ptr))->ifa_list||\
2424         !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))){
2425         DBGLOG(INIT, INFO, ("ipv6 is not avaliable.\n"));
2426         return;
2427     }
2428     // <6> copy the IPv6 address
2429     kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
2430     DBGLOG(INIT, INFO, ("ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
2431             ip6[0],ip6[1],ip6[2],ip6[3],
2432             ip6[4],ip6[5],ip6[6],ip6[7],
2433             ip6[8],ip6[9],ip6[10],ip6[11],
2434             ip6[12],ip6[13],ip6[14],ip6[15]
2435             ));
2436
2437     // todo: traverse between list to find whole sets of IPv6 addresses
2438     if (!((ip6[0] == 0) &&
2439          (ip6[1] == 0) &&
2440          (ip6[2] == 0) &&
2441          (ip6[3] == 0) &&
2442          (ip6[4] == 0) &&
2443          (ip6[5] == 0))) {
2444         //u4NumIPv6++;
2445     }
2446
2447 #endif
2448
2449     // <7> set up the ARP filter
2450     {
2451         WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
2452         UINT_32 u4SetInfoLen = 0;
2453 //        UINT_8 aucBuf[32] = {0};
2454         UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress);
2455         P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST)g_aucBufIpAddr;//aucBuf;
2456         P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress;
2457
2458         kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
2459
2460         prParamNetAddrList->u4AddressCount = u4NumIPv4 + u4NumIPv6;
2461         prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
2462         for (i = 0; i < u4NumIPv4; i++) {
2463             prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP);//4;;
2464             prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;;
2465 #if 0
2466             kalMemCopy(prParamNetAddr->aucAddress, ip, sizeof(ip));
2467             prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(ip));
2468             u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip);
2469 #else
2470             prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP)prParamNetAddr->aucAddress;
2471             kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip));
2472             prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS));
2473             u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS);
2474 #endif
2475         }
2476 #ifdef  CONFIG_IPV6
2477         for (i = 0; i < u4NumIPv6; i++) {
2478             prParamNetAddr->u2AddressLength = 6;;
2479             prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;;
2480             kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6));
2481             prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(ip6));
2482             u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6);
2483        }
2484 #endif
2485         ASSERT(u4Len <= sizeof(g_aucBufIpAddr/*aucBuf*/));
2486
2487         rStatus = kalIoctl(prGlueInfo,
2488                 wlanoidSetNetworkAddress,
2489                 (PVOID)prParamNetAddrList,
2490                 u4Len,
2491                 FALSE,
2492                 FALSE,
2493                 TRUE,
2494                 FALSE,
2495                 &u4SetInfoLen);
2496
2497         if (rStatus != WLAN_STATUS_SUCCESS) {
2498             DBGLOG(INIT, INFO, ("set HW pattern filter fail 0x%lx\n", rStatus));
2499         }
2500     }
2501 }
2502
2503 static void wlanLateResume(void)
2504 {
2505     struct net_device *prDev = NULL;
2506     P_GLUE_INFO_T prGlueInfo = NULL;
2507     UINT_8  ip[4] = { 0 };
2508 #ifdef  CONFIG_IPV6
2509     UINT_8  ip6[16] = { 0 };     // FIX ME: avoid to allocate large memory in stack
2510 #endif
2511
2512     DBGLOG(INIT, INFO, ("*********wlanLateResume************\n"));
2513
2514     // <1> Sanity check and acquire the net_device
2515     ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES);
2516     prDev = arWlanDevInfo[u4WlanDevNum-1].prDev;
2517     ASSERT(prDev);
2518
2519 fgIsUnderEarlierSuspend = false;
2520
2521     // <2> get the IPv4 address
2522     if(!prDev || !(prDev->ip_ptr)||\
2523         !((struct in_device *)(prDev->ip_ptr))->ifa_list||\
2524         !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))){
2525         DBGLOG(INIT, INFO, ("ip is not avaliable.\n"));
2526         return;
2527     }
2528
2529     // <3> acquire the prGlueInfo
2530     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
2531     ASSERT(prGlueInfo);
2532
2533     // <4> copy the IPv4 address
2534     kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip));
2535     DBGLOG(INIT, INFO, ("ip is %d.%d.%d.%d\n",
2536             ip[0],ip[1],ip[2],ip[3]));
2537
2538 #ifdef  CONFIG_IPV6
2539     // <5> get the IPv6 address
2540     if(!prDev || !(prDev->ip6_ptr)||\
2541         !((struct in_device *)(prDev->ip6_ptr))->ifa_list||\
2542         !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))){
2543         DBGLOG(INIT, INFO, ("ipv6 is not avaliable.\n"));
2544         return;
2545     }
2546     // <6> copy the IPv6 address
2547     kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
2548     DBGLOG(INIT, INFO, ("ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
2549             ip6[0],ip6[1],ip6[2],ip6[3],
2550             ip6[4],ip6[5],ip6[6],ip6[7],
2551             ip6[8],ip6[9],ip6[10],ip6[11],
2552             ip6[12],ip6[13],ip6[14],ip6[15]
2553             ));
2554 #endif
2555     // <7> clear the ARP filter
2556     {
2557         WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
2558         UINT_32 u4SetInfoLen = 0;
2559 //        UINT_8 aucBuf[32] = {0};
2560         UINT_32 u4Len = sizeof(PARAM_NETWORK_ADDRESS_LIST);
2561         P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST)g_aucBufIpAddr;//aucBuf;
2562
2563         kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
2564
2565         prParamNetAddrList->u4AddressCount = 0;
2566         prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
2567
2568         ASSERT(u4Len <= sizeof(g_aucBufIpAddr/*aucBuf*/));
2569         rStatus = kalIoctl(prGlueInfo,
2570                 wlanoidSetNetworkAddress,
2571                 (PVOID)prParamNetAddrList,
2572                 u4Len,
2573                 FALSE,
2574                 FALSE,
2575                 TRUE,
2576                 FALSE,
2577                 &u4SetInfoLen);
2578
2579         if (rStatus != WLAN_STATUS_SUCCESS) {
2580             DBGLOG(INIT, INFO, ("set HW pattern filter fail 0x%lx\n", rStatus));
2581         }
2582     }
2583 }
2584
2585 #if defined(CONFIG_HAS_EARLYSUSPEND)
2586 static struct early_suspend mt6620_early_suspend_desc = {
2587     .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN,
2588 };
2589
2590 static void wlan_early_suspend(struct early_suspend *h)
2591 {
2592     DBGLOG(INIT, INFO, ("*********wlan_early_suspend************\n"));
2593     wlanEarlySuspend();
2594 }
2595
2596 static void wlan_late_resume(struct early_suspend *h)
2597 {
2598     DBGLOG(INIT, INFO, ("*********wlan_late_resume************\n"));
2599     wlanLateResume();
2600 }
2601 #endif //defined(CONFIG_HAS_EARLYSUSPEND)
2602 #endif //! CONFIG_X86
2603
2604 /*----------------------------------------------------------------------------*/
2605 /*!
2606 * \brief Wlan probe function. This function probes and initializes the device.
2607 *
2608 * \param[in] pvData     data passed by bus driver init function
2609 *                           _HIF_EHPI: NULL
2610 *                           _HIF_SDIO: sdio bus driver handle
2611 *
2612 * \retval 0 Success
2613 * \retval negative value Failed
2614 */
2615 /*----------------------------------------------------------------------------*/
2616 /*mtk80707 rollback to aosp hal*/
2617 typedef int (*set_p2p_mode)(struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUC_T p2pmode);
2618 extern void register_set_p2p_mode_handler(set_p2p_mode handler);
2619
2620 int set_p2p_mode_handler(struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUC_T p2pmode) {
2621         P_GLUE_INFO_T prGlueInfo  = *((P_GLUE_INFO_T *)netdev_priv(netdev));
2622         PARAM_CUSTOM_P2P_SET_STRUC_T rSetP2P;
2623     WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
2624         UINT_32 u4BufLen = 0;
2625
2626     rSetP2P.u4Enable = p2pmode.u4Enable;
2627     rSetP2P.u4Mode = p2pmode.u4Mode;
2628
2629     if(!rSetP2P.u4Enable) {
2630         p2pNetUnregister(prGlueInfo, FALSE);
2631     }
2632
2633     rWlanStatus = kalIoctl(prGlueInfo,
2634                         wlanoidSetP2pMode,
2635                         (PVOID)&rSetP2P,
2636                         sizeof(PARAM_CUSTOM_P2P_SET_STRUC_T),
2637                         FALSE,
2638                         FALSE,
2639                         TRUE,
2640                         FALSE,
2641                         &u4BufLen);
2642         printk("set_p2p_mode_handler ret = %d\n", rWlanStatus);
2643     if(rSetP2P.u4Enable) {
2644         p2pNetRegister(prGlueInfo, TRUE);
2645     }
2646         //return ((rWlanStatus == WLAN_STATUS_SUCCESS) ? 0 : -1);
2647         return 0;
2648 }
2649 /*endof mtk80707*/
2650
2651 static INT_32
2652 wlanProbe(
2653     PVOID pvData
2654     )
2655 {
2656     struct wireless_dev *prWdev = NULL;
2657     P_WLANDEV_INFO_T prWlandevInfo = NULL;
2658     INT_32 i4DevIdx = 0;
2659     P_GLUE_INFO_T prGlueInfo = NULL;
2660     P_ADAPTER_T prAdapter = NULL;
2661     INT_32 i4Status = 0;
2662     BOOL bRet = FALSE;
2663
2664
2665     do {
2666 #if DBG
2667         int i;
2668         /* Initialize DEBUG CLASS of each module */
2669         for (i = 0; i < DBG_MODULE_NUM; i++) {
2670             aucDebugModule[i] = DBG_CLASS_ERROR | \
2671                                 DBG_CLASS_WARN | \
2672                                 DBG_CLASS_STATE | \
2673                                 DBG_CLASS_TRACE | \
2674                                 DBG_CLASS_EVENT;
2675             //aucDebugModule[i] = 0;
2676         }
2677 #if 0
2678         aucDebugModule[DBG_INIT_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2679         aucDebugModule[DBG_ARB_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2680         aucDebugModule[DBG_JOIN_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2681         //aucDebugModule[DBG_RX_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2682         aucDebugModule[DBG_TX_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2683         aucDebugModule[DBG_NIC_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2684         aucDebugModule[DBG_HAL_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2685         aucDebugModule[DBG_KEVIN_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO | DBG_CLASS_TEMP;
2686         aucDebugModule[DBG_SCAN_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2687         aucDebugModule[DBG_REQ_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2688         //aucDebugModule[DBG_MGT_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2689         aucDebugModule[DBG_RSN_IDX] |= DBG_CLASS_TRACE;
2690         aucDebugModule[DBG_ROAMING_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2691 #endif
2692 #endif /* DBG */
2693
2694         //4 <1> Initialize the IO port of the interface
2695         /*  GeorgeKuo: pData has different meaning for _HIF_XXX:
2696          * _HIF_EHPI: pointer to memory base variable, which will be
2697          *      initialized by glBusInit().
2698          * _HIF_SDIO: bus driver handle
2699          */
2700
2701         bRet = glBusInit(pvData);
2702
2703         /* Cannot get IO address from interface */
2704         if (FALSE == bRet) {
2705             DBGLOG(INIT, ERROR, (KERN_ALERT "wlanProbe: glBusInit() fail\n"));
2706             i4Status = -EIO;
2707             break;
2708         }
2709
2710         //4 <2> Create network device, Adapter, KalInfo, prDevHandler(netdev)
2711         if ((prWdev = wlanNetCreate(pvData)) == NULL) {
2712             DBGLOG(INIT, ERROR, ("wlanProbe: No memory for dev and its private\n"));
2713             i4Status = -ENOMEM;
2714             break;
2715         }
2716
2717         //4 <2.5> Set the ioaddr to HIF Info
2718         prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
2719         gPrDev = prGlueInfo->prDevHandler;
2720         glSetHifInfo(prGlueInfo, (UINT_32) pvData);
2721
2722
2723         /* main thread is created in this function */
2724         init_waitqueue_head(&prGlueInfo->waitq);
2725         //
2726
2727         QUEUE_INITIALIZE(&prGlueInfo->rCmdQueue);
2728         QUEUE_INITIALIZE(&prGlueInfo->rTxQueue);
2729
2730
2731
2732         //prGlueInfo->main_thread = kthread_run(tx_thread, prGlueInfo->prDevHandler, "tx_thread");
2733
2734         //4 <4> Setup IRQ
2735         prWlandevInfo = &arWlanDevInfo[i4DevIdx];
2736
2737         i4Status = glBusSetIrq(prWdev->netdev, NULL, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev)));
2738
2739         if (i4Status != WLAN_STATUS_SUCCESS) {
2740             DBGLOG(INIT, ERROR, ("wlanProbe: Set IRQ error\n"));
2741             break;
2742         }
2743
2744         prGlueInfo->i4DevIdx = i4DevIdx;
2745
2746         prAdapter = prGlueInfo->prAdapter;
2747
2748         prGlueInfo->u4ReadyFlag = 0;
2749
2750 #if CFG_TCP_IP_CHKSUM_OFFLOAD
2751         prAdapter->u4CSUMFlags = (CSUM_OFFLOAD_EN_TX_TCP | CSUM_OFFLOAD_EN_TX_UDP | CSUM_OFFLOAD_EN_TX_IP);
2752 #endif
2753
2754         //4 <5> Start Device
2755         //
2756 #if CFG_ENABLE_FW_DOWNLOAD
2757         /* before start adapter, we need to open and load firmware */
2758         {
2759             UINT_32 u4FwSize = 0;
2760             PVOID prFwBuffer = NULL;
2761             P_REG_INFO_T prRegInfo = &prGlueInfo->rRegInfo;
2762
2763             //P_REG_INFO_T prRegInfo = (P_REG_INFO_T) kmalloc(sizeof(REG_INFO_T), GFP_KERNEL);
2764             kalMemSet(prRegInfo, 0, sizeof(REG_INFO_T));
2765             prRegInfo->u4StartAddress = CFG_FW_START_ADDRESS;
2766             prRegInfo->u4LoadAddress =  CFG_FW_LOAD_ADDRESS;
2767
2768             // Load NVRAM content to REG_INFO_T
2769             glLoadNvram(prGlueInfo, prRegInfo);
2770
2771             //kalMemCopy(&prGlueInfo->rRegInfo, prRegInfo, sizeof(REG_INFO_T));
2772
2773             prRegInfo->u4PowerMode = CFG_INIT_POWER_SAVE_PROF;
2774             prRegInfo->fgEnArpFilter = TRUE;
2775
2776             if (kalFirmwareImageMapping(prGlueInfo, &prFwBuffer, &u4FwSize) == NULL) {
2777                 i4Status = -EIO;
2778                 goto bailout;
2779             } else {
2780                 if (wlanAdapterStart(prAdapter, prRegInfo,  prFwBuffer, u4FwSize) != WLAN_STATUS_SUCCESS) {
2781                     i4Status = -EIO;
2782                 }
2783             }
2784
2785             kalFirmwareImageUnmapping(prGlueInfo, NULL, prFwBuffer);
2786
2787 bailout:
2788             //kfree(prRegInfo);
2789
2790             if (i4Status < 0) {
2791                 break;
2792             }
2793         }
2794 #else
2795         //P_REG_INFO_T prRegInfo = (P_REG_INFO_T) kmalloc(sizeof(REG_INFO_T), GFP_KERNEL);
2796         kalMemSet(&prGlueInfo->rRegInfo, 0, sizeof(REG_INFO_T));
2797         P_REG_INFO_T prRegInfo = &prGlueInfo->rRegInfo;
2798
2799         // Load NVRAM content to REG_INFO_T
2800         glLoadNvram(prGlueInfo, prRegInfo);
2801
2802         prRegInfo->u4PowerMode = CFG_INIT_POWER_SAVE_PROF;
2803
2804         if (wlanAdapterStart(prAdapter, prRegInfo, NULL, 0) != WLAN_STATUS_SUCCESS) {
2805             i4Status = -EIO;
2806             break;
2807         }
2808 #endif
2809         if(TRUE == prAdapter->fgEnable5GBand)
2810                 prWdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mtk_band_5ghz;
2811         prGlueInfo->main_thread = kthread_run(tx_thread, prGlueInfo->prDevHandler, "tx_thread");
2812
2813         /* set MAC address */
2814         {
2815             WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
2816             struct sockaddr MacAddr;
2817             UINT_32 u4SetInfoLen = 0;
2818
2819             rStatus = kalIoctl(prGlueInfo,
2820                     wlanoidQueryCurrentAddr,
2821                     &MacAddr.sa_data,
2822                     PARAM_MAC_ADDR_LEN,
2823                     TRUE,
2824                     TRUE,
2825                     TRUE,
2826                     FALSE,
2827                     &u4SetInfoLen);
2828
2829             if (rStatus != WLAN_STATUS_SUCCESS) {
2830                 DBGLOG(INIT, WARN, ("set MAC addr fail 0x%lx\n", rStatus));
2831                 prGlueInfo->u4ReadyFlag = 0;
2832             } else {
2833                 memcpy(prGlueInfo->prDevHandler->dev_addr, &MacAddr.sa_data, ETH_ALEN);
2834                 memcpy(prGlueInfo->prDevHandler->perm_addr, prGlueInfo->prDevHandler->dev_addr, ETH_ALEN);
2835
2836                 /* card is ready */
2837                 prGlueInfo->u4ReadyFlag = 1;
2838 #if CFG_SHOW_MACADDR_SOURCE
2839                 DBGLOG(INIT, INFO, ("MAC address: "MACSTR, MAC2STR(&MacAddr.sa_data)));
2840 #endif
2841             }
2842         }
2843
2844
2845 #if CFG_TCP_IP_CHKSUM_OFFLOAD
2846         /* set HW checksum offload */
2847         {
2848             WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
2849             UINT_32 u4CSUMFlags = CSUM_OFFLOAD_EN_ALL;
2850             UINT_32 u4SetInfoLen = 0;
2851
2852             rStatus = kalIoctl(prGlueInfo,
2853                     wlanoidSetCSUMOffload,
2854                     (PVOID)&u4CSUMFlags,
2855                     sizeof(UINT_32),
2856                     FALSE,
2857                     FALSE,
2858                     TRUE,
2859                     FALSE,
2860                     &u4SetInfoLen);
2861
2862             if (rStatus != WLAN_STATUS_SUCCESS) {
2863                 DBGLOG(INIT, WARN, ("set HW checksum offload fail 0x%lx\n", rStatus));
2864             }
2865         }
2866 #endif
2867 #if CFG_ENABLE_WIFI_DIRECT
2868                 register_set_p2p_mode_handler(set_p2p_mode_handler);
2869 #endif
2870
2871         //4 <3> Register the card
2872         if ((i4DevIdx = wlanNetRegister(prWdev)) < 0){
2873             i4Status = -ENXIO;
2874             DBGLOG(INIT, ERROR, ("wlanProbe: Cannot register the net_device context to the kernel\n"));
2875             break;
2876         }
2877
2878         //4 <6> Initialize /proc filesystem
2879 #ifdef WLAN_INCLUDE_PROC
2880         if ( (i4Status = procInitProcfs(prDev, NIC_DEVICE_ID_LOW)) < 0) {
2881             DBGLOG(INIT, ERROR, ("wlanProbe: init procfs failed\n"));
2882             break;
2883         }
2884 #endif /* WLAN_INCLUDE_PROC */
2885
2886 #if CFG_ENABLE_BT_OVER_WIFI
2887         prGlueInfo->rBowInfo.fgIsNetRegistered = FALSE;
2888         prGlueInfo->rBowInfo.fgIsRegistered = FALSE;
2889         glRegisterAmpc(prGlueInfo);
2890 #endif
2891
2892 #if CFG_ENABLE_WIFI_DIRECT
2893         /*wlan is launched*/
2894         prGlueInfo->prAdapter->fgIsWlanLaunched = TRUE;
2895         /*if p2p module is inserted, notify tx_thread to init p2p network*/
2896         if(rSubModHandler[P2P_MODULE].subModInit) {
2897             wlanSubModInit(prGlueInfo);
2898         }
2899                 
2900
2901 #endif
2902     }
2903     while (FALSE);
2904
2905     return i4Status;
2906 } /* end of wlanProbe() */
2907
2908
2909 /*----------------------------------------------------------------------------*/
2910 /*!
2911 * \brief A method to stop driver operation and release all resources. Following
2912 *        this call, no frame should go up or down through this interface.
2913 *
2914 * \return (none)
2915 */
2916 /*----------------------------------------------------------------------------*/
2917 static VOID
2918 wlanRemove(
2919     VOID
2920     )
2921 {
2922     struct net_device *prDev = NULL;
2923     P_WLANDEV_INFO_T prWlandevInfo = NULL;
2924     P_GLUE_INFO_T prGlueInfo = NULL;
2925     P_ADAPTER_T prAdapter = NULL;
2926
2927     DBGLOG(INIT, INFO, ("Remove wlan!\n"));
2928
2929
2930     //4 <0> Sanity check
2931     ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES);
2932     if (0 == u4WlanDevNum) {
2933         DBGLOG(INIT, INFO, ("0 == u4WlanDevNum\n"));
2934         return;
2935     }
2936         
2937         /*mtk80707 rollback aosp hal*/
2938         register_set_p2p_mode_handler(NULL);
2939
2940     prDev = arWlanDevInfo[u4WlanDevNum-1].prDev;
2941     prWlandevInfo = &arWlanDevInfo[u4WlanDevNum-1];
2942
2943     ASSERT(prDev);
2944     if (NULL == prDev) {
2945         DBGLOG(INIT, INFO, ("NULL == prDev\n"));
2946         return;
2947     }
2948
2949     prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
2950     ASSERT(prGlueInfo);
2951     if (NULL == prGlueInfo) {
2952         DBGLOG(INIT, INFO, ("NULL == prGlueInfo\n"));
2953         free_netdev(prDev);
2954         return;
2955     }
2956
2957
2958 #if CFG_ENABLE_WIFI_DIRECT
2959     prGlueInfo->prAdapter->fgIsWlanLaunched = FALSE;
2960     if(prGlueInfo->prAdapter->fgIsP2PRegistered) {
2961         p2pNetUnregister(prGlueInfo, TRUE);
2962         p2pRemove(prGlueInfo);
2963     }
2964
2965 #if 0
2966     prGlueInfo->prAdapter->fgIsWlanLaunched = FALSE;
2967     //if(prGlueInfo->prAdapter->fgIsP2PRegistered) {
2968     if (prGlueInfo->prP2PInfo) {
2969         //p2pRemove(prGlueInfo);
2970         if (prGlueInfo->prP2PInfo->prDevHandler) {
2971             free_netdev(prGlueInfo->prP2PInfo->prDevHandler);
2972             prGlueInfo->prP2PInfo->prDevHandler = NULL;
2973
2974         }
2975
2976
2977         if(!p2PFreeInfo(prGlueInfo)) {
2978            printk(KERN_ALERT DRV_NAME "Free memory for p2p FAILED\n");
2979            ASSERT(0);
2980            return;
2981         }
2982     }
2983 #endif
2984 #endif
2985
2986 #if CFG_ENABLE_BT_OVER_WIFI
2987     if(prGlueInfo->rBowInfo.fgIsNetRegistered) {
2988         bowNotifyAllLinkDisconnected(prGlueInfo->prAdapter);
2989         /*wait 300ms for BoW module to send deauth*/
2990         kalMsleep(300);
2991     }
2992 #endif
2993
2994     //4 <1> Stopping handling interrupt and free IRQ
2995     glBusFreeIrq(prDev, *((P_GLUE_INFO_T *) netdev_priv(prDev)));
2996
2997     kalMemSet(&(prGlueInfo->prAdapter->rWlanInfo), 0, sizeof(WLAN_INFO_T));
2998
2999     flush_delayed_work_sync(&workq);
3000
3001     down(&g_halt_sem);
3002     g_u4HaltFlag = 1;
3003
3004     //4 <2> Mark HALT, notify main thread to stop, and clean up queued requests
3005     prGlueInfo->u4Flag |= GLUE_FLAG_HALT;
3006     /* wake up main thread */
3007     wake_up_interruptible(&prGlueInfo->waitq);
3008     /* wait main thread stops */
3009     wait_for_completion_interruptible(&prGlueInfo->rHaltComp);
3010
3011     DBGLOG(INIT, INFO, ("mtk_sdiod stopped\n"));
3012
3013     //prGlueInfo->rHifInfo.main_thread = NULL;
3014     prGlueInfo->main_thread = NULL;
3015
3016 #if CFG_ENABLE_BT_OVER_WIFI
3017     if(prGlueInfo->rBowInfo.fgIsRegistered) {
3018         glUnregisterAmpc(prGlueInfo);
3019     }
3020 #endif
3021
3022
3023     //4 <3> Remove /proc filesystem.
3024 #ifdef WLAN_INCLUDE_PROC
3025     procRemoveProcfs(prDev, NIC_DEVICE_ID_LOW);
3026 #endif /* WLAN_INCLUDE_PROC */
3027
3028     //4 <4> wlanAdapterStop
3029     prAdapter = prGlueInfo->prAdapter;
3030
3031     wlanAdapterStop(prAdapter);
3032     DBGLOG(INIT, INFO, ("Number of Stalled Packets = %ld\n", prGlueInfo->i4TxPendingFrameNum));
3033
3034     //4 <5> Release the Bus
3035     glBusRelease(prDev);
3036
3037     up(&g_halt_sem);
3038
3039     //4 <6> Unregister the card
3040     wlanNetUnregister(prDev->ieee80211_ptr);
3041
3042     //4 <7> Destroy the device
3043     wlanNetDestroy(prDev->ieee80211_ptr);
3044     prDev = NULL;
3045         mt5931_power_off();
3046
3047     return;
3048 } /* end of wlanRemove() */
3049
3050
3051
3052 /*----------------------------------------------------------------------------*/
3053 /*!
3054 * \brief Driver entry point when the driver is configured as a Linux Module, and
3055 *        is called once at module load time, by the user-level modutils
3056 *        application: insmod or modprobe.
3057 *
3058 * \retval 0     Success
3059 */
3060 /*----------------------------------------------------------------------------*/
3061 //1 Module Entry Point
3062 static int __init initWlan(void)
3063 {
3064     int ret = 0;
3065
3066     DBGLOG(INIT, INFO, ("initWlan\n"));
3067
3068     //mt5931_power_on();
3069     //omap_mmc_update_mtk_card_status(1);  
3070
3071     /* memory pre-allocation */
3072     kalInitIOBuffer();
3073
3074
3075     //return ((glRegisterBus(wlanProbe, wlanRemove) == WLAN_STATUS_SUCCESS) ? 0: -EIO);
3076     ret = ((glRegisterBus(wlanProbe, wlanRemove) == WLAN_STATUS_SUCCESS) ? 0: -EIO);
3077
3078     if (ret == -EIO) {
3079         kalUninitIOBuffer();
3080         return ret;
3081     }
3082
3083
3084 #if defined(CONFIG_HAS_EARLYSUSPEND)
3085
3086     glRegisterEarlySuspend(&mt6620_early_suspend_desc, wlan_early_suspend, wlan_late_resume);
3087     wlanRegisterNotifier();
3088 #endif
3089
3090 #if (CFG_CHIP_RESET_SUPPORT)
3091     glResetInit();
3092 #endif
3093
3094     return ret;
3095 } /* end of initWlan() */
3096
3097
3098 /*----------------------------------------------------------------------------*/
3099 /*!
3100 * \brief Driver exit point when the driver as a Linux Module is removed. Called
3101 *        at module unload time, by the user level modutils application: rmmod.
3102 *        This is our last chance to clean up after ourselves.
3103 *
3104 * \return (none)
3105 */
3106 /*----------------------------------------------------------------------------*/
3107 //1 Module Leave Point
3108 static VOID __exit exitWlan(void)
3109 {
3110     //printk("remove %p\n", wlanRemove);
3111 #if defined(CONFIG_HAS_EARLYSUSPEND)
3112     glUnregisterEarlySuspend(&mt6620_early_suspend_desc);
3113 #endif
3114     wlanUnregisterNotifier();
3115
3116 #if CFG_CHIP_RESET_SUPPORT
3117     glResetUninit();
3118 #endif
3119
3120     glUnregisterBus(wlanRemove);
3121
3122     /* free pre-allocated memory */
3123     kalUninitIOBuffer();
3124        
3125     //mt5931_power_off();
3126     //omap_mmc_update_mtk_card_status(0);
3127
3128     DBGLOG(INIT, INFO, ("exitWlan\n"));
3129
3130     return;
3131 } /* end of exitWlan() */
3132
3133 module_init(initWlan);
3134 module_exit(exitWlan);
3135 #if 0
3136 /* export necessary symbol for p2p driver using */
3137 #if CFG_ENABLE_WIFI_DIRECT
3138 EXPORT_SYMBOL(wlanSubModRegisterInitExit);
3139 EXPORT_SYMBOL(wlanSubModExit);
3140 EXPORT_SYMBOL(wlanSubModInit);
3141
3142 EXPORT_SYMBOL(nicPmIndicateBssCreated);
3143 EXPORT_SYMBOL(rlmProcessAssocRsp);
3144 EXPORT_SYMBOL(kalSetEvent);
3145 EXPORT_SYMBOL(rlmBssInitForAPandIbss);
3146 EXPORT_SYMBOL(kalEnqueueCommand);
3147 EXPORT_SYMBOL(nicIncreaseTxSeqNum);
3148 EXPORT_SYMBOL(nicCmdEventQueryAddress);
3149 EXPORT_SYMBOL(bssCreateStaRecFromBssDesc);
3150 EXPORT_SYMBOL(rlmBssAborted);
3151 EXPORT_SYMBOL(cnmStaRecResetStatus);
3152 EXPORT_SYMBOL(mqmProcessAssocRsp);
3153 EXPORT_SYMBOL(nicTxReturnMsduInfo);
3154 EXPORT_SYMBOL(nicTxEnqueueMsdu);
3155 EXPORT_SYMBOL(wlanProcessSecurityFrame);
3156 EXPORT_SYMBOL(nicChannelNum2Freq);
3157 EXPORT_SYMBOL(nicUpdateBss);
3158 EXPORT_SYMBOL(wlanSendSetQueryCmd);
3159 EXPORT_SYMBOL(cnmStaRecAlloc);
3160 EXPORT_SYMBOL(cnmTimerInitTimer);
3161 EXPORT_SYMBOL(rateGetRateSetFromIEs);
3162 EXPORT_SYMBOL(nicOidCmdTimeoutCommon);
3163 EXPORT_SYMBOL(cnmStaRecChangeState);
3164 EXPORT_SYMBOL(rateGetDataRatesFromRateSet);
3165 EXPORT_SYMBOL(cnmMgtPktAlloc);
3166 EXPORT_SYMBOL(cnmMgtPktFree);
3167 EXPORT_SYMBOL(wextSrchDesiredWPAIE);
3168 EXPORT_SYMBOL(nicRxReturnRFB);
3169 EXPORT_SYMBOL(cnmTimerStartTimer);
3170 EXPORT_SYMBOL(cmdBufAllocateCmdInfo);
3171 EXPORT_SYMBOL(cnmGetStaRecByAddress);
3172 EXPORT_SYMBOL(nicMediaStateChange);
3173 EXPORT_SYMBOL(bssUpdateBeaconContent);
3174 EXPORT_SYMBOL(kalIoctl);
3175 EXPORT_SYMBOL(nicActivateNetwork);
3176 EXPORT_SYMBOL(nicDeactivateNetwork);
3177 EXPORT_SYMBOL(kalRandomNumber);
3178 EXPORT_SYMBOL(nicCmdEventSetCommon);
3179 EXPORT_SYMBOL(cnmTimerStopTimer);
3180 EXPORT_SYMBOL(nicIncreaseCmdSeqNum);
3181 EXPORT_SYMBOL(authSendDeauthFrame);
3182 EXPORT_SYMBOL(cnmMemAlloc);
3183 EXPORT_SYMBOL(nicPmIndicateBssAbort);
3184 EXPORT_SYMBOL(nicCmdEventSetIpAddress);
3185 EXPORT_SYMBOL(mboxSendMsg);
3186 EXPORT_SYMBOL(scanSearchBssDescByBssid);
3187 EXPORT_SYMBOL(bssRemoveStaRecFromClientList);
3188 EXPORT_SYMBOL(assocProcessRxDisassocFrame);
3189 EXPORT_SYMBOL(authProcessRxDeauthFrame);
3190 EXPORT_SYMBOL(cnmStaRecFree);
3191 EXPORT_SYMBOL(rNonHTPhyAttributes);
3192 EXPORT_SYMBOL(rNonHTApModeAttributes);
3193 EXPORT_SYMBOL(cnmMemFree);
3194 EXPORT_SYMBOL(wlanExportGlueInfo);
3195 EXPORT_SYMBOL(bssInitForAP);
3196 EXPORT_SYMBOL(nicPmIndicateBssConnected);
3197 EXPORT_SYMBOL(rlmRspGenerateHtOpIE);
3198 EXPORT_SYMBOL(bssGenerateExtSuppRate_IE);
3199 EXPORT_SYMBOL(rlmRspGenerateErpIE);
3200 EXPORT_SYMBOL(rlmRspGenerateHtCapIE);
3201 EXPORT_SYMBOL(cnmGetStaRecByIndex);
3202 EXPORT_SYMBOL(rsnGenerateWpaNoneIE);
3203 EXPORT_SYMBOL(rlmRspGenerateExtCapIE);
3204 EXPORT_SYMBOL(rsnGenerateRSNIE);
3205 EXPORT_SYMBOL(rsnParseRsnIE);
3206 #if CFG_SUPPORT_WPS
3207 EXPORT_SYMBOL(wextSrchDesiredWPSIE);
3208 #endif
3209 EXPORT_SYMBOL(mboxDummy);
3210 EXPORT_SYMBOL(saaFsmRunEventStart);
3211 EXPORT_SYMBOL(saaFsmRunEventAbort);
3212 EXPORT_SYMBOL(cnmP2PIsPermitted);
3213 EXPORT_SYMBOL(cnmBss40mBwPermitted);
3214 EXPORT_SYMBOL(mqmGenerateWmmParamIE);
3215 EXPORT_SYMBOL(cnmPreferredChannel);
3216 EXPORT_SYMBOL(bssAddStaRecToClientList);
3217 EXPORT_SYMBOL(nicQmUpdateWmmParms);
3218 EXPORT_SYMBOL(qmFreeAllByNetType);
3219 EXPORT_SYMBOL(wlanQueryInformation);
3220 EXPORT_SYMBOL(nicConfigPowerSaveProfile);
3221 EXPORT_SYMBOL(scanSearchExistingBssDesc);
3222 EXPORT_SYMBOL(scanAllocateBssDesc);
3223 EXPORT_SYMBOL(wlanProcessCommandQueue);
3224 EXPORT_SYMBOL(wlanAcquirePowerControl);
3225 EXPORT_SYMBOL(wlanReleasePowerControl);
3226 EXPORT_SYMBOL(wlanReleasePendingCMDbyNetwork);
3227 #if DBG
3228 EXPORT_SYMBOL(aucDebugModule);
3229 EXPORT_SYMBOL(fgIsBusAccessFailed);
3230 EXPORT_SYMBOL(allocatedMemSize);
3231 EXPORT_SYMBOL(dumpMemory8);
3232 EXPORT_SYMBOL(dumpMemory32);
3233 #endif
3234 EXPORT_SYMBOL(rlmDomainIsLegalChannel);
3235 EXPORT_SYMBOL(scnQuerySparseChannel);
3236 EXPORT_SYMBOL(rlmDomainGetChnlList);
3237 EXPORT_SYMBOL(p2pSetMulticastListWorkQueueWrapper);
3238 EXPORT_SYMBOL(nicUpdateRSSI);
3239 EXPORT_SYMBOL(nicCmdEventQueryLinkQuality);
3240 EXPORT_SYMBOL(kalGetMediaStateIndicated);
3241 EXPORT_SYMBOL(nicFreq2ChannelNum);
3242 EXPORT_SYMBOL(assocSendDisAssocFrame);
3243 EXPORT_SYMBOL(nicUpdateBeaconIETemplate);
3244 EXPORT_SYMBOL(rsnParseCheckForWFAInfoElem);
3245 EXPORT_SYMBOL(kalClearMgmtFramesByNetType);
3246 EXPORT_SYMBOL(kalClearSecurityFramesByNetType);
3247 EXPORT_SYMBOL(nicFreePendingTxMsduInfoByNetwork);
3248 EXPORT_SYMBOL(bssComposeBeaconProbeRespFrameHeaderAndFF);
3249 EXPORT_SYMBOL(bssBuildBeaconProbeRespFrameCommonIEs);
3250 EXPORT_SYMBOL(wlanoidSetWapiAssocInfo);
3251 EXPORT_SYMBOL(wlanoidSetWSCAssocInfo);
3252 #endif
3253 #endif