2 ** $Id: //Department/DaVinci/BRANCHES/MT662X_593X_WIFI_DRIVER_V2_3/os/linux/gl_init.c#3 $
6 \brief Main routines of Linux driver
8 This file contains the main routines of Linux driver for MediaTek Inc. 802.11
12 /*******************************************************************************
13 * Copyright (c) 2007 MediaTek Inc.
15 * All rights reserved. Copying, compilation, modification, distribution
16 * or any other use whatsoever of this material is strictly prohibited
17 * except in accordance with a Software License Agreement with
19 ********************************************************************************
22 /*******************************************************************************
25 * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND
26 * AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK
27 * SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE
28 * PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY
29 * DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
30 * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
31 * PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE
32 * ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY
33 * WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK
34 * SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY
35 * WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE
36 * FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO
37 * CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
39 * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
40 * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL
41 * BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT
42 * ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY
43 * BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
45 * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
46 * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT
47 * OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING
48 * THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN
49 * FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE
51 ********************************************************************************
58 ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
59 ** enable checksum offloading configuration as default
62 ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
63 ** sync for NVRAM warning scan result generation for CFG80211.
66 ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
70 ** [WCXRP00001269] [MT6620 Wi-Fi][Driver] cfg80211 porting merge back to DaVinci
71 ** cfg80211 support merge back from ALPS.JB to DaVinci - MT6620 Driver v2.3 branch.
73 * 07 17 2012 yuche.tsai
77 * 07 17 2012 yuche.tsai
79 * Fix compile error for JB.
81 * 07 17 2012 yuche.tsai
83 * Let netdev bring up.
85 * 07 17 2012 yuche.tsai
87 * Compile no error before trial run.
89 * 06 13 2012 yuche.tsai
91 * Update maintrunk driver.
92 * Add support for driver compose assoc request frame.
94 * 05 25 2012 yuche.tsai
99 * [WCXRP00001237] [MT6620 Wi-Fi][Driver] Show MAC address and MAC address source for ACS's convenience
100 * show MAC address & source while initiliazation
102 * 03 02 2012 terry.wu
104 * EXPORT_SYMBOL(rsnParseCheckForWFAInfoElem);.
106 * 03 02 2012 terry.wu
108 * Snc CFG80211 modification for ICS migration from branch 2.2.
110 * 03 02 2012 terry.wu
112 * Sync CFG80211 modification from branch 2,2.
114 * 03 02 2012 terry.wu
116 * Enable CFG80211 Support.
118 * 12 22 2011 george.huang
119 * [WCXRP00000905] [MT6628 Wi-Fi][FW] Code refinement for ROM/ RAM module dependency
120 * using global variable instead of stack for setting wlanoidSetNetworkAddress(), due to buffer may be released before TX thread handling
122 * 11 18 2011 yuche.tsai
124 * CONFIG P2P support RSSI query, default turned off.
126 * 11 14 2011 yuche.tsai
127 * [WCXRP00001107] [Volunteer Patch][Driver] Large Network Type index assert in FW issue.
128 * Fix large network type index assert in FW issue.
130 * 11 14 2011 cm.chang
132 * Fix compiling warning
134 * 11 11 2011 yuche.tsai
136 * Fix work thread cancel issue.
139 * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
140 * 1. eliminaite direct calls to printk in porting layer.
141 * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
143 * 10 06 2011 eddie.chen
144 * [WCXRP00001027] [MT6628 Wi-Fi][Firmware/Driver] Tx fragmentation
145 * Add rlmDomainGetChnlList symbol.
147 * 09 22 2011 cm.chang
149 * Safer writng stype to avoid unitialized regitry structure
151 * 09 21 2011 cm.chang
152 * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
153 * Avoid possible structure alignment problem
155 * 09 20 2011 chinglan.wang
156 * [WCXRP00000989] [WiFi Direct] [Driver] Add a new io control API to start the formation for the sigma test.
159 * 09 08 2011 cm.chang
160 * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
161 * Use new fields ucChannelListMap and ucChannelListIndex in NVRAM
163 * 08 31 2011 cm.chang
164 * [WCXRP00000969] [MT6620 Wi-Fi][Driver][FW] Channel list for 5G band based on country code
168 * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time
169 * expose scnQuerySparseChannel() for P2P-FSM.
172 * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time
173 * sparse channel detection:
174 * driver: collect sparse channel information with scan-done event
176 * 08 02 2011 yuche.tsai
177 * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a disconnecting device issue.
178 * Fix GO send deauth frame issue.
181 * [WCXRP00000839] [MT6620 Wi-Fi][Driver] Add the dumpMemory8 and dumpMemory32 EXPORT_SYMBOL
182 * Add the dumpMemory8 symbol export for debug mode.
184 * 07 06 2011 terry.wu
185 * [WCXRP00000735] [MT6620 Wi-Fi][BoW][FW/Driver] Protect BoW connection establishment
186 * Improve BoW connection establishment speed.
188 * 07 05 2011 yuche.tsai
189 * [WCXRP00000821] [Volunteer Patch][WiFi Direct][Driver] WiFi Direct Connection Speed Issue
190 * Export one symbol for enhancement.
192 * 06 13 2011 eddie.chen
193 * [WCXRP00000779] [MT6620 Wi-Fi][DRV] Add tx rx statistics in linux and use netif_rx_ni
194 * Add tx rx statistics and netif_rx_ni.
197 * [WCXRP00000749] [MT6620 Wi-Fi][Driver] Add band edge tx power control to Wi-Fi NVRAM
198 * invoke CMD_ID_SET_EDGE_TXPWR_LIMIT when there is valid data exist in NVRAM content.
201 * [WCXRP00000734] [MT6620 Wi-Fi][Driver] Pass PHY_PARAM in NVRAM to firmware domain
202 * pass PHY_PARAM in NVRAM from driver to firmware.
204 * 05 09 2011 jeffrey.chang
205 * [WCXRP00000710] [MT6620 Wi-Fi] Support pattern filter update function on IP address change
206 * support ARP filter through kernel notifier
208 * 05 03 2011 chinghwa.yu
209 * [WCXRP00000065] Update BoW design and settings
210 * Use kalMemAlloc to allocate event buffer for kalIndicateBOWEvent.
212 * 04 27 2011 george.huang
213 * [WCXRP00000684] [MT6620 Wi-Fi][Driver] Support P2P setting ARP filter
214 * Support P2P ARP filter setting on early suspend/ late resume
216 * 04 18 2011 terry.wu
217 * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
218 * Remove flag CFG_WIFI_DIRECT_MOVED.
220 * 04 15 2011 chinghwa.yu
221 * [WCXRP00000065] Update BoW design and settings
222 * Add BOW short range mode.
224 * 04 14 2011 yuche.tsai
225 * [WCXRP00000646] [Volunteer Patch][MT6620][FW/Driver] Sigma Test Modification for some test case.
226 * Modify some driver connection flow or behavior to pass Sigma test more easier..
228 * 04 12 2011 cm.chang
229 * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
232 * 04 11 2011 george.huang
233 * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode
234 * export wlan functions to p2p
237 * [WCXRP00000623] [MT6620 Wi-Fi][Driver] use ARCH define to distinguish PC Linux driver
238 * Use CONFIG_X86 instead of PC_LINUX_DRIVER_USE option to have proper compile settting for PC Linux driver
241 * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
242 * glBusFreeIrq() should use the same pvCookie as glBusSetIrq() or request_irq()/free_irq() won't work as a pair.
244 * 04 08 2011 eddie.chen
245 * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
249 * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
250 * 1. do not check for pvData inside wlanNetCreate() due to it is NULL for eHPI port
251 * 2. update perm_addr as well for MAC address
252 * 3. not calling check_mem_region() anymore for eHPI
253 * 4. correct MSC_CS macro for 0-based notation
256 * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for RESET_START and RESET_END events
260 * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for RESET_START and RESET_END events
261 * implement kernel-to-userspace communication via generic netlink socket for whole-chip resetting mechanism
264 * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
265 * apply multi-queue operation only for linux kernel > 2.6.26
268 * [WCXRP00000592] [MT6620 Wi-Fi][Driver] Support PC Linux Environment Driver Build
269 * Add a compiler option "PC_LINUX_DRIVER_USE" for building driver in PC Linux environment.
272 * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
273 * portability for compatible with linux 2.6.12.
276 * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
277 * improve portability for awareness of early version of linux kernel and wireless extension.
280 * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
281 * portability improvement
283 * 03 18 2011 jeffrey.chang
284 * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
285 * remove early suspend functions
288 * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage after system running for a long period
289 * reverse order to prevent probing racing.
292 * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage after system running for a long period
293 * 1. pre-allocate physical continuous buffer while module is being loaded
294 * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer
296 * The windows part remained the same as before, but added similiar APIs to hide the difference.
298 * 03 15 2011 jeffrey.chang
299 * [WCXRP00000558] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] refine the queue selection algorithm for WMM
300 * refine the queue_select function
303 * [WCXRP00000532] [MT6620 Wi-Fi][Driver] Migrate NVRAM configuration procedures from MT6620 E2 to MT6620 E3
304 * deprecate configuration used by MT6620 E2
306 * 03 10 2011 terry.wu
307 * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration
308 * Remove unnecessary assert and message.
310 * 03 08 2011 terry.wu
311 * [WCXRP00000505] [MT6620 Wi-Fi][Driver/FW] WiFi Direct Integration
312 * Export nicQmUpdateWmmParms.
314 * 03 03 2011 jeffrey.chang
315 * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
316 * support concurrent network
318 * 03 03 2011 jeffrey.chang
319 * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
320 * modify net device relative functions to support multiple H/W queues
322 * 02 24 2011 george.huang
323 * [WCXRP00000495] [MT6620 Wi-Fi][FW] Support pattern filter for unwanted ARP frames
324 * Support ARP filter during suspended
327 * [WCXRP00000482] [MT6620 Wi-Fi][Driver] Simplify logic for checking NVRAM existence in driver domain
328 * simplify logic for checking NVRAM existence only once.
330 * 02 17 2011 terry.wu
331 * [WCXRP00000459] [MT6620 Wi-Fi][Driver] Fix deference null pointer problem in wlanRemove
332 * Fix deference a null pointer problem in wlanRemove.
334 * 02 16 2011 jeffrey.chang
338 * 02 16 2011 jeffrey.chang
340 * Add query ipv4 and ipv6 address during early suspend and late resume
342 * 02 15 2011 jeffrey.chang
344 * to support early suspend in android
346 * 02 11 2011 yuche.tsai
347 * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
348 * Add one more export symbol.
350 * 02 10 2011 yuche.tsai
351 * [WCXRP00000431] [Volunteer Patch][MT6620][Driver] Add MLME support for deauthentication under AP(Hot-Spot) mode.
352 * Add RX deauthentication & disassociation process under Hot-Spot mode.
354 * 02 09 2011 terry.wu
355 * [WCXRP00000383] [MT6620 Wi-Fi][Driver] Separate WiFi and P2P driver into two modules
356 * Halt p2p module init and exit until TxThread finished p2p register and unregister.
358 * 02 08 2011 george.huang
359 * [WCXRP00000422] [MT6620 Wi-Fi][Driver] support query power mode OID handler
360 * Support querying power mode OID.
362 * 02 08 2011 yuche.tsai
363 * [WCXRP00000421] [Volunteer Patch][MT6620][Driver] Fix incorrect SSID length Issue
364 * Export Deactivation Network.
366 * 02 01 2011 jeffrey.chang
367 * [WCXRP00000414] KAL Timer is not unregistered when driver not loaded
368 * Unregister the KAL timer during driver unloading
370 * 01 26 2011 cm.chang
371 * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
372 * Allocate system RAM if fixed message or mgmt buffer is not available
375 * [WCXRP00000371] [MT6620 Wi-Fi][Driver] make linux glue layer portable for Android 2.3.1 with Linux 2.6.35.7
376 * add compile option to check linux version 2.6.35 for different usage of system API to improve portability
379 * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP
380 * implementation of separate BT_OVER_WIFI data path.
383 * [WCXRP00000349] [MT6620 Wi-Fi][Driver] make kalIoctl() of linux port as a thread safe API to avoid potential issues due to multiple access
384 * use mutex to protect kalIoctl() for thread safe.
387 * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease physically continous memory demands
388 * separate kalMemAlloc() into virtually-continous and physically-continous type to ease slab system pressure
391 * [WCXRP00000265] [MT6620 Wi-Fi][Driver] Remove set_mac_address routine from legacy Wi-Fi Android driver
392 * remove set MAC address. MAC address is always loaded from NVRAM instead.
394 * 12 10 2010 kevin.huang
395 * [WCXRP00000128] [MT6620 Wi-Fi][Driver] Add proc support to Android Driver for debug and driver status check
396 * Add Linux Proc Support
398 * 11 01 2010 yarco.yang
399 * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform
400 * Add GPIO debug function
403 * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000150] [MT6620 Wi-Fi][Driver] Add implementation for querying current TX rate from firmware auto rate module
404 * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
405 * 2) Remove CNM CH-RECOVER event handling
406 * 3) cfg read/write API renamed with kal prefix for unified naming rules.
409 * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command
410 * 1) update NVRAM content template to ver 1.02
411 * 2) add compile option for querying NIC capability (default: off)
412 * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting
413 * 4) correct auto-rate compiler error under linux (treat warning as error)
414 * 5) simplify usage of NVRAM and REG_INFO_T
415 * 6) add version checking between driver and firmware
417 * 10 21 2010 chinghwa.yu
418 * [WCXRP00000065] Update BoW design and settings
421 * 10 19 2010 jeffrey.chang
422 * [WCXRP00000120] [MT6620 Wi-Fi][Driver] Refine linux kernel module to the license of MTK propietary and enable MTK HIF by default
423 * Refine linux kernel module to the license of MTK and enable MTK HIF
425 * 10 18 2010 jeffrey.chang
426 * [WCXRP00000106] [MT6620 Wi-Fi][Driver] Enable setting multicast callback in Android
430 * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android
431 * complete implementation of Android NVRAM access
433 * 09 27 2010 chinghwa.yu
434 * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000065] Update BoW design and settings
435 * Update BCM/BoW design and settings.
438 * [WCXRP00000051] [MT6620 Wi-Fi][Driver] WHQL test fail in MAC address changed item
439 * use firmware reported mac address right after wlanAdapterStart() as permanent address
441 * 09 21 2010 kevin.huang
442 * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
443 * Eliminate Linux Compile Warning
445 * 09 03 2010 kevin.huang
447 * Refine #include sequence and solve recursive/nested #include issue
451 * adding the wapi support for integration test.
453 * 08 18 2010 yarco.yang
455 * 1. Fixed HW checksum offload function not work under Linux issue.
456 * 2. Add debug message.
458 * 08 16 2010 yarco.yang
462 * 08 02 2010 jeffrey.chang
464 * 1) modify tx service thread to avoid busy looping
465 * 2) add spin lock declartion for linux build
467 * 07 29 2010 jeffrey.chang
469 * fix memory leak for module unloading
471 * 07 28 2010 jeffrey.chang
473 * 1) remove unused spinlocks
474 * 2) enable encyption ioctls
475 * 3) fix scan ioctl which may cause supplicant to hang
477 * 07 23 2010 jeffrey.chang
479 * bug fix: allocate regInfo when disabling firmware download
481 * 07 23 2010 jeffrey.chang
483 * use glue layer api to decrease or increase counter atomically
485 * 07 22 2010 jeffrey.chang
489 * 07 19 2010 jeffrey.chang
491 * modify cmd/data path for new design
495 * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
497 * 06 06 2010 kevin.huang
498 * [WPD00003832][MT6620 5931] Create driver base
499 * [MT6620 5931] Create driver base
501 * 05 26 2010 jeffrey.chang
502 * [WPD00003826]Initial import for Linux port
503 * 1) Modify set mac address code
504 * 2) remove power managment macro
507 * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
508 * implement basic wi-fi direct framework
510 * 05 07 2010 jeffrey.chang
511 * [WPD00003826]Initial import for Linux port
512 * prevent supplicant accessing driver during resume
515 * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
516 * add basic framework for implementating P2P driver hook.
518 * 04 27 2010 jeffrey.chang
519 * [WPD00003826]Initial import for Linux port
520 * 1) fix firmware download bug
521 * 2) remove query statistics for acelerating firmware download
523 * 04 27 2010 jeffrey.chang
524 * [WPD00003826]Initial import for Linux port
525 * follow Linux's firmware framework, and remove unused kal API
527 * 04 21 2010 jeffrey.chang
528 * [WPD00003826]Initial import for Linux port
529 * add for private ioctl support
531 * 04 19 2010 jeffrey.chang
532 * [WPD00003826]Initial import for Linux port
533 * Query statistics from firmware
535 * 04 19 2010 jeffrey.chang
536 * [WPD00003826]Initial import for Linux port
537 * modify tcp/ip checksum offload flags
539 * 04 16 2010 jeffrey.chang
540 * [WPD00003826]Initial import for Linux port
541 * fix tcp/ip checksum offload bug
544 * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
545 * add framework for BT-over-Wi-Fi support.
546 * * * * * * * * * * * * * * * * * 1) prPendingCmdInfo is replaced by queue for multiple handler capability
547 * * * * * * * * * * * * * * * * * 2) command sequence number is now increased atomically
548 * * * * * * * * * * * * * * * * * 3) private data could be hold and taken use for other purpose
550 * 04 09 2010 jeffrey.chang
551 * [WPD00003826]Initial import for Linux port
554 * 04 07 2010 jeffrey.chang
555 * [WPD00003826]Initial import for Linux port
556 * Set MAC address from firmware
559 * [WPD00001943]Create WiFi test driver framework on WinXP
560 * rWlanInfo should be placed at adapter rather than glue due to most operations
561 * * * * * * are done in adapter layer.
563 * 04 07 2010 jeffrey.chang
564 * [WPD00003826]Initial import for Linux port
565 * (1)improve none-glue code portability
566 * * (2) disable set Multicast address during atomic context
568 * 04 06 2010 jeffrey.chang
569 * [WPD00003826]Initial import for Linux port
570 * adding debug module
573 * [WPD00003816][MT6620 Wi-Fi] Adding the security support
574 * modify the wapi related code for new driver's design.
576 * 03 30 2010 jeffrey.chang
577 * [WPD00003826]Initial import for Linux port
578 * emulate NDIS Pending OID facility
580 * 03 26 2010 jeffrey.chang
581 * [WPD00003826]Initial import for Linux port
582 * fix f/w download start and load address by using config.h
584 * 03 26 2010 jeffrey.chang
585 * [WPD00003826]Initial import for Linux port
586 * [WPD00003826] Initial import for Linux port
587 * adding firmware download support
589 * 03 24 2010 jeffrey.chang
590 * [WPD00003826]Initial import for Linux port
591 * initial import for Linux port
592 ** \main\maintrunk.MT5921\52 2009-10-27 22:49:59 GMT mtk01090
593 ** Fix compile error for Linux EHPI driver
594 ** \main\maintrunk.MT5921\51 2009-10-20 17:38:22 GMT mtk01090
595 ** Refine driver unloading and clean up procedure. Block requests, stop main thread and clean up queued requests, and then stop hw.
596 ** \main\maintrunk.MT5921\50 2009-10-08 10:33:11 GMT mtk01090
597 ** Avoid accessing private data of net_device directly. Replace with netdev_priv(). Add more checking for input parameters and pointers.
598 ** \main\maintrunk.MT5921\49 2009-09-28 20:19:05 GMT mtk01090
599 ** Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel.
600 ** \main\maintrunk.MT5921\48 2009-09-03 13:58:46 GMT mtk01088
601 ** remove non-used code
602 ** \main\maintrunk.MT5921\47 2009-09-03 11:40:25 GMT mtk01088
603 ** adding the module parameter for wapi
604 ** \main\maintrunk.MT5921\46 2009-08-18 22:56:41 GMT mtk01090
605 ** Add Linux SDIO (with mmc core) support.
606 ** Add Linux 2.6.21, 2.6.25, 2.6.26.
607 ** Fix compile warning in Linux.
608 ** \main\maintrunk.MT5921\45 2009-07-06 20:53:00 GMT mtk01088
609 ** adding the code to check the wapi 1x frame
610 ** \main\maintrunk.MT5921\44 2009-06-23 23:18:55 GMT mtk01090
611 ** Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support
612 ** \main\maintrunk.MT5921\43 2009-02-16 23:46:51 GMT mtk01461
613 ** Revise the order of increasing u4TxPendingFrameNum because of CFG_TX_RET_TX_CTRL_EARLY
614 ** \main\maintrunk.MT5921\42 2009-01-22 13:11:59 GMT mtk01088
615 ** set the tid and 1x value at same packet reserved field
616 ** \main\maintrunk.MT5921\41 2008-10-20 22:43:53 GMT mtk01104
617 ** Fix wrong variable name "prDev" in wlanStop()
618 ** \main\maintrunk.MT5921\40 2008-10-16 15:37:10 GMT mtk01461
619 ** add handle WLAN_STATUS_SUCCESS in wlanHardStartXmit() for CFG_TX_RET_TX_CTRL_EARLY
620 ** \main\maintrunk.MT5921\39 2008-09-25 15:56:21 GMT mtk01461
621 ** Update driver for Code review
622 ** \main\maintrunk.MT5921\38 2008-09-05 17:25:07 GMT mtk01461
623 ** Update Driver for Code Review
624 ** \main\maintrunk.MT5921\37 2008-09-02 10:57:06 GMT mtk01461
625 ** Update driver for code review
626 ** \main\maintrunk.MT5921\36 2008-08-05 01:53:28 GMT mtk01461
627 ** Add support for linux statistics
628 ** \main\maintrunk.MT5921\35 2008-08-04 16:52:58 GMT mtk01461
629 ** Fix ASSERT if removing module in BG_SSID_SCAN state
630 ** \main\maintrunk.MT5921\34 2008-06-13 22:52:24 GMT mtk01461
631 ** Revise status code handling in wlanHardStartXmit() for WLAN_STATUS_SUCCESS
632 ** \main\maintrunk.MT5921\33 2008-05-30 18:56:53 GMT mtk01461
633 ** Not use wlanoidSetCurrentAddrForLinux()
634 ** \main\maintrunk.MT5921\32 2008-05-30 14:39:40 GMT mtk01461
635 ** Remove WMM Assoc Flag
636 ** \main\maintrunk.MT5921\31 2008-05-23 10:26:40 GMT mtk01084
637 ** modify wlanISR interface
638 ** \main\maintrunk.MT5921\30 2008-05-03 18:52:36 GMT mtk01461
639 ** Fix Unset Broadcast filter when setMulticast
640 ** \main\maintrunk.MT5921\29 2008-05-03 15:17:26 GMT mtk01461
641 ** Move Query Media Status to GLUE
642 ** \main\maintrunk.MT5921\28 2008-04-24 22:48:21 GMT mtk01461
643 ** Revise set multicast function by using windows oid style for LP own back
644 ** \main\maintrunk.MT5921\27 2008-04-24 12:00:08 GMT mtk01461
645 ** Fix multicast setting in Linux and add comment
646 ** \main\maintrunk.MT5921\26 2008-03-28 10:40:22 GMT mtk01461
647 ** Fix set mac address func in Linux
648 ** \main\maintrunk.MT5921\25 2008-03-26 15:37:26 GMT mtk01461
649 ** Add set MAC Address
650 ** \main\maintrunk.MT5921\24 2008-03-26 14:24:53 GMT mtk01461
651 ** For Linux, set net_device has feature with checksum offload by default
652 ** \main\maintrunk.MT5921\23 2008-03-11 14:50:52 GMT mtk01461
654 ** \main\maintrunk.MT5921\22 2008-02-29 15:35:20 GMT mtk01088
655 ** add 1x decide code for sw port control
656 ** \main\maintrunk.MT5921\21 2008-02-21 15:01:54 GMT mtk01461
657 ** Rearrange the set off place of GLUE spin lock in HardStartXmit
658 ** \main\maintrunk.MT5921\20 2008-02-12 23:26:50 GMT mtk01461
659 ** Add debug option - Packet Order for Linux and add debug level - Event
660 ** \main\maintrunk.MT5921\19 2007-12-11 00:11:12 GMT mtk01461
661 ** Fix SPIN_LOCK protection
662 ** \main\maintrunk.MT5921\18 2007-11-30 17:02:25 GMT mtk01425
663 ** 1. Set Rx multicast packets mode before setting the address list
664 ** \main\maintrunk.MT5921\17 2007-11-26 19:44:24 GMT mtk01461
665 ** Add OS_TIMESTAMP to packet
666 ** \main\maintrunk.MT5921\16 2007-11-21 15:47:20 GMT mtk01088
667 ** fixed the unload module issue
668 ** \main\maintrunk.MT5921\15 2007-11-07 18:37:38 GMT mtk01461
669 ** Fix compile warnning
670 ** \main\maintrunk.MT5921\14 2007-11-02 01:03:19 GMT mtk01461
671 ** Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning
672 ** \main\maintrunk.MT5921\13 2007-10-30 10:42:33 GMT mtk01425
673 ** 1. Refine for multicast list
674 ** \main\maintrunk.MT5921\12 2007-10-25 18:08:13 GMT mtk01461
675 ** Add VOIP SCAN Support & Refine Roaming
676 ** Revision 1.4 2007/07/05 07:25:33 MTK01461
677 ** Add Linux initial code, modify doc, add 11BB, RF init code
679 ** Revision 1.3 2007/06/27 02:18:50 MTK01461
680 ** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API
682 ** Revision 1.2 2007/06/25 06:16:24 MTK01461
683 ** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API
687 /*******************************************************************************
688 * C O M P I L E R F L A G S
689 ********************************************************************************
692 /*******************************************************************************
693 * E X T E R N A L R E F E R E N C E S
694 ********************************************************************************
698 #include "wlan_lib.h"
700 #include "gl_cfg80211.h"
703 /*******************************************************************************
705 ********************************************************************************
707 //#define MAX_IOREQ_NUM 10
709 BOOLEAN fgIsUnderEarlierSuspend = false;
711 struct semaphore g_halt_sem;
712 int g_u4HaltFlag = 0;
715 /*******************************************************************************
717 ********************************************************************************
719 /* Tasklet mechanism is like buttom-half in Linux. We just want to
720 * send a signal to OS for interrupt defer processing. All resources
721 * are NOT allowed reentry, so txPacket, ISR-DPC and ioctl must avoid preempty.
723 typedef struct _WLANDEV_INFO_T {
724 struct net_device *prDev;
725 } WLANDEV_INFO_T, *P_WLANDEV_INFO_T;
727 /*******************************************************************************
728 * P U B L I C D A T A
729 ********************************************************************************
732 MODULE_AUTHOR(NIC_AUTHOR);
733 MODULE_DESCRIPTION(NIC_DESC);
734 MODULE_SUPPORTED_DEVICE(NIC_NAME);
735 extern void wlanRegisterNotifier(void);
736 extern void wlanUnregisterNotifier(void);
737 extern int mt5931_power_off(void);
740 MODULE_LICENSE("MTK Propietary");
742 MODULE_LICENSE("GPL");
745 #define NIC_INF_NAME "wlan%d" /* interface name */
746 #define LEGACY_IN_AP_MODE "legacy_wlan%d" /*interface name in AP mode*/
747 extern volatile int PowerOnIFname;
751 UINT_8 aucDebugModule[DBG_MODULE_NUM];
752 UINT_32 u4DebugModule = 0;
755 //4 2007/06/26, mikewu, now we don't use this, we just fix the number of wlan device to 1
756 static WLANDEV_INFO_T arWlanDevInfo[CFG_MAX_WLAN_DEVICES] = {{0}};
757 static UINT_32 u4WlanDevNum = 0; /* How many NICs coexist now */
759 /*******************************************************************************
760 * P R I V A T E D A T A
761 ********************************************************************************
763 #if CFG_ENABLE_WIFI_DIRECT
764 static SUB_MODULE_HANDLER rSubModHandler[SUB_MODULE_NUM] = {{NULL}};
767 #define CHAN2G(_channel, _freq, _flags) \
769 .band = IEEE80211_BAND_2GHZ, \
770 .center_freq = (_freq), \
771 .hw_value = (_channel), \
773 .max_antenna_gain = 0, \
776 static struct ieee80211_channel mtk_2ghz_channels[] = {
793 #define CHAN5G(_channel, _flags) \
795 .band = IEEE80211_BAND_5GHZ, \
796 .center_freq = 5000 + (5 * (_channel)), \
797 .hw_value = (_channel), \
799 .max_antenna_gain = 0, \
802 static struct ieee80211_channel mtk_5ghz_channels[] = {
803 CHAN5G(34, 0), CHAN5G(36, 0),
804 CHAN5G(38, 0), CHAN5G(40, 0),
805 CHAN5G(42, 0), CHAN5G(44, 0),
806 CHAN5G(46, 0), CHAN5G(48, 0),
807 CHAN5G(52, 0), CHAN5G(56, 0),
808 CHAN5G(60, 0), CHAN5G(64, 0),
809 CHAN5G(100, 0), CHAN5G(104, 0),
810 CHAN5G(108, 0), CHAN5G(112, 0),
811 CHAN5G(116, 0), CHAN5G(120, 0),
812 CHAN5G(124, 0), CHAN5G(128, 0),
813 CHAN5G(132, 0), CHAN5G(136, 0),
814 CHAN5G(140, 0), CHAN5G(149, 0),
815 CHAN5G(153, 0), CHAN5G(157, 0),
816 CHAN5G(161, 0), CHAN5G(165, 0),
817 CHAN5G(169, 0), CHAN5G(173, 0),
818 CHAN5G(184, 0), CHAN5G(188, 0),
819 CHAN5G(192, 0), CHAN5G(196, 0),
820 CHAN5G(200, 0), CHAN5G(204, 0),
821 CHAN5G(208, 0), CHAN5G(212, 0),
825 /* for cfg80211 - rate table */
826 static struct ieee80211_rate mtk_rates[] = {
827 RATETAB_ENT(10, 0x1000, 0),
828 RATETAB_ENT(20, 0x1001, 0),
829 RATETAB_ENT(55, 0x1002, 0),
830 RATETAB_ENT(110, 0x1003, 0), /* 802.11b */
831 RATETAB_ENT(60, 0x2000, 0),
832 RATETAB_ENT(90, 0x2001, 0),
833 RATETAB_ENT(120, 0x2002, 0),
834 RATETAB_ENT(180, 0x2003, 0),
835 RATETAB_ENT(240, 0x2004, 0),
836 RATETAB_ENT(360, 0x2005, 0),
837 RATETAB_ENT(480, 0x2006, 0),
838 RATETAB_ENT(540, 0x2007, 0), /* 802.11a/g */
841 #define mtk_a_rates (mtk_rates + 4)
842 #define mtk_a_rates_size (sizeof(mtk_rates) / sizeof(mtk_rates[0]) - 4)
843 #define mtk_g_rates (mtk_rates + 0)
844 #define mtk_g_rates_size (sizeof(mtk_rates) / sizeof(mtk_rates[0]) - 0)
846 #define MT6620_MCS_INFO \
848 .rx_mask = {0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0},\
850 .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \
853 #define MT6620_HT_CAP \
855 .ht_supported = true, \
856 .cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 \
857 | IEEE80211_HT_CAP_SM_PS \
858 | IEEE80211_HT_CAP_GRN_FLD \
859 | IEEE80211_HT_CAP_SGI_20 \
860 | IEEE80211_HT_CAP_SGI_40, \
861 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, \
862 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE, \
863 .mcs = MT6620_MCS_INFO, \
866 /* public for both Legacy Wi-Fi / P2P access */
867 struct ieee80211_supported_band mtk_band_2ghz = {
868 .band = IEEE80211_BAND_2GHZ,
869 .channels = mtk_2ghz_channels,
870 .n_channels = ARRAY_SIZE(mtk_2ghz_channels),
871 .bitrates = mtk_g_rates,
872 .n_bitrates = mtk_g_rates_size,
873 .ht_cap = MT6620_HT_CAP,
876 /* public for both Legacy Wi-Fi / P2P access */
877 struct ieee80211_supported_band mtk_band_5ghz = {
878 .band = IEEE80211_BAND_5GHZ,
879 .channels = mtk_5ghz_channels,
880 .n_channels = ARRAY_SIZE(mtk_5ghz_channels),
881 .bitrates = mtk_a_rates,
882 .n_bitrates = mtk_a_rates_size,
883 .ht_cap = MT6620_HT_CAP,
886 static const UINT_32 mtk_cipher_suites[] = {
887 /* keep WEP first, it may be removed below */
888 WLAN_CIPHER_SUITE_WEP40,
889 WLAN_CIPHER_SUITE_WEP104,
890 WLAN_CIPHER_SUITE_TKIP,
891 WLAN_CIPHER_SUITE_CCMP,
893 /* keep last -- depends on hw flags! */
894 WLAN_CIPHER_SUITE_AES_CMAC
897 static struct cfg80211_ops mtk_wlan_ops = {
898 .change_virtual_intf = mtk_cfg80211_change_iface,
899 .add_key = mtk_cfg80211_add_key,
900 .get_key = mtk_cfg80211_get_key,
901 .del_key = mtk_cfg80211_del_key,
902 .set_default_key = mtk_cfg80211_set_default_key,
903 .get_station = mtk_cfg80211_get_station,
904 .scan = mtk_cfg80211_scan,
905 .connect = mtk_cfg80211_connect,
906 .disconnect = mtk_cfg80211_disconnect,
907 .join_ibss = mtk_cfg80211_join_ibss,
908 .leave_ibss = mtk_cfg80211_leave_ibss,
909 .set_power_mgmt = mtk_cfg80211_set_power_mgmt,
910 .set_pmksa = mtk_cfg80211_set_pmksa,
911 .del_pmksa = mtk_cfg80211_del_pmksa,
912 .flush_pmksa = mtk_cfg80211_flush_pmksa,
914 /* Action Frame TX/RX */
915 .remain_on_channel = mtk_cfg80211_remain_on_channel,
916 .cancel_remain_on_channel = mtk_cfg80211_cancel_remain_on_channel,
917 .mgmt_tx = mtk_cfg80211_mgmt_tx,
918 .mgmt_tx_cancel_wait = mtk_cfg80211_mgmt_tx_cancel_wait,
919 #ifdef CONFIG_NL80211_TESTMODE
920 .testmode_cmd = mtk_cfg80211_testmode_cmd,
924 /*******************************************************************************
926 ********************************************************************************
929 /*******************************************************************************
930 * F U N C T I O N D E C L A R A T I O N S
931 ********************************************************************************
934 #if defined(CONFIG_HAS_EARLYSUSPEND)
935 extern int glRegisterEarlySuspend(
936 struct early_suspend *prDesc,
937 early_suspend_callback wlanSuspend,
938 late_resume_callback wlanResume);
940 extern int glUnregisterEarlySuspend(struct early_suspend *prDesc);
943 /*******************************************************************************
945 ********************************************************************************
948 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
949 /*----------------------------------------------------------------------------*/
951 * \brief Override the implementation of select queue
953 * \param[in] dev Pointer to struct net_device
954 * \param[in] skb Pointer to struct skb_buff
958 /*----------------------------------------------------------------------------*/
959 unsigned int _cfg80211_classify8021d(struct sk_buff *skb)
961 unsigned int dscp = 0;
963 /* skb->priority values from 256->263 are magic values
964 * directly indicate a specific 802.1d priority. This is
965 * to allow 802.1d priority to be passed directly in from
969 if (skb->priority >= 256 && skb->priority <= 263) {
970 return skb->priority - 256;
972 switch (skb->protocol) {
973 case htons(ETH_P_IP):
974 dscp = ip_hdr(skb)->tos & 0xfc;
981 static const UINT_16 au16Wlan1dToQueueIdx[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
985 struct net_device *dev,
988 skb->priority = _cfg80211_classify8021d(skb);
990 return au16Wlan1dToQueueIdx[skb->priority];
995 /*----------------------------------------------------------------------------*/
997 * \brief Load NVRAM data and translate it into REG_INFO_T
999 * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T
1000 * \param[out] prRegInfo Pointer to struct REG_INFO_T
1004 /*----------------------------------------------------------------------------*/
1007 IN P_GLUE_INFO_T prGlueInfo,
1008 OUT P_REG_INFO_T prRegInfo
1018 if((!prGlueInfo) || (!prRegInfo)) {
1022 if(kalCfgDataRead16(prGlueInfo,
1023 sizeof(WIFI_CFG_PARAM_STRUCT) - sizeof(UINT_16),
1024 (PUINT_16)aucTmp) == TRUE) {
1025 prGlueInfo->fgNvramAvailable = TRUE;
1028 for (i = 0 ; i < sizeof(PARAM_MAC_ADDR_LEN) ; i += sizeof(UINT_16)) {
1029 kalCfgDataRead16(prGlueInfo,
1030 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucMacAddress) + i,
1031 (PUINT_16) (((PUINT_8)prRegInfo->aucMacAddr) + i));
1034 // load country code
1035 kalCfgDataRead16(prGlueInfo,
1036 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucCountryCode[0]),
1039 // cast to wide characters
1040 prRegInfo->au2CountryCode[0] = (UINT_16) aucTmp[0];
1041 prRegInfo->au2CountryCode[1] = (UINT_16) aucTmp[1];
1043 // load default normal TX power
1044 for (i = 0 ; i < sizeof(TX_PWR_PARAM_T) ; i += sizeof(UINT_16)) {
1045 kalCfgDataRead16(prGlueInfo,
1046 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, rTxPwr) + i,
1047 (PUINT_16) (((PUINT_8)&(prRegInfo->rTxPwr)) + i));
1050 // load feature flags
1051 kalCfgDataRead16(prGlueInfo,
1052 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucTxPwrValid),
1054 prRegInfo->ucTxPwrValid = aucTmp[0];
1055 prRegInfo->ucSupport5GBand = aucTmp[1];
1057 kalCfgDataRead16(prGlueInfo,
1058 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, uc2G4BwFixed20M),
1060 prRegInfo->uc2G4BwFixed20M = aucTmp[0];
1061 prRegInfo->uc5GBwFixed20M = aucTmp[1];
1063 kalCfgDataRead16(prGlueInfo,
1064 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucEnable5GBand),
1066 prRegInfo->ucEnable5GBand = aucTmp[0];
1068 /* load EFUSE overriding part */
1069 for (i = 0 ; i < sizeof(prRegInfo->aucEFUSE) ; i += sizeof(UINT_16)) {
1070 kalCfgDataRead16(prGlueInfo,
1071 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucEFUSE) + i,
1072 (PUINT_16) (((PUINT_8)&(prRegInfo->aucEFUSE)) + i));
1075 /* load band edge tx power control */
1076 kalCfgDataRead16(prGlueInfo,
1077 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, fg2G4BandEdgePwrUsed),
1079 prRegInfo->fg2G4BandEdgePwrUsed = (BOOLEAN)aucTmp[0];
1081 prRegInfo->cBandEdgeMaxPwrCCK = (INT_8)aucTmp[1];
1083 kalCfgDataRead16(prGlueInfo,
1084 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, cBandEdgeMaxPwrOFDM20),
1086 prRegInfo->cBandEdgeMaxPwrOFDM20 = (INT_8)aucTmp[0];
1087 prRegInfo->cBandEdgeMaxPwrOFDM40 = (INT_8)aucTmp[1];
1090 /* load regulation subbands */
1091 kalCfgDataRead16(prGlueInfo,
1092 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, ucRegChannelListMap),
1094 prRegInfo->eRegChannelListMap = (ENUM_REG_CH_MAP_T) aucTmp[0];
1095 prRegInfo->ucRegChannelListIndex = aucTmp[1];
1097 if (prRegInfo->eRegChannelListMap == REG_CH_MAP_CUSTOMIZED) {
1098 for (i = 0 ; i < MAX_SUBBAND_NUM; i++) {
1099 pucDest = (PUINT_8) &prRegInfo->rDomainInfo.rSubBand[i];
1100 for (j = 0; j < 6; j += sizeof(UINT_16)) {
1101 kalCfgDataRead16(prGlueInfo,
1102 OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucRegSubbandInfo)
1106 *pucDest++ = aucTmp[0];
1107 *pucDest++ = aucTmp[1];
1113 prGlueInfo->fgNvramAvailable = FALSE;
1120 #if CFG_ENABLE_WIFI_DIRECT
1121 /*----------------------------------------------------------------------------*/
1123 * \brief called by txthread, run sub module init function
1125 * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T
1129 /*----------------------------------------------------------------------------*/
1132 P_GLUE_INFO_T prGlueInfo
1135 /*now, we only have p2p module*/
1136 if(rSubModHandler[P2P_MODULE].fgIsInited == FALSE) {
1137 rSubModHandler[P2P_MODULE].subModInit(prGlueInfo);
1138 rSubModHandler[P2P_MODULE].fgIsInited = TRUE;
1143 /*----------------------------------------------------------------------------*/
1145 * \brief called by txthread, run sub module exit function
1147 * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T
1151 /*----------------------------------------------------------------------------*/
1154 P_GLUE_INFO_T prGlueInfo
1157 /*now, we only have p2p module*/
1158 if(rSubModHandler[P2P_MODULE].fgIsInited == TRUE) {
1159 rSubModHandler[P2P_MODULE].subModExit(prGlueInfo);
1160 rSubModHandler[P2P_MODULE].fgIsInited = FALSE;
1164 /*----------------------------------------------------------------------------*/
1166 * \brief set sub module init flag, force TxThread to run sub modle init
1168 * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T
1172 /*----------------------------------------------------------------------------*/
1175 P_GLUE_INFO_T prGlueInfo
1178 //4 Mark HALT, notify main thread to finish current job
1179 prGlueInfo->u4Flag |= GLUE_FLAG_SUB_MOD_INIT;
1180 /* wake up main thread */
1181 wake_up_interruptible(&prGlueInfo->waitq);
1182 /* wait main thread finish sub module INIT*/
1183 wait_for_completion_interruptible(&prGlueInfo->rSubModComp);
1186 if(prGlueInfo->prAdapter->fgIsP2PRegistered) {
1187 p2pNetRegister(prGlueInfo);
1194 /*----------------------------------------------------------------------------*/
1196 * \brief set sub module exit flag, force TxThread to run sub modle exit
1198 * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T
1202 /*----------------------------------------------------------------------------*/
1205 P_GLUE_INFO_T prGlueInfo
1209 if(prGlueInfo->prAdapter->fgIsP2PRegistered) {
1210 p2pNetUnregister(prGlueInfo);
1214 //4 Mark HALT, notify main thread to finish current job
1215 prGlueInfo->u4Flag |= GLUE_FLAG_SUB_MOD_EXIT;
1216 /* wake up main thread */
1217 wake_up_interruptible(&prGlueInfo->waitq);
1218 /* wait main thread finish sub module EXIT */
1219 wait_for_completion_interruptible(&prGlueInfo->rSubModComp);
1225 /*----------------------------------------------------------------------------*/
1227 * \brief set by sub module, indicate sub module is already inserted
1229 * \param[in] rSubModInit, function pointer point to sub module init function
1230 * \param[in] rSubModExit, function pointer point to sub module exit function
1231 * \param[in] eSubModIdx, sub module index
1235 /*----------------------------------------------------------------------------*/
1237 wlanSubModRegisterInitExit(
1238 SUB_MODULE_INIT rSubModInit,
1239 SUB_MODULE_EXIT rSubModExit,
1240 ENUM_SUB_MODULE_IDX_T eSubModIdx
1243 rSubModHandler[eSubModIdx].subModInit = rSubModInit;
1244 rSubModHandler[eSubModIdx].subModExit = rSubModExit;
1245 rSubModHandler[eSubModIdx].fgIsInited = FALSE;
1249 /*----------------------------------------------------------------------------*/
1251 * \brief check wlan is launched or not
1255 * \return TRUE, wlan is already started
1256 * FALSE, wlan is not started yet
1258 /*----------------------------------------------------------------------------*/
1264 struct net_device *prDev = NULL;
1265 P_GLUE_INFO_T prGlueInfo = NULL;
1267 //4 <0> Sanity check
1268 ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES);
1269 if (0 == u4WlanDevNum) {
1273 prDev = arWlanDevInfo[u4WlanDevNum-1].prDev;
1276 if (NULL == prDev) {
1280 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
1282 if (NULL == prGlueInfo) {
1286 return prGlueInfo->prAdapter->fgIsWlanLaunched;
1291 /*----------------------------------------------------------------------------*/
1293 * \brief Export wlan GLUE_INFO_T pointer to p2p module
1295 * \param[in] prGlueInfo Pointer to struct GLUE_INFO_T
1297 * \return TRUE: get GlueInfo pointer successfully
1298 * FALSE: wlan is not started yet
1300 /*---------------------------------------------------------------------------*/
1303 P_GLUE_INFO_T *prGlueInfoExpAddr
1306 struct net_device *prDev = NULL;
1307 P_GLUE_INFO_T prGlueInfo = NULL;
1309 if (0 == u4WlanDevNum) {
1313 prDev = arWlanDevInfo[u4WlanDevNum-1].prDev;
1314 if (NULL == prDev) {
1318 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
1319 if (NULL == prGlueInfo) {
1323 if(FALSE == prGlueInfo->prAdapter->fgIsWlanLaunched) {
1327 *prGlueInfoExpAddr = prGlueInfo;
1334 /*----------------------------------------------------------------------------*/
1336 * \brief Release prDev from wlandev_array and free tasklet object related to it.
1338 * \param[in] prDev Pointer to struct net_device
1342 /*----------------------------------------------------------------------------*/
1345 struct net_device *prDev
1352 for (i = 0; i < CFG_MAX_WLAN_DEVICES; i++) {
1353 if (arWlanDevInfo[i].prDev == prDev) {
1354 arWlanDevInfo[i].prDev = NULL;
1360 } /* end of wlanClearDevIdx() */
1363 /*----------------------------------------------------------------------------*/
1365 * \brief Allocate an unique interface index, net_device::ifindex member for this
1366 * wlan device. Store the net_device in wlandev_array, and initialize
1367 * tasklet object related to it.
1369 * \param[in] prDev Pointer to struct net_device
1371 * \retval >= 0 The device number.
1372 * \retval -1 Fail to get index.
1374 /*----------------------------------------------------------------------------*/
1377 struct net_device *prDev
1384 for (i = 0; i < CFG_MAX_WLAN_DEVICES; i++) {
1385 if (arWlanDevInfo[i].prDev == (struct net_device *) NULL) {
1386 /* Reserve 2 bytes space to store one digit of
1387 * device number and NULL terminator.
1389 arWlanDevInfo[i].prDev = prDev;
1396 } /* end of wlanGetDevIdx() */
1398 /*----------------------------------------------------------------------------*/
1400 * \brief A method of struct net_device, a primary SOCKET interface to configure
1401 * the interface lively. Handle an ioctl call on one of our devices.
1402 * Everything Linux ioctl specific is done here. Then we pass the contents
1403 * of the ifr->data to the request message handler.
1405 * \param[in] prDev Linux kernel netdevice
1407 * \param[in] prIFReq Our private ioctl request structure, typed for the generic
1408 * struct ifreq so we can use ptr to function
1410 * \param[in] cmd Command ID
1412 * \retval WLAN_STATUS_SUCCESS The IOCTL command is executed successfully.
1413 * \retval OTHER The execution of IOCTL command is failed.
1415 /*----------------------------------------------------------------------------*/
1418 struct net_device *prDev,
1419 struct ifreq *prIFReq,
1423 P_GLUE_INFO_T prGlueInfo = NULL;
1426 /* Verify input parameters for the following functions */
1427 ASSERT(prDev && prIFReq);
1428 if (!prDev || !prIFReq) {
1429 DBGLOG(INIT, WARN, ("%s Invalid input data\n", __FUNCTION__));
1433 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
1436 DBGLOG(INIT, WARN, ("%s No glue info\n", __FUNCTION__));
1440 if (prGlueInfo->u4ReadyFlag == 0) {
1444 //printk ("ioctl %x\n", i4Cmd);
1446 if (i4Cmd == SIOCGIWPRIV) {
1447 /* 0x8B0D, get private ioctl table */
1448 ret = wext_get_priv(prDev, prIFReq);
1450 else if ((i4Cmd >= SIOCIWFIRST) && (i4Cmd < SIOCIWFIRSTPRIV)) {
1451 /* 0x8B00 ~ 0x8BDF, wireless extension region */
1452 ret = wext_support_ioctl(prDev, prIFReq, i4Cmd);
1454 else if ((i4Cmd >= SIOCIWFIRSTPRIV) && (i4Cmd < SIOCIWLASTPRIV)) {
1455 /* 0x8BE0 ~ 0x8BFF, private ioctl region */
1456 ret = priv_support_ioctl(prDev, prIFReq, i4Cmd);
1459 DBGLOG(INIT, WARN, ("Unexpected ioctl command: 0x%04x\n", i4Cmd));
1460 /* return 0 for safe? */
1464 } /* end of wlanDoIOCTL() */
1466 /*----------------------------------------------------------------------------*/
1468 * \brief This function is to set multicast list and set rx mode.
1470 * \param[in] prDev Pointer to struct net_device
1474 /*----------------------------------------------------------------------------*/
1476 static struct delayed_work workq;
1477 static struct net_device *gPrDev;
1480 wlanSetMulticastList (struct net_device *prDev)
1483 schedule_delayed_work(&workq, 0);
1486 /* FIXME: Since we cannot sleep in the wlanSetMulticastList, we arrange
1487 * another workqueue for sleeping. We don't want to block
1488 * tx_thread, so we can't let tx_thread to do this */
1491 wlanSetMulticastListWorkQueue (struct work_struct *work) {
1493 P_GLUE_INFO_T prGlueInfo = NULL;
1494 UINT_32 u4PacketFilter = 0;
1495 UINT_32 u4SetInfoLen;
1496 struct net_device *prDev = gPrDev;
1504 prGlueInfo = (NULL != prDev) ? *((P_GLUE_INFO_T *) netdev_priv(prDev)) : NULL;
1507 if (!prDev || !prGlueInfo) {
1508 DBGLOG(INIT, WARN, ("abnormal dev or skb: prDev(0x%p), prGlueInfo(0x%p)\n",
1509 prDev, prGlueInfo));
1514 if (prDev->flags & IFF_PROMISC) {
1515 u4PacketFilter |= PARAM_PACKET_FILTER_PROMISCUOUS;
1518 if (prDev->flags & IFF_BROADCAST) {
1519 u4PacketFilter |= PARAM_PACKET_FILTER_BROADCAST;
1522 if (prDev->flags & IFF_MULTICAST) {
1523 if ((prDev->flags & IFF_ALLMULTI) ||
1524 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
1525 (netdev_mc_count(prDev) > MAX_NUM_GROUP_ADDR)) {
1527 (prDev->mc_count > MAX_NUM_GROUP_ADDR)) {
1530 u4PacketFilter |= PARAM_PACKET_FILTER_ALL_MULTICAST;
1533 u4PacketFilter |= PARAM_PACKET_FILTER_MULTICAST;
1539 if (kalIoctl(prGlueInfo,
1540 wlanoidSetCurrentPacketFilter,
1542 sizeof(u4PacketFilter),
1547 &u4SetInfoLen) != WLAN_STATUS_SUCCESS) {
1552 if (u4PacketFilter & PARAM_PACKET_FILTER_MULTICAST) {
1553 /* Prepare multicast address list */
1554 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
1555 struct netdev_hw_addr *ha;
1557 struct dev_mc_list *prMcList;
1559 PUINT_8 prMCAddrList = NULL;
1568 prMCAddrList = kalMemAlloc(MAX_NUM_GROUP_ADDR * ETH_ALEN, VIR_MEM_TYPE);
1570 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
1571 netdev_for_each_mc_addr(ha, prDev) {
1572 if(i < MAX_NUM_GROUP_ADDR) {
1573 memcpy((prMCAddrList + i * ETH_ALEN), ha->addr, ETH_ALEN);
1578 for (i = 0, prMcList = prDev->mc_list;
1579 (prMcList) && (i < prDev->mc_count) && (i < MAX_NUM_GROUP_ADDR);
1580 i++, prMcList = prMcList->next) {
1581 memcpy((prMCAddrList + i * ETH_ALEN), prMcList->dmi_addr, ETH_ALEN);
1587 kalIoctl(prGlueInfo,
1588 wlanoidSetMulticastList,
1597 kalMemFree(prMCAddrList, VIR_MEM_TYPE, MAX_NUM_GROUP_ADDR * ETH_ALEN);
1601 } /* end of wlanSetMulticastList() */
1604 /* FIXME: Since we cannot sleep in the wlanSetMulticastList, we arrange
1605 * another workqueue for sleeping. We don't want to block
1606 * tx_thread, so we can't let tx_thread to do this */
1609 p2pSetMulticastListWorkQueueWrapper (P_GLUE_INFO_T prGlueInfo) {
1614 DBGLOG(INIT, WARN, ("abnormal dev or skb: prGlueInfo(0x%p)\n",
1619 #if CFG_ENABLE_WIFI_DIRECT
1620 if(prGlueInfo->prAdapter->fgIsP2PRegistered) {
1621 mtk_p2p_wext_set_Multicastlist(prGlueInfo);
1626 } /* end of p2pSetMulticastListWorkQueueWrapper() */
1630 /*----------------------------------------------------------------------------*/
1632 * \brief This function is TX entry point of NET DEVICE.
1634 * \param[in] prSkb Pointer of the sk_buff to be sent
1635 * \param[in] prDev Pointer to struct net_device
1637 * \retval NETDEV_TX_OK - on success.
1638 * \retval NETDEV_TX_BUSY - on failure, packet will be discarded by upper layer.
1640 /*----------------------------------------------------------------------------*/
1643 struct sk_buff *prSkb,
1644 struct net_device *prDev
1647 P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
1649 P_QUE_ENTRY_T prQueueEntry = NULL;
1650 P_QUE_T prTxQueue = NULL;
1651 UINT_16 u2QueueIdx = 0;
1657 GLUE_SPIN_LOCK_DECLARATION();
1663 if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) {
1664 DBGLOG(INIT, INFO, ("GLUE_FLAG_HALT skip tx\n"));
1665 dev_kfree_skb(prSkb);
1666 return NETDEV_TX_OK;
1669 prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb);
1670 prTxQueue = &prGlueInfo->rTxQueue;
1673 DBGLOG(BOW, TRACE, ("sk_buff->len: %d\n", prSkb->len));
1674 DBGLOG(BOW, TRACE, ("sk_buff->data_len: %d\n", prSkb->data_len));
1675 DBGLOG(BOW, TRACE, ("sk_buff->data:\n"));
1677 for(i = 0; i < prSkb->len; i++)
1679 DBGLOG(BOW, TRACE, ("%4x", prSkb->data[i]));
1683 DBGLOG(BOW, TRACE, ("\n"));
1687 DBGLOG(BOW, TRACE, ("\n"));
1690 if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) {
1692 #if CFG_DBG_GPIO_PINS
1694 /* TX request from OS */
1695 mtk_wcn_stp_debug_gpio_assert(IDX_TX_REQ, DBG_TIE_LOW);
1697 mtk_wcn_stp_debug_gpio_assert(IDX_TX_REQ, DBG_TIE_HIGH);
1701 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26)
1702 u2QueueIdx = skb_get_queue_mapping(prSkb);
1703 ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM);
1706 #if CFG_ENABLE_PKT_LIFETIME_PROFILE
1707 GLUE_SET_PKT_ARRIVAL_TIME(prSkb, kalGetTimeTick());
1710 GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
1711 QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry);
1712 GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
1714 GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum);
1715 GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx]);
1717 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26)
1718 if (prGlueInfo->ai4TxPendingFrameNumPerQueue[NETWORK_TYPE_AIS_INDEX][u2QueueIdx] >= CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) {
1719 netif_stop_subqueue(prDev, u2QueueIdx);
1722 if (prGlueInfo->i4TxPendingFrameNum >= CFG_TX_STOP_NETIF_QUEUE_THRESHOLD) {
1723 netif_stop_queue(prDev);
1727 //printk("is security frame\n");
1729 GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum);
1732 DBGLOG(TX, EVENT, ("\n+++++ pending frame %d len = %d +++++\n", prGlueInfo->i4TxPendingFrameNum, prSkb->len));
1733 prGlueInfo->rNetDevStats.tx_bytes += prSkb->len;
1734 prGlueInfo->rNetDevStats.tx_packets++;
1736 //pr->u4Flag |= GLUE_FLAG_TXREQ;
1737 //wake_up_interruptible(&prGlueInfo->waitq);
1738 kalSetEvent(prGlueInfo);
1741 /* For Linux, we'll always return OK FLAG, because we'll free this skb by ourself */
1742 return NETDEV_TX_OK;
1743 } /* end of wlanHardStartXmit() */
1746 /*----------------------------------------------------------------------------*/
1748 * \brief A method of struct net_device, to get the network interface statistical
1751 * Whenever an application needs to get statistics for the interface, this method
1752 * is called. This happens, for example, when ifconfig or netstat -i is run.
1754 * \param[in] prDev Pointer to struct net_device.
1756 * \return net_device_stats buffer pointer.
1758 /*----------------------------------------------------------------------------*/
1759 struct net_device_stats *
1761 IN struct net_device *prDev
1764 P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
1767 WLAN_STATUS rStatus;
1768 UINT_32 u4XmitError = 0;
1769 UINT_32 u4XmitOk = 0;
1770 UINT_32 u4RecvError = 0;
1771 UINT_32 u4RecvOk = 0;
1776 /* @FIX ME: need a more clear way to do this */
1779 rStatus = kalIoctl(prGlueInfo,
1780 wlanoidQueryXmitError,
1788 rStatus = kalIoctl(prGlueInfo,
1796 rStatus = kalIoctl(prGlueInfo,
1804 rStatus = kalIoctl(prGlueInfo,
1805 wlanoidQueryRcvError,
1812 prGlueInfo->rNetDevStats.rx_packets = u4RecvOk;
1813 prGlueInfo->rNetDevStats.tx_packets = u4XmitOk;
1814 prGlueInfo->rNetDevStats.tx_errors = u4XmitError;
1815 prGlueInfo->rNetDevStats.rx_errors = u4RecvError;
1816 //prGlueInfo->rNetDevStats.rx_bytes = rCustomNetDevStats.u4RxBytes;
1817 //prGlueInfo->rNetDevStats.tx_bytes = rCustomNetDevStats.u4TxBytes;
1818 //prGlueInfo->rNetDevStats.rx_errors = rCustomNetDevStats.u4RxErrors;
1819 //prGlueInfo->rNetDevStats.multicast = rCustomNetDevStats.u4Multicast;
1821 //prGlueInfo->rNetDevStats.rx_packets = 0;
1822 //prGlueInfo->rNetDevStats.tx_packets = 0;
1823 prGlueInfo->rNetDevStats.tx_errors = 0;
1824 prGlueInfo->rNetDevStats.rx_errors = 0;
1825 //prGlueInfo->rNetDevStats.rx_bytes = 0;
1826 //prGlueInfo->rNetDevStats.tx_bytes = 0;
1827 prGlueInfo->rNetDevStats.rx_errors = 0;
1828 prGlueInfo->rNetDevStats.multicast = 0;
1830 return &prGlueInfo->rNetDevStats;
1832 } /* end of wlanGetStats() */
1834 /*----------------------------------------------------------------------------*/
1836 * \brief A function for prDev->init
1838 * \param[in] prDev Pointer to struct net_device.
1840 * \retval 0 The execution of wlanInit succeeds.
1841 * \retval -ENXIO No such device.
1843 /*----------------------------------------------------------------------------*/
1846 struct net_device *prDev
1849 P_GLUE_INFO_T prGlueInfo = NULL;
1855 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
1856 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 12)
1857 INIT_DELAYED_WORK(&workq, wlanSetMulticastListWorkQueue);
1859 INIT_DELAYED_WORK(&workq, wlanSetMulticastListWorkQueue, NULL);
1862 return 0; /* success */
1863 } /* end of wlanInit() */
1866 /*----------------------------------------------------------------------------*/
1868 * \brief A function for prDev->uninit
1870 * \param[in] prDev Pointer to struct net_device.
1874 /*----------------------------------------------------------------------------*/
1877 struct net_device *prDev
1881 } /* end of wlanUninit() */
1884 /*----------------------------------------------------------------------------*/
1886 * \brief A function for prDev->open
1888 * \param[in] prDev Pointer to struct net_device.
1890 * \retval 0 The execution of wlanOpen succeeds.
1891 * \retval < 0 The execution of wlanOpen failed.
1893 /*----------------------------------------------------------------------------*/
1896 struct net_device *prDev
1901 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26)
1902 netif_tx_start_all_queues(prDev);
1904 netif_start_queue(prDev);
1907 return 0; /* success */
1908 } /* end of wlanOpen() */
1911 /*----------------------------------------------------------------------------*/
1913 * \brief A function for prDev->stop
1915 * \param[in] prDev Pointer to struct net_device.
1917 * \retval 0 The execution of wlanStop succeeds.
1918 * \retval < 0 The execution of wlanStop failed.
1920 /*----------------------------------------------------------------------------*/
1923 struct net_device *prDev
1926 P_GLUE_INFO_T prGlueInfo = NULL;
1927 struct cfg80211_scan_request *prScanRequest = NULL;
1928 GLUE_SPIN_LOCK_DECLARATION();
1932 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
1935 GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
1936 if(prGlueInfo->prScanRequest != NULL) {
1937 prScanRequest = prGlueInfo->prScanRequest;
1938 prGlueInfo->prScanRequest = NULL;
1940 GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
1943 cfg80211_scan_done(prScanRequest, TRUE);
1946 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26)
1947 netif_tx_stop_all_queues(prDev);
1949 netif_stop_queue(prDev);
1952 return 0; /* success */
1953 } /* end of wlanStop() */
1956 /*----------------------------------------------------------------------------*/
1958 * \brief Update Channel table for cfg80211 for Wi-Fi Direct based on current country code
1960 * \param[in] prGlueInfo Pointer to glue info
1964 /*----------------------------------------------------------------------------*/
1966 wlanUpdateChannelTable(
1967 P_GLUE_INFO_T prGlueInfo
1971 UINT_8 ucNumOfChannel;
1972 RF_CHANNEL_INFO_T aucChannelList[ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_channels)];
1974 // 1. Disable all channel
1975 for(i = 0; i < ARRAY_SIZE(mtk_2ghz_channels); i++) {
1976 mtk_2ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED;
1979 for(i = 0; i < ARRAY_SIZE(mtk_5ghz_channels); i++) {
1980 mtk_5ghz_channels[i].flags |= IEEE80211_CHAN_DISABLED;
1983 // 2. Get current domain channel list
1984 rlmDomainGetChnlList(prGlueInfo->prAdapter,
1986 ARRAY_SIZE(mtk_2ghz_channels) + ARRAY_SIZE(mtk_5ghz_channels),
1990 // 3. Enable specific channel based on domain channel list
1991 for(i = 0; i < ucNumOfChannel; i++) {
1992 switch(aucChannelList[i].eBand) {
1994 for(j = 0 ; j < ARRAY_SIZE(mtk_2ghz_channels) ; j++) {
1995 if(mtk_2ghz_channels[j].hw_value == aucChannelList[i].ucChannelNum) {
1996 mtk_2ghz_channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
2003 for(j = 0 ; j < ARRAY_SIZE(mtk_5ghz_channels) ; j++) {
2004 if(mtk_5ghz_channels[j].hw_value == aucChannelList[i].ucChannelNum) {
2005 mtk_5ghz_channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
2020 /*----------------------------------------------------------------------------*/
2022 * \brief Register the device to the kernel and return the index.
2024 * \param[in] prDev Pointer to struct net_device.
2026 * \retval 0 The execution of wlanNetRegister succeeds.
2027 * \retval < 0 The execution of wlanNetRegister failed.
2029 /*----------------------------------------------------------------------------*/
2032 struct wireless_dev *prWdev
2035 P_GLUE_INFO_T prGlueInfo;
2036 INT_32 i4DevIdx = -1;
2046 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
2048 if ((i4DevIdx = wlanGetDevIdx(prWdev->netdev)) < 0) {
2049 DBGLOG(INIT, ERROR, ("wlanNetRegister: net_device number exceeds.\n"));
2053 /* adjust channel support status */
2054 wlanUpdateChannelTable((P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy));
2056 if (wiphy_register(prWdev->wiphy) < 0) {
2057 DBGLOG(INIT, ERROR, ("wlanNetRegister: wiphy context is not registered.\n"));
2058 wlanClearDevIdx(prWdev->netdev);
2062 if(register_netdev(prWdev->netdev) < 0) {
2063 DBGLOG(INIT, ERROR, ("wlanNetRegister: net_device context is not registered.\n"));
2065 wiphy_unregister(prWdev->wiphy);
2066 wlanClearDevIdx(prWdev->netdev);
2070 if(i4DevIdx != -1) {
2071 prGlueInfo->fgIsRegistered = TRUE;
2076 return i4DevIdx; /* success */
2077 } /* end of wlanNetRegister() */
2080 /*----------------------------------------------------------------------------*/
2082 * \brief Unregister the device from the kernel
2084 * \param[in] prWdev Pointer to struct net_device.
2088 /*----------------------------------------------------------------------------*/
2091 struct wireless_dev *prWdev
2094 P_GLUE_INFO_T prGlueInfo;
2097 DBGLOG(INIT, ERROR, ("wlanNetUnregister: The device context is NULL\n"));
2101 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
2103 wlanClearDevIdx(prWdev->netdev);
2104 unregister_netdev(prWdev->netdev);
2105 wiphy_unregister(prWdev->wiphy);
2107 prGlueInfo->fgIsRegistered = FALSE;
2109 DBGLOG(INIT, INFO, ("unregister wireless_dev(0x%p)\n", prWdev));
2112 } /* end of wlanNetUnregister() */
2115 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
2116 static const struct net_device_ops wlan_netdev_ops = {
2117 .ndo_open = wlanOpen,
2118 .ndo_stop = wlanStop,
2119 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
2120 .ndo_set_rx_mode = wlanSetMulticastList,
2122 .ndo_set_multicast_list = wlanSetMulticastList,
2124 .ndo_get_stats = wlanGetStats,
2125 .ndo_do_ioctl = wlanDoIOCTL,
2126 .ndo_start_xmit = wlanHardStartXmit,
2127 .ndo_init = wlanInit,
2128 .ndo_uninit = wlanUninit,
2129 .ndo_select_queue = wlanSelectQueue,
2133 /*----------------------------------------------------------------------------*/
2135 * \brief A method for creating Linux NET4 struct net_device object and the
2136 * private data(prGlueInfo and prAdapter). Setup the IO address to the HIF.
2137 * Assign the function pointer to the net_device object
2139 * \param[in] pvData Memory address for the device
2141 * \retval Not null The wireless_dev object.
2142 * \retval NULL Fail to create wireless_dev object
2144 /*----------------------------------------------------------------------------*/
2145 static struct lock_class_key rSpinKey[SPIN_LOCK_NUM];
2146 static struct wireless_dev *
2151 struct wireless_dev *prWdev = NULL;
2152 P_GLUE_INFO_T prGlueInfo = NULL;
2153 P_ADAPTER_T prAdapter = NULL;
2155 struct device *prDev;
2157 //4 <1.1> Create wireless_dev
2158 prWdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2159 DBGLOG(INIT, INFO, ("wireless_dev prWdev(0x%p) allocated\n", prWdev));
2161 DBGLOG(INIT, ERROR, ("Allocating memory to wireless_dev context failed\n"));
2165 //4 <1.2> Create wiphy
2166 prWdev->wiphy = wiphy_new(&mtk_wlan_ops, sizeof(GLUE_INFO_T));
2167 DBGLOG(INIT, INFO, ("wiphy (0x%p) allocated\n", prWdev->wiphy));
2168 if (!prWdev->wiphy) {
2169 DBGLOG(INIT, ERROR, ("Allocating memory to wiphy device failed\n"));
2174 //4 <1.3> co-relate wiphy & prDev
2175 #if MTK_WCN_HIF_SDIO
2176 mtk_wcn_hif_sdio_get_dev(*((MTK_WCN_HIF_SDIO_CLTCTX *)pvData), &prDev);
2178 prDev = &((struct sdio_func *) pvData)->dev;
2181 printk(KERN_ALERT DRV_NAME "unable to get struct dev for wlan\n");
2183 set_wiphy_dev(prWdev->wiphy, prDev);
2185 //4 <1.4> configure wireless_dev & wiphy
2186 prWdev->iftype = NL80211_IFTYPE_STATION;
2187 prWdev->wiphy->max_scan_ssids = 1; /* FIXME: for combo scan */
2188 prWdev->wiphy->max_scan_ie_len = 512;
2189 prWdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2190 prWdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mtk_band_2ghz;
2191 //for the WPS probe request suband issue
2192 //prWdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mtk_band_5ghz;
2193 prWdev->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
2194 prWdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2195 prWdev->wiphy->cipher_suites = (const u32 *)mtk_cipher_suites;
2196 prWdev->wiphy->n_cipher_suites = ARRAY_SIZE(mtk_cipher_suites);
2197 #if LINUX_VERSION_CODE > KERNEL_VERSION(3, 2, 0)
2198 prWdev->wiphy->flags = WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_SUPPORTS_FW_ROAM;
2200 prWdev->wiphy->flags = WIPHY_FLAG_CUSTOM_REGULATORY;
2201 printk(KERN_ALERT DRV_NAME "Not support WIPHY_FLAG_SUPPORTS_FW_ROAM\n");
2204 //4 <2> Create Glue structure
2205 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
2207 DBGLOG(INIT, ERROR, ("Allocating memory to glue layer failed\n"));
2211 //4 <3> Initial Glue structure
2212 //4 <3.1> create net device
2213 if (PowerOnIFname==0){
2214 prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), NIC_INF_NAME, ether_setup, CFG_MAX_TXQ_NUM);
2217 prGlueInfo->prDevHandler = alloc_netdev_mq(sizeof(P_GLUE_INFO_T), LEGACY_IN_AP_MODE, ether_setup, CFG_MAX_TXQ_NUM);
2219 DBGLOG(INIT, INFO, ("net_device prDev(0x%p) allocated\n", prGlueInfo->prDevHandler));
2220 if (!prGlueInfo->prDevHandler) {
2221 DBGLOG(INIT, ERROR, ("Allocating memory to net_device context failed\n"));
2225 //4 <3.1.1> initialize net device varaiables
2226 *((P_GLUE_INFO_T *) netdev_priv(prGlueInfo->prDevHandler)) = prGlueInfo;
2228 prGlueInfo->prDevHandler->netdev_ops = &wlan_netdev_ops;
2229 #ifdef CONFIG_WIRELESS_EXT
2230 prGlueInfo->prDevHandler->wireless_handlers = &wext_handler_def;
2232 netif_carrier_off(prGlueInfo->prDevHandler);
2233 netif_tx_stop_all_queues(prGlueInfo->prDevHandler);
2235 //4 <3.1.2> co-relate with wiphy bi-directionally
2236 prGlueInfo->prDevHandler->ieee80211_ptr = prWdev;
2237 #if CFG_TCP_IP_CHKSUM_OFFLOAD
2238 prGlueInfo->prDevHandler->features = NETIF_F_HW_CSUM;
2240 prWdev->netdev = prGlueInfo->prDevHandler;
2242 //4 <3.1.3> co-relate net device & prDev
2243 SET_NETDEV_DEV(prGlueInfo->prDevHandler, wiphy_dev(prWdev->wiphy));
2245 //4 <3.2> initiali glue variables
2246 prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED;
2247 prGlueInfo->ePowerState = ParamDeviceStateD0;
2248 prGlueInfo->fgIsMacAddrOverride = FALSE;
2249 prGlueInfo->fgIsRegistered = FALSE;
2250 prGlueInfo->prScanRequest = NULL;
2252 init_completion(&prGlueInfo->rScanComp);
2253 init_completion(&prGlueInfo->rHaltComp);
2254 init_completion(&prGlueInfo->rPendComp);
2255 #if 0//LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)
2256 init_completion(&prGlueInfo->rMgmtTxComp);
2257 atomic_set(&prGlueInfo->rMgmtTxAto, 0);
2259 #if CFG_ENABLE_WIFI_DIRECT
2260 init_completion(&prGlueInfo->rSubModComp);
2263 /* initialize timer for OID timeout checker */
2264 kalOsTimerInitialize(prGlueInfo, kalTimeoutHandler);
2266 for (i = 0; i < SPIN_LOCK_NUM; i++) {
2267 spin_lock_init(&prGlueInfo->rSpinLock[i]);
2268 lockdep_set_class(&prGlueInfo->rSpinLock[i], &rSpinKey[i]);
2271 /* initialize semaphore for ioctl */
2272 sema_init(&prGlueInfo->ioctl_sem, 1);
2274 /* initialize semaphore for ioctl */
2275 sema_init(&g_halt_sem, 1);
2278 //4 <4> Create Adapter structure
2279 prAdapter = (P_ADAPTER_T) wlanAdapterCreate(prGlueInfo);
2282 DBGLOG(INIT, ERROR, ("Allocating memory to adapter failed\n"));
2286 prGlueInfo->prAdapter = prAdapter;
2288 #ifdef CONFIG_CFG80211_WEXT
2289 //4 <5> Use wireless extension to replace IOCTL
2290 prWdev->wiphy->wext = &wext_handler_def;
2293 goto netcreate_done;
2296 if (NULL != prAdapter) {
2297 wlanAdapterDestroy(prAdapter);
2301 if (NULL != prGlueInfo->prDevHandler) {
2302 free_netdev(prGlueInfo->prDevHandler);
2303 prGlueInfo->prDevHandler = NULL;
2306 if (NULL != prWdev->wiphy) {
2307 wiphy_free(prWdev->wiphy);
2308 prWdev->wiphy = NULL;
2311 if (NULL != prWdev) {
2312 /* Free net_device and private data, which are allocated by
2322 } /* end of wlanNetCreate() */
2325 /*----------------------------------------------------------------------------*/
2327 * \brief Destroying the struct net_device object and the private data.
2329 * \param[in] prWdev Pointer to struct wireless_dev.
2333 /*----------------------------------------------------------------------------*/
2336 struct wireless_dev *prWdev
2339 P_GLUE_INFO_T prGlueInfo = NULL;
2344 DBGLOG(INIT, ERROR, ("wlanNetDestroy: The device context is NULL\n"));
2348 /* prGlueInfo is allocated with net_device */
2349 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
2352 /* destroy kal OS timer */
2353 kalCancelTimer(prGlueInfo);
2355 glClearHifInfo(prGlueInfo);
2357 wlanAdapterDestroy(prGlueInfo->prAdapter);
2358 prGlueInfo->prAdapter = NULL;
2360 /* Free net_device and private data, which are allocated by alloc_netdev().
2362 free_netdev(prWdev->netdev);
2363 wiphy_free(prWdev->wiphy);
2368 } /* end of wlanNetDestroy() */
2371 UINT_8 g_aucBufIpAddr[32] = {0};
2373 static void wlanEarlySuspend(void)
2375 struct net_device *prDev = NULL;
2376 P_GLUE_INFO_T prGlueInfo = NULL;
2377 UINT_8 ip[4] = { 0 };
2378 UINT_32 u4NumIPv4 = 0;
2380 UINT_8 ip6[16] = { 0 }; // FIX ME: avoid to allocate large memory in stack
2381 UINT_32 u4NumIPv6 = 0;
2384 P_PARAM_NETWORK_ADDRESS_IP prParamIpAddr;
2386 DBGLOG(INIT, INFO, ("*********wlanEarlySuspend************\n"));
2388 // <1> Sanity check and acquire the net_device
2389 ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES);
2390 prDev = arWlanDevInfo[u4WlanDevNum-1].prDev;
2393 fgIsUnderEarlierSuspend = true;
2395 // <2> get the IPv4 address
2396 if(!prDev || !(prDev->ip_ptr)||\
2397 !((struct in_device *)(prDev->ip_ptr))->ifa_list||\
2398 !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))){
2399 DBGLOG(INIT, INFO, ("ip is not avaliable.\n"));
2403 // <3> acquire the prGlueInfo
2404 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
2407 // <4> copy the IPv4 address
2408 kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip));
2409 DBGLOG(INIT, INFO, ("ip is %d.%d.%d.%d\n",
2410 ip[0],ip[1],ip[2],ip[3]));
2412 // todo: traverse between list to find whole sets of IPv4 addresses
2413 if (!((ip[0] == 0) &&
2421 // <5> get the IPv6 address
2422 if(!prDev || !(prDev->ip6_ptr)||\
2423 !((struct in_device *)(prDev->ip6_ptr))->ifa_list||\
2424 !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))){
2425 DBGLOG(INIT, INFO, ("ipv6 is not avaliable.\n"));
2428 // <6> copy the IPv6 address
2429 kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
2430 DBGLOG(INIT, INFO, ("ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
2431 ip6[0],ip6[1],ip6[2],ip6[3],
2432 ip6[4],ip6[5],ip6[6],ip6[7],
2433 ip6[8],ip6[9],ip6[10],ip6[11],
2434 ip6[12],ip6[13],ip6[14],ip6[15]
2437 // todo: traverse between list to find whole sets of IPv6 addresses
2438 if (!((ip6[0] == 0) &&
2449 // <7> set up the ARP filter
2451 WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
2452 UINT_32 u4SetInfoLen = 0;
2453 // UINT_8 aucBuf[32] = {0};
2454 UINT_32 u4Len = OFFSET_OF(PARAM_NETWORK_ADDRESS_LIST, arAddress);
2455 P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST)g_aucBufIpAddr;//aucBuf;
2456 P_PARAM_NETWORK_ADDRESS prParamNetAddr = prParamNetAddrList->arAddress;
2458 kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
2460 prParamNetAddrList->u4AddressCount = u4NumIPv4 + u4NumIPv6;
2461 prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
2462 for (i = 0; i < u4NumIPv4; i++) {
2463 prParamNetAddr->u2AddressLength = sizeof(PARAM_NETWORK_ADDRESS_IP);//4;;
2464 prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;;
2466 kalMemCopy(prParamNetAddr->aucAddress, ip, sizeof(ip));
2467 prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(ip));
2468 u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip);
2470 prParamIpAddr = (P_PARAM_NETWORK_ADDRESS_IP)prParamNetAddr->aucAddress;
2471 kalMemCopy(&prParamIpAddr->in_addr, ip, sizeof(ip));
2472 prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(PARAM_NETWORK_ADDRESS));
2473 u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(PARAM_NETWORK_ADDRESS);
2477 for (i = 0; i < u4NumIPv6; i++) {
2478 prParamNetAddr->u2AddressLength = 6;;
2479 prParamNetAddr->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;;
2480 kalMemCopy(prParamNetAddr->aucAddress, ip6, sizeof(ip6));
2481 prParamNetAddr = (P_PARAM_NETWORK_ADDRESS)((UINT_32)prParamNetAddr + sizeof(ip6));
2482 u4Len += OFFSET_OF(PARAM_NETWORK_ADDRESS, aucAddress) + sizeof(ip6);
2485 ASSERT(u4Len <= sizeof(g_aucBufIpAddr/*aucBuf*/));
2487 rStatus = kalIoctl(prGlueInfo,
2488 wlanoidSetNetworkAddress,
2489 (PVOID)prParamNetAddrList,
2497 if (rStatus != WLAN_STATUS_SUCCESS) {
2498 DBGLOG(INIT, INFO, ("set HW pattern filter fail 0x%lx\n", rStatus));
2503 static void wlanLateResume(void)
2505 struct net_device *prDev = NULL;
2506 P_GLUE_INFO_T prGlueInfo = NULL;
2507 UINT_8 ip[4] = { 0 };
2509 UINT_8 ip6[16] = { 0 }; // FIX ME: avoid to allocate large memory in stack
2512 DBGLOG(INIT, INFO, ("*********wlanLateResume************\n"));
2514 // <1> Sanity check and acquire the net_device
2515 ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES);
2516 prDev = arWlanDevInfo[u4WlanDevNum-1].prDev;
2519 fgIsUnderEarlierSuspend = false;
2521 // <2> get the IPv4 address
2522 if(!prDev || !(prDev->ip_ptr)||\
2523 !((struct in_device *)(prDev->ip_ptr))->ifa_list||\
2524 !(&(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local))){
2525 DBGLOG(INIT, INFO, ("ip is not avaliable.\n"));
2529 // <3> acquire the prGlueInfo
2530 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
2533 // <4> copy the IPv4 address
2534 kalMemCopy(ip, &(((struct in_device *)(prDev->ip_ptr))->ifa_list->ifa_local), sizeof(ip));
2535 DBGLOG(INIT, INFO, ("ip is %d.%d.%d.%d\n",
2536 ip[0],ip[1],ip[2],ip[3]));
2539 // <5> get the IPv6 address
2540 if(!prDev || !(prDev->ip6_ptr)||\
2541 !((struct in_device *)(prDev->ip6_ptr))->ifa_list||\
2542 !(&(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local))){
2543 DBGLOG(INIT, INFO, ("ipv6 is not avaliable.\n"));
2546 // <6> copy the IPv6 address
2547 kalMemCopy(ip6, &(((struct in_device *)(prDev->ip6_ptr))->ifa_list->ifa_local), sizeof(ip6));
2548 DBGLOG(INIT, INFO, ("ipv6 is %d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d.%d\n",
2549 ip6[0],ip6[1],ip6[2],ip6[3],
2550 ip6[4],ip6[5],ip6[6],ip6[7],
2551 ip6[8],ip6[9],ip6[10],ip6[11],
2552 ip6[12],ip6[13],ip6[14],ip6[15]
2555 // <7> clear the ARP filter
2557 WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
2558 UINT_32 u4SetInfoLen = 0;
2559 // UINT_8 aucBuf[32] = {0};
2560 UINT_32 u4Len = sizeof(PARAM_NETWORK_ADDRESS_LIST);
2561 P_PARAM_NETWORK_ADDRESS_LIST prParamNetAddrList = (P_PARAM_NETWORK_ADDRESS_LIST)g_aucBufIpAddr;//aucBuf;
2563 kalMemZero(g_aucBufIpAddr, sizeof(g_aucBufIpAddr));
2565 prParamNetAddrList->u4AddressCount = 0;
2566 prParamNetAddrList->u2AddressType = PARAM_PROTOCOL_ID_TCP_IP;
2568 ASSERT(u4Len <= sizeof(g_aucBufIpAddr/*aucBuf*/));
2569 rStatus = kalIoctl(prGlueInfo,
2570 wlanoidSetNetworkAddress,
2571 (PVOID)prParamNetAddrList,
2579 if (rStatus != WLAN_STATUS_SUCCESS) {
2580 DBGLOG(INIT, INFO, ("set HW pattern filter fail 0x%lx\n", rStatus));
2585 #if defined(CONFIG_HAS_EARLYSUSPEND)
2586 static struct early_suspend mt6620_early_suspend_desc = {
2587 .level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN,
2590 static void wlan_early_suspend(struct early_suspend *h)
2592 DBGLOG(INIT, INFO, ("*********wlan_early_suspend************\n"));
2596 static void wlan_late_resume(struct early_suspend *h)
2598 DBGLOG(INIT, INFO, ("*********wlan_late_resume************\n"));
2601 #endif //defined(CONFIG_HAS_EARLYSUSPEND)
2602 #endif //! CONFIG_X86
2604 /*----------------------------------------------------------------------------*/
2606 * \brief Wlan probe function. This function probes and initializes the device.
2608 * \param[in] pvData data passed by bus driver init function
2610 * _HIF_SDIO: sdio bus driver handle
2613 * \retval negative value Failed
2615 /*----------------------------------------------------------------------------*/
2616 /*mtk80707 rollback to aosp hal*/
2617 typedef int (*set_p2p_mode)(struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUC_T p2pmode);
2618 extern void register_set_p2p_mode_handler(set_p2p_mode handler);
2620 int set_p2p_mode_handler(struct net_device *netdev, PARAM_CUSTOM_P2P_SET_STRUC_T p2pmode) {
2621 P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *)netdev_priv(netdev));
2622 PARAM_CUSTOM_P2P_SET_STRUC_T rSetP2P;
2623 WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
2624 UINT_32 u4BufLen = 0;
2626 rSetP2P.u4Enable = p2pmode.u4Enable;
2627 rSetP2P.u4Mode = p2pmode.u4Mode;
2629 if(!rSetP2P.u4Enable) {
2630 p2pNetUnregister(prGlueInfo, FALSE);
2633 rWlanStatus = kalIoctl(prGlueInfo,
2636 sizeof(PARAM_CUSTOM_P2P_SET_STRUC_T),
2642 printk("set_p2p_mode_handler ret = %d\n", rWlanStatus);
2643 if(rSetP2P.u4Enable) {
2644 p2pNetRegister(prGlueInfo, TRUE);
2646 //return ((rWlanStatus == WLAN_STATUS_SUCCESS) ? 0 : -1);
2656 struct wireless_dev *prWdev = NULL;
2657 P_WLANDEV_INFO_T prWlandevInfo = NULL;
2658 INT_32 i4DevIdx = 0;
2659 P_GLUE_INFO_T prGlueInfo = NULL;
2660 P_ADAPTER_T prAdapter = NULL;
2661 INT_32 i4Status = 0;
2668 /* Initialize DEBUG CLASS of each module */
2669 for (i = 0; i < DBG_MODULE_NUM; i++) {
2670 aucDebugModule[i] = DBG_CLASS_ERROR | \
2675 //aucDebugModule[i] = 0;
2678 aucDebugModule[DBG_INIT_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2679 aucDebugModule[DBG_ARB_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2680 aucDebugModule[DBG_JOIN_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2681 //aucDebugModule[DBG_RX_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2682 aucDebugModule[DBG_TX_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2683 aucDebugModule[DBG_NIC_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2684 aucDebugModule[DBG_HAL_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2685 aucDebugModule[DBG_KEVIN_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO | DBG_CLASS_TEMP;
2686 aucDebugModule[DBG_SCAN_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2687 aucDebugModule[DBG_REQ_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2688 //aucDebugModule[DBG_MGT_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2689 aucDebugModule[DBG_RSN_IDX] |= DBG_CLASS_TRACE;
2690 aucDebugModule[DBG_ROAMING_IDX] |= DBG_CLASS_TRACE | DBG_CLASS_INFO;
2694 //4 <1> Initialize the IO port of the interface
2695 /* GeorgeKuo: pData has different meaning for _HIF_XXX:
2696 * _HIF_EHPI: pointer to memory base variable, which will be
2697 * initialized by glBusInit().
2698 * _HIF_SDIO: bus driver handle
2701 bRet = glBusInit(pvData);
2703 /* Cannot get IO address from interface */
2704 if (FALSE == bRet) {
2705 DBGLOG(INIT, ERROR, (KERN_ALERT "wlanProbe: glBusInit() fail\n"));
2710 //4 <2> Create network device, Adapter, KalInfo, prDevHandler(netdev)
2711 if ((prWdev = wlanNetCreate(pvData)) == NULL) {
2712 DBGLOG(INIT, ERROR, ("wlanProbe: No memory for dev and its private\n"));
2717 //4 <2.5> Set the ioaddr to HIF Info
2718 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(prWdev->wiphy);
2719 gPrDev = prGlueInfo->prDevHandler;
2720 glSetHifInfo(prGlueInfo, (UINT_32) pvData);
2723 /* main thread is created in this function */
2724 init_waitqueue_head(&prGlueInfo->waitq);
2727 QUEUE_INITIALIZE(&prGlueInfo->rCmdQueue);
2728 QUEUE_INITIALIZE(&prGlueInfo->rTxQueue);
2732 //prGlueInfo->main_thread = kthread_run(tx_thread, prGlueInfo->prDevHandler, "tx_thread");
2735 prWlandevInfo = &arWlanDevInfo[i4DevIdx];
2737 i4Status = glBusSetIrq(prWdev->netdev, NULL, *((P_GLUE_INFO_T *) netdev_priv(prWdev->netdev)));
2739 if (i4Status != WLAN_STATUS_SUCCESS) {
2740 DBGLOG(INIT, ERROR, ("wlanProbe: Set IRQ error\n"));
2744 prGlueInfo->i4DevIdx = i4DevIdx;
2746 prAdapter = prGlueInfo->prAdapter;
2748 prGlueInfo->u4ReadyFlag = 0;
2750 #if CFG_TCP_IP_CHKSUM_OFFLOAD
2751 prAdapter->u4CSUMFlags = (CSUM_OFFLOAD_EN_TX_TCP | CSUM_OFFLOAD_EN_TX_UDP | CSUM_OFFLOAD_EN_TX_IP);
2754 //4 <5> Start Device
2756 #if CFG_ENABLE_FW_DOWNLOAD
2757 /* before start adapter, we need to open and load firmware */
2759 UINT_32 u4FwSize = 0;
2760 PVOID prFwBuffer = NULL;
2761 P_REG_INFO_T prRegInfo = &prGlueInfo->rRegInfo;
2763 //P_REG_INFO_T prRegInfo = (P_REG_INFO_T) kmalloc(sizeof(REG_INFO_T), GFP_KERNEL);
2764 kalMemSet(prRegInfo, 0, sizeof(REG_INFO_T));
2765 prRegInfo->u4StartAddress = CFG_FW_START_ADDRESS;
2766 prRegInfo->u4LoadAddress = CFG_FW_LOAD_ADDRESS;
2768 // Load NVRAM content to REG_INFO_T
2769 glLoadNvram(prGlueInfo, prRegInfo);
2771 //kalMemCopy(&prGlueInfo->rRegInfo, prRegInfo, sizeof(REG_INFO_T));
2773 prRegInfo->u4PowerMode = CFG_INIT_POWER_SAVE_PROF;
2774 prRegInfo->fgEnArpFilter = TRUE;
2776 if (kalFirmwareImageMapping(prGlueInfo, &prFwBuffer, &u4FwSize) == NULL) {
2780 if (wlanAdapterStart(prAdapter, prRegInfo, prFwBuffer, u4FwSize) != WLAN_STATUS_SUCCESS) {
2785 kalFirmwareImageUnmapping(prGlueInfo, NULL, prFwBuffer);
2795 //P_REG_INFO_T prRegInfo = (P_REG_INFO_T) kmalloc(sizeof(REG_INFO_T), GFP_KERNEL);
2796 kalMemSet(&prGlueInfo->rRegInfo, 0, sizeof(REG_INFO_T));
2797 P_REG_INFO_T prRegInfo = &prGlueInfo->rRegInfo;
2799 // Load NVRAM content to REG_INFO_T
2800 glLoadNvram(prGlueInfo, prRegInfo);
2802 prRegInfo->u4PowerMode = CFG_INIT_POWER_SAVE_PROF;
2804 if (wlanAdapterStart(prAdapter, prRegInfo, NULL, 0) != WLAN_STATUS_SUCCESS) {
2809 if(TRUE == prAdapter->fgEnable5GBand)
2810 prWdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mtk_band_5ghz;
2811 prGlueInfo->main_thread = kthread_run(tx_thread, prGlueInfo->prDevHandler, "tx_thread");
2813 /* set MAC address */
2815 WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
2816 struct sockaddr MacAddr;
2817 UINT_32 u4SetInfoLen = 0;
2819 rStatus = kalIoctl(prGlueInfo,
2820 wlanoidQueryCurrentAddr,
2829 if (rStatus != WLAN_STATUS_SUCCESS) {
2830 DBGLOG(INIT, WARN, ("set MAC addr fail 0x%lx\n", rStatus));
2831 prGlueInfo->u4ReadyFlag = 0;
2833 memcpy(prGlueInfo->prDevHandler->dev_addr, &MacAddr.sa_data, ETH_ALEN);
2834 memcpy(prGlueInfo->prDevHandler->perm_addr, prGlueInfo->prDevHandler->dev_addr, ETH_ALEN);
2837 prGlueInfo->u4ReadyFlag = 1;
2838 #if CFG_SHOW_MACADDR_SOURCE
2839 DBGLOG(INIT, INFO, ("MAC address: "MACSTR, MAC2STR(&MacAddr.sa_data)));
2845 #if CFG_TCP_IP_CHKSUM_OFFLOAD
2846 /* set HW checksum offload */
2848 WLAN_STATUS rStatus = WLAN_STATUS_FAILURE;
2849 UINT_32 u4CSUMFlags = CSUM_OFFLOAD_EN_ALL;
2850 UINT_32 u4SetInfoLen = 0;
2852 rStatus = kalIoctl(prGlueInfo,
2853 wlanoidSetCSUMOffload,
2854 (PVOID)&u4CSUMFlags,
2862 if (rStatus != WLAN_STATUS_SUCCESS) {
2863 DBGLOG(INIT, WARN, ("set HW checksum offload fail 0x%lx\n", rStatus));
2867 #if CFG_ENABLE_WIFI_DIRECT
2868 register_set_p2p_mode_handler(set_p2p_mode_handler);
2871 //4 <3> Register the card
2872 if ((i4DevIdx = wlanNetRegister(prWdev)) < 0){
2874 DBGLOG(INIT, ERROR, ("wlanProbe: Cannot register the net_device context to the kernel\n"));
2878 //4 <6> Initialize /proc filesystem
2879 #ifdef WLAN_INCLUDE_PROC
2880 if ( (i4Status = procInitProcfs(prDev, NIC_DEVICE_ID_LOW)) < 0) {
2881 DBGLOG(INIT, ERROR, ("wlanProbe: init procfs failed\n"));
2884 #endif /* WLAN_INCLUDE_PROC */
2886 #if CFG_ENABLE_BT_OVER_WIFI
2887 prGlueInfo->rBowInfo.fgIsNetRegistered = FALSE;
2888 prGlueInfo->rBowInfo.fgIsRegistered = FALSE;
2889 glRegisterAmpc(prGlueInfo);
2892 #if CFG_ENABLE_WIFI_DIRECT
2893 /*wlan is launched*/
2894 prGlueInfo->prAdapter->fgIsWlanLaunched = TRUE;
2895 /*if p2p module is inserted, notify tx_thread to init p2p network*/
2896 if(rSubModHandler[P2P_MODULE].subModInit) {
2897 wlanSubModInit(prGlueInfo);
2906 } /* end of wlanProbe() */
2909 /*----------------------------------------------------------------------------*/
2911 * \brief A method to stop driver operation and release all resources. Following
2912 * this call, no frame should go up or down through this interface.
2916 /*----------------------------------------------------------------------------*/
2922 struct net_device *prDev = NULL;
2923 P_WLANDEV_INFO_T prWlandevInfo = NULL;
2924 P_GLUE_INFO_T prGlueInfo = NULL;
2925 P_ADAPTER_T prAdapter = NULL;
2927 DBGLOG(INIT, INFO, ("Remove wlan!\n"));
2930 //4 <0> Sanity check
2931 ASSERT(u4WlanDevNum <= CFG_MAX_WLAN_DEVICES);
2932 if (0 == u4WlanDevNum) {
2933 DBGLOG(INIT, INFO, ("0 == u4WlanDevNum\n"));
2937 /*mtk80707 rollback aosp hal*/
2938 register_set_p2p_mode_handler(NULL);
2940 prDev = arWlanDevInfo[u4WlanDevNum-1].prDev;
2941 prWlandevInfo = &arWlanDevInfo[u4WlanDevNum-1];
2944 if (NULL == prDev) {
2945 DBGLOG(INIT, INFO, ("NULL == prDev\n"));
2949 prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev));
2951 if (NULL == prGlueInfo) {
2952 DBGLOG(INIT, INFO, ("NULL == prGlueInfo\n"));
2958 #if CFG_ENABLE_WIFI_DIRECT
2959 prGlueInfo->prAdapter->fgIsWlanLaunched = FALSE;
2960 if(prGlueInfo->prAdapter->fgIsP2PRegistered) {
2961 p2pNetUnregister(prGlueInfo, TRUE);
2962 p2pRemove(prGlueInfo);
2966 prGlueInfo->prAdapter->fgIsWlanLaunched = FALSE;
2967 //if(prGlueInfo->prAdapter->fgIsP2PRegistered) {
2968 if (prGlueInfo->prP2PInfo) {
2969 //p2pRemove(prGlueInfo);
2970 if (prGlueInfo->prP2PInfo->prDevHandler) {
2971 free_netdev(prGlueInfo->prP2PInfo->prDevHandler);
2972 prGlueInfo->prP2PInfo->prDevHandler = NULL;
2977 if(!p2PFreeInfo(prGlueInfo)) {
2978 printk(KERN_ALERT DRV_NAME "Free memory for p2p FAILED\n");
2986 #if CFG_ENABLE_BT_OVER_WIFI
2987 if(prGlueInfo->rBowInfo.fgIsNetRegistered) {
2988 bowNotifyAllLinkDisconnected(prGlueInfo->prAdapter);
2989 /*wait 300ms for BoW module to send deauth*/
2994 //4 <1> Stopping handling interrupt and free IRQ
2995 glBusFreeIrq(prDev, *((P_GLUE_INFO_T *) netdev_priv(prDev)));
2997 kalMemSet(&(prGlueInfo->prAdapter->rWlanInfo), 0, sizeof(WLAN_INFO_T));
2999 flush_delayed_work_sync(&workq);
3004 //4 <2> Mark HALT, notify main thread to stop, and clean up queued requests
3005 prGlueInfo->u4Flag |= GLUE_FLAG_HALT;
3006 /* wake up main thread */
3007 wake_up_interruptible(&prGlueInfo->waitq);
3008 /* wait main thread stops */
3009 wait_for_completion_interruptible(&prGlueInfo->rHaltComp);
3011 DBGLOG(INIT, INFO, ("mtk_sdiod stopped\n"));
3013 //prGlueInfo->rHifInfo.main_thread = NULL;
3014 prGlueInfo->main_thread = NULL;
3016 #if CFG_ENABLE_BT_OVER_WIFI
3017 if(prGlueInfo->rBowInfo.fgIsRegistered) {
3018 glUnregisterAmpc(prGlueInfo);
3023 //4 <3> Remove /proc filesystem.
3024 #ifdef WLAN_INCLUDE_PROC
3025 procRemoveProcfs(prDev, NIC_DEVICE_ID_LOW);
3026 #endif /* WLAN_INCLUDE_PROC */
3028 //4 <4> wlanAdapterStop
3029 prAdapter = prGlueInfo->prAdapter;
3031 wlanAdapterStop(prAdapter);
3032 DBGLOG(INIT, INFO, ("Number of Stalled Packets = %ld\n", prGlueInfo->i4TxPendingFrameNum));
3034 //4 <5> Release the Bus
3035 glBusRelease(prDev);
3039 //4 <6> Unregister the card
3040 wlanNetUnregister(prDev->ieee80211_ptr);
3042 //4 <7> Destroy the device
3043 wlanNetDestroy(prDev->ieee80211_ptr);
3048 } /* end of wlanRemove() */
3052 /*----------------------------------------------------------------------------*/
3054 * \brief Driver entry point when the driver is configured as a Linux Module, and
3055 * is called once at module load time, by the user-level modutils
3056 * application: insmod or modprobe.
3060 /*----------------------------------------------------------------------------*/
3061 //1 Module Entry Point
3062 static int __init initWlan(void)
3066 DBGLOG(INIT, INFO, ("initWlan\n"));
3068 //mt5931_power_on();
3069 //omap_mmc_update_mtk_card_status(1);
3071 /* memory pre-allocation */
3075 //return ((glRegisterBus(wlanProbe, wlanRemove) == WLAN_STATUS_SUCCESS) ? 0: -EIO);
3076 ret = ((glRegisterBus(wlanProbe, wlanRemove) == WLAN_STATUS_SUCCESS) ? 0: -EIO);
3079 kalUninitIOBuffer();
3084 #if defined(CONFIG_HAS_EARLYSUSPEND)
3086 glRegisterEarlySuspend(&mt6620_early_suspend_desc, wlan_early_suspend, wlan_late_resume);
3087 wlanRegisterNotifier();
3090 #if (CFG_CHIP_RESET_SUPPORT)
3095 } /* end of initWlan() */
3098 /*----------------------------------------------------------------------------*/
3100 * \brief Driver exit point when the driver as a Linux Module is removed. Called
3101 * at module unload time, by the user level modutils application: rmmod.
3102 * This is our last chance to clean up after ourselves.
3106 /*----------------------------------------------------------------------------*/
3107 //1 Module Leave Point
3108 static VOID __exit exitWlan(void)
3110 //printk("remove %p\n", wlanRemove);
3111 #if defined(CONFIG_HAS_EARLYSUSPEND)
3112 glUnregisterEarlySuspend(&mt6620_early_suspend_desc);
3114 wlanUnregisterNotifier();
3116 #if CFG_CHIP_RESET_SUPPORT
3120 glUnregisterBus(wlanRemove);
3122 /* free pre-allocated memory */
3123 kalUninitIOBuffer();
3125 //mt5931_power_off();
3126 //omap_mmc_update_mtk_card_status(0);
3128 DBGLOG(INIT, INFO, ("exitWlan\n"));
3131 } /* end of exitWlan() */
3133 module_init(initWlan);
3134 module_exit(exitWlan);
3136 /* export necessary symbol for p2p driver using */
3137 #if CFG_ENABLE_WIFI_DIRECT
3138 EXPORT_SYMBOL(wlanSubModRegisterInitExit);
3139 EXPORT_SYMBOL(wlanSubModExit);
3140 EXPORT_SYMBOL(wlanSubModInit);
3142 EXPORT_SYMBOL(nicPmIndicateBssCreated);
3143 EXPORT_SYMBOL(rlmProcessAssocRsp);
3144 EXPORT_SYMBOL(kalSetEvent);
3145 EXPORT_SYMBOL(rlmBssInitForAPandIbss);
3146 EXPORT_SYMBOL(kalEnqueueCommand);
3147 EXPORT_SYMBOL(nicIncreaseTxSeqNum);
3148 EXPORT_SYMBOL(nicCmdEventQueryAddress);
3149 EXPORT_SYMBOL(bssCreateStaRecFromBssDesc);
3150 EXPORT_SYMBOL(rlmBssAborted);
3151 EXPORT_SYMBOL(cnmStaRecResetStatus);
3152 EXPORT_SYMBOL(mqmProcessAssocRsp);
3153 EXPORT_SYMBOL(nicTxReturnMsduInfo);
3154 EXPORT_SYMBOL(nicTxEnqueueMsdu);
3155 EXPORT_SYMBOL(wlanProcessSecurityFrame);
3156 EXPORT_SYMBOL(nicChannelNum2Freq);
3157 EXPORT_SYMBOL(nicUpdateBss);
3158 EXPORT_SYMBOL(wlanSendSetQueryCmd);
3159 EXPORT_SYMBOL(cnmStaRecAlloc);
3160 EXPORT_SYMBOL(cnmTimerInitTimer);
3161 EXPORT_SYMBOL(rateGetRateSetFromIEs);
3162 EXPORT_SYMBOL(nicOidCmdTimeoutCommon);
3163 EXPORT_SYMBOL(cnmStaRecChangeState);
3164 EXPORT_SYMBOL(rateGetDataRatesFromRateSet);
3165 EXPORT_SYMBOL(cnmMgtPktAlloc);
3166 EXPORT_SYMBOL(cnmMgtPktFree);
3167 EXPORT_SYMBOL(wextSrchDesiredWPAIE);
3168 EXPORT_SYMBOL(nicRxReturnRFB);
3169 EXPORT_SYMBOL(cnmTimerStartTimer);
3170 EXPORT_SYMBOL(cmdBufAllocateCmdInfo);
3171 EXPORT_SYMBOL(cnmGetStaRecByAddress);
3172 EXPORT_SYMBOL(nicMediaStateChange);
3173 EXPORT_SYMBOL(bssUpdateBeaconContent);
3174 EXPORT_SYMBOL(kalIoctl);
3175 EXPORT_SYMBOL(nicActivateNetwork);
3176 EXPORT_SYMBOL(nicDeactivateNetwork);
3177 EXPORT_SYMBOL(kalRandomNumber);
3178 EXPORT_SYMBOL(nicCmdEventSetCommon);
3179 EXPORT_SYMBOL(cnmTimerStopTimer);
3180 EXPORT_SYMBOL(nicIncreaseCmdSeqNum);
3181 EXPORT_SYMBOL(authSendDeauthFrame);
3182 EXPORT_SYMBOL(cnmMemAlloc);
3183 EXPORT_SYMBOL(nicPmIndicateBssAbort);
3184 EXPORT_SYMBOL(nicCmdEventSetIpAddress);
3185 EXPORT_SYMBOL(mboxSendMsg);
3186 EXPORT_SYMBOL(scanSearchBssDescByBssid);
3187 EXPORT_SYMBOL(bssRemoveStaRecFromClientList);
3188 EXPORT_SYMBOL(assocProcessRxDisassocFrame);
3189 EXPORT_SYMBOL(authProcessRxDeauthFrame);
3190 EXPORT_SYMBOL(cnmStaRecFree);
3191 EXPORT_SYMBOL(rNonHTPhyAttributes);
3192 EXPORT_SYMBOL(rNonHTApModeAttributes);
3193 EXPORT_SYMBOL(cnmMemFree);
3194 EXPORT_SYMBOL(wlanExportGlueInfo);
3195 EXPORT_SYMBOL(bssInitForAP);
3196 EXPORT_SYMBOL(nicPmIndicateBssConnected);
3197 EXPORT_SYMBOL(rlmRspGenerateHtOpIE);
3198 EXPORT_SYMBOL(bssGenerateExtSuppRate_IE);
3199 EXPORT_SYMBOL(rlmRspGenerateErpIE);
3200 EXPORT_SYMBOL(rlmRspGenerateHtCapIE);
3201 EXPORT_SYMBOL(cnmGetStaRecByIndex);
3202 EXPORT_SYMBOL(rsnGenerateWpaNoneIE);
3203 EXPORT_SYMBOL(rlmRspGenerateExtCapIE);
3204 EXPORT_SYMBOL(rsnGenerateRSNIE);
3205 EXPORT_SYMBOL(rsnParseRsnIE);
3207 EXPORT_SYMBOL(wextSrchDesiredWPSIE);
3209 EXPORT_SYMBOL(mboxDummy);
3210 EXPORT_SYMBOL(saaFsmRunEventStart);
3211 EXPORT_SYMBOL(saaFsmRunEventAbort);
3212 EXPORT_SYMBOL(cnmP2PIsPermitted);
3213 EXPORT_SYMBOL(cnmBss40mBwPermitted);
3214 EXPORT_SYMBOL(mqmGenerateWmmParamIE);
3215 EXPORT_SYMBOL(cnmPreferredChannel);
3216 EXPORT_SYMBOL(bssAddStaRecToClientList);
3217 EXPORT_SYMBOL(nicQmUpdateWmmParms);
3218 EXPORT_SYMBOL(qmFreeAllByNetType);
3219 EXPORT_SYMBOL(wlanQueryInformation);
3220 EXPORT_SYMBOL(nicConfigPowerSaveProfile);
3221 EXPORT_SYMBOL(scanSearchExistingBssDesc);
3222 EXPORT_SYMBOL(scanAllocateBssDesc);
3223 EXPORT_SYMBOL(wlanProcessCommandQueue);
3224 EXPORT_SYMBOL(wlanAcquirePowerControl);
3225 EXPORT_SYMBOL(wlanReleasePowerControl);
3226 EXPORT_SYMBOL(wlanReleasePendingCMDbyNetwork);
3228 EXPORT_SYMBOL(aucDebugModule);
3229 EXPORT_SYMBOL(fgIsBusAccessFailed);
3230 EXPORT_SYMBOL(allocatedMemSize);
3231 EXPORT_SYMBOL(dumpMemory8);
3232 EXPORT_SYMBOL(dumpMemory32);
3234 EXPORT_SYMBOL(rlmDomainIsLegalChannel);
3235 EXPORT_SYMBOL(scnQuerySparseChannel);
3236 EXPORT_SYMBOL(rlmDomainGetChnlList);
3237 EXPORT_SYMBOL(p2pSetMulticastListWorkQueueWrapper);
3238 EXPORT_SYMBOL(nicUpdateRSSI);
3239 EXPORT_SYMBOL(nicCmdEventQueryLinkQuality);
3240 EXPORT_SYMBOL(kalGetMediaStateIndicated);
3241 EXPORT_SYMBOL(nicFreq2ChannelNum);
3242 EXPORT_SYMBOL(assocSendDisAssocFrame);
3243 EXPORT_SYMBOL(nicUpdateBeaconIETemplate);
3244 EXPORT_SYMBOL(rsnParseCheckForWFAInfoElem);
3245 EXPORT_SYMBOL(kalClearMgmtFramesByNetType);
3246 EXPORT_SYMBOL(kalClearSecurityFramesByNetType);
3247 EXPORT_SYMBOL(nicFreePendingTxMsduInfoByNetwork);
3248 EXPORT_SYMBOL(bssComposeBeaconProbeRespFrameHeaderAndFF);
3249 EXPORT_SYMBOL(bssBuildBeaconProbeRespFrameCommonIEs);
3250 EXPORT_SYMBOL(wlanoidSetWapiAssocInfo);
3251 EXPORT_SYMBOL(wlanoidSetWSCAssocInfo);