06ea9285e8a54558c3b48eaf82f56f116ebe3edd
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / combo_mt66xx / mt6620 / wlan / 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             prGlueInfo->prP2PInfo->rNetDevStats.rx_bytes += prSkb->len;
1504                 prGlueInfo->prP2PInfo->rNetDevStats.rx_packets++;
1505             
1506 #else
1507             prNetDev = prGlueInfo->prDevHandler;
1508 #endif
1509         }
1510         else if (GLUE_GET_PKT_IS_PAL(prSkb)) {
1511             /* BOW */
1512 #if CFG_ENABLE_BT_OVER_WIFI && CFG_BOW_SEPARATE_DATA_PATH
1513             if (prGlueInfo->rBowInfo.fgIsNetRegistered) {
1514             prNetDev = prGlueInfo->rBowInfo.prDevHandler;
1515             }
1516 #else
1517             prNetDev = prGlueInfo->prDevHandler;
1518 #endif
1519         }
1520         else {
1521             /* AIS */
1522             prNetDev = prGlueInfo->prDevHandler;
1523             prGlueInfo->rNetDevStats.rx_bytes += prSkb->len;
1524             prGlueInfo->rNetDevStats.rx_packets++;
1525
1526         }
1527
1528         prNetDev->last_rx = jiffies;
1529         prSkb->protocol = eth_type_trans(prSkb, prNetDev);
1530         prSkb->dev = prNetDev;
1531         //DBGLOG_MEM32(RX, TRACE, (PUINT_32)prSkb->data, prSkb->len);
1532         DBGLOG(RX, EVENT, ("kalRxIndicatePkts len = %d\n", prSkb->len));
1533
1534 #if CFG_BOW_TEST
1535     DBGLOG(BOW, TRACE, ("Rx sk_buff->len: %d\n", prSkb->len));
1536     DBGLOG(BOW, TRACE, ("Rx sk_buff->data_len: %d\n", prSkb->data_len));
1537     DBGLOG(BOW, TRACE, ("Rx sk_buff->data:\n"));
1538
1539         for(i = 0; i < prSkb->len; i++)
1540         {
1541         DBGLOG(BOW, TRACE, ("%4x", prSkb->data[i]));
1542
1543             if((i+1)%16 ==0)
1544             {
1545             DBGLOG(BOW, TRACE, ("\n"));
1546             }
1547         }
1548
1549     DBGLOG(BOW, TRACE, ("\n"));
1550 #endif
1551 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
1552         if(!in_interrupt()){
1553             netif_rx_ni(prSkb); /* only in non-interrupt context */
1554         }
1555         else {
1556             netif_rx(prSkb);
1557         }
1558 #else
1559         netif_rx(prSkb);
1560 #endif
1561
1562         wlanReturnPacket(prGlueInfo->prAdapter, NULL);
1563     }
1564
1565     return WLAN_STATUS_SUCCESS;
1566 }
1567
1568 /*----------------------------------------------------------------------------*/
1569 /*!
1570 * \brief Called by driver to indicate event to upper layer, for example, the wpa
1571 *        supplicant or wireless tools.
1572 *
1573 * \param[in] pvAdapter Pointer to the adapter descriptor.
1574 * \param[in] eStatus Indicated status.
1575 * \param[in] pvBuf Indicated message buffer.
1576 * \param[in] u4BufLen Indicated message buffer size.
1577 *
1578 * \return (none)
1579 *
1580 */
1581 /*----------------------------------------------------------------------------*/
1582 VOID
1583 kalIndicateStatusAndComplete (
1584     IN P_GLUE_INFO_T    prGlueInfo,
1585     IN WLAN_STATUS      eStatus,
1586     IN PVOID            pvBuf,
1587     IN UINT_32          u4BufLen
1588     )
1589 {
1590     UINT_32 bufLen;
1591     P_PARAM_STATUS_INDICATION_T pStatus = (P_PARAM_STATUS_INDICATION_T) pvBuf;
1592     P_PARAM_AUTH_EVENT_T pAuth = (P_PARAM_AUTH_EVENT_T) pStatus;
1593     P_PARAM_PMKID_CANDIDATE_LIST_T pPmkid =
1594         (P_PARAM_PMKID_CANDIDATE_LIST_T) (pStatus + 1);
1595     PARAM_MAC_ADDRESS arBssid;
1596     struct cfg80211_scan_request *prScanRequest = NULL;
1597     PARAM_SSID_T ssid;
1598     struct ieee80211_channel *prChannel = NULL;
1599     struct cfg80211_bss *bss;
1600     UINT_8 ucChannelNum;
1601     P_BSS_DESC_T prBssDesc = NULL;
1602
1603     GLUE_SPIN_LOCK_DECLARATION();
1604
1605     kalMemZero(arBssid, MAC_ADDR_LEN);
1606
1607     ASSERT(prGlueInfo);
1608
1609     switch (eStatus) {
1610     case WLAN_STATUS_ROAM_OUT_FIND_BEST:
1611     case WLAN_STATUS_MEDIA_CONNECT:
1612
1613         prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_CONNECTED;
1614
1615         /* indicate assoc event */
1616         wlanQueryInformation(prGlueInfo->prAdapter,
1617             wlanoidQueryBssid,
1618             &arBssid[0],
1619             sizeof(arBssid),
1620             &bufLen);
1621         wext_indicate_wext_event(prGlueInfo, SIOCGIWAP, arBssid, bufLen);
1622
1623         /* switch netif on */
1624         netif_carrier_on(prGlueInfo->prDevHandler);
1625
1626         do {
1627             /* print message on console */
1628             wlanQueryInformation(prGlueInfo->prAdapter,
1629                 wlanoidQuerySsid,
1630                 &ssid,
1631                 sizeof(ssid),
1632                 &bufLen);
1633
1634             ssid.aucSsid[(ssid.u4SsidLen >= PARAM_MAX_LEN_SSID) ?
1635                 (PARAM_MAX_LEN_SSID - 1) : ssid.u4SsidLen ] = '\0';
1636             DBGLOG(INIT, INFO, ("[wifi] %s netif_carrier_on [ssid:%s " MACSTR "]\n",
1637                 prGlueInfo->prDevHandler->name,
1638                 ssid.aucSsid,
1639                 MAC2STR(arBssid)));
1640         } while(0);
1641
1642         if(prGlueInfo->fgIsRegistered == TRUE) {
1643             /* retrieve channel */
1644             ucChannelNum = wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX);
1645             if(ucChannelNum <= 14) {
1646                 prChannel = ieee80211_get_channel(priv_to_wiphy(prGlueInfo), ieee80211_channel_to_frequency(ucChannelNum, IEEE80211_BAND_2GHZ));
1647             }
1648             else {
1649                 prChannel = ieee80211_get_channel(priv_to_wiphy(prGlueInfo), ieee80211_channel_to_frequency(ucChannelNum, IEEE80211_BAND_5GHZ));
1650             }
1651
1652             /* ensure BSS exists */
1653             bss = cfg80211_get_bss(priv_to_wiphy(prGlueInfo), prChannel, arBssid,
1654                     ssid.aucSsid, ssid.u4SsidLen, 
1655                     WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
1656
1657             if(bss == NULL) {
1658                 /* create BSS on-the-fly */
1659                 prBssDesc = wlanGetTargetBssDescByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX);
1660
1661                 if(prBssDesc != NULL) {
1662                     bss = cfg80211_inform_bss(priv_to_wiphy(prGlueInfo),
1663                         prChannel,
1664                         arBssid,
1665                         0,                                      /* TSF */
1666                         WLAN_CAPABILITY_ESS,
1667                         prBssDesc->u2BeaconInterval,            /* beacon interval */
1668                         prBssDesc->aucIEBuf,                    /* IE */
1669                         prBssDesc->u2IELength,                  /* IE Length */
1670                         RCPI_TO_dBm(prBssDesc->ucRCPI) * 100,   /* MBM */
1671                         GFP_KERNEL);
1672                 }
1673             }
1674
1675             /* CFG80211 Indication */
1676             if(eStatus == WLAN_STATUS_MEDIA_CONNECT 
1677                     && prGlueInfo->prDevHandler->ieee80211_ptr->sme_state == CFG80211_SME_CONNECTING) {
1678                 cfg80211_connect_result(prGlueInfo->prDevHandler,
1679                         arBssid,
1680                         prGlueInfo->aucReqIe,
1681                         prGlueInfo->u4ReqIeLength,
1682                         prGlueInfo->aucRspIe,
1683                         prGlueInfo->u4RspIeLength,
1684                         WLAN_STATUS_SUCCESS,
1685                         GFP_KERNEL);
1686             }
1687             else if(eStatus == WLAN_STATUS_ROAM_OUT_FIND_BEST
1688                     && prGlueInfo->prDevHandler->ieee80211_ptr->sme_state == CFG80211_SME_CONNECTED) {
1689                 #if LINUX_VERSION_CODE > KERNEL_VERSION(3, 3, 0)
1690                 cfg80211_roamed_bss(prGlueInfo->prDevHandler, 
1691                         bss,
1692                         prGlueInfo->aucReqIe,
1693                         prGlueInfo->u4ReqIeLength,
1694                         prGlueInfo->aucRspIe,
1695                         prGlueInfo->u4RspIeLength,
1696                         GFP_KERNEL);
1697                 #else
1698                                 struct ieee80211_channel *prChannel = NULL;
1699                 UINT_8 ucChannelNum = wlanGetChannelNumberByNetwork(prGlueInfo->prAdapter, NETWORK_TYPE_AIS_INDEX);
1700
1701                 if(ucChannelNum <= 14) {
1702                     prChannel = ieee80211_get_channel(priv_to_wiphy(prGlueInfo), ieee80211_channel_to_frequency(ucChannelNum, IEEE80211_BAND_2GHZ));
1703                 }
1704                 else {
1705                     prChannel = ieee80211_get_channel(priv_to_wiphy(prGlueInfo), ieee80211_channel_to_frequency(ucChannelNum, IEEE80211_BAND_5GHZ));
1706                 }
1707
1708                 cfg80211_roamed(prGlueInfo->prDevHandler, 
1709                         prChannel,
1710                         arBssid,
1711                         prGlueInfo->aucReqIe,
1712                         prGlueInfo->u4ReqIeLength,
1713                         prGlueInfo->aucRspIe,
1714                         prGlueInfo->u4RspIeLength,                        
1715                         GFP_KERNEL);
1716                                 #endif
1717                 }
1718         }
1719         break;
1720
1721     case WLAN_STATUS_MEDIA_DISCONNECT:
1722         /* indicate disassoc event */
1723         wext_indicate_wext_event(prGlueInfo, SIOCGIWAP, NULL, 0);
1724         /* For CR 90 and CR99, While supplicant do reassociate, driver will do netif_carrier_off first,
1725            after associated success, at joinComplete(), do netif_carier_on,
1726            but for unknown reason, the supplicant 1x pkt will not called the driver
1727            hardStartXmit, for template workaround these bugs, add this compiling flag
1728         */
1729         /* switch netif off */
1730
1731 #if 1   /* CONSOLE_MESSAGE */
1732          DBGLOG(INIT, INFO, ("[wifi] %s netif_carrier_off\n", prGlueInfo->prDevHandler->name));
1733 #endif
1734
1735         netif_carrier_off(prGlueInfo->prDevHandler);
1736
1737         if(prGlueInfo->fgIsRegistered == TRUE
1738                 && prGlueInfo->prDevHandler->ieee80211_ptr->sme_state == CFG80211_SME_CONNECTED) {
1739             /* CFG80211 Indication */
1740             cfg80211_disconnected(prGlueInfo->prDevHandler, 0, NULL, 0, GFP_KERNEL);
1741         }
1742
1743         prGlueInfo->eParamMediaStateIndicated = PARAM_MEDIA_STATE_DISCONNECTED;
1744
1745         break;
1746
1747     case WLAN_STATUS_SCAN_COMPLETE:
1748         /* indicate scan complete event */
1749         wext_indicate_wext_event(prGlueInfo, SIOCGIWSCAN, NULL, 0);
1750
1751         /* 1. reset first for newly incoming request */
1752         GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
1753         if(prGlueInfo->prScanRequest != NULL) {
1754             prScanRequest = prGlueInfo->prScanRequest;
1755             prGlueInfo->prScanRequest = NULL;
1756         }
1757         GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV);
1758
1759         /* 2. then CFG80211 Indication */
1760         if(prScanRequest != NULL) {
1761             cfg80211_scan_done(prScanRequest, FALSE);
1762         }
1763         break;
1764         case WLAN_STATUS_CONNECT_INDICATION:
1765             /* indicate AIS Jion fail  event */
1766             if(prGlueInfo->prDevHandler->ieee80211_ptr->sme_state == CFG80211_SME_CONNECTING) {
1767             cfg80211_connect_result(prGlueInfo->prDevHandler,
1768                     prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo.prTargetBssDesc->aucBSSID,
1769                     prGlueInfo->aucReqIe,
1770                     prGlueInfo->u4ReqIeLength,
1771                     prGlueInfo->aucRspIe,
1772                     prGlueInfo->u4RspIeLength,
1773                     REASON_CODE_UNSPECIFIED,
1774                     GFP_KERNEL);
1775                 }
1776             break;
1777
1778     #if 0
1779     case WLAN_STATUS_MSDU_OK:
1780         if (netif_running(prGlueInfo->prDevHandler)) {
1781             netif_wake_queue(prGlueInfo->prDevHandler);
1782         }
1783         break;
1784     #endif
1785
1786     case WLAN_STATUS_MEDIA_SPECIFIC_INDICATION:
1787         if (pStatus) {
1788             switch (pStatus->eStatusType) {
1789             case ENUM_STATUS_TYPE_AUTHENTICATION:
1790                 /*
1791                 printk(KERN_NOTICE "ENUM_STATUS_TYPE_AUTHENTICATION: L(%ld) [" MACSTR "] F:%lx\n",
1792                     pAuth->Request[0].Length,
1793                     MAC2STR(pAuth->Request[0].Bssid),
1794                     pAuth->Request[0].Flags);
1795                 */
1796                 /* indicate (UC/GC) MIC ERROR event only */
1797                 if ((pAuth->arRequest[0].u4Flags ==
1798                         PARAM_AUTH_REQUEST_PAIRWISE_ERROR) ||
1799                         (pAuth->arRequest[0].u4Flags ==
1800                         PARAM_AUTH_REQUEST_GROUP_ERROR)) {
1801                     cfg80211_michael_mic_failure(prGlueInfo->prDevHandler, NULL, 
1802                                        (pAuth->arRequest[0].u4Flags == PARAM_AUTH_REQUEST_PAIRWISE_ERROR) ? NL80211_KEYTYPE_PAIRWISE : NL80211_KEYTYPE_GROUP,
1803                                        0, NULL, GFP_KERNEL);
1804                     wext_indicate_wext_event(prGlueInfo,
1805                         IWEVMICHAELMICFAILURE,
1806                         (unsigned char *)&pAuth->arRequest[0],
1807                         pAuth->arRequest[0].u4Length);
1808                 }
1809                 break;
1810
1811             case ENUM_STATUS_TYPE_CANDIDATE_LIST:
1812                 /*
1813                 printk(KERN_NOTICE "Param_StatusType_PMKID_CandidateList: Ver(%ld) Num(%ld)\n",
1814                     pPmkid->u2Version,
1815                     pPmkid->u4NumCandidates);
1816                 if (pPmkid->u4NumCandidates > 0) {
1817                     printk(KERN_NOTICE "candidate[" MACSTR "] preAuth Flag:%lx\n",
1818                         MAC2STR(pPmkid->arCandidateList[0].rBSSID),
1819                         pPmkid->arCandidateList[0].fgFlags);
1820                 }
1821                 */
1822                 {
1823                  UINT_32  i = 0;
1824
1825                  P_PARAM_PMKID_CANDIDATE_T prPmkidCand = (P_PARAM_PMKID_CANDIDATE_T)&pPmkid->arCandidateList[0];
1826
1827                  for (i=0; i<pPmkid->u4NumCandidates; i++) {
1828                     wext_indicate_wext_event(prGlueInfo,
1829                         IWEVPMKIDCAND,
1830                         (unsigned char *)&pPmkid->arCandidateList[i],
1831                         pPmkid->u4NumCandidates);
1832                     prPmkidCand += sizeof(PARAM_PMKID_CANDIDATE_T);
1833                 }
1834                 }
1835                 break;
1836
1837             default:
1838                 /* case ENUM_STATUS_TYPE_MEDIA_STREAM_MODE */
1839                 /*
1840                 printk(KERN_NOTICE "unknown media specific indication type:%x\n",
1841                     pStatus->StatusType);
1842                 */
1843                 break;
1844             }
1845         }
1846         else {
1847             /*
1848             printk(KERN_WARNING "media specific indication buffer NULL\n");
1849             */
1850         }
1851         break;
1852
1853 #if CFG_SUPPORT_BCM && CFG_SUPPORT_BCM_BWCS
1854     case WLAN_STATUS_BWCS_UPDATE:
1855     {
1856         wext_indicate_wext_event(prGlueInfo, IWEVCUSTOM, pvBuf, sizeof(PTA_IPC_T));
1857     }
1858
1859         break;
1860
1861 #endif
1862
1863     default:
1864         /*
1865         printk(KERN_WARNING "unknown indication:%lx\n", eStatus);
1866         */
1867         break;
1868     }
1869 } /* kalIndicateStatusAndComplete */
1870
1871
1872 /*----------------------------------------------------------------------------*/
1873 /*!
1874 * \brief This routine is called to update the (re)association request
1875 *        information to the structure used to query and set
1876 *        OID_802_11_ASSOCIATION_INFORMATION.
1877 *
1878 * \param[in] prGlueInfo Pointer to the Glue structure.
1879 * \param[in] pucFrameBody Pointer to the frame body of the last (Re)Association
1880 *                         Request frame from the AP.
1881 * \param[in] u4FrameBodyLen The length of the frame body of the last
1882 *                           (Re)Association Request frame.
1883 * \param[in] fgReassocRequest TRUE, if it is a Reassociation Request frame.
1884 *
1885 * \return (none)
1886 *
1887 */
1888 /*----------------------------------------------------------------------------*/
1889 VOID
1890 kalUpdateReAssocReqInfo (
1891     IN P_GLUE_INFO_T    prGlueInfo,
1892     IN PUINT_8          pucFrameBody,
1893     IN UINT_32          u4FrameBodyLen,
1894     IN BOOLEAN          fgReassocRequest
1895     )
1896 {
1897     PUINT_8 cp;
1898
1899     ASSERT(prGlueInfo);
1900
1901     /* reset */
1902     prGlueInfo->u4ReqIeLength = 0;
1903
1904     if (fgReassocRequest) {
1905         if (u4FrameBodyLen < 15) {
1906             /*
1907             printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen);
1908             */
1909             return;
1910         }
1911     }
1912     else {
1913         if (u4FrameBodyLen < 9) {
1914             /*
1915             printk(KERN_WARNING "frameBodyLen too short:%ld\n", frameBodyLen);
1916             */
1917             return;
1918         }
1919     }
1920
1921     cp = pucFrameBody;
1922
1923     if (fgReassocRequest) {
1924         /* Capability information field 2 */
1925         /* Listen interval field 2*/
1926         /* Current AP address 6 */
1927         cp += 10;
1928         u4FrameBodyLen -= 10;
1929     }
1930     else {
1931         /* Capability information field 2 */
1932         /* Listen interval field 2*/
1933         cp += 4;
1934         u4FrameBodyLen -= 4;
1935     }
1936
1937     wext_indicate_wext_event(prGlueInfo, IWEVASSOCREQIE, cp, u4FrameBodyLen);
1938
1939     if(u4FrameBodyLen <= CFG_CFG80211_IE_BUF_LEN) {
1940         prGlueInfo->u4ReqIeLength = u4FrameBodyLen;
1941         kalMemCopy(prGlueInfo->aucReqIe, cp, u4FrameBodyLen);
1942     }
1943
1944     return;
1945 }
1946
1947
1948 /*----------------------------------------------------------------------------*/
1949 /*!
1950 * @brief This routine is called to update the (re)association
1951 *        response information to the structure used to reply with 
1952 *        cfg80211_connect_result 
1953 *
1954 * @param prGlueInfo      Pointer to adapter descriptor
1955 * @param pucFrameBody    Pointer to the frame body of the last (Re)Association
1956 *                         Response frame from the AP
1957 * @param u4FrameBodyLen  The length of the frame body of the last
1958 *                          (Re)Association Response frame
1959 *
1960 * @return (none)
1961 */
1962 /*----------------------------------------------------------------------------*/
1963 VOID
1964 kalUpdateReAssocRspInfo (
1965     IN P_GLUE_INFO_T    prGlueInfo,
1966     IN PUINT_8          pucFrameBody,
1967     IN UINT_32          u4FrameBodyLen
1968     )
1969 {
1970     UINT_32 u4IEOffset = 6; /* cap_info, status_code & assoc_id */
1971     UINT_32 u4IELength = u4FrameBodyLen - u4IEOffset;
1972
1973     ASSERT(prGlueInfo);
1974
1975     /* reset */
1976     prGlueInfo->u4RspIeLength = 0;
1977
1978     if(u4IELength <= CFG_CFG80211_IE_BUF_LEN) {
1979         prGlueInfo->u4RspIeLength = u4IELength;
1980         kalMemCopy(prGlueInfo->aucRspIe, pucFrameBody + u4IEOffset, u4IELength);
1981     }
1982
1983 }   /* kalUpdateReAssocRspInfo */
1984
1985
1986 /*----------------------------------------------------------------------------*/
1987 /*!
1988 * \brief Notify OS with SendComplete event of the specific packet. Linux should
1989 *        free packets here.
1990 *
1991 * \param[in] prGlueInfo     Pointer of GLUE Data Structure
1992 * \param[in] pvPacket       Pointer of Packet Handle
1993 * \param[in] status         Status Code for OS upper layer
1994 *
1995 * \return -
1996 */
1997 /*----------------------------------------------------------------------------*/
1998 VOID
1999 kalSendCompleteAndAwakeQueue (
2000     IN P_GLUE_INFO_T prGlueInfo,
2001     IN PVOID pvPacket
2002     )
2003 {
2004
2005     struct net_device   *prDev = NULL;
2006     struct sk_buff      *prSkb = NULL;
2007     UINT_16             u2QueueIdx = 0;
2008     UINT_8              ucNetworkType = 0;
2009     BOOLEAN             fgIsValidDevice = TRUE;
2010
2011
2012     ASSERT(pvPacket);
2013     ASSERT(prGlueInfo->i4TxPendingFrameNum);
2014
2015     prSkb = (struct sk_buff *) pvPacket;
2016 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26)
2017     u2QueueIdx = skb_get_queue_mapping(prSkb);
2018 #endif
2019     ASSERT(u2QueueIdx < CFG_MAX_TXQ_NUM);
2020
2021     if (GLUE_GET_PKT_IS_PAL(prSkb)) {
2022         ucNetworkType = NETWORK_TYPE_BOW_INDEX;
2023     } else if (GLUE_GET_PKT_IS_P2P(prSkb)) {
2024         ucNetworkType = NETWORK_TYPE_P2P_INDEX;
2025
2026 #if CFG_ENABLE_WIFI_DIRECT
2027         /* in case packet was sent after P2P device is unregistered */
2028         if(prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE) {
2029             fgIsValidDevice = FALSE;
2030         }
2031 #endif
2032     } else {
2033         ucNetworkType = NETWORK_TYPE_AIS_INDEX;
2034     }
2035
2036     GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingFrameNum);
2037     GLUE_DEC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[ucNetworkType][u2QueueIdx]);
2038     prDev = prSkb->dev;
2039
2040     ASSERT(prDev);
2041
2042     if(fgIsValidDevice == TRUE) {
2043 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26)
2044         if (netif_subqueue_stopped(prDev, prSkb) &&
2045                 prGlueInfo->ai4TxPendingFrameNumPerQueue[ucNetworkType][u2QueueIdx] <= CFG_TX_START_NETIF_PER_QUEUE_THRESHOLD) {
2046             netif_wake_subqueue(prDev, u2QueueIdx);
2047         }
2048 #else
2049         if (prGlueInfo->i4TxPendingFrameNum < CFG_TX_STOP_NETIF_QUEUE_THRESHOLD) {
2050             netif_wake_queue(prGlueInfo->prDevHandler);
2051         }
2052 #endif
2053     }
2054
2055
2056     dev_kfree_skb((struct sk_buff *) pvPacket);
2057
2058     DBGLOG(TX, EVENT, ("----- pending frame %d -----\n", prGlueInfo->i4TxPendingFrameNum));
2059
2060     return;
2061 }
2062
2063
2064 /*----------------------------------------------------------------------------*/
2065 /*!
2066 * \brief Copy Mac Address setting from registry. It's All Zeros in Linux.
2067 *
2068 * \param[in] prAdapter Pointer to the Adapter structure
2069 *
2070 * \param[out] paucMacAddr Pointer to the Mac Address buffer
2071 *
2072 * \retval WLAN_STATUS_SUCCESS
2073 *
2074 * \note
2075 */
2076 /*----------------------------------------------------------------------------*/
2077 VOID
2078 kalQueryRegistryMacAddr (
2079     IN  P_GLUE_INFO_T   prGlueInfo,
2080     OUT PUINT_8        paucMacAddr
2081     )
2082 {
2083     UINT_8 aucZeroMac[MAC_ADDR_LEN] = {0,0,0,0,0,0}
2084     DEBUGFUNC("kalQueryRegistryMacAddr");
2085
2086     ASSERT(prGlueInfo);
2087     ASSERT(paucMacAddr);
2088
2089     kalMemCopy((PVOID) paucMacAddr, (PVOID)aucZeroMac, MAC_ADDR_LEN);
2090
2091     return;
2092 } /* end of kalQueryRegistryMacAddr() */
2093
2094 #if CFG_SUPPORT_EXT_CONFIG
2095 /*----------------------------------------------------------------------------*/
2096 /*!
2097 * \brief Read external configuration, ex. NVRAM or file
2098 *
2099 * \param[in] prGlueInfo     Pointer of GLUE Data Structure
2100 *
2101 * \return none
2102 */
2103 /*----------------------------------------------------------------------------*/
2104 UINT_32
2105 kalReadExtCfg (
2106     IN P_GLUE_INFO_T prGlueInfo
2107     )
2108 {
2109     ASSERT(prGlueInfo);
2110
2111     /* External data is given from user space by ioctl or /proc, not read by
2112         driver.
2113     */
2114     if (0 != prGlueInfo->u4ExtCfgLength) {
2115         DBGLOG(INIT, TRACE, ("Read external configuration data -- OK\n"));
2116     }
2117     else {
2118         DBGLOG(INIT, TRACE, ("Read external configuration data -- fail\n"));
2119     }
2120
2121     return prGlueInfo->u4ExtCfgLength;
2122 }
2123 #endif
2124
2125 /*----------------------------------------------------------------------------*/
2126 /*!
2127 * @brief This inline function is to extract some packet information, including
2128 *        user priority, packet length, destination address, 802.1x and BT over Wi-Fi
2129 *        or not.
2130 *
2131 * @param prGlueInfo         Pointer to the glue structure
2132 * @param prNdisPacket       Packet descriptor
2133 * @param pucPriorityParam   User priority
2134 * @param pu4PacketLen       Packet length
2135 * @param pucEthDestAddr Destination address
2136 * @param pfgIs1X            802.1x packet or not
2137 * @param pfgIsPAL           BT over Wi-Fi packet or not
2138 *
2139 * @retval TRUE      Success to extract information
2140 * @retval FALSE     Fail to extract correct information
2141 */
2142 /*----------------------------------------------------------------------------*/
2143
2144 BOOL
2145 kalQoSFrameClassifierAndPacketInfo (
2146     IN P_GLUE_INFO_T prGlueInfo,
2147     IN P_NATIVE_PACKET prPacket,
2148     OUT PUINT_8 pucPriorityParam,
2149     OUT PUINT_32 pu4PacketLen,
2150     OUT PUINT_8 pucEthDestAddr,
2151     OUT PBOOLEAN pfgIs1X,
2152     OUT PBOOLEAN pfgIsPAL,
2153     OUT PUINT_8 pucNetworkType
2154     )
2155 {
2156
2157     UINT_32 u4PacketLen;
2158
2159
2160     UINT_8 ucUserPriority = USER_PRIORITY_DEFAULT; /* Default */
2161     UINT_16 u2EtherTypeLen;
2162     struct sk_buff *prSkb = (struct sk_buff *) prPacket;
2163     PUINT_8 aucLookAheadBuf = NULL;
2164
2165     DEBUGFUNC("kalQoSFrameClassifierAndPacketInfo");
2166
2167     u4PacketLen = prSkb->len;
2168
2169     if (u4PacketLen < ETH_HLEN) {
2170         DBGLOG(INIT, WARN, ("Invalid Ether packet length: %d\n", u4PacketLen));
2171         return FALSE;
2172     }
2173
2174     aucLookAheadBuf = prSkb->data;
2175
2176     *pfgIs1X = FALSE;
2177     *pfgIsPAL = FALSE;
2178     //4 <3> Obtain the User Priority for WMM
2179     u2EtherTypeLen = (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET] << 8) | (aucLookAheadBuf[ETH_TYPE_LEN_OFFSET + 1]);
2180
2181     if ((u2EtherTypeLen == ETH_P_IP) &&
2182         (u4PacketLen >= LOOK_AHEAD_LEN)) {
2183         PUINT_8 pucIpHdr = &aucLookAheadBuf[ETH_HLEN];
2184         UINT_8 ucIpVersion;
2185
2186         ucIpVersion = (pucIpHdr[0] & IPVH_VERSION_MASK) >> IPVH_VERSION_OFFSET;
2187         //printk ("ip version %x\n", ucIpVersion);
2188         if (ucIpVersion == IPVERSION) {
2189             UINT_8 ucIpTos;
2190             /* Get the DSCP value from the header of IP packet. */
2191             ucIpTos = pucIpHdr[1];
2192             ucUserPriority = ((ucIpTos & IPTOS_PREC_MASK) >> IPTOS_PREC_OFFSET);
2193         }
2194
2195         /* TODO(Kevin): Add TSPEC classifier here */
2196     }
2197     else if (u2EtherTypeLen == ETH_P_1X) { /* For Port Control */
2198         //DBGLOG(REQ, TRACE, ("Tx 1x\n"));
2199         *pfgIs1X = TRUE;
2200     }
2201     else if (u2EtherTypeLen == ETH_P_PRE_1X) { /* For Pre 1x pkt */
2202         //DBGLOG(REQ, TRACE, ("Tx Pre-1x\n"));
2203         *pfgIs1X = TRUE;
2204     }
2205 #if CFG_SUPPORT_WAPI
2206     else if (u2EtherTypeLen == ETH_WPI_1X) {
2207         *pfgIs1X = TRUE;
2208     }
2209 #endif
2210     else if (u2EtherTypeLen <= 1500) { /* 802.3 Frame */
2211         UINT_8 ucDSAP, ucSSAP, ucControl;
2212         UINT_8 aucOUI[3];
2213
2214         ucDSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET];
2215         ucSSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 1];
2216         ucControl = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 2];
2217
2218         aucOUI[0] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET];
2219         aucOUI[1] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 1];
2220         aucOUI[2] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 2];
2221
2222         if(ucDSAP == ETH_LLC_DSAP_SNAP &&
2223                 ucSSAP == ETH_LLC_SSAP_SNAP &&
2224                 ucControl == ETH_LLC_CONTROL_UNNUMBERED_INFORMATION &&
2225                 aucOUI[0] == ETH_SNAP_BT_SIG_OUI_0 &&
2226                 aucOUI[1] == ETH_SNAP_BT_SIG_OUI_1 &&
2227                 aucOUI[2] == ETH_SNAP_BT_SIG_OUI_2) {
2228
2229             UINT_16 tmp = ((aucLookAheadBuf[ETH_SNAP_OFFSET + 3] << 8) | aucLookAheadBuf[ETH_SNAP_OFFSET + 4]);
2230
2231             *pfgIsPAL = TRUE;
2232             ucUserPriority = (UINT_8)prSkb->priority;
2233
2234             if (tmp == BOW_PROTOCOL_ID_SECURITY_FRAME) {
2235                 *pfgIs1X = TRUE;
2236             }
2237         }
2238     }
2239
2240     //4 <4> Return the value of Priority Parameter.
2241     *pucPriorityParam = ucUserPriority;
2242
2243     //4 <5> Retrieve Packet Information - DA
2244     /* Packet Length/ Destination Address */
2245     *pu4PacketLen = u4PacketLen;
2246
2247     kalMemCopy(pucEthDestAddr, aucLookAheadBuf, PARAM_MAC_ADDR_LEN);
2248
2249
2250     //<6> Network type
2251 #if CFG_ENABLE_BT_OVER_WIFI
2252     if(*pfgIsPAL == TRUE) {
2253         *pucNetworkType = NETWORK_TYPE_BOW_INDEX;
2254     }
2255     else
2256 #endif
2257     {
2258 #if CFG_ENABLE_WIFI_DIRECT
2259         if(prGlueInfo->prAdapter->fgIsP2PRegistered && GLUE_GET_PKT_IS_P2P(prPacket)) {
2260             *pucNetworkType = NETWORK_TYPE_P2P_INDEX;
2261         }
2262         else
2263 #endif
2264         {
2265             *pucNetworkType = NETWORK_TYPE_AIS_INDEX;
2266         }
2267     }
2268     return TRUE;
2269 } /* end of kalQoSFrameClassifier() */
2270
2271 VOID
2272 kalOidComplete (
2273     IN P_GLUE_INFO_T prGlueInfo,
2274     IN BOOLEAN fgSetQuery,
2275     IN UINT_32 u4SetQueryInfoLen,
2276     IN WLAN_STATUS rOidStatus
2277     )
2278 {
2279
2280     ASSERT(prGlueInfo);
2281     /* remove timeout check timer */
2282     wlanoidClearTimeoutCheck(prGlueInfo->prAdapter);
2283
2284     //if (prGlueInfo->u4TimeoutFlag != 1) {
2285     prGlueInfo->rPendStatus = rOidStatus;
2286     complete(&prGlueInfo->rPendComp);
2287     prGlueInfo->u4OidCompleteFlag = 1;
2288     //}
2289     /* else let it timeout on kalIoctl entry */
2290 }
2291
2292 VOID
2293 kalOidClearance(
2294     IN P_GLUE_INFO_T prGlueInfo
2295     )
2296 {
2297     //if (prGlueInfo->u4TimeoutFlag != 1) {
2298      //clear_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->u4Flag);
2299     if (prGlueInfo->u4OidCompleteFlag != 1) {
2300         complete(&prGlueInfo->rPendComp);
2301     }
2302     //}
2303 }
2304
2305
2306 /*----------------------------------------------------------------------------*/
2307 /*!
2308 * @brief This function is used to transfer linux ioctl to OID, and  we
2309 * need to specify the behavior of the OID by ourself
2310 *
2311 * @param prGlueInfo         Pointer to the glue structure
2312 * @param pvInfoBuf          Data buffer
2313 * @param u4InfoBufLen       Data buffer length
2314 * @param fgRead             Is this a read OID
2315 * @param fgWaitResp         does this OID need to wait for values
2316 * @param fgCmd              does this OID compose command packet
2317 * @param pu4QryInfoLen      The data length of the return values
2318 *
2319 * @retval TRUE      Success to extract information
2320 * @retval FALSE     Fail to extract correct information
2321 */
2322 /*----------------------------------------------------------------------------*/
2323
2324 // todo: enqueue the i/o requests for multiple processes access
2325 //
2326 // currently, return -1
2327 //
2328
2329 //static GL_IO_REQ_T OidEntry;
2330
2331 WLAN_STATUS
2332 kalIoctl (IN P_GLUE_INFO_T    prGlueInfo,
2333     IN PFN_OID_HANDLER_FUNC     pfnOidHandler,
2334     IN PVOID                    pvInfoBuf,
2335     IN UINT_32                  u4InfoBufLen,
2336     IN BOOL                     fgRead,
2337     IN BOOL                     fgWaitResp,
2338     IN BOOL                     fgCmd,
2339     IN BOOL                     fgIsP2pOid,
2340     OUT PUINT_32                pu4QryInfoLen
2341     )
2342 {
2343     P_GL_IO_REQ_T prIoReq = NULL;
2344     WLAN_STATUS ret = WLAN_STATUS_SUCCESS;
2345  
2346     
2347     //GLUE_SPIN_LOCK_DECLARATION();
2348     ASSERT(prGlueInfo);
2349
2350
2351
2352     /* <1> Check if driver is halt */
2353
2354     //if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) {
2355     //    return WLAN_STATUS_ADAPTER_NOT_READY;
2356     //}
2357
2358     if (down_interruptible(&g_halt_sem)) {
2359         return WLAN_STATUS_FAILURE;
2360     }
2361
2362
2363     if (g_u4HaltFlag) {
2364         up(&g_halt_sem);
2365         return WLAN_STATUS_ADAPTER_NOT_READY;
2366     }
2367
2368     if(down_interruptible(&prGlueInfo->ioctl_sem)) {
2369         up(&g_halt_sem);
2370         return WLAN_STATUS_FAILURE;
2371     }
2372
2373     /* <2> TODO: thread-safe */
2374
2375     /* <3> point to the OidEntry of Glue layer */
2376
2377     prIoReq = &(prGlueInfo->OidEntry);
2378
2379     ASSERT(prIoReq);
2380
2381     /* <4> Compose the I/O request */
2382     prIoReq->prAdapter = prGlueInfo->prAdapter;
2383     prIoReq->pfnOidHandler = pfnOidHandler;
2384     prIoReq->pvInfoBuf = pvInfoBuf;
2385     prIoReq->u4InfoBufLen = u4InfoBufLen;
2386     prIoReq->pu4QryInfoLen = pu4QryInfoLen;
2387     prIoReq->fgRead = fgRead;
2388     prIoReq->fgWaitResp= fgWaitResp;
2389     prIoReq->rStatus = WLAN_STATUS_FAILURE;
2390 #if CFG_ENABLE_WIFI_DIRECT
2391     prIoReq->fgIsP2pOid = fgIsP2pOid;
2392 #endif
2393
2394     /* <5> Reset the status of pending OID */
2395     prGlueInfo->rPendStatus = WLAN_STATUS_FAILURE;
2396     //prGlueInfo->u4TimeoutFlag = 0;
2397     //prGlueInfo->u4OidCompleteFlag = 0;
2398
2399     /* <6> Check if we use the command queue */
2400     prIoReq->u4Flag = fgCmd;
2401
2402     /* <7> schedule the OID bit */
2403     set_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->u4Flag);
2404
2405     /* <8> Wake up tx thread to handle kick start the I/O request */
2406     wake_up_interruptible(&prGlueInfo->waitq);
2407
2408     /* <9> Block and wait for event or timeout, current the timeout is 5 secs */
2409     //if (wait_for_completion_interruptible_timeout(&prGlueInfo->rPendComp, 5 * KAL_HZ)) {
2410     //if (!wait_for_completion_interruptible(&prGlueInfo->rPendComp)) {
2411     wait_for_completion(&prGlueInfo->rPendComp); {
2412         /* Case 1: No timeout. */
2413         /* if return WLAN_STATUS_PENDING, the status of cmd is stored in prGlueInfo  */
2414         if (prIoReq->rStatus == WLAN_STATUS_PENDING) {
2415             ret = prGlueInfo->rPendStatus;
2416         } else {
2417             ret = prIoReq->rStatus;
2418         }
2419     }
2420     #if 0
2421         else {
2422         /* Case 2: timeout */
2423         /* clear pending OID's cmd in CMD queue */
2424         if (fgCmd) {
2425             prGlueInfo->u4TimeoutFlag = 1;
2426             wlanReleasePendingOid(prGlueInfo->prAdapter, 0);
2427         }
2428         ret = WLAN_STATUS_FAILURE;
2429     }
2430     #endif
2431
2432     up(&prGlueInfo->ioctl_sem);
2433     up(&g_halt_sem);
2434     
2435
2436     
2437     return ret;
2438 }
2439
2440 /*----------------------------------------------------------------------------*/
2441 /*!
2442 * \brief This routine is used to clear all pending security frames
2443 *
2444 * \param prGlueInfo     Pointer of GLUE Data Structure
2445 *
2446 * \retval none
2447 */
2448 /*----------------------------------------------------------------------------*/
2449 VOID
2450 kalClearSecurityFrames(
2451     IN P_GLUE_INFO_T prGlueInfo
2452     )
2453 {
2454     P_QUE_T prCmdQue;
2455     QUE_T rTempCmdQue;
2456     P_QUE_T prTempCmdQue = &rTempCmdQue;
2457     P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T)NULL;
2458
2459     P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T)NULL;
2460     GLUE_SPIN_LOCK_DECLARATION();
2461
2462     ASSERT(prGlueInfo);
2463
2464     // Clear pending security frames in prGlueInfo->rCmdQueue
2465     prCmdQue = &prGlueInfo->rCmdQueue;
2466
2467
2468
2469     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
2470     QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
2471
2472     QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
2473     while (prQueueEntry) {
2474         prCmdInfo = (P_CMD_INFO_T)prQueueEntry;
2475
2476         if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME) {
2477             prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo);
2478             cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo);
2479         }
2480         else {
2481             QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry);
2482         }
2483
2484         QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
2485     }
2486
2487     QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue);
2488     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
2489 }
2490
2491
2492 /*----------------------------------------------------------------------------*/
2493 /*!
2494 * \brief This routine is used to clear pending security frames
2495 *        belongs to dedicated network type
2496 *
2497 * \param prGlueInfo         Pointer of GLUE Data Structure
2498 * \param eNetworkTypeIdx    Network Type Index
2499 *
2500 * \retval none
2501 */
2502 /*----------------------------------------------------------------------------*/
2503 VOID
2504 kalClearSecurityFramesByNetType(
2505     IN P_GLUE_INFO_T prGlueInfo,
2506     IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx
2507     )
2508 {
2509     P_QUE_T prCmdQue;
2510     QUE_T rTempCmdQue;
2511     P_QUE_T prTempCmdQue = &rTempCmdQue;
2512     P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T)NULL;
2513
2514     P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T)NULL;
2515     GLUE_SPIN_LOCK_DECLARATION();
2516
2517
2518     ASSERT(prGlueInfo);
2519
2520     // Clear pending security frames in prGlueInfo->rCmdQueue
2521     prCmdQue = &prGlueInfo->rCmdQueue;
2522
2523     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
2524     QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
2525
2526     QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
2527     while (prQueueEntry) {
2528         prCmdInfo = (P_CMD_INFO_T)prQueueEntry;
2529
2530         if (prCmdInfo->eCmdType == COMMAND_TYPE_SECURITY_FRAME &&
2531                 prCmdInfo->eNetworkType == eNetworkTypeIdx) {
2532             prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo);
2533             cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo);
2534         }
2535         else {
2536             QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry);
2537         }
2538
2539         QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
2540     }
2541
2542     QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue);
2543     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
2544 }
2545
2546
2547 /*----------------------------------------------------------------------------*/
2548 /*!
2549 * \brief This routine is used to clear all pending management frames
2550 *
2551 * \param prGlueInfo     Pointer of GLUE Data Structure
2552 *
2553 * \retval none
2554 */
2555 /*----------------------------------------------------------------------------*/
2556 VOID
2557 kalClearMgmtFrames(
2558     IN P_GLUE_INFO_T prGlueInfo
2559     )
2560 {
2561     P_QUE_T prCmdQue;
2562     QUE_T rTempCmdQue;
2563     P_QUE_T prTempCmdQue = &rTempCmdQue;
2564     P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T)NULL;
2565     P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T)NULL;
2566
2567     GLUE_SPIN_LOCK_DECLARATION();
2568
2569     ASSERT(prGlueInfo);
2570
2571     // Clear pending management frames in prGlueInfo->rCmdQueue
2572     prCmdQue = &prGlueInfo->rCmdQueue;
2573
2574     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
2575     QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
2576
2577     QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
2578     while (prQueueEntry) {
2579         prCmdInfo = (P_CMD_INFO_T)prQueueEntry;
2580
2581         if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME) {
2582             wlanReleaseCommand(prGlueInfo->prAdapter, prCmdInfo);
2583             cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo);
2584         }
2585         else {
2586             QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry);
2587         }
2588
2589         QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
2590     }
2591
2592     QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue);
2593     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
2594 }
2595
2596
2597 /*----------------------------------------------------------------------------*/
2598 /*!
2599 * \brief This routine is used to clear all pending management frames
2600 *           belongs to dedicated network type
2601 * \param prGlueInfo     Pointer of GLUE Data Structure
2602 *
2603 * \retval none
2604 */
2605 /*----------------------------------------------------------------------------*/
2606 VOID
2607 kalClearMgmtFramesByNetType (
2608     IN P_GLUE_INFO_T prGlueInfo,
2609     IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx
2610     )
2611 {
2612     P_QUE_T prCmdQue;
2613     QUE_T rTempCmdQue;
2614     P_QUE_T prTempCmdQue = &rTempCmdQue;
2615     P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T)NULL;
2616     P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T)NULL;
2617
2618     GLUE_SPIN_LOCK_DECLARATION();
2619
2620     ASSERT(prGlueInfo);
2621
2622     // Clear pending management frames in prGlueInfo->rCmdQueue
2623     prCmdQue = &prGlueInfo->rCmdQueue;
2624
2625     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
2626     QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
2627
2628     QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
2629     while (prQueueEntry) {
2630         prCmdInfo = (P_CMD_INFO_T)prQueueEntry;
2631
2632         if (prCmdInfo->eCmdType == COMMAND_TYPE_MANAGEMENT_FRAME &&
2633                 prCmdInfo->eNetworkType == eNetworkTypeIdx) {
2634             wlanReleaseCommand(prGlueInfo->prAdapter, prCmdInfo);
2635             cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo);
2636         }
2637         else {
2638             QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry);
2639         }
2640
2641         QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
2642     }
2643
2644     QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue);
2645     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
2646 } /* kalClearMgmtFramesByNetType */
2647
2648
2649
2650 /*----------------------------------------------------------------------------*/
2651 /*!
2652 * @brief This function is a kernel thread function for handling command packets
2653 * Tx requests and interrupt events
2654 *
2655 * @param data       data pointer to private data of tx_thread
2656 *
2657 * @retval           If the function succeeds, the return value is 0.
2658 * Otherwise, an error code is returned.
2659 *
2660 */
2661 /*----------------------------------------------------------------------------*/
2662
2663 int tx_thread(void *data)
2664 {
2665     struct net_device   *dev = data;
2666     P_GLUE_INFO_T       prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(dev));
2667
2668     P_QUE_ENTRY_T       prQueueEntry = NULL;
2669     P_GL_IO_REQ_T       prIoReq = NULL;
2670     P_QUE_T             prTxQueue = NULL;
2671     P_QUE_T             prCmdQue = NULL;
2672
2673     int                 ret = 0;
2674
2675     BOOLEAN             fgNeedHwAccess = FALSE;
2676
2677     struct sk_buff      *prSkb = NULL;
2678
2679     /* for spin lock acquire and release */
2680     GLUE_SPIN_LOCK_DECLARATION();
2681
2682     prTxQueue = &prGlueInfo->rTxQueue;
2683     prCmdQue = &prGlueInfo->rCmdQueue;
2684
2685     current->flags |= PF_NOFREEZE;
2686
2687     DBGLOG(INIT, STATE, ("tx_thread starts running... \n"));
2688
2689     while (TRUE) {
2690
2691 #if CFG_ENABLE_WIFI_DIRECT
2692         /*run p2p multicast list work. */
2693         if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->u4Flag)) {
2694             p2pSetMulticastListWorkQueueWrapper(prGlueInfo);
2695         }
2696 #endif
2697
2698         if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) {
2699             DBGLOG(INIT, INFO, ("tx_thread should stop now...\n"));
2700             break;
2701         }
2702
2703         /*
2704          * sleep on waitqueue if no events occurred. Event contain (1) GLUE_FLAG_INT
2705          * (2) GLUE_FLAG_OID (3) GLUE_FLAG_TXREQ (4) GLUE_FLAG_HALT
2706          *
2707          */
2708
2709         ret = wait_event_interruptible(prGlueInfo->waitq,
2710                 (prGlueInfo->u4Flag != 0));
2711
2712 #if CFG_DBG_GPIO_PINS
2713         /* TX thread Wake up */
2714         mtk_wcn_stp_debug_gpio_assert(IDX_TX_THREAD, DBG_TIE_LOW);
2715 #endif
2716 #if CFG_ENABLE_WIFI_DIRECT
2717         /*run p2p multicast list work. */
2718         if (test_and_clear_bit(GLUE_FLAG_SUB_MOD_MULTICAST_BIT, &prGlueInfo->u4Flag)) {
2719             p2pSetMulticastListWorkQueueWrapper(prGlueInfo);
2720         }
2721
2722         if (test_and_clear_bit(GLUE_FLAG_FRAME_FILTER_BIT, &prGlueInfo->u4Flag)) {
2723             p2pFuncUpdateMgmtFrameRegister(prGlueInfo->prAdapter, prGlueInfo->prP2PInfo->u4OsMgmtFrameFilter);
2724         }
2725
2726         
2727 #endif
2728         if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) {
2729             DBGLOG(INIT, INFO, ("<1>tx_thread should stop now...\n"));
2730             break;
2731         }
2732
2733         fgNeedHwAccess = FALSE;
2734
2735         /* Handle Interrupt */
2736         if (test_and_clear_bit(GLUE_FLAG_INT_BIT, &prGlueInfo->u4Flag)) {
2737
2738             if (fgNeedHwAccess == FALSE) {
2739                 fgNeedHwAccess = TRUE;
2740
2741                 wlanAcquirePowerControl(prGlueInfo->prAdapter);
2742             }
2743
2744             /* the Wi-Fi interrupt is already disabled in mmc thread,
2745                     so we set the flag only to enable the interrupt later  */
2746             prGlueInfo->prAdapter->fgIsIntEnable = FALSE;
2747             //wlanISR(prGlueInfo->prAdapter, TRUE);
2748
2749             if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) {
2750                 /* Should stop now... skip pending interrupt */
2751                 DBGLOG(INIT, INFO, ("ignore pending interrupt\n"));
2752             }
2753             else {
2754
2755                 wlanIST(prGlueInfo->prAdapter);
2756             }
2757         }
2758
2759         /* transfer ioctl to OID request */
2760         #if 0
2761         if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) {
2762             printk(KERN_INFO DRV_NAME"<2>tx_thread should stop now...\n");
2763             break;
2764         }
2765         #endif
2766
2767         do {
2768             if (test_and_clear_bit(GLUE_FLAG_OID_BIT, &prGlueInfo->u4Flag)) {
2769                 /* get current prIoReq */
2770                 prGlueInfo->u4OidCompleteFlag = 0;
2771                 prIoReq = &(prGlueInfo->OidEntry);
2772 #if CFG_ENABLE_WIFI_DIRECT
2773                 if(prGlueInfo->prAdapter->fgIsP2PRegistered == FALSE
2774                     && prIoReq->fgIsP2pOid == TRUE) {
2775                     /*    if this Oid belongs to p2p and p2p module is removed
2776                                     *      do nothing,
2777                                     */
2778                 }
2779                 else
2780 #endif
2781                 {
2782                     if (FALSE == prIoReq->fgRead) {
2783                         prIoReq->rStatus = wlanSetInformation(
2784                                 prIoReq->prAdapter,
2785                                 prIoReq->pfnOidHandler,
2786                                 prIoReq->pvInfoBuf,
2787                                 prIoReq->u4InfoBufLen,
2788                                 prIoReq->pu4QryInfoLen);
2789                     } else {
2790                         prIoReq->rStatus = wlanQueryInformation(
2791                                 prIoReq->prAdapter,
2792                                 prIoReq->pfnOidHandler,
2793                                 prIoReq->pvInfoBuf,
2794                                 prIoReq->u4InfoBufLen,
2795                                 prIoReq->pu4QryInfoLen);
2796                     }
2797
2798                     if (prIoReq->rStatus != WLAN_STATUS_PENDING) {
2799                         complete(&prGlueInfo->rPendComp);
2800                     }
2801                     else {
2802                         wlanoidTimeoutCheck(prGlueInfo->prAdapter, prIoReq->pfnOidHandler);
2803                     }
2804                 }
2805              }
2806
2807         } while (FALSE);
2808
2809
2810         /*
2811          *
2812          * if TX request, clear the TXREQ flag. TXREQ set by kalSetEvent/GlueSetEvent
2813          * indicates the following requests occur
2814          *
2815          */
2816         #if 0
2817         if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) {
2818             printk(KERN_INFO DRV_NAME"<3>tx_thread should stop now...\n");
2819             break;
2820         }
2821         #endif
2822
2823         if (test_and_clear_bit(GLUE_FLAG_TXREQ_BIT, &prGlueInfo->u4Flag))
2824         {
2825
2826             /* Process Mailbox Messages */
2827             wlanProcessMboxMessage(prGlueInfo->prAdapter);
2828
2829             /* Process CMD request */
2830             do {
2831                 if (prCmdQue->u4NumElem > 0) {
2832                     if (fgNeedHwAccess == FALSE) {
2833                         fgNeedHwAccess = TRUE;
2834
2835                         wlanAcquirePowerControl(prGlueInfo->prAdapter);
2836                     }
2837                     wlanProcessCommandQueue(prGlueInfo->prAdapter, prCmdQue);
2838                 }
2839             } while (FALSE);
2840
2841             /* Handle Packet Tx */
2842             {
2843                 while (QUEUE_IS_NOT_EMPTY(prTxQueue)) {
2844                     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
2845                     QUEUE_REMOVE_HEAD(prTxQueue, prQueueEntry, P_QUE_ENTRY_T);
2846                     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
2847
2848                     ASSERT(prQueueEntry);
2849                     if (NULL == prQueueEntry) {
2850                         break;
2851                     }
2852
2853                     prSkb = (struct sk_buff *) GLUE_GET_PKT_DESCRIPTOR(prQueueEntry);
2854                     ASSERT(prSkb);
2855                     if (NULL == prSkb) {
2856                         DBGLOG(INIT, WARN, ("prSkb == NULL in tx\n"));
2857                         continue;
2858                     }
2859
2860                     if(wlanEnqueueTxPacket(prGlueInfo->prAdapter,
2861                                 (P_NATIVE_PACKET)prSkb) == WLAN_STATUS_RESOURCES) {
2862                         GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
2863                         QUEUE_INSERT_HEAD(prTxQueue, prQueueEntry);
2864                         GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
2865
2866                         break;
2867                     }
2868                 }
2869
2870                 if (wlanGetTxPendingFrameCount(prGlueInfo->prAdapter) > 0) {
2871                     wlanTxPendingPackets(prGlueInfo->prAdapter, &fgNeedHwAccess);
2872                 }
2873             }
2874
2875         }
2876
2877         /* Process RX, In linux, we don't need to free sk_buff by ourself */
2878
2879         /* In linux, we don't need to free sk_buff by ourself */
2880
2881         /* In linux, we don't do reset */
2882         if (fgNeedHwAccess == TRUE) {
2883             wlanReleasePowerControl(prGlueInfo->prAdapter);
2884         }
2885
2886         /* handle cnmTimer time out */
2887         if (test_and_clear_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->u4Flag)) {
2888             wlanTimerTimeoutCheck(prGlueInfo->prAdapter);
2889         }
2890
2891     #if CFG_DBG_GPIO_PINS
2892         /* TX thread go to sleep */
2893         if (!prGlueInfo->u4Flag){
2894             mtk_wcn_stp_debug_gpio_assert(IDX_TX_THREAD, DBG_TIE_HIGH);
2895         }
2896     #endif
2897     }
2898
2899     #if 0
2900     if (fgNeedHwAccess == TRUE) {
2901         wlanReleasePowerControl(prGlueInfo->prAdapter);
2902     }
2903     #endif
2904
2905         nicDisableInterrupt(prGlueInfo->prAdapter);
2906     glBusFreeIrq(dev, *((P_GLUE_INFO_T *) netdev_priv(dev)));
2907
2908     /* flush the pending TX packets */
2909     if (prGlueInfo->i4TxPendingFrameNum > 0) {
2910         kalFlushPendingTxPackets(prGlueInfo);
2911     }
2912
2913     /* flush pending security frames */
2914     if (prGlueInfo->i4TxPendingSecurityFrameNum > 0) {
2915         kalClearSecurityFrames(prGlueInfo);
2916     }
2917
2918     /* remove pending oid */
2919     wlanReleasePendingOid(prGlueInfo->prAdapter, 0);
2920
2921
2922     /* In linux, we don't need to free sk_buff by ourself */
2923
2924     DBGLOG(INIT, INFO, ("mtk_sdiod stops\n"));
2925     complete(&prGlueInfo->rHaltComp);
2926
2927     return 0;
2928
2929 }
2930
2931 /*----------------------------------------------------------------------------*/
2932 /*!
2933 * \brief This routine is used to check if card is removed
2934 *
2935 * \param pvGlueInfo     Pointer of GLUE Data Structure
2936 *
2937 * \retval TRUE:     card is removed
2938 *         FALSE:    card is still attached
2939 */
2940 /*----------------------------------------------------------------------------*/
2941 BOOLEAN
2942 kalIsCardRemoved(
2943     IN P_GLUE_INFO_T    prGlueInfo
2944     )
2945 {
2946     ASSERT(prGlueInfo);
2947
2948     return FALSE;
2949     // Linux MMC doesn't have removal notification yet
2950 }
2951
2952 /*----------------------------------------------------------------------------*/
2953 /*!
2954  * \brief This routine is used to send command to firmware for overriding netweork address
2955  *
2956  * \param pvGlueInfo Pointer of GLUE Data Structure
2957
2958  * \retval TRUE
2959  *         FALSE
2960  */
2961 /*----------------------------------------------------------------------------*/
2962 BOOLEAN
2963 kalRetrieveNetworkAddress(
2964     IN P_GLUE_INFO_T prGlueInfo,
2965     IN OUT PARAM_MAC_ADDRESS * prMacAddr
2966     )
2967 {
2968     ASSERT(prGlueInfo);
2969
2970     if(prGlueInfo->fgIsMacAddrOverride == FALSE) {
2971     #if !defined(CONFIG_X86)
2972         UINT_32 i;
2973         BOOLEAN fgIsReadError = FALSE;
2974
2975         for(i = 0 ; i < MAC_ADDR_LEN ; i+=2) {
2976             if(kalCfgDataRead16(prGlueInfo,
2977                         OFFSET_OF(WIFI_CFG_PARAM_STRUCT, aucMacAddress) + i,
2978                         (PUINT_16) (((PUINT_8)prMacAddr) + i)) == FALSE) {
2979                 fgIsReadError = TRUE;
2980                 break;
2981             }
2982         }
2983
2984         if(fgIsReadError == TRUE) {
2985             return FALSE;
2986         }
2987         else {
2988             return TRUE;
2989         }
2990     #else
2991         /* x86 Linux doesn't need to override network address so far */
2992         return FALSE;
2993     #endif
2994     }
2995     else {
2996         COPY_MAC_ADDR(prMacAddr, prGlueInfo->rMacAddrOverride);
2997
2998         return TRUE;
2999     }
3000 }
3001
3002
3003 /*----------------------------------------------------------------------------*/
3004 /*!
3005 * \brief This routine is used to flush pending TX packets in glue layer
3006 *
3007 * \param pvGlueInfo     Pointer of GLUE Data Structure
3008 *
3009 * \retval none
3010 */
3011 /*----------------------------------------------------------------------------*/
3012 VOID
3013 kalFlushPendingTxPackets(
3014     IN P_GLUE_INFO_T    prGlueInfo
3015     )
3016 {
3017     P_QUE_T prTxQue;
3018     P_QUE_ENTRY_T prQueueEntry;
3019     PVOID prPacket;
3020
3021     GLUE_SPIN_LOCK_DECLARATION();
3022
3023     ASSERT(prGlueInfo);
3024
3025     prTxQue = &(prGlueInfo->rTxQueue);
3026
3027     if (prGlueInfo->i4TxPendingFrameNum) {
3028         while (TRUE) {
3029             GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
3030             QUEUE_REMOVE_HEAD(prTxQue, prQueueEntry, P_QUE_ENTRY_T);
3031             GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE);
3032
3033             if (prQueueEntry == NULL) {
3034                 break;
3035             }
3036
3037             prPacket = GLUE_GET_PKT_DESCRIPTOR(prQueueEntry);
3038
3039             kalSendComplete(prGlueInfo,
3040                     prPacket,
3041                     WLAN_STATUS_NOT_ACCEPTED);
3042         }
3043     }
3044 }
3045
3046 /*----------------------------------------------------------------------------*/
3047 /*!
3048 * \brief This routine is get indicated media state
3049 *
3050 * \param pvGlueInfo     Pointer of GLUE Data Structure
3051 *
3052 * \retval
3053 */
3054 /*----------------------------------------------------------------------------*/
3055 ENUM_PARAM_MEDIA_STATE_T
3056 kalGetMediaStateIndicated(
3057     IN P_GLUE_INFO_T    prGlueInfo
3058     )
3059 {
3060     ASSERT(prGlueInfo);
3061
3062     return prGlueInfo->eParamMediaStateIndicated;
3063 }
3064
3065
3066 /*----------------------------------------------------------------------------*/
3067 /*!
3068 * \brief This routine is used to set indicated media state
3069 *
3070 * \param pvGlueInfo     Pointer of GLUE Data Structure
3071 *
3072 * \retval none
3073 */
3074 /*----------------------------------------------------------------------------*/
3075 VOID
3076 kalSetMediaStateIndicated(
3077     IN P_GLUE_INFO_T            prGlueInfo,
3078     IN ENUM_PARAM_MEDIA_STATE_T eParamMediaStateIndicate
3079     )
3080 {
3081     ASSERT(prGlueInfo);
3082
3083     prGlueInfo->eParamMediaStateIndicated = eParamMediaStateIndicate;
3084 }
3085
3086
3087 /*----------------------------------------------------------------------------*/
3088 /*!
3089 * \brief This routine is used to clear pending OID staying in command queue
3090 *
3091 * \param prGlueInfo     Pointer of GLUE Data Structure
3092 *
3093 * \retval none
3094 */
3095 /*----------------------------------------------------------------------------*/
3096 VOID
3097 kalOidCmdClearance(
3098     IN P_GLUE_INFO_T prGlueInfo
3099     )
3100 {
3101     P_QUE_T prCmdQue;
3102     QUE_T rTempCmdQue;
3103     P_QUE_T prTempCmdQue = &rTempCmdQue;
3104     P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T)NULL;
3105     P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T)NULL;
3106
3107     GLUE_SPIN_LOCK_DECLARATION();
3108
3109     ASSERT(prGlueInfo);
3110
3111     prCmdQue = &prGlueInfo->rCmdQueue;
3112
3113     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
3114     QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
3115
3116     QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
3117     while (prQueueEntry) {
3118
3119         if (((P_CMD_INFO_T)prQueueEntry)->fgIsOid) {
3120             prCmdInfo = (P_CMD_INFO_T)prQueueEntry;
3121             break;
3122         }
3123         else {
3124             QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry);
3125         }
3126
3127         QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
3128     }
3129
3130     QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue);
3131     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
3132
3133     if (prCmdInfo) {
3134         if (prCmdInfo->pfCmdTimeoutHandler) {
3135             prCmdInfo->pfCmdTimeoutHandler(prGlueInfo->prAdapter, prCmdInfo);
3136         }
3137         else {
3138             kalOidComplete(prGlueInfo,
3139                     prCmdInfo->fgSetQuery,
3140                     0,
3141                     WLAN_STATUS_NOT_ACCEPTED);
3142         }
3143
3144         prGlueInfo->u4OidCompleteFlag = 1;
3145         cmdBufFreeCmdInfo(prGlueInfo->prAdapter, prCmdInfo);
3146     }
3147 }
3148
3149
3150 /*----------------------------------------------------------------------------*/
3151 /*!
3152 * \brief This routine is used to insert command into prCmdQueue
3153 *
3154 * \param prGlueInfo     Pointer of GLUE Data Structure
3155 *        prQueueEntry   Pointer of queue entry to be inserted
3156 *
3157 * \retval none
3158 */
3159 /*----------------------------------------------------------------------------*/
3160 VOID
3161 kalEnqueueCommand(
3162     IN P_GLUE_INFO_T prGlueInfo,
3163     IN P_QUE_ENTRY_T prQueueEntry
3164     )
3165 {
3166     P_QUE_T prCmdQue;
3167
3168     GLUE_SPIN_LOCK_DECLARATION();
3169
3170     ASSERT(prGlueInfo);
3171     ASSERT(prQueueEntry);
3172
3173     prCmdQue = &prGlueInfo->rCmdQueue;
3174
3175     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
3176     QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry);
3177     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_CMD_QUE);
3178 }
3179
3180 /*----------------------------------------------------------------------------*/
3181 /*!
3182 * @brief Handle EVENT_ID_ASSOC_INFO event packet by indicating to OS with
3183 *        proper information
3184 *
3185 * @param pvGlueInfo     Pointer of GLUE Data Structure
3186 * @param prAssocInfo    Pointer of EVENT_ID_ASSOC_INFO Packet
3187 *
3188 * @return none
3189 */
3190 /*----------------------------------------------------------------------------*/
3191 VOID
3192 kalHandleAssocInfo(
3193     IN P_GLUE_INFO_T prGlueInfo,
3194     IN P_EVENT_ASSOC_INFO prAssocInfo
3195     )
3196 {
3197     // to do
3198 }
3199
3200 /*----------------------------------------------------------------------------*/
3201 /*!
3202 * \brief This routine is used to get firmware load address from registry
3203 *
3204 * \param prGlueInfo     Pointer of GLUE Data Structure
3205 *
3206 * \retval
3207 */
3208 /*----------------------------------------------------------------------------*/
3209 UINT_32
3210 kalGetFwLoadAddress(
3211     IN P_GLUE_INFO_T    prGlueInfo
3212     )
3213 {
3214     ASSERT(prGlueInfo);
3215
3216     return prGlueInfo->rRegInfo.u4LoadAddress;
3217 }
3218
3219
3220 /*----------------------------------------------------------------------------*/
3221 /*!
3222 * \brief This routine is used to get firmware start address from registry
3223 *
3224 * \param prGlueInfo     Pointer of GLUE Data Structure
3225 *
3226 * \retval
3227 */
3228 /*----------------------------------------------------------------------------*/
3229 UINT_32
3230 kalGetFwStartAddress(
3231     IN P_GLUE_INFO_T    prGlueInfo
3232     )
3233 {
3234     ASSERT(prGlueInfo);
3235
3236     return prGlueInfo->rRegInfo.u4StartAddress;
3237 }
3238
3239 /*----------------------------------------------------------------------------*/
3240 /*!
3241  * * @brief Notify OS with SendComplete event of the specific packet. Linux should
3242  * *        free packets here.
3243  * *
3244  * * @param pvGlueInfo     Pointer of GLUE Data Structure
3245  * * @param pvPacket       Pointer of Packet Handle
3246  * * @param status         Status Code for OS upper layer
3247  * *
3248  * * @return none
3249  * */
3250 /*----------------------------------------------------------------------------*/
3251
3252 /// Todo
3253 VOID
3254 kalSecurityFrameSendComplete (
3255     IN P_GLUE_INFO_T prGlueInfo,
3256     IN PVOID pvPacket,
3257     IN WLAN_STATUS rStatus
3258     )
3259 {
3260     ASSERT(pvPacket);
3261
3262     dev_kfree_skb((struct sk_buff *) pvPacket);
3263     GLUE_DEC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum);
3264 }
3265
3266 UINT_32
3267 kalGetTxPendingFrameCount(
3268     IN P_GLUE_INFO_T    prGlueInfo
3269     )
3270 {
3271     ASSERT(prGlueInfo);
3272
3273     return (UINT_32)(prGlueInfo->i4TxPendingFrameNum);
3274 }
3275
3276
3277 /*----------------------------------------------------------------------------*/
3278 /*!
3279 * \brief This routine is used to retrieve the number of pending commands
3280 *        (including MMPDU, 802.1X and command packets)
3281 *
3282 * \param prGlueInfo     Pointer of GLUE Data Structure
3283 *
3284 * \retval
3285 */
3286 /*----------------------------------------------------------------------------*/
3287 UINT_32
3288 kalGetTxPendingCmdCount(
3289     IN P_GLUE_INFO_T    prGlueInfo
3290     )
3291 {
3292     P_QUE_T prCmdQue;
3293
3294     ASSERT(prGlueInfo);
3295     prCmdQue = &prGlueInfo->rCmdQueue;
3296
3297     return prCmdQue->u4NumElem;
3298 }
3299
3300
3301 /*----------------------------------------------------------------------------*/
3302 /*!
3303 * \brief Timer Initialization Procedure
3304 *
3305 * \param[in] prGlueInfo     Pointer to GLUE Data Structure
3306 * \param[in] prTimerHandler Pointer to timer handling function, whose only
3307 *                           argument is "prAdapter"
3308 *
3309 * \retval none
3310 *
3311 */
3312 /*----------------------------------------------------------------------------*/
3313
3314 //static struct timer_list tickfn;
3315
3316 VOID
3317 kalOsTimerInitialize (
3318     IN P_GLUE_INFO_T    prGlueInfo,
3319     IN PVOID            prTimerHandler
3320     )
3321 {
3322
3323     ASSERT(prGlueInfo);
3324
3325     init_timer(&(prGlueInfo->tickfn));
3326     prGlueInfo->tickfn.function = prTimerHandler;
3327     prGlueInfo->tickfn.data = (unsigned long) prGlueInfo;
3328 }
3329
3330 // Todo
3331 /*----------------------------------------------------------------------------*/
3332 /*!
3333 * \brief This routine is called to set the time to do the time out check.
3334 *
3335 * \param[in] prGlueInfo Pointer to GLUE Data Structure
3336 * \param[in] rInterval  Time out interval from current time.
3337 *
3338 * \retval TRUE Success.
3339 */
3340 /*----------------------------------------------------------------------------*/
3341 BOOLEAN
3342 kalSetTimer(
3343     IN P_GLUE_INFO_T    prGlueInfo,
3344     IN UINT_32          u4Interval
3345     )
3346 {
3347     ASSERT(prGlueInfo);
3348     del_timer_sync(&(prGlueInfo->tickfn));
3349
3350     prGlueInfo->tickfn.expires = jiffies + u4Interval * HZ / MSEC_PER_SEC;
3351     add_timer(&(prGlueInfo->tickfn));
3352
3353     return TRUE; /* success */
3354 }
3355 /*----------------------------------------------------------------------------*/
3356 /*!
3357 * \brief This routine is called to cancel
3358 *
3359 * \param[in] prGlueInfo Pointer to GLUE Data Structure
3360 *
3361 * \retval TRUE  :   Timer has been canceled
3362 *         FALAE :   Timer doens't exist
3363 */
3364 /*----------------------------------------------------------------------------*/
3365 BOOLEAN
3366 kalCancelTimer(
3367     IN P_GLUE_INFO_T    prGlueInfo
3368     )
3369 {
3370     ASSERT(prGlueInfo);
3371
3372     clear_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->u4Flag);
3373
3374     if (del_timer_sync(&(prGlueInfo->tickfn)) >=0) {
3375         return TRUE;
3376     } else {
3377         return FALSE;
3378     }
3379 }
3380 /*----------------------------------------------------------------------------*/
3381 /*!
3382 * \brief This routine is a callback function for scanning done
3383 *
3384 * \param[in] prGlueInfo Pointer to GLUE Data Structure
3385 *
3386 * \retval none
3387 *
3388 */
3389 /*----------------------------------------------------------------------------*/
3390 VOID
3391 kalScanDone(
3392     IN P_GLUE_INFO_T                 prGlueInfo,
3393     IN ENUM_KAL_NETWORK_TYPE_INDEX_T eNetTypeIdx,
3394     IN WLAN_STATUS                   status
3395     )
3396 {
3397     ASSERT(prGlueInfo);
3398
3399     P_AIS_FSM_INFO_T prAisFsmInfo;
3400     prAisFsmInfo = &(prGlueInfo->prAdapter->rWifiVar.rAisFsmInfo);
3401
3402     cnmTimerStopTimer(prGlueInfo->prAdapter, &prAisFsmInfo->rScanDoneTimer);
3403 #if CFG_NVRAM_EXISTENCE_CHECK
3404     /* check for system configuration for generating error message on scan list */
3405     wlanCheckSystemConfiguration(prGlueInfo->prAdapter);
3406 #endif
3407     kalIndicateStatusAndComplete(prGlueInfo, WLAN_STATUS_SCAN_COMPLETE, NULL, 0);
3408 }
3409
3410 /*----------------------------------------------------------------------------*/
3411 /*!
3412 * \brief This routine is used to generate a random number
3413 *
3414 * \param none
3415 *
3416 * \retval UINT_32
3417 */
3418 /*----------------------------------------------------------------------------*/
3419 UINT_32
3420 kalRandomNumber(
3421     VOID
3422     )
3423 {
3424     UINT_32 number = 0;
3425
3426     get_random_bytes(&number, 4);
3427
3428     return number;
3429 }
3430
3431 /*----------------------------------------------------------------------------*/
3432 /*!
3433  * \brief command timeout call-back function
3434  *
3435  * \param[in] prGlueInfo Pointer to the GLUE data structure.
3436  *
3437  * \retval (none)
3438  */
3439 /*----------------------------------------------------------------------------*/
3440 VOID
3441 kalTimeoutHandler (unsigned long arg)
3442 {
3443
3444     P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T) arg;
3445
3446     ASSERT(prGlueInfo);
3447
3448     /* Notify tx thread  for timeout event */
3449     set_bit(GLUE_FLAG_TIMEOUT_BIT, &prGlueInfo->u4Flag);
3450     wake_up_interruptible(&prGlueInfo->waitq);
3451
3452     return;
3453 }
3454
3455
3456 VOID
3457 kalSetEvent (P_GLUE_INFO_T pr) {
3458     set_bit(GLUE_FLAG_TXREQ_BIT, &pr->u4Flag);
3459     wake_up_interruptible(&pr->waitq);
3460 }
3461
3462
3463 /*----------------------------------------------------------------------------*/
3464 /*!
3465 * \brief to check if configuration file (NVRAM/Registry) exists
3466 *
3467 * \param[in]
3468 *           prGlueInfo
3469 *
3470 * \return
3471 *           TRUE
3472 *           FALSE
3473 */
3474 /*----------------------------------------------------------------------------*/
3475 BOOLEAN
3476 kalIsConfigurationExist(
3477     IN P_GLUE_INFO_T    prGlueInfo
3478     )
3479 {
3480 #if !defined(CONFIG_X86)
3481     ASSERT(prGlueInfo);
3482
3483     return prGlueInfo->fgNvramAvailable;
3484 #else
3485     /* there is no configuration data for x86-linux */
3486     return FALSE;
3487 #endif
3488 }
3489
3490
3491 /*----------------------------------------------------------------------------*/
3492 /*!
3493 * \brief to retrieve Registry information
3494 *
3495 * \param[in]
3496 *           prGlueInfo
3497 *
3498 * \return
3499 *           Pointer of REG_INFO_T
3500 */
3501 /*----------------------------------------------------------------------------*/
3502 P_REG_INFO_T
3503 kalGetConfiguration(
3504     IN P_GLUE_INFO_T    prGlueInfo
3505     )
3506 {
3507     ASSERT(prGlueInfo);
3508
3509     return &(prGlueInfo->rRegInfo);
3510 }
3511
3512
3513 /*----------------------------------------------------------------------------*/
3514 /*!
3515 * \brief to retrieve version information of corresponding configuration file
3516 *
3517 * \param[in]
3518 *           prGlueInfo
3519 *
3520 * \param[out]
3521 *           pu2Part1CfgOwnVersion
3522 *           pu2Part1CfgPeerVersion
3523 *           pu2Part2CfgOwnVersion
3524 *           pu2Part2CfgPeerVersion
3525 *
3526 * \return
3527 *           NONE
3528 */
3529 /*----------------------------------------------------------------------------*/
3530 VOID
3531 kalGetConfigurationVersion(
3532     IN P_GLUE_INFO_T    prGlueInfo,
3533     OUT PUINT_16        pu2Part1CfgOwnVersion,
3534     OUT PUINT_16        pu2Part1CfgPeerVersion,
3535     OUT PUINT_16        pu2Part2CfgOwnVersion,
3536     OUT PUINT_16        pu2Part2CfgPeerVersion
3537     )
3538 {
3539     ASSERT(prGlueInfo);
3540
3541     ASSERT(pu2Part1CfgOwnVersion);
3542     ASSERT(pu2Part1CfgPeerVersion);
3543     ASSERT(pu2Part2CfgOwnVersion);
3544     ASSERT(pu2Part2CfgPeerVersion);
3545
3546     kalCfgDataRead16(prGlueInfo,
3547             OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part1OwnVersion),
3548             pu2Part1CfgOwnVersion);
3549
3550     kalCfgDataRead16(prGlueInfo,
3551             OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part1PeerVersion),
3552             pu2Part1CfgPeerVersion);
3553
3554     kalCfgDataRead16(prGlueInfo,
3555             OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2OwnVersion),
3556             pu2Part2CfgOwnVersion);
3557
3558     kalCfgDataRead16(prGlueInfo,
3559             OFFSET_OF(WIFI_CFG_PARAM_STRUCT, u2Part2PeerVersion),
3560             pu2Part2CfgPeerVersion);
3561
3562     return;
3563 }
3564
3565 /*----------------------------------------------------------------------------*/
3566 /*!
3567 * \brief to check if the WPS is active or not
3568 *
3569 * \param[in]
3570 *           prGlueInfo
3571 *
3572 * \return
3573 *           TRUE
3574 *           FALSE
3575 */
3576 /*----------------------------------------------------------------------------*/
3577 BOOLEAN
3578 kalWSCGetActiveState(
3579     IN P_GLUE_INFO_T    prGlueInfo
3580     )
3581 {
3582     ASSERT(prGlueInfo);
3583
3584     return (prGlueInfo->fgWpsActive);
3585 }
3586
3587
3588 /*----------------------------------------------------------------------------*/
3589 /*!
3590 * \brief update RSSI and LinkQuality to GLUE layer
3591 *
3592 * \param[in]
3593 *           prGlueInfo
3594 *           eNetTypeIdx
3595 *           cRssi
3596 *           cLinkQuality
3597 *
3598 * \return
3599 *           None
3600 */
3601 /*----------------------------------------------------------------------------*/
3602 VOID
3603 kalUpdateRSSI(
3604     IN P_GLUE_INFO_T                    prGlueInfo,
3605     IN ENUM_KAL_NETWORK_TYPE_INDEX_T    eNetTypeIdx,
3606     IN INT_8                            cRssi,
3607     IN INT_8                            cLinkQuality
3608     )
3609 {
3610     struct iw_statistics *pStats = (struct iw_statistics *)NULL;
3611
3612     ASSERT(prGlueInfo);
3613
3614     switch(eNetTypeIdx) {
3615     case KAL_NETWORK_TYPE_AIS_INDEX:
3616         pStats =  (struct iw_statistics *) (&(prGlueInfo->rIwStats));
3617         break;
3618 #if CFG_ENABLE_WIFI_DIRECT
3619 #if CFG_SUPPORT_P2P_RSSI_QUERY
3620     case KAL_NETWORK_TYPE_P2P_INDEX:
3621         pStats =  (struct iw_statistics *) (&(prGlueInfo->rP2pIwStats));
3622         break;
3623 #endif
3624 #endif
3625     default:
3626         break;
3627
3628     }
3629
3630     if (pStats) {
3631         pStats->qual.qual = cLinkQuality;
3632         pStats->qual.noise = 0;
3633         pStats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_NOISE_UPDATED;
3634         pStats->qual.level = 0x100 + cRssi;
3635         pStats->qual.updated |= IW_QUAL_LEVEL_UPDATED;
3636     }
3637
3638
3639     return;
3640 }
3641
3642
3643 /*----------------------------------------------------------------------------*/
3644 /*!
3645 * \brief Pre-allocate I/O buffer
3646 *
3647 * \param[in]
3648 *           none
3649 *
3650 * \return
3651 *           TRUE
3652 *           FALSE
3653 */
3654 /*----------------------------------------------------------------------------*/
3655 BOOLEAN
3656 kalInitIOBuffer(
3657     VOID
3658     )
3659 {
3660     UINT_32 u4Size;
3661
3662     if(CFG_COALESCING_BUFFER_SIZE >= CFG_RX_COALESCING_BUFFER_SIZE) {
3663         u4Size = CFG_COALESCING_BUFFER_SIZE + sizeof(ENHANCE_MODE_DATA_STRUCT_T);
3664     }
3665     else {
3666         u4Size = CFG_RX_COALESCING_BUFFER_SIZE + sizeof(ENHANCE_MODE_DATA_STRUCT_T);
3667     }
3668
3669     pvIoBuffer = kmalloc(u4Size, GFP_KERNEL);
3670     if(pvIoBuffer) {
3671         pvIoBufferSize = u4Size;
3672         pvIoBufferUsage = 0;
3673
3674         return TRUE;
3675     }
3676
3677     return FALSE;
3678 }
3679
3680
3681 /*----------------------------------------------------------------------------*/
3682 /*!
3683 * \brief Free pre-allocated I/O buffer
3684 *
3685 * \param[in]
3686 *           none
3687 *
3688 * \return
3689 *           none
3690 */
3691 /*----------------------------------------------------------------------------*/
3692 VOID
3693 kalUninitIOBuffer(
3694     VOID
3695     )
3696 {
3697     if(pvIoBuffer) {
3698         kfree(pvIoBuffer);
3699
3700         pvIoBuffer = (PVOID) NULL;
3701         pvIoBufferSize = 0;
3702         pvIoBufferUsage = 0;
3703     }
3704
3705     return;
3706 }
3707
3708
3709 /*----------------------------------------------------------------------------*/
3710 /*!
3711 * \brief Dispatch pre-allocated I/O buffer
3712 *
3713 * \param[in]
3714 *           u4AllocSize
3715 *
3716 * \return
3717 *           PVOID for pointer of pre-allocated I/O buffer
3718 */
3719 /*----------------------------------------------------------------------------*/
3720 PVOID
3721 kalAllocateIOBuffer(
3722     IN UINT_32 u4AllocSize
3723     )
3724 {
3725     PVOID ret = (PVOID)NULL;
3726
3727     if(pvIoBuffer) {
3728         if(u4AllocSize <= (pvIoBufferSize - pvIoBufferUsage)) {
3729             ret = (PVOID)&(((PUINT_8)(pvIoBuffer))[pvIoBufferUsage]);
3730             pvIoBufferUsage += u4AllocSize;
3731         }
3732     }
3733     else {
3734         /* fault tolerance */
3735         ret = (PVOID) kalMemAlloc(u4AllocSize, PHY_MEM_TYPE);
3736     }
3737
3738     return ret;
3739 }
3740
3741
3742 /*----------------------------------------------------------------------------*/
3743 /*!
3744 * \brief Release all dispatched I/O buffer
3745 *
3746 * \param[in]
3747 *           none
3748 *
3749 * \return
3750 *           none
3751 */
3752 /*----------------------------------------------------------------------------*/
3753 VOID
3754 kalReleaseIOBuffer(
3755     IN PVOID pvAddr,
3756     IN UINT_32 u4Size
3757     )
3758 {
3759     if(pvIoBuffer) {
3760         pvIoBufferUsage -= u4Size;
3761     }
3762     else {
3763         /* fault tolerance */
3764         kalMemFree(pvAddr, PHY_MEM_TYPE, u4Size);
3765     }
3766 }
3767
3768 /*----------------------------------------------------------------------------*/
3769 /*!
3770 * \brief
3771 *
3772 * \param[in] prAdapter  Pointer of ADAPTER_T
3773 *
3774 * \return none
3775 */
3776 /*----------------------------------------------------------------------------*/
3777 VOID
3778 kalGetChannelList(
3779     IN P_GLUE_INFO_T           prGlueInfo,
3780     IN ENUM_BAND_T             eSpecificBand,
3781     IN UINT_8                  ucMaxChannelNum,
3782     IN PUINT_8                 pucNumOfChannel,
3783     IN P_RF_CHANNEL_INFO_T     paucChannelList
3784     )
3785 {
3786     rlmDomainGetChnlList(prGlueInfo->prAdapter,
3787                               eSpecificBand,
3788                               ucMaxChannelNum,
3789                               pucNumOfChannel,
3790                               paucChannelList);
3791 }
3792
3793
3794 /*----------------------------------------------------------------------------*/
3795 /*!
3796 * \brief
3797 *
3798 * \param[in] prAdapter  Pointer of ADAPTER_T
3799 *
3800 * \return none
3801 */
3802 /*----------------------------------------------------------------------------*/
3803 BOOL
3804 kalIsAPmode(
3805     IN P_GLUE_INFO_T           prGlueInfo
3806     )
3807 {
3808 #if CFG_ENABLE_WIFI_DIRECT
3809     if (IS_NET_ACTIVE(prGlueInfo->prAdapter, NETWORK_TYPE_P2P_INDEX) &&
3810         p2pFuncIsAPMode(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo))
3811         return TRUE;
3812 #endif
3813
3814     return FALSE;
3815 }
3816
3817
3818 #if CFG_SUPPORT_802_11W
3819 /*----------------------------------------------------------------------------*/
3820 /*!
3821 * \brief to check if the MFP is active or not
3822 *
3823 * \param[in]
3824 *           prGlueInfo
3825 *
3826 * \return
3827 *           TRUE
3828 *           FALSE
3829 */
3830 /*----------------------------------------------------------------------------*/
3831 UINT_32
3832 kalGetMfpSetting(
3833     IN P_GLUE_INFO_T    prGlueInfo
3834     )
3835 {
3836     ASSERT(prGlueInfo);
3837
3838     return (prGlueInfo->rWpaInfo.u4Mfp);
3839 }
3840 #endif
3841
3842 struct file*
3843 kalFileOpen(
3844     const char* path,
3845     int flags,
3846     int rights)
3847 {
3848     struct file* filp = NULL;
3849     mm_segment_t oldfs;
3850     int err = 0;
3851
3852     oldfs = get_fs();
3853     set_fs(get_ds());
3854     filp = filp_open(path, flags, rights);
3855     set_fs(oldfs);
3856     if(IS_ERR(filp)) {
3857         err = PTR_ERR(filp);
3858         return NULL;
3859     }
3860     return filp;
3861 }
3862
3863 VOID
3864 kalFileClose(
3865     struct file* file)
3866 {
3867     filp_close(file, NULL);
3868 }
3869
3870 UINT_32
3871 kalFileRead(
3872     struct file* file,
3873     unsigned long long offset,
3874     unsigned char* data,
3875     unsigned int size)
3876 {
3877     mm_segment_t oldfs;
3878     int ret;
3879
3880     oldfs = get_fs();
3881     set_fs(get_ds());
3882
3883     ret = vfs_read(file, data, size, &offset);
3884
3885     set_fs(oldfs);
3886     return ret;
3887 }
3888
3889 UINT_32
3890 kalFileWrite(
3891     struct file* file,
3892     unsigned long long offset,
3893     unsigned char* data,
3894     unsigned int size)
3895 {
3896     mm_segment_t oldfs;
3897     int ret;
3898
3899     oldfs = get_fs();
3900     set_fs(get_ds());
3901
3902     ret = vfs_write(file, data, size, &offset);
3903
3904     set_fs(oldfs);
3905     return ret;
3906 }
3907
3908 UINT_32
3909 kalWriteToFile(
3910     const PUINT_8 pucPath,
3911     BOOLEAN fgDoAppend,
3912     PUINT_8 pucData,
3913     UINT_32 u4Size)
3914 {
3915     struct file* file = NULL;
3916     UINT_32 ret;
3917     UINT_32 u4Flags = 0;
3918
3919     if(fgDoAppend) {
3920         u4Flags = O_APPEND;
3921     }
3922
3923     file = kalFileOpen(pucPath, O_WRONLY | O_CREAT | u4Flags, S_IRWXU);
3924     ret = kalFileWrite(file, 0, pucData, u4Size);
3925     kalFileClose(file);
3926
3927     return ret;
3928 }
3929
3930
3931 /*----------------------------------------------------------------------------*/
3932 /*!
3933 * \brief    To indicate BSS-INFO to NL80211 as scanning result
3934 *
3935 * \param[in]
3936 *           prGlueInfo
3937 *           pucBeaconProbeResp
3938 *           u4FrameLen
3939 *
3940 *
3941 *
3942 * \return
3943 *           none
3944 */
3945 /*----------------------------------------------------------------------------*/
3946 VOID
3947 kalIndicateBssInfo (
3948     IN P_GLUE_INFO_T        prGlueInfo,
3949     IN PUINT_8              pucBeaconProbeResp,
3950     IN UINT_32              u4FrameLen,
3951     IN UINT_8               ucChannelNum,
3952     IN INT_32               i4SignalStrength
3953     )
3954 {
3955     struct wiphy *wiphy;
3956     struct ieee80211_channel *prChannel = NULL;
3957
3958     ASSERT(prGlueInfo);
3959     wiphy = priv_to_wiphy(prGlueInfo);
3960
3961     /* search through channel entries */
3962     if(ucChannelNum <= 14) {
3963         prChannel = ieee80211_get_channel(wiphy, ieee80211_channel_to_frequency(ucChannelNum, IEEE80211_BAND_2GHZ));
3964     }
3965     else {
3966         prChannel = ieee80211_get_channel(wiphy, ieee80211_channel_to_frequency(ucChannelNum, IEEE80211_BAND_5GHZ));
3967     }
3968
3969     if(prChannel != NULL && prGlueInfo->prScanRequest != NULL) {
3970         struct cfg80211_bss *bss;
3971
3972         /* indicate to NL80211 subsystem */
3973         bss = cfg80211_inform_bss_frame(wiphy,
3974                 prChannel,
3975                 (struct ieee80211_mgmt *)pucBeaconProbeResp,
3976                 u4FrameLen,
3977                 i4SignalStrength * 100,
3978                 GFP_KERNEL);
3979
3980         if(!bss) {
3981             DBGLOG(REQ, WARN, ("cfg80211_inform_bss_frame() returned with NULL\n"));
3982         }
3983         else {
3984             cfg80211_put_bss(bss);
3985         }
3986     }
3987
3988     return;
3989 }
3990