f1aa99622afd7a012e130f2364a74c1403e7dff7
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / mt5931 / os / linux / gl_kal.c
1 /*
2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/os/linux/gl_kal.c#3 $
3 */
4
5 /*! \file   gl_kal.c
6     \brief  GLUE Layer will export the required procedures here for internal driver stack.
7
8     This file contains all routines which are exported from GLUE Layer to internal
9     driver stack.
10 */
11
12
13
14 /*
15 ** $Log: gl_kal.c $
16 ** 
17 ** 08 20 2012 yuche.tsai
18 ** NULL
19 ** Fix possible KE issue.
20  *
21  * 07 17 2012 yuche.tsai
22  * NULL
23  * Let netdev bring up.
24  *
25  * 07 17 2012 yuche.tsai
26  * NULL
27  * Compile no error before trial run.
28  *
29  * 06 13 2012 yuche.tsai
30  * NULL
31  * Update maintrunk driver.
32  * Add support for driver compose assoc request frame.
33  *
34  * 05 31 2012 terry.wu
35  * NULL
36  * .
37  *
38  * 03 26 2012 cp.wu
39  * [WCXRP00001187] [MT6620 Wi-Fi][Driver][Android] Add error handling while firmware image doesn't exist
40  * invoke put_cred() after get_current_cred() calls.
41  *
42  * 03 07 2012 yuche.tsai
43  * NULL
44  * Fix compile error when WiFi Direct is off.
45  *
46  * 03 02 2012 terry.wu
47  * NULL
48  * Snc CFG80211 modification for ICS migration from branch 2.2.
49  *
50  * 02 20 2012 cp.wu
51  * [WCXRP00001187] [MT6620 Wi-Fi][Driver][Android] Add error handling while firmware image doesn't exist
52  * do not need to invoke free() while firmware image file doesn't exist
53  *
54  * 01 05 2012 wh.su
55  * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
56  * Adding the related ioctl / wlan oid function to set the Tx power cfg.
57  *
58  * 01 02 2012 wh.su
59  * [WCXRP00001153] [MT6620 Wi-Fi][Driver] Adding the get_ch_list and set_tx_power proto type function
60  * Adding the proto type function for set_int set_tx_power and get int get_ch_list.
61  *
62  * 11 21 2011 cp.wu
63  * [WCXRP00001118] [MT6620 Wi-Fi][Driver] Corner case protections to pass Monkey testing
64  * 1. wlanoidQueryBssIdList might be passed with a non-zero length but a NULL pointer of buffer
65  * add more checking for such cases
66  *
67  * 2. kalSendComplete() might be invoked with a packet belongs to P2P network right after P2P is unregistered.
68  * add some tweaking to protect such cases because that net device has become invalid.
69  *
70  * 11 18 2011 yuche.tsai
71  * NULL
72  * CONFIG P2P support RSSI query, default turned off.
73  *
74  * 11 16 2011 yuche.tsai
75  * NULL
76  * Avoid using work thread.
77  *
78  * 11 10 2011 cp.wu
79  * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
80  * 1. eliminaite direct calls to printk in porting layer.
81  * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
82  *
83  * 10 12 2011 wh.su
84  * [WCXRP00001036] [MT6620 Wi-Fi][Driver][FW] Adding the 802.11w code for MFP
85  * adding the 802.11w related function and define .
86  *
87  * 09 23 2011 yuche.tsai
88  * [WCXRP00000998] [Volunteer Patch][WiFi Direct][FW] P2P Social Channel & country domain issue
89  * Regulation domain feature check in.
90  *
91  * 08 12 2011 cp.wu
92  * [WCXRP00000913] [MT6620 Wi-Fi] create repository of source code dedicated for MT6620 E6 ASIC
93  * load WIFI_RAM_CODE_E6 for MT6620 E6 ASIC.
94  *
95  * 07 18 2011 chinghwa.yu
96  * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
97  * Add CMD/Event for RDD and BWCS.
98  *
99  * 06 13 2011 eddie.chen
100  * [WCXRP00000779] [MT6620 Wi-Fi][DRV]  Add tx rx statistics in linux and use netif_rx_ni
101  * Add tx rx statistics and netif_rx_ni.
102  *
103  * 04 15 2011 chinghwa.yu
104  * [WCXRP00000065] Update BoW design and settings
105  * Add BOW short range mode.
106  *
107  * 04 12 2011 cp.wu
108  * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for dedicated network type
109  * clear pending security frames for dedicated network type when BSS is being deactivated/disconnected
110  *
111  * 04 08 2011 cp.wu
112  * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
113  * correct i4TxPendingFrameNum decreasing.
114  *
115  * 03 23 2011 cp.wu
116  * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
117  * apply multi-queue operation only for linux kernel > 2.6.26
118  *
119  * 03 21 2011 cp.wu
120  * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
121  * portability for compatible with linux 2.6.12.
122  *
123  * 03 21 2011 cp.wu
124  * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
125  * improve portability for awareness of early version of linux kernel and wireless extension.
126  *
127  * 03 18 2011 cp.wu
128  * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage after system running for a long period
129  * refix ...
130  *
131  * 03 18 2011 cp.wu
132  * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage after system running for a long period
133  * correct compiling warning/error.
134  *
135  * 03 18 2011 cp.wu
136  * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage after system running for a long period
137  * add more robust fault tolerance design when pre-allocation failed. (rarely happen)
138  *
139  * 03 17 2011 cp.wu
140  * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage after system running for a long period
141  * use pre-allocated buffer for storing enhanced interrupt response as well
142  *
143  * 03 16 2011 cp.wu
144  * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage after system running for a long period
145  * 1. pre-allocate physical continuous buffer while module is being loaded
146  * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer
147  *
148  * The windows part remained the same as before, but added similiar APIs to hide the difference.
149  *
150  * 03 15 2011 cp.wu
151  * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous memory consumption
152  * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK
153  * 2. Use common coalescing buffer for both TX/RX directions
154  *
155  *
156  * 03 14 2011 jeffrey.chang
157  * [WCXRP00000546] [MT6620 Wi-Fi][MT6620 Wi-Fi][Driver] fix kernel build warning message
158  * fix kernel build warning message
159  *
160  * 03 07 2011 terry.wu
161  * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message
162  * Toggle non-standard debug messages to comments.
163  *
164  * 03 06 2011 chinghwa.yu
165  * [WCXRP00000065] Update BoW design and settings
166  * Sync BOW Driver to latest person development branch version..
167  *
168  * 03 03 2011 jeffrey.chang
169  * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
170  * support concurrent network
171  *
172  * 03 03 2011 jeffrey.chang
173  * [WCXRP00000512] [MT6620 Wi-Fi][Driver] modify the net device relative functions to support the H/W multiple queue
174  * modify net device relative functions to support multiple H/W queues
175  *
176  * 03 02 2011 cp.wu
177  * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after connection is built.
178  * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI.
179  *
180  * 02 21 2011 cp.wu
181  * [WCXRP00000482] [MT6620 Wi-Fi][Driver] Simplify logic for checking NVRAM existence in driver domain
182  * simplify logic for checking NVRAM existence only once.
183  *
184  * 01 24 2011 cp.wu
185  * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving
186  * 1. add an extra counter for tracking pending forward frames.
187  * 2. notify TX service thread as well when there is pending forward frame
188  * 3. correct build errors leaded by introduction of Wi-Fi direct separation module
189  *
190  * 01 19 2011 cp.wu
191  * [WCXRP00000371] [MT6620 Wi-Fi][Driver] make linux glue layer portable for Android 2.3.1 with Linux 2.6.35.7
192  * add compile option to check linux version 2.6.35 for different usage of system API to improve portability
193  *
194  * 01 12 2011 cp.wu
195  * [WCXRP00000357] [MT6620 Wi-Fi][Driver][Bluetooth over Wi-Fi] add another net device interface for BT AMP
196  * implementation of separate BT_OVER_WIFI data path.
197  *
198  * 01 10 2011 cp.wu
199  * [WCXRP00000349] [MT6620 Wi-Fi][Driver] make kalIoctl() of linux port as a thread safe API to avoid potential issues due to multiple access
200  * use mutex to protect kalIoctl() for thread safe.
201  *
202  * 11 26 2010 cp.wu
203  * [WCXRP00000209] [MT6620 Wi-Fi][Driver] Modify NVRAM checking mechanism to warning only with necessary data field checking
204  * 1. NVRAM error is now treated as warning only, thus normal operation is still available but extra scan result used to indicate user is attached
205  * 2. DPD and TX-PWR are needed fields from now on, if these 2 fields are not availble then warning message is shown
206  *
207  * 11 04 2010 wh.su
208  * [WCXRP00000164] [MT6620 Wi-Fi][Driver] Support the p2p random SSID
209  * adding the p2p random ssid support.
210  *
211  * 11 02 2010 jeffrey.chang
212  * [WCXRP00000145] [MT6620 Wi-Fi][Driver] fix issue of byte endian in packet classifier which discards BoW packets
213  * .
214  *
215  * 11 01 2010 cp.wu
216  * [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
217  * 1) Query link speed (TX rate) from firmware directly with buffering mechanism to reduce overhead
218  * 2) Remove CNM CH-RECOVER event handling
219  * 3) cfg read/write API renamed with kal prefix for unified naming rules.
220  *
221  * 11 01 2010 yarco.yang
222  * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform
223  * Add code to run WlanIST in SDIO callback.
224  *
225  * 10 26 2010 cp.wu
226  * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000137] [MT6620 Wi-Fi] [FW] Support NIC capability query command
227  * 1) update NVRAM content template to ver 1.02
228  * 2) add compile option for querying NIC capability (default: off)
229  * 3) modify AIS 5GHz support to run-time option, which could be turned on by registry or NVRAM setting
230  * 4) correct auto-rate compiler error under linux (treat warning as error)
231  * 5) simplify usage of NVRAM and REG_INFO_T
232  * 6) add version checking between driver and firmware
233  *
234  * 10 25 2010 jeffrey.chang
235  * [WCXRP00000129] [MT6620] [Driver] Kernel panic when rmmod module on Andriod platform
236  * Remove redundant code which cause mismatch of power control release
237  *
238  * 10 25 2010 jeffrey.chang
239  * [WCXRP00000129] [MT6620] [Driver] Kernel panic when rmmod module on Andriod platform
240  * Remove redundant GLUE_HALT condfition to avoid unmatched release of power control
241  *
242  * 10 18 2010 jeffrey.chang
243  * [WCXRP00000116] [MT6620 Wi-Fi][Driver] Refine the set_scan ioctl to resolve the Android UI hanging issue
244  * refine the scan ioctl to prevent hanging of Android UI
245  *
246  * 10 18 2010 cp.wu
247  * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check[WCXRP00000086] [MT6620 Wi-Fi][Driver] The mac address is all zero at android
248  * complete implementation of Android NVRAM access
249  *
250  * 10 06 2010 cp.wu
251  * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
252  * if there is NVRAM, then use MAC address on NVRAM as default MAC address.
253  *
254  * 10 06 2010 cp.wu
255  * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
256  * code reorganization to improve isolation between GLUE and CORE layers.
257  *
258  * 10 05 2010 cp.wu
259  * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
260  * 1) add NVRAM access API
261  * 2) fake scanning result when NVRAM doesn't exist and/or version mismatch. (off by compiler option)
262  * 3) add OID implementation for NVRAM read/write service
263  *
264  * 09 21 2010 cp.wu
265  * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS associated
266  * Do a complete reset with STA-REC null checking for RF test re-entry
267  *
268  * 09 21 2010 kevin.huang
269  * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
270  * Eliminate Linux Compile Warning
271  *
272  * 09 07 2010 wh.su
273  * NULL
274  * adding the code for beacon/probe req/ probe rsp wsc ie at p2p.
275  *
276  * 09 03 2010 kevin.huang
277  * NULL
278  * Refine #include sequence and solve recursive/nested #include issue
279  *
280  * 08 30 2010 cp.wu
281  * NULL
282  * API added: nicTxPendingPackets(), for simplifying porting layer
283  *
284  * 08 20 2010 yuche.tsai
285  * NULL
286  * Support second interface indicate when enabling P2P.
287  *
288  * 08 18 2010 yarco.yang
289  * NULL
290  * 1. Fixed HW checksum offload function not work under Linux issue.
291  * 2. Add debug message.
292  *
293  * 08 16 2010 jeffrey.chang
294  * NULL
295  * remove redundant code which cause kernel panic
296  *
297  * 08 16 2010 cp.wu
298  * NULL
299  * P2P packets are now marked when being queued into driver, and identified later without checking MAC address
300  *
301  * 08 02 2010 jeffrey.chang
302  * NULL
303  * 1) modify tx service thread to avoid busy looping
304  * 2) add spin lock declartion for linux build
305  *
306  * 07 29 2010 cp.wu
307  * NULL
308  * simplify post-handling after TX_DONE interrupt is handled.
309  *
310  * 07 28 2010 jeffrey.chang
311  * NULL
312  * 1) remove unused spinlocks
313  * 2) enable encyption ioctls
314  * 3) fix scan ioctl which may cause supplicant to hang
315  *
316  * 07 23 2010 cp.wu
317  *
318  * 1) re-enable AIS-FSM beacon timeout handling.
319  * 2) scan done API revised
320  *
321  * 07 23 2010 jeffrey.chang
322  *
323  * add new KAL api
324  *
325  * 07 23 2010 jeffrey.chang
326  *
327  * bug fix: allocate regInfo when disabling firmware download
328  *
329  * 07 23 2010 jeffrey.chang
330  *
331  * use glue layer api to decrease or increase counter atomically
332  *
333  * 07 22 2010 jeffrey.chang
334  *
335  * modify tx thread and remove some spinlock
336  *
337  * 07 22 2010 jeffrey.chang
338  *
339  * use different spin lock for security frame
340  *
341  * 07 22 2010 jeffrey.chang
342  *
343  * add new spinlock
344  *
345  * 07 19 2010 jeffrey.chang
346  *
347  * add spinlock for pending security frame count
348  *
349  * 07 19 2010 jeffrey.chang
350  *
351  * adjust the timer unit to microsecond
352  *
353  * 07 19 2010 jeffrey.chang
354  *
355  * timer should return value greater than zero
356  *
357  * 07 19 2010 jeffrey.chang
358  *
359  * add kal api for scanning done
360  *
361  * 07 19 2010 jeffrey.chang
362  *
363  * modify cmd/data path for new design
364  *
365  * 07 19 2010 jeffrey.chang
366  *
367  * add new kal api
368  *
369  * 07 19 2010 jeffrey.chang
370  *
371  * for linux driver migration
372  *
373  * 07 19 2010 jeffrey.chang
374  *
375  * Linux port modification
376  *
377  * 07 08 2010 cp.wu
378  *
379  * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
380  *
381  * 06 23 2010 yarco.yang
382  * [WPD00003837][MT6620]Data Path Refine
383  * Merge g_arStaRec[] into adapter->arStaRec[]
384  *
385  * 06 21 2010 cp.wu
386  * [WPD00003833][MT6620 and MT5931] Driver migration
387  * change MAC address updating logic.
388  *
389  * 06 06 2010 kevin.huang
390  * [WPD00003832][MT6620 5931] Create driver base
391  * [MT6620 5931] Create driver base
392  *
393  * 06 01 2010 cp.wu
394  * [WPD00001943]Create WiFi test driver framework on WinXP
395  * remove unused files.
396  *
397  * 05 29 2010 jeffrey.chang
398  * [WPD00003826]Initial import for Linux port
399  * fix private ioctl for rftest
400  *
401  * 05 29 2010 jeffrey.chang
402  * [WPD00003826]Initial import for Linux port
403  * workaround for fixing request_firmware() failure on android 2.1
404  *
405  * 05 28 2010 jeffrey.chang
406  * [WPD00003826]Initial import for Linux port
407  * fix kernel panic when debug mode enabled
408  *
409  * 05 26 2010 jeffrey.chang
410  * [WPD00003826]Initial import for Linux port
411  * 1) Modify set mac address code
412  * 2) remove power managment macro
413  *
414  * 05 17 2010 cp.wu
415  * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
416  * 1) add timeout handler mechanism for pending command packets
417  * 2) add p2p add/removal key
418  *
419  * 05 14 2010 jeffrey.chang
420  * [WPD00003826]Initial import for Linux port
421  * Disable network interface after disassociation
422  *
423  * 05 10 2010 cp.wu
424  * [WPD00003831][MT6620 Wi-Fi] Add framework for Wi-Fi Direct support
425  * fill network type field while doing frame identification.
426  *
427  * 05 07 2010 jeffrey.chang
428  * [WPD00003826]Initial import for Linux port
429  * prevent supplicant accessing driver during resume
430  *
431  * 04 27 2010 cp.wu
432  * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
433  * identify BT Over Wi-Fi Security frame and mark it as 802.1X frame
434  *
435  * 04 27 2010 jeffrey.chang
436  * [WPD00003826]Initial import for Linux port
437  * 1) fix firmware download bug
438  * 2) remove query statistics for acelerating firmware download
439  *
440  * 04 27 2010 jeffrey.chang
441  * [WPD00003826]Initial import for Linux port
442  * follow Linux's firmware framework, and remove unused kal API
443  *
444  * 04 22 2010 jeffrey.chang
445  * [WPD00003826]Initial import for Linux port
446  *
447  * 1) modify rx path code for supporting Wi-Fi direct
448  * 2) modify config.h since Linux dont need to consider retaining packet
449  *
450  * 04 21 2010 jeffrey.chang
451  * [WPD00003826]Initial import for Linux port
452  * add for private ioctl support
453  *
454  * 04 15 2010 jeffrey.chang
455  * [WPD00003826]Initial import for Linux port
456  * change firmware name
457  *
458  * 04 14 2010 jeffrey.chang
459  * [WPD00003826]Initial import for Linux port
460  * flush pending TX packets while unloading driver
461  *
462  * 04 14 2010 jeffrey.chang
463  * [WPD00003826]Initial import for Linux port
464  * Set driver own before handling cmd queue
465  *
466  * 04 14 2010 jeffrey.chang
467  * [WPD00003826]Initial import for Linux port
468  * 1) prGlueInfo->pvInformationBuffer and prGlueInfo->u4InformationBufferLength are no longer used
469  * 2) fix ioctl
470  *
471  * 04 14 2010 cp.wu
472  * [WPD00001943]Create WiFi test driver framework on WinXP
473  * information buffer for query oid/ioctl is now buffered in prCmdInfo
474  *  *  *  *  *  *  * instead of glue-layer variable to improve multiple oid/ioctl capability
475  *
476  * 04 13 2010 cp.wu
477  * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
478  * add framework for BT-over-Wi-Fi support.
479  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 1) prPendingCmdInfo is replaced by queue for multiple handler capability
480  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 2) command sequence number is now increased atomically
481  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * 3) private data could be hold and taken use for other purpose
482  *
483  * 04 09 2010 jeffrey.chang
484  * [WPD00003826]Initial import for Linux port
485  * fix spinlock usage
486  *
487  * 04 09 2010 jeffrey.chang
488  * [WPD00003826]Initial import for Linux port
489  * add spinlock for i4TxPendingFrameNum access
490  *
491  * 04 09 2010 jeffrey.chang
492  * [WPD00003826]Initial import for Linux port
493  * 1) add spinlock
494  *  * 2) add KAPI for handling association info
495  *
496  * 04 09 2010 jeffrey.chang
497  * [WPD00003826]Initial import for Linux port
498  * fix spinlock usage
499  *
500  * 04 09 2010 jeffrey.chang
501  * [WPD00003826]Initial import for Linux port
502  * adding firmware download KAPI
503  *
504  * 04 07 2010 jeffrey.chang
505  * [WPD00003826]Initial import for Linux port
506  * Set MAC address from firmware
507  *
508  * 04 07 2010 cp.wu
509  * [WPD00001943]Create WiFi test driver framework on WinXP
510  * 1. free cmdinfo after command is emiited.
511  * 2. for BoW frames, user priority is extracted from sk_buff directly.
512  *
513  * 04 07 2010 cp.wu
514  * [WPD00001943]Create WiFi test driver framework on WinXP
515  * finish non-glue layer access to glue variables
516  *
517  * 04 07 2010 cp.wu
518  * [WPD00001943]Create WiFi test driver framework on WinXP
519  * accessing to firmware load/start address, and access to OID handling information
520  *  *  * are now handled in glue layer
521  *
522  * 04 07 2010 cp.wu
523  * [WPD00001943]Create WiFi test driver framework on WinXP
524  * rWlanInfo should be placed at adapter rather than glue due to most operations
525  *  *  *  *  *  *  * are done in adapter layer.
526  *
527  * 04 07 2010 cp.wu
528  * [WPD00001943]Create WiFi test driver framework on WinXP
529  * eliminate direct access to prGlueInfo->eParamMediaStateIndicated from non-glue layer
530  *
531  * 04 06 2010 jeffrey.chang
532  * [WPD00003826]Initial import for Linux port
533  * (1)deliver the kalOidComplete status to upper layer
534  * (2) fix spin lock
535  *
536  * 04 06 2010 cp.wu
537  * [WPD00001943]Create WiFi test driver framework on WinXP
538  * add KAL API: kalFlushPendingTxPackets(), and take use of the API
539  *
540  * 04 06 2010 cp.wu
541  * [WPD00001943]Create WiFi test driver framework on WinXP
542  * eliminate direct access to prGlueInfo->rWlanInfo.eLinkAttr.ucMediaStreamMode from non-glue layer.
543  *
544  * 04 06 2010 jeffrey.chang
545  * [WPD00003826]Initial import for Linux port
546  * add timeout check in the kalOidComplete
547  *
548  * 04 06 2010 jeffrey.chang
549  * [WPD00003826]Initial import for Linux port
550  * improve none-glue code portability
551  *
552  * 04 06 2010 cp.wu
553  * [WPD00001943]Create WiFi test driver framework on WinXP
554  * code refine: fgTestMode should be at adapter rather than glue due to the device/fw is also involved
555  *
556  * 04 06 2010 cp.wu
557  * [WPD00001943]Create WiFi test driver framework on WinXP
558  * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer
559  *
560  * 04 06 2010 cp.wu
561  * [WPD00001943]Create WiFi test driver framework on WinXP
562  * 1) for some OID, never do timeout expiration
563  *  *  * 2) add 2 kal API for later integration
564  *
565  * 04 06 2010 jeffrey.chang
566  * [WPD00003826]Initial import for Linux port
567  * raising the priority of processing interrupt
568  *
569  * 04 01 2010 jeffrey.chang
570  * [WPD00003826]Initial import for Linux port
571  * Bug fix: the tx thread will cause starvation of MMC thread, and the interrupt will never come in
572  *
573  * 03 30 2010 jeffrey.chang
574  * [WPD00003826]Initial import for Linux port
575  * emulate NDIS Pending OID facility
576  *
577  * 03 28 2010 jeffrey.chang
578  * [WPD00003826]Initial import for Linux port
579  * adding secondary command queue for improving non-glue code portability
580  *
581  * 03 26 2010 jeffrey.chang
582  * [WPD00003826]Initial import for Linux port
583  * [WPD00003826] Initial import for Linux port
584  * adding firmware download kal api
585  *
586  * 03 25 2010 cp.wu
587  * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
588  * add Bluetooth-over-Wifi frame header check
589  *
590  * 03 24 2010 jeffrey.chang
591  * [WPD00003826]Initial import for Linux port
592  * initial import for Linux port
593 **  \main\maintrunk.MT5921\50 2009-09-28 20:19:08 GMT mtk01090
594 **  Add private ioctl to carry OID structures. Restructure public/private ioctl interfaces to Linux kernel.
595 **  \main\maintrunk.MT5921\49 2009-08-18 22:56:44 GMT mtk01090
596 **  Add Linux SDIO (with mmc core) support.
597 **  Add Linux 2.6.21, 2.6.25, 2.6.26.
598 **  Fix compile warning in Linux.
599 **  \main\maintrunk.MT5921\48 2009-06-23 23:18:58 GMT mtk01090
600 **  Add build option BUILD_USE_EEPROM and compile option CFG_SUPPORT_EXT_CONFIG for NVRAM support
601 **  \main\maintrunk.MT5921\47 2008-11-19 11:55:43 GMT mtk01088
602 **  fixed some lint warning, and rename some variable with pre-fix to avoid the misunderstanding
603 **  \main\maintrunk.MT5921\46 2008-09-02 21:07:42 GMT mtk01461
604 **  Remove ASSERT(pvBuf) in kalIndicateStatusAndComplete(), this parameter can be NULL
605 **  \main\maintrunk.MT5921\45 2008-08-29 16:03:21 GMT mtk01088
606 **  remove non-used code for code review, add assert check
607 **  \main\maintrunk.MT5921\44 2008-08-21 00:32:49 GMT mtk01461
608 **  \main\maintrunk.MT5921\43 2008-05-30 20:27:02 GMT mtk01461
609 **  Rename KAL function
610 **  \main\maintrunk.MT5921\42 2008-05-30 15:47:29 GMT mtk01461
611 **  \main\maintrunk.MT5921\41 2008-05-30 15:13:04 GMT mtk01084
612 **  rename wlanoid
613 **  \main\maintrunk.MT5921\40 2008-05-29 14:15:14 GMT mtk01084
614 **  remove un-used KAL function
615 **  \main\maintrunk.MT5921\39 2008-05-03 15:17:30 GMT mtk01461
616 **  Move Query Media Status to GLUE
617 **  \main\maintrunk.MT5921\38 2008-04-24 11:59:44 GMT mtk01461
618 **  change awake queue threshold and remove code which mark #if 0
619 **  \main\maintrunk.MT5921\37 2008-04-17 23:06:35 GMT mtk01461
620 **  Add iwpriv support for AdHocMode setting
621 **  \main\maintrunk.MT5921\36 2008-04-08 15:38:56 GMT mtk01084
622 **  add KAL function to setting pattern search function enable/ disable
623 **  \main\maintrunk.MT5921\35 2008-04-01 23:53:13 GMT mtk01461
624 **  Add comment
625 **  \main\maintrunk.MT5921\34 2008-03-26 15:36:48 GMT mtk01461
626 **  Add update MAC Address for Linux
627 **  \main\maintrunk.MT5921\33 2008-03-18 11:49:34 GMT mtk01084
628 **  update function for initial value access
629 **  \main\maintrunk.MT5921\32 2008-03-18 10:25:22 GMT mtk01088
630 **  use kal update associate request at linux
631 **  \main\maintrunk.MT5921\31 2008-03-06 23:43:08 GMT mtk01385
632 **   1. add Query Registry Mac address function.
633 **  \main\maintrunk.MT5921\30 2008-02-26 09:47:57 GMT mtk01084
634 **  modify KAL set network address/ checksum offload part
635 **  \main\maintrunk.MT5921\29 2008-02-12 23:26:53 GMT mtk01461
636 **  Add debug option - Packet Order for Linux
637 **  \main\maintrunk.MT5921\28 2008-01-09 17:54:43 GMT mtk01084
638 **  modify the argument of kalQueryPacketInfo()
639 **  \main\maintrunk.MT5921\27 2007-12-24 16:02:03 GMT mtk01425
640 **  1. Revise csum offload
641 **  \main\maintrunk.MT5921\26 2007-11-30 17:03:36 GMT mtk01425
642 **  1. Fix bugs
643 **
644 **  \main\maintrunk.MT5921\25 2007-11-29 01:57:17 GMT mtk01461
645 **  Fix Windows RX multiple packet retain problem
646 **  \main\maintrunk.MT5921\24 2007-11-20 11:24:07 GMT mtk01088
647 **  <workaround> CR90, not doing the netif_carrier_off to let supplicant 1x pkt can be rcv at hardstattXmit
648 **  \main\maintrunk.MT5921\23 2007-11-09 16:36:44 GMT mtk01425
649 **  1. Modify for CSUM offloading with Tx Fragment
650 **  \main\maintrunk.MT5921\22 2007-11-07 18:37:39 GMT mtk01461
651 **  Add Tx Fragmentation Support
652 **  \main\maintrunk.MT5921\21 2007-11-06 19:34:06 GMT mtk01088
653 **  add the WPS code, indicate the mgmt frame to upper layer
654 **  \main\maintrunk.MT5921\20 2007-11-02 01:03:21 GMT mtk01461
655 **  Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning
656 **  \main\maintrunk.MT5921\19 2007-10-30 11:59:38 GMT MTK01425
657 **  1. Update wlanQueryInformation
658 **  \main\maintrunk.MT5921\18 2007-10-30 10:44:57 GMT mtk01425
659 **  1. Refine multicast list code
660 **  2. Refine TCP/IP csum offload code
661 **
662 ** Revision 1.5  2007/07/17 13:01:18  MTK01088
663 ** add associate req and rsp function
664 **
665 ** Revision 1.4  2007/07/13 05:19:19  MTK01084
666 ** provide timer set functions
667 **
668 ** Revision 1.3  2007/06/27 02:18:51  MTK01461
669 ** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API
670 **
671 ** Revision 1.2  2007/06/25 06:16:24  MTK01461
672 ** Update illustrations, gl_init.c, gl_kal.c, gl_kal.h, gl_os.h and RX API
673 **
674 */
675
676 /*******************************************************************************
677 *                         C O M P I L E R   F L A G S
678 ********************************************************************************
679 */
680
681 /*******************************************************************************
682 *                    E X T E R N A L   R E F E R E N C E S
683 ********************************************************************************
684 */
685 #include "gl_os.h"
686 #include "gl_wext.h"
687 #include "precomp.h"
688
689 /*******************************************************************************
690 *                              C O N S T A N T S
691 ********************************************************************************
692 */
693
694 /*******************************************************************************
695 *                             D A T A   T Y P E S
696 ********************************************************************************
697 */
698
699 /*******************************************************************************
700 *                            P U B L I C   D A T A
701 ********************************************************************************
702 */
703 #if DBG
704 int allocatedMemSize = 0;
705 #endif
706
707 extern struct semaphore g_halt_sem;
708 extern int g_u4HaltFlag;
709
710 /*******************************************************************************
711 *                           P R I V A T E   D A T A
712 ********************************************************************************
713 */
714 static PVOID pvIoBuffer = NULL;
715 static UINT_32 pvIoBufferSize = 0;
716 static UINT_32 pvIoBufferUsage = 0;
717
718
719 /*******************************************************************************
720 *                                 M A C R O S
721 ********************************************************************************
722 */
723
724 /*******************************************************************************
725 *                  F U N C T I O N   D E C L A R A T I O N S
726 ********************************************************************************
727 */
728 #if defined(MT6620) && CFG_MULTI_ECOVER_SUPPORT
729 typedef enum _ENUM_WMTHWVER_TYPE_T{
730     WMTHWVER_MT6620_E1 = 0x0,
731     WMTHWVER_MT6620_E2 = 0x1,
732     WMTHWVER_MT6620_E3 = 0x2,
733     WMTHWVER_MT6620_E4 = 0x3,
734     WMTHWVER_MT6620_E5 = 0x4,
735     WMTHWVER_MT6620_E6 = 0x5,
736     WMTHWVER_MT6620_MAX,
737     WMTHWVER_INVALID = 0xff
738 } ENUM_WMTHWVER_TYPE_T, *P_ENUM_WMTHWVER_TYPE_T;
739
740 extern ENUM_WMTHWVER_TYPE_T
741 mtk_wcn_wmt_hwver_get(
742     VOID
743     );
744 #elif defined(MT5931) && CFG_MULTI_ECOVER_SUPPORT
745 typedef enum _ENUM_HWVER_TYPE_T{
746     HWVER_MT5931_E1 = 0x1,
747     HWVER_MT5931_E2 = 0x2,
748     HWVER_MT5931_E3 = 0x3,
749     HWVER_MT5931_MAX,
750     HWVER_INVALID = 0xff
751 } ENUM_HWVER_TYPE_T, *P_ENUM_HWVER_TYPE_T;
752 #endif
753
754
755 /*******************************************************************************
756 *                              F U N C T I O N S
757 ********************************************************************************
758 */
759 #if CFG_ENABLE_FW_DOWNLOAD
760
761 static struct file *filp = NULL;
762 static uid_t orgfsuid;
763 static gid_t orgfsgid;
764 static mm_segment_t orgfs;
765
766 /*----------------------------------------------------------------------------*/
767 /*!
768 * \brief This function is provided by GLUE Layer for internal driver stack to
769 *        open firmware image in kernel space
770 *
771 * \param[in] prGlueInfo     Pointer of GLUE Data Structure
772 *
773 * \retval WLAN_STATUS_SUCCESS.
774 * \retval WLAN_STATUS_FAILURE.
775 *
776 */
777 /*----------------------------------------------------------------------------*/
778 WLAN_STATUS
779 kalFirmwareOpen (
780     IN P_GLUE_INFO_T                prGlueInfo
781     )
782 {
783     /* FIX ME: since we don't have hotplug script in the filesystem
784      * , so the request_firmware() KAPI can not work properly
785      */
786
787     /* save uid and gid used for filesystem access.
788      * set user and group to 0(root) */
789 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
790     orgfsuid = current->fsuid;
791     orgfsgid = current->fsgid;
792     current->fsuid = current->fsgid = 0;
793 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
794     struct cred *cred = (struct cred *) get_current_cred();
795     orgfsuid = cred->fsuid;
796     orgfsgid = cred->fsgid;
797     cred->fsuid = cred->fsgid = 0;
798 #else
799     struct cred *cred = get_task_cred(current);
800     orgfsuid = cred->fsuid;
801     orgfsgid = cred->fsgid;
802     cred->fsuid = cred->fsgid = 0;
803 #endif
804
805     ASSERT(prGlueInfo);
806
807
808     orgfs = get_fs();
809     set_fs(get_ds());
810
811
812     /* open the fw file */
813 #if defined(MT6620) & CFG_MULTI_ECOVER_SUPPORT
814     switch(mtk_wcn_wmt_hwver_get()) {
815     case WMTHWVER_MT6620_E1:
816     case WMTHWVER_MT6620_E2:
817     case WMTHWVER_MT6620_E3:
818     case WMTHWVER_MT6620_E4:
819     case WMTHWVER_MT6620_E5:
820         filp = filp_open("/etc/firmware/"CFG_FW_FILENAME, O_RDONLY, 0);
821         break;
822
823     case WMTHWVER_MT6620_E6:
824     default:
825         filp = filp_open("/etc/firmware/"CFG_FW_FILENAME"_E6", O_RDONLY, 0);
826         break;
827     }
828 #elif defined(MT5931) && CFG_MULTI_ECOVER_SUPPORT
829     switch (wlanGetEcoVersion(prGlueInfo->prAdapter)) {
830     case HWVER_MT5931_E1:
831     case HWVER_MT5931_E2:
832         filp = filp_open("/etc/firmware/"CFG_FW_FILENAME"_E2", O_RDONLY, 0);
833         break;
834     case HWVER_MT5931_E3:
835     default:
836         filp = filp_open("/etc/firmware/"CFG_FW_FILENAME, O_RDONLY, 0);
837         break;
838     }
839 #elif defined(MT6628)
840     filp = filp_open("/etc/firmware/"CFG_FW_FILENAME"_MT6628", O_RDONLY, 0);
841 #else
842     filp = filp_open("/etc/firmware/"CFG_FW_FILENAME, O_RDONLY, 0);
843 #endif
844     if (IS_ERR(filp)) {
845         DBGLOG(INIT, INFO, ("Open FW image: %s failed\n", CFG_FW_FILENAME));
846         goto error_open;
847     }
848     DBGLOG(INIT, INFO, ("Open FW image: %s done\n", CFG_FW_FILENAME));
849     return WLAN_STATUS_SUCCESS;
850
851 error_open:
852     /* restore */
853     set_fs(orgfs);
854 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
855     current->fsuid = orgfsuid;
856     current->fsgid = orgfsgid;
857 #else
858     cred->fsuid = orgfsuid;
859     cred->fsgid = orgfsgid;
860     #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
861     put_cred(cred);
862     #endif
863 #endif
864     return WLAN_STATUS_FAILURE;
865 }
866
867
868 /*----------------------------------------------------------------------------*/
869 /*!
870 * \brief This function is provided by GLUE Layer for internal driver stack to
871 *        release firmware image in kernel space
872 *
873 * \param[in] prGlueInfo     Pointer of GLUE Data Structure
874 *
875 * \retval WLAN_STATUS_SUCCESS.
876 * \retval WLAN_STATUS_FAILURE.
877 *
878 */
879 /*----------------------------------------------------------------------------*/
880 WLAN_STATUS
881 kalFirmwareClose (
882     IN P_GLUE_INFO_T                prGlueInfo
883     )
884 {
885     ASSERT(prGlueInfo);
886
887     if ((filp != NULL) && !IS_ERR(filp)) {
888         /* close firmware file */
889         filp_close(filp, NULL);
890
891         /* restore */
892         set_fs(orgfs);
893 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
894         current->fsuid = orgfsuid;
895         current->fsgid = orgfsgid;
896 #else
897         {
898 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
899             struct cred *cred = (struct cred *) get_current_cred();
900 #else
901             struct cred *cred = get_task_cred(current);
902 #endif
903             cred->fsuid = orgfsuid;
904             cred->fsgid = orgfsgid;
905     #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
906             put_cred(cred);
907     #endif
908         }
909 #endif
910         filp = NULL;
911     }
912
913     return WLAN_STATUS_SUCCESS;
914 }
915
916 /*----------------------------------------------------------------------------*/
917 /*!
918 * \brief This function is provided by GLUE Layer for internal driver stack to
919 *        load firmware image in kernel space
920 *
921 * \param[in] prGlueInfo     Pointer of GLUE Data Structure
922 *
923 * \retval WLAN_STATUS_SUCCESS.
924 * \retval WLAN_STATUS_FAILURE.
925 *
926 */
927 /*----------------------------------------------------------------------------*/
928 WLAN_STATUS
929 kalFirmwareLoad (
930     IN P_GLUE_INFO_T                prGlueInfo,
931     OUT PVOID                       prBuf,
932     IN UINT_32                      u4Offset,
933     OUT PUINT_32                    pu4Size
934     )
935 {
936     ASSERT(prGlueInfo);
937     ASSERT(pu4Size);
938     ASSERT(prBuf);
939
940     //l = filp->f_path.dentry->d_inode->i_size;
941
942     /* the object must have a read method */
943     if ((filp == NULL) || IS_ERR(filp) || (filp->f_op == NULL) || (filp->f_op->read == NULL)) {
944         goto error_read;
945     } else {
946         filp->f_pos = u4Offset;
947         *pu4Size = filp->f_op->read(filp, prBuf, *pu4Size, &filp->f_pos);
948     }
949
950     return WLAN_STATUS_SUCCESS;
951
952 error_read:
953     return WLAN_STATUS_FAILURE;
954 }
955
956 /*----------------------------------------------------------------------------*/
957 /*!
958 * \brief This function is provided by GLUE Layer for internal driver stack to
959 *        query firmware image size in kernel space
960 *
961 * \param[in] prGlueInfo     Pointer of GLUE Data Structure
962 *
963 * \retval WLAN_STATUS_SUCCESS.
964 * \retval WLAN_STATUS_FAILURE.
965 *
966 */
967 /*----------------------------------------------------------------------------*/
968
969 WLAN_STATUS
970 kalFirmwareSize (
971     IN P_GLUE_INFO_T                prGlueInfo,
972     OUT PUINT_32                     pu4Size
973     )
974 {
975     ASSERT(prGlueInfo);
976     ASSERT(pu4Size);
977
978 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 12)
979     *pu4Size = filp->f_path.dentry->d_inode->i_size;
980 #else
981     *pu4Size = filp->f_dentry->d_inode->i_size;
982 #endif
983
984     return WLAN_STATUS_SUCCESS;
985 }
986
987
988 /*----------------------------------------------------------------------------*/
989 /*!
990 * \brief This routine is used to load firmware image
991 *
992 * \param pvGlueInfo     Pointer of GLUE Data Structure
993 * \param ppvMapFileBuf  Pointer of pointer to memory-mapped firmware image
994 * \param pu4FileLength  File length and memory mapped length as well
995
996 * \retval Map File Handle, used for unammping
997 */
998 /*----------------------------------------------------------------------------*/
999
1000 PVOID
1001 kalFirmwareImageMapping (
1002     IN P_GLUE_INFO_T    prGlueInfo,
1003     OUT PPVOID          ppvMapFileBuf,
1004     OUT PUINT_32        pu4FileLength
1005     )
1006 {
1007     DEBUGFUNC("kalFirmwareImageMapping");
1008
1009     ASSERT(prGlueInfo);
1010     ASSERT(ppvMapFileBuf);
1011     ASSERT(pu4FileLength);
1012
1013     do {
1014         /* <1> Open firmware */
1015         if (kalFirmwareOpen(prGlueInfo) != WLAN_STATUS_SUCCESS) {
1016             break;
1017         } else {
1018             UINT_32 u4FwSize = 0;
1019             PVOID prFwBuffer = NULL;
1020             /* <2> Query firmare size */
1021             kalFirmwareSize(prGlueInfo, &u4FwSize);
1022             /* <3> Use vmalloc for allocating large memory trunk */
1023             prFwBuffer = vmalloc(ALIGN_4(u4FwSize));
1024             /* <4> Load image binary into buffer */
1025             if (kalFirmwareLoad(prGlueInfo, prFwBuffer, 0, &u4FwSize) != WLAN_STATUS_SUCCESS) {
1026                 vfree(prFwBuffer);
1027                 kalFirmwareClose(prGlueInfo);
1028                 break;
1029             }
1030             /* <5> write back info */
1031             *pu4FileLength = u4FwSize;
1032             *ppvMapFileBuf = prFwBuffer;
1033
1034             return prFwBuffer;
1035         }
1036
1037     } while (FALSE);
1038
1039     return NULL;
1040 }
1041
1042 /*----------------------------------------------------------------------------*/
1043 /*!
1044 * \brief This routine is used to unload firmware image mapped memory
1045 *
1046 * \param pvGlueInfo     Pointer of GLUE Data Structure
1047 * \param pvFwHandle     Pointer to mapping handle
1048 * \param pvMapFileBuf   Pointer to memory-mapped firmware image
1049 *
1050 * \retval none
1051 */
1052 /*----------------------------------------------------------------------------*/
1053
1054 VOID
1055 kalFirmwareImageUnmapping (
1056     IN P_GLUE_INFO_T    prGlueInfo,
1057     IN PVOID            prFwHandle,
1058     IN PVOID            pvMapFileBuf
1059     )
1060 {
1061     DEBUGFUNC("kalFirmwareImageUnmapping");
1062
1063     ASSERT(prGlueInfo);
1064
1065     /* pvMapFileBuf might be NULL when file doesn't exist */
1066     if(pvMapFileBuf) {
1067         vfree(pvMapFileBuf);
1068     }
1069
1070     kalFirmwareClose(prGlueInfo);
1071 }
1072
1073 #endif
1074
1075 #if 0
1076
1077 /*----------------------------------------------------------------------------*/
1078 /*!
1079 * \brief This routine is used to load firmware image
1080 *
1081 * \param pvGlueInfo     Pointer of GLUE Data Structure
1082 * \param ppvMapFileBuf  Pointer of pointer to memory-mapped firmware image
1083 * \param pu4FileLength  File length and memory mapped length as well
1084
1085 * \retval Map File Handle, used for unammping
1086 */
1087 /*----------------------------------------------------------------------------*/
1088
1089 PVOID
1090 kalFirmwareImageMapping (
1091     IN P_GLUE_INFO_T    prGlueInfo,
1092     OUT PPVOID          ppvMapFileBuf,
1093     OUT PUINT_32        pu4FileLength
1094     )
1095 {
1096     INT_32 i4Ret = 0;
1097
1098     DEBUGFUNC("kalFirmwareImageMapping");
1099
1100     ASSERT(prGlueInfo);
1101     ASSERT(ppvMapFileBuf);
1102     ASSERT(pu4FileLength);
1103
1104     do {
1105         GL_HIF_INFO_T *prHifInfo = &prGlueInfo->rHifInfo;
1106         prGlueInfo->prFw = NULL;
1107
1108         /* <1> Open firmware */
1109         i4Ret = request_firmware(&prGlueInfo->prFw, CFG_FW_FILENAME, &prHifInfo->func->dev);
1110
1111         if (i4Ret) {
1112             printk (KERN_INFO DRV_NAME"fw %s:request failed %d\n", CFG_FW_FILENAME, i4Ret);
1113             break;
1114         } else {
1115             *pu4FileLength = prGlueInfo->prFw->size;
1116             *ppvMapFileBuf = prGlueInfo->prFw->data;
1117             return prGlueInfo->prFw->data;
1118         }
1119
1120     } while (FALSE);
1121
1122     return NULL;
1123 }
1124
1125 /*----------------------------------------------------------------------------*/
1126 /*!
1127 * \brief This routine is used to unload firmware image mapped memory
1128 *
1129 * \param pvGlueInfo     Pointer of GLUE Data Structure
1130 * \param pvFwHandle     Pointer to mapping handle
1131 * \param pvMapFileBuf   Pointer to memory-mapped firmware image
1132 *
1133 * \retval none
1134 */
1135 /*----------------------------------------------------------------------------*/
1136
1137 VOID
1138 kalFirmwareImageUnmapping (
1139     IN P_GLUE_INFO_T    prGlueInfo,
1140     IN PVOID            prFwHandle,
1141     IN PVOID            pvMapFileBuf
1142     )
1143 {
1144     DEBUGFUNC("kalFirmwareImageUnmapping");
1145
1146     ASSERT(prGlueInfo);
1147     ASSERT(pvMapFileBuf);
1148
1149     release_firmware(prGlueInfo->prFw);
1150
1151 }
1152 #endif
1153
1154 /*----------------------------------------------------------------------------*/
1155 /*!
1156 * \brief This function is provided by GLUE Layer for internal driver stack to acquire
1157 *        OS SPIN_LOCK.
1158 *
1159 * \param[in] prGlueInfo     Pointer of GLUE Data Structure
1160 * \param[in] rLockCategory  Specify which SPIN_LOCK
1161 * \param[out] pu4Flags      Pointer of a variable for saving IRQ flags
1162 *
1163 * \return (none)
1164 */
1165 /*----------------------------------------------------------------------------*/
1166 VOID
1167 kalAcquireSpinLock (
1168     IN P_GLUE_INFO_T                prGlueInfo,
1169     IN ENUM_SPIN_LOCK_CATEGORY_E    rLockCategory,
1170     OUT PUINT_32                    pu4Flags
1171     )
1172 {
1173     UINT_32 u4Flags = 0;
1174
1175     ASSERT(prGlueInfo);
1176     ASSERT(pu4Flags);
1177
1178     if (rLockCategory < SPIN_LOCK_NUM) {
1179
1180 #if CFG_USE_SPIN_LOCK_BOTTOM_HALF
1181         spin_lock_bh(&prGlueInfo->rSpinLock[rLockCategory]);
1182 #else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */
1183         spin_lock_irqsave(&prGlueInfo->rSpinLock[rLockCategory], u4Flags);
1184 #endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */
1185
1186         *pu4Flags = u4Flags;
1187     }
1188
1189     return;
1190 } /* end of kalAcquireSpinLock() */
1191
1192
1193 /*----------------------------------------------------------------------------*/
1194 /*!
1195 * \brief This function is provided by GLUE Layer for internal driver stack to release
1196 *        OS SPIN_LOCK.
1197 *
1198 * \param[in] prGlueInfo     Pointer of GLUE Data Structure
1199 * \param[in] rLockCategory  Specify which SPIN_LOCK
1200 * \param[in] u4Flags        Saved IRQ flags
1201 *
1202 * \return (none)
1203 */
1204 /*----------------------------------------------------------------------------*/
1205 VOID
1206 kalReleaseSpinLock (
1207     IN P_GLUE_INFO_T                prGlueInfo,
1208     IN ENUM_SPIN_LOCK_CATEGORY_E    rLockCategory,
1209     IN UINT_32                      u4Flags
1210     )
1211 {
1212     ASSERT(prGlueInfo);
1213
1214     if (rLockCategory < SPIN_LOCK_NUM) {
1215
1216 #if CFG_USE_SPIN_LOCK_BOTTOM_HALF
1217         spin_unlock_bh(&prGlueInfo->rSpinLock[rLockCategory]);
1218 #else /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */
1219         spin_unlock_irqrestore(&prGlueInfo->rSpinLock[rLockCategory], u4Flags);
1220 #endif /* !CFG_USE_SPIN_LOCK_BOTTOM_HALF */
1221
1222     }
1223
1224     return;
1225 } /* end of kalReleaseSpinLock() */
1226
1227
1228 /*----------------------------------------------------------------------------*/
1229 /*!
1230 * \brief This function is provided by GLUE Layer for internal driver stack to update
1231 *        current MAC address.
1232 *
1233 * \param[in] prGlueInfo     Pointer of GLUE Data Structure
1234 * \param[in] pucMacAddr     Pointer of current MAC address
1235 *
1236 * \return (none)
1237 */
1238 /*----------------------------------------------------------------------------*/
1239 VOID
1240 kalUpdateMACAddress (
1241     IN P_GLUE_INFO_T prGlueInfo,
1242     IN PUINT_8 pucMacAddr
1243     )
1244 {
1245     ASSERT(prGlueInfo);
1246     ASSERT(pucMacAddr);
1247
1248     if(UNEQUAL_MAC_ADDR(prGlueInfo->prDevHandler->dev_addr, pucMacAddr)) {
1249         memcpy(prGlueInfo->prDevHandler->dev_addr, pucMacAddr, PARAM_MAC_ADDR_LEN);
1250     }
1251
1252     return;
1253 }
1254
1255
1256 #if CFG_TCP_IP_CHKSUM_OFFLOAD
1257 /*----------------------------------------------------------------------------*/
1258 /*!
1259 * \brief To query the packet information for offload related parameters.
1260 *
1261 * \param[in] pvPacket Pointer to the packet descriptor.
1262 * \param[in] pucFlag  Points to the offload related parameter.
1263 *
1264 * \return (none)
1265 *
1266 */
1267 /*----------------------------------------------------------------------------*/
1268 VOID
1269 kalQueryTxChksumOffloadParam (
1270     IN PVOID pvPacket,
1271     OUT PUINT_8 pucFlag
1272     )
1273 {
1274     struct sk_buff *skb = (struct sk_buff *) pvPacket;
1275     UINT_8 ucFlag = 0;
1276
1277     ASSERT(pvPacket);
1278     ASSERT(pucFlag);
1279
1280 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
1281     if (skb->ip_summed == CHECKSUM_HW)
1282 #else
1283     if (skb->ip_summed == CHECKSUM_PARTIAL)
1284 #endif
1285     {
1286
1287 #if DBG
1288         /* Kevin: do double check, we can remove this part in Normal Driver.
1289          * Because we register NIC feature with NETIF_F_IP_CSUM for MT5912B MAC, so
1290          * we'll process IP packet only.
1291          */
1292         if (skb->protocol != __constant_htons(ETH_P_IP)) {
1293             //printk("Wrong skb->protocol( = %08x) for TX Checksum Offload.\n", skb->protocol);
1294         }
1295         else
1296 #endif
1297         ucFlag |= (TX_CS_IP_GEN | TX_CS_TCP_UDP_GEN);
1298     }
1299
1300     *pucFlag = ucFlag;
1301
1302     return;
1303 } /* kalQueryChksumOffloadParam */
1304
1305
1306 //4 2007/10/8, mikewu, this is rewritten by Mike
1307 /*----------------------------------------------------------------------------*/
1308 /*!
1309 * \brief To update the checksum offload status to the packet to be indicated to OS.
1310 *
1311 * \param[in] pvPacket Pointer to the packet descriptor.
1312 * \param[in] pucFlag  Points to the offload related parameter.
1313 *
1314 * \return (none)
1315 *
1316 */
1317 /*----------------------------------------------------------------------------*/
1318 VOID
1319 kalUpdateRxCSUMOffloadParam (
1320     IN PVOID pvPacket,
1321     IN ENUM_CSUM_RESULT_T aeCSUM[]
1322     )
1323 {
1324     struct sk_buff *skb = (struct sk_buff *)pvPacket;
1325
1326     ASSERT(pvPacket);
1327
1328     if ( (aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_SUCCESS || aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_SUCCESS)&&
1329         ( (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_SUCCESS) || (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_SUCCESS)) ) {
1330         skb->ip_summed = CHECKSUM_UNNECESSARY;
1331     }
1332     else {
1333         skb->ip_summed = CHECKSUM_NONE;
1334 #if DBG
1335         if (aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_NONE && aeCSUM[CSUM_TYPE_IPV6] == CSUM_RES_NONE) {
1336             DBGLOG(RX, TRACE, ("RX: \"non-IPv4/IPv6\" Packet\n"));
1337         }
1338         else if (aeCSUM[CSUM_TYPE_IPV4] == CSUM_RES_FAILED) {
1339             DBGLOG(RX, TRACE, ("RX: \"bad IP Checksum\" Packet\n"));
1340         }
1341         else if (aeCSUM[CSUM_TYPE_TCP] == CSUM_RES_FAILED) {
1342             DBGLOG(RX, TRACE, ("RX: \"bad TCP Checksum\" Packet\n"));
1343         }
1344         else if (aeCSUM[CSUM_TYPE_UDP] == CSUM_RES_FAILED) {
1345             DBGLOG(RX, TRACE, ("RX: \"bad UDP Checksum\" Packet\n"));
1346         }
1347         else {
1348
1349         }
1350 #endif
1351     }
1352
1353 } /* kalUpdateRxCSUMOffloadParam */
1354 #endif /* CFG_TCP_IP_CHKSUM_OFFLOAD */
1355
1356
1357 /*----------------------------------------------------------------------------*/
1358 /*!
1359 * \brief This function is called to free packet allocated from kalPacketAlloc.
1360 *
1361 * \param[in] prGlueInfo     Pointer of GLUE Data Structure
1362 * \param[in] pvPacket       Pointer of the packet descriptor
1363 *
1364 * \return (none)
1365 */
1366 /*----------------------------------------------------------------------------*/
1367 VOID
1368 kalPacketFree(
1369     IN P_GLUE_INFO_T   prGlueInfo,
1370     IN PVOID           pvPacket
1371     )
1372 {
1373     dev_kfree_skb((struct sk_buff *) pvPacket);
1374 }
1375
1376
1377 /*----------------------------------------------------------------------------*/
1378 /*!
1379 * \brief Only handles driver own creating packet (coalescing buffer).
1380 *
1381 * \param prGlueInfo   Pointer of GLUE Data Structure
1382 * \param u4Size       Pointer of Packet Handle
1383 * \param ppucData     Status Code for OS upper layer
1384 *
1385 * \return NULL: Failed to allocate skb, Not NULL get skb
1386 */
1387 /*----------------------------------------------------------------------------*/
1388 PVOID
1389 kalPacketAlloc (
1390     IN P_GLUE_INFO_T    prGlueInfo,
1391     IN UINT_32          u4Size,
1392     OUT PUINT_8         *ppucData
1393     )
1394 {
1395     struct sk_buff  *prSkb = dev_alloc_skb(u4Size);
1396
1397     if (prSkb) {
1398         *ppucData = (PUINT_8) (prSkb->data);
1399     }
1400 #if DBG
1401 {
1402     PUINT_32 pu4Head = (PUINT_32)&prSkb->cb[0];
1403     *pu4Head = (UINT_32)prSkb->head;
1404     DBGLOG(RX, TRACE, ("prSkb->head = %#lx, prSkb->cb = %#lx\n", (UINT_32)prSkb->head, *pu4Head));
1405 }
1406 #endif
1407     return (PVOID) prSkb;
1408 }
1409
1410 /*----------------------------------------------------------------------------*/
1411 /*!
1412 * \brief Process the received packet for indicating to OS.
1413 *
1414 * \param[in] prGlueInfo     Pointer to the Adapter structure.
1415 * \param[in] pvPacket       Pointer of the packet descriptor
1416 * \param[in] pucPacketStart The starting address of the buffer of Rx packet.
1417 * \param[in] u4PacketLen    The packet length.
1418 * \param[in] pfgIsRetain    Is the packet to be retained.
1419 * \param[in] aerCSUM        The result of TCP/ IP checksum offload.
1420 *
1421 * \retval WLAN_STATUS_SUCCESS.
1422 * \retval WLAN_STATUS_FAILURE.
1423 *
1424 */
1425 /*----------------------------------------------------------------------------*/
1426 WLAN_STATUS
1427 kalProcessRxPacket (
1428     IN P_GLUE_INFO_T      prGlueInfo,
1429     IN PVOID              pvPacket,
1430     IN PUINT_8            pucPacketStart,
1431     IN UINT_32            u4PacketLen,
1432     //IN PBOOLEAN           pfgIsRetain,
1433     IN BOOLEAN            fgIsRetain,
1434     IN ENUM_CSUM_RESULT_T aerCSUM[]
1435     )
1436 {
1437     WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
1438     struct sk_buff *skb = (struct sk_buff *)pvPacket;
1439
1440
1441     skb->data = (unsigned char *)pucPacketStart;
1442     skb->tail = (unsigned char *) ((UINT_32) (pucPacketStart + u4PacketLen));
1443     skb->len = (unsigned int)u4PacketLen;
1444
1445 #if CFG_TCP_IP_CHKSUM_OFFLOAD
1446     kalUpdateRxCSUMOffloadParam(skb, aerCSUM);
1447 #endif
1448
1449     return rStatus;
1450 }
1451
1452 /*----------------------------------------------------------------------------*/
1453 /*!
1454 * \brief To indicate an array of received packets is available for higher
1455 *        level protocol uses.
1456 *
1457 * \param[in] prGlueInfo Pointer to the Adapter structure.
1458 * \param[in] apvPkts The packet array to be indicated
1459 * \param[in] ucPktNum The number of packets to be indicated
1460 *
1461 * \retval TRUE Success.
1462 *
1463 */
1464 /*----------------------------------------------------------------------------*/
1465 WLAN_STATUS
1466 kalRxIndicatePkts (
1467     IN P_GLUE_INFO_T    prGlueInfo,
1468     IN PVOID            apvPkts[],
1469     IN UINT_8           ucPktNum
1470     )
1471 {
1472     UINT_8 ucIdx = 0;
1473     struct net_device *prNetDev = prGlueInfo->prDevHandler;
1474     struct sk_buff *prSkb = NULL;
1475
1476     ASSERT(prGlueInfo);
1477     ASSERT(apvPkts);
1478
1479 #if CFG_BOW_TEST
1480     UINT_32 i;
1481 #endif
1482
1483     for(ucIdx = 0; ucIdx < ucPktNum; ucIdx++) {
1484         prSkb = apvPkts[ucIdx];
1485 #if DBG
1486         do {
1487             PUINT_8 pu4Head = (PUINT_8)&prSkb->cb[0];
1488             UINT_32 u4HeadValue = 0;
1489             kalMemCopy(&u4HeadValue, pu4Head, sizeof(u4HeadValue));
1490             DBGLOG(RX, TRACE, ("prSkb->head = 0x%p, prSkb->cb = 0x%lx\n", pu4Head, u4HeadValue));
1491         } while (0);
1492 #endif
1493
1494         if (GLUE_GET_PKT_IS_P2P(prSkb)) {
1495             /* P2P */
1496 #if CFG_ENABLE_WIFI_DIRECT
1497             if(prGlueInfo->prAdapter->fgIsP2PRegistered) {
1498                 prNetDev = kalP2PGetDevHdlr(prGlueInfo);
1499             }
1500
1501             prNetDev->stats.rx_bytes += prSkb->len;
1502             prNetDev->stats.rx_packets++;
1503             
1504 #else
1505             prNetDev = prGlueInfo->prDevHandler;
1506 #endif
1507         }
1508         else if (GLUE_GET_PKT_IS_PAL(prSkb)) {
1509             /* BOW */
1510 #if CFG_ENABLE_BT_OVER_WIFI && CFG_BOW_SEPARATE_DATA_PATH
1511             if (prGlueInfo->rBowInfo.fgIsNetRegistered) {
1512             prNetDev = prGlueInfo->rBowInfo.prDevHandler;
1513             }
1514 #else
1515             prNetDev = prGlueInfo->prDevHandler;
1516 #endif
1517         }
1518         else {
1519             /* AIS */
1520             prNetDev = prGlueInfo->prDevHandler;
1521             prGlueInfo->rNetDevStats.rx_bytes += prSkb->len;
1522             prGlueInfo->rNetDevStats.rx_packets++;
1523
1524         }
1525
1526         prNetDev->last_rx = jiffies;
1527         prSkb->protocol = eth_type_trans(prSkb, prNetDev);
1528         prSkb->dev = prNetDev;
1529         //DBGLOG_MEM32(RX, TRACE, (PUINT_32)prSkb->data, prSkb->len);
1530         DBGLOG(RX, EVENT, ("kalRxIndicatePkts len = %d\n", prSkb->len));
1531
1532 #if CFG_BOW_TEST
1533     DBGLOG(BOW, TRACE, ("Rx sk_buff->len: %d\n", prSkb->len));
1534     DBGLOG(BOW, TRACE, ("Rx sk_buff->data_len: %d\n", prSkb->data_len));
1535     DBGLOG(BOW, TRACE, ("Rx sk_buff->data:\n"));
1536
1537         for(i = 0; i < prSkb->len && i < 64; i++)
1538         {
1539             LOG_FUNC("%02x ", prSkb->data[i]);
1540
1541             if((i+1)%16 ==0)
1542             {
1543                 LOG_FUNC("\n");
1544             }
1545         }
1546
1547     LOG_FUNC("\n");
1548 #endif
1549 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
1550         if(!in_interrupt()){
1551             netif_rx_ni(prSkb); /* only in non-interrupt context */
1552         }
1553         else {
1554             netif_rx(prSkb);
1555         }
1556 #else
1557         netif_rx(prSkb);
1558 #endif
1559
1560         wlanReturnPacket(prGlueInfo->prAdapter, NULL);
1561     }
1562
1563     return WLAN_STATUS_SUCCESS;
1564 }
1565
1566 /*----------------------------------------------------------------------------*/
1567 /*!
1568 * \brief Called by driver to indicate event to upper layer, for example, the wpa
1569 *        supplicant or wireless tools.
1570 *
1571 * \param[in] pvAdapter Pointer to the adapter descriptor.
1572 * \param[in] eStatus Indicated status.
1573 * \param[in] pvBuf Indicated message buffer.
1574 * \param[in] u4BufLen Indicated message buffer size.
1575 *
1576 * \return (none)
1577 *
1578 */
1579 /*----------------------------------------------------------------------------*/
1580 VOID
1581 kalIndicateStatusAndComplete (
1582     IN P_GLUE_INFO_T    prGlueInfo,
1583     IN WLAN_STATUS      eStatus,
1584     IN PVOID            pvBuf,
1585     IN UINT_32          u4BufLen
1586     )
1587 {
1588     UINT_32 bufLen;
1589     P_PARAM_STATUS_INDICATION_T pStatus = (P_PARAM_STATUS_INDICATION_T) pvBuf;
1590     P_PARAM_AUTH_EVENT_T pAuth = (P_PARAM_AUTH_EVENT_T) pStatus;
1591     P_PARAM_PMKID_CANDIDATE_LIST_T pPmkid =
1592         (P_PARAM_PMKID_CANDIDATE_LIST_T) (pStatus + 1);
1593     PARAM_MAC_ADDRESS arBssid;
1594     struct cfg80211_scan_request *prScanRequest = NULL;
1595     GLUE_SPIN_LOCK_DECLARATION();
1596
1597     kalMemZero(arBssid, MAC_ADDR_LEN);
1598
1599     ASSERT(prGlueInfo);
1600
1601     switch (eStatus) {
1602     case WLAN_STATUS_ROAM_OUT_FIND_BEST:
1603     case WLAN_STATUS_MEDIA_CONNECT:
1604
1605         prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_CONNECTED;
1606
1607         /* indicate assoc event */
1608         wlanQueryInformation(prGlueInfo->prAdapter,
1609             wlanoidQueryBssid,
1610             &arBssid[0],
1611             sizeof(arBssid),
1612             &bufLen);
1613         wext_indicate_wext_event(prGlueInfo, SIOCGIWAP, arBssid, bufLen);
1614
1615         /* switch netif on */
1616         netif_carrier_on(prGlueInfo->prDevHandler);
1617
1618         do {
1619             /* print message on console */
1620             PARAM_SSID_T ssid;
1621
1622             wlanQueryInformation(prGlueInfo->prAdapter,
1623                 wlanoidQuerySsid,
1624                 &ssid,
1625                 sizeof(ssid),
1626                 &bufLen);
1627
1628             ssid.aucSsid[(ssid.u4SsidLen >= PARAM_MAX_LEN_SSID) ?
1629                 (PARAM_MAX_LEN_SSID - 1) : ssid.u4SsidLen ] = '\0';
1630             DBGLOG(INIT, INFO, ("[wifi] %s netif_carrier_on [ssid:%s " MACSTR "]\n",
1631                 prGlueInfo->prDevHandler->name,
1632                 ssid.aucSsid,
1633                 MAC2STR(arBssid)));
1634         } while(0);
1635
1636         if(prGlueInfo->fgIsRegistered == TRUE) {
1637             /* CFG80211 Indication */
1638             if(eStatus == WLAN_STATUS_MEDIA_CONNECT 
1639                     && prGlueInfo->prDevHandler->ieee80211_ptr->sme_state == CFG80211_SME_CONNECTING) {
1640                 cfg80211_connect_result(prGlueInfo->prDevHandler,
1641                         arBssid,
1642                         prGlueInfo->aucReqIe,
1643                         prGlueInfo->u4ReqIeLength,
1644                         prGlueInfo->aucRspIe,
1645                         prGlueInfo->u4RspIeLength,
1646                         WLAN_STATUS_SUCCESS,
1647                         GFP_KERNEL);
1648             }
1649             else if(eStatus == WLAN_STATUS_ROAM_OUT_FIND_BEST
1650                     && prGlueInfo->prDevHandler->ieee80211_ptr->sme_state == CFG80211_SME_CONNECTED) {
1651                 struct ieee80211_channel *prChannel = NULL;
1652                 UINT_8 ucChannelNum = wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX);
1653
1654                 if(ucChannelNum <= 14) {
1655                     prChannel = ieee80211_get_channel(priv_to_wiphy(prGlueInfo), ieee80211_channel_to_frequency(ucChannelNum, IEEE80211_BAND_2GHZ));
1656                 }
1657                 else {
1658                     prChannel = ieee80211_get_channel(priv_to_wiphy(prGlueInfo), ieee80211_channel_to_frequency(ucChannelNum, IEEE80211_BAND_5GHZ));
1659                 }
1660
1661                 cfg80211_roamed(prGlueInfo->prDevHandler, 
1662                         prChannel,
1663                         arBssid,
1664                         prGlueInfo->aucReqIe,
1665                         prGlueInfo->u4ReqIeLength,
1666                         prGlueInfo->aucRspIe,
1667                         prGlueInfo->u4RspIeLength,                        
1668                         GFP_KERNEL);
1669             }
1670         }
1671
1672         break;
1673
1674     case WLAN_STATUS_MEDIA_DISCONNECT:
1675         /* indicate disassoc event */
1676         wext_indicate_wext_event(prGlueInfo, SIOCGIWAP, NULL, 0);
1677         /* For CR 90 and CR99, While supplicant do reassociate, driver will do netif_carrier_off first,
1678            after associated success, at joinComplete(), do netif_carier_on,
1679            but for unknown reason, the supplicant 1x pkt will not called the driver
1680            hardStartXmit, for template workaround these bugs, add this compiling flag
1681         */
1682         /* switch netif off */
1683
1684 #if 1   /* CONSOLE_MESSAGE */
1685          DBGLOG(INIT, INFO, ("[wifi] %s netif_carrier_off\n", prGlueInfo->prDevHandler->name));
1686 #endif
1687
1688         netif_carrier_off(prGlueInfo->prDevHandler);
1689
1690         if(prGlueInfo->fgIsRegistered == TRUE
1691                 && prGlueInfo->prDevHandler->ieee80211_ptr->sme_state == CFG80211_SME_CONNECTED) {
1692             /* CFG80211 Indication */
1693             cfg80211_disconnected(prGlueInfo->prDevHandler, 0, NULL, 0, GFP_KERNEL);
1694         }
1695
1696         prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED;
1697
1698         break;
1699
1700     case WLAN_STATUS_SCAN_COMPLETE:
1701         /* indicate scan complete event */
1702         wext_indicate_wext_event(prGlueInfo, SIOCGIWSCAN, NULL, 0);
1703
1704         /* 1. reset first for newly incoming request */
1705         GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
1706         if(prGlueInfo->prScanRequest != NULL) {
1707             prScanRequest = prGlueInfo->prScanRequest;
1708             prGlueInfo->prScanRequest = NULL;
1709         }
1710         GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
1711
1712         /* 2. then CFG80211 Indication */
1713         if(prScanRequest != NULL) {
1714             cfg80211_scan_done(prScanRequest, FALSE);
1715         }
1716         break;
1717
1718     #if 0
1719     case WLAN_STATUS_MSDU_OK:
1720         if (netif_running(prGlueInfo->prDevHandler)) {
1721             netif_wake_queue(prGlueInfo->prDevHandler);
1722         }
1723         break;
1724     #endif
1725
1726     case WLAN_STATUS_MEDIA_SPECIFIC_INDICATION:
1727         if (pStatus) {
1728             switch (pStatus->eStatusType) {
1729             case ENUM_STATUS_TYPE_AUTHENTICATION:
1730                 /*
1731                 printk(KERN_NOTICE "ENUM_STATUS_TYPE_AUTHENTICATION: L(%ld) [" MACSTR "] F:%lx\n",
1732                     pAuth->Request[0].Length,
1733                     MAC2STR(pAuth->Request[0].Bssid),
1734                     pAuth->Request[0].Flags);
1735                 */
1736                 /* indicate (UC/GC) MIC ERROR event only */
1737                 if ((pAuth->arRequest[0].u4Flags ==
1738                         PARAM_AUTH_REQUEST_PAIRWISE_ERROR) ||
1739                         (pAuth->arRequest[0].u4Flags ==
1740                         PARAM_AUTH_REQUEST_GROUP_ERROR)) {
1741                     cfg80211_michael_mic_failure(prGlueInfo->prDevHandler, NULL, 
1742                                        (pAuth->arRequest[0].u4Flags == PARAM_AUTH_REQUEST_PAIRWISE_ERROR) ? NL80211_KEYTYPE_PAIRWISE : NL80211_KEYTYPE_GROUP,
1743                                        0, NULL, GFP_KERNEL);
1744                     wext_indicate_wext_event(prGlueInfo,
1745                         IWEVMICHAELMICFAILURE,
1746                         (unsigned char *)&pAuth->arRequest[0],
1747                         pAuth->arRequest[0].u4Length);
1748                 }
1749                 break;
1750
1751             case ENUM_STATUS_TYPE_CANDIDATE_LIST:
1752                 /*
1753                 printk(KERN_NOTICE "Param_StatusType_PMKID_CandidateList: Ver(%ld) Num(%ld)\n",
1754                     pPmkid->u2Version,
1755                     pPmkid->u4NumCandidates);
1756                 if (pPmkid->u4NumCandidates > 0) {
1757                     printk(KERN_NOTICE "candidate[" MACSTR "] preAuth Flag:%lx\n",
1758                         MAC2STR(pPmkid->arCandidateList[0].rBSSID),
1759                         pPmkid->arCandidateList[0].fgFlags);
1760                 }
1761                 */
1762                 {
1763                  UINT_32  i = 0;
1764
1765                  P_PARAM_PMKID_CANDIDATE_T prPmkidCand = (P_PARAM_PMKID_CANDIDATE_T)&pPmkid->arCandidateList[0];
1766
1767                  for (i=0; i<pPmkid->u4NumCandidates; i++) {
1768                     wext_indicate_wext_event(prGlueInfo,
1769                         IWEVPMKIDCAND,
1770                         (unsigned char *)&pPmkid->arCandidateList[i],
1771                         pPmkid->u4NumCandidates);
1772                     prPmkidCand += sizeof(PARAM_PMKID_CANDIDATE_T);
1773                 }
1774                 }
1775                 break;
1776
1777             default:
1778                 /* case ENUM_STATUS_TYPE_MEDIA_STREAM_MODE */
1779                 /*
1780                 printk(KERN_NOTICE "unknown media specific indication type:%x\n",
1781                     pStatus->StatusType);
1782                 */
1783                 break;
1784             }
1785         }
1786         else {
1787             /*
1788             printk(KERN_WARNING "media specific indication buffer NULL\n");
1789             */
1790         }
1791         break;
1792
1793 #if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS
1794     case WLAN_STATUS_BWCS_UPDATE:
1795     {
1796         wext_indicate_wext_event(prGlueInfo, IWEVCUSTOM, pvBuf, sizeof(PTA_IPC_T));
1797     }
1798
1799         break;
1800
1801 #endif
1802
1803     default:
1804         /*
1805         printk(KERN_WARNING "unknown indication:%lx\n", eStatus);
1806         */
1807         break;
1808     }
1809 } /* kalIndicateStatusAndComplete */
1810
1811
1812 /*----------------------------------------------------------------------------*/
1813 /*!
1814 * \brief This routine is called to update the (re)association request
1815 *        information to the structure used to query and set
1816 *        OID_802_11_ASSOCIATION_INFORMATION.
1817 *
1818 * \param[in] prGlueInfo Pointer to the Glue structure.
1819 * \param[in] pucFrameBody Pointer to the frame body of the last (Re)Association
1820 *                         Request frame from the AP.
1821 * \param[in] u4FrameBodyLen The length of the frame body of the last
1822 *                           (Re)Association Request frame.
1823 * \param[in] fgReassocRequest TRUE, if it is a Reassociation Request frame.
1824 *
1825 * \return (none)
1826 *
1827 */
1828 /*----------------------------------------------------------------------------*/
1829 VOID
1830 kalUpdateReAssocReqInfo (
1831     IN P_GLUE_INFO_T    prGlueInfo,
1832     IN PUINT_8          pucFrameBody,
1833     IN UINT_32          u4FrameBodyLen,
1834     IN BOOLEAN          fgReassocRequest
1835     )
1836 {
1837     PUINT_8 cp;
1838
1839     ASSERT(prGlueInfo);
1840
1841     /* reset */
1842     prGlueInfo->u4ReqIeLength = 0;
1843
1844     if (fgReassocRequest) {
1845         if (u4FrameBodyLen < 15) {
1846             /*
1847             printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen);
1848             */
1849             return;
1850         }
1851     }
1852     else {
1853         if (u4FrameBodyLen < 9) {
1854             /*
1855             printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen);
1856             */
1857             return;
1858         }
1859     }
1860
1861     cp = pucFrameBody;
1862
1863     if (fgReassocRequest) {
1864         /* Capability information field 2 */
1865         /* Listen interval field 2*/
1866         /* Current AP address 6 */
1867         cp += 10;
1868         u4FrameBodyLen -= 10;
1869     }
1870     else {
1871         /* Capability information field 2 */
1872         /* Listen interval field 2*/
1873         cp += 4;
1874         u4FrameBodyLen -= 4;
1875     }
1876
1877     wext_indicate_wext_event(prGlueInfo, IWEVASSOCREQIE, cp, u4FrameBodyLen);
1878
1879     if(u4FrameBodyLen <= CFG_CFG80211_IE_BUF_LEN) {
1880         prGlueInfo->u4ReqIeLength = u4FrameBodyLen;
1881         kalMemCopy(prGlueInfo->aucReqIe, cp, u4FrameBodyLen);
1882     }
1883
1884     return;
1885 }
1886
1887
1888 /*----------------------------------------------------------------------------*/
1889 /*!
1890 * @brief This routine is called to update the (re)association
1891 *        response information to the structure used to reply with 
1892 *        cfg80211_connect_result 
1893 *
1894 * @param prGlueInfo      Pointer to adapter descriptor
1895 * @param pucFrameBody    Pointer to the frame body of the last (Re)Association
1896 *                         Response frame from the AP
1897 * @param u4FrameBodyLen  The length of the frame body of the last
1898 *                          (Re)Association Response frame
1899 *
1900 * @return (none)
1901 */
1902 /*----------------------------------------------------------------------------*/
1903 VOID
1904 kalUpdateReAssocRspInfo (
1905     IN P_GLUE_INFO_T    prGlueInfo,
1906     IN PUINT_8          pucFrameBody,
1907     IN UINT_32          u4FrameBodyLen
1908     )
1909 {
1910     UINT_32 u4IEOffset = 6; /* cap_info, status_code & assoc_id */
1911     UINT_32 u4IELength = u4FrameBodyLen - u4IEOffset;
1912
1913     ASSERT(prGlueInfo);
1914
1915     /* reset */
1916     prGlueInfo->u4RspIeLength = 0;
1917
1918     if(u4IELength <= CFG_CFG80211_IE_BUF_LEN) {
1919         prGlueInfo->u4RspIeLength = u4IELength;
1920         kalMemCopy(prGlueInfo->aucRspIe, pucFrameBody + u4IEOffset, u4IELength);
1921     }
1922
1923 }   /* kalUpdateReAssocRspInfo */
1924
1925
1926 /*----------------------------------------------------------------------------*/
1927 /*!
1928 * \brief Notify OS with SendComplete event of the specific packet. Linux should
1929 *        free packets here.
1930 *
1931 * \param[in] prGlueInfo     Pointer of GLUE Data Structure
1932 * \param[in] pvPacket       Pointer of Packet Handle
1933 * \param[in] status         Status Code for OS upper layer
1934 *
1935 * \return -
1936 */
1937 /*----------------------------------------------------------------------------*/
1938 VOID
1939 kalSendCompleteAndAwakeQueue (
1940     IN P_GLUE_INFO_T prGlueInfo,
1941     IN PVOID pvPacket
1942     )
1943 {
1944
1945     struct net_device   *prDev = NULL;
1946     struct sk_buff      *prSkb = NULL;
1947     UINT_16             u2QueueIdx = 0;
1948     UINT_8              ucNetworkType = 0;
1949     BOOLEAN             fgIsValidDevice = TRUE;
1950
1951
1952     ASSERT(pvPacket);
1953     ASSERT(prGlueInfo->i4TxPendingFrameNum);
1954
1955     prSkb = (struct sk_buff *) pvPacket;
1956 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26)
1957     u2QueueIdx = skb_get_queue_mapping(prSkb);
1958 #endif
1959     ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM);
1960
1961     if (GLUE_GET_PKT_IS_PAL(prSkb)) {
1962         ucNetworkType = NETWORK_TYPE_BOW_INDEX;
1963     } else if (GLUE_GET_PKT_IS_P2P(prSkb)) {
1964         ucNetworkType = NETWORK_TYPE_P2P_INDEX;
1965
1966 #if CFG_ENABLE_WIFI_DIRECT
1967         /* in case packet was sent after P2P device is unregistered */
1968         if(prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) {
1969             fgIsValidDevice = FALSE;
1970         }
1971 #endif
1972     } else {
1973         ucNetworkType = NETWORK_TYPE_AIS_INDEX;
1974     }
1975
1976     GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingFrameNum);
1977     GLUE_DEC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[ucNetworkType][u2QueueIdx]);
1978     prDev = prSkb->dev;
1979
1980     ASSERT(prDev);
1981
1982     if(fgIsValidDevice == TRUE) {
1983 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26)
1984         if (netif_subqueue_stopped(prDev, prSkb) &&
1985                 prGlueInfo->ai4TxPendingFrameNumPerQueue[ucNetworkType][u2QueueIdx] <= CFG_TX_START_NETIF_PER_QUEUE_THRESHOLD) {
1986             netif_wake_subqueue(prDev, u2QueueIdx);
1987         }
1988 #else
1989         if (prGlueInfo->i4TxPendingFrameNum < CFG_TX_STOP_NETIF_QUEUE_THRESHOLD) {
1990             netif_wake_queue(prGlueInfo->prDevHandler);
1991         }
1992 #endif
1993     }
1994
1995
1996     dev_kfree_skb((struct sk_buff *) pvPacket);
1997
1998     DBGLOG(TX, EVENT, ("----- pending frame %d -----\n", prGlueInfo->i4TxPendingFrameNum));
1999
2000     return;
2001 }
2002
2003
2004 /*----------------------------------------------------------------------------*/
2005 /*!
2006 * \brief Copy Mac Address setting from registry. It's All Zeros in Linux.
2007 *
2008 * \param[in] prAdapter Pointer to the Adapter structure
2009 *
2010 * \param[out] paucMacAddr Pointer to the Mac Address buffer
2011 *
2012 * \retval WLAN_STATUS_SUCCESS
2013 *
2014 * \note
2015 */
2016 /*----------------------------------------------------------------------------*/
2017 VOID
2018 kalQueryRegistryMacAddr (
2019     IN  P_GLUE_INFO_T   prGlueInfo,
2020     OUT PUINT_8        paucMacAddr
2021     )
2022 {
2023     UINT_8 aucZeroMac[MAC_ADDR_LEN] = {0,0,0,0,0,0}
2024     DEBUGFUNC("kalQueryRegistryMacAddr");
2025
2026     ASSERT(prGlueInfo);
2027     ASSERT(paucMacAddr);
2028
2029     kalMemCopy((PVOID) paucMacAddr, (PVOID)aucZeroMac, MAC_ADDR_LEN);
2030
2031     return;
2032 } /* end of kalQueryRegistryMacAddr() */
2033
2034 #if CFG_SUPPORT_EXT_CONFIG
2035 /*----------------------------------------------------------------------------*/
2036 /*!
2037 * \brief Read external configuration, ex. NVRAM or file
2038 *
2039 * \param[in] prGlueInfo     Pointer of GLUE Data Structure
2040 *
2041 * \return none
2042 */
2043 /*----------------------------------------------------------------------------*/
2044 UINT_32
2045 kalReadExtCfg (
2046     IN P_GLUE_INFO_T prGlueInfo
2047     )
2048 {
2049     ASSERT(prGlueInfo);
2050
2051     /* External data is given from user space by ioctl or /proc, not read by
2052         driver.
2053     */
2054     if (0 != prGlueInfo->u4ExtCfgLength) {
2055         DBGLOG(INIT, TRACE, ("Read external configuration data -- OK\n"));
2056     }
2057     else {
2058         DBGLOG(INIT, TRACE, ("Read external configuration data -- fail\n"));
2059     }
2060
2061     return prGlueInfo->u4ExtCfgLength;
2062 }
2063 #endif
2064
2065 /*----------------------------------------------------------------------------*/
2066 /*!
2067 * @brief This inline function is to extract some packet information, including
2068 *        user priority, packet length, destination address, 802.1x and BT over Wi-Fi
2069 *        or not.
2070 *
2071 * @param prGlueInfo         Pointer to the glue structure
2072 * @param prNdisPacket       Packet descriptor
2073 * @param pucPriorityParam   User priority
2074 * @param pu4PacketLen       Packet length
2075 * @param pucEthDestAddr Destination address
2076 * @param pfgIs1X            802.1x packet or not
2077 * @param pfgIsPAL           BT over Wi-Fi packet or not
2078 *
2079 * @retval TRUE      Success to extract information
2080 * @retval FALSE     Fail to extract correct information
2081 */
2082 /*----------------------------------------------------------------------------*/
2083
2084 BOOL
2085 kalQoSFrameClassifierAndPacketInfo (
2086     IN P_GLUE_INFO_T prGlueInfo,
2087     IN P_NATIVE_PACKET prPacket,
2088     OUT PUINT_8 pucPriorityParam,
2089     OUT PUINT_32 pu4PacketLen,
2090     OUT PUINT_8 pucEthDestAddr,
2091     OUT PBOOLEAN pfgIs1X,
2092     OUT PBOOLEAN pfgIsPAL,
2093     OUT PUINT_8 pucNetworkType
2094     )
2095 {
2096
2097     UINT_32 u4PacketLen;
2098
2099
2100     UINT_8 ucUserPriority = USER_PRIORITY_DEFAULT; /* Default */
2101     UINT_16 u2EtherTypeLen;
2102     struct sk_buff *prSkb = (struct sk_buff *) prPacket;
2103     PUINT_8 aucLookAheadBuf = NULL;
2104
2105     DEBUGFUNC("kalQoSFrameClassifierAndPacketInfo");
2106
2107     u4PacketLen = prSkb->len;
2108
2109     if (u4PacketLen < ETH_HLEN) {
2110         DBGLOG(INIT, WARN, ("Invalid Ether packet length: %d\n", u4PacketLen));
2111         return FALSE;
2112     }
2113
2114     aucLookAheadBuf = prSkb->data;
2115
2116     *pfgIs1X = FALSE;
2117     *pfgIsPAL = FALSE;
2118     //4 <3> Obtain the User Priority for WMM
2119     u2EtherTypeLen = (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET] << 8) | (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET + 1]);
2120
2121     if ((u2EtherTypeLen == ETH_P_IP) &&
2122         (u4PacketLen >= LOOK_AHEAD_LEN)) {
2123         PUINT_8 pucIpHdr = &aucLookAheadBuf[ETH_HLEN];
2124         UINT_8 ucIpVersion;
2125
2126         ucIpVersion = (pucIpHdr[0] & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET;
2127         //printk ("ip version %x\n", ucIpVersion);
2128         if (ucIpVersion == IPVERSION) {
2129             UINT_8 ucIpTos;
2130             /* Get the DSCP value from the header of IP packet. */
2131             ucIpTos = pucIpHdr[1];
2132             ucUserPriority = ((ucIpTos & IPTOS_PREC_MASK) >> IPTOS_PREC_OFFSET);
2133         }
2134
2135         /* TODO(Kevin): Add TSPEC classifier here */
2136     }
2137     else if (u2EtherTypeLen == ETH_P_1X) { /* For Port Control */
2138         //DBGLOG(REQ, TRACE, ("Tx 1x\n"));
2139         *pfgIs1X = TRUE;
2140     }
2141     else if (u2EtherTypeLen == ETH_P_PRE_1X) { /* For Pre 1x pkt */
2142         //DBGLOG(REQ, TRACE, ("Tx Pre-1x\n"));
2143         *pfgIs1X = TRUE;
2144     }
2145 #if CFG_SUPPORT_WAPI
2146     else if (u2EtherTypeLen == ETH_WPI_1X) {
2147         *pfgIs1X = TRUE;
2148     }
2149 #endif
2150     else if (u2EtherTypeLen <= 1500) { /* 802.3 Frame */
2151         UINT_8 ucDSAP, ucSSAP, ucControl;
2152         UINT_8 aucOUI[3];
2153
2154         ucDSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET];
2155         ucSSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 1];
2156         ucControl = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 2];
2157
2158         aucOUI[0] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET];
2159         aucOUI[1] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 1];
2160         aucOUI[2] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 2];
2161
2162         if(ucDSAP == ETH_LLC_DSAP_SNAP &&
2163                 ucSSAP == ETH_LLC_SSAP_SNAP &&
2164                 ucControl == ETH_LLC_CONTROL_UNNUMBERED_INFORMATION &&
2165                 aucOUI[0] == ETH_SNAP_BT_SIG_OUI_0 &&
2166                 aucOUI[1] == ETH_SNAP_BT_SIG_OUI_1 &&
2167                 aucOUI[2] == ETH_SNAP_BT_SIG_OUI_2) {
2168
2169             UINT_16 tmp = ((aucLookAheadBuf[ETH_SNAP_OFFSET + 3] << 8) | aucLookAheadBuf[ETH_SNAP_OFFSET + 4]);
2170
2171             *pfgIsPAL = TRUE;
2172             ucUserPriority = (UINT_8)prSkb->priority;
2173
2174             if (tmp == BOW_PROTOCOL_ID_SECURITY_FRAME) {
2175                 *pfgIs1X = TRUE;
2176             }
2177         }
2178     }
2179
2180     //4 <4> Return the value of Priority Parameter.
2181     *pucPriorityParam = ucUserPriority;
2182
2183     //4 <5> Retrieve Packet Information - DA
2184     /* Packet Length/ Destination Address */
2185     *pu4PacketLen = u4PacketLen;
2186
2187     kalMemCopy(pucEthDestAddr, aucLookAheadBuf, PARAM_MAC_ADDR_LEN);
2188
2189
2190     //<6> Network type
2191 #if CFG_ENABLE_BT_OVER_WIFI
2192     if(*pfgIsPAL == TRUE) {
2193         *pucNetworkType = NETWORK_TYPE_BOW_INDEX;
2194     }
2195     else
2196 #endif
2197     {
2198 #if CFG_ENABLE_WIFI_DIRECT
2199         if(prGlueInfo->prAdapter->fgIsP2PRegistered && GLUE_GET_PKT_IS_P2P(prPacket)) {
2200             *pucNetworkType = NETWORK_TYPE_P2P_INDEX;
2201         }
2202         else
2203 #endif
2204         {
2205             *pucNetworkType = NETWORK_TYPE_AIS_INDEX;
2206         }
2207     }
2208     return TRUE;
2209 } /* end of kalQoSFrameClassifier() */
2210
2211 VOID
2212 kalOidComplete (
2213     IN P_GLUE_INFO_T prGlueInfo,
2214     IN BOOLEAN fgSetQuery,
2215     IN UINT_32 u4SetQueryInfoLen,
2216     IN WLAN_STATUS rOidStatus
2217     )
2218 {
2219
2220     ASSERT(prGlueInfo);
2221     /* remove timeout check timer */
2222     wlanoidClearTimeoutCheck(prGlueInfo->prAdapter);
2223
2224     //if (prGlueInfo->u4TimeoutFlag != 1) {
2225     prGlueInfo->rPendStatus = rOidStatus;
2226     complete(&prGlueInfo->rPendComp);
2227     prGlueInfo->u4OidCompleteFlag = 1;
2228     //}
2229     /* else let it timeout on kalIoctl entry */
2230 }
2231
2232 VOID
2233 kalOidClearance(
2234     IN P_GLUE_INFO_T prGlueInfo
2235     )
2236 {
2237     //if (prGlueInfo->u4TimeoutFlag != 1) {
2238      //clear_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->u4Flag);
2239     if (prGlueInfo->u4OidCompleteFlag != 1) {
2240         complete(&prGlueInfo->rPendComp);
2241     }
2242     //}
2243 }
2244
2245
2246 /*----------------------------------------------------------------------------*/
2247 /*!
2248 * @brief This function is used to transfer linux ioctl to OID, and  we
2249 * need to specify the behavior of the OID by ourself
2250 *
2251 * @param prGlueInfo         Pointer to the glue structure
2252 * @param pvInfoBuf          Data buffer
2253 * @param u4InfoBufLen       Data buffer length
2254 * @param fgRead             Is this a read OID
2255 * @param fgWaitResp         does this OID need to wait for values
2256 * @param fgCmd              does this OID compose command packet
2257 * @param pu4QryInfoLen      The data length of the return values
2258 *
2259 * @retval TRUE      Success to extract information
2260 * @retval FALSE     Fail to extract correct information
2261 */
2262 /*----------------------------------------------------------------------------*/
2263
2264 // todo: enqueue the i/o requests for multiple processes access
2265 //
2266 // currently, return -1
2267 //
2268
2269 //static GL_IO_REQ_T OidEntry;
2270
2271 WLAN_STATUS
2272 kalIoctl (IN P_GLUE_INFO_T    prGlueInfo,
2273     IN PFN_OID_HANDLER_FUNC     pfnOidHandler,
2274     IN PVOID                    pvInfoBuf,
2275     IN UINT_32                  u4InfoBufLen,
2276     IN BOOL                     fgRead,
2277     IN BOOL                     fgWaitResp,
2278     IN BOOL                     fgCmd,
2279     IN BOOL                     fgIsP2pOid,
2280     OUT PUINT_32                pu4QryInfoLen
2281     )
2282 {
2283     P_GL_IO_REQ_T prIoReq = NULL;
2284     WLAN_STATUS ret = WLAN_STATUS_SUCCESS;
2285
2286     //GLUE_SPIN_LOCK_DECLARATION();
2287     ASSERT(prGlueInfo);
2288
2289     /* <1> Check if driver is halt */
2290
2291     //if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) {
2292     //    return WLAN_STATUS_ADAPTER_NOT_READY;
2293     //}
2294
2295     if (down_interruptible(&g_halt_sem)) {
2296         return WLAN_STATUS_FAILURE;
2297     }
2298
2299
2300     if (g_u4HaltFlag) {
2301         up(&g_halt_sem);
2302         return WLAN_STATUS_ADAPTER_NOT_READY;
2303     }
2304
2305     if(down_interruptible(&prGlueInfo->ioctl_sem)) {
2306         up(&g_halt_sem);
2307         return WLAN_STATUS_FAILURE;
2308     }
2309
2310     /* <2> TODO: thread-safe */
2311
2312     /* <3> point to the OidEntry of Glue layer */
2313
2314     prIoReq = &(prGlueInfo->OidEntry);
2315
2316     ASSERT(prIoReq);
2317
2318     /* <4> Compose the I/O request */
2319     prIoReq->prAdapter = prGlueInfo->prAdapter;
2320     prIoReq->pfnOidHandler = pfnOidHandler;
2321     prIoReq->pvInfoBuf = pvInfoBuf;
2322     prIoReq->u4InfoBufLen = u4InfoBufLen;
2323     prIoReq->pu4QryInfoLen = pu4QryInfoLen;
2324     prIoReq->fgRead = fgRead;
2325     prIoReq->fgWaitResp= fgWaitResp;
2326     prIoReq->rStatus = WLAN_STATUS_FAILURE;
2327 #if CFG_ENABLE_WIFI_DIRECT
2328     prIoReq->fgIsP2pOid = fgIsP2pOid;
2329 #endif
2330
2331     /* <5> Reset the status of pending OID */
2332     prGlueInfo->rPendStatus = WLAN_STATUS_FAILURE;
2333     //prGlueInfo->u4TimeoutFlag = 0;
2334     prGlueInfo->u4OidCompleteFlag = 0;
2335
2336     /* <6> Check if we use the command queue */
2337     prIoReq->u4Flag = fgCmd;
2338
2339     /* <7> schedule the OID bit */
2340     set_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->u4Flag);
2341
2342     /* <8> Wake up tx thread to handle kick start the I/O request */
2343     wake_up_interruptible(&prGlueInfo->waitq);
2344
2345     /* <9> Block and wait for event or timeout, current the timeout is 5 secs */
2346     //if (wait_for_completion_interruptible_timeout(&prGlueInfo->rPendComp, 5 * KAL_HZ)) {
2347     //if (!wait_for_completion_interruptible(&prGlueInfo->rPendComp)) {
2348     wait_for_completion(&prGlueInfo->rPendComp); {
2349         /* Case 1: No timeout. */
2350         /* if return WLAN_STATUS_PENDING, the status of cmd is stored in prGlueInfo  */
2351         if (prIoReq->rStatus == WLAN_STATUS_PENDING) {
2352             ret = prGlueInfo->rPendStatus;
2353         } else {
2354             ret = prIoReq->rStatus;
2355         }
2356     }
2357     #if 0
2358         else {
2359         /* Case 2: timeout */
2360         /* clear pending OID's cmd in CMD queue */
2361         if (fgCmd) {
2362             prGlueInfo->u4TimeoutFlag = 1;
2363             wlanReleasePendingOid(prGlueInfo->prAdapter, 0);
2364         }
2365         ret = WLAN_STATUS_FAILURE;
2366     }
2367     #endif
2368
2369     up(&prGlueInfo->ioctl_sem);
2370     up(&g_halt_sem);
2371
2372     return ret;
2373 }
2374
2375 /*----------------------------------------------------------------------------*/
2376 /*!
2377 * \brief This routine is used to clear all pending security frames
2378 *
2379 * \param prGlueInfo     Pointer of GLUE Data Structure
2380 *
2381 * \retval none
2382 */
2383 /*----------------------------------------------------------------------------*/
2384 VOID
2385 kalClearSecurityFrames(
2386     IN P_GLUE_INFO_T prGlueInfo
2387     )
2388 {
2389     P_QUE_T prCmdQue;
2390     QUE_T rTempCmdQue;
2391     P_QUE_T prTempCmdQue = &rTempCmdQue;
2392     P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T)NULL;
2393
2394     P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T)NULL;
2395     GLUE_SPIN_LOCK_DECLARATION();
2396
2397     ASSERT(prGlueInfo);
2398
2399     // Clear pending security frames in prGlueInfo->rCmdQueue
2400     prCmdQue = &prGlueInfo->rCmdQueue;
2401
2402
2403
2404     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
2405     QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
2406
2407     QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
2408     while (prQueueEntry) {
2409         prCmdInfo = (P_CMD_INFO_T)prQueueEntry;
2410
2411         if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) {
2412             prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo);
2413             cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo);
2414         }
2415         else {
2416             QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry);
2417         }
2418
2419         QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
2420     }
2421
2422     QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue);
2423     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
2424 }
2425
2426
2427 /*----------------------------------------------------------------------------*/
2428 /*!
2429 * \brief This routine is used to clear pending security frames
2430 *        belongs to dedicated network type
2431 *
2432 * \param prGlueInfo         Pointer of GLUE Data Structure
2433 * \param eNetworkTypeIdx    Network Type Index
2434 *
2435 * \retval none
2436 */
2437 /*----------------------------------------------------------------------------*/
2438 VOID
2439 kalClearSecurityFramesByNetType(
2440     IN P_GLUE_INFO_T prGlueInfo,
2441     IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx
2442     )
2443 {
2444     P_QUE_T prCmdQue;
2445     QUE_T rTempCmdQue;
2446     P_QUE_T prTempCmdQue = &rTempCmdQue;
2447     P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T)NULL;
2448
2449     P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T)NULL;
2450     GLUE_SPIN_LOCK_DECLARATION();
2451
2452
2453     ASSERT(prGlueInfo);
2454
2455     // Clear pending security frames in prGlueInfo->rCmdQueue
2456     prCmdQue = &prGlueInfo->rCmdQueue;
2457
2458     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
2459     QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
2460
2461     QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
2462     while (prQueueEntry) {
2463         prCmdInfo = (P_CMD_INFO_T)prQueueEntry;
2464
2465         if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME &&
2466                 prCmdInfo->eNetworkType == eNetworkTypeIdx) {
2467             prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo);
2468             cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo);
2469         }
2470         else {
2471             QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry);
2472         }
2473
2474         QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
2475     }
2476
2477     QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue);
2478     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
2479 }
2480
2481
2482 /*----------------------------------------------------------------------------*/
2483 /*!
2484 * \brief This routine is used to clear all pending management frames
2485 *
2486 * \param prGlueInfo     Pointer of GLUE Data Structure
2487 *
2488 * \retval none
2489 */
2490 /*----------------------------------------------------------------------------*/
2491 VOID
2492 kalClearMgmtFrames(
2493     IN P_GLUE_INFO_T prGlueInfo
2494     )
2495 {
2496     P_QUE_T prCmdQue;
2497     QUE_T rTempCmdQue;
2498     P_QUE_T prTempCmdQue = &rTempCmdQue;
2499     P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T)NULL;
2500     P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T)NULL;
2501
2502     GLUE_SPIN_LOCK_DECLARATION();
2503
2504     ASSERT(prGlueInfo);
2505
2506     // Clear pending management frames in prGlueInfo->rCmdQueue
2507     prCmdQue = &prGlueInfo->rCmdQueue;
2508
2509     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
2510     QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
2511
2512     QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
2513     while (prQueueEntry) {
2514         prCmdInfo = (P_CMD_INFO_T)prQueueEntry;
2515
2516         if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) {
2517             wlanReleaseCommand(prGlueInfo->prAdapter, prCmdInfo);
2518             cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo);
2519         }
2520         else {
2521             QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry);
2522         }
2523
2524         QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
2525     }
2526
2527     QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue);
2528     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
2529 }
2530
2531
2532 /*----------------------------------------------------------------------------*/
2533 /*!
2534 * \brief This routine is used to clear all pending management frames
2535 *           belongs to dedicated network type
2536 * \param prGlueInfo     Pointer of GLUE Data Structure
2537 *
2538 * \retval none
2539 */
2540 /*----------------------------------------------------------------------------*/
2541 VOID
2542 kalClearMgmtFramesByNetType (
2543     IN P_GLUE_INFO_T prGlueInfo,
2544     IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx
2545     )
2546 {
2547     P_QUE_T prCmdQue;
2548     QUE_T rTempCmdQue;
2549     P_QUE_T prTempCmdQue = &rTempCmdQue;
2550     P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T)NULL;
2551     P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T)NULL;
2552
2553     GLUE_SPIN_LOCK_DECLARATION();
2554
2555     ASSERT(prGlueInfo);
2556
2557     // Clear pending management frames in prGlueInfo->rCmdQueue
2558     prCmdQue = &prGlueInfo->rCmdQueue;
2559
2560     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
2561     QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
2562
2563     QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
2564     while (prQueueEntry) {
2565         prCmdInfo = (P_CMD_INFO_T)prQueueEntry;
2566
2567         if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME &&
2568                 prCmdInfo->eNetworkType == eNetworkTypeIdx) {
2569             wlanReleaseCommand(prGlueInfo->prAdapter, prCmdInfo);
2570             cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo);
2571         }
2572         else {
2573             QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry);
2574         }
2575
2576         QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
2577     }
2578
2579     QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue);
2580     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
2581 } /* kalClearMgmtFramesByNetType */
2582
2583
2584
2585 /*----------------------------------------------------------------------------*/
2586 /*!
2587 * @brief This function is a kernel thread function for handling command packets
2588 * Tx requests and interrupt events
2589 *
2590 * @param data       data pointer to private data of tx_thread
2591 *
2592 * @retval           If the function succeeds, the return value is 0.
2593 * Otherwise, an error code is returned.
2594 *
2595 */
2596 /*----------------------------------------------------------------------------*/
2597
2598 int tx_thread(void *data)
2599 {
2600     struct net_device   *dev = data;
2601     P_GLUE_INFO_T       prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(dev));
2602
2603     P_QUE_ENTRY_T       prQueueEntry = NULL;
2604     P_GL_IO_REQ_T       prIoReq = NULL;
2605     P_QUE_T             prTxQueue = NULL;
2606     P_QUE_T             prCmdQue = NULL;
2607
2608     int                 ret = 0;
2609
2610     BOOLEAN             fgNeedHwAccess = FALSE;
2611
2612     struct sk_buff      *prSkb = NULL;
2613
2614     /* for spin lock acquire and release */
2615     GLUE_SPIN_LOCK_DECLARATION();
2616
2617     prTxQueue = &prGlueInfo->rTxQueue;
2618     prCmdQue = &prGlueInfo->rCmdQueue;
2619
2620     current->flags |= PF_NOFREEZE;
2621
2622     DBGLOG(INIT, INFO, ("tx_thread starts running... \n"));
2623
2624     while (TRUE) {
2625
2626 #if CFG_ENABLE_WIFI_DIRECT
2627         /*run p2p multicast list work. */
2628         if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->u4Flag)) {
2629             p2pSetMulticastListWorkQueueWrapper(prGlueInfo);
2630         }
2631 #endif
2632
2633         if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) {
2634             DBGLOG(INIT, INFO, ("tx_thread should stop now...\n"));
2635             break;
2636         }
2637
2638         /*
2639          * sleep on waitqueue if no events occurred. Event contain (1) GLUE_FLAG_INT
2640          * (2) GLUE_FLAG_OID (3) GLUE_FLAG_TXREQ (4) GLUE_FLAG_HALT
2641          *
2642          */
2643
2644         ret = wait_event_interruptible(prGlueInfo->waitq,
2645                 (prGlueInfo->u4Flag != 0));
2646
2647 #if CFG_DBG_GPIO_PINS
2648         /* TX thread Wake up */
2649         mtk_wcn_stp_debug_gpio_assert(IDX_TX_THREAD, DBG_TIE_LOW);
2650 #endif
2651 #if CFG_ENABLE_WIFI_DIRECT
2652         /*run p2p multicast list work. */
2653         if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->u4Flag)) {
2654             p2pSetMulticastListWorkQueueWrapper(prGlueInfo);
2655         }
2656
2657         if (test_and_clear_bit(GLUE_FLAG_FRAME_FILTER_BIT, &prGlueInfo->u4Flag)) {
2658             p2pFuncUpdateMgmtFrameRegister(prGlueInfo->prAdapter, prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter);
2659         }
2660
2661         
2662 #endif
2663         if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) {
2664             DBGLOG(INIT, INFO, ("<1>tx_thread should stop now...\n"));
2665             break;
2666         }
2667
2668         fgNeedHwAccess = FALSE;
2669
2670         /* Handle Interrupt */
2671         if (test_and_clear_bit(GLUE_FLAG_INT_BIT, &prGlueInfo->u4Flag)) {
2672
2673             if (fgNeedHwAccess == FALSE) {
2674                 fgNeedHwAccess = TRUE;
2675
2676                 wlanAcquirePowerControl(prGlueInfo->prAdapter);
2677             }
2678
2679             /* the Wi-Fi interrupt is already disabled in mmc thread,
2680                     so we set the flag only to enable the interrupt later  */
2681             prGlueInfo->prAdapter->fgIsIntEnable = FALSE;
2682             //wlanISR(prGlueInfo->prAdapter, TRUE);
2683
2684             if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) {
2685                 /* Should stop now... skip pending interrupt */
2686                 DBGLOG(INIT, INFO, ("ignore pending interrupt\n"));
2687             }
2688             else {
2689
2690                 wlanIST(prGlueInfo->prAdapter);
2691             }
2692         }
2693
2694         /* transfer ioctl to OID request */
2695         #if 0
2696         if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) {
2697             printk(KERN_INFO DRV_NAME"<2>tx_thread should stop now...\n");
2698             break;
2699         }
2700         #endif
2701
2702         do {
2703             if (test_and_clear_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->u4Flag)) {
2704                 /* get current prIoReq */
2705                 prIoReq = &(prGlueInfo->OidEntry);
2706 #if CFG_ENABLE_WIFI_DIRECT
2707                 if(prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE
2708                     && prIoReq->fgIsP2pOid == TRUE) {
2709                     /*    if this Oid belongs to p2p and p2p module is removed
2710                                     *      do nothing,
2711                                     */
2712                 }
2713                 else
2714 #endif
2715                 {
2716                     if (FALSE == prIoReq->fgRead) {
2717                         prIoReq->rStatus = wlanSetInformation(
2718                                 prIoReq->prAdapter,
2719                                 prIoReq->pfnOidHandler,
2720                                 prIoReq->pvInfoBuf,
2721                                 prIoReq->u4InfoBufLen,
2722                                 prIoReq->pu4QryInfoLen);
2723                     } else {
2724                         prIoReq->rStatus = wlanQueryInformation(
2725                                 prIoReq->prAdapter,
2726                                 prIoReq->pfnOidHandler,
2727                                 prIoReq->pvInfoBuf,
2728                                 prIoReq->u4InfoBufLen,
2729                                 prIoReq->pu4QryInfoLen);
2730                     }
2731
2732                     if (prIoReq->rStatus != WLAN_STATUS_PENDING) {
2733                         complete(&prGlueInfo->rPendComp);
2734                     }
2735                     else {
2736                         wlanoidTimeoutCheck(prGlueInfo->prAdapter, prIoReq->pfnOidHandler);
2737                     }
2738                 }
2739              }
2740
2741         } while (FALSE);
2742
2743
2744         /*
2745          *
2746          * if TX request, clear the TXREQ flag. TXREQ set by kalSetEvent/GlueSetEvent
2747          * indicates the following requests occur
2748          *
2749          */
2750         #if 0
2751         if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) {
2752             printk(KERN_INFO DRV_NAME"<3>tx_thread should stop now...\n");
2753             break;
2754         }
2755         #endif
2756
2757         if (test_and_clear_bit(GLUE_FLAG_TXREQ_BIT, &prGlueInfo->u4Flag))
2758         {
2759
2760             /* Process Mailbox Messages */
2761             wlanProcessMboxMessage(prGlueInfo->prAdapter);
2762
2763             /* Process CMD request */
2764             do {
2765                 if (prCmdQue->u4NumElem > 0) {
2766                     if (fgNeedHwAccess == FALSE) {
2767                         fgNeedHwAccess = TRUE;
2768
2769                         wlanAcquirePowerControl(prGlueInfo->prAdapter);
2770                     }
2771                     wlanProcessCommandQueue(prGlueInfo->prAdapter, prCmdQue);
2772                 }
2773             } while (FALSE);
2774
2775             /* Handle Packet Tx */
2776             {
2777                 while (QUEUE_IS_NOT_EMPTY(prTxQueue)) {
2778                     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
2779                     QUEUE_REMOVE_HEAD(prTxQueue, prQueueEntry, P_QUE_ENTRY_T);
2780                     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
2781
2782                     ASSERT(prQueueEntry);
2783                     if (NULL == prQueueEntry) {
2784                         break;
2785                     }
2786
2787                     prSkb = (struct sk_buff *) GLUE_GET_PKT_DESCRIPTOR(prQueueEntry);
2788                     ASSERT(prSkb);
2789                     if (NULL == prSkb) {
2790                         DBGLOG(INIT, WARN, ("prSkb == NULL in tx\n"));
2791                         continue;
2792                     }
2793
2794                     if(wlanEnqueueTxPacket(prGlueInfo->prAdapter,
2795                                 (P_NATIVE_PACKET)prSkb) == WLAN_STATUS_RESOURCES) {
2796                         GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
2797                         QUEUE_INSERT_HEAD(prTxQueue, prQueueEntry);
2798                         GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
2799
2800                         break;
2801                     }
2802                 }
2803
2804                 if (wlanGetTxPendingFrameCount(prGlueInfo->prAdapter) > 0) {
2805                     wlanTxPendingPackets(prGlueInfo->prAdapter, &fgNeedHwAccess);
2806                 }
2807             }
2808
2809         }
2810
2811         /* Process RX, In linux, we don't need to free sk_buff by ourself */
2812
2813         /* In linux, we don't need to free sk_buff by ourself */
2814
2815         /* In linux, we don't do reset */
2816         if (fgNeedHwAccess == TRUE) {
2817             wlanReleasePowerControl(prGlueInfo->prAdapter);
2818         }
2819
2820         /* handle cnmTimer time out */
2821         if (test_and_clear_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->u4Flag)) {
2822             wlanTimerTimeoutCheck(prGlueInfo->prAdapter);
2823         }
2824
2825     #if CFG_DBG_GPIO_PINS
2826         /* TX thread go to sleep */
2827         if (!prGlueInfo->u4Flag){
2828             mtk_wcn_stp_debug_gpio_assert(IDX_TX_THREAD, DBG_TIE_HIGH);
2829         }
2830     #endif
2831     }
2832
2833     #if 0
2834     if (fgNeedHwAccess == TRUE) {
2835         wlanReleasePowerControl(prGlueInfo->prAdapter);
2836     }
2837     #endif
2838
2839     /* flush the pending TX packets */
2840     if (prGlueInfo->i4TxPendingFrameNum > 0) {
2841         kalFlushPendingTxPackets(prGlueInfo);
2842     }
2843
2844     /* flush pending security frames */
2845     if (prGlueInfo->i4TxPendingSecurityFrameNum > 0) {
2846         kalClearSecurityFrames(prGlueInfo);
2847     }
2848
2849     /* remove pending oid */
2850     wlanReleasePendingOid(prGlueInfo->prAdapter, 0);
2851
2852
2853     /* In linux, we don't need to free sk_buff by ourself */
2854
2855     DBGLOG(INIT, INFO, ("mtk_sdiod stops\n"));
2856     complete(&prGlueInfo->rHaltComp);
2857
2858     return 0;
2859
2860 }
2861
2862 /*----------------------------------------------------------------------------*/
2863 /*!
2864 * \brief This routine is used to check if card is removed
2865 *
2866 * \param pvGlueInfo     Pointer of GLUE Data Structure
2867 *
2868 * \retval TRUE:     card is removed
2869 *         FALSE:    card is still attached
2870 */
2871 /*----------------------------------------------------------------------------*/
2872 BOOLEAN
2873 kalIsCardRemoved(
2874     IN P_GLUE_INFO_T    prGlueInfo
2875     )
2876 {
2877     ASSERT(prGlueInfo);
2878
2879     return FALSE;
2880     // Linux MMC doesn't have removal notification yet
2881 }
2882
2883 /*----------------------------------------------------------------------------*/
2884 /*!
2885  * \brief This routine is used to send command to firmware for overriding netweork address
2886  *
2887  * \param pvGlueInfo Pointer of GLUE Data Structure
2888
2889  * \retval TRUE
2890  *         FALSE
2891  */
2892 /*----------------------------------------------------------------------------*/
2893 BOOLEAN
2894 kalRetrieveNetworkAddress(
2895     IN P_GLUE_INFO_T prGlueInfo,
2896     IN OUT PARAM_MAC_ADDRESS * prMacAddr
2897     )
2898 {
2899     ASSERT(prGlueInfo);
2900
2901     if(prGlueInfo->fgIsMacAddrOverride == FALSE) {
2902     #if !defined(CONFIG_X86)
2903         UINT_32 i;
2904         BOOLEAN fgIsReadError = FALSE;
2905
2906         for(i = 0 ; i < MAC_ADDR_LEN ; i+=2) {
2907             if(kalCfgDataRead16(prGlueInfo,
2908                         OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucMacAddress) + i,
2909                         (PUINT_16) (((PUINT_8)prMacAddr) + i)) == FALSE) {
2910                 fgIsReadError = TRUE;
2911                 break;
2912             }
2913         }
2914
2915         if(fgIsReadError == TRUE) {
2916             return FALSE;
2917         }
2918         else {
2919             return TRUE;
2920         }
2921     #else
2922         /* x86 Linux doesn't need to override network address so far */
2923         return FALSE;
2924     #endif
2925     }
2926     else {
2927         COPY_MAC_ADDR(prMacAddr, prGlueInfo->rMacAddrOverride);
2928
2929         return TRUE;
2930     }
2931 }
2932
2933
2934 /*----------------------------------------------------------------------------*/
2935 /*!
2936 * \brief This routine is used to flush pending TX packets in glue layer
2937 *
2938 * \param pvGlueInfo     Pointer of GLUE Data Structure
2939 *
2940 * \retval none
2941 */
2942 /*----------------------------------------------------------------------------*/
2943 VOID
2944 kalFlushPendingTxPackets(
2945     IN P_GLUE_INFO_T    prGlueInfo
2946     )
2947 {
2948     P_QUE_T prTxQue;
2949     P_QUE_ENTRY_T prQueueEntry;
2950     PVOID prPacket;
2951
2952     GLUE_SPIN_LOCK_DECLARATION();
2953
2954     ASSERT(prGlueInfo);
2955
2956     prTxQue = &(prGlueInfo->rTxQueue);
2957
2958     if (prGlueInfo->i4TxPendingFrameNum) {
2959         while (TRUE) {
2960             GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
2961             QUEUE_REMOVE_HEAD(prTxQue, prQueueEntry, P_QUE_ENTRY_T);
2962             GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
2963
2964             if (prQueueEntry == NULL) {
2965                 break;
2966             }
2967
2968             prPacket = GLUE_GET_PKT_DESCRIPTOR(prQueueEntry);
2969
2970             kalSendComplete(prGlueInfo,
2971                     prPacket,
2972                     WLAN_STATUS_NOT_ACCEPTED);
2973         }
2974     }
2975 }
2976
2977 /*----------------------------------------------------------------------------*/
2978 /*!
2979 * \brief This routine is get indicated media state
2980 *
2981 * \param pvGlueInfo     Pointer of GLUE Data Structure
2982 *
2983 * \retval
2984 */
2985 /*----------------------------------------------------------------------------*/
2986 ENUM_PARAM_MEDIA_STATE_T
2987 kalGetMediaStateIndicated(
2988     IN P_GLUE_INFO_T    prGlueInfo
2989     )
2990 {
2991     ASSERT(prGlueInfo);
2992
2993     return prGlueInfo->eParamMediaStateIndicated;
2994 }
2995
2996
2997 /*----------------------------------------------------------------------------*/
2998 /*!
2999 * \brief This routine is used to set indicated media state
3000 *
3001 * \param pvGlueInfo     Pointer of GLUE Data Structure
3002 *
3003 * \retval none
3004 */
3005 /*----------------------------------------------------------------------------*/
3006 VOID
3007 kalSetMediaStateIndicated(
3008     IN P_GLUE_INFO_T            prGlueInfo,
3009     IN ENUM_PARAM_MEDIA_STATE_T eParamMediaStateIndicate
3010     )
3011 {
3012     ASSERT(prGlueInfo);
3013
3014     prGlueInfo->eParamMediaStateIndicated = eParamMediaStateIndicate;
3015 }
3016
3017
3018 /*----------------------------------------------------------------------------*/
3019 /*!
3020 * \brief This routine is used to clear pending OID staying in command queue
3021 *
3022 * \param prGlueInfo     Pointer of GLUE Data Structure
3023 *
3024 * \retval none
3025 */
3026 /*----------------------------------------------------------------------------*/
3027 VOID
3028 kalOidCmdClearance(
3029     IN P_GLUE_INFO_T prGlueInfo
3030     )
3031 {
3032     P_QUE_T prCmdQue;
3033     QUE_T rTempCmdQue;
3034     P_QUE_T prTempCmdQue = &rTempCmdQue;
3035     P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T)NULL;
3036     P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T)NULL;
3037
3038     GLUE_SPIN_LOCK_DECLARATION();
3039
3040     ASSERT(prGlueInfo);
3041
3042     prCmdQue = &prGlueInfo->rCmdQueue;
3043
3044     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
3045     QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
3046
3047     QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
3048     while (prQueueEntry) {
3049
3050         if (((P_CMD_INFO_T)prQueueEntry)->fgIsOid) {
3051             prCmdInfo = (P_CMD_INFO_T)prQueueEntry;
3052             break;
3053         }
3054         else {
3055             QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry);
3056         }
3057
3058         QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
3059     }
3060
3061     QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue);
3062     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
3063
3064     if (prCmdInfo) {
3065         if (prCmdInfo->pfCmdTimeoutHandler) {
3066             prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo);
3067         }
3068         else {
3069             kalOidComplete(prGlueInfo,
3070                     prCmdInfo->fgSetQuery,
3071                     0,
3072                     WLAN_STATUS_NOT_ACCEPTED);
3073         }
3074
3075         prGlueInfo->u4OidCompleteFlag = 1;
3076         cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo);
3077     }
3078 }
3079
3080
3081 /*----------------------------------------------------------------------------*/
3082 /*!
3083 * \brief This routine is used to insert command into prCmdQueue
3084 *
3085 * \param prGlueInfo     Pointer of GLUE Data Structure
3086 *        prQueueEntry   Pointer of queue entry to be inserted
3087 *
3088 * \retval none
3089 */
3090 /*----------------------------------------------------------------------------*/
3091 VOID
3092 kalEnqueueCommand(
3093     IN P_GLUE_INFO_T prGlueInfo,
3094     IN P_QUE_ENTRY_T prQueueEntry
3095     )
3096 {
3097     P_QUE_T prCmdQue;
3098
3099     GLUE_SPIN_LOCK_DECLARATION();
3100
3101     ASSERT(prGlueInfo);
3102     ASSERT(prQueueEntry);
3103
3104     prCmdQue = &prGlueInfo->rCmdQueue;
3105
3106     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
3107     QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry);
3108     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
3109 }
3110
3111 /*----------------------------------------------------------------------------*/
3112 /*!
3113 * @brief Handle EVENT_ID_ASSOC_INFO event packet by indicating to OS with
3114 *        proper information
3115 *
3116 * @param pvGlueInfo     Pointer of GLUE Data Structure
3117 * @param prAssocInfo    Pointer of EVENT_ID_ASSOC_INFO Packet
3118 *
3119 * @return none
3120 */
3121 /*----------------------------------------------------------------------------*/
3122 VOID
3123 kalHandleAssocInfo(
3124     IN P_GLUE_INFO_T prGlueInfo,
3125     IN P_EVENT_ASSOC_INFO prAssocInfo
3126     )
3127 {
3128     // to do
3129 }
3130
3131 /*----------------------------------------------------------------------------*/
3132 /*!
3133 * \brief This routine is used to get firmware load address from registry
3134 *
3135 * \param prGlueInfo     Pointer of GLUE Data Structure
3136 *
3137 * \retval
3138 */
3139 /*----------------------------------------------------------------------------*/
3140 UINT_32
3141 kalGetFwLoadAddress(
3142     IN P_GLUE_INFO_T    prGlueInfo
3143     )
3144 {
3145     ASSERT(prGlueInfo);
3146
3147     return prGlueInfo->rRegInfo.u4LoadAddress;
3148 }
3149
3150
3151 /*----------------------------------------------------------------------------*/
3152 /*!
3153 * \brief This routine is used to get firmware start address from registry
3154 *
3155 * \param prGlueInfo     Pointer of GLUE Data Structure
3156 *
3157 * \retval
3158 */
3159 /*----------------------------------------------------------------------------*/
3160 UINT_32
3161 kalGetFwStartAddress(
3162     IN P_GLUE_INFO_T    prGlueInfo
3163     )
3164 {
3165     ASSERT(prGlueInfo);
3166
3167     return prGlueInfo->rRegInfo.u4StartAddress;
3168 }
3169
3170 /*----------------------------------------------------------------------------*/
3171 /*!
3172  * * @brief Notify OS with SendComplete event of the specific packet. Linux should
3173  * *        free packets here.
3174  * *
3175  * * @param pvGlueInfo     Pointer of GLUE Data Structure
3176  * * @param pvPacket       Pointer of Packet Handle
3177  * * @param status         Status Code for OS upper layer
3178  * *
3179  * * @return none
3180  * */
3181 /*----------------------------------------------------------------------------*/
3182
3183 /// Todo
3184 VOID
3185 kalSecurityFrameSendComplete (
3186     IN P_GLUE_INFO_T prGlueInfo,
3187     IN PVOID pvPacket,
3188     IN WLAN_STATUS rStatus
3189     )
3190 {
3191     ASSERT(pvPacket);
3192
3193     dev_kfree_skb((struct sk_buff *) pvPacket);
3194     GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum);
3195 }
3196
3197 UINT_32
3198 kalGetTxPendingFrameCount(
3199     IN P_GLUE_INFO_T    prGlueInfo
3200     )
3201 {
3202     ASSERT(prGlueInfo);
3203
3204     return (UINT_32)(prGlueInfo->i4TxPendingFrameNum);
3205 }
3206
3207
3208 /*----------------------------------------------------------------------------*/
3209 /*!
3210 * \brief This routine is used to retrieve the number of pending commands
3211 *        (including MMPDU, 802.1X and command packets)
3212 *
3213 * \param prGlueInfo     Pointer of GLUE Data Structure
3214 *
3215 * \retval
3216 */
3217 /*----------------------------------------------------------------------------*/
3218 UINT_32
3219 kalGetTxPendingCmdCount(
3220     IN P_GLUE_INFO_T    prGlueInfo
3221     )
3222 {
3223     P_QUE_T prCmdQue;
3224
3225     ASSERT(prGlueInfo);
3226     prCmdQue = &prGlueInfo->rCmdQueue;
3227
3228     return prCmdQue->u4NumElem;
3229 }
3230
3231
3232 /*----------------------------------------------------------------------------*/
3233 /*!
3234 * \brief Timer Initialization Procedure
3235 *
3236 * \param[in] prGlueInfo     Pointer to GLUE Data Structure
3237 * \param[in] prTimerHandler Pointer to timer handling function, whose only
3238 *                           argument is "prAdapter"
3239 *
3240 * \retval none
3241 *
3242 */
3243 /*----------------------------------------------------------------------------*/
3244
3245 //static struct timer_list tickfn;
3246
3247 VOID
3248 kalOsTimerInitialize (
3249     IN P_GLUE_INFO_T    prGlueInfo,
3250     IN PVOID            prTimerHandler
3251     )
3252 {
3253
3254     ASSERT(prGlueInfo);
3255
3256     init_timer(&(prGlueInfo->tickfn));
3257     prGlueInfo->tickfn.function = prTimerHandler;
3258     prGlueInfo->tickfn.data = (unsigned long) prGlueInfo;
3259 }
3260
3261 // Todo
3262 /*----------------------------------------------------------------------------*/
3263 /*!
3264 * \brief This routine is called to set the time to do the time out check.
3265 *
3266 * \param[in] prGlueInfo Pointer to GLUE Data Structure
3267 * \param[in] rInterval  Time out interval from current time.
3268 *
3269 * \retval TRUE Success.
3270 */
3271 /*----------------------------------------------------------------------------*/
3272 BOOLEAN
3273 kalSetTimer(
3274     IN P_GLUE_INFO_T    prGlueInfo,
3275     IN UINT_32          u4Interval
3276     )
3277 {
3278     ASSERT(prGlueInfo);
3279     del_timer_sync(&(prGlueInfo->tickfn));
3280
3281     prGlueInfo->tickfn.expires = jiffies + u4Interval * HZ / MSEC_PER_SEC;
3282     add_timer(&(prGlueInfo->tickfn));
3283
3284     return TRUE; /* success */
3285 }
3286 /*----------------------------------------------------------------------------*/
3287 /*!
3288 * \brief This routine is called to cancel
3289 *
3290 * \param[in] prGlueInfo Pointer to GLUE Data Structure
3291 *
3292 * \retval TRUE  :   Timer has been canceled
3293 *         FALAE :   Timer doens't exist
3294 */
3295 /*----------------------------------------------------------------------------*/
3296 BOOLEAN
3297 kalCancelTimer(
3298     IN P_GLUE_INFO_T    prGlueInfo
3299     )
3300 {
3301     ASSERT(prGlueInfo);
3302
3303     clear_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->u4Flag);
3304
3305     if (del_timer_sync(&(prGlueInfo->tickfn)) >=0) {
3306         return TRUE;
3307     } else {
3308         return FALSE;
3309     }
3310 }
3311 /*----------------------------------------------------------------------------*/
3312 /*!
3313 * \brief This routine is a callback function for scanning done
3314 *
3315 * \param[in] prGlueInfo Pointer to GLUE Data Structure
3316 *
3317 * \retval none
3318 *
3319 */
3320 /*----------------------------------------------------------------------------*/
3321 VOID
3322 kalScanDone(
3323     IN P_GLUE_INFO_T                 prGlueInfo,
3324     IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx,
3325     IN WLAN_STATUS                   status
3326     )
3327 {
3328     ASSERT(prGlueInfo);
3329
3330     /* check for system configuration for generating error message on scan list */
3331     //wlanCheckSystemConfiguration(prGlueInfo->prAdapter);
3332
3333     kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0);
3334 }
3335
3336 /*----------------------------------------------------------------------------*/
3337 /*!
3338 * \brief This routine is used to generate a random number
3339 *
3340 * \param none
3341 *
3342 * \retval UINT_32
3343 */
3344 /*----------------------------------------------------------------------------*/
3345 UINT_32
3346 kalRandomNumber(
3347     VOID
3348     )
3349 {
3350     UINT_32 number = 0;
3351
3352     get_random_bytes(&number, 4);
3353
3354     return number;
3355 }
3356
3357 /*----------------------------------------------------------------------------*/
3358 /*!
3359  * \brief command timeout call-back function
3360  *
3361  * \param[in] prGlueInfo Pointer to the GLUE data structure.
3362  *
3363  * \retval (none)
3364  */
3365 /*----------------------------------------------------------------------------*/
3366 VOID
3367 kalTimeoutHandler (unsigned long arg)
3368 {
3369
3370     P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) arg;
3371
3372     ASSERT(prGlueInfo);
3373
3374     /* Notify tx thread  for timeout event */
3375     set_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->u4Flag);
3376     wake_up_interruptible(&prGlueInfo->waitq);
3377
3378     return;
3379 }
3380
3381
3382 VOID
3383 kalSetEvent (P_GLUE_INFO_T pr) {
3384     set_bit(GLUE_FLAG_TXREQ_BIT, &pr->u4Flag);
3385     wake_up_interruptible(&pr->waitq);
3386 }
3387
3388
3389 /*----------------------------------------------------------------------------*/
3390 /*!
3391 * \brief to check if configuration file (NVRAM/Registry) exists
3392 *
3393 * \param[in]
3394 *           prGlueInfo
3395 *
3396 * \return
3397 *           TRUE
3398 *           FALSE
3399 */
3400 /*----------------------------------------------------------------------------*/
3401 BOOLEAN
3402 kalIsConfigurationExist(
3403     IN P_GLUE_INFO_T    prGlueInfo
3404     )
3405 {
3406 #if !defined(CONFIG_X86)
3407     ASSERT(prGlueInfo);
3408
3409     return prGlueInfo->fgNvramAvailable;
3410 #else
3411     /* there is no configuration data for x86-linux */
3412     return FALSE;
3413 #endif
3414 }
3415
3416
3417 /*----------------------------------------------------------------------------*/
3418 /*!
3419 * \brief to retrieve Registry information
3420 *
3421 * \param[in]
3422 *           prGlueInfo
3423 *
3424 * \return
3425 *           Pointer of REG_INFO_T
3426 */
3427 /*----------------------------------------------------------------------------*/
3428 P_REG_INFO_T
3429 kalGetConfiguration(
3430     IN P_GLUE_INFO_T    prGlueInfo
3431     )
3432 {
3433     ASSERT(prGlueInfo);
3434
3435     return &(prGlueInfo->rRegInfo);
3436 }
3437
3438
3439 /*----------------------------------------------------------------------------*/
3440 /*!
3441 * \brief to retrieve version information of corresponding configuration file
3442 *
3443 * \param[in]
3444 *           prGlueInfo
3445 *
3446 * \param[out]
3447 *           pu2Part1CfgOwnVersion
3448 *           pu2Part1CfgPeerVersion
3449 *           pu2Part2CfgOwnVersion
3450 *           pu2Part2CfgPeerVersion
3451 *
3452 * \return
3453 *           NONE
3454 */
3455 /*----------------------------------------------------------------------------*/
3456 VOID
3457 kalGetConfigurationVersion(
3458     IN P_GLUE_INFO_T    prGlueInfo,
3459     OUT PUINT_16        pu2Part1CfgOwnVersion,
3460     OUT PUINT_16        pu2Part1CfgPeerVersion,
3461     OUT PUINT_16        pu2Part2CfgOwnVersion,
3462     OUT PUINT_16        pu2Part2CfgPeerVersion
3463     )
3464 {
3465     ASSERT(prGlueInfo);
3466
3467     ASSERT(pu2Part1CfgOwnVersion);
3468     ASSERT(pu2Part1CfgPeerVersion);
3469     ASSERT(pu2Part2CfgOwnVersion);
3470     ASSERT(pu2Part2CfgPeerVersion);
3471
3472     kalCfgDataRead16(prGlueInfo,
3473             OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part1OwnVersion),
3474             pu2Part1CfgOwnVersion);
3475
3476     kalCfgDataRead16(prGlueInfo,
3477             OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part1PeerVersion),
3478             pu2Part1CfgPeerVersion);
3479
3480     kalCfgDataRead16(prGlueInfo,
3481             OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2OwnVersion),
3482             pu2Part2CfgOwnVersion);
3483
3484     kalCfgDataRead16(prGlueInfo,
3485             OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2PeerVersion),
3486             pu2Part2CfgPeerVersion);
3487
3488     return;
3489 }
3490
3491 /*----------------------------------------------------------------------------*/
3492 /*!
3493 * \brief to check if the WPS is active or not
3494 *
3495 * \param[in]
3496 *           prGlueInfo
3497 *
3498 * \return
3499 *           TRUE
3500 *           FALSE
3501 */
3502 /*----------------------------------------------------------------------------*/
3503 BOOLEAN
3504 kalWSCGetActiveState(
3505     IN P_GLUE_INFO_T    prGlueInfo
3506     )
3507 {
3508     ASSERT(prGlueInfo);
3509
3510     return (prGlueInfo->fgWpsActive);
3511 }
3512
3513
3514 /*----------------------------------------------------------------------------*/
3515 /*!
3516 * \brief update RSSI and LinkQuality to GLUE layer
3517 *
3518 * \param[in]
3519 *           prGlueInfo
3520 *           eNetTypeIdx
3521 *           cRssi
3522 *           cLinkQuality
3523 *
3524 * \return
3525 *           None
3526 */
3527 /*----------------------------------------------------------------------------*/
3528 VOID
3529 kalUpdateRSSI(
3530     IN P_GLUE_INFO_T                    prGlueInfo,
3531     IN ENUM_KAL_NETWORK_TYPE_INDEX_T    eNetTypeIdx,
3532     IN INT_8                            cRssi,
3533     IN INT_8                            cLinkQuality
3534     )
3535 {
3536     struct iw_statistics *pStats = (struct iw_statistics *)NULL;
3537
3538     ASSERT(prGlueInfo);
3539
3540     switch(eNetTypeIdx) {
3541     case KAL_NETWORK_TYPE_AIS_INDEX:
3542         pStats =  (struct iw_statistics *) (&(prGlueInfo->rIwStats));
3543         break;
3544 #if CFG_ENABLE_WIFI_DIRECT
3545 #if CFG_SUPPORT_P2P_RSSI_QUERY
3546     case KAL_NETWORK_TYPE_P2P_INDEX:
3547         pStats =  (struct iw_statistics *) (&(prGlueInfo->rP2pIwStats));
3548         break;
3549 #endif
3550 #endif
3551     default:
3552         break;
3553
3554     }
3555
3556     if (pStats) {
3557         pStats->qual.qual = cLinkQuality;
3558         pStats->qual.noise = 0;
3559         pStats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_NOISE_UPDATED;
3560         pStats->qual.level = 0x100 + cRssi;
3561         pStats->qual.updated |= IW_QUAL_LEVEL_UPDATED;
3562     }
3563
3564
3565     return;
3566 }
3567
3568
3569 /*----------------------------------------------------------------------------*/
3570 /*!
3571 * \brief Pre-allocate I/O buffer
3572 *
3573 * \param[in]
3574 *           none
3575 *
3576 * \return
3577 *           TRUE
3578 *           FALSE
3579 */
3580 /*----------------------------------------------------------------------------*/
3581 BOOLEAN
3582 kalInitIOBuffer(
3583     VOID
3584     )
3585 {
3586     UINT_32 u4Size;
3587
3588     if(CFG_COALESCING_BUFFER_SIZE >= CFG_RX_COALESCING_BUFFER_SIZE) {
3589         u4Size = CFG_COALESCING_BUFFER_SIZE + sizeof(ENHANCE_MODE_DATA_STRUCT_T);
3590     }
3591     else {
3592         u4Size = CFG_RX_COALESCING_BUFFER_SIZE + sizeof(ENHANCE_MODE_DATA_STRUCT_T);
3593     }
3594
3595     pvIoBuffer = kmalloc(u4Size, GFP_KERNEL);
3596     if(pvIoBuffer) {
3597         pvIoBufferSize = u4Size;
3598         pvIoBufferUsage = 0;
3599
3600         return TRUE;
3601     }
3602
3603     return FALSE;
3604 }
3605
3606
3607 /*----------------------------------------------------------------------------*/
3608 /*!
3609 * \brief Free pre-allocated I/O buffer
3610 *
3611 * \param[in]
3612 *           none
3613 *
3614 * \return
3615 *           none
3616 */
3617 /*----------------------------------------------------------------------------*/
3618 VOID
3619 kalUninitIOBuffer(
3620     VOID
3621     )
3622 {
3623     if(pvIoBuffer) {
3624         kfree(pvIoBuffer);
3625
3626         pvIoBuffer = (PVOID) NULL;
3627         pvIoBufferSize = 0;
3628         pvIoBufferUsage = 0;
3629     }
3630
3631     return;
3632 }
3633
3634
3635 /*----------------------------------------------------------------------------*/
3636 /*!
3637 * \brief Dispatch pre-allocated I/O buffer
3638 *
3639 * \param[in]
3640 *           u4AllocSize
3641 *
3642 * \return
3643 *           PVOID for pointer of pre-allocated I/O buffer
3644 */
3645 /*----------------------------------------------------------------------------*/
3646 PVOID
3647 kalAllocateIOBuffer(
3648     IN UINT_32 u4AllocSize
3649     )
3650 {
3651     PVOID ret = (PVOID)NULL;
3652
3653     if(pvIoBuffer) {
3654         if(u4AllocSize <= (pvIoBufferSize - pvIoBufferUsage)) {
3655             ret = (PVOID)&(((PUINT_8)(pvIoBuffer))[pvIoBufferUsage]);
3656             pvIoBufferUsage += u4AllocSize;
3657         }
3658     }
3659     else {
3660         /* fault tolerance */
3661         ret = (PVOID) kalMemAlloc(u4AllocSize, PHY_MEM_TYPE);
3662     }
3663
3664     return ret;
3665 }
3666
3667
3668 /*----------------------------------------------------------------------------*/
3669 /*!
3670 * \brief Release all dispatched I/O buffer
3671 *
3672 * \param[in]
3673 *           none
3674 *
3675 * \return
3676 *           none
3677 */
3678 /*----------------------------------------------------------------------------*/
3679 VOID
3680 kalReleaseIOBuffer(
3681     IN PVOID pvAddr,
3682     IN UINT_32 u4Size
3683     )
3684 {
3685     if(pvIoBuffer) {
3686         pvIoBufferUsage -= u4Size;
3687     }
3688     else {
3689         /* fault tolerance */
3690         kalMemFree(pvAddr, PHY_MEM_TYPE, u4Size);
3691     }
3692 }
3693
3694 /*----------------------------------------------------------------------------*/
3695 /*!
3696 * \brief
3697 *
3698 * \param[in] prAdapter  Pointer of ADAPTER_T
3699 *
3700 * \return none
3701 */
3702 /*----------------------------------------------------------------------------*/
3703 VOID
3704 kalGetChannelList(
3705     IN P_GLUE_INFO_T           prGlueInfo,
3706     IN ENUM_BAND_T             eSpecificBand,
3707     IN UINT_8                  ucMaxChannelNum,
3708     IN PUINT_8                 pucNumOfChannel,
3709     IN P_RF_CHANNEL_INFO_T     paucChannelList
3710     )
3711 {
3712     rlmDomainGetChnlList(prGlueInfo->prAdapter,
3713                               eSpecificBand,
3714                               ucMaxChannelNum,
3715                               pucNumOfChannel,
3716                               paucChannelList);
3717 }
3718
3719
3720 /*----------------------------------------------------------------------------*/
3721 /*!
3722 * \brief
3723 *
3724 * \param[in] prAdapter  Pointer of ADAPTER_T
3725 *
3726 * \return none
3727 */
3728 /*----------------------------------------------------------------------------*/
3729 BOOL
3730 kalIsAPmode(
3731     IN P_GLUE_INFO_T           prGlueInfo
3732     )
3733 {
3734 #if CFG_ENABLE_WIFI_DIRECT
3735     if (IS_NET_ACTIVE(prGlueInfo->prAdapter, NETWORK_TYPE_P2P_INDEX) &&
3736         p2pFuncIsAPMode(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo))
3737         return TRUE;
3738 #endif
3739
3740     return FALSE;
3741 }
3742
3743
3744 #if CFG_SUPPORT_802_11W
3745 /*----------------------------------------------------------------------------*/
3746 /*!
3747 * \brief to check if the MFP is active or not
3748 *
3749 * \param[in]
3750 *           prGlueInfo
3751 *
3752 * \return
3753 *           TRUE
3754 *           FALSE
3755 */
3756 /*----------------------------------------------------------------------------*/
3757 UINT_32
3758 kalGetMfpSetting(
3759     IN P_GLUE_INFO_T    prGlueInfo
3760     )
3761 {
3762     ASSERT(prGlueInfo);
3763
3764     return (prGlueInfo->rWpaInfo.u4Mfp);
3765 }
3766 #endif
3767
3768 struct file*
3769 kalFileOpen(
3770     const char* path,
3771     int flags,
3772     int rights)
3773 {
3774     struct file* filp = NULL;
3775     mm_segment_t oldfs;
3776     int err = 0;
3777
3778     oldfs = get_fs();
3779     set_fs(get_ds());
3780     filp = filp_open(path, flags, rights);
3781     set_fs(oldfs);
3782     if(IS_ERR(filp)) {
3783         err = PTR_ERR(filp);
3784         return NULL;
3785     }
3786     return filp;
3787 }
3788
3789 VOID
3790 kalFileClose(
3791     struct file* file)
3792 {
3793     filp_close(file, NULL);
3794 }
3795
3796 UINT_32
3797 kalFileRead(
3798     struct file* file,
3799     unsigned long long offset,
3800     unsigned char* data,
3801     unsigned int size)
3802 {
3803     mm_segment_t oldfs;
3804     int ret;
3805
3806     oldfs = get_fs();
3807     set_fs(get_ds());
3808
3809     ret = vfs_read(file, data, size, &offset);
3810
3811     set_fs(oldfs);
3812     return ret;
3813 }
3814
3815 UINT_32
3816 kalFileWrite(
3817     struct file* file,
3818     unsigned long long offset,
3819     unsigned char* data,
3820     unsigned int size)
3821 {
3822     mm_segment_t oldfs;
3823     int ret;
3824
3825     oldfs = get_fs();
3826     set_fs(get_ds());
3827
3828     ret = vfs_write(file, data, size, &offset);
3829
3830     set_fs(oldfs);
3831     return ret;
3832 }
3833
3834 UINT_32
3835 kalWriteToFile(
3836     const PUINT_8 pucPath,
3837     BOOLEAN fgDoAppend,
3838     PUINT_8 pucData,
3839     UINT_32 u4Size)
3840 {
3841     struct file* file = NULL;
3842     UINT_32 ret;
3843     UINT_32 u4Flags = 0;
3844
3845     if(fgDoAppend) {
3846         u4Flags = O_APPEND;
3847     }
3848
3849     file = kalFileOpen(pucPath, O_WRONLY | O_CREAT | u4Flags, S_IRWXU);
3850     ret = kalFileWrite(file, 0, pucData, u4Size);
3851     kalFileClose(file);
3852
3853     return ret;
3854 }
3855
3856
3857 /*----------------------------------------------------------------------------*/
3858 /*!
3859 * \brief    To indicate BSS-INFO to NL80211 as scanning result
3860 *
3861 * \param[in]
3862 *           prGlueInfo
3863 *           pucBeaconProbeResp
3864 *           u4FrameLen
3865 *
3866 *
3867 *
3868 * \return
3869 *           none
3870 */
3871 /*----------------------------------------------------------------------------*/
3872 VOID
3873 kalIndicateBssInfo (
3874     IN P_GLUE_INFO_T        prGlueInfo,
3875     IN PUINT_8              pucBeaconProbeResp,
3876     IN UINT_32              u4FrameLen,
3877     IN UINT_8               ucChannelNum,
3878     IN INT_32               i4SignalStrength
3879     )
3880 {
3881     struct wiphy *wiphy;
3882     struct ieee80211_channel *prChannel = NULL;
3883
3884     ASSERT(prGlueInfo);
3885     wiphy = priv_to_wiphy(prGlueInfo);
3886
3887     /* search through channel entries */
3888     if(ucChannelNum <= 14) {
3889         prChannel = ieee80211_get_channel(wiphy, ieee80211_channel_to_frequency(ucChannelNum, IEEE80211_BAND_2GHZ));
3890     }
3891     else {
3892         prChannel = ieee80211_get_channel(wiphy, ieee80211_channel_to_frequency(ucChannelNum, IEEE80211_BAND_5GHZ));
3893     }
3894
3895     if(prChannel != NULL && prGlueInfo->prScanRequest != NULL) {
3896         struct cfg80211_bss *bss;
3897
3898         /* indicate to NL80211 subsystem */
3899         bss = cfg80211_inform_bss_frame(wiphy,
3900                 prChannel,
3901                 (struct ieee80211_mgmt *)pucBeaconProbeResp,
3902                 u4FrameLen,
3903                 i4SignalStrength * 100,
3904                 GFP_KERNEL);
3905
3906         if(!bss) {
3907             DBGLOG(REQ, WARN, ("cfg80211_inform_bss_frame() returned with NULL\n"));
3908         }
3909         else {
3910             cfg80211_put_bss(bss);
3911         }
3912     }
3913
3914     return;
3915 }
3916