2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_init.c#7 $
6 \brief Main routines of Linux driver
8 This file contains the main routines of Linux driver for MediaTek Inc. 802.11
17 * 07 17 2012 yuche.tsai
21 * 07 17 2012 yuche.tsai
23 * Fix compile error for JB.
25 * 07 17 2012 yuche.tsai
27 * Let netdev bring up.
29 * 07 17 2012 yuche.tsai
31 * Compile no error before trial run.
33 * 06 13 2012 yuche.tsai
35 * Update maintrunk driver.
36 * Add support for driver compose assoc request frame.
38 * 05 25 2012 yuche.tsai
43 * [WCXRP00001237] [MT6620 Wi-Fi][Driver] Show MAC address and MAC address source for ACS's convenience
44 * show MAC address & source while initiliazation
48 * EXPORT_SYMBOL(rsnParseCheckForWFAInfoElem);.
52 * Snc CFG80211 modification for ICS migration from branch 2.2.
56 * Sync CFG80211 modification from branch 2,2.
60 * Enable CFG80211 Support.
62 * 12 22 2011 george.huang
63 * [WCXRP00000905] [MT6628 Wi-Fi][FW] Code refinement for ROM/ RAM module dependency
64 * using global variable instead of stack for setting wlanoidSetNetworkAddress(), due to buffer may be released before TX thread handling
66 * 11 18 2011 yuche.tsai
68 * CONFIG P2P support RSSI query, default turned off.
70 * 11 14 2011 yuche.tsai
71 * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue.
72 * Fix large network type index assert in FW issue.
76 * Fix compiling warning
78 * 11 11 2011 yuche.tsai
80 * Fix work thread cancel issue.
83 * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
84 * 1. eliminaite direct calls to printk in porting layer.
85 * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
87 * 10 06 2011 eddie.chen
88 * [WCXRP00001027] [MT6628 Wi-Fi][Firmware/Driver] Tx fragmentation
89 * Add rlmDomainGetChnlList symbol.
93 * Safer writng stype to avoid unitialized regitry structure
96 * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
97 * Avoid possible structure alignment problem
99 * 09 20 2011 chinglan.wang
100 * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test.
103 * 09 08 2011 cm.chang
104 * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
105 * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM
107 * 08 31 2011 cm.chang
108 * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
112 * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time
113 * expose scnQuerySparseChannel() for P2P-FSM.
116 * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time
117 * sparse channel detection:
118 * driver: collect sparse channel information with scan-done event
120 * 08 02 2011 yuche.tsai
121 * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a disconnecting device issue.
122 * Fix GO send deauth frame issue.
125 * [WCXRP00000839] [MT6620 Wi-Fi][Driver] Add the dumpMemory8 and dumpMemory32 EXPORT_SYMBOL
126 * Add the dumpMemory8 symbol export for debug mode.
128 * 07 06 2011 terry.wu
129 * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment
130 * Improve BoW connection establishment speed.
132 * 07 05 2011 yuche.tsai
133 * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue
134 * Export one symbol for enhancement.
136 * 06 13 2011 eddie.chen
137 * [WCXRP00000779] [MT6620 Wi-Fi][DRV] Add tx rx statistics in linux and use netif_rx_ni
138 * Add tx rx statistics and netif_rx_ni.
141 * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM
142 * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content.
145 * [WCXRP00000734] [MT6620 Wi-Fi][Driver] Pass PHY_PARAM in NVRAM to firmware domain
146 * pass PHY_PARAM in NVRAM from driver to firmware.
148 * 05 09 2011 jeffrey.chang
149 * [WCXRP00000710] [MT6620 Wi-Fi] Support pattern filter update function on IP address change
150 * support ARP filter through kernel notifier
152 * 05 03 2011 chinghwa.yu
153 * [WCXRP00000065] Update BoW design and settings
154 * Use kalMemAlloc to allocate event buffer for kalIndicateBOWEvent.
156 * 04 27 2011 george.huang
157 * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter
158 * Support P2P ARP filter setting on early suspend/ late resume
160 * 04 18 2011 terry.wu
161 * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
162 * Remove flag CFG_WIFI_DIRECT_MOVED.
164 * 04 15 2011 chinghwa.yu
165 * [WCXRP00000065] Update BoW design and settings
166 * Add BOW short range mode.
168 * 04 14 2011 yuche.tsai
169 * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case.
170 * Modify some driver connection flow or behavior to pass Sigma test more easier..
172 * 04 12 2011 cm.chang
173 * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
176 * 04 11 2011 george.huang
177 * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode
178 * export wlan functions to p2p
181 * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver
182 * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile settting for PC Linux driver
185 * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
186 * glBusFreeIrq() should use the same pvCookie as glBusSetIrq() or request_irq()/free_irq() won't work as a pair.
188 * 04 08 2011 eddie.chen
189 * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
193 * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
194 * 1. do not check for pvData inside wlanNetCreate() due to it is NULL for eHPI port
195 * 2. update perm_addr as well for MAC address
196 * 3. not calling check_mem_region() anymore for eHPI
197 * 4. correct MSC_CS macro for 0-based notation
200 * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for RESET_START and RESET_END events
204 * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for RESET_START and RESET_END events
205 * implement kernel-to-userspace communication via generic netlink socket for whole-chip resetting mechanism
208 * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
209 * apply multi-queue operation only for linux kernel > 2.6.26
212 * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build
213 * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment.
216 * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
217 * portability for compatible with linux 2.6.12.
220 * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
221 * improve portability for awareness of early version of linux kernel and wireless extension.
224 * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
225 * portability improvement
227 * 03 18 2011 jeffrey.chang
228 * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
229 * remove early suspend functions
232 * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage after system running for a long period
233 * reverse order to prevent probing racing.
236 * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage after system running for a long period
237 * 1. pre-allocate physical continuous buffer while module is being loaded
238 * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer
240 * The windows part remained the same as before, but added similiar APIs to hide the difference.
242 * 03 15 2011 jeffrey.chang
243 * [WCXRP00000558] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] refine the queue selection algorithm for WMM
244 * refine the queue_select function
247 * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3
248 * deprecate configuration used by MT6620 E2
250 * 03 10 2011 terry.wu
251 * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration
252 * Remove unnecessary assert and message.
254 * 03 08 2011 terry.wu
255 * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration
256 * Export nicQmUpdateWmmParms.
258 * 03 03 2011 jeffrey.chang
259 * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
260 * support concurrent network
262 * 03 03 2011 jeffrey.chang
263 * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
264 * modify net device relative functions to support multiple H/W queues
266 * 02 24 2011 george.huang
267 * [WCXRP00000495] [MT6620 Wi-Fi][FW] Support pattern filter for unwanted ARP frames
268 * Support ARP filter during suspended
271 * [WCXRP00000482] [MT6620 Wi-Fi][Driver] Simplify logic for checking NVRAM existence in driver domain
272 * simplify logic for checking NVRAM existence only once.
274 * 02 17 2011 terry.wu
275 * [WCXRP00000459] [MT6620 Wi-Fi][Driver] Fix deference null pointer problem in wlanRemove
276 * Fix deference a null pointer problem in wlanRemove.
278 * 02 16 2011 jeffrey.chang
282 * 02 16 2011 jeffrey.chang
284 * Add query ipv4 and ipv6 address during early suspend and late resume
286 * 02 15 2011 jeffrey.chang
288 * to support early suspend in android
290 * 02 11 2011 yuche.tsai
291 * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
292 * Add one more export symbol.
294 * 02 10 2011 yuche.tsai
295 * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
296 * Add RX deauthentication & disassociation process under Hot-Spot mode.
298 * 02 09 2011 terry.wu
299 * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules
300 * Halt p2p module init and exit until TxThread finished p2p register and unregister.
302 * 02 08 2011 george.huang
303 * [WCXRP00000422] [MT6620 Wi-Fi][Driver] support query power mode OID handler
304 * Support querying power mode OID.
306 * 02 08 2011 yuche.tsai
307 * [WCXRP00000421] [Volunteer Patch][MT6620][Driver] Fix incorrect SSID length Issue
308 * Export Deactivation Network.
310 * 02 01 2011 jeffrey.chang
311 * [WCXRP00000414] KAL Timer is not unregistered when driver not loaded
312 * Unregister the KAL timer during driver unloading
314 * 01 26 2011 cm.chang
315 * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
316 * Allocate system RAM if fixed message or mgmt buffer is not available
319 * [WCXRP00000371] [MT6620 Wi-Fi][Driver] make linux glue layer portable for Android 2.3.1 with Linux 2.6.35.7
320 * add compile option to check linux version 2.6.35 for different usage of system API to improve portability
323 * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP
324 * implementation of separate BT_OVER_WIFI data path.
327 * [WCXRP00000349] [MT6620 Wi-Fi][Driver] make kalIoctl() of linux port as a thread safe API to avoid potential issues due to multiple access
328 * use mutex to protect kalIoctl() for thread safe.
331 * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease physically continous memory demands
332 * separate kalMemAlloc() into virtually-continous and physically-continous type to ease slab system pressure
335 * [WCXRP00000265] [MT6620 Wi-Fi][Driver] Remove set_mac_address routine from legacy Wi-Fi Android driver
336 * remove set MAC address. MAC address is always loaded from NVRAM instead.
338 * 12 10 2010 kevin.huang
339 * [WCXRP00000128] [MT6620 Wi-Fi][Driver] Add proc support to Android Driver for debug and driver status check
340 * Add Linux Proc Support
342 * 11 01 2010 yarco.yang
343 * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform
344 * Add GPIO debug function
347 * [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
348 * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
349 * 2) Remove CNM CH-RECOVER event handling
350 * 3) cfg read/write API renamed with kal prefix for unified naming rules.
353 * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command
354 * 1) update NVRAM content template to ver 1.02
355 * 2) add compile option for querying NIC capability (default: off)
356 * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting
357 * 4) correct auto-rate compiler error under linux (treat warning as error)
358 * 5) simplify usage of NVRAM and REG_INFO_T
359 * 6) add version checking between driver and firmware
361 * 10 21 2010 chinghwa.yu
362 * [WCXRP00000065] Update BoW design and settings
365 * 10 19 2010 jeffrey.chang
366 * [WCXRP00000120] [MT6620 Wi-Fi][Driver] Refine linux kernel module to the license of MTK propietary and enable MTK HIF by default
367 * Refine linux kernel module to the license of MTK and enable MTK HIF
369 * 10 18 2010 jeffrey.chang
370 * [WCXRP00000106] [MT6620 Wi-Fi][Driver] Enable setting multicast callback in Android
374 * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android
375 * complete implementation of Android NVRAM access
377 * 09 27 2010 chinghwa.yu
378 * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings
379 * Update BCM/BoW design and settings.
382 * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item
383 * use firmware reported mac address right after wlanAdapterStart() as permanent address
385 * 09 21 2010 kevin.huang
386 * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
387 * Eliminate Linux Compile Warning
389 * 09 03 2010 kevin.huang
391 * Refine #include sequence and solve recursive/nested #include issue
395 * adding the wapi support for integration test.
397 * 08 18 2010 yarco.yang
399 * 1. Fixed HW checksum offload function not work under Linux issue.
400 * 2. Add debug message.
402 * 08 16 2010 yarco.yang
406 * 08 02 2010 jeffrey.chang
408 * 1) modify tx service thread to avoid busy looping
409 * 2) add spin lock declartion for linux build
411 * 07 29 2010 jeffrey.chang
413 * fix memory leak for module unloading
415 * 07 28 2010 jeffrey.chang
417 * 1) remove unused spinlocks
418 * 2) enable encyption ioctls
419 * 3) fix scan ioctl which may cause supplicant to hang
421 * 07 23 2010 jeffrey.chang
423 * bug fix: allocate regInfo when disabling firmware download
425 * 07 23 2010 jeffrey.chang
427 * use glue layer api to decrease or increase counter atomically
429 * 07 22 2010 jeffrey.chang
433 * 07 19 2010 jeffrey.chang
435 * modify cmd/data path for new design
439 * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
441 * 06 06 2010 kevin.huang
442 * [WPD00003832][MT6620 5931] Create driver base
443 * [MT6620 5931] Create driver base
445 * 05 26 2010 jeffrey.chang
446 * [WPD00003826]Initial import for Linux port
447 * 1) Modify set mac address code
448 * 2) remove power managment macro
451 * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
452 * implement basic wi-fi direct framework
454 * 05 07 2010 jeffrey.chang
455 * [WPD00003826]Initial import for Linux port
456 * prevent supplicant accessing driver during resume
459 * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
460 * add basic framework for implementating P2P driver hook.
462 * 04 27 2010 jeffrey.chang
463 * [WPD00003826]Initial import for Linux port
464 * 1) fix firmware download bug
465 * 2) remove query statistics for acelerating firmware download
467 * 04 27 2010 jeffrey.chang
468 * [WPD00003826]Initial import for Linux port
469 * follow Linux's firmware framework, and remove unused kal API
471 * 04 21 2010 jeffrey.chang
472 * [WPD00003826]Initial import for Linux port
473 * add for private ioctl support
475 * 04 19 2010 jeffrey.chang
476 * [WPD00003826]Initial import for Linux port
477 * Query statistics from firmware
479 * 04 19 2010 jeffrey.chang
480 * [WPD00003826]Initial import for Linux port
481 * modify tcp/ip checksum offload flags
483 * 04 16 2010 jeffrey.chang
484 * [WPD00003826]Initial import for Linux port
485 * fix tcp/ip checksum offload bug
488 * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
489 * add framework for BT-over-Wi-Fi support.
490 * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability
491 * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically
492 * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose
494 * 04 09 2010 jeffrey.chang
495 * [WPD00003826]Initial import for Linux port
498 * 04 07 2010 jeffrey.chang
499 * [WPD00003826]Initial import for Linux port
500 * Set MAC address from firmware
503 * [WPD00001943]Create WiFi test driver framework on WinXP
504 * rWlanInfo should be placed at adapter rather than glue due to most operations
505 * * * * * * are done in adapter layer.
507 * 04 07 2010 jeffrey.chang
508 * [WPD00003826]Initial import for Linux port
509 * (1)improve none-glue code portability
510 * * (2) disable set Multicast address during atomic context
512 * 04 06 2010 jeffrey.chang
513 * [WPD00003826]Initial import for Linux port
514 * adding debug module
517 * [WPD00003816][MT6620 Wi-Fi] Adding the security support
518 * modify the wapi related code for new driver's design.
520 * 03 30 2010 jeffrey.chang
521 * [WPD00003826]Initial import for Linux port
522 * emulate NDIS Pending OID facility
524 * 03 26 2010 jeffrey.chang
525 * [WPD00003826]Initial import for Linux port
526 * fix f/w download start and load address by using config.h
528 * 03 26 2010 jeffrey.chang
529 * [WPD00003826]Initial import for Linux port
530 * [WPD00003826] Initial import for Linux port
531 * adding firmware download support
533 * 03 24 2010 jeffrey.chang
534 * [WPD00003826]Initial import for Linux port
535 * initial import for Linux port
536 ** \main\maintrunk.MT5921\52 2009-10-27 22:49:59 GMT mtk01090
537 ** Fix compile error for Linux EHPI driver
538 ** \main\maintrunk.MT5921\51 2009-10-20 17:38:22 GMT mtk01090
539 ** Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests, and then stop hw.
540 ** \main\maintrunk.MT5921\50 2009-10-08 10:33:11 GMT mtk01090
541 ** Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input parameters and pointers.
542 ** \main\maintrunk.MT5921\49 2009-09-28 20:19:05 GMT mtk01090
543 ** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel.
544 ** \main\maintrunk.MT5921\48 2009-09-03 13:58:46 GMT mtk01088
545 ** remove non-used code
546 ** \main\maintrunk.MT5921\47 2009-09-03 11:40:25 GMT mtk01088
547 ** adding the module parameter for wapi
548 ** \main\maintrunk.MT5921\46 2009-08-18 22:56:41 GMT mtk01090
549 ** Add Linux SDIO (with mmc core) support.
550 ** Add Linux 2.6.21, 2.6.25, 2.6.26.
551 ** Fix compile warning in Linux.
552 ** \main\maintrunk.MT5921\45 2009-07-06 20:53:00 GMT mtk01088
553 ** adding the code to check the wapi 1x frame
554 ** \main\maintrunk.MT5921\44 2009-06-23 23:18:55 GMT mtk01090
555 ** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support
556 ** \main\maintrunk.MT5921\43 2009-02-16 23:46:51 GMT mtk01461
557 ** Revise the order of increasing u4TxPendingFrameNum because of CFG_TX_RET_TX_CTRL_EARLY
558 ** \main\maintrunk.MT5921\42 2009-01-22 13:11:59 GMT mtk01088
559 ** set the tid and 1x value at same packet reserved field
560 ** \main\maintrunk.MT5921\41 2008-10-20 22:43:53 GMT mtk01104
561 ** Fix wrong variable name "prDev" in wlanStop()
562 ** \main\maintrunk.MT5921\40 2008-10-16 15:37:10 GMT mtk01461
563 ** add handle WLAN_STATUS_SUCCESS in wlanHardStartXmit() for CFG_TX_RET_TX_CTRL_EARLY
564 ** \main\maintrunk.MT5921\39 2008-09-25 15:56:21 GMT mtk01461
565 ** Update driver for Code review
566 ** \main\maintrunk.MT5921\38 2008-09-05 17:25:07 GMT mtk01461
567 ** Update Driver for Code Review
568 ** \main\maintrunk.MT5921\37 2008-09-02 10:57:06 GMT mtk01461
569 ** Update driver for code review
570 ** \main\maintrunk.MT5921\36 2008-08-05 01:53:28 GMT mtk01461
571 ** Add support for linux statistics
572 ** \main\maintrunk.MT5921\35 2008-08-04 16:52:58 GMT mtk01461
573 ** Fix ASSERT if removing module in BG_SSID_SCAN state
574 ** \main\maintrunk.MT5921\34 2008-06-13 22:52:24 GMT mtk01461
575 ** Revise status code handling in wlanHardStartXmit() for WLAN_STATUS_SUCCESS
576 ** \main\maintrunk.MT5921\33 2008-05-30 18:56:53 GMT mtk01461
577 ** Not use wlanoidSetCurrentAddrForLinux()
578 ** \main\maintrunk.MT5921\32 2008-05-30 14:39:40 GMT mtk01461
579 ** Remove WMM Assoc Flag
580 ** \main\maintrunk.MT5921\31 2008-05-23 10:26:40 GMT mtk01084
581 ** modify wlanISR interface
582 ** \main\maintrunk.MT5921\30 2008-05-03 18:52:36 GMT mtk01461
583 ** Fix Unset Broadcast filter when setMulticast
584 ** \main\maintrunk.MT5921\29 2008-05-03 15:17:26 GMT mtk01461
585 ** Move Query Media Status to GLUE
586 ** \main\maintrunk.MT5921\28 2008-04-24 22:48:21 GMT mtk01461
587 ** Revise set multicast function by using windows oid style for LP own back
588 ** \main\maintrunk.MT5921\27 2008-04-24 12:00:08 GMT mtk01461
589 ** Fix multicast setting in Linux and add comment
590 ** \main\maintrunk.MT5921\26 2008-03-28 10:40:22 GMT mtk01461
591 ** Fix set mac address func in Linux
592 ** \main\maintrunk.MT5921\25 2008-03-26 15:37:26 GMT mtk01461
593 ** Add set MAC Address
594 ** \main\maintrunk.MT5921\24 2008-03-26 14:24:53 GMT mtk01461
595 ** For Linux, set net_device has feature with checksum offload by default
596 ** \main\maintrunk.MT5921\23 2008-03-11 14:50:52 GMT mtk01461
598 ** \main\maintrunk.MT5921\22 2008-02-29 15:35:20 GMT mtk01088
599 ** add 1x decide code for sw port control
600 ** \main\maintrunk.MT5921\21 2008-02-21 15:01:54 GMT mtk01461
601 ** Rearrange the set off place of GLUE spin lock in HardStartXmit
602 ** \main\maintrunk.MT5921\20 2008-02-12 23:26:50 GMT mtk01461
603 ** Add debug option - Packet Order for Linux and add debug level - Event
604 ** \main\maintrunk.MT5921\19 2007-12-11 00:11:12 GMT mtk01461
605 ** Fix SPIN_LOCK protection
606 ** \main\maintrunk.MT5921\18 2007-11-30 17:02:25 GMT mtk01425
607 ** 1. Set Rx multicast packets mode before setting the address list
608 ** \main\maintrunk.MT5921\17 2007-11-26 19:44:24 GMT mtk01461
609 ** Add OS_TIMESTAMP to packet
610 ** \main\maintrunk.MT5921\16 2007-11-21 15:47:20 GMT mtk01088
611 ** fixed the unload module issue
612 ** \main\maintrunk.MT5921\15 2007-11-07 18:37:38 GMT mtk01461
613 ** Fix compile warnning
614 ** \main\maintrunk.MT5921\14 2007-11-02 01:03:19 GMT mtk01461
615 ** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning
616 ** \main\maintrunk.MT5921\13 2007-10-30 10:42:33 GMT mtk01425
617 ** 1. Refine for multicast list
618 ** \main\maintrunk.MT5921\12 2007-10-25 18:08:13 GMT mtk01461
619 ** Add VOIP SCAN Support & Refine Roaming
620 ** Revision 1.4 2007/07/05 07:25:33 MTK01461
621 ** Add Linux initial code, modify doc, add 11BB, RF init code
623 ** Revision 1.3 2007/06/27 02:18:50 MTK01461
624 ** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API
626 ** Revision 1.2 2007/06/25 06:16:24 MTK01461
627 ** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API
631 /*******************************************************************************
632 * C O M P I L E R F L A G S
633 ********************************************************************************
636 /*******************************************************************************
637 * E X T E R N A L R E F E R E N C E S
638 ********************************************************************************
642 #include "wlan_lib.h"
644 #include "gl_cfg80211.h"
647 #if defined(CONFIG_WIFI_CONTROL_FUNC)
648 #include <linux/platform_device.h>
649 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
650 #include <linux/wlan_plat.h>
652 #include <linux/wifi_tiwlan.h>
654 #endif /* CONFIG_WIFI_CONTROL_FUNC */
656 /*******************************************************************************
658 ********************************************************************************
660 //#define MAX_IOREQ_NUM 10
662 int driver_start_ok = 0;
665 BOOLEAN fgIsUnderEarlierSuspend = false;
667 struct semaphore g_halt_sem;
668 int g_u4HaltFlag = 0;
671 /*******************************************************************************
673 ********************************************************************************
675 /* Tasklet mechanism is like buttom-half in Linux. We just want to
676 * send a signal to OS for interrupt defer processing. All resources
677 * are NOT allowed reentry, so txPacket, ISR-DPC and ioctl must avoid preempty.
679 typedef struct _WLANDEV_INFO_T {
680 struct net_device *prDev;
681 } WLANDEV_INFO_T, *P_WLANDEV_INFO_T;
683 /*******************************************************************************
684 * P U B L I C D A T A
685 ********************************************************************************
688 MODULE_AUTHOR(NIC_AUTHOR);
689 MODULE_DESCRIPTION(NIC_DESC);
690 MODULE_SUPPORTED_DEVICE(NIC_NAME);
693 keep OS wake up for 100ms after sdio interrupt happen,
694 make sure that RX & TX procedure isn't suspended
696 KAL_WAKE_LOCK_T isr_wakelock;
699 MODULE_LICENSE("MTK Propietary");
701 MODULE_LICENSE("GPL");
704 #define NIC_INF_NAME "wlan%d" /* interface name */
707 UINT_8 aucDebugModule[DBG_MODULE_NUM];
708 UINT_32 u4DebugModule = 0;
711 //4 2007/06/26, mikewu, now we don't use this, we just fix the number of wlan device to 1
712 static WLANDEV_INFO_T arWlanDevInfo[CFG_MAX_WLAN_DEVICES] = {{0}};
713 static UINT_32 u4WlanDevNum = 0; /* How many NICs coexist now */
715 /*******************************************************************************
716 * P R I V A T E D A T A
717 ********************************************************************************
719 #if CFG_ENABLE_WIFI_DIRECT
720 static SUB_MODULE_HANDLER rSubModHandler[SUB_MODULE_NUM] = {{NULL}};
723 #define CHAN2G(_channel, _freq, _flags) \
725 .band = IEEE80211_BAND_2GHZ, \
726 .center_freq = (_freq), \
727 .hw_value = (_channel), \
729 .max_antenna_gain = 0, \
732 static struct ieee80211_channel mtk_2ghz_channels[] = {
749 #define CHAN5G(_channel, _flags) \
751 .band = IEEE80211_BAND_5GHZ, \
752 .center_freq = 5000 + (5 * (_channel)), \
753 .hw_value = (_channel), \
755 .max_antenna_gain = 0, \
758 static struct ieee80211_channel mtk_5ghz_channels[] = {
759 CHAN5G(34, 0), CHAN5G(36, 0),
760 CHAN5G(38, 0), CHAN5G(40, 0),
761 CHAN5G(42, 0), CHAN5G(44, 0),
762 CHAN5G(46, 0), CHAN5G(48, 0),
763 CHAN5G(52, 0), CHAN5G(56, 0),
764 CHAN5G(60, 0), CHAN5G(64, 0),
765 CHAN5G(100, 0), CHAN5G(104, 0),
766 CHAN5G(108, 0), CHAN5G(112, 0),
767 CHAN5G(116, 0), CHAN5G(120, 0),
768 CHAN5G(124, 0), CHAN5G(128, 0),
769 CHAN5G(132, 0), CHAN5G(136, 0),
770 CHAN5G(140, 0), CHAN5G(149, 0),
771 CHAN5G(153, 0), CHAN5G(157, 0),
772 CHAN5G(161, 0), CHAN5G(165, 0),
773 CHAN5G(169, 0), CHAN5G(173, 0),
774 CHAN5G(184, 0), CHAN5G(188, 0),
775 CHAN5G(192, 0), CHAN5G(196, 0),
776 CHAN5G(200, 0), CHAN5G(204, 0),
777 CHAN5G(208, 0), CHAN5G(212, 0),
781 /* for cfg80211 - rate table */
782 static struct ieee80211_rate mtk_rates[] = {
783 RATETAB_ENT(10, 0x1000, 0),
784 RATETAB_ENT(20, 0x1001, 0),
785 RATETAB_ENT(55, 0x1002, 0),
786 RATETAB_ENT(110, 0x1003, 0), /* 802.11b */
787 RATETAB_ENT(60, 0x2000, 0),
788 RATETAB_ENT(90, 0x2001, 0),
789 RATETAB_ENT(120, 0x2002, 0),
790 RATETAB_ENT(180, 0x2003, 0),
791 RATETAB_ENT(240, 0x2004, 0),
792 RATETAB_ENT(360, 0x2005, 0),
793 RATETAB_ENT(480, 0x2006, 0),
794 RATETAB_ENT(540, 0x2007, 0), /* 802.11a/g */
797 #define mtk_a_rates (mtk_rates + 4)
798 #define mtk_a_rates_size (sizeof(mtk_rates) / sizeof(mtk_rates[0]) - 4)
799 #define mtk_g_rates (mtk_rates + 0)
800 #define mtk_g_rates_size (sizeof(mtk_rates) / sizeof(mtk_rates[0]) - 0)
802 #define MT6620_MCS_INFO \
804 .rx_mask = {0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0},\
806 .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \
809 #define MT6620_HT_CAP \
811 .ht_supported = true, \
812 .cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 \
813 | IEEE80211_HT_CAP_SM_PS \
814 | IEEE80211_HT_CAP_GRN_FLD \
815 | IEEE80211_HT_CAP_SGI_20 \
816 | IEEE80211_HT_CAP_SGI_40, \
817 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, \
818 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE, \
819 .mcs = MT6620_MCS_INFO, \
822 /* public for both Legacy Wi-Fi / P2P access */
823 struct ieee80211_supported_band mtk_band_2ghz = {
824 .band = IEEE80211_BAND_2GHZ,
825 .channels = mtk_2ghz_channels,
826 .n_channels = ARRAY_SIZE(mtk_2ghz_channels),
827 .bitrates = mtk_g_rates,
828 .n_bitrates = mtk_g_rates_size,
829 .ht_cap = MT6620_HT_CAP,
832 /* public for both Legacy Wi-Fi / P2P access */
833 struct ieee80211_supported_band mtk_band_5ghz = {
834 .band = IEEE80211_BAND_5GHZ,
835 .channels = mtk_5ghz_channels,
836 .n_channels = ARRAY_SIZE(mtk_5ghz_channels),
837 .bitrates = mtk_a_rates,
838 .n_bitrates = mtk_a_rates_size,
839 .ht_cap = MT6620_HT_CAP,
842 static const UINT_32 mtk_cipher_suites[] = {
843 /* keep WEP first, it may be removed below */
844 WLAN_CIPHER_SUITE_WEP40,
845 WLAN_CIPHER_SUITE_WEP104,
846 WLAN_CIPHER_SUITE_TKIP,
847 WLAN_CIPHER_SUITE_CCMP,
849 /* keep last -- depends on hw flags! */
850 WLAN_CIPHER_SUITE_AES_CMAC
853 static struct cfg80211_ops mtk_wlan_ops = {
854 .change_virtual_intf = mtk_cfg80211_change_iface,
855 .add_key = mtk_cfg80211_add_key,
856 .get_key = mtk_cfg80211_get_key,
857 .del_key = mtk_cfg80211_del_key,
858 .set_default_key = mtk_cfg80211_set_default_key,
859 .get_station = mtk_cfg80211_get_station,
860 .scan = mtk_cfg80211_scan,
861 .connect = mtk_cfg80211_connect,
862 .disconnect = mtk_cfg80211_disconnect,
863 .join_ibss = mtk_cfg80211_join_ibss,
864 .leave_ibss = mtk_cfg80211_leave_ibss,
865 .set_power_mgmt = mtk_cfg80211_set_power_mgmt,
866 .set_pmksa = mtk_cfg80211_set_pmksa,
867 .del_pmksa = mtk_cfg80211_del_pmksa,
868 .flush_pmksa = mtk_cfg80211_flush_pmksa,
870 /* Action Frame TX/RX */
871 .remain_on_channel = mtk_cfg80211_remain_on_channel,
872 .cancel_remain_on_channel = mtk_cfg80211_cancel_remain_on_channel,
873 .mgmt_tx = mtk_cfg80211_mgmt_tx,
874 .mgmt_tx_cancel_wait = mtk_cfg80211_mgmt_tx_cancel_wait,
875 #ifdef CONFIG_NL80211_TESTMODE
876 .testmode_cmd = mtk_cfg80211_testmode_cmd,
880 /*******************************************************************************
882 ********************************************************************************
885 /*******************************************************************************
886 * F U N C T I O N D E C L A R A T I O N S
887 ********************************************************************************
890 #if defined(CONFIG_HAS_EARLYSUSPEND)
891 extern int glRegisterEarlySuspend(
892 struct early_suspend *prDesc,
893 early_suspend_callback wlanSuspend,
894 late_resume_callback wlanResume);
896 extern int glUnregisterEarlySuspend(struct early_suspend *prDesc);
899 /*******************************************************************************
901 ********************************************************************************
905 * Functions for Android WiFi card detection
907 #if defined(CONFIG_WIFI_CONTROL_FUNC)
909 static int g_wifidev_registered = 0;
910 static struct semaphore wifi_control_sem;
911 static struct wifi_platform_data *wifi_control_data = NULL;
912 static struct resource *wifi_irqres = NULL;
914 static int wifi_add_dev(void);
915 static void wifi_del_dev(void);
917 #define ANDROID_ERR(x) printk x
918 #define ANDROID_TRACE(x) printk x
920 int wl_android_wifictrl_func_add(void)
923 sema_init(&wifi_control_sem, 0);
925 ret = wifi_add_dev();
927 ANDROID_ERR(("%s: platform_driver_register failed\n", __FUNCTION__));
930 g_wifidev_registered = 1;
932 /* Waiting callback after platform_driver_register is done or exit with error */
933 if (down_timeout(&wifi_control_sem, msecs_to_jiffies(1000)) != 0) {
935 ANDROID_ERR(("%s: platform_driver_register timeout\n", __FUNCTION__));
938 printk("wl_android_wifictrl_func_add success.\n");
942 void wl_android_wifictrl_func_del(void)
944 if (g_wifidev_registered)
947 g_wifidev_registered = 0;
951 int wifi_set_power(int on, unsigned long msec)
953 ANDROID_ERR(("%s = %d\n", __FUNCTION__, on));
954 if (wifi_control_data && wifi_control_data->set_power) {
955 wifi_control_data->set_power(on);
962 int wifi_set_reset(int on, unsigned long msec)
964 ANDROID_ERR(("%s = %d\n", __FUNCTION__, on));
965 if (wifi_control_data && wifi_control_data->set_reset) {
966 wifi_control_data->set_reset(on);
973 static int wifi_set_carddetect(int on)
975 ANDROID_ERR(("%s = %d\n", __FUNCTION__, on));
976 if (wifi_control_data && wifi_control_data->set_carddetect) {
977 wifi_control_data->set_carddetect(on);
982 static int wifi_probe(struct platform_device *pdev)
984 struct wifi_platform_data *wifi_ctrl =
985 (struct wifi_platform_data *)(pdev->dev.platform_data);
987 ANDROID_ERR(("## %s\n", __FUNCTION__));
988 wifi_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcmdhd_wlan_irq");
989 if (wifi_irqres == NULL)
990 wifi_irqres = platform_get_resource_byname(pdev,
991 IORESOURCE_IRQ, "bcm4329_wlan_irq");
992 wifi_control_data = wifi_ctrl;
994 //wifi_set_power(0, 0);
995 //wifi_set_reset(0, 10);
997 wifi_set_power(1, 0);
998 //wifi_set_reset(1, 12); /* Power On */
1000 wifi_set_carddetect(1); /* CardDetect (0->1) */
1002 up(&wifi_control_sem);
1006 static int wifi_remove(struct platform_device *pdev)
1008 struct wifi_platform_data *wifi_ctrl =
1009 (struct wifi_platform_data *)(pdev->dev.platform_data);
1011 ANDROID_ERR(("## %s\n", __FUNCTION__));
1012 wifi_control_data = wifi_ctrl;
1014 wifi_set_power(0, 0); /* Power Off */
1015 //wifi_set_reset(0, 0);
1017 wifi_set_carddetect(0); /* CardDetect (1->0) */
1022 static int wifi_suspend(struct platform_device *pdev, pm_message_t state)
1024 ANDROID_TRACE(("##> %s\n", __FUNCTION__));
1028 static int wifi_resume(struct platform_device *pdev)
1030 ANDROID_TRACE(("##> %s\n", __FUNCTION__));
1034 static struct platform_driver wifi_device = {
1035 .probe = wifi_probe,
1036 .remove = wifi_remove,
1037 .suspend = wifi_suspend,
1038 .resume = wifi_resume,
1040 .name = "bcmdhd_wlan",
1044 static struct platform_driver wifi_device_legacy = {
1045 .probe = wifi_probe,
1046 .remove = wifi_remove,
1047 .suspend = wifi_suspend,
1048 .resume = wifi_resume,
1050 .name = "bcm4329_wlan",
1054 static int wifi_add_dev(void)
1056 ANDROID_TRACE(("## Calling platform_driver_register\n"));
1057 platform_driver_register(&wifi_device);
1058 platform_driver_register(&wifi_device_legacy);
1062 static void wifi_del_dev(void)
1064 ANDROID_TRACE(("## Unregister platform_driver_register\n"));
1065 platform_driver_unregister(&wifi_device);
1066 platform_driver_unregister(&wifi_device_legacy);
1068 #endif /* defined(CONFIG_WIFI_CONTROL_FUNC) */
1070 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
1071 /*----------------------------------------------------------------------------*/
1073 * \brief Override the implementation of select queue
1075 * \param[in] dev Pointer to struct net_device
1076 * \param[in] skb Pointer to struct skb_buff
1080 /*----------------------------------------------------------------------------*/
1081 unsigned int _cfg80211_classify8021d(struct sk_buff *skb)
1083 unsigned int dscp = 0;
1085 /* skb->priority values from 256->263 are magic values
1086 * directly indicate a specific 802.1d priority. This is
1087 * to allow 802.1d priority to be passed directly in from
1091 if (skb->priority >= 256 && skb->priority <= 263) {
1092 return skb->priority - 256;
1094 switch (skb->protocol) {
1095 case htons(ETH_P_IP):
1096 dscp = ip_hdr(skb)->tos & 0xfc;
1103 static const UINT_16 au16Wlan1dToQueueIdx[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
1107 struct net_device *dev,
1108 struct sk_buff *skb)
1110 skb->priority = _cfg80211_classify8021d(skb);
1112 return au16Wlan1dToQueueIdx[skb->priority];
1117 /*----------------------------------------------------------------------------*/
1119 * \brief Load NVRAM data and translate it into REG_INFO_T
1121 * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T
1122 * \param[out] prRegInfo Pointer to struct REG_INFO_T
1126 /*----------------------------------------------------------------------------*/
1129 IN P_GLUE_INFO_T prGlueInfo,
1130 OUT P_REG_INFO_T prRegInfo
1140 if((!prGlueInfo) || (!prRegInfo)) {
1144 if(kalCfgDataRead16(prGlueInfo,
1145 sizeof(WIFI_CFG_PARAM_STRUCT) - sizeof(UINT_16),
1146 (PUINT_16)aucTmp) == TRUE) {
1147 prGlueInfo->fgNvramAvailable = TRUE;
1150 for (i = 0 ; i < sizeof(PARAM_MAC_ADDR_LEN) ; i += sizeof(UINT_16)) {
1151 kalCfgDataRead16(prGlueInfo,
1152 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucMacAddress) + i,
1153 (PUINT_16) (((PUINT_8)prRegInfo->aucMacAddr) + i));
1156 // load country code
1157 kalCfgDataRead16(prGlueInfo,
1158 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucCountryCode[0]),
1161 // cast to wide characters
1162 prRegInfo->au2CountryCode[0] = (UINT_16) aucTmp[0];
1163 prRegInfo->au2CountryCode[1] = (UINT_16) aucTmp[1];
1165 // load default normal TX power
1166 for (i = 0 ; i < sizeof(TX_PWR_PARAM_T) ; i += sizeof(UINT_16)) {
1167 kalCfgDataRead16(prGlueInfo,
1168 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, rTxPwr) + i,
1169 (PUINT_16) (((PUINT_8)&(prRegInfo->rTxPwr)) + i));
1172 // load feature flags
1173 kalCfgDataRead16(prGlueInfo,
1174 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucTxPwrValid),
1176 prRegInfo->ucTxPwrValid = aucTmp[0];
1177 prRegInfo->ucSupport5GBand = aucTmp[1];
1179 kalCfgDataRead16(prGlueInfo,
1180 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, uc2G4BwFixed20M),
1182 prRegInfo->uc2G4BwFixed20M = aucTmp[0];
1183 prRegInfo->uc5GBwFixed20M = aucTmp[1];
1185 kalCfgDataRead16(prGlueInfo,
1186 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucEnable5GBand),
1188 prRegInfo->ucEnable5GBand = aucTmp[0];
1190 /* load EFUSE overriding part */
1191 for (i = 0 ; i < sizeof(prRegInfo->aucEFUSE) ; i += sizeof(UINT_16)) {
1192 kalCfgDataRead16(prGlueInfo,
1193 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucEFUSE) + i,
1194 (PUINT_16) (((PUINT_8)&(prRegInfo->aucEFUSE)) + i));
1197 /* load band edge tx power control */
1198 kalCfgDataRead16(prGlueInfo,
1199 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, fg2G4BandEdgePwrUsed),
1201 prRegInfo->fg2G4BandEdgePwrUsed = (BOOLEAN)aucTmp[0];
1203 prRegInfo->cBandEdgeMaxPwrCCK = (INT_8)aucTmp[1];
1205 kalCfgDataRead16(prGlueInfo,
1206 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, cBandEdgeMaxPwrOFDM20),
1208 prRegInfo->cBandEdgeMaxPwrOFDM20 = (INT_8)aucTmp[0];
1209 prRegInfo->cBandEdgeMaxPwrOFDM40 = (INT_8)aucTmp[1];
1212 /* load regulation subbands */
1213 kalCfgDataRead16(prGlueInfo,
1214 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucRegChannelListMap),
1216 prRegInfo->eRegChannelListMap = (ENUM_REG_CH_MAP_T) aucTmp[0];
1217 prRegInfo->ucRegChannelListIndex = aucTmp[1];
1219 if (prRegInfo->eRegChannelListMap == REG_CH_MAP_CUSTOMIZED) {
1220 for (i = 0 ; i < MAX_SUBBAND_NUM; i++) {
1221 pucDest = (PUINT_8) &prRegInfo->rDomainInfo.rSubBand[i];
1222 for (j = 0; j < 6; j += sizeof(UINT_16)) {
1223 kalCfgDataRead16(prGlueInfo,
1224 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucRegSubbandInfo)
1228 *pucDest++ = aucTmp[0];
1229 *pucDest++ = aucTmp[1];
1235 prGlueInfo->fgNvramAvailable = FALSE;
1242 #if CFG_ENABLE_WIFI_DIRECT
1243 /*----------------------------------------------------------------------------*/
1245 * \brief called by txthread, run sub module init function
1247 * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T
1251 /*----------------------------------------------------------------------------*/
1254 P_GLUE_INFO_T prGlueInfo
1257 /*now, we only have p2p module*/
1258 if(rSubModHandler[P2P_MODULE].fgIsInited == FALSE) {
1259 rSubModHandler[P2P_MODULE].subModInit(prGlueInfo);
1260 rSubModHandler[P2P_MODULE].fgIsInited = TRUE;
1265 /*----------------------------------------------------------------------------*/
1267 * \brief called by txthread, run sub module exit function
1269 * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T
1273 /*----------------------------------------------------------------------------*/
1276 P_GLUE_INFO_T prGlueInfo
1279 /*now, we only have p2p module*/
1280 if(rSubModHandler[P2P_MODULE].fgIsInited == TRUE) {
1281 rSubModHandler[P2P_MODULE].subModExit(prGlueInfo);
1282 rSubModHandler[P2P_MODULE].fgIsInited = FALSE;
1286 /*----------------------------------------------------------------------------*/
1288 * \brief set sub module init flag, force TxThread to run sub modle init
1290 * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T
1294 /*----------------------------------------------------------------------------*/
1297 P_GLUE_INFO_T prGlueInfo
1300 //4 Mark HALT, notify main thread to finish current job
1301 prGlueInfo->u4Flag |= GLUE_FLAG_SUB_MOD_INIT;
1302 /* wake up main thread */
1303 wake_up_interruptible(&prGlueInfo->waitq);
1304 /* wait main thread finish sub module INIT*/
1305 wait_for_completion_interruptible(&prGlueInfo->rSubModComp);
1308 if(prGlueInfo->prAdapter->fgIsP2PRegistered) {
1309 p2pNetRegister(prGlueInfo);
1316 /*----------------------------------------------------------------------------*/
1318 * \brief set sub module exit flag, force TxThread to run sub modle exit
1320 * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T
1324 /*----------------------------------------------------------------------------*/
1327 P_GLUE_INFO_T prGlueInfo
1331 if(prGlueInfo->prAdapter->fgIsP2PRegistered) {
1332 p2pNetUnregister(prGlueInfo);
1336 //4 Mark HALT, notify main thread to finish current job
1337 prGlueInfo->u4Flag |= GLUE_FLAG_SUB_MOD_EXIT;
1338 /* wake up main thread */
1339 wake_up_interruptible(&prGlueInfo->waitq);
1340 /* wait main thread finish sub module EXIT */
1341 wait_for_completion_interruptible(&prGlueInfo->rSubModComp);
1347 /*----------------------------------------------------------------------------*/
1349 * \brief set by sub module, indicate sub module is already inserted
1351 * \param[in] rSubModInit, function pointer point to sub module init function
1352 * \param[in] rSubModExit, function pointer point to sub module exit function
1353 * \param[in] eSubModIdx, sub module index
1357 /*----------------------------------------------------------------------------*/
1359 wlanSubModRegisterInitExit(
1360 SUB_MODULE_INIT rSubModInit,
1361 SUB_MODULE_EXIT rSubModExit,
1362 ENUM_SUB_MODULE_IDX_T eSubModIdx
1365 rSubModHandler[eSubModIdx].subModInit = rSubModInit;
1366 rSubModHandler[eSubModIdx].subModExit = rSubModExit;
1367 rSubModHandler[eSubModIdx].fgIsInited = FALSE;
1371 /*----------------------------------------------------------------------------*/
1373 * \brief check wlan is launched or not
1377 * \return TRUE, wlan is already started
1378 * FALSE, wlan is not started yet
1380 /*----------------------------------------------------------------------------*/
1386 struct net_device *prDev = NULL;
1387 P_GLUE_INFO_T prGlueInfo = NULL;
1389 //4 <0> Sanity check
1390 ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES);
1391 if (0 == u4WlanDevNum) {
1395 prDev = arWlanDevInfo[u4WlanDevNum-1].prDev;
1398 if (NULL == prDev) {
1402 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
1404 if (NULL == prGlueInfo) {
1408 return prGlueInfo->prAdapter->fgIsWlanLaunched;
1413 /*----------------------------------------------------------------------------*/
1415 * \brief Export wlan GLUE_INFO_T pointer to p2p module
1417 * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T
1419 * \return TRUE: get GlueInfo pointer successfully
1420 * FALSE: wlan is not started yet
1422 /*---------------------------------------------------------------------------*/
1425 P_GLUE_INFO_T *prGlueInfoExpAddr
1428 struct net_device *prDev = NULL;
1429 P_GLUE_INFO_T prGlueInfo = NULL;
1431 if (0 == u4WlanDevNum) {
1435 prDev = arWlanDevInfo[u4WlanDevNum-1].prDev;
1436 if (NULL == prDev) {
1440 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
1441 if (NULL == prGlueInfo) {
1445 if(FALSE == prGlueInfo->prAdapter->fgIsWlanLaunched) {
1449 *prGlueInfoExpAddr = prGlueInfo;
1456 /*----------------------------------------------------------------------------*/
1458 * \brief Release prDev from wlandev_array and free tasklet object related to it.
1460 * \param[in] prDev Pointer to struct net_device
1464 /*----------------------------------------------------------------------------*/
1467 struct net_device *prDev
1474 for (i = 0; i < CFG_MAX_WLAN_DEVICES; i++) {
1475 if (arWlanDevInfo[i].prDev == prDev) {
1476 arWlanDevInfo[i].prDev = NULL;
1482 } /* end of wlanClearDevIdx() */
1485 /*----------------------------------------------------------------------------*/
1487 * \brief Allocate an unique interface index, net_device::ifindex member for this
1488 * wlan device. Store the net_device in wlandev_array, and initialize
1489 * tasklet object related to it.
1491 * \param[in] prDev Pointer to struct net_device
1493 * \retval >= 0 The device number.
1494 * \retval -1 Fail to get index.
1496 /*----------------------------------------------------------------------------*/
1499 struct net_device *prDev
1506 for (i = 0; i < CFG_MAX_WLAN_DEVICES; i++) {
1507 if (arWlanDevInfo[i].prDev == (struct net_device *) NULL) {
1508 /* Reserve 2 bytes space to store one digit of
1509 * device number and NULL terminator.
1511 arWlanDevInfo[i].prDev = prDev;
1518 } /* end of wlanGetDevIdx() */
1520 /*----------------------------------------------------------------------------*/
1522 * \brief A method of struct net_device, a primary SOCKET interface to configure
1523 * the interface lively. Handle an ioctl call on one of our devices.
1524 * Everything Linux ioctl specific is done here. Then we pass the contents
1525 * of the ifr->data to the request message handler.
1527 * \param[in] prDev Linux kernel netdevice
1529 * \param[in] prIFReq Our private ioctl request structure, typed for the generic
1530 * struct ifreq so we can use ptr to function
1532 * \param[in] cmd Command ID
1534 * \retval WLAN_STATUS_SUCCESS The IOCTL command is executed successfully.
1535 * \retval OTHER The execution of IOCTL command is failed.
1537 /*----------------------------------------------------------------------------*/
1540 struct net_device *prDev,
1541 struct ifreq *prIFReq,
1545 P_GLUE_INFO_T prGlueInfo = NULL;
1548 /* Verify input parameters for the following functions */
1549 ASSERT(prDev && prIFReq);
1550 if (!prDev || !prIFReq) {
1551 DBGLOG(INIT, WARN, ("%s Invalid input data\n", __FUNCTION__));
1555 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
1558 DBGLOG(INIT, WARN, ("%s No glue info\n", __FUNCTION__));
1562 if (prGlueInfo->u4ReadyFlag == 0) {
1566 printk ("ioctl %x\n", i4Cmd);
1568 if (i4Cmd == SIOCGIWPRIV) {
1569 /* 0x8B0D, get private ioctl table */
1570 ret = wext_get_priv(prDev, prIFReq);
1572 else if ((i4Cmd >= SIOCIWFIRST) && (i4Cmd < SIOCIWFIRSTPRIV)) {
1573 /* 0x8B00 ~ 0x8BDF, wireless extension region */
1574 ret = wext_support_ioctl(prDev, prIFReq, i4Cmd);
1576 else if ((i4Cmd >= SIOCIWFIRSTPRIV) && (i4Cmd < SIOCIWLASTPRIV)) {
1577 /* 0x8BE0 ~ 0x8BFF, private ioctl region */
1578 ret = priv_support_ioctl(prDev, prIFReq, i4Cmd);
1581 DBGLOG(INIT, WARN, ("Unexpected ioctl command: 0x%04x\n", i4Cmd));
1582 /* return 0 for safe? */
1586 } /* end of wlanDoIOCTL() */
1588 /*----------------------------------------------------------------------------*/
1590 * \brief This function is to set multicast list and set rx mode.
1592 * \param[in] prDev Pointer to struct net_device
1596 /*----------------------------------------------------------------------------*/
1598 static struct delayed_work workq;
1599 static struct net_device *gPrDev;
1602 wlanSetMulticastList (struct net_device *prDev)
1605 schedule_delayed_work(&workq, 0);
1608 /* FIXME: Since we cannot sleep in the wlanSetMulticastList, we arrange
1609 * another workqueue for sleeping. We don't want to block
1610 * tx_thread, so we can't let tx_thread to do this */
1613 wlanSetMulticastListWorkQueue (struct work_struct *work) {
1615 P_GLUE_INFO_T prGlueInfo = NULL;
1616 UINT_32 u4PacketFilter = 0;
1617 UINT_32 u4SetInfoLen;
1618 struct net_device *prDev = gPrDev;
1626 prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL;
1629 if (!prDev || !prGlueInfo) {
1630 DBGLOG(INIT, WARN, ("abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n",
1631 prDev, prGlueInfo));
1636 if (prDev->flags & IFF_PROMISC) {
1637 u4PacketFilter |= PARAM_PACKET_FILTER_PROMISCUOUS;
1640 if (prDev->flags & IFF_BROADCAST) {
1641 u4PacketFilter |= PARAM_PACKET_FILTER_BROADCAST;
1644 if (prDev->flags & IFF_MULTICAST) {
1645 if ((prDev->flags & IFF_ALLMULTI) ||
1646 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
1647 (netdev_mc_count(prDev) > MAX_NUM_GROUP_ADDR)) {
1649 (prDev->mc_count > MAX_NUM_GROUP_ADDR)) {
1652 u4PacketFilter |= PARAM_PACKET_FILTER_ALL_MULTICAST;
1655 u4PacketFilter |= PARAM_PACKET_FILTER_MULTICAST;
1661 if (kalIoctl(prGlueInfo,
1662 wlanoidSetCurrentPacketFilter,
1664 sizeof(u4PacketFilter),
1669 &u4SetInfoLen) != WLAN_STATUS_SUCCESS) {
1674 if (u4PacketFilter & PARAM_PACKET_FILTER_MULTICAST) {
1675 /* Prepare multicast address list */
1676 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
1677 struct netdev_hw_addr *ha;
1679 struct dev_mc_list *prMcList;
1681 PUINT_8 prMCAddrList = NULL;
1690 prMCAddrList = kalMemAlloc(MAX_NUM_GROUP_ADDR * ETH_ALEN, VIR_MEM_TYPE);
1692 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
1693 netdev_for_each_mc_addr(ha, prDev) {
1694 if(i < MAX_NUM_GROUP_ADDR) {
1695 memcpy((prMCAddrList + i * ETH_ALEN), ha->addr, ETH_ALEN);
1700 for (i = 0, prMcList = prDev->mc_list;
1701 (prMcList) && (i < prDev->mc_count) && (i < MAX_NUM_GROUP_ADDR);
1702 i++, prMcList = prMcList->next) {
1703 memcpy((prMCAddrList + i * ETH_ALEN), prMcList->dmi_addr, ETH_ALEN);
1709 kalIoctl(prGlueInfo,
1710 wlanoidSetMulticastList,
1719 kalMemFree(prMCAddrList, VIR_MEM_TYPE, MAX_NUM_GROUP_ADDR * ETH_ALEN);
1723 } /* end of wlanSetMulticastList() */
1726 /* FIXME: Since we cannot sleep in the wlanSetMulticastList, we arrange
1727 * another workqueue for sleeping. We don't want to block
1728 * tx_thread, so we can't let tx_thread to do this */
1731 p2pSetMulticastListWorkQueueWrapper (P_GLUE_INFO_T prGlueInfo) {
1736 DBGLOG(INIT, WARN, ("abnormal dev or skb: prGlueInfo(0x%p)\n",
1741 #if CFG_ENABLE_WIFI_DIRECT
1742 if(prGlueInfo->prAdapter->fgIsP2PRegistered) {
1743 mtk_p2p_wext_set_Multicastlist(prGlueInfo);
1748 } /* end of p2pSetMulticastListWorkQueueWrapper() */
1752 /*----------------------------------------------------------------------------*/
1754 * \brief This function is TX entry point of NET DEVICE.
1756 * \param[in] prSkb Pointer of the sk_buff to be sent
1757 * \param[in] prDev Pointer to struct net_device
1759 * \retval NETDEV_TX_OK - on success.
1760 * \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer.
1762 /*----------------------------------------------------------------------------*/
1765 struct sk_buff *prSkb,
1766 struct net_device *prDev
1769 P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
1771 P_QUE_ENTRY_T prQueueEntry = NULL;
1772 P_QUE_T prTxQueue = NULL;
1773 UINT_16 u2QueueIdx = 0;
1779 GLUE_SPIN_LOCK_DECLARATION();
1785 if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) {
1786 DBGLOG(INIT, INFO, ("GLUE_FLAG_HALT skip tx\n"));
1787 dev_kfree_skb(prSkb);
1788 return NETDEV_TX_OK;
1791 prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb);
1792 prTxQueue = &prGlueInfo->rTxQueue;
1795 DBGLOG(BOW, TRACE, ("sk_buff->len: %d\n", prSkb->len));
1796 DBGLOG(BOW, TRACE, ("sk_buff->data_len: %d\n", prSkb->data_len));
1797 DBGLOG(BOW, TRACE, ("sk_buff->data:\n"));
1799 for(i = 0; i < prSkb->len && i < 64; i++)
1801 LOG_FUNC("%02x ", prSkb->data[i]);
1812 if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) {
1814 #if CFG_DBG_GPIO_PINS
1816 /* TX request from OS */
1817 mtk_wcn_stp_debug_gpio_assert(IDX_TX_REQ, DBG_TIE_LOW);
1819 mtk_wcn_stp_debug_gpio_assert(IDX_TX_REQ, DBG_TIE_HIGH);
1823 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26)
1824 u2QueueIdx = skb_get_queue_mapping(prSkb);
1825 ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM);
1828 GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
1829 QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry);
1830 GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
1832 GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum);
1833 GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]);
1835 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26)
1836 if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx] >= CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) {
1837 netif_stop_subqueue(prDev, u2QueueIdx);
1840 if (prGlueInfo->i4TxPendingFrameNum >= CFG_TX_STOP_NETIF_QUEUE_THRESHOLD) {
1841 netif_stop_queue(prDev);
1845 //printk("is security frame\n");
1847 GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum);
1850 DBGLOG(TX, EVENT, ("\n+++++ pending frame %d len = %d +++++\n", prGlueInfo->i4TxPendingFrameNum, prSkb->len));
1851 prGlueInfo->rNetDevStats.tx_bytes += prSkb->len;
1852 prGlueInfo->rNetDevStats.tx_packets++;
1854 //pr->u4Flag |= GLUE_FLAG_TXREQ;
1855 //wake_up_interruptible(&prGlueInfo->waitq);
1856 kalSetEvent(prGlueInfo);
1859 /* For Linux, we'll always return OK FLAG, because we'll free this skb by ourself */
1860 return NETDEV_TX_OK;
1861 } /* end of wlanHardStartXmit() */
1864 /*----------------------------------------------------------------------------*/
1866 * \brief A method of struct net_device, to get the network interface statistical
1869 * Whenever an application needs to get statistics for the interface, this method
1870 * is called. This happens, for example, when ifconfig or netstat -i is run.
1872 * \param[in] prDev Pointer to struct net_device.
1874 * \return net_device_stats buffer pointer.
1876 /*----------------------------------------------------------------------------*/
1877 struct net_device_stats *
1879 IN struct net_device *prDev
1882 P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
1885 WLAN_STATUS rStatus;
1886 UINT_32 u4XmitError = 0;
1887 UINT_32 u4XmitOk = 0;
1888 UINT_32 u4RecvError = 0;
1889 UINT_32 u4RecvOk = 0;
1894 /* @FIX ME: need a more clear way to do this */
1897 rStatus = kalIoctl(prGlueInfo,
1898 wlanoidQueryXmitError,
1906 rStatus = kalIoctl(prGlueInfo,
1914 rStatus = kalIoctl(prGlueInfo,
1922 rStatus = kalIoctl(prGlueInfo,
1923 wlanoidQueryRcvError,
1930 prGlueInfo->rNetDevStats.rx_packets = u4RecvOk;
1931 prGlueInfo->rNetDevStats.tx_packets = u4XmitOk;
1932 prGlueInfo->rNetDevStats.tx_errors = u4XmitError;
1933 prGlueInfo->rNetDevStats.rx_errors = u4RecvError;
1934 //prGlueInfo->rNetDevStats.rx_bytes = rCustomNetDevStats.u4RxBytes;
1935 //prGlueInfo->rNetDevStats.tx_bytes = rCustomNetDevStats.u4TxBytes;
1936 //prGlueInfo->rNetDevStats.rx_errors = rCustomNetDevStats.u4RxErrors;
1937 //prGlueInfo->rNetDevStats.multicast = rCustomNetDevStats.u4Multicast;
1939 //prGlueInfo->rNetDevStats.rx_packets = 0;
1940 //prGlueInfo->rNetDevStats.tx_packets = 0;
1941 prGlueInfo->rNetDevStats.tx_errors = 0;
1942 prGlueInfo->rNetDevStats.rx_errors = 0;
1943 //prGlueInfo->rNetDevStats.rx_bytes = 0;
1944 //prGlueInfo->rNetDevStats.tx_bytes = 0;
1945 prGlueInfo->rNetDevStats.rx_errors = 0;
1946 prGlueInfo->rNetDevStats.multicast = 0;
1948 return &prGlueInfo->rNetDevStats;
1950 } /* end of wlanGetStats() */
1952 /*----------------------------------------------------------------------------*/
1954 * \brief A function for prDev->init
1956 * \param[in] prDev Pointer to struct net_device.
1958 * \retval 0 The execution of wlanInit succeeds.
1959 * \retval -ENXIO No such device.
1961 /*----------------------------------------------------------------------------*/
1964 struct net_device *prDev
1967 P_GLUE_INFO_T prGlueInfo = NULL;
1973 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
1974 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 12)
1975 INIT_DELAYED_WORK(&workq, wlanSetMulticastListWorkQueue);
1977 INIT_DELAYED_WORK(&workq, wlanSetMulticastListWorkQueue, NULL);
1980 return 0; /* success */
1981 } /* end of wlanInit() */
1983 void mtk_init_delayed_work(struct delayed_work *work, void *func)
1985 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 12)
1986 INIT_DELAYED_WORK(work, func);
1988 INIT_DELAYED_WORK(work, func, NULL);
1991 EXPORT_SYMBOL(mtk_init_delayed_work);
1993 /*----------------------------------------------------------------------------*/
1995 * \brief A function for prDev->uninit
1997 * \param[in] prDev Pointer to struct net_device.
2001 /*----------------------------------------------------------------------------*/
2004 struct net_device *prDev
2008 } /* end of wlanUninit() */
2011 /*----------------------------------------------------------------------------*/
2013 * \brief A function for prDev->open
2015 * \param[in] prDev Pointer to struct net_device.
2017 * \retval 0 The execution of wlanOpen succeeds.
2018 * \retval < 0 The execution of wlanOpen failed.
2020 /*----------------------------------------------------------------------------*/
2023 struct net_device *prDev
2028 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26)
2029 netif_tx_start_all_queues(prDev);
2031 netif_start_queue(prDev);
2034 return 0; /* success */
2035 } /* end of wlanOpen() */
2038 /*----------------------------------------------------------------------------*/
2040 * \brief A function for prDev->stop
2042 * \param[in] prDev Pointer to struct net_device.
2044 * \retval 0 The execution of wlanStop succeeds.
2045 * \retval < 0 The execution of wlanStop failed.
2047 /*----------------------------------------------------------------------------*/
2050 struct net_device *prDev
2053 P_GLUE_INFO_T prGlueInfo = NULL;
2054 struct cfg80211_scan_request *prScanRequest = NULL;
2055 GLUE_SPIN_LOCK_DECLARATION();
2059 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
2062 GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
2063 if(prGlueInfo->prScanRequest != NULL) {
2064 prScanRequest = prGlueInfo->prScanRequest;
2065 prGlueInfo->prScanRequest = NULL;
2067 GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
2070 cfg80211_scan_done(prScanRequest, TRUE);
2073 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26)
2074 netif_tx_stop_all_queues(prDev);
2076 netif_stop_queue(prDev);
2079 return 0; /* success */
2080 } /* end of wlanStop() */
2083 /*----------------------------------------------------------------------------*/
2085 * \brief Update Channel table for cfg80211 for Wi-Fi Direct based on current country code
2087 * \param[in] prGlueInfo Pointer to glue info
2091 /*----------------------------------------------------------------------------*/
2093 wlanUpdateChannelTable(
2094 P_GLUE_INFO_T prGlueInfo
2098 UINT_8 ucNumOfChannel;
2099 RF_CHANNEL_INFO_T aucChannelList[ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_channels)];
2101 // 1. Disable all channel
2102 for(i = 0; i < ARRAY_SIZE(mtk_2ghz_channels); i++) {
2103 mtk_2ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED;
2106 for(i = 0; i < ARRAY_SIZE(mtk_5ghz_channels); i++) {
2107 mtk_5ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED;
2110 // 2. Get current domain channel list
2111 rlmDomainGetChnlList(prGlueInfo->prAdapter,
2113 ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_channels),
2117 // 3. Enable specific channel based on domain channel list
2118 for(i = 0; i < ucNumOfChannel; i++) {
2119 switch(aucChannelList[i].eBand) {
2121 for(j = 0 ; j < ARRAY_SIZE(mtk_2ghz_channels) ; j++) {
2122 if(mtk_2ghz_channels[j].hw_value == aucChannelList[i].ucChannelNum) {
2123 mtk_2ghz_channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
2130 for(j = 0 ; j < ARRAY_SIZE(mtk_5ghz_channels) ; j++) {
2131 if(mtk_5ghz_channels[j].hw_value == aucChannelList[i].ucChannelNum) {
2132 mtk_5ghz_channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
2147 /*----------------------------------------------------------------------------*/
2149 * \brief Register the device to the kernel and return the index.
2151 * \param[in] prDev Pointer to struct net_device.
2153 * \retval 0 The execution of wlanNetRegister succeeds.
2154 * \retval < 0 The execution of wlanNetRegister failed.
2156 /*----------------------------------------------------------------------------*/
2159 struct wireless_dev *prWdev
2162 P_GLUE_INFO_T prGlueInfo;
2163 INT_32 i4DevIdx = -1;
2173 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
2175 if ((i4DevIdx = wlanGetDevIdx(prWdev->netdev)) < 0) {
2176 DBGLOG(INIT, ERROR, ("wlanNetRegister: net_device number exceeds.\n"));
2180 /* adjust channel support status */
2181 wlanUpdateChannelTable((P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy));
2183 if (wiphy_register(prWdev->wiphy) < 0) {
2184 DBGLOG(INIT, ERROR, ("wlanNetRegister: wiphy context is not registered.\n"));
2185 wlanClearDevIdx(prWdev->netdev);
2189 if(register_netdev(prWdev->netdev) < 0) {
2190 DBGLOG(INIT, ERROR, ("wlanNetRegister: net_device context is not registered.\n"));
2192 wiphy_unregister(prWdev->wiphy);
2193 wlanClearDevIdx(prWdev->netdev);
2197 if(i4DevIdx != -1) {
2198 prGlueInfo->fgIsRegistered = TRUE;
2203 return i4DevIdx; /* success */
2204 } /* end of wlanNetRegister() */
2207 /*----------------------------------------------------------------------------*/
2209 * \brief Unregister the device from the kernel
2211 * \param[in] prWdev Pointer to struct net_device.
2215 /*----------------------------------------------------------------------------*/
2218 struct wireless_dev *prWdev
2221 P_GLUE_INFO_T prGlueInfo;
2224 DBGLOG(INIT, ERROR, ("wlanNetUnregister: The device context is NULL\n"));
2228 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
2230 wlanClearDevIdx(prWdev->netdev);
2231 unregister_netdev(prWdev->netdev);
2232 wiphy_unregister(prWdev->wiphy);
2234 prGlueInfo->fgIsRegistered = FALSE;
2236 DBGLOG(INIT, INFO, ("unregister wireless_dev(0x%p)\n", prWdev));
2239 } /* end of wlanNetUnregister() */
2242 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
2243 static const struct net_device_ops wlan_netdev_ops = {
2244 .ndo_open = wlanOpen,
2245 .ndo_stop = wlanStop,
2246 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
2247 .ndo_set_rx_mode = wlanSetMulticastList,
2249 .ndo_set_multicast_list = wlanSetMulticastList,
2251 .ndo_get_stats = wlanGetStats,
2252 .ndo_do_ioctl = wlanDoIOCTL,
2253 .ndo_start_xmit = wlanHardStartXmit,
2254 .ndo_init = wlanInit,
2255 .ndo_uninit = wlanUninit,
2256 .ndo_select_queue = wlanSelectQueue,
2260 /*----------------------------------------------------------------------------*/
2262 * \brief A method for creating Linux NET4 struct net_device object and the
2263 * private data(prGlueInfo and prAdapter). Setup the IO address to the HIF.
2264 * Assign the function pointer to the net_device object
2266 * \param[in] pvData Memory address for the device
2268 * \retval Not null The wireless_dev object.
2269 * \retval NULL Fail to create wireless_dev object
2271 /*----------------------------------------------------------------------------*/
2272 static struct wireless_dev *
2277 struct wireless_dev *prWdev = NULL;
2278 P_GLUE_INFO_T prGlueInfo = NULL;
2279 P_ADAPTER_T prAdapter = NULL;
2281 struct device *prDev;
2283 //4 <1.1> Create wireless_dev
2284 prWdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2285 DBGLOG(INIT, INFO, ("wireless_dev prWdev(0x%p) allocated\n", prWdev));
2287 DBGLOG(INIT, ERROR, ("Allocating memory to wireless_dev context failed\n"));
2291 //4 <1.2> Create wiphy
2292 prWdev->wiphy = wiphy_new(&mtk_wlan_ops, sizeof(GLUE_INFO_T));
2293 DBGLOG(INIT, INFO, ("wiphy (0x%p) allocated\n", prWdev->wiphy));
2294 if (!prWdev->wiphy) {
2295 DBGLOG(INIT, ERROR, ("Allocating memory to wiphy device failed\n"));
2300 //4 <1.3> co-relate wiphy & prDev
2301 #if MTK_WCN_HIF_SDIO
2302 mtk_wcn_hif_sdio_get_dev(*((MTK_WCN_HIF_SDIO_CLTCTX *)pvData), &prDev);
2304 prDev = & ((struct sdio_func *) pvData)->dev; //mark skynine add "&"
2307 printk(KERN_ALERT DRV_NAME "unable to get struct dev for wlan\n");
2309 set_wiphy_dev(prWdev->wiphy, prDev);
2311 //4 <1.4> configure wireless_dev & wiphy
2312 prWdev->iftype = NL80211_IFTYPE_STATION;
2313 prWdev->wiphy->max_scan_ssids = 1; /* FIXME: for combo scan */
2314 prWdev->wiphy->max_scan_ie_len = 512;
2315 prWdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2316 prWdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mtk_band_2ghz;
2317 prWdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mtk_band_5ghz;
2318 prWdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2319 prWdev->wiphy->cipher_suites = (const u32 *)mtk_cipher_suites;
2320 prWdev->wiphy->n_cipher_suites = ARRAY_SIZE(mtk_cipher_suites);
2321 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
2322 prWdev->wiphy->flags = WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_SUPPORTS_FW_ROAM;
2324 prWdev->wiphy->flags = WIPHY_FLAG_CUSTOM_REGULATORY;
2326 //4 <2> Create Glue structure
2327 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
2329 DBGLOG(INIT, ERROR, ("Allocating memory to glue layer failed\n"));
2333 //4 <3> Initial Glue structure
2334 //4 <3.1> create net device
2335 prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, ether_setup, CFG_MAX_TXQ_NUM);
2337 DBGLOG(INIT, INFO, ("net_device prDev(0x%p) allocated\n", prGlueInfo->prDevHandler));
2338 if (!prGlueInfo->prDevHandler) {
2339 DBGLOG(INIT, ERROR, ("Allocating memory to net_device context failed\n"));
2343 //4 <3.1.1> initialize net device varaiables
2344 *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->prDevHandler)) = prGlueInfo;
2346 prGlueInfo->prDevHandler->netdev_ops = &wlan_netdev_ops;
2347 #ifdef CONFIG_WIRELESS_EXT
2348 prGlueInfo->prDevHandler->wireless_handlers = &wext_handler_def;
2350 netif_carrier_off(prGlueInfo->prDevHandler);
2351 netif_tx_stop_all_queues(prGlueInfo->prDevHandler);
2353 //4 <3.1.2> co-relate with wiphy bi-directionally
2354 prGlueInfo->prDevHandler->ieee80211_ptr = prWdev;
2355 prWdev->netdev = prGlueInfo->prDevHandler;
2357 //4 <3.1.3> co-relate net device & prDev
2358 SET_NETDEV_DEV(prGlueInfo->prDevHandler, wiphy_dev(prWdev->wiphy));
2360 //4 <3.2> initiali glue variables
2361 prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED;
2362 prGlueInfo->ePowerState = ParamDeviceStateD0;
2363 prGlueInfo->fgIsMacAddrOverride = FALSE;
2364 prGlueInfo->fgIsRegistered = FALSE;
2365 prGlueInfo->prScanRequest = NULL;
2367 init_completion(&prGlueInfo->rScanComp);
2368 init_completion(&prGlueInfo->rHaltComp);
2369 init_completion(&prGlueInfo->rPendComp);
2370 #if CFG_ENABLE_WIFI_DIRECT
2371 init_completion(&prGlueInfo->rSubModComp);
2374 /* initialize timer for OID timeout checker */
2375 kalOsTimerInitialize(prGlueInfo, kalTimeoutHandler);
2377 for (i = 0; i < SPIN_LOCK_NUM; i++) {
2378 spin_lock_init(&prGlueInfo->rSpinLock[i]);
2381 /* initialize semaphore for ioctl */
2382 sema_init(&prGlueInfo->ioctl_sem, 1);
2384 /* initialize semaphore for ioctl */
2385 sema_init(&g_halt_sem, 1);
2388 //4 <4> Create Adapter structure
2389 prAdapter = (P_ADAPTER_T) wlanAdapterCreate(prGlueInfo);
2392 DBGLOG(INIT, ERROR, ("Allocating memory to adapter failed\n"));
2396 prGlueInfo->prAdapter = prAdapter;
2398 #ifdef CONFIG_CFG80211_WEXT
2399 //4 <5> Use wireless extension to replace IOCTL
2400 prWdev->wiphy->wext = &wext_handler_def;
2403 goto netcreate_done;
2406 if (NULL != prAdapter) {
2407 wlanAdapterDestroy(prAdapter);
2411 if (NULL != prGlueInfo->prDevHandler) {
2412 free_netdev(prGlueInfo->prDevHandler);
2413 prGlueInfo->prDevHandler = NULL;
2416 if (NULL != prWdev->wiphy) {
2417 wiphy_free(prWdev->wiphy);
2418 prWdev->wiphy = NULL;
2421 if (NULL != prWdev) {
2422 /* Free net_device and private data, which are allocated by
2432 } /* end of wlanNetCreate() */
2435 /*----------------------------------------------------------------------------*/
2437 * \brief Destroying the struct net_device object and the private data.
2439 * \param[in] prWdev Pointer to struct wireless_dev.
2443 /*----------------------------------------------------------------------------*/
2446 struct wireless_dev *prWdev
2449 P_GLUE_INFO_T prGlueInfo = NULL;
2454 DBGLOG(INIT, ERROR, ("wlanNetDestroy: The device context is NULL\n"));
2458 /* prGlueInfo is allocated with net_device */
2459 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
2462 /* destroy kal OS timer */
2463 kalCancelTimer(prGlueInfo);
2465 glClearHifInfo(prGlueInfo);
2467 wlanAdapterDestroy(prGlueInfo->prAdapter);
2468 prGlueInfo->prAdapter = NULL;
2470 /* Free net_device and private data, which are allocated by alloc_netdev().
2472 free_netdev(prWdev->netdev);
2473 wiphy_free(prWdev->wiphy);
2478 } /* end of wlanNetDestroy() */
2481 UINT_8 g_aucBufIpAddr[32] = {0};
2483 static void wlanEarlySuspend(void)
2485 struct net_device *prDev = NULL;
2486 P_GLUE_INFO_T prGlueInfo = NULL;
2487 UINT_8 ip[4] = { 0 };
2488 UINT_32 u4NumIPv4 = 0;
2490 UINT_8 ip6[16] = { 0 }; // FIX ME: avoid to allocate large memory in stack
2491 UINT_32 u4NumIPv6 = 0;
2494 P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr;
2496 DBGLOG(INIT, INFO, ("*********wlanEarlySuspend************\n"));
2498 // <1> Sanity check and acquire the net_device
2499 ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES);
2500 if(u4WlanDevNum == 0){
2501 DBGLOG(INIT, ERROR, ("wlanEarlySuspend u4WlanDevNum==0 invalid!!\n"));
2504 prDev = arWlanDevInfo[u4WlanDevNum-1].prDev;
2507 fgIsUnderEarlierSuspend = true;
2509 // <2> get the IPv4 address
2510 if(!prDev || !(prDev->ip_ptr)||\
2511 !((struct in_device *)(prDev->ip_ptr))->ifa_list||\
2512 !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))){
2513 DBGLOG(INIT, INFO, ("ip is not avaliable.\n"));
2517 // <3> acquire the prGlueInfo
2518 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
2521 // <4> copy the IPv4 address
2522 kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip));
2523 DBGLOG(INIT, INFO, ("ip is %d.%d.%d.%d\n",
2524 ip[0],ip[1],ip[2],ip[3]));
2526 // todo: traverse between list to find whole sets of IPv4 addresses
2527 if (!((ip[0] == 0) &&
2535 // <5> get the IPv6 address
2536 if(!prDev || !(prDev->ip6_ptr)||\
2537 !((struct in_device *)(prDev->ip6_ptr))->ifa_list||\
2538 !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))){
2539 DBGLOG(INIT, INFO, ("ipv6 is not avaliable.\n"));
2542 // <6> copy the IPv6 address
2543 kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
2544 DBGLOG(INIT, INFO, ("ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
2545 ip6[0],ip6[1],ip6[2],ip6[3],
2546 ip6[4],ip6[5],ip6[6],ip6[7],
2547 ip6[8],ip6[9],ip6[10],ip6[11],
2548 ip6[12],ip6[13],ip6[14],ip6[15]
2551 // todo: traverse between list to find whole sets of IPv6 addresses
2552 if (!((ip6[0] == 0) &&
2563 // <7> set up the ARP filter
2565 WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
2566 UINT_32 u4SetInfoLen = 0;
2567 // UINT_8 aucBuf[32] = {0};
2568 UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress);
2569 P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST)g_aucBufIpAddr;//aucBuf;
2570 P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress;
2572 kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
2574 prParamNetAddrList->u4AddressCount = u4NumIPv4 + u4NumIPv6;
2575 prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
2576 for (i = 0; i < u4NumIPv4; i++) {
2577 prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP);//4;;
2578 prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;;
2580 kalMemCopy(prParamNetAddr->aucAddress, ip, sizeof(ip));
2581 prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(ip));
2582 u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip);
2584 prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP)prParamNetAddr->aucAddress;
2585 kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip));
2586 prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS));
2587 u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS);
2591 for (i = 0; i < u4NumIPv6; i++) {
2592 prParamNetAddr->u2AddressLength = 6;;
2593 prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;;
2594 kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6));
2595 prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(ip6));
2596 u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6);
2599 ASSERT(u4Len <= sizeof(g_aucBufIpAddr/*aucBuf*/));
2601 rStatus = kalIoctl(prGlueInfo,
2602 wlanoidSetNetworkAddress,
2603 (PVOID)prParamNetAddrList,
2611 if (rStatus != WLAN_STATUS_SUCCESS) {
2612 DBGLOG(INIT, INFO, ("set HW pattern filter fail 0x%lx\n", rStatus));
2617 static void wlanLateResume(void)
2619 struct net_device *prDev = NULL;
2620 P_GLUE_INFO_T prGlueInfo = NULL;
2621 UINT_8 ip[4] = { 0 };
2623 UINT_8 ip6[16] = { 0 }; // FIX ME: avoid to allocate large memory in stack
2626 DBGLOG(INIT, INFO, ("*********wlanLateResume************\n"));
2628 // <1> Sanity check and acquire the net_device
2629 ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES);
2631 if(u4WlanDevNum == 0){
2632 DBGLOG(INIT, ERROR, ("wlanLateResume u4WlanDevNum==0 invalid!!\n"));
2635 prDev = arWlanDevInfo[u4WlanDevNum-1].prDev;
2638 fgIsUnderEarlierSuspend = false;
2640 // <2> get the IPv4 address
2641 if(!prDev || !(prDev->ip_ptr)||\
2642 !((struct in_device *)(prDev->ip_ptr))->ifa_list||\
2643 !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))){
2644 DBGLOG(INIT, INFO, ("ip is not avaliable.\n"));
2648 // <3> acquire the prGlueInfo
2649 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
2652 // <4> copy the IPv4 address
2653 kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip));
2654 DBGLOG(INIT, INFO, ("ip is %d.%d.%d.%d\n",
2655 ip[0],ip[1],ip[2],ip[3]));
2658 // <5> get the IPv6 address
2659 if(!prDev || !(prDev->ip6_ptr)||\
2660 !((struct in_device *)(prDev->ip6_ptr))->ifa_list||\
2661 !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))){
2662 DBGLOG(INIT, INFO, ("ipv6 is not avaliable.\n"));
2665 // <6> copy the IPv6 address
2666 kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
2667 DBGLOG(INIT, INFO, ("ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
2668 ip6[0],ip6[1],ip6[2],ip6[3],
2669 ip6[4],ip6[5],ip6[6],ip6[7],
2670 ip6[8],ip6[9],ip6[10],ip6[11],
2671 ip6[12],ip6[13],ip6[14],ip6[15]
2674 // <7> clear the ARP filter
2676 WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
2677 UINT_32 u4SetInfoLen = 0;
2678 // UINT_8 aucBuf[32] = {0};
2679 UINT_32 u4Len = sizeof(PARAM_NETWORK_ADDRESS_LIST);
2680 P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST)g_aucBufIpAddr;//aucBuf;
2682 kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
2684 prParamNetAddrList->u4AddressCount = 0;
2685 prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
2687 ASSERT(u4Len <= sizeof(g_aucBufIpAddr/*aucBuf*/));
2688 rStatus = kalIoctl(prGlueInfo,
2689 wlanoidSetNetworkAddress,
2690 (PVOID)prParamNetAddrList,
2698 if (rStatus != WLAN_STATUS_SUCCESS) {
2699 DBGLOG(INIT, INFO, ("set HW pattern filter fail 0x%lx\n", rStatus));
2704 #if defined(CONFIG_HAS_EARLYSUSPEND)
2705 static struct early_suspend mt6620_early_suspend_desc = {
2706 .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN,
2709 static void wlan_early_suspend(struct early_suspend *h)
2711 DBGLOG(INIT, INFO, ("*********wlan_early_suspend************\n"));
2715 static void wlan_late_resume(struct early_suspend *h)
2717 DBGLOG(INIT, INFO, ("*********wlan_late_resume************\n"));
2720 #endif //defined(CONFIG_HAS_EARLYSUSPEND)
2721 #endif //! CONFIG_X86
2723 extern void wlanRegisterNotifier(void);
2724 extern void wlanUnregisterNotifier(void);
2726 /*----------------------------------------------------------------------------*/
2728 * \brief Wlan probe function. This function probes and initializes the device.
2730 * \param[in] pvData data passed by bus driver init function
2732 * _HIF_SDIO: sdio bus driver handle
2735 * \retval negative value Failed
2737 /*----------------------------------------------------------------------------*/
2743 struct wireless_dev *prWdev = NULL;
2744 P_WLANDEV_INFO_T prWlandevInfo = NULL;
2745 INT_32 i4DevIdx = 0;
2746 P_GLUE_INFO_T prGlueInfo = NULL;
2747 P_ADAPTER_T prAdapter = NULL;
2748 INT_32 i4Status = 0;
2755 /* Initialize DEBUG CLASS of each module */
2756 for (i = 0; i < DBG_MODULE_NUM; i++) {
2757 aucDebugModule[i] = DBG_CLASS_ERROR | \
2762 //aucDebugModule[i] = 0;
2765 aucDebugModule[DBG_INIT_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2766 aucDebugModule[DBG_ARB_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2767 aucDebugModule[DBG_JOIN_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2768 //aucDebugModule[DBG_RX_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2769 aucDebugModule[DBG_TX_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2770 aucDebugModule[DBG_NIC_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2771 aucDebugModule[DBG_HAL_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2772 aucDebugModule[DBG_KEVIN_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO | DBG_CLASS_TEMP;
2773 aucDebugModule[DBG_SCAN_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2774 aucDebugModule[DBG_REQ_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2775 //aucDebugModule[DBG_MGT_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2776 aucDebugModule[DBG_RSN_IDX] |= DBG_CLASS_TRACE;
2777 aucDebugModule[DBG_ROAMING_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2781 //4 <1> Initialize the IO port of the interface
2782 /* GeorgeKuo: pData has different meaning for _HIF_XXX:
2783 * _HIF_EHPI: pointer to memory base variable, which will be
2784 * initialized by glBusInit().
2785 * _HIF_SDIO: bus driver handle
2788 bRet = glBusInit(pvData);
2790 /* Cannot get IO address from interface */
2791 if (FALSE == bRet) {
2792 DBGLOG(INIT, ERROR, (KERN_ALERT "wlanProbe: glBusInit() fail\n"));
2797 //4 <2> Create network device, Adapter, KalInfo, prDevHandler(netdev)
2798 if ((prWdev = wlanNetCreate(pvData)) == NULL) {
2799 DBGLOG(INIT, ERROR, ("wlanProbe: No memory for dev and its private\n"));
2804 //4 <2.5> Set the ioaddr to HIF Info
2805 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
2806 gPrDev = prGlueInfo->prDevHandler;
2807 glSetHifInfo(prGlueInfo, (UINT_32) pvData);
2810 /* main thread is created in this function */
2811 init_waitqueue_head(&prGlueInfo->waitq);
2814 QUEUE_INITIALIZE(&prGlueInfo->rCmdQueue);
2815 QUEUE_INITIALIZE(&prGlueInfo->rTxQueue);
2819 //prGlueInfo->main_thread = kthread_run(tx_thread, prGlueInfo->prDevHandler, "tx_thread");
2822 prWlandevInfo = &arWlanDevInfo[i4DevIdx];
2824 //i4Status = glBusSetIrq(prWdev->netdev, NULL, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev)));
2826 if (i4Status != WLAN_STATUS_SUCCESS) {
2827 DBGLOG(INIT, ERROR, ("wlanProbe: Set IRQ error\n"));
2831 prGlueInfo->i4DevIdx = i4DevIdx;
2833 prAdapter = prGlueInfo->prAdapter;
2835 prGlueInfo->u4ReadyFlag = 0;
2837 #if CFG_TCP_IP_CHKSUM_OFFLOAD
2838 prAdapter->u4CSUMFlags = (CSUM_OFFLOAD_EN_TX_TCP | CSUM_OFFLOAD_EN_TX_UDP | CSUM_OFFLOAD_EN_TX_IP);
2841 //4 <5> Start Device
2843 #if CFG_ENABLE_FW_DOWNLOAD
2844 /* before start adapter, we need to open and load firmware */
2846 UINT_32 u4FwSize = 0;
2847 PVOID prFwBuffer = NULL;
2848 P_REG_INFO_T prRegInfo = &prGlueInfo->rRegInfo;
2850 //P_REG_INFO_T prRegInfo = (P_REG_INFO_T) kmalloc(sizeof(REG_INFO_T), GFP_KERNEL);
2851 kalMemSet(prRegInfo, 0, sizeof(REG_INFO_T));
2852 prRegInfo->u4StartAddress = CFG_FW_START_ADDRESS;
2853 prRegInfo->u4LoadAddress = CFG_FW_LOAD_ADDRESS;
2855 // Load NVRAM content to REG_INFO_T
2856 glLoadNvram(prGlueInfo, prRegInfo);
2858 //kalMemCopy(&prGlueInfo->rRegInfo, prRegInfo, sizeof(REG_INFO_T));
2860 prRegInfo->u4PowerMode = CFG_INIT_POWER_SAVE_PROF;
2861 prRegInfo->fgEnArpFilter = TRUE;
2863 if (kalFirmwareImageMapping(prGlueInfo, &prFwBuffer, &u4FwSize) == NULL) {
2867 if (wlanAdapterStart(prAdapter, prRegInfo, prFwBuffer, u4FwSize) != WLAN_STATUS_SUCCESS) {
2872 kalFirmwareImageUnmapping(prGlueInfo, NULL, prFwBuffer);
2882 //P_REG_INFO_T prRegInfo = (P_REG_INFO_T) kmalloc(sizeof(REG_INFO_T), GFP_KERNEL);
2883 kalMemSet(&prGlueInfo->rRegInfo, 0, sizeof(REG_INFO_T));
2884 P_REG_INFO_T prRegInfo = &prGlueInfo->rRegInfo;
2886 // Load NVRAM content to REG_INFO_T
2887 glLoadNvram(prGlueInfo, prRegInfo);
2889 prRegInfo->u4PowerMode = CFG_INIT_POWER_SAVE_PROF;
2891 if (wlanAdapterStart(prAdapter, prRegInfo, NULL, 0) != WLAN_STATUS_SUCCESS) {
2896 prGlueInfo->main_thread = kthread_run(tx_thread, prGlueInfo->prDevHandler, "tx_thread");
2898 /* set MAC address */
2900 WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
2901 struct sockaddr MacAddr;
2902 UINT_32 u4SetInfoLen = 0;
2904 rStatus = kalIoctl(prGlueInfo,
2905 wlanoidQueryCurrentAddr,
2914 if (rStatus != WLAN_STATUS_SUCCESS) {
2915 DBGLOG(INIT, WARN, ("set MAC addr fail 0x%lx\n", rStatus));
2916 prGlueInfo->u4ReadyFlag = 0;
2918 memcpy(prGlueInfo->prDevHandler->dev_addr, &MacAddr.sa_data, ETH_ALEN);
2919 memcpy(prGlueInfo->prDevHandler->perm_addr, prGlueInfo->prDevHandler->dev_addr, ETH_ALEN);
2922 prGlueInfo->u4ReadyFlag = 1;
2923 #if CFG_SHOW_MACADDR_SOURCE
2924 DBGLOG(INIT, INFO, ("MAC address: "MACSTR, MAC2STR(&MacAddr.sa_data)));
2930 #if CFG_TCP_IP_CHKSUM_OFFLOAD
2931 /* set HW checksum offload */
2933 WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
2934 UINT_32 u4CSUMFlags = CSUM_OFFLOAD_EN_ALL;
2935 UINT_32 u4SetInfoLen = 0;
2937 rStatus = kalIoctl(prGlueInfo,
2938 wlanoidSetCSUMOffload,
2939 (PVOID)&u4CSUMFlags,
2947 if (rStatus != WLAN_STATUS_SUCCESS) {
2948 DBGLOG(INIT, WARN, ("set HW checksum offload fail 0x%lx\n", rStatus));
2953 //4 <3> Register the card
2954 if ((i4DevIdx = wlanNetRegister(prWdev)) < 0){
2956 DBGLOG(INIT, ERROR, ("wlanProbe: Cannot register the net_device context to the kernel\n"));
2960 glRegisterEarlySuspend(&mt6620_early_suspend_desc, wlan_early_suspend, wlan_late_resume);
2961 wlanRegisterNotifier();
2962 //4 <6> Initialize /proc filesystem
2963 #ifdef WLAN_INCLUDE_PROC
2964 if ( (i4Status = procInitProcfs(prDev, NIC_DEVICE_ID_LOW)) < 0) {
2965 DBGLOG(INIT, ERROR, ("wlanProbe: init procfs failed\n"));
2968 #endif /* WLAN_INCLUDE_PROC */
2970 #if CFG_ENABLE_BT_OVER_WIFI
2971 prGlueInfo->rBowInfo.fgIsNetRegistered = FALSE;
2972 prGlueInfo->rBowInfo.fgIsRegistered = FALSE;
2973 glRegisterAmpc(prGlueInfo);
2976 #if CFG_ENABLE_WIFI_DIRECT
2977 /*wlan is launched*/
2978 prGlueInfo->prAdapter->fgIsWlanLaunched = TRUE;
2979 /*if p2p module is inserted, notify tx_thread to init p2p network*/
2980 if(rSubModHandler[P2P_MODULE].subModInit) {
2981 wlanSubModInit(prGlueInfo);
2989 driver_start_ok = -1;
2991 driver_start_ok = 1;
2995 } /* end of wlanProbe() */
2998 /*----------------------------------------------------------------------------*/
3000 * \brief A method to stop driver operation and release all resources. Following
3001 * this call, no frame should go up or down through this interface.
3005 /*----------------------------------------------------------------------------*/
3011 struct net_device *prDev = NULL;
3012 P_WLANDEV_INFO_T prWlandevInfo = NULL;
3013 P_GLUE_INFO_T prGlueInfo = NULL;
3014 P_ADAPTER_T prAdapter = NULL;
3016 DBGLOG(INIT, INFO, ("Remove wlan!\n"));
3019 //4 <0> Sanity check
3020 ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES);
3021 if (0 == u4WlanDevNum) {
3022 DBGLOG(INIT, INFO, ("0 == u4WlanDevNum\n"));
3026 prDev = arWlanDevInfo[u4WlanDevNum-1].prDev;
3027 prWlandevInfo = &arWlanDevInfo[u4WlanDevNum-1];
3030 if (NULL == prDev) {
3031 DBGLOG(INIT, INFO, ("NULL == prDev\n"));
3035 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
3037 if (NULL == prGlueInfo) {
3038 DBGLOG(INIT, INFO, ("NULL == prGlueInfo\n"));
3044 #if CFG_ENABLE_WIFI_DIRECT
3045 prGlueInfo->prAdapter->fgIsWlanLaunched = FALSE;
3046 if(prGlueInfo->prAdapter->fgIsP2PRegistered) {
3047 p2pNetUnregister(prGlueInfo, FALSE);
3048 p2pRemove(prGlueInfo);
3052 prGlueInfo->prAdapter->fgIsWlanLaunched = FALSE;
3053 //if(prGlueInfo->prAdapter->fgIsP2PRegistered) {
3054 if (prGlueInfo->prP2PInfo) {
3055 //p2pRemove(prGlueInfo);
3056 if (prGlueInfo->prP2PInfo->prDevHandler) {
3057 free_netdev(prGlueInfo->prP2PInfo->prDevHandler);
3058 prGlueInfo->prP2PInfo->prDevHandler = NULL;
3063 if(!p2PFreeInfo(prGlueInfo)) {
3064 printk(KERN_ALERT DRV_NAME "Free memory for p2p FAILED\n");
3072 #if CFG_ENABLE_BT_OVER_WIFI
3073 if(prGlueInfo->rBowInfo.fgIsNetRegistered) {
3074 bowNotifyAllLinkDisconnected(prGlueInfo->prAdapter);
3075 /*wait 300ms for BoW module to send deauth*/
3080 //4 <1> Stopping handling interrupt and free IRQ
3081 glBusFreeIrq(prDev, *((P_GLUE_INFO_T *) netdev_priv(prDev)));
3083 kalMemSet(&(prGlueInfo->prAdapter->rWlanInfo), 0, sizeof(WLAN_INFO_T));
3085 flush_delayed_work_sync(&workq);
3090 //4 <2> Mark HALT, notify main thread to stop, and clean up queued requests
3091 prGlueInfo->u4Flag |= GLUE_FLAG_HALT;
3092 /* wake up main thread */
3093 wake_up_interruptible(&prGlueInfo->waitq);
3094 /* wait main thread stops */
3095 wait_for_completion_interruptible(&prGlueInfo->rHaltComp);
3097 DBGLOG(INIT, INFO, ("mtk_sdiod stopped\n"));
3099 //prGlueInfo->rHifInfo.main_thread = NULL;
3100 prGlueInfo->main_thread = NULL;
3102 #if CFG_ENABLE_BT_OVER_WIFI
3103 if(prGlueInfo->rBowInfo.fgIsRegistered) {
3104 glUnregisterAmpc(prGlueInfo);
3109 //4 <3> Remove /proc filesystem.
3110 #ifdef WLAN_INCLUDE_PROC
3111 procRemoveProcfs(prDev, NIC_DEVICE_ID_LOW);
3112 #endif /* WLAN_INCLUDE_PROC */
3114 //4 <4> wlanAdapterStop
3115 prAdapter = prGlueInfo->prAdapter;
3117 wlanAdapterStop(prAdapter);
3118 DBGLOG(INIT, INFO, ("Number of Stalled Packets = %ld\n", prGlueInfo->i4TxPendingFrameNum));
3120 //4 <5> Release the Bus
3121 glBusRelease(prDev);
3125 //4 <6> Unregister the card
3126 wlanNetUnregister(prDev->ieee80211_ptr);
3128 //4 <7> Destroy the device
3129 wlanNetDestroy(prDev->ieee80211_ptr);
3132 glUnregisterEarlySuspend(&mt6620_early_suspend_desc);
3133 wlanUnregisterNotifier();
3135 } /* end of wlanRemove() */
3137 /*----------------------------------------------------------------------------*/
3139 * \brief Driver entry point when the driver is configured as a Linux Module, and
3140 * is called once at module load time, by the user-level modutils
3141 * application: insmod or modprobe.
3145 /*----------------------------------------------------------------------------*/
3146 //1 Module Entry Point
3148 #include "wifi_version.h"
3150 extern void initRssiHistory(void);
3151 extern void initScanRssiHistory(void);
3152 extern VOID exitWlan(void);
3153 /*static */int initWlan(void)
3155 int ret = 0, timeout = 0;
3157 driver_start_ok = 0;
3161 initScanRssiHistory();
3165 //printk("=======================================================\n");
3166 //printk("==== Launching Wi-Fi driver! (Powered by Rockchip) ====\n");
3167 //printk("=======================================================\n");
3168 printk("MT5931 SDIO WiFi driver (Powered by Rockchip,Ver %s) init.\n", MT5931_DRV_VERSION);
3170 DBGLOG(INIT, INFO, ("initWlan\n"));
3173 #if defined(CONFIG_WIFI_CONTROL_FUNC)
3174 if (wl_android_wifictrl_func_add() < 0) {
3180 /* memory pre-allocation */
3183 //return ((glRegisterBus(wlanProbe, wlanRemove) == WLAN_STATUS_SUCCESS) ? 0: -EIO);
3184 ret = ((glRegisterBus(wlanProbe, wlanRemove) == WLAN_STATUS_SUCCESS) ? 0: -EIO);
3187 kalUninitIOBuffer();
3192 #if (CFG_CHIP_RESET_SUPPORT)
3196 /*WCNCR00002676, keep OS wake up for 100ms*/
3197 KAL_WAKE_LOCK_INIT(NULL, &isr_wakelock, "WLAN TIME 2");
3199 /*for (timeout = 50; timeout >=0; timeout--)
3201 if (driver_start_ok == 1)
3205 if (timeout <= 0 && count > 0)
3208 if (driver_start_ok == 0)
3209 printk("No WiFi function card has been attached (5s). retry!\n");
3210 else if (driver_start_ok < 0)
3211 printk("wifi driver probe processing fail. retry!\n");
3213 goto retry_initwlan;
3220 #if defined(CONFIG_WIFI_CONTROL_FUNC)
3221 wl_android_wifictrl_func_del();
3225 } /* end of initWlan() */
3228 /*----------------------------------------------------------------------------*/
3230 * \brief Driver exit point when the driver as a Linux Module is removed. Called
3231 * at module unload time, by the user level modutils application: rmmod.
3232 * This is our last chance to clean up after ourselves.
3236 /*----------------------------------------------------------------------------*/
3237 //1 Module Leave Point
3238 /*static */VOID exitWlan(void)
3240 //printk("=======================================================\n");
3241 //printk("== Dis-launching Wi-Fi driver! (Powered by Rockchip) ==\n");
3242 //printk("=======================================================\n");
3244 //printk("remove %p\n", wlanRemove);
3245 #if CFG_CHIP_RESET_SUPPORT
3249 glUnregisterBus(wlanRemove);
3252 KAL_WAKE_LOCK_DESTROY(NULL, &isr_wakelock);
3254 /* free pre-allocated memory */
3255 kalUninitIOBuffer();
3257 #if defined(CONFIG_WIFI_CONTROL_FUNC)
3258 wl_android_wifictrl_func_del();
3259 #endif /* CONFIG_WIFI_CONTROL_FUNC */
3261 DBGLOG(INIT, INFO, ("exitWlan\n"));
3264 } /* end of exitWlan() */
3266 int rockchip_wifi_init_module(void)
3271 int rockchip_wifi_exit_module(void)
3276 EXPORT_SYMBOL(rockchip_wifi_init_module);
3277 EXPORT_SYMBOL(rockchip_wifi_exit_module);
3279 //module_init(initWlan);
3280 //module_exit(exitWlan);
3282 /* export necessary symbol for p2p driver using */
3283 #if CFG_ENABLE_WIFI_DIRECT
3284 EXPORT_SYMBOL(wlanSubModRegisterInitExit);
3285 EXPORT_SYMBOL(wlanSubModExit);
3286 EXPORT_SYMBOL(wlanSubModInit);
3288 EXPORT_SYMBOL(nicPmIndicateBssCreated);
3289 EXPORT_SYMBOL(rlmProcessAssocRsp);
3290 EXPORT_SYMBOL(kalSetEvent);
3291 EXPORT_SYMBOL(rlmBssInitForAPandIbss);
3292 EXPORT_SYMBOL(kalEnqueueCommand);
3293 EXPORT_SYMBOL(nicIncreaseTxSeqNum);
3294 EXPORT_SYMBOL(nicCmdEventQueryAddress);
3295 EXPORT_SYMBOL(bssCreateStaRecFromBssDesc);
3296 EXPORT_SYMBOL(rlmBssAborted);
3297 EXPORT_SYMBOL(cnmStaRecResetStatus);
3298 EXPORT_SYMBOL(mqmProcessAssocRsp);
3299 EXPORT_SYMBOL(nicTxReturnMsduInfo);
3300 EXPORT_SYMBOL(nicTxEnqueueMsdu);
3301 EXPORT_SYMBOL(wlanProcessSecurityFrame);
3302 EXPORT_SYMBOL(nicChannelNum2Freq);
3303 EXPORT_SYMBOL(nicUpdateBss);
3304 EXPORT_SYMBOL(wlanSendSetQueryCmd);
3305 EXPORT_SYMBOL(cnmStaRecAlloc);
3306 EXPORT_SYMBOL(cnmTimerInitTimer);
3307 EXPORT_SYMBOL(rateGetRateSetFromIEs);
3308 EXPORT_SYMBOL(nicOidCmdTimeoutCommon);
3309 EXPORT_SYMBOL(cnmStaRecChangeState);
3310 EXPORT_SYMBOL(rateGetDataRatesFromRateSet);
3311 EXPORT_SYMBOL(cnmMgtPktAlloc);
3312 EXPORT_SYMBOL(cnmMgtPktFree);
3313 EXPORT_SYMBOL(wextSrchDesiredWPAIE);
3314 EXPORT_SYMBOL(nicRxReturnRFB);
3315 EXPORT_SYMBOL(cnmTimerStartTimer);
3316 EXPORT_SYMBOL(cmdBufAllocateCmdInfo);
3317 EXPORT_SYMBOL(cnmGetStaRecByAddress);
3318 EXPORT_SYMBOL(nicMediaStateChange);
3319 EXPORT_SYMBOL(bssUpdateBeaconContent);
3320 EXPORT_SYMBOL(kalIoctl);
3321 EXPORT_SYMBOL(nicActivateNetwork);
3322 EXPORT_SYMBOL(nicDeactivateNetwork);
3323 EXPORT_SYMBOL(kalRandomNumber);
3324 EXPORT_SYMBOL(nicCmdEventSetCommon);
3325 EXPORT_SYMBOL(cnmTimerStopTimer);
3326 EXPORT_SYMBOL(nicIncreaseCmdSeqNum);
3327 EXPORT_SYMBOL(authSendDeauthFrame);
3328 EXPORT_SYMBOL(cnmMemAlloc);
3329 EXPORT_SYMBOL(nicPmIndicateBssAbort);
3330 EXPORT_SYMBOL(nicCmdEventSetIpAddress);
3331 EXPORT_SYMBOL(mboxSendMsg);
3332 EXPORT_SYMBOL(scanSearchBssDescByBssid);
3333 EXPORT_SYMBOL(bssRemoveStaRecFromClientList);
3334 EXPORT_SYMBOL(assocProcessRxDisassocFrame);
3335 EXPORT_SYMBOL(authProcessRxDeauthFrame);
3336 EXPORT_SYMBOL(cnmStaRecFree);
3337 EXPORT_SYMBOL(rNonHTPhyAttributes);
3338 EXPORT_SYMBOL(rNonHTApModeAttributes);
3339 EXPORT_SYMBOL(cnmMemFree);
3340 EXPORT_SYMBOL(wlanExportGlueInfo);
3341 EXPORT_SYMBOL(bssInitForAP);
3342 EXPORT_SYMBOL(nicPmIndicateBssConnected);
3343 EXPORT_SYMBOL(rlmRspGenerateHtOpIE);
3344 EXPORT_SYMBOL(bssGenerateExtSuppRate_IE);
3345 EXPORT_SYMBOL(rlmRspGenerateErpIE);
3346 EXPORT_SYMBOL(rlmRspGenerateHtCapIE);
3347 EXPORT_SYMBOL(cnmGetStaRecByIndex);
3348 EXPORT_SYMBOL(rsnGenerateWpaNoneIE);
3349 EXPORT_SYMBOL(rlmRspGenerateExtCapIE);
3350 EXPORT_SYMBOL(rsnGenerateRSNIE);
3351 EXPORT_SYMBOL(rsnParseRsnIE);
3353 EXPORT_SYMBOL(wextSrchDesiredWPSIE);
3355 EXPORT_SYMBOL(mboxDummy);
3356 EXPORT_SYMBOL(saaFsmRunEventStart);
3357 EXPORT_SYMBOL(saaFsmRunEventAbort);
3358 EXPORT_SYMBOL(cnmP2PIsPermitted);
3359 EXPORT_SYMBOL(cnmBss40mBwPermitted);
3360 EXPORT_SYMBOL(mqmGenerateWmmParamIE);
3361 EXPORT_SYMBOL(cnmPreferredChannel);
3362 EXPORT_SYMBOL(bssAddStaRecToClientList);
3363 EXPORT_SYMBOL(nicQmUpdateWmmParms);
3364 EXPORT_SYMBOL(qmFreeAllByNetType);
3365 EXPORT_SYMBOL(wlanQueryInformation);
3366 EXPORT_SYMBOL(nicConfigPowerSaveProfile);
3367 EXPORT_SYMBOL(scanSearchExistingBssDesc);
3368 EXPORT_SYMBOL(scanAllocateBssDesc);
3369 EXPORT_SYMBOL(wlanProcessCommandQueue);
3370 EXPORT_SYMBOL(wlanAcquirePowerControl);
3371 EXPORT_SYMBOL(wlanReleasePowerControl);
3372 EXPORT_SYMBOL(wlanReleasePendingCMDbyNetwork);
3374 EXPORT_SYMBOL(aucDebugModule);
3375 EXPORT_SYMBOL(fgIsBusAccessFailed);
3376 EXPORT_SYMBOL(allocatedMemSize);
3377 EXPORT_SYMBOL(dumpMemory8);
3378 EXPORT_SYMBOL(dumpMemory32);
3380 EXPORT_SYMBOL(rlmDomainIsLegalChannel);
3381 EXPORT_SYMBOL(scnQuerySparseChannel);
3382 EXPORT_SYMBOL(rlmDomainGetChnlList);
3383 EXPORT_SYMBOL(p2pSetMulticastListWorkQueueWrapper);
3384 EXPORT_SYMBOL(nicUpdateRSSI);
3385 EXPORT_SYMBOL(nicCmdEventQueryLinkQuality);
3386 EXPORT_SYMBOL(kalGetMediaStateIndicated);
3387 EXPORT_SYMBOL(nicFreq2ChannelNum);
3388 EXPORT_SYMBOL(assocSendDisAssocFrame);
3389 EXPORT_SYMBOL(nicUpdateBeaconIETemplate);
3390 EXPORT_SYMBOL(rsnParseCheckForWFAInfoElem);
3391 EXPORT_SYMBOL(kalClearMgmtFramesByNetType);
3392 EXPORT_SYMBOL(kalClearSecurityFramesByNetType);
3393 EXPORT_SYMBOL(nicFreePendingTxMsduInfoByNetwork);
3394 EXPORT_SYMBOL(bssComposeBeaconProbeRespFrameHeaderAndFF);
3395 EXPORT_SYMBOL(bssBuildBeaconProbeRespFrameCommonIEs);
3396 EXPORT_SYMBOL(wlanoidSetWapiAssocInfo);
3397 EXPORT_SYMBOL(wlanoidSetWSCAssocInfo);