a4337ef402b1cb58f02812600bf2cab2033117ad
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / combo_mt66xx / mt6620 / wlan / nic / nic.c
1 /*
2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/nic/nic.c#2 $
3 */
4
5 /*! \file   nic.c
6     \brief  Functions that provide operation in NIC's (Network Interface Card) point of view.
7
8     This file includes functions which unite multiple hal(Hardware) operations
9     and also take the responsibility of Software Resource Management in order
10     to keep the synchronization with Hardware Manipulation.
11 */
12
13
14
15 /*
16 ** $Log: nic.c $
17 **
18 ** 07 29 2013 yuche.tsai
19 ** [ALPS00818788] [PreRC1][Mobile HotSpot]DUT should support hidden SSID broadcast for Mobile HotSpot
20 ** Support hidden SSID for MT6630.
21 ** FW Label: 20130729_ALPS_WIFI_FW_MT6620_V1_12
22  *
23  * 07 17 2012 yuche.tsai
24  * NULL
25  * Compile no error before trial run.
26  *
27  * 05 02 2012 terry.wu
28  * NULL
29  * Set the default value of AP StaRec index to "STA_REC_INDEX_NOT_FOUND" in update firmware bss command.
30  *
31  * 03 02 2012 terry.wu
32  * NULL
33  * Sync CFG80211 modification from branch 2,2.
34  *
35  * 11 28 2011 cp.wu
36  * [WCXRP00001125] [MT6620 Wi-Fi][Firmware] Strengthen Wi-Fi power off sequence to have a clearroom environment when returining to ROM code
37  * 1. Due to firmware now stops HIF DMA for powering off, do not try to receive any packet from firmware
38  * 2. Take use of prAdapter->fgIsEnterD3ReqIssued for tracking whether it is powering off or not
39  *
40  * 11 22 2011 tsaiyuan.hsu
41  * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered
42  * keep debug counter setting after wake up.
43  *
44  * 11 19 2011 yuche.tsai
45  * NULL
46  * Update RSSI for P2P.
47  *
48  * 11 18 2011 yuche.tsai
49  * NULL
50  * CONFIG P2P support RSSI query, default turned off.
51  *
52  * 11 07 2011 tsaiyuan.hsu
53  * [WCXRP00001083] [MT6620 Wi-Fi][DRV]] dump debug counter or frames when debugging is triggered
54  * add debug counters and periodically dump counters for debugging.
55  *
56  * 11 04 2011 cp.wu
57  * [WCXRP00001079] [MT5931][Driver] Release pending MMPDU only when BSS is being deactivated
58  * pre-check for NULL before calling MMPDU free function
59  *
60  * 11 03 2011 wh.su
61  * [WCXRP00001078] [MT6620 Wi-Fi][Driver] Adding the mediatek log improment support : XLOG
62  * change the DBGLOG for "\n" and "\r\n". LABEL to LOUD for XLOG
63  *
64  * 11 01 2011 chinglan.wang
65  * NULL
66  * Modify the Wi-Fi method of the flush TX queue when disconnect the AP.
67  * If disconnect the AP and flush all the data frame in the TX queue, WPS cannot do the 4-way handshake to connect to the AP..
68  *
69  * 10 11 2011 terry.wu
70  * NULL
71  * Rewrite Assert Dump Function for Portability.
72  *
73  * 09 20 2011 cm.chang
74  * [WCXRP00000997] [MT6620 Wi-Fi][Driver][FW] Handle change of BSS preamble type and slot time
75  * New CMD definition about RLM parameters
76  *
77  * 08 15 2011 cp.wu
78  * [WCXRP00000851] [MT6628 Wi-Fi][Driver] Add HIFSYS related definition to driver source tree
79  * reuse firmware download logic of MT6620 for MT6628.
80  *
81  * 08 03 2011 terry.wu
82  * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode
83  * Reply Probe Rsp in FW for Hotspot Mode.
84  *
85  *
86  *
87  * 08 03 2011 terry.wu
88  * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode
89  * Reply Probe Rsp in FW for Hotspot Mode.
90  *
91  *
92  * 08 03 2011 terry.wu
93  * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode
94  * Reply Probe Rsp in FW for Hotspot Mode.
95  *
96  * 08 03 2011 terry.wu
97  * [WCXRP00000899] [MT6620] [FW] Reply probe rsp in FW for hotspot mode
98  * Reply Probe Rsp in FW for Hotspot Mode.
99  *
100  * 08 02 2011 yuche.tsai
101  * [WCXRP00000896] [Volunteer Patch][WiFi Direct][Driver] GO with multiple client, TX deauth to a disconnecting device issue.
102  * Fix GO send deauth frame issue.
103  *
104  * 07 18 2011 chinghwa.yu
105  * [WCXRP00000063] Update BCM CoEx design and settings[WCXRP00000612] [MT6620 Wi-Fi] [FW] CSD update SWRDD algorithm
106  * Add CMD/Event for RDD and BWCS.
107  *
108  * 07 11 2011 wh.su
109  * [WCXRP00000849] [MT6620 Wi-Fi][Driver] Remove some of the WAPI define for make sure the value is initialize, for customer not enable WAPI
110  * For make sure wapi initial value is set.
111  *
112  * 06 27 2011 cp.wu
113  * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings to work around some tricky AP which use space character as hidden SSID
114  * 1. correct logic
115  * 2. replace only BSS-DESC which doesn't have a valid SSID.
116  *
117  * 06 27 2011 cp.wu
118  * [WCXRP00000815] [MT6620 Wi-Fi][Driver] allow single BSSID with multiple SSID settings to work around some tricky AP which use space character as hidden SSID
119  * allow to have a single BSSID with multiple SSID to be presented in scanning result
120  *
121  * 05 12 2011 puff.wen
122  * NULL
123  * FW Assert information dump to driver
124  *
125  * 04 18 2011 terry.wu
126  * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
127  * Remove flag CFG_WIFI_DIRECT_MOVED.
128  *
129  * 04 15 2011 cp.wu
130  * [WCXRP00000651] [MT6620 Wi-Fi][Driver] Refine RSSI buffering mechanism
131  * ROLLBACK due to the special design is to workaround incorrect initial RCPI value coming from firmware domain.
132  *
133  * 04 14 2011 cm.chang
134  * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
135  * .
136  *
137  * 04 14 2011 cp.wu
138  * [WCXRP00000598] [MT6620 Wi-Fi][Driver] Implementation of interface for communicating with user space process for RESET_START and RESET_END events
139  * 1. add code to put whole-chip resetting trigger when abnormal firmware assertion is detected
140  * 2. add dummy function for both Win32 and Linux part.
141  *
142  * 04 12 2011 cp.wu
143  * [WCXRP00000635] [MT6620 Wi-Fi][Driver] Clear pending security frames when QM clear pending data frames for dedicated network type
144  * clear pending security frames for dedicated network type when BSS is being deactivated/disconnected
145  *
146  * 04 12 2011 wh.su
147  * NULL
148  * enable the p2p check the cipher to set the bssInfo auth mode.
149  *
150  * 04 12 2011 wh.su
151  * NULL
152  * prepare the code for sync the auth mode and encryption status for P2P and BOW.
153  *
154  * 04 11 2011 yuche.tsai
155  * [WCXRP00000627] [Volunteer Patch][MT6620][Driver] Pending MMPUD of P2P Network may crash system issue.
156  * Fix kernel panic issue when MMPDU of P2P is pending in driver.
157  *
158  * 04 10 2011 george.huang
159  * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode
160  * Fix compiler issue.
161  *
162  * 04 08 2011 george.huang
163  * [WCXRP00000621] [MT6620 Wi-Fi][Driver] Support P2P supplicant to set power mode
164  * separate settings of P2P and AIS
165  *
166  * 04 08 2011 eddie.chen
167  * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
168  * Fix for sigma
169  *
170  * 04 07 2011 cp.wu
171  * [WCXRP00000616] [MT6620 Wi-Fi][Driver] Free memory to pool and kernel in case any unexpected failure happend inside wlanAdapterStart
172  * .
173  *
174  * 04 07 2011 cp.wu
175  * [WCXRP00000616] [MT6620 Wi-Fi][Driver] Free memory to pool and kernel in case any unexpected failure happend inside wlanAdapterStart
176  * implementation of internal error handling of nicAllocateAdapterMemory.
177  *
178  * 03 31 2011 chinglan.wang
179  * [WCXRP00000613] [MT6620 Wi-Fi] [FW] [Driver] BssInfo can get the security mode which is WPA/WPA2/WAPI or not.
180  * .
181  *
182  * 03 21 2011 cp.wu
183  * [WCXRP00000540] [MT5931][Driver] Add eHPI8/eHPI16 support to Linux Glue Layer
184  * portability improvement
185  *
186  * 03 17 2011 cp.wu
187  * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage after system running for a long period
188  * use pre-allocated buffer for storing enhanced interrupt response as well
189  *
190  * 03 16 2011 cp.wu
191  * [WCXRP00000562] [MT6620 Wi-Fi][Driver] I/O buffer pre-allocation to avoid physically continuous memory shortage after system running for a long period
192  * 1. pre-allocate physical continuous buffer while module is being loaded
193  * 2. use pre-allocated physical continuous buffer for TX/RX DMA transfer
194  *
195  * The windows part remained the same as before, but added similiar APIs to hide the difference.
196  *
197  * 03 15 2011 cp.wu
198  * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous memory consumption
199  * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK
200  * 2. Use common coalescing buffer for both TX/RX directions
201  *
202  *
203  * 03 10 2011 cm.chang
204  * [WCXRP00000358] [MT6620 Wi-Fi][Driver] Provide concurrent information for each module
205  * Add some functions to let AIS/Tethering or AIS/BOW be the same channel
206  *
207  * 03 07 2011 terry.wu
208  * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message
209  * Toggle non-standard debug messages to comments.
210  *
211  * 03 02 2011 cp.wu
212  * [WCXRP00000503] [MT6620 Wi-Fi][Driver] Take RCPI brought by association response as initial RSSI right after connection is built.
213  * use RCPI brought by ASSOC-RESP after connection is built as initial RCPI to avoid using a uninitialized MAC-RX RCPI.
214  *
215  * 02 08 2011 terry.wu
216  * [WCXRP00000412] [MT6620 Wi-Fi][FW/Driver] Dump firmware assert info at android kernel log
217  * Use kalPrint to print firmware assert info.
218  *
219  * 02 01 2011 terry.wu
220  * [WCXRP00000412] [MT6620 Wi-Fi][FW/Driver] Dump firmware assert info at android kernel log
221  * .
222  *
223  * 02 01 2011 cm.chang
224  * [WCXRP00000415] [MT6620 Wi-Fi][Driver] Check if any memory leakage happens when uninitializing in DGB mode
225  * .
226  *
227  * 01 31 2011 terry.wu
228  * [WCXRP00000412] [MT6620 Wi-Fi][FW/Driver] Dump firmware assert info at android kernel log
229  * Print firmware ASSERT info at Android kernel log, driver side
230  *
231  * 01 27 2011 tsaiyuan.hsu
232  * [WCXRP00000392] [MT6620 Wi-Fi][Driver] Add Roaming Support
233  * add roaming fsm
234  * 1. not support 11r, only use strength of signal to determine roaming.
235  * 2. not enable CFG_SUPPORT_ROAMING until completion of full test.
236  * 3. in 6620, adopt work-around to avoid sign extension problem of cck of hw
237  * 4. assume that change of link quality in smooth way.
238  *
239  * 01 26 2011 cm.chang
240  * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
241  * Allocate system RAM if fixed message or mgmt buffer is not available
242  *
243  * 01 24 2011 cp.wu
244  * [WCXRP00000382] [MT6620 Wi-Fi][Driver] Track forwarding packet number with notifying tx thread for serving
245  * 1. add an extra counter for tracking pending forward frames.
246  * 2. notify TX service thread as well when there is pending forward frame
247  * 3. correct build errors leaded by introduction of Wi-Fi direct separation module
248  *
249  * 01 19 2011 cp.wu
250  * [WCXRP00000372] [MT6620 Wi-Fi][Driver] Check bus access failure inside nicProcessIST()
251  * check bus error and/or card removal when retrieving interrupt status from HAL
252  *
253  * 01 04 2011 cp.wu
254  * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease physically continous memory demands
255  * 1) correct typo in scan.c
256  * 2) TX descriptors, RX descriptos and management buffer should use virtually continous buffer instead of physically contineous one
257  *
258  * 01 04 2011 cp.wu
259  * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease physically continous memory demands
260  * separate kalMemAlloc() into virtually-continous and physically-continous type to ease slab system pressure
261  *
262  * 12 30 2010 cp.wu
263  * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side
264  * host driver not to set FW-own when there is still pending interrupts
265  *
266  * 12 17 2010 cp.wu
267  * [WCXRP00000270] [MT6620 Wi-Fi][Driver] Clear issues after concurrent networking support has been merged
268  * before BSS disconnection is indicated to firmware, all correlated peer should be cleared and freed
269  *
270  * 12 07 2010 cm.chang
271  * [WCXRP00000239] MT6620 Wi-Fi][Driver][FW] Merge concurrent branch back to maintrunk
272  * 1. BSSINFO include RLM parameter
273  * 2. free all sta records when network is disconnected
274  *
275  * 12 02 2010 eddie.chen
276  * [WCXRP00000218] [MT6620 Wi-Fi][Driver] Add auto rate window control in registry
277  * Add more control value but dont use it now.
278  *
279  * 11 30 2010 eddie.chen
280  * [WCXRP00000218] [MT6620 Wi-Fi][Driver] Add auto rate window control in registry
281  * Add auto rate check window in registry
282  *
283  * 11 10 2010 eddie.chen
284  * [WCXRP00000156] [MT6620][FW] Change Auto rate window to 64 and add throughput swcr
285  * Use autorate parameter 1 as phy rate mask.
286  *
287  * 11 08 2010 cp.wu
288  * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period
289  * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time
290  *
291  * 10 26 2010 eddie.chen
292  * [WCXRP00000134] [MT6620 Wi-Fi][Driver] Add a registry to enable auto rate for SQA test by using E1 EVB
293  * Add auto rate parameter in registry.
294  *
295  * 10 18 2010 cp.wu
296  * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS associated
297  * 1. remove redundant variables in STA_REC structure
298  * 2. add STA-REC uninitialization routine for clearing pending events
299  *
300  * 10 18 2010 cp.wu
301  * [WCXRP00000103] [MT6620 Wi-Fi][Driver] Driver crashed when using WZC to connect to AP#B with connection with AP#A
302  * reset ptrs when IEs are going to be dropped
303  *
304  * 10 12 2010 cp.wu
305  * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test
306  * add HT (802.11n) fixed rate support.
307  *
308  * 10 08 2010 cp.wu
309  * [WCXRP00000084] [MT6620 Wi-Fi][Driver][FW] Add fixed rate support for distance test
310  * adding fixed rate support for distance test. (from registry setting)
311  *
312  * 10 07 2010 cp.wu
313  * [WCXRP00000083] [MT5931][Driver][FW] Add necessary logic for MT5931 first connection
314  * add firmware download for MT5931.
315  *
316  * 10 05 2010 cp.wu
317  * [WCXRP00000056] [MT6620 Wi-Fi][Driver] NVRAM implementation with Version Check
318  * load manufacture data when CFG_SUPPORT_NVRAM is set to 1
319  *
320  * 10 04 2010 cp.wu
321  * [WCXRP00000077] [MT6620 Wi-Fi][Driver][FW] Eliminate use of ENUM_NETWORK_TYPE_T and replaced by ENUM_NETWORK_TYPE_INDEX_T only
322  * remove ENUM_NETWORK_TYPE_T definitions
323  *
324  * 09 21 2010 cp.wu
325  * [WCXRP00000053] [MT6620 Wi-Fi][Driver] Reset incomplete and might leads to BSOD when entering RF test with AIS associated
326  * Do a complete reset with STA-REC null checking for RF test re-entry
327  *
328  * 09 08 2010 cp.wu
329  * NULL
330  * use static memory pool for storing IEs of scanning result.
331  *
332  * 09 06 2010 cp.wu
333  * NULL
334  * Androi/Linux: return current operating channel information
335  *
336  * 09 01 2010 cp.wu
337  * NULL
338  * HIFSYS Clock Source Workaround
339  *
340  * 08 26 2010 yuche.tsai
341  * NULL
342  * Fix someones coding error while enable WIFI_DIRECT.
343  *
344  * 08 25 2010 george.huang
345  * NULL
346  * update OID/ registry control path for PM related settings
347  *
348  * 08 24 2010 cm.chang
349  * NULL
350  * Support RLM initail channel of Ad-hoc, P2P and BOW
351  *
352  * 08 24 2010 chinghwa.yu
353  * NULL
354  * Update BOW for the 1st time.
355  *
356  * 08 23 2010 chinghwa.yu
357  * NULL
358  * Update for BOW.
359  *
360  * 08 20 2010 yuche.tsai
361  * NULL
362  * Add state change indication.
363  *
364  * 08 16 2010 yuche.tsai
365  * NULL
366  * Add support for P2P BSS update info.
367  *
368  * 08 12 2010 cp.wu
369  * NULL
370  * [removing debugging] not to dump beacon content.
371  *
372  * 08 12 2010 cp.wu
373  * NULL
374  * [AIS-FSM] honor registry setting for adhoc running mode. (A/B/G)
375  *
376  * 08 11 2010 cp.wu
377  * NULL
378  * 1) do not use in-stack variable for beacon updating. (for MAUI porting)
379  * 2) extending scanning result to 64 instead of 48
380  *
381  * 08 04 2010 yarco.yang
382  * NULL
383  * Add TX_AMPDU and ADDBA_REJECT command
384  *
385  * 08 03 2010 cp.wu
386  * NULL
387  * surpress compilation warning.
388  *
389  * 08 03 2010 cp.wu
390  * NULL
391  * Centralize mgmt/system service procedures into independent calls.
392  *
393  * 07 28 2010 cp.wu
394  * NULL
395  * 1) eliminate redundant variable eOPMode in prAdapter->rWlanInfo
396  * 2) change nicMediaStateChange() API prototype
397  *
398  * 07 28 2010 cp.wu
399  * NULL
400  * sync. CMD_BSS_INFO structure change to CMD-EVENT v0.15.
401  *
402  * 07 24 2010 wh.su
403  *
404  * .support the Wi-Fi RSN
405  *
406  * 07 23 2010 cp.wu
407  *
408  * FIX: structure of CMD_SET_BSS_INFO has been changed but no follow-ups are done.
409  *
410  * 07 22 2010 george.huang
411  *
412  * .
413  *
414  * 07 22 2010 george.huang
415  *
416  * Update fgIsQoS information in BSS INFO by CMD
417  *
418  * 07 19 2010 cp.wu
419  *
420  * [WPD00003833] [MT6620 and MT5931] Driver migration.
421  * Add Ad-Hoc support to AIS-FSM
422  *
423  * 07 14 2010 yarco.yang
424  *
425  * 1. Remove CFG_MQM_MIGRATION
426  * 2. Add CMD_UPDATE_WMM_PARMS command
427  *
428  * 07 08 2010 cp.wu
429  *
430  * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
431  *
432  * 07 07 2010 cp.wu
433  * [WPD00003833][MT6620 and MT5931] Driver migration
434  * update prStaRecOfAP with BSS-INFO.
435  *
436  * 07 06 2010 george.huang
437  * [WPD00001556]Basic power managemenet function
438  * Update arguments for nicUpdateBeaconIETemplate()
439  *
440  * 07 06 2010 cp.wu
441  * [WPD00003833][MT6620 and MT5931] Driver migration
442  * STA-REC is maintained by CNM only.
443  *
444  * 07 05 2010 cp.wu
445  * [WPD00003833][MT6620 and MT5931] Driver migration
446  * 1) ignore RSN checking when RSN is not turned on.
447  * 2) set STA-REC deactivation callback as NULL
448  * 3) add variable initialization API based on PHY configuration
449  *
450  * 07 01 2010 cm.chang
451  * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
452  * Support sync command of STA_REC
453  *
454  * 06 30 2010 cp.wu
455  * [WPD00003833][MT6620 and MT5931] Driver migration
456  * sync. with CMD/EVENT document ver0.07.
457  *
458  * 06 29 2010 cp.wu
459  * [WPD00003833][MT6620 and MT5931] Driver migration
460  * correct variable naming for 8-bit variable used in CMD_BEACON_TEMPLATE_UPDATE.
461  *
462  * 06 29 2010 cp.wu
463  * [WPD00003833][MT6620 and MT5931] Driver migration
464  * 1) sync to. CMD/EVENT document v0.03
465  * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again.
466  * 3) send command packet to indicate FW-PM after
467  *     a) 1st beacon is received after AIS has connected to an AP
468  *     b) IBSS-ALONE has been created
469  *     c) IBSS-MERGE has occured
470  *
471  * 06 25 2010 george.huang
472  * [WPD00001556]Basic power managemenet function
473  * Create beacon update path, with expose bssUpdateBeaconContent()
474  *
475  * 06 22 2010 cp.wu
476  * [WPD00003833][MT6620 and MT5931] Driver migration
477  * fill fgIsUapsdConnection when indicating BSS-CREATE with AIS-STA mode.
478  *
479  * 06 22 2010 cp.wu
480  * [WPD00003833][MT6620 and MT5931] Driver migration
481  * 1) add command warpper for STA-REC/BSS-INFO sync.
482  * 2) enhance command packet sending procedure for non-oid part
483  * 3) add command packet definitions for STA-REC/BSS-INFO sync.
484  *
485  * 06 21 2010 cp.wu
486  * [WPD00003833][MT6620 and MT5931] Driver migration
487  * implement TX_DONE callback path.
488  *
489  * 06 21 2010 wh.su
490  * [WPD00003840][MT6620 5931] Security migration
491  * remove duplicate variable for migration.
492  *
493  * 06 21 2010 cp.wu
494  * [WPD00003833][MT6620 and MT5931] Driver migration
495  * TX descriptors are now allocated once for reducing allocation overhead
496  *
497  * 06 18 2010 cm.chang
498  * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
499  * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
500  *
501  * 06 11 2010 cp.wu
502  * [WPD00003833][MT6620 and MT5931] Driver migration
503  * 1) migrate assoc.c.
504  * 2) add ucTxSeqNum for tracking frames which needs TX-DONE awareness
505  * 3) add configuration options for CNM_MEM and RSN modules
506  * 4) add data path for management frames
507  * 5) eliminate rPacketInfo of MSDU_INFO_T
508  *
509  * 06 10 2010 cp.wu
510  * [WPD00003833][MT6620 and MT5931] Driver migration
511  * 1) eliminate CFG_CMD_EVENT_VERSION_0_9
512  * 2) when disconnected, indicate nic directly (no event is needed)
513  *
514  * 06 06 2010 kevin.huang
515  * [WPD00003832][MT6620 5931] Create driver base
516  * [MT6620 5931] Create driver base
517  *
518  * 04 26 2010 cp.wu
519  * [WPD00001943]Create WiFi test driver framework on WinXP
520  * 1) surpress compiler warning
521  * 2) when acqruing LP-own, keep writing WHLPCR whenever OWN is not acquired yet
522  *
523  * 04 23 2010 cp.wu
524  * [WPD00001943]Create WiFi test driver framework on WinXP
525  * surpress compiler warning
526  *
527  * 04 13 2010 cp.wu
528  * [WPD00003823][MT6620 Wi-Fi] Add Bluetooth-over-Wi-Fi support
529  * add framework for BT-over-Wi-Fi support.
530  *  *  *  *  *  *  *  *  *  *  *  *  * 1) prPendingCmdInfo is replaced by queue for multiple handler capability
531  *  *  *  *  *  *  *  *  *  *  *  *  * 2) command sequence number is now increased atomically
532  *  *  *  *  *  *  *  *  *  *  *  *  * 3) private data could be hold and taken use for other purpose
533  *
534  * 04 12 2010 cp.wu
535  * [WPD00001943]Create WiFi test driver framework on WinXP
536  * add channel frequency <-> number conversion
537  *
538  * 04 06 2010 cp.wu
539  * [WPD00001943]Create WiFi test driver framework on WinXP
540  * eliminate direct access for prGlueInfo->fgIsCardRemoved in non-glue layer
541  *
542  * 04 06 2010 cp.wu
543  * [WPD00003827][MT6620 Wi-Fi] Chariot fail and following ping fail, no pkt send from driver
544  * correct nicProcessIST_impl() for interrupt status brought up by RX enhanced response
545  *
546  * 03 19 2010 cp.wu
547  * [WPD00001943]Create WiFi test driver framework on WinXP
548  * 1) add ACPI D0/D3 state switching support
549  *  *  *  *  *  *  * 2) use more formal way to handle interrupt when the status is retrieved from enhanced RX response
550  *
551  * 03 17 2010 cp.wu
552  * [WPD00001943]Create WiFi test driver framework on WinXP
553  * always process TX interrupt first then RX interrupt.
554  *
555  * 02 25 2010 cp.wu
556  * [WPD00001943]Create WiFi test driver framework on WinXP
557  * correct behavior to prevent duplicated RX handling for RX0_DONE and RX1_DONE
558  *
559  * 02 23 2010 cp.wu
560  * [WPD00001943]Create WiFi test driver framework on WinXP
561  * add checksum offloading support.
562 **  \main\maintrunk.MT6620WiFiDriver_Prj\27 2009-12-16 18:03:43 GMT mtk02752
563 **  handling enhanced response which fields are fetched at different moments
564 **  \main\maintrunk.MT6620WiFiDriver_Prj\26 2009-12-15 17:00:29 GMT mtk02752
565 **  if RX enhanced response is used, D2H interrupt status should be coming from buffered result as well
566 **  \main\maintrunk.MT6620WiFiDriver_Prj\25 2009-12-15 12:01:55 GMT mtk02752
567 **  if TX_DONE bit is not set but WTSR0/WTSR1 is non-zero, then set TX_DONE bit due to time latency of interrupt status enhanced response
568 **  \main\maintrunk.MT6620WiFiDriver_Prj\24 2009-12-10 16:52:52 GMT mtk02752
569 **  code clean
570 **  \main\maintrunk.MT6620WiFiDriver_Prj\23 2009-11-24 20:51:01 GMT mtk02752
571 **  integrate with SD1 by invoking qmHandleMailboxRxMessage()
572 **  \main\maintrunk.MT6620WiFiDriver_Prj\22 2009-11-16 17:32:33 GMT mtk02752
573 **  prepare code for invoking rxHandleMailboxRxMessage()
574 **  \main\maintrunk.MT6620WiFiDriver_Prj\21 2009-11-11 10:36:08 GMT mtk01084
575 **  \main\maintrunk.MT6620WiFiDriver_Prj\20 2009-11-09 22:56:41 GMT mtk01084
576 **  modify HW access routines
577 **  \main\maintrunk.MT6620WiFiDriver_Prj\19 2009-10-30 18:17:20 GMT mtk01084
578 **  prevent warning
579 **  \main\maintrunk.MT6620WiFiDriver_Prj\18 2009-10-29 19:54:57 GMT mtk01084
580 **  init HIF
581 **  \main\maintrunk.MT6620WiFiDriver_Prj\17 2009-10-23 16:08:30 GMT mtk01084
582 **  \main\maintrunk.MT6620WiFiDriver_Prj\16 2009-10-13 21:59:12 GMT mtk01084
583 **  update for new HW design
584 **  \main\maintrunk.MT6620WiFiDriver_Prj\15 2009-09-09 17:26:15 GMT mtk01084
585 **  modify for CFG_TEST_WITH_MT5921
586 **  \main\maintrunk.MT6620WiFiDriver_Prj\14 2009-05-19 10:55:22 GMT mtk01461
587 **  Unmask the unused HISR
588 **  \main\maintrunk.MT6620WiFiDriver_Prj\13 2009-05-18 15:59:13 GMT mtk01084
589 **  remove debug purpose code
590 **  \main\maintrunk.MT6620WiFiDriver_Prj\12 2009-05-18 14:05:02 GMT mtk01084
591 **  update for WIFI ownback part on initial
592 **  \main\maintrunk.MT6620WiFiDriver_Prj\11 2009-05-04 21:32:57 GMT mtk01084
593 **  add temporarily code to set driver own on adapter initialization
594 **  \main\maintrunk.MT6620WiFiDriver_Prj\10 2009-04-28 10:35:41 GMT mtk01461
595 **  Add init of TX aggregation and fix RX STATUS is DW align for SDIO_STATUS_ENHANCE mode
596 **  \main\maintrunk.MT6620WiFiDriver_Prj\9 2009-04-24 21:12:10 GMT mtk01104
597 **  Add function nicRestoreSpiDefMode()
598 **  \main\maintrunk.MT6620WiFiDriver_Prj\8 2009-04-21 09:43:31 GMT mtk01461
599 **  Revise for MTK coding style - nicInitializeAdapter()
600 **  \main\maintrunk.MT6620WiFiDriver_Prj\7 2009-04-17 19:52:47 GMT mtk01461
601 **  Update allocate Adapter Memory for MGMT Memory pool
602 **  \main\maintrunk.MT6620WiFiDriver_Prj\6 2009-04-01 10:57:08 GMT mtk01461
603 **  Refine the order of release memory from pucRxCoalescingBufCached
604 **  \main\maintrunk.MT6620WiFiDriver_Prj\5 2009-03-19 18:32:57 GMT mtk01084
605 **  update for basic power management functions
606 **  \main\maintrunk.MT6620WiFiDriver_Prj\4 2009-03-18 21:00:14 GMT mtk01426
607 **  Add CFG_SDIO_RX_ENHANCE support
608 **  \main\maintrunk.MT6620WiFiDriver_Prj\3 2009-03-16 09:10:27 GMT mtk01461
609 **  Update TX PATH API
610 **  \main\maintrunk.MT6620WiFiDriver_Prj\2 2009-03-10 20:25:59 GMT mtk01426
611 **  Init for develop
612 **
613 */
614
615 /*******************************************************************************
616 *                         C O M P I L E R   F L A G S
617 ********************************************************************************
618 */
619
620 /*******************************************************************************
621 *                    E X T E R N A L   R E F E R E N C E S
622 ********************************************************************************
623 */
624 #include "precomp.h"
625
626
627 /*******************************************************************************
628 *                              C O N S T A N T S
629 ********************************************************************************
630 */
631 const UINT_8 aucPhyCfg2PhyTypeSet[PHY_CONFIG_NUM] =
632 {
633     PHY_TYPE_SET_802_11ABG,         /* PHY_CONFIG_802_11ABG */
634     PHY_TYPE_SET_802_11BG,          /* PHY_CONFIG_802_11BG */
635     PHY_TYPE_SET_802_11G,           /* PHY_CONFIG_802_11G */
636     PHY_TYPE_SET_802_11A,           /* PHY_CONFIG_802_11A */
637     PHY_TYPE_SET_802_11B,           /* PHY_CONFIG_802_11B */
638     PHY_TYPE_SET_802_11ABGN,        /* PHY_CONFIG_802_11ABGN */
639     PHY_TYPE_SET_802_11BGN,         /* PHY_CONFIG_802_11BGN */
640     PHY_TYPE_SET_802_11AN,          /* PHY_CONFIG_802_11AN */
641     PHY_TYPE_SET_802_11GN           /* PHY_CONFIG_802_11GN */
642 };
643
644 #if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1)
645     #define REQ_GATING_ENABLE_H2D_INT   BIT(31)
646     #define REQ_GATING_DISABLE_H2D_INT  BIT(30)
647     #define ACK_GATING_ENABLE_D2H_INT   BIT(31)
648     #define ACK_GATING_DISABLE_D2H_INT  BIT(30)
649
650     #define GATING_CONTROL_POLL_LIMIT   64
651 #endif
652
653 /*******************************************************************************
654 *                             D A T A   T Y P E S
655 ********************************************************************************
656 */
657
658 /*******************************************************************************
659 *                            P U B L I C   D A T A
660 ********************************************************************************
661 */
662
663 static INT_EVENT_MAP_T arIntEventMapTable[] = {
664     {WHISR_ABNORMAL_INT,                        INT_EVENT_ABNORMAL},
665     {WHISR_D2H_SW_INT,                          INT_EVENT_SW_INT},
666     {WHISR_TX_DONE_INT,                         INT_EVENT_TX},
667     {(WHISR_RX0_DONE_INT | WHISR_RX1_DONE_INT), INT_EVENT_RX}
668 };
669
670 static const UINT_8 ucIntEventMapSize = (sizeof(arIntEventMapTable) / sizeof(INT_EVENT_MAP_T));
671
672 static IST_EVENT_FUNCTION apfnEventFuncTable[] = {
673     nicProcessAbnormalInterrupt,            /*!< INT_EVENT_ABNORMAL */
674     nicProcessSoftwareInterrupt,            /*!< INT_EVENT_SW_INT   */
675     nicProcessTxInterrupt,                  /*!< INT_EVENT_TX       */
676     nicProcessRxInterrupt,                  /*!< INT_EVENT_RX       */
677 };
678 /*******************************************************************************
679 *                           P R I V A T E   D A T A
680 ********************************************************************************
681 */
682
683 /*******************************************************************************
684 *                                 M A C R O S
685 ********************************************************************************
686 */
687 /*! This macro is used to reduce coding errors inside nicAllocateAdapterMemory()
688  * and also enhance the readability.
689  */
690 #define LOCAL_NIC_ALLOCATE_MEMORY(pucMem, u4Size, eMemType, pucComment) \
691         { \
692             DBGLOG(INIT, INFO, ("Allocating %ld bytes for %s.\n", u4Size, pucComment)); \
693             if ((pucMem = (PUINT_8)kalMemAlloc(u4Size, eMemType)) == (PUINT_8)NULL) { \
694                 DBGLOG(INIT, ERROR, ("Could not allocate %ld bytes for %s.\n", u4Size, pucComment)); \
695                 break; \
696             } \
697             ASSERT(((UINT_32)pucMem % 4) == 0); \
698             DBGLOG(INIT, INFO, ("Virtual Address = %08lx for %s.\n", (UINT_32)pucMem, pucComment)); \
699         }
700
701
702
703 /*******************************************************************************
704 *                   F U N C T I O N   D E C L A R A T I O N S
705 ********************************************************************************
706 */
707
708 /*******************************************************************************
709 *                              F U N C T I O N S
710 ********************************************************************************
711 */
712
713
714 /*----------------------------------------------------------------------------*/
715 /*!
716 * @brief This routine is responsible for the allocation of the data structures
717 *        inside the Adapter structure, include:
718 *        1. SW_RFB_Ts
719 *        2. Common coalescing buffer for TX PATH.
720 *
721 * @param prAdapter Pointer of Adapter Data Structure
722 *
723 * @retval WLAN_STATUS_SUCCESS - Has enough memory.
724 * @retval WLAN_STATUS_RESOURCES - Memory is not enough.
725 */
726 /*----------------------------------------------------------------------------*/
727 WLAN_STATUS
728 nicAllocateAdapterMemory (
729     IN P_ADAPTER_T prAdapter
730     )
731 {
732     WLAN_STATUS status = WLAN_STATUS_RESOURCES;
733     P_RX_CTRL_T prRxCtrl;
734     P_TX_CTRL_T prTxCtrl;
735
736     DEBUGFUNC("nicAllocateAdapterMemory");
737
738     ASSERT(prAdapter);
739     prRxCtrl = &prAdapter->rRxCtrl;
740     prTxCtrl = &prAdapter->rTxCtrl;
741
742     do {
743         //4 <0> Reset all Memory Handler
744     #if CFG_DBG_MGT_BUF
745         prAdapter->u4MemFreeDynamicCount = 0;
746         prAdapter->u4MemAllocDynamicCount = 0;
747     #endif
748         prAdapter->pucMgtBufCached = (PUINT_8)NULL;
749         prRxCtrl->pucRxCached = (PUINT_8)NULL;
750         prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T)NULL;
751
752
753         //4 <1> Memory for Management Memory Pool and CMD_INFO_T
754         /* Allocate memory for the CMD_INFO_T and its MGMT memory pool. */
755         prAdapter->u4MgtBufCachedSize = MGT_BUFFER_SIZE;
756
757         LOCAL_NIC_ALLOCATE_MEMORY(prAdapter->pucMgtBufCached,
758                                   prAdapter->u4MgtBufCachedSize,
759                                   VIR_MEM_TYPE,
760                                   "COMMON MGMT MEMORY POOL");
761
762         //4 <2> Memory for RX Descriptor
763         /* Initialize the number of rx buffers we will have in our queue. */
764         /* <TODO> We may setup ucRxPacketDescriptors by GLUE Layer, and using
765          * this variable directly.
766          */
767         /* Allocate memory for the SW receive structures. */
768         prRxCtrl->u4RxCachedSize = CFG_RX_MAX_PKT_NUM * \
769                                    ALIGN_4(sizeof(SW_RFB_T));
770
771         LOCAL_NIC_ALLOCATE_MEMORY(prRxCtrl->pucRxCached,
772                                   prRxCtrl->u4RxCachedSize,
773                                   VIR_MEM_TYPE,
774                                   "SW_RFB_T");
775
776         //4 <3> Memory for TX DEscriptor
777         prTxCtrl->u4TxCachedSize = CFG_TX_MAX_PKT_NUM * \
778                                    ALIGN_4(sizeof(MSDU_INFO_T));
779
780         LOCAL_NIC_ALLOCATE_MEMORY(prTxCtrl->pucTxCached,
781                                   prTxCtrl->u4TxCachedSize,
782                                   VIR_MEM_TYPE,
783                                   "MSDU_INFO_T");
784
785         //4 <4> Memory for Common Coalescing Buffer
786 #if CFG_COALESCING_BUFFER_SIZE || CFG_SDIO_RX_AGG
787         prAdapter->pucCoalescingBufCached = (PUINT_8)NULL;
788
789         /* Allocate memory for the common coalescing buffer. */
790         prAdapter->u4CoalescingBufCachedSize = CFG_COALESCING_BUFFER_SIZE > CFG_RX_COALESCING_BUFFER_SIZE ?
791             CFG_COALESCING_BUFFER_SIZE : CFG_RX_COALESCING_BUFFER_SIZE;
792
793         prAdapter->pucCoalescingBufCached =
794             kalAllocateIOBuffer(prAdapter->u4CoalescingBufCachedSize);
795
796         if(prAdapter->pucCoalescingBufCached == NULL) {
797             DBGLOG(INIT, ERROR, ("Could not allocate %ld bytes for coalescing buffer.\n", prAdapter->u4CoalescingBufCachedSize));
798             break;
799         }
800 #endif /* CFG_COALESCING_BUFFER_SIZE */
801
802         //4 <5> Memory for enhanced interrupt response
803         prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T)
804             kalAllocateIOBuffer(sizeof(ENHANCE_MODE_DATA_STRUCT_T));
805
806         if(prAdapter->prSDIOCtrl == NULL) {
807             DBGLOG(INIT, ERROR, ("Could not allocate %ld bytes for interrupt response.\n", sizeof(ENHANCE_MODE_DATA_STRUCT_T)));
808             break;
809         }
810
811         status = WLAN_STATUS_SUCCESS;
812
813     }
814     while(FALSE);
815
816     if(status != WLAN_STATUS_SUCCESS) {
817         nicReleaseAdapterMemory(prAdapter);
818     }
819
820     return status;
821
822 }   /* end of nicAllocateAdapterMemory() */
823
824
825 /*----------------------------------------------------------------------------*/
826 /*!
827 * @brief This routine is responsible for releasing the allocated memory by
828 *        nicAllocatedAdapterMemory().
829 *
830 * @param prAdapter Pointer of Adapter Data Structure
831 *
832 * @return (none)
833 */
834 /*----------------------------------------------------------------------------*/
835 VOID
836 nicReleaseAdapterMemory (
837     IN P_ADAPTER_T prAdapter
838     )
839 {
840     P_TX_CTRL_T prTxCtrl;
841     P_RX_CTRL_T prRxCtrl;
842
843     ASSERT(prAdapter);
844     prTxCtrl = &prAdapter->rTxCtrl;
845     prRxCtrl = &prAdapter->rRxCtrl;
846
847     //4 <5> Memory for enhanced interrupt response
848     if (prAdapter->prSDIOCtrl) {
849         kalReleaseIOBuffer((PVOID)prAdapter->prSDIOCtrl, sizeof(ENHANCE_MODE_DATA_STRUCT_T));
850         prAdapter->prSDIOCtrl = (P_SDIO_CTRL_T)NULL;
851     }
852
853     //4 <4> Memory for Common Coalescing Buffer
854 #if CFG_COALESCING_BUFFER_SIZE || CFG_SDIO_RX_AGG
855     if (prAdapter->pucCoalescingBufCached) {
856         kalReleaseIOBuffer((PVOID)prAdapter->pucCoalescingBufCached, prAdapter->u4CoalescingBufCachedSize);
857         prAdapter->pucCoalescingBufCached = (PUINT_8)NULL;
858     }
859 #endif /* CFG_COALESCING_BUFFER_SIZE */
860
861     //4 <3> Memory for TX Descriptor
862     if (prTxCtrl->pucTxCached) {
863         kalMemFree((PVOID)prTxCtrl->pucTxCached,
864                    VIR_MEM_TYPE,
865                    prTxCtrl->u4TxCachedSize);
866         prTxCtrl->pucTxCached = (PUINT_8)NULL;
867     }
868
869     //4 <2> Memory for RX Descriptor
870     if (prRxCtrl->pucRxCached) {
871         kalMemFree((PVOID)prRxCtrl->pucRxCached,
872                    VIR_MEM_TYPE,
873                    prRxCtrl->u4RxCachedSize);
874         prRxCtrl->pucRxCached = (PUINT_8)NULL;
875     }
876
877     //4 <1> Memory for Management Memory Pool
878     if (prAdapter->pucMgtBufCached) {
879         kalMemFree((PVOID)prAdapter->pucMgtBufCached,
880                    VIR_MEM_TYPE,
881                    prAdapter->u4MgtBufCachedSize);
882         prAdapter->pucMgtBufCached = (PUINT_8)NULL;
883     }
884
885 #if CFG_DBG_MGT_BUF
886     /* Check if all allocated memories are free */
887     ASSERT(prAdapter->u4MemFreeDynamicCount ==
888            prAdapter->u4MemAllocDynamicCount);
889 #endif
890
891     return;
892 }
893
894
895 /*----------------------------------------------------------------------------*/
896 /*!
897 * @brief disable global interrupt
898 *
899 * @param prAdapter pointer to the Adapter handler
900 *
901 * @return (none)
902 */
903 /*----------------------------------------------------------------------------*/
904 VOID
905 nicDisableInterrupt (
906     IN P_ADAPTER_T prAdapter
907     )
908 {
909     ASSERT(prAdapter);
910
911     HAL_BYTE_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_CLR);
912
913     prAdapter->fgIsIntEnable = FALSE;
914 }
915
916 /*----------------------------------------------------------------------------*/
917 /*!
918 * @brief enable global interrupt
919 *
920 * @param prAdapter pointer to the Adapter handler
921 *
922 * @return (none)
923 */
924 /*----------------------------------------------------------------------------*/
925 VOID
926 nicEnableInterrupt (
927     IN P_ADAPTER_T prAdapter
928     )
929 {
930     BOOLEAN fgIsIntEnableCache;
931
932
933     ASSERT(prAdapter);
934     fgIsIntEnableCache = prAdapter->fgIsIntEnable;
935
936     prAdapter->fgIsIntEnable = TRUE; // NOTE(Kevin): It must be placed before MCR GINT write.
937
938     /* If need enable INT and also set LPOwn at the same time. */
939     if (prAdapter->fgIsIntEnableWithLPOwnSet) {
940         prAdapter->fgIsIntEnableWithLPOwnSet = FALSE; /* NOTE(Kevin): It's better to place it
941                                                        * before MCR GINT write.
942                                                        */
943         /* If INT was enabled, only set LPOwn */
944         if (fgIsIntEnableCache) {
945             HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET);
946             prAdapter->fgIsFwOwn = TRUE;
947         }
948         /* If INT was not enabled, enable it and also set LPOwn now */
949         else {
950             HAL_MCR_WR(prAdapter, MCR_WHLPCR, WHLPCR_FW_OWN_REQ_SET |
951                                               WHLPCR_INT_EN_SET);
952             prAdapter->fgIsFwOwn = TRUE;
953         }
954     }
955     /* If INT was not enabled, enable it now */
956     else if (!fgIsIntEnableCache) {
957         HAL_BYTE_WR(prAdapter, MCR_WHLPCR, WHLPCR_INT_EN_SET);
958     }
959
960     return;
961 } /* end of nicEnableInterrupt() */
962
963
964 #if CFG_SDIO_INTR_ENHANCE
965 /*----------------------------------------------------------------------------*/
966 /*!
967 * @brief For SDIO enhance mode, set the max rx len and tx status
968 *
969 * @param prAdapter      a pointer to adapter private data structure.
970 *
971 * @return  - none
972 */
973 /*----------------------------------------------------------------------------*/
974 VOID
975 nicSDIOInit (
976     IN P_ADAPTER_T prAdapter
977     )
978 {
979     UINT_32 u4Value = 0;
980
981     ASSERT(prAdapter);
982
983     //4 <1> Check STATUS Buffer is DW alignment.
984     ASSERT( IS_ALIGN_4( (UINT_32)&prAdapter->prSDIOCtrl->u4WHISR ) );
985
986     //4 <2> Setup STATUS count.
987     {
988         HAL_MCR_RD(prAdapter, MCR_WHCR, &u4Value);
989
990         //4 <2.1> Setup the number of maximum RX length to be report
991         u4Value &= ~(WHCR_MAX_HIF_RX_LEN_NUM);
992         u4Value |= ((SDIO_MAXIMUM_RX_LEN_NUM << WHCR_OFFSET_MAX_HIF_RX_LEN_NUM));
993
994         //4 <2.2> Setup RX enhancement mode
995 #if CFG_SDIO_RX_ENHANCE
996         u4Value |= WHCR_RX_ENHANCE_MODE_EN;
997 #else
998         u4Value &= ~WHCR_RX_ENHANCE_MODE_EN;
999 #endif /* CFG_SDIO_RX_AGG */
1000
1001         HAL_MCR_WR(prAdapter, MCR_WHCR, u4Value);
1002     }
1003
1004     return;
1005
1006 } /* end of nicSDIOInit() */
1007
1008 /*----------------------------------------------------------------------------*/
1009 /*!
1010 * @brief Read interrupt status from hardware
1011 *
1012 * @param prAdapter pointer to the Adapter handler
1013 * @param the interrupts
1014 *
1015 * @return N/A
1016 *
1017 */
1018 /*----------------------------------------------------------------------------*/
1019 VOID
1020 nicSDIOReadIntStatus (
1021     IN P_ADAPTER_T prAdapter,
1022     OUT PUINT_32   pu4IntStatus
1023     )
1024 {
1025     P_SDIO_CTRL_T prSDIOCtrl;
1026
1027     DEBUGFUNC("nicSDIOReadIntStatus");
1028
1029     ASSERT(prAdapter);
1030     ASSERT(pu4IntStatus);
1031
1032     prSDIOCtrl = prAdapter->prSDIOCtrl;
1033     ASSERT(prSDIOCtrl);
1034
1035     HAL_PORT_RD(prAdapter,
1036                 MCR_WHISR,
1037                 sizeof(ENHANCE_MODE_DATA_STRUCT_T),
1038                 (PUINT_8)prSDIOCtrl,
1039                 sizeof(ENHANCE_MODE_DATA_STRUCT_T));
1040
1041     if(kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE
1042             || fgIsBusAccessFailed == TRUE) {
1043         *pu4IntStatus = 0;
1044         return;
1045     }
1046
1047     /* workaround */
1048     if((prSDIOCtrl->u4WHISR & WHISR_TX_DONE_INT) == 0 &&
1049             (prSDIOCtrl->rTxInfo.au4WTSR[0] | prSDIOCtrl->rTxInfo.au4WTSR[1])) {
1050         prSDIOCtrl->u4WHISR |= WHISR_TX_DONE_INT;
1051     }
1052
1053     if((prSDIOCtrl->u4WHISR & BIT(31)) == 0 &&
1054             HAL_GET_MAILBOX_READ_CLEAR(prAdapter) == TRUE &&
1055             (prSDIOCtrl->u4RcvMailbox0 != 0 || prSDIOCtrl->u4RcvMailbox1 != 0)) {
1056         prSDIOCtrl->u4WHISR |= BIT(31);
1057     }
1058
1059     *pu4IntStatus = prSDIOCtrl->u4WHISR;
1060
1061     return;
1062 } /* end of nicSDIOReadIntStatus() */
1063 #endif
1064
1065 /*----------------------------------------------------------------------------*/
1066 /*!
1067 * @brief The function used to read interrupt status and then invoking
1068 *        dispatching procedure for the appropriate functions
1069 *        corresponding to specific interrupt bits
1070 *
1071 * @param prAdapter pointer to the Adapter handler
1072 *
1073 * @retval WLAN_STATUS_SUCCESS
1074 * @retval WLAN_STATUS_ADAPTER_NOT_READY
1075 */
1076 /*----------------------------------------------------------------------------*/
1077 WLAN_STATUS
1078 nicProcessIST (
1079     IN P_ADAPTER_T prAdapter
1080     )
1081 {
1082     WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
1083     UINT_32 u4IntStatus = 0;
1084     UINT_32 i;
1085
1086     DEBUGFUNC("nicProcessIST");
1087     //DBGLOG(INIT, LOUD, ("\n"));
1088
1089     ASSERT(prAdapter);
1090
1091     if (prAdapter->rAcpiState == ACPI_STATE_D3) {
1092         DBGLOG(REQ, WARN, ("Fail in set nicProcessIST! (Adapter not ready). ACPI=D%d, Radio=%d\n",
1093                     prAdapter->rAcpiState, prAdapter->fgIsRadioOff));
1094         return WLAN_STATUS_ADAPTER_NOT_READY;
1095     }
1096
1097 #if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1)
1098     if(prAdapter->fgIsClockGatingEnabled == TRUE) {
1099         nicDisableClockGating(prAdapter);
1100     }
1101 #endif
1102
1103     for (i = 0; i < CFG_IST_LOOP_COUNT; i++) {
1104
1105 #if CFG_SDIO_INTR_ENHANCE
1106         nicSDIOReadIntStatus(prAdapter, &u4IntStatus);
1107 #else
1108         HAL_MCR_RD(prAdapter, MCR_WHISR, &u4IntStatus);
1109 #endif /* CFG_SDIO_INTR_ENHANCE */
1110
1111         //DBGLOG(INIT, TRACE, ("u4IntStatus: 0x%x\n", u4IntStatus));
1112
1113         if (u4IntStatus & ~(WHIER_DEFAULT | WHIER_FW_OWN_BACK_INT_EN)) {
1114             DBGLOG(INTR, WARN, ("Un-handled HISR %#x, HISR = %#x (HIER:0x%x)\n",
1115                 (u4IntStatus & ~WHIER_DEFAULT), u4IntStatus, WHIER_DEFAULT));
1116             u4IntStatus &= WHIER_DEFAULT;
1117         }
1118
1119         nicProcessIST_impl(prAdapter, u4IntStatus);
1120
1121         if(u4IntStatus == 0) {
1122             if(i == 0) {
1123                 u4Status = WLAN_STATUS_NOT_INDICATING;
1124             }
1125             break;
1126         }
1127     }
1128
1129 #if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1)
1130     if(prAdapter->fgIsClockGatingEnabled == FALSE) {
1131         nicEnableClockGating(prAdapter);
1132     }
1133 #endif
1134
1135     return u4Status;
1136 } /* end of nicProcessIST() */
1137
1138
1139 /*----------------------------------------------------------------------------*/
1140 /*!
1141 * @brief The function used to dispatch the appropriate functions for specific
1142 *        interrupt bits
1143 *
1144 * @param prAdapter   pointer to the Adapter handler
1145 *        u4IntStatus interrupt status bits
1146 *
1147 * @retval WLAN_STATUS_SUCCESS
1148 * @retval WLAN_STATUS_ADAPTER_NOT_READY
1149 */
1150 /*----------------------------------------------------------------------------*/
1151 WLAN_STATUS
1152 nicProcessIST_impl (
1153     IN P_ADAPTER_T prAdapter,
1154     IN UINT_32 u4IntStatus
1155     )
1156 {
1157     UINT_32 u4IntCount = 0;
1158     P_INT_EVENT_MAP_T prIntEventMap = NULL;
1159
1160     ASSERT(prAdapter);
1161
1162     prAdapter->u4IntStatus = u4IntStatus;
1163
1164     /* Process each of the interrupt status consequently */
1165     prIntEventMap = &arIntEventMapTable[0];
1166     for (u4IntCount = 0; u4IntCount < ucIntEventMapSize; prIntEventMap++, u4IntCount++) {
1167         if (prIntEventMap->u4Int & prAdapter->u4IntStatus) {
1168             if(prIntEventMap->u4Event == INT_EVENT_RX &&
1169                     prAdapter->fgIsEnterD3ReqIssued == TRUE) {
1170                 // ignore 
1171             }
1172             else if (apfnEventFuncTable[prIntEventMap->u4Event] != NULL) {
1173                 apfnEventFuncTable[prIntEventMap->u4Event](prAdapter);
1174             }
1175             else {
1176                 DBGLOG(INTR , WARN,
1177                         ("Empty INTR handler! ISAR bit#: %ld, event:%d, func: 0x%x\n",
1178                          prIntEventMap->u4Int, prIntEventMap->u4Event, apfnEventFuncTable[prIntEventMap->u4Event]));
1179
1180                 ASSERT(0); // to trap any NULL interrupt handler
1181             }
1182             prAdapter->u4IntStatus &= ~prIntEventMap->u4Int;
1183         }
1184     }
1185
1186     return WLAN_STATUS_SUCCESS;
1187 } /* end of nicProcessIST_impl() */
1188
1189
1190 /*----------------------------------------------------------------------------*/
1191 /*!
1192 * @brief Verify the CHIP ID
1193 *
1194 * @param prAdapter      a pointer to adapter private data structure.
1195 *
1196 *
1197 * @retval TRUE          CHIP ID is the same as the setting compiled
1198 * @retval FALSE         CHIP ID is different from the setting compiled
1199 */
1200 /*----------------------------------------------------------------------------*/
1201 BOOL
1202 nicVerifyChipID (
1203     IN P_ADAPTER_T prAdapter
1204     )
1205 {
1206     UINT_32 u4CIR = 0;
1207
1208     ASSERT(prAdapter);
1209
1210     HAL_MCR_RD(prAdapter, MCR_WCIR, &u4CIR );
1211
1212     DBGLOG(INIT, TRACE,("Chip ID: 0x%x\n", u4CIR & WCIR_CHIP_ID));
1213     DBGLOG(INIT, TRACE,("Revision ID: 0x%x\n", ((u4CIR & WCIR_REVISION_ID) >> 16)));
1214
1215     if ((u4CIR & WCIR_CHIP_ID) != MTK_CHIP_REV) {
1216         return FALSE;
1217     }
1218
1219     prAdapter->ucRevID = (UINT_8)(((u4CIR & WCIR_REVISION_ID) >> 16) & 0xF) ;
1220
1221     return TRUE;
1222 }
1223
1224 /*----------------------------------------------------------------------------*/
1225 /*!
1226 * @brief Initialize the MCR to the appropriate init value, and verify the init
1227 *        value
1228 *
1229 * @param prAdapter      a pointer to adapter private data structure.
1230 *
1231 * @return -
1232 */
1233 /*----------------------------------------------------------------------------*/
1234 VOID
1235 nicMCRInit (
1236     IN P_ADAPTER_T prAdapter
1237     )
1238 {
1239
1240     ASSERT(prAdapter);
1241
1242     //4 <0> Initial value
1243 }
1244
1245 VOID
1246 nicHifInit (
1247     IN P_ADAPTER_T prAdapter
1248     )
1249 {
1250
1251     ASSERT(prAdapter);
1252 #if 0
1253     /* reset event */
1254     nicPutMailbox(prAdapter, 0, 0x52455345); // RESE
1255     nicPutMailbox(prAdapter, 1, 0x545F5746); // T_WF
1256     nicSetSwIntr(prAdapter, BIT(16));
1257 #endif
1258 }
1259
1260
1261 /*----------------------------------------------------------------------------*/
1262 /*!
1263 * @brief Initialize the Adapter soft variable
1264 *
1265 * @param prAdapter pointer to the Adapter handler
1266 *
1267 * @return (none)
1268 *
1269 */
1270 /*----------------------------------------------------------------------------*/
1271 WLAN_STATUS
1272 nicInitializeAdapter (
1273     IN P_ADAPTER_T prAdapter
1274     )
1275 {
1276     WLAN_STATUS u4Status = WLAN_STATUS_SUCCESS;
1277
1278     ASSERT(prAdapter);
1279
1280     prAdapter->fgIsIntEnableWithLPOwnSet = FALSE;
1281
1282     do {
1283         if (!nicVerifyChipID(prAdapter)) {
1284             u4Status = WLAN_STATUS_FAILURE;
1285             break;
1286         }
1287
1288         //4 <1> MCR init
1289         nicMCRInit(prAdapter);
1290
1291     #if CFG_SDIO_INTR_ENHANCE
1292         nicSDIOInit(prAdapter);
1293     #endif /* CFG_SDIO_INTR_ENHANCE */
1294
1295         HAL_MCR_WR(prAdapter, MCR_WHIER, WHIER_DEFAULT);
1296
1297
1298         //4 <2> init FW HIF
1299         nicHifInit(prAdapter);
1300     }
1301     while (FALSE);
1302
1303
1304     return u4Status;
1305 }
1306
1307
1308 #if defined(_HIF_SPI)
1309 /*----------------------------------------------------------------------------*/
1310 /*!
1311 * \brief Restore the SPI Mode Select to default mode,
1312 *        this is important while driver is unload, and this must be last mcr
1313 *        since the operation will let the hif use 8bit mode access
1314 *
1315 * \param[in] prAdapter      a pointer to adapter private data structure.
1316 * \param[in] eGPIO2_Mode    GPIO2 operation mode
1317 *
1318 * \return (none)
1319 */
1320 /*----------------------------------------------------------------------------*/
1321 void
1322 nicRestoreSpiDefMode (
1323     IN P_ADAPTER_T prAdapter
1324     )
1325 {
1326     ASSERT(prAdapter);
1327
1328     HAL_MCR_WR(prAdapter, MCR_WCSR, SPICSR_8BIT_MODE_DATA);
1329
1330 }
1331 #endif
1332
1333 /*----------------------------------------------------------------------------*/
1334 /*!
1335 * @brief Process rx interrupt. When the rx
1336 *        Interrupt is asserted, it means there are frames in queue.
1337 *
1338 * @param prAdapter      Pointer to the Adapter structure.
1339 *
1340 * @return (none)
1341 */
1342 /*----------------------------------------------------------------------------*/
1343 VOID
1344 nicProcessAbnormalInterrupt (
1345     IN  P_ADAPTER_T prAdapter
1346     )
1347 {
1348     UINT_32 u4Value;
1349
1350     HAL_MCR_RD(prAdapter, MCR_WASR, &u4Value);
1351     DBGLOG(REQ, WARN, ("MCR_WASR: 0x%x \n", u4Value));
1352 }
1353
1354 /*----------------------------------------------------------------------------*/
1355 /*!
1356 * @brief .
1357 *
1358 * @param prAdapter  Pointer to the Adapter structure.
1359 *
1360 * @return (none)
1361 */
1362 /*----------------------------------------------------------------------------*/
1363 VOID
1364 nicProcessFwOwnBackInterrupt(
1365     IN P_ADAPTER_T prAdapter
1366     )
1367 {
1368
1369     return;
1370 } /* end of nicProcessFwOwnBackInterrupt() */
1371
1372 /*----------------------------------------------------------------------------*/
1373 /*!
1374 * @brief .
1375 *
1376 * @param prAdapter  Pointer to the Adapter structure.
1377 *
1378 * @return (none)
1379 */
1380 /*----------------------------------------------------------------------------*/
1381 VOID
1382 nicProcessSoftwareInterrupt(
1383     IN P_ADAPTER_T prAdapter
1384     )
1385 {
1386     UINT_32 u4IntrBits;
1387
1388     ASSERT(prAdapter);
1389
1390     u4IntrBits = prAdapter->u4IntStatus & BITS(8, 31);
1391
1392     if((u4IntrBits & WHISR_D2H_SW_ASSERT_INFO_INT) != 0) {
1393         nicPrintFirmwareAssertInfo(prAdapter);
1394 #if CFG_CHIP_RESET_SUPPORT
1395         glSendResetRequest();
1396 #endif
1397     }
1398
1399 #if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1)
1400     ASSERT((u4IntrBits & (ACK_GATING_ENABLE_D2H_INT | ACK_GATING_DISABLE_D2H_INT))
1401             != (ACK_GATING_ENABLE_D2H_INT | ACK_GATING_DISABLE_D2H_INT));
1402
1403     if(u4IntrBits & ACK_GATING_ENABLE_D2H_INT) {
1404         prAdapter->fgIsClockGatingEnabled = TRUE;
1405     }
1406
1407     if(u4IntrBits & ACK_GATING_DISABLE_D2H_INT) {
1408         prAdapter->fgIsClockGatingEnabled = FALSE;
1409
1410         // Indicate Service Thread for TX
1411         if(kalGetTxPendingCmdCount(prAdapter->prGlueInfo) > 0
1412                 || wlanGetTxPendingFrameCount(prAdapter) > 0) {
1413             kalSetEvent(prAdapter->prGlueInfo);
1414         }
1415     }
1416 #endif
1417
1418     DBGLOG(REQ, WARN, ("u4IntrBits: 0x%x \n", u4IntrBits));
1419
1420     return;
1421 } /* end of nicProcessSoftwareInterrupt() */
1422
1423 VOID
1424 nicPutMailbox (
1425     IN P_ADAPTER_T prAdapter,
1426     IN UINT_32 u4MailboxNum,
1427     IN UINT_32 u4Data
1428     )
1429 {
1430     if (u4MailboxNum == 0) {
1431         HAL_MCR_WR(prAdapter, MCR_H2DSM0R, u4Data);
1432     } else if (u4MailboxNum == 1) {
1433         HAL_MCR_WR(prAdapter, MCR_H2DSM1R, u4Data);
1434     } else {
1435         ASSERT(0);
1436     }
1437 }
1438
1439 VOID
1440 nicGetMailbox (
1441     IN P_ADAPTER_T prAdapter,
1442     IN UINT_32 u4MailboxNum,
1443     OUT PUINT_32 pu4Data
1444     )
1445 {
1446     if (u4MailboxNum == 0) {
1447         HAL_MCR_RD(prAdapter, MCR_D2HRM0R, pu4Data);
1448     } else if (u4MailboxNum == 1) {
1449         HAL_MCR_RD(prAdapter, MCR_D2HRM1R, pu4Data);
1450     } else {
1451         ASSERT(0);
1452     }
1453 }
1454
1455 VOID
1456 nicSetSwIntr (
1457     IN P_ADAPTER_T prAdapter,
1458     IN UINT_32 u4SwIntrBitmap
1459     )
1460 {
1461     /* NOTE:
1462      *  SW interrup in HW bit 16 is mapping to SW bit 0 (shift 16bit in HW transparancy)
1463      *  SW interrupt valid from b0~b15
1464      */
1465     ASSERT((u4SwIntrBitmap & BITS(0, 15)) == 0);
1466 //    DBGLOG(INIT, TRACE, ("u4SwIntrBitmap: 0x%08x\n", u4SwIntrBitmap));
1467
1468     HAL_MCR_WR(prAdapter, MCR_WSICR, u4SwIntrBitmap);
1469 }
1470
1471
1472 /*----------------------------------------------------------------------------*/
1473 /*!
1474 * @brief This procedure is used to dequeue from prAdapter->rPendingCmdQueue
1475 *        with specified sequential number
1476 *
1477 * @param    prAdapter   Pointer of ADAPTER_T
1478 *           ucSeqNum    Sequential Number
1479 *
1480 * @retval - P_CMD_INFO_T
1481 */
1482 /*----------------------------------------------------------------------------*/
1483 P_CMD_INFO_T
1484 nicGetPendingCmdInfo (
1485     IN P_ADAPTER_T prAdapter,
1486     IN UINT_8 ucSeqNum
1487     )
1488 {
1489     P_QUE_T prCmdQue;
1490     QUE_T rTempCmdQue;
1491     P_QUE_T prTempCmdQue = &rTempCmdQue;
1492     P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T)NULL;
1493     P_CMD_INFO_T prCmdInfo = (P_CMD_INFO_T)NULL;
1494
1495     GLUE_SPIN_LOCK_DECLARATION();
1496
1497     ASSERT(prAdapter);
1498
1499     KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING);
1500
1501     prCmdQue = &prAdapter->rPendingCmdQueue;
1502     QUEUE_MOVE_ALL(prTempCmdQue, prCmdQue);
1503
1504     QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
1505     while (prQueueEntry) {
1506         prCmdInfo = (P_CMD_INFO_T)prQueueEntry;
1507
1508         if(prCmdInfo->ucCmdSeqNum == ucSeqNum)
1509             break;
1510         else {
1511             QUEUE_INSERT_TAIL(prCmdQue, prQueueEntry);
1512
1513             prCmdInfo = NULL;
1514         }
1515
1516         QUEUE_REMOVE_HEAD(prTempCmdQue, prQueueEntry, P_QUE_ENTRY_T);
1517     }
1518     QUEUE_CONCATENATE_QUEUES(prCmdQue, prTempCmdQue);
1519
1520     KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_PENDING);
1521
1522     return prCmdInfo;
1523 }
1524
1525
1526 /*----------------------------------------------------------------------------*/
1527 /*!
1528 * @brief This procedure is used to dequeue from prAdapter->rTxCtrl.rTxMgmtTxingQueue
1529 *        with specified sequential number
1530 *
1531 * @param    prAdapter   Pointer of ADAPTER_T
1532 *           ucSeqNum    Sequential Number
1533 *
1534 * @retval - P_MSDU_INFO_T
1535 */
1536 /*----------------------------------------------------------------------------*/
1537 P_MSDU_INFO_T
1538 nicGetPendingTxMsduInfo (
1539     IN P_ADAPTER_T prAdapter,
1540     IN UINT_8 ucSeqNum
1541     )
1542 {
1543     P_QUE_T prTxingQue;
1544     QUE_T rTempQue;
1545     P_QUE_T prTempQue = &rTempQue;
1546     P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T)NULL;
1547     P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T)NULL;
1548
1549     GLUE_SPIN_LOCK_DECLARATION();
1550
1551     ASSERT(prAdapter);
1552
1553     KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
1554
1555     prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue);
1556     QUEUE_MOVE_ALL(prTempQue, prTxingQue);
1557
1558     QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T);
1559     while (prQueueEntry) {
1560         prMsduInfo = (P_MSDU_INFO_T)prQueueEntry;
1561
1562         if(prMsduInfo->ucTxSeqNum == ucSeqNum)
1563             break;
1564         else {
1565             QUEUE_INSERT_TAIL(prTxingQue, prQueueEntry);
1566
1567             prMsduInfo = NULL;
1568         }
1569
1570         QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T);
1571     }
1572     QUEUE_CONCATENATE_QUEUES(prTxingQue, prTempQue);
1573
1574     KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
1575
1576     return prMsduInfo;
1577 }
1578
1579 P_MSDU_INFO_T
1580 nicGetPendingStaMMPDU (
1581     IN P_ADAPTER_T prAdapter,
1582     IN UINT_8 ucStaRecIdx
1583     )
1584 {
1585     P_MSDU_INFO_T prMsduInfoListHead = (P_MSDU_INFO_T)NULL;
1586     P_QUE_T prTxingQue = (P_QUE_T)NULL;
1587     QUE_T rTempQue;
1588     P_QUE_T prTempQue = &rTempQue;
1589     P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T)NULL;
1590     P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T)NULL;
1591
1592     GLUE_SPIN_LOCK_DECLARATION();
1593
1594     KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
1595     do {
1596         if (prAdapter == NULL) {
1597
1598             ASSERT(FALSE);
1599             break;
1600         }
1601
1602         prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue);
1603         QUEUE_MOVE_ALL(prTempQue, prTxingQue);
1604
1605         QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T);
1606         while (prQueueEntry) {
1607             prMsduInfo = (P_MSDU_INFO_T)prQueueEntry;
1608
1609             if ((prMsduInfo->ucStaRecIndex == ucStaRecIdx) && (prMsduInfo->pfTxDoneHandler != NULL)) {
1610                 QM_TX_SET_NEXT_MSDU_INFO(prMsduInfo,
1611                                     prMsduInfoListHead);
1612                 prMsduInfoListHead = prMsduInfo;
1613             }
1614             else {
1615                 QUEUE_INSERT_TAIL(prTxingQue, prQueueEntry);
1616
1617                 prMsduInfo = NULL;
1618             }
1619
1620
1621             QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T);
1622         }
1623
1624     } while (FALSE);
1625     KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
1626
1627
1628     return prMsduInfoListHead;
1629 } /* nicGetPendingStaMMPDU */
1630
1631
1632 VOID
1633 nicFreePendingTxMsduInfoByNetwork (
1634     IN P_ADAPTER_T                  prAdapter,
1635     IN ENUM_NETWORK_TYPE_INDEX_T    eNetworkType
1636     )
1637 {
1638     P_QUE_T prTxingQue;
1639     QUE_T rTempQue;
1640     P_QUE_T prTempQue = &rTempQue;
1641     P_QUE_ENTRY_T prQueueEntry = (P_QUE_ENTRY_T)NULL;
1642     P_MSDU_INFO_T prMsduInfoListHead = (P_MSDU_INFO_T)NULL;
1643     P_MSDU_INFO_T prMsduInfoListTail = (P_MSDU_INFO_T)NULL;
1644     P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T)NULL;
1645
1646     GLUE_SPIN_LOCK_DECLARATION();
1647
1648     ASSERT(prAdapter);
1649
1650     KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
1651
1652     prTxingQue = &(prAdapter->rTxCtrl.rTxMgmtTxingQueue);
1653     QUEUE_MOVE_ALL(prTempQue, prTxingQue);
1654
1655     QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T);
1656     while (prQueueEntry) {
1657         prMsduInfo = (P_MSDU_INFO_T)prQueueEntry;
1658
1659         if((ENUM_NETWORK_TYPE_INDEX_T)(prMsduInfo->ucNetworkType) == eNetworkType) {
1660             if(prMsduInfoListHead == NULL) {
1661                 prMsduInfoListHead = prMsduInfoListTail = prMsduInfo;
1662             }
1663             else {
1664                 QM_TX_SET_NEXT_MSDU_INFO(prMsduInfoListTail, prMsduInfo);
1665                 prMsduInfoListTail = prMsduInfo;
1666             }
1667         }
1668         else {
1669             QUEUE_INSERT_TAIL(prTxingQue, prQueueEntry);
1670
1671             prMsduInfo = NULL;
1672         }
1673
1674         QUEUE_REMOVE_HEAD(prTempQue, prQueueEntry, P_QUE_ENTRY_T);
1675     }
1676     QUEUE_CONCATENATE_QUEUES(prTxingQue, prTempQue);
1677
1678     KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TXING_MGMT_LIST);
1679
1680     /* free */
1681     if(prMsduInfoListHead) {
1682         nicTxFreeMsduInfoPacket(prAdapter, prMsduInfoListHead);
1683     }
1684
1685     return;
1686
1687 } /* end of nicFreePendingTxMsduInfoByNetwork() */
1688
1689
1690
1691 /*----------------------------------------------------------------------------*/
1692 /*!
1693 * @brief This procedure is used to retrieve a CMD sequence number atomically
1694 *
1695 * @param    prAdapter   Pointer of ADAPTER_T
1696 *
1697 * @retval - UINT_8
1698 */
1699 /*----------------------------------------------------------------------------*/
1700 UINT_8
1701 nicIncreaseCmdSeqNum (
1702     IN P_ADAPTER_T prAdapter
1703     )
1704 {
1705     UINT_8 ucRetval;
1706
1707     KAL_SPIN_LOCK_DECLARATION();
1708
1709     ASSERT(prAdapter);
1710
1711     KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_SEQ_NUM);
1712
1713     prAdapter->ucCmdSeqNum++;
1714     ucRetval = prAdapter->ucCmdSeqNum;
1715
1716     KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_CMD_SEQ_NUM);
1717
1718     return ucRetval;
1719 }
1720
1721
1722 /*----------------------------------------------------------------------------*/
1723 /*!
1724 * @brief This procedure is used to retrieve a TX sequence number atomically
1725 *
1726 * @param    prAdapter   Pointer of ADAPTER_T
1727 *
1728 * @retval - UINT_8
1729 */
1730 /*----------------------------------------------------------------------------*/
1731 UINT_8
1732 nicIncreaseTxSeqNum (
1733     IN P_ADAPTER_T prAdapter
1734     )
1735 {
1736     UINT_8 ucRetval;
1737
1738     KAL_SPIN_LOCK_DECLARATION();
1739
1740     ASSERT(prAdapter);
1741
1742     KAL_ACQUIRE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_SEQ_NUM);
1743
1744     prAdapter->ucTxSeqNum++;
1745     ucRetval = prAdapter->ucTxSeqNum;
1746
1747     KAL_RELEASE_SPIN_LOCK(prAdapter, SPIN_LOCK_TX_SEQ_NUM);
1748
1749     return ucRetval;
1750 }
1751
1752
1753
1754 /*----------------------------------------------------------------------------*/
1755 /*!
1756 * @brief This utility function is used to handle
1757 *        media state change event
1758 *
1759 * @param
1760 *
1761 * @retval
1762 */
1763 /*----------------------------------------------------------------------------*/
1764 WLAN_STATUS
1765 nicMediaStateChange (
1766     IN P_ADAPTER_T                  prAdapter,
1767     IN ENUM_NETWORK_TYPE_INDEX_T    eNetworkType,
1768     IN P_EVENT_CONNECTION_STATUS    prConnectionStatus
1769     )
1770 {
1771     P_GLUE_INFO_T prGlueInfo;
1772
1773     ASSERT(prAdapter);
1774     prGlueInfo = prAdapter->prGlueInfo;
1775
1776     switch(eNetworkType) {
1777     case NETWORK_TYPE_AIS_INDEX:
1778         if (prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_DISCONNECTED) { // disconnected
1779             if(kalGetMediaStateIndicated(prGlueInfo) != PARAM_MEDIA_STATE_DISCONNECTED) {
1780
1781                 kalIndicateStatusAndComplete(prGlueInfo,
1782                         WLAN_STATUS_MEDIA_DISCONNECT,
1783                         NULL,
1784                         0);
1785
1786                 prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick();
1787             }
1788
1789             /* reset buffered link quality information */
1790             prAdapter->fgIsLinkQualityValid = FALSE;
1791             prAdapter->fgIsLinkRateValid = FALSE;
1792         }
1793         else if(prConnectionStatus->ucMediaStatus == PARAM_MEDIA_STATE_CONNECTED) { // connected
1794             prAdapter->rWlanInfo.u4SysTime = kalGetTimeTick();
1795
1796             // fill information for association result
1797             prAdapter->rWlanInfo.rCurrBssId.rSsid.u4SsidLen
1798                 = prConnectionStatus->ucSsidLen;
1799             kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.rSsid.aucSsid,
1800                     prConnectionStatus->aucSsid,
1801                     prConnectionStatus->ucSsidLen);
1802             kalMemCopy(prAdapter->rWlanInfo.rCurrBssId.arMacAddress,
1803                     prConnectionStatus->aucBssid,
1804                     MAC_ADDR_LEN);
1805             prAdapter->rWlanInfo.rCurrBssId.u4Privacy
1806                 = prConnectionStatus->ucEncryptStatus; // @FIXME
1807             prAdapter->rWlanInfo.rCurrBssId.rRssi
1808                 = 0; //@FIXME
1809             prAdapter->rWlanInfo.rCurrBssId.eNetworkTypeInUse
1810                 = PARAM_NETWORK_TYPE_AUTOMODE; //@FIXME
1811             prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4BeaconPeriod
1812                 = prConnectionStatus->u2BeaconPeriod;
1813             prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4ATIMWindow
1814                 = prConnectionStatus->u2ATIMWindow;
1815             prAdapter->rWlanInfo.rCurrBssId.rConfiguration.u4DSConfig
1816                 = prConnectionStatus->u4FreqInKHz;
1817             prAdapter->rWlanInfo.ucNetworkType
1818                 = prConnectionStatus->ucNetworkType;
1819             prAdapter->rWlanInfo.rCurrBssId.eOpMode
1820                 = (ENUM_PARAM_OP_MODE_T) prConnectionStatus->ucInfraMode;
1821
1822             // always indicate to OS according to MSDN (re-association/roaming)
1823             if(kalGetMediaStateIndicated(prGlueInfo) != PARAM_MEDIA_STATE_CONNECTED) {
1824                 kalIndicateStatusAndComplete(prGlueInfo,
1825                         WLAN_STATUS_MEDIA_CONNECT,
1826                         NULL,
1827                         0);
1828             }
1829             else {
1830                 /* connected -> connected : roaming ? */
1831                 kalIndicateStatusAndComplete(prGlueInfo,
1832                         WLAN_STATUS_ROAM_OUT_FIND_BEST,
1833                         NULL,
1834                         0);
1835             }
1836         }
1837         break;
1838
1839 #if CFG_ENABLE_BT_OVER_WIFI
1840     case NETWORK_TYPE_BOW_INDEX:
1841         break;
1842 #endif
1843
1844 #if CFG_ENABLE_WIFI_DIRECT
1845     case NETWORK_TYPE_P2P_INDEX:
1846         break;
1847 #endif
1848     default:
1849         ASSERT(0);
1850     }
1851
1852     return WLAN_STATUS_SUCCESS;
1853 } /* nicMediaStateChange */
1854
1855 /*----------------------------------------------------------------------------*/
1856 /*!
1857 * @brief This utility function is used to convert between
1858 *        frequency and channel number
1859 *
1860 * @param u4ChannelNum
1861 *
1862 * @retval - Frequency in unit of KHz, 0 for invalid channel number
1863 */
1864 /*----------------------------------------------------------------------------*/
1865 UINT_32
1866 nicChannelNum2Freq (
1867     UINT_32 u4ChannelNum
1868     )
1869 {
1870     UINT_32 u4ChannelInMHz;
1871
1872     if(u4ChannelNum >= 1 && u4ChannelNum <= 13) {
1873         u4ChannelInMHz = 2412 + (u4ChannelNum - 1) * 5;
1874     }
1875     else if(u4ChannelNum == 14) {
1876         u4ChannelInMHz = 2484;
1877     }
1878     else if(u4ChannelNum == 133) {
1879         u4ChannelInMHz = 3665; // 802.11y
1880     }
1881     else if(u4ChannelNum == 137) {
1882         u4ChannelInMHz = 3685; // 802.11y
1883     }
1884     else if(u4ChannelNum >= 34 && u4ChannelNum <= 165) {
1885         u4ChannelInMHz = 5000 + u4ChannelNum * 5;
1886     }
1887     else if(u4ChannelNum >= 183 && u4ChannelNum <= 196) {
1888         u4ChannelInMHz = 4000 + u4ChannelNum * 5;
1889     }
1890     else {
1891         u4ChannelInMHz = 0;
1892     }
1893
1894     return 1000 * u4ChannelInMHz;
1895 }
1896
1897
1898 /*----------------------------------------------------------------------------*/
1899 /*!
1900 * @brief This utility function is used to convert between
1901 *        frequency and channel number
1902 *
1903 * @param u4FreqInKHz
1904 *
1905 * @retval - Frequency Number, 0 for invalid freqency
1906 */
1907 /*----------------------------------------------------------------------------*/
1908 UINT_32
1909 nicFreq2ChannelNum (
1910     UINT_32 u4FreqInKHz
1911     )
1912 {
1913     switch(u4FreqInKHz) {
1914     case 2412000:
1915         return 1;
1916     case 2417000:
1917         return 2;
1918     case 2422000:
1919         return 3;
1920     case 2427000:
1921         return 4;
1922     case 2432000:
1923         return 5;
1924     case 2437000:
1925         return 6;
1926     case 2442000:
1927         return 7;
1928     case 2447000:
1929         return 8;
1930     case 2452000:
1931         return 9;
1932     case 2457000:
1933         return 10;
1934     case 2462000:
1935         return 11;
1936     case 2467000:
1937         return 12;
1938     case 2472000:
1939         return 13;
1940     case 2484000:
1941         return 14;
1942     case 3665000:
1943         return 133; // 802.11y
1944     case 3685000:
1945         return 137; // 802.11y
1946     case 4915000:
1947         return 183;
1948     case 4920000:
1949         return 184;
1950     case 4925000:
1951         return 185;
1952     case 4930000:
1953         return 186;
1954     case 4935000:
1955         return 187;
1956     case 4940000:
1957         return 188;
1958     case 4945000:
1959         return 189;
1960     case 4960000:
1961         return 192;
1962     case 4980000:
1963         return 196;
1964     case 5170000:
1965         return 34;
1966     case 5180000:
1967         return 36;
1968     case 5190000:
1969         return 38;
1970     case 5200000:
1971         return 40;
1972     case 5210000:
1973         return 42;
1974     case 5220000:
1975         return 44;
1976     case 5230000:
1977         return 46;
1978     case 5240000:
1979         return 48;
1980     case 5250000:
1981         return 50;
1982     case 5260000:
1983         return 52;
1984     case 5270000:
1985         return 54;
1986     case 5280000:
1987         return 56;
1988     case 5290000:
1989         return 58;
1990     case 5300000:
1991         return 60;
1992     case 5320000:
1993         return 64;
1994     case 5500000:
1995         return 100;
1996     case 5520000:
1997         return 104;
1998     case 5540000:
1999         return 108;
2000     case 5560000:
2001         return 112;
2002     case 5580000:
2003         return 116;
2004     case 5600000:
2005         return 120;
2006     case 5620000:
2007         return 124;
2008     case 5640000:
2009         return 128;
2010     case 5660000:
2011         return 132;
2012     case 5680000:
2013         return 136;
2014     case 5700000:
2015         return 140;
2016     case 5745000:
2017         return 149;
2018     case 5765000:
2019         return 153;
2020     case 5785000:
2021         return 157;
2022     case 5805000:
2023         return 161;
2024     case 5825000:
2025         return 165;
2026     default:
2027         return 0;
2028     }
2029 }
2030
2031
2032 /* firmware command wrapper */
2033 /* NETWORK (WIFISYS) */
2034 /*----------------------------------------------------------------------------*/
2035 /*!
2036 * @brief This utility function is used to activate WIFISYS for specified network
2037 *
2038 * @param prAdapter          Pointer of ADAPTER_T
2039 *        eNetworkTypeIdx    Index of network type
2040 *
2041 * @retval -
2042 */
2043 /*----------------------------------------------------------------------------*/
2044 WLAN_STATUS
2045 nicActivateNetwork(
2046     IN P_ADAPTER_T prAdapter,
2047     IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx
2048     )
2049 {
2050     CMD_BSS_ACTIVATE_CTRL   rCmdActivateCtrl;
2051     P_BSS_INFO_T            prBssInfo;
2052
2053     ASSERT(prAdapter);
2054     ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM);
2055
2056     rCmdActivateCtrl.ucNetTypeIndex     = (UINT_8)eNetworkTypeIdx;
2057     rCmdActivateCtrl.ucActive           = 1;
2058
2059     if (((UINT_8) eNetworkTypeIdx) < NETWORK_TYPE_INDEX_NUM) {
2060         prBssInfo = &prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx];
2061         prBssInfo->fg40mBwAllowed = FALSE;
2062         prBssInfo->fgAssoc40mBwAllowed = FALSE;
2063     }
2064
2065     return wlanSendSetQueryCmd(prAdapter,
2066             CMD_ID_BSS_ACTIVATE_CTRL,
2067             TRUE,
2068             FALSE,
2069             FALSE,
2070             NULL,
2071             NULL,
2072             sizeof(CMD_BSS_ACTIVATE_CTRL),
2073             (PUINT_8)&rCmdActivateCtrl,
2074             NULL,
2075             0);
2076 }
2077
2078
2079 /*----------------------------------------------------------------------------*/
2080 /*!
2081 * @brief This utility function is used to deactivate WIFISYS for specified network
2082 *
2083 * @param prAdapter          Pointer of ADAPTER_T
2084 *        eNetworkTypeIdx    Index of network type
2085 *
2086 * @retval -
2087 */
2088 /*----------------------------------------------------------------------------*/
2089 WLAN_STATUS
2090 nicDeactivateNetwork(
2091     IN P_ADAPTER_T prAdapter,
2092     IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx
2093     )
2094 {
2095     WLAN_STATUS u4Status;
2096     CMD_BSS_ACTIVATE_CTRL rCmdActivateCtrl;
2097
2098     ASSERT(prAdapter);
2099     ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM);
2100
2101     rCmdActivateCtrl.ucNetTypeIndex     = (UINT_8)eNetworkTypeIdx;
2102     rCmdActivateCtrl.ucActive           = 0;
2103
2104     u4Status = wlanSendSetQueryCmd(prAdapter,
2105             CMD_ID_BSS_ACTIVATE_CTRL,
2106             TRUE,
2107             FALSE,
2108             FALSE,
2109             NULL,
2110             NULL,
2111             sizeof(CMD_BSS_ACTIVATE_CTRL),
2112             (PUINT_8)&rCmdActivateCtrl,
2113             NULL,
2114             0);
2115
2116     /* free all correlated station records */
2117     cnmStaFreeAllStaByNetType(prAdapter, eNetworkTypeIdx, FALSE);
2118     qmFreeAllByNetType(prAdapter, eNetworkTypeIdx);
2119     nicFreePendingTxMsduInfoByNetwork(prAdapter, eNetworkTypeIdx);
2120     kalClearSecurityFramesByNetType(prAdapter->prGlueInfo, eNetworkTypeIdx);
2121
2122     return u4Status;
2123 }
2124
2125
2126 /* BSS-INFO */
2127 /*----------------------------------------------------------------------------*/
2128 /*!
2129 * @brief This utility function is used to sync bss info with firmware
2130 *        when a new BSS has been connected or disconnected
2131 *
2132 * @param prAdapter          Pointer of ADAPTER_T
2133 *        eNetworkTypeIdx    Index of BSS-INFO type
2134 *
2135 * @retval -
2136 */
2137 /*----------------------------------------------------------------------------*/
2138 WLAN_STATUS
2139 nicUpdateBss(
2140     IN P_ADAPTER_T prAdapter,
2141     IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx
2142     )
2143 {
2144     WLAN_STATUS u4Status;
2145     P_BSS_INFO_T prBssInfo;
2146     CMD_SET_BSS_INFO rCmdSetBssInfo;
2147
2148     ASSERT(prAdapter);
2149     ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM);
2150
2151     prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]);
2152
2153     kalMemZero(&rCmdSetBssInfo, sizeof(CMD_SET_BSS_INFO));
2154
2155     rCmdSetBssInfo.ucNetTypeIndex               = (UINT_8)eNetworkTypeIdx;
2156     rCmdSetBssInfo.ucConnectionState            = (UINT_8)prBssInfo->eConnectionState;
2157     rCmdSetBssInfo.ucCurrentOPMode              = (UINT_8)prBssInfo->eCurrentOPMode;
2158     rCmdSetBssInfo.ucSSIDLen                    = (UINT_8)prBssInfo->ucSSIDLen;
2159     kalMemCopy(rCmdSetBssInfo.aucSSID, prBssInfo->aucSSID, prBssInfo->ucSSIDLen);
2160     COPY_MAC_ADDR(rCmdSetBssInfo.aucBSSID, prBssInfo->aucBSSID);
2161     rCmdSetBssInfo.ucIsQBSS                     = (UINT_8)prBssInfo->fgIsQBSS;
2162     rCmdSetBssInfo.ucNonHTBasicPhyType          = prBssInfo->ucNonHTBasicPhyType;
2163     rCmdSetBssInfo.u2OperationalRateSet         = prBssInfo->u2OperationalRateSet;
2164     rCmdSetBssInfo.u2BSSBasicRateSet            = prBssInfo->u2BSSBasicRateSet;
2165     rCmdSetBssInfo.ucPhyTypeSet                 = prBssInfo->ucPhyTypeSet;
2166         rCmdSetBssInfo.fgHiddenSsidMode             = prBssInfo->eHiddenSsidType;
2167 #if CFG_ENABLE_WIFI_DIRECT
2168     if(prAdapter->fgIsP2PRegistered) {
2169         COPY_MAC_ADDR(rCmdSetBssInfo.aucOwnMac, prBssInfo->aucOwnMacAddr);
2170     }
2171 #endif
2172
2173     rlmFillSyncCmdParam(&rCmdSetBssInfo.rBssRlmParam, prBssInfo);
2174
2175     rCmdSetBssInfo.fgWapiMode                   = (UINT_8)FALSE;
2176
2177     if(rCmdSetBssInfo.ucNetTypeIndex == NETWORK_TYPE_AIS_INDEX) {
2178         P_CONNECTION_SETTINGS_T prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
2179
2180         rCmdSetBssInfo.ucAuthMode               = (UINT_8)prConnSettings->eAuthMode;
2181         rCmdSetBssInfo.ucEncStatus              = (UINT_8)prConnSettings->eEncStatus;
2182         rCmdSetBssInfo.fgWapiMode               = (UINT_8)prConnSettings->fgWapiMode;
2183     }
2184 #if CFG_ENABLE_BT_OVER_WIFI
2185     else if(rCmdSetBssInfo.ucNetTypeIndex == NETWORK_TYPE_BOW_INDEX) {
2186         //P_CONNECTION_SETTINGS_T prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
2187         rCmdSetBssInfo.ucAuthMode               = (UINT_8)AUTH_MODE_WPA2_PSK;
2188         rCmdSetBssInfo.ucEncStatus              = (UINT_8)ENUM_ENCRYPTION3_KEY_ABSENT;
2189     }
2190 #endif
2191     else {
2192 #if CFG_ENABLE_WIFI_DIRECT
2193         if(prAdapter->fgIsP2PRegistered) {
2194             if (kalP2PGetCipher(prAdapter->prGlueInfo)) {
2195             rCmdSetBssInfo.ucAuthMode               = (UINT_8)AUTH_MODE_WPA2_PSK;
2196             rCmdSetBssInfo.ucEncStatus              = (UINT_8)ENUM_ENCRYPTION3_KEY_ABSENT;
2197             }
2198             else {
2199                 rCmdSetBssInfo.ucAuthMode               = (UINT_8)AUTH_MODE_OPEN;
2200                 rCmdSetBssInfo.ucEncStatus              = (UINT_8)ENUM_ENCRYPTION_DISABLED;
2201             }
2202                         /* Need the probe response to detect the PBC overlap */    
2203             rCmdSetBssInfo.fgIsApMode = p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo);
2204         }
2205 #else
2206         rCmdSetBssInfo.ucAuthMode               = (UINT_8)AUTH_MODE_WPA2_PSK;
2207         rCmdSetBssInfo.ucEncStatus              = (UINT_8)ENUM_ENCRYPTION3_KEY_ABSENT;
2208 #endif
2209     }
2210
2211     if(eNetworkTypeIdx == NETWORK_TYPE_AIS_INDEX &&
2212             prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE &&
2213             prBssInfo->prStaRecOfAP != NULL) {
2214         rCmdSetBssInfo.ucStaRecIdxOfAP          = prBssInfo->prStaRecOfAP->ucIndex;
2215
2216         cnmAisInfraConnectNotify(prAdapter);
2217     }
2218 #if CFG_ENABLE_WIFI_DIRECT
2219     else if ((prAdapter->fgIsP2PRegistered) &&
2220             (eNetworkTypeIdx == NETWORK_TYPE_P2P_INDEX) &&
2221             (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) &&
2222             (prBssInfo->prStaRecOfAP != NULL)) {
2223         rCmdSetBssInfo.ucStaRecIdxOfAP = prBssInfo->prStaRecOfAP->ucIndex;
2224     }
2225 #endif
2226
2227 #if CFG_ENABLE_BT_OVER_WIFI
2228     else if (eNetworkTypeIdx == NETWORK_TYPE_BOW_INDEX &&
2229             prBssInfo->eCurrentOPMode == OP_MODE_BOW &&
2230             prBssInfo->prStaRecOfAP != NULL) {
2231         rCmdSetBssInfo.ucStaRecIdxOfAP = prBssInfo->prStaRecOfAP->ucIndex;
2232     }
2233 #endif
2234     else {
2235         rCmdSetBssInfo.ucStaRecIdxOfAP              = STA_REC_INDEX_NOT_FOUND;
2236     }
2237
2238     u4Status = wlanSendSetQueryCmd(prAdapter,
2239             CMD_ID_SET_BSS_INFO,
2240             TRUE,
2241             FALSE,
2242             FALSE,
2243             NULL,
2244             NULL,
2245             sizeof(CMD_SET_BSS_INFO),
2246             (PUINT_8)&rCmdSetBssInfo,
2247             NULL,
2248             0);
2249
2250     /* if BSS-INFO is going to be disconnected state, free all correlated station records */
2251     if(prBssInfo->eConnectionState == PARAM_MEDIA_STATE_DISCONNECTED) {
2252         /* clear client list */
2253         bssClearClientList(prAdapter, prBssInfo);
2254
2255         /* free all correlated station records */
2256         cnmStaFreeAllStaByNetType(prAdapter, eNetworkTypeIdx, FALSE);
2257         qmFreeAllByNetType(prAdapter, eNetworkTypeIdx);
2258         kalClearSecurityFramesByNetType(prAdapter->prGlueInfo, eNetworkTypeIdx);
2259     }
2260
2261     return u4Status;
2262 }
2263
2264
2265 /* BSS-INFO Indication (PM) */
2266 /*----------------------------------------------------------------------------*/
2267 /*!
2268 * @brief This utility function is used to indicate PM that
2269 *        a BSS has been created. (for AdHoc / P2P-GO)
2270 *
2271 * @param prAdapter          Pointer of ADAPTER_T
2272 *        eNetworkTypeIdx    Index of BSS-INFO
2273 *
2274 * @retval -
2275 */
2276 /*----------------------------------------------------------------------------*/
2277 WLAN_STATUS
2278 nicPmIndicateBssCreated(
2279     IN P_ADAPTER_T prAdapter,
2280     IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx
2281     )
2282 {
2283     P_BSS_INFO_T prBssInfo;
2284     CMD_INDICATE_PM_BSS_CREATED rCmdIndicatePmBssCreated;
2285
2286     ASSERT(prAdapter);
2287     ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM);
2288
2289     prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]);
2290
2291     rCmdIndicatePmBssCreated.ucNetTypeIndex     = (UINT_8)eNetworkTypeIdx;
2292     rCmdIndicatePmBssCreated.ucDtimPeriod       = prBssInfo->ucDTIMPeriod;
2293     rCmdIndicatePmBssCreated.u2BeaconInterval   = prBssInfo->u2BeaconInterval;
2294     rCmdIndicatePmBssCreated.u2AtimWindow       = prBssInfo->u2ATIMWindow;
2295
2296     return wlanSendSetQueryCmd(prAdapter,
2297             CMD_ID_INDICATE_PM_BSS_CREATED,
2298             TRUE,
2299             FALSE,
2300             FALSE,
2301             NULL,
2302             NULL,
2303             sizeof(CMD_INDICATE_PM_BSS_CREATED),
2304             (PUINT_8)&rCmdIndicatePmBssCreated,
2305             NULL,
2306             0);
2307 }
2308
2309
2310 /*----------------------------------------------------------------------------*/
2311 /*!
2312 * @brief This utility function is used to indicate PM that
2313 *        a BSS has been connected
2314 *
2315 * @param prAdapter          Pointer of ADAPTER_T
2316 *        eNetworkTypeIdx    Index of BSS-INFO
2317 *
2318 * @retval -
2319 */
2320 /*----------------------------------------------------------------------------*/
2321 WLAN_STATUS
2322 nicPmIndicateBssConnected(
2323     IN P_ADAPTER_T prAdapter,
2324     IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx
2325     )
2326 {
2327     P_BSS_INFO_T prBssInfo;
2328     CMD_INDICATE_PM_BSS_CONNECTED rCmdIndicatePmBssConnected;
2329
2330     ASSERT(prAdapter);
2331     ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM);
2332
2333     prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]);
2334
2335     rCmdIndicatePmBssConnected.ucNetTypeIndex   = (UINT_8)eNetworkTypeIdx;
2336     rCmdIndicatePmBssConnected.ucDtimPeriod     = prBssInfo->ucDTIMPeriod;
2337     rCmdIndicatePmBssConnected.u2AssocId        = prBssInfo->u2AssocId;
2338     rCmdIndicatePmBssConnected.u2BeaconInterval = prBssInfo->u2BeaconInterval;
2339     rCmdIndicatePmBssConnected.u2AtimWindow     = prBssInfo->u2ATIMWindow;
2340
2341     rCmdIndicatePmBssConnected.ucBmpDeliveryAC  = prBssInfo->rPmProfSetupInfo.ucBmpDeliveryAC;
2342     rCmdIndicatePmBssConnected.ucBmpTriggerAC   = prBssInfo->rPmProfSetupInfo.ucBmpTriggerAC;
2343
2344     //DBGPRINTF("nicPmIndicateBssConnected: ucBmpDeliveryAC:0x%x, ucBmpTriggerAC:0x%x",
2345             //rCmdIndicatePmBssConnected.ucBmpDeliveryAC,
2346             //rCmdIndicatePmBssConnected.ucBmpTriggerAC);
2347
2348     if ((eNetworkTypeIdx == NETWORK_TYPE_AIS_INDEX)
2349 #if CFG_ENABLE_WIFI_DIRECT
2350         || ((eNetworkTypeIdx == NETWORK_TYPE_P2P_INDEX) && (prAdapter->fgIsP2PRegistered))
2351 #endif
2352          ) {
2353         if(prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) {
2354             rCmdIndicatePmBssConnected.fgIsUapsdConnection  = (UINT_8)prBssInfo->prStaRecOfAP->fgIsUapsdSupported;
2355         }
2356         else {
2357             rCmdIndicatePmBssConnected.fgIsUapsdConnection  = 0; //@FIXME
2358         }
2359     }
2360     else {
2361         rCmdIndicatePmBssConnected.fgIsUapsdConnection  = 0;
2362     }
2363
2364     return wlanSendSetQueryCmd(prAdapter,
2365             CMD_ID_INDICATE_PM_BSS_CONNECTED,
2366             TRUE,
2367             FALSE,
2368             FALSE,
2369             NULL,
2370             NULL,
2371             sizeof(CMD_INDICATE_PM_BSS_CONNECTED),
2372             (PUINT_8)&rCmdIndicatePmBssConnected,
2373             NULL,
2374             0);
2375 }
2376
2377
2378 /*----------------------------------------------------------------------------*/
2379 /*!
2380 * @brief This utility function is used to indicate PM that
2381 *        a BSS has been disconnected
2382 *
2383 * @param prAdapter          Pointer of ADAPTER_T
2384 *        eNetworkTypeIdx    Index of BSS-INFO
2385 *
2386 * @retval -
2387 */
2388 /*----------------------------------------------------------------------------*/
2389 WLAN_STATUS
2390 nicPmIndicateBssAbort(
2391     IN P_ADAPTER_T prAdapter,
2392     IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx
2393     )
2394 {
2395     CMD_INDICATE_PM_BSS_ABORT rCmdIndicatePmBssAbort;
2396
2397     ASSERT(prAdapter);
2398     ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM);
2399
2400     rCmdIndicatePmBssAbort.ucNetTypeIndex       = (UINT_8)eNetworkTypeIdx;
2401
2402     return wlanSendSetQueryCmd(prAdapter,
2403             CMD_ID_INDICATE_PM_BSS_ABORT,
2404             TRUE,
2405             FALSE,
2406             FALSE,
2407             NULL,
2408             NULL,
2409             sizeof(CMD_INDICATE_PM_BSS_ABORT),
2410             (PUINT_8)&rCmdIndicatePmBssAbort,
2411             NULL,
2412             0);
2413 }
2414
2415 WLAN_STATUS
2416 nicConfigPowerSaveProfile (
2417     IN  P_ADAPTER_T prAdapter,
2418     ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex,
2419     PARAM_POWER_MODE ePwrMode,
2420     BOOLEAN fgEnCmdEvent
2421     )
2422 {
2423     DEBUGFUNC("nicConfigPowerSaveProfile");
2424     DBGLOG(INIT, TRACE, ("eNetTypeIndex:%d, ePwrMode:%d, fgEnCmdEvent:%d\n",
2425                     eNetTypeIndex, ePwrMode, fgEnCmdEvent));
2426
2427     ASSERT(prAdapter);
2428
2429         if (eNetTypeIndex >= NETWORK_TYPE_INDEX_NUM) {
2430                 ASSERT(0);
2431                 return WLAN_STATUS_NOT_SUPPORTED;
2432         }
2433
2434 //    prAdapter->rWlanInfo.ePowerSaveMode.ucNetTypeIndex = eNetTypeIndex;
2435 //    prAdapter->rWlanInfo.ePowerSaveMode.ucPsProfile = (UINT_8)ePwrMode;
2436     prAdapter->rWlanInfo.arPowerSaveMode[eNetTypeIndex].ucNetTypeIndex = eNetTypeIndex;
2437     prAdapter->rWlanInfo.arPowerSaveMode[eNetTypeIndex].ucPsProfile = (UINT_8)ePwrMode;
2438
2439     return wlanSendSetQueryCmd(prAdapter,
2440             CMD_ID_POWER_SAVE_MODE,
2441             TRUE,
2442             FALSE,
2443             TRUE,
2444             (fgEnCmdEvent ? nicCmdEventSetCommon : NULL),
2445             (fgEnCmdEvent ? nicOidCmdTimeoutCommon : NULL),
2446             sizeof(CMD_PS_PROFILE_T),
2447             (PUINT_8)&(prAdapter->rWlanInfo.arPowerSaveMode[eNetTypeIndex]),
2448             NULL,
2449             sizeof(PARAM_POWER_MODE)
2450             );
2451
2452 } /* end of wlanoidSetAcpiDevicePowerStateMode() */
2453
2454 /*----------------------------------------------------------------------------*/
2455 /*!
2456 * @brief This utility function is used to indicate firmware domain
2457 *        for beacon generation parameters
2458 *
2459 * @param prAdapter          Pointer of ADAPTER_T
2460 *        eIeUpdMethod,      Update Method
2461 *        eNetTypeIndex      Index of Network
2462 *        u2Capability       Capability
2463 *        aucIe              Pointer to buffer of IEs
2464 *        u2IELen            Length of IEs
2465 *
2466 * @retval - WLAN_STATUS_SUCCESS
2467 *           WLAN_STATUS_FAILURE
2468 *           WLAN_STATUS_PENDING
2469 *           WLAN_STATUS_INVALID_DATA
2470 */
2471 /*----------------------------------------------------------------------------*/
2472 WLAN_STATUS
2473 nicUpdateBeaconIETemplate (
2474     IN P_ADAPTER_T prAdapter,
2475     IN ENUM_IE_UPD_METHOD_T eIeUpdMethod,
2476     IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex,
2477     IN UINT_16 u2Capability,
2478     IN PUINT_8 aucIe,
2479     IN UINT_16 u2IELen
2480     )
2481 {
2482     P_CMD_BEACON_TEMPLATE_UPDATE prCmdBcnUpdate;
2483     UINT_16 u2CmdBufLen = 0;
2484     P_GLUE_INFO_T prGlueInfo;
2485     P_CMD_INFO_T prCmdInfo;
2486     P_WIFI_CMD_T prWifiCmd;
2487     UINT_8 ucCmdSeqNum;
2488
2489     DEBUGFUNC("wlanUpdateBeaconIETemplate");
2490     DBGLOG(INIT, LOUD, ("\n"));
2491
2492
2493     ASSERT(prAdapter);
2494     prGlueInfo = prAdapter->prGlueInfo;
2495
2496     if (u2IELen > MAX_IE_LENGTH) {
2497         return WLAN_STATUS_INVALID_DATA;
2498     }
2499
2500     if (eIeUpdMethod == IE_UPD_METHOD_UPDATE_RANDOM
2501             || eIeUpdMethod == IE_UPD_METHOD_UPDATE_ALL) {
2502         u2CmdBufLen = OFFSET_OF(CMD_BEACON_TEMPLATE_UPDATE, aucIE) + u2IELen;
2503     }
2504     else if (eIeUpdMethod == IE_UPD_METHOD_DELETE_ALL) {
2505         u2CmdBufLen = OFFSET_OF(CMD_BEACON_TEMPLATE_UPDATE, u2IELen);
2506     }
2507     else {
2508         ASSERT(0);
2509         return WLAN_STATUS_FAILURE;
2510     }
2511
2512     // prepare command info
2513     prCmdInfo = cmdBufAllocateCmdInfo(prAdapter, (CMD_HDR_SIZE + u2CmdBufLen));
2514     if (!prCmdInfo) {
2515         DBGLOG(INIT, ERROR, ("Allocate CMD_INFO_T ==> FAILED.\n"));
2516         return WLAN_STATUS_FAILURE;
2517     }
2518
2519     // increase command sequence number
2520     ucCmdSeqNum = nicIncreaseCmdSeqNum(prAdapter);
2521     DBGLOG(REQ, TRACE, ("ucCmdSeqNum =%d\n", ucCmdSeqNum));
2522
2523     // Setup common CMD Info Packet
2524     prCmdInfo->eCmdType = COMMAND_TYPE_NETWORK_IOCTL;
2525     prCmdInfo->eNetworkType = eNetTypeIndex;
2526     prCmdInfo->u2InfoBufLen = (UINT_16)(CMD_HDR_SIZE + u2CmdBufLen);
2527     prCmdInfo->pfCmdDoneHandler = NULL;     //@FIXME
2528     prCmdInfo->pfCmdTimeoutHandler = NULL;  //@FIXME
2529     prCmdInfo->fgIsOid = FALSE;
2530     prCmdInfo->ucCID = CMD_ID_UPDATE_BEACON_CONTENT;
2531     prCmdInfo->fgSetQuery = TRUE;
2532     prCmdInfo->fgNeedResp = FALSE;
2533     prCmdInfo->fgDriverDomainMCR = FALSE;
2534     prCmdInfo->ucCmdSeqNum = ucCmdSeqNum;
2535     prCmdInfo->u4SetInfoLen = u2CmdBufLen;
2536     prCmdInfo->pvInformationBuffer = NULL;
2537     prCmdInfo->u4InformationBufferLength = 0;
2538
2539     // Setup WIFI_CMD_T (no payload)
2540     prWifiCmd = (P_WIFI_CMD_T)(prCmdInfo->pucInfoBuffer);
2541     prWifiCmd->u2TxByteCount_UserPriority = prCmdInfo->u2InfoBufLen;
2542     prWifiCmd->ucCID = prCmdInfo->ucCID;
2543     prWifiCmd->ucSetQuery = prCmdInfo->fgSetQuery;
2544     prWifiCmd->ucSeqNum = prCmdInfo->ucCmdSeqNum;
2545
2546     prCmdBcnUpdate = (P_CMD_BEACON_TEMPLATE_UPDATE)(prWifiCmd->aucBuffer);
2547
2548     // fill beacon updating command
2549     prCmdBcnUpdate->ucUpdateMethod  = (UINT_8) eIeUpdMethod;
2550     prCmdBcnUpdate->ucNetTypeIndex  = (UINT_8) eNetTypeIndex;
2551     prCmdBcnUpdate->u2Capability    = u2Capability;
2552     prCmdBcnUpdate->u2IELen         = u2IELen;
2553     if(u2IELen > 0 ) {
2554         kalMemCopy(prCmdBcnUpdate->aucIE, aucIe, u2IELen);
2555     }
2556
2557     // insert into prCmdQueue
2558     kalEnqueueCommand(prGlueInfo, (P_QUE_ENTRY_T)prCmdInfo);
2559
2560     // wakeup txServiceThread later
2561     GLUE_SET_EVENT(prGlueInfo);
2562     return WLAN_STATUS_PENDING;
2563 }
2564
2565
2566 /*----------------------------------------------------------------------------*/
2567 /*!
2568 * @brief This utility function is used to initialization PHY related
2569 *        varaibles
2570 *
2571 * @param prAdapter  Pointer of ADAPTER_T
2572 *
2573 * @retval none
2574 */
2575 /*----------------------------------------------------------------------------*/
2576 VOID
2577 nicSetAvailablePhyTypeSet (
2578     IN P_ADAPTER_T prAdapter
2579     )
2580 {
2581     P_CONNECTION_SETTINGS_T prConnSettings;
2582
2583     ASSERT(prAdapter);
2584
2585     prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
2586
2587     if (prConnSettings->eDesiredPhyConfig >= PHY_CONFIG_NUM) {
2588         ASSERT(0);
2589         return;
2590     }
2591
2592     prAdapter->rWifiVar.ucAvailablePhyTypeSet =
2593         aucPhyCfg2PhyTypeSet[prConnSettings->eDesiredPhyConfig];
2594
2595     if (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_BIT_ERP) {
2596         prAdapter->rWifiVar.eNonHTBasicPhyType2G4 = PHY_TYPE_ERP_INDEX;
2597     }
2598     /* NOTE(Kevin): Because we don't have N only mode, TBD */
2599     else /* if (ucNonHTPhyTypeSet & PHY_TYPE_HR_DSSS_INDEX) */ {
2600         prAdapter->rWifiVar.eNonHTBasicPhyType2G4 = PHY_TYPE_HR_DSSS_INDEX;
2601     }
2602
2603     return;
2604 }
2605
2606
2607 /*----------------------------------------------------------------------------*/
2608 /*!
2609 * @brief This utility function is used to update WMM Parms
2610 *
2611 * @param prAdapter          Pointer of ADAPTER_T
2612 *        eNetworkTypeIdx    Index of BSS-INFO
2613 *
2614 * @retval -
2615 */
2616 /*----------------------------------------------------------------------------*/
2617 WLAN_STATUS
2618 nicQmUpdateWmmParms(
2619     IN P_ADAPTER_T prAdapter,
2620     IN ENUM_NETWORK_TYPE_INDEX_T eNetworkTypeIdx
2621     )
2622 {
2623     P_BSS_INFO_T prBssInfo;
2624     CMD_UPDATE_WMM_PARMS_T rCmdUpdateWmmParms;
2625
2626     ASSERT(prAdapter);
2627     ASSERT(eNetworkTypeIdx < NETWORK_TYPE_INDEX_NUM);
2628
2629     DBGLOG(QM, EVENT, ("sizeof(AC_QUE_PARMS_T): %d \n", sizeof(AC_QUE_PARMS_T)));
2630     DBGLOG(QM, EVENT, ("sizeof(CMD_UPDATE_WMM_PARMS): %d \n", sizeof(CMD_UPDATE_WMM_PARMS_T)));
2631     DBGLOG(QM, EVENT, ("sizeof(WIFI_CMD_T): %d \n", sizeof(WIFI_CMD_T)));
2632
2633     prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetworkTypeIdx]);
2634     rCmdUpdateWmmParms.ucNetTypeIndex = (UINT_8)eNetworkTypeIdx;
2635     kalMemCopy(&rCmdUpdateWmmParms.arACQueParms[0], &prBssInfo->arACQueParms[0],
2636         (sizeof(AC_QUE_PARMS_T)*AC_NUM));
2637
2638     rCmdUpdateWmmParms.fgIsQBSS = prBssInfo->fgIsQBSS;
2639
2640     return wlanSendSetQueryCmd(prAdapter,
2641             CMD_ID_UPDATE_WMM_PARMS,
2642             TRUE,
2643             FALSE,
2644             FALSE,
2645             NULL,
2646             NULL,
2647             sizeof(CMD_UPDATE_WMM_PARMS_T),
2648             (PUINT_8)&rCmdUpdateWmmParms,
2649             NULL,
2650             0);
2651 }
2652
2653
2654 /*----------------------------------------------------------------------------*/
2655 /*!
2656 * @brief This utility function is used to update TX power gain corresponding to
2657 *        each band/modulation combination
2658 *
2659 * @param prAdapter          Pointer of ADAPTER_T
2660 *        prTxPwrParam       Pointer of TX power parameters
2661 *
2662 * @retval WLAN_STATUS_PENDING
2663 *         WLAN_STATUS_FAILURE
2664 */
2665 /*----------------------------------------------------------------------------*/
2666 WLAN_STATUS
2667 nicUpdateTxPower(
2668     IN P_ADAPTER_T      prAdapter,
2669     IN P_CMD_TX_PWR_T   prTxPwrParam
2670     )
2671 {
2672     DEBUGFUNC("nicUpdateTxPower");
2673
2674     ASSERT(prAdapter);
2675
2676     return wlanSendSetQueryCmd(prAdapter,
2677             CMD_ID_SET_TX_PWR,
2678             TRUE,
2679             FALSE,
2680             FALSE,
2681             NULL,
2682             NULL,
2683             sizeof(CMD_TX_PWR_T),
2684             (PUINT_8)prTxPwrParam,
2685             NULL,
2686             0);
2687 }
2688
2689 /*----------------------------------------------------------------------------*/
2690 /*!
2691 * @brief This utility function is used to set auto tx power parameter
2692 *
2693 * @param prAdapter          Pointer of ADAPTER_T
2694 *        prTxPwrParam       Pointer of Auto TX power parameters
2695 *
2696 * @retval WLAN_STATUS_PENDING
2697 *         WLAN_STATUS_FAILURE
2698 */
2699 /*----------------------------------------------------------------------------*/
2700 WLAN_STATUS
2701 nicSetAutoTxPower(
2702     IN P_ADAPTER_T      prAdapter,
2703     IN P_CMD_AUTO_POWER_PARAM_T   prAutoPwrParam
2704     )
2705 {
2706     DEBUGFUNC("nicSetAutoTxPower");
2707
2708     ASSERT(prAdapter);
2709
2710     return wlanSendSetQueryCmd(prAdapter,
2711             CMD_ID_SET_AUTOPWR_CTRL,
2712             TRUE,
2713             FALSE,
2714             FALSE,
2715             NULL,
2716             NULL,
2717             sizeof(CMD_AUTO_POWER_PARAM_T),
2718             (PUINT_8)prAutoPwrParam,
2719             NULL,
2720             0);
2721 }
2722
2723
2724 /*----------------------------------------------------------------------------*/
2725 /*!
2726 * @brief This utility function is used to update TX power gain corresponding to
2727 *        each band/modulation combination
2728 *
2729 * @param prAdapter          Pointer of ADAPTER_T
2730 *        prTxPwrParam       Pointer of TX power parameters
2731 *
2732 * @retval WLAN_STATUS_PENDING
2733 *         WLAN_STATUS_FAILURE
2734 */
2735 /*----------------------------------------------------------------------------*/
2736 WLAN_STATUS
2737 nicSetAutoTxPowerControl(
2738     IN P_ADAPTER_T      prAdapter,
2739     IN P_CMD_TX_PWR_T   prTxPwrParam
2740     )
2741 {
2742     DEBUGFUNC("nicUpdateTxPower");
2743
2744     ASSERT(prAdapter);
2745
2746     return wlanSendSetQueryCmd(prAdapter,
2747             CMD_ID_SET_TX_PWR,
2748             TRUE,
2749             FALSE,
2750             FALSE,
2751             NULL,
2752             NULL,
2753             sizeof(CMD_TX_PWR_T),
2754             (PUINT_8)prTxPwrParam,
2755             NULL,
2756             0);
2757 }
2758
2759
2760 /*----------------------------------------------------------------------------*/
2761 /*!
2762 * @brief This utility function is used to update power offset around 5GHz band
2763 *
2764 * @param prAdapter          Pointer of ADAPTER_T
2765 *        pr5GPwrOffset      Pointer of 5GHz power offset parameter
2766 *
2767 * @retval WLAN_STATUS_PENDING
2768 *         WLAN_STATUS_FAILURE
2769 */
2770 /*----------------------------------------------------------------------------*/
2771 WLAN_STATUS
2772 nicUpdate5GOffset(
2773     IN P_ADAPTER_T              prAdapter,
2774     IN P_CMD_5G_PWR_OFFSET_T    pr5GPwrOffset
2775     )
2776 {
2777     DEBUGFUNC("nicUpdate5GOffset");
2778
2779     ASSERT(prAdapter);
2780
2781     return wlanSendSetQueryCmd(prAdapter,
2782             CMD_ID_SET_5G_PWR_OFFSET,
2783             TRUE,
2784             FALSE,
2785             FALSE,
2786             NULL,
2787             NULL,
2788             sizeof(CMD_5G_PWR_OFFSET_T),
2789             (PUINT_8)pr5GPwrOffset,
2790             NULL,
2791             0);
2792 }
2793
2794
2795 /*----------------------------------------------------------------------------*/
2796 /*!
2797 * @brief This utility function is used to update DPD calibration result
2798 *
2799 * @param prAdapter          Pointer of ADAPTER_T
2800 *        pr5GPwrOffset      Pointer of parameter for DPD calibration result
2801 *
2802 * @retval WLAN_STATUS_PENDING
2803 *         WLAN_STATUS_FAILURE
2804 */
2805 /*----------------------------------------------------------------------------*/
2806 WLAN_STATUS
2807 nicUpdateDPD(
2808     IN P_ADAPTER_T          prAdapter,
2809     IN P_CMD_PWR_PARAM_T    prDpdCalResult
2810     )
2811 {
2812     DEBUGFUNC("nicUpdateDPD");
2813
2814     ASSERT(prAdapter);
2815
2816     return wlanSendSetQueryCmd(prAdapter,
2817             CMD_ID_SET_PWR_PARAM,
2818             TRUE,
2819             FALSE,
2820             FALSE,
2821             NULL,
2822             NULL,
2823             sizeof(CMD_PWR_PARAM_T),
2824             (PUINT_8)prDpdCalResult,
2825             NULL,
2826             0);
2827 }
2828
2829
2830 /*----------------------------------------------------------------------------*/
2831 /*!
2832 * @brief This utility function starts system service such as timer and
2833 *        memory pools
2834 *
2835 * @param prAdapter          Pointer of ADAPTER_T
2836 *
2837 * @retval none
2838 */
2839 /*----------------------------------------------------------------------------*/
2840 VOID
2841 nicInitSystemService (
2842     IN P_ADAPTER_T prAdapter
2843     )
2844 {
2845     ASSERT(prAdapter);
2846
2847     // <1> Initialize MGMT Memory pool and STA_REC
2848     cnmMemInit(prAdapter);
2849     cnmStaRecInit(prAdapter);
2850     cmdBufInitialize(prAdapter);
2851
2852     // <2> Mailbox Initialization
2853     mboxInitialize(prAdapter);
2854
2855     // <3> Timer Initialization
2856     cnmTimerInitialize(prAdapter);
2857
2858     return;
2859 }
2860
2861
2862 /*----------------------------------------------------------------------------*/
2863 /*!
2864 * @brief This utility function reset some specific system service,
2865 *        such as STA-REC
2866 *
2867 * @param prAdapter          Pointer of ADAPTER_T
2868 *
2869 * @retval none
2870 */
2871 /*----------------------------------------------------------------------------*/
2872 VOID
2873 nicResetSystemService (
2874     IN P_ADAPTER_T prAdapter
2875     )
2876 {
2877     ASSERT(prAdapter);
2878 }
2879
2880
2881 /*----------------------------------------------------------------------------*/
2882 /*!
2883 * @brief This utility function is used to update WMM Parms
2884 *
2885 * @param prAdapter          Pointer of ADAPTER_T
2886 *
2887 * @retval none
2888 */
2889 /*----------------------------------------------------------------------------*/
2890 VOID
2891 nicUninitSystemService (
2892     IN P_ADAPTER_T prAdapter
2893     )
2894 {
2895     ASSERT(prAdapter);
2896
2897     /* Timer Destruction */
2898     cnmTimerDestroy(prAdapter);
2899
2900     /* Mailbox Destruction */
2901     mboxDestroy(prAdapter);
2902
2903     return;
2904 }
2905
2906
2907 /*----------------------------------------------------------------------------*/
2908 /*!
2909 * @brief This utility function is used to update WMM Parms
2910 *
2911 * @param prAdapter          Pointer of ADAPTER_T
2912 *
2913 * @retval none
2914 */
2915 /*----------------------------------------------------------------------------*/
2916 VOID
2917 nicInitMGMT (
2918     IN P_ADAPTER_T prAdapter,
2919     IN P_REG_INFO_T prRegInfo
2920     )
2921 {
2922     ASSERT(prAdapter);
2923
2924     /* CNM Module - initialization */
2925     cnmInit(prAdapter);
2926
2927     /* RLM Module - initialization */
2928     rlmFsmEventInit(prAdapter);
2929
2930     /* SCN Module - initialization */
2931     scnInit(prAdapter);
2932
2933     /* AIS Module - intiailization */
2934     aisInitializeConnectionSettings(prAdapter, prRegInfo);
2935     aisFsmInit(prAdapter);
2936
2937 #if CFG_SUPPORT_ROAMING
2938     /* Roaming Module - intiailization */
2939     roamingFsmInit(prAdapter);
2940 #endif /* CFG_SUPPORT_ROAMING */
2941
2942 #if CFG_SUPPORT_SWCR
2943     swCrDebugInit(prAdapter);
2944 #endif /* CFG_SUPPORT_SWCR */
2945
2946     return;
2947 }
2948
2949
2950 /*----------------------------------------------------------------------------*/
2951 /*!
2952 * @brief This utility function is used to update WMM Parms
2953 *
2954 * @param prAdapter          Pointer of ADAPTER_T
2955 *
2956 * @retval none
2957 */
2958 /*----------------------------------------------------------------------------*/
2959 VOID
2960 nicUninitMGMT (
2961     IN P_ADAPTER_T prAdapter
2962     )
2963 {
2964     ASSERT(prAdapter);
2965
2966 #if CFG_SUPPORT_SWCR
2967     swCrDebugUninit(prAdapter);
2968 #endif /* CFG_SUPPORT_SWCR */
2969
2970 #if CFG_SUPPORT_ROAMING
2971     /* Roaming Module - unintiailization */
2972     roamingFsmUninit(prAdapter);
2973 #endif /* CFG_SUPPORT_ROAMING */
2974
2975     /* AIS Module - unintiailization */
2976     aisFsmUninit(prAdapter);
2977
2978     /* SCN Module - unintiailization */
2979     scnUninit(prAdapter);
2980
2981     /* RLM Module - uninitialization */
2982     rlmFsmEventUninit(prAdapter);
2983
2984     /* CNM Module - uninitialization */
2985     cnmUninit(prAdapter);
2986
2987     return;
2988 }
2989
2990
2991 #if (MT6620_E1_ASIC_HIFSYS_WORKAROUND == 1)
2992 /*----------------------------------------------------------------------------*/
2993 /*!
2994 * @brief This utility function is to inform firmware to enable MCU clock gating
2995 *
2996 * @param prAdapter          Pointer of ADAPTER_T
2997 *
2998 * @retval none
2999 */
3000 /*----------------------------------------------------------------------------*/
3001 WLAN_STATUS
3002 nicEnableClockGating (
3003     IN P_ADAPTER_T prAdapter
3004     )
3005 {
3006     UINT_32 i, u4WHISR = 0;
3007
3008     ASSERT(prAdapter);
3009
3010     if(prAdapter->fgIsClockGatingEnabled == TRUE) {
3011         return WLAN_STATUS_SUCCESS;
3012     }
3013     else {
3014         nicSetSwIntr(prAdapter, REQ_GATING_ENABLE_H2D_INT);
3015
3016         i = 0;
3017         while(i < GATING_CONTROL_POLL_LIMIT) {
3018             if(kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE
3019                     || fgIsBusAccessFailed == TRUE) {
3020                 return WLAN_STATUS_FAILURE;
3021             }
3022
3023             HAL_READ_INTR_STATUS(prAdapter, sizeof(UINT_32), (PUINT_8)&u4WHISR);
3024
3025             if(u4WHISR & ACK_GATING_ENABLE_D2H_INT) {
3026                 prAdapter->fgIsClockGatingEnabled = TRUE;
3027                 return WLAN_STATUS_SUCCESS;
3028             }
3029         }
3030
3031         ASSERT(0);
3032         return WLAN_STATUS_PENDING;
3033     }
3034 }
3035
3036
3037 /*----------------------------------------------------------------------------*/
3038 /*!
3039 * @brief This utility function is to inform firmware to disable MCU clock gating
3040 *
3041 * @param prAdapter          Pointer of ADAPTER_T
3042 *
3043 * @retval none
3044 */
3045 /*----------------------------------------------------------------------------*/
3046 WLAN_STATUS
3047 nicDisableClockGating (
3048     IN P_ADAPTER_T prAdapter
3049     )
3050 {
3051     UINT_32 i, u4WHISR = 0;
3052
3053     ASSERT(prAdapter);
3054
3055     if(prAdapter->fgIsClockGatingEnabled == FALSE) {
3056         return WLAN_STATUS_SUCCESS;
3057     }
3058     else {
3059         nicSetSwIntr(prAdapter, REQ_GATING_DISABLE_H2D_INT);
3060
3061         i = 0;
3062         while(i < GATING_CONTROL_POLL_LIMIT) {
3063             if(kalIsCardRemoved(prAdapter->prGlueInfo) == TRUE
3064                     || fgIsBusAccessFailed == TRUE) {
3065                 return WLAN_STATUS_FAILURE;
3066             }
3067
3068             HAL_READ_INTR_STATUS(prAdapter, sizeof(UINT_32), (PUINT_8)&u4WHISR);
3069
3070             if(u4WHISR & ACK_GATING_DISABLE_D2H_INT) {
3071                 prAdapter->fgIsClockGatingEnabled = FALSE;
3072                 return WLAN_STATUS_SUCCESS;
3073             }
3074         }
3075
3076         ASSERT(0);
3077         return WLAN_STATUS_PENDING;
3078     }
3079 }
3080 #endif
3081
3082
3083 /*----------------------------------------------------------------------------*/
3084 /*!
3085 * @brief This function is invoked to buffer scan result
3086 *
3087 * @param prAdapter          Pointer to the Adapter structure.
3088 * @param rMacAddr           BSSID
3089 * @param prSsid             Pointer to SSID
3090 * @param u4Privacy          Privacy settings (0: Open / 1: WEP/WPA/WPA2 enabled)
3091 * @param rRssi              Received Strength (-10 ~ -200 dBm)
3092 * @param eNetworkType       Network Type (a/b/g)
3093 * @param prConfiguration    Network Parameter
3094 * @param eOpMode            Infra/Ad-Hoc
3095 * @param rSupportedRates    Supported basic rates
3096 * @param u2IELength         IE Length
3097 * @param pucIEBuf           Pointer to Information Elements(IEs)
3098 *
3099 * @return (none)
3100 */
3101 /*----------------------------------------------------------------------------*/
3102 VOID
3103 nicAddScanResult (
3104     IN P_ADAPTER_T                  prAdapter,
3105     IN PARAM_MAC_ADDRESS            rMacAddr,
3106     IN P_PARAM_SSID_T               prSsid,
3107     IN UINT_32                      u4Privacy,
3108     IN PARAM_RSSI                   rRssi,
3109     IN ENUM_PARAM_NETWORK_TYPE_T    eNetworkType,
3110     IN P_PARAM_802_11_CONFIG_T      prConfiguration,
3111     IN ENUM_PARAM_OP_MODE_T         eOpMode,
3112     IN PARAM_RATES_EX               rSupportedRates,
3113     IN UINT_16                      u2IELength,
3114     IN PUINT_8                      pucIEBuf
3115     )
3116 {
3117     BOOLEAN bReplace;
3118     UINT_32 i;
3119     UINT_32 u4IdxWeakest = 0;
3120     PARAM_RSSI rWeakestRssi;
3121     UINT_32 u4BufferSize;
3122
3123     ASSERT(prAdapter);
3124
3125     rWeakestRssi = (PARAM_RSSI)INT_MAX;
3126     u4BufferSize = sizeof(prAdapter->rWlanInfo.aucScanIEBuf) / sizeof(prAdapter->rWlanInfo.aucScanIEBuf[0]);
3127
3128     bReplace = FALSE;
3129
3130     // decide to replace or add
3131     for(i = 0 ; i < prAdapter->rWlanInfo.u4ScanResultNum ; i++) {
3132         // find weakest entry && not connected one
3133         if(UNEQUAL_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, prAdapter->rWlanInfo.rCurrBssId.arMacAddress)
3134                 && prAdapter->rWlanInfo.arScanResult[i].rRssi < rWeakestRssi) {
3135             u4IdxWeakest = i;
3136             rWeakestRssi = prAdapter->rWlanInfo.arScanResult[i].rRssi;
3137         }
3138
3139         if(prAdapter->rWlanInfo.arScanResult[i].eOpMode == eOpMode &&
3140                 EQUAL_MAC_ADDR(&(prAdapter->rWlanInfo.arScanResult[i].arMacAddress), rMacAddr) &&
3141                     (EQUAL_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid,
3142                             prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen,
3143                             prSsid->aucSsid,
3144                             prSsid->u4SsidLen)
3145                      || prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen == 0)) {
3146             // replace entry
3147             bReplace = TRUE;
3148
3149             // free IE buffer then zero
3150             nicFreeScanResultIE(prAdapter, i);
3151             kalMemZero(&(prAdapter->rWlanInfo.arScanResult[i]), OFFSET_OF(PARAM_BSSID_EX_T, aucIEs));
3152
3153             // then fill buffer
3154             prAdapter->rWlanInfo.arScanResult[i].u4Length =
3155                 OFFSET_OF(PARAM_BSSID_EX_T, aucIEs) + u2IELength;
3156             COPY_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, rMacAddr);
3157             COPY_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid,
3158                     prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen,
3159                     prSsid->aucSsid,
3160                     prSsid->u4SsidLen);
3161             prAdapter->rWlanInfo.arScanResult[i].u4Privacy = u4Privacy;
3162             prAdapter->rWlanInfo.arScanResult[i].rRssi = rRssi;
3163             prAdapter->rWlanInfo.arScanResult[i].eNetworkTypeInUse = eNetworkType;
3164             kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[i].rConfiguration),
3165                     prConfiguration,
3166                     sizeof(PARAM_802_11_CONFIG_T));
3167             prAdapter->rWlanInfo.arScanResult[i].eOpMode = eOpMode;
3168             kalMemCopy((prAdapter->rWlanInfo.arScanResult[i].rSupportedRates),
3169                     rSupportedRates,
3170                     sizeof(PARAM_RATES_EX));
3171             prAdapter->rWlanInfo.arScanResult[i].u4IELength = (UINT_32)u2IELength;
3172
3173             // IE - allocate buffer and update pointer
3174             if(u2IELength > 0) {
3175                 if(ALIGN_4(u2IELength) + prAdapter->rWlanInfo.u4ScanIEBufferUsage <= u4BufferSize) {
3176                     kalMemCopy(&(prAdapter->rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]),
3177                             pucIEBuf,
3178                             u2IELength);
3179
3180                     prAdapter->rWlanInfo.apucScanResultIEs[i] =
3181                         &(prAdapter->rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]);
3182
3183                     prAdapter->rWlanInfo.u4ScanIEBufferUsage += ALIGN_4(u2IELength);
3184                 }
3185                 else {
3186                     // buffer is not enough
3187                     prAdapter->rWlanInfo.arScanResult[i].u4Length -= u2IELength;
3188                     prAdapter->rWlanInfo.arScanResult[i].u4IELength = 0;
3189                     prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL;
3190                 }
3191             }
3192             else {
3193                 prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL;
3194             }
3195
3196             break;
3197         }
3198     }
3199
3200     if (bReplace == FALSE) {
3201         if (prAdapter->rWlanInfo.u4ScanResultNum < (CFG_MAX_NUM_BSS_LIST - 1)) {
3202             i = prAdapter->rWlanInfo.u4ScanResultNum;
3203
3204             // zero
3205             kalMemZero(&(prAdapter->rWlanInfo.arScanResult[i]),
3206                     OFFSET_OF(PARAM_BSSID_EX_T, aucIEs));
3207
3208             // then fill buffer
3209             prAdapter->rWlanInfo.arScanResult[i].u4Length =
3210                 OFFSET_OF(PARAM_BSSID_EX_T, aucIEs) + u2IELength;
3211             COPY_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, rMacAddr);
3212             COPY_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid,
3213                     prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen,
3214                     prSsid->aucSsid,
3215                     prSsid->u4SsidLen);
3216             prAdapter->rWlanInfo.arScanResult[i].u4Privacy = u4Privacy;
3217             prAdapter->rWlanInfo.arScanResult[i].rRssi = rRssi;
3218             prAdapter->rWlanInfo.arScanResult[i].eNetworkTypeInUse = eNetworkType;
3219             kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[i].rConfiguration),
3220                     prConfiguration,
3221                     sizeof(PARAM_802_11_CONFIG_T));
3222             prAdapter->rWlanInfo.arScanResult[i].eOpMode = eOpMode;
3223             kalMemCopy((prAdapter->rWlanInfo.arScanResult[i].rSupportedRates),
3224                     rSupportedRates,
3225                     sizeof(PARAM_RATES_EX));
3226             prAdapter->rWlanInfo.arScanResult[i].u4IELength = (UINT_32)u2IELength;
3227
3228             // IE - allocate buffer and update pointer
3229             if(u2IELength > 0) {
3230                 if(ALIGN_4(u2IELength) + prAdapter->rWlanInfo.u4ScanIEBufferUsage <= u4BufferSize) {
3231                     kalMemCopy(&(prAdapter->rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]),
3232                             pucIEBuf,
3233                             u2IELength);
3234
3235                     prAdapter->rWlanInfo.apucScanResultIEs[i] =
3236                         &(prAdapter->rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]);
3237
3238                     prAdapter->rWlanInfo.u4ScanIEBufferUsage += ALIGN_4(u2IELength);
3239                 }
3240                 else {
3241                     // buffer is not enough
3242                     prAdapter->rWlanInfo.arScanResult[i].u4Length -= u2IELength;
3243                     prAdapter->rWlanInfo.arScanResult[i].u4IELength = 0;
3244                     prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL;
3245                 }
3246             }
3247             else {
3248                 prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL;
3249             }
3250
3251             prAdapter->rWlanInfo.u4ScanResultNum++;
3252         }
3253         else if(rWeakestRssi != (PARAM_RSSI)INT_MAX) {
3254             // replace weakest one
3255             i = u4IdxWeakest;
3256
3257             // free IE buffer then zero
3258             nicFreeScanResultIE(prAdapter, i);
3259             kalMemZero(&(prAdapter->rWlanInfo.arScanResult[i]),
3260                     OFFSET_OF(PARAM_BSSID_EX_T, aucIEs));
3261
3262             // then fill buffer
3263             prAdapter->rWlanInfo.arScanResult[i].u4Length =
3264                 OFFSET_OF(PARAM_BSSID_EX_T, aucIEs) + u2IELength;
3265             COPY_MAC_ADDR(prAdapter->rWlanInfo.arScanResult[i].arMacAddress, rMacAddr);
3266             COPY_SSID(prAdapter->rWlanInfo.arScanResult[i].rSsid.aucSsid,
3267                     prAdapter->rWlanInfo.arScanResult[i].rSsid.u4SsidLen,
3268                     prSsid->aucSsid,
3269                     prSsid->u4SsidLen);
3270             prAdapter->rWlanInfo.arScanResult[i].u4Privacy = u4Privacy;
3271             prAdapter->rWlanInfo.arScanResult[i].rRssi = rRssi;
3272             prAdapter->rWlanInfo.arScanResult[i].eNetworkTypeInUse = eNetworkType;
3273             kalMemCopy(&(prAdapter->rWlanInfo.arScanResult[i].rConfiguration),
3274                     prConfiguration,
3275                     sizeof(PARAM_802_11_CONFIG_T));
3276             prAdapter->rWlanInfo.arScanResult[i].eOpMode = eOpMode;
3277             kalMemCopy((prAdapter->rWlanInfo.arScanResult[i].rSupportedRates),
3278                     rSupportedRates,
3279                     sizeof(PARAM_RATES_EX));
3280             prAdapter->rWlanInfo.arScanResult[i].u4IELength = (UINT_32)u2IELength;
3281
3282             if(u2IELength > 0) {
3283                 // IE - allocate buffer and update pointer
3284                 if(ALIGN_4(u2IELength) + prAdapter->rWlanInfo.u4ScanIEBufferUsage <= u4BufferSize) {
3285                     kalMemCopy(&(prAdapter->rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]),
3286                             pucIEBuf,
3287                             u2IELength);
3288
3289                     prAdapter->rWlanInfo.apucScanResultIEs[i] =
3290                         &(prAdapter->rWlanInfo.aucScanIEBuf[prAdapter->rWlanInfo.u4ScanIEBufferUsage]);
3291
3292                     prAdapter->rWlanInfo.u4ScanIEBufferUsage += ALIGN_4(u2IELength);
3293                 }
3294                 else {
3295                     // buffer is not enough
3296                     prAdapter->rWlanInfo.arScanResult[i].u4Length -= u2IELength;
3297                     prAdapter->rWlanInfo.arScanResult[i].u4IELength = 0;
3298                     prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL;
3299                 }
3300             }
3301             else {
3302                 prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL;
3303             }
3304         }
3305     }
3306 }
3307
3308
3309 /*----------------------------------------------------------------------------*/
3310 /*!
3311 * @brief This function is invoked to free IE buffer for dedicated scan result
3312 *
3313 * @param prAdapter          Pointer to the Adapter structure.
3314 * @param u4Idx              Index of Scan Result
3315 *
3316 * @return (none)
3317 */
3318 /*----------------------------------------------------------------------------*/
3319 VOID
3320 nicFreeScanResultIE (
3321     IN P_ADAPTER_T  prAdapter,
3322     IN UINT_32      u4Idx
3323     )
3324 {
3325     UINT_32 i;
3326     PUINT_8 pucPivot, pucMovePivot;
3327     UINT_32 u4MoveSize, u4FreeSize, u4ReserveSize;
3328
3329     ASSERT(prAdapter);
3330     ASSERT(u4Idx < CFG_MAX_NUM_BSS_LIST);
3331
3332     if(prAdapter->rWlanInfo.arScanResult[u4Idx].u4IELength == 0
3333             || prAdapter->rWlanInfo.apucScanResultIEs[u4Idx] == NULL) {
3334         return;
3335     }
3336
3337     u4FreeSize = ALIGN_4(prAdapter->rWlanInfo.arScanResult[u4Idx].u4IELength);
3338
3339     pucPivot = prAdapter->rWlanInfo.apucScanResultIEs[u4Idx];
3340     pucMovePivot = (PUINT_8)((UINT_32)(prAdapter->rWlanInfo.apucScanResultIEs[u4Idx]) + u4FreeSize);
3341
3342     u4ReserveSize = ((UINT_32)pucPivot) - (UINT_32)(&(prAdapter->rWlanInfo.aucScanIEBuf[0]));
3343     u4MoveSize = prAdapter->rWlanInfo.u4ScanIEBufferUsage - u4ReserveSize - u4FreeSize;
3344
3345     // 1. rest of buffer to move forward
3346     kalMemCopy(pucPivot, pucMovePivot, u4MoveSize);
3347
3348     // 1.1 modify pointers
3349     for(i = 0 ; i < prAdapter->rWlanInfo.u4ScanResultNum ; i++) {
3350         if(i != u4Idx) {
3351             if(prAdapter->rWlanInfo.apucScanResultIEs[i] >= pucMovePivot) {
3352                 prAdapter->rWlanInfo.apucScanResultIEs[i] =
3353                     (PUINT_8)((UINT_32)(prAdapter->rWlanInfo.apucScanResultIEs[i]) - u4FreeSize);
3354             }
3355         }
3356     }
3357
3358     // 1.2 reset the freed one
3359     prAdapter->rWlanInfo.arScanResult[u4Idx].u4IELength = 0;
3360     prAdapter->rWlanInfo.apucScanResultIEs[i] = NULL;
3361
3362     // 2. reduce IE buffer usage
3363     prAdapter->rWlanInfo.u4ScanIEBufferUsage -= u4FreeSize;
3364
3365     return;
3366 }
3367
3368
3369 /*----------------------------------------------------------------------------*/
3370 /*!
3371 * @brief This function is to hack parameters for WLAN TABLE for
3372 *        fixed rate settings
3373 *
3374 * @param prAdapter          Pointer to the Adapter structure.
3375 * @param eRateSetting
3376 * @param pu2DesiredNonHTRateSet,
3377 * @param pu2BSSBasicRateSet,
3378 * @param pucMcsSet
3379 * @param pucSupMcs32
3380 * @param pu2HtCapInfo
3381 *
3382 * @return WLAN_STATUS_SUCCESS
3383 */
3384 /*----------------------------------------------------------------------------*/
3385 WLAN_STATUS
3386 nicUpdateRateParams (
3387     IN P_ADAPTER_T                  prAdapter,
3388     IN ENUM_REGISTRY_FIXED_RATE_T   eRateSetting,
3389     IN PUINT_8                      pucDesiredPhyTypeSet,
3390     IN PUINT_16                     pu2DesiredNonHTRateSet,
3391     IN PUINT_16                     pu2BSSBasicRateSet,
3392     IN PUINT_8                      pucMcsSet,
3393     IN PUINT_8                      pucSupMcs32,
3394     IN PUINT_16                     pu2HtCapInfo
3395     )
3396 {
3397     ASSERT(prAdapter);
3398     ASSERT(eRateSetting > FIXED_RATE_NONE && eRateSetting < FIXED_RATE_NUM);
3399
3400     switch(prAdapter->rWifiVar.eRateSetting) {
3401     case FIXED_RATE_1M:
3402         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS;
3403         *pu2DesiredNonHTRateSet = RATE_SET_BIT_1M;
3404         *pu2BSSBasicRateSet = RATE_SET_BIT_1M;
3405         *pucMcsSet = 0;
3406         *pucSupMcs32 = 0;
3407         *pu2HtCapInfo = 0;
3408         break;
3409
3410     case FIXED_RATE_2M:
3411         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS;
3412         *pu2DesiredNonHTRateSet = RATE_SET_BIT_2M;
3413         *pu2BSSBasicRateSet = RATE_SET_BIT_2M;
3414         *pucMcsSet = 0;
3415         *pucSupMcs32 = 0;
3416         *pu2HtCapInfo = 0;
3417         break;
3418
3419     case FIXED_RATE_5_5M:
3420         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS;
3421         *pu2DesiredNonHTRateSet = RATE_SET_BIT_5_5M;
3422         *pu2BSSBasicRateSet = RATE_SET_BIT_5_5M;
3423         *pucMcsSet = 0;
3424         *pucSupMcs32 = 0;
3425         *pu2HtCapInfo = 0;
3426         break;
3427
3428     case FIXED_RATE_11M:
3429         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HR_DSSS;
3430         *pu2DesiredNonHTRateSet = RATE_SET_BIT_11M;
3431         *pu2BSSBasicRateSet = RATE_SET_BIT_11M;
3432         *pucMcsSet = 0;
3433         *pucSupMcs32 = 0;
3434         *pu2HtCapInfo = 0;
3435         break;
3436
3437     case FIXED_RATE_6M:
3438         if((*pucDesiredPhyTypeSet) | PHY_TYPE_BIT_ERP) {
3439             *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP;
3440         }
3441         else if((*pucDesiredPhyTypeSet) | PHY_TYPE_BIT_OFDM) {
3442             *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM;
3443         }
3444
3445         *pu2DesiredNonHTRateSet = RATE_SET_BIT_6M;
3446         *pu2BSSBasicRateSet = RATE_SET_BIT_6M;
3447         *pucMcsSet = 0;
3448         *pucSupMcs32 = 0;
3449         *pu2HtCapInfo = 0;
3450         break;
3451
3452     case FIXED_RATE_9M:
3453         if((*pucDesiredPhyTypeSet) | PHY_TYPE_BIT_ERP) {
3454             *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP;
3455         }
3456         else if((*pucDesiredPhyTypeSet) | PHY_TYPE_BIT_OFDM) {
3457             *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM;
3458         }
3459
3460         *pu2DesiredNonHTRateSet = RATE_SET_BIT_9M;
3461         *pu2BSSBasicRateSet = RATE_SET_BIT_9M;
3462         *pucMcsSet = 0;
3463         *pucSupMcs32 = 0;
3464         *pu2HtCapInfo = 0;
3465         break;
3466
3467     case FIXED_RATE_12M:
3468         if((*pucDesiredPhyTypeSet) | PHY_TYPE_BIT_ERP) {
3469             *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP;
3470         }
3471         else if((*pucDesiredPhyTypeSet) | PHY_TYPE_BIT_OFDM) {
3472             *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM;
3473         }
3474
3475         *pu2DesiredNonHTRateSet = RATE_SET_BIT_12M;
3476         *pu2BSSBasicRateSet = RATE_SET_BIT_12M;
3477         *pucMcsSet = 0;
3478         *pucSupMcs32 = 0;
3479         *pu2HtCapInfo = 0;
3480         break;
3481
3482     case FIXED_RATE_18M:
3483         if((*pucDesiredPhyTypeSet) | PHY_TYPE_BIT_ERP) {
3484             *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP;
3485         }
3486         else if((*pucDesiredPhyTypeSet) | PHY_TYPE_BIT_OFDM) {
3487             *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM;
3488         }
3489
3490         *pu2DesiredNonHTRateSet = RATE_SET_BIT_18M;
3491         *pu2BSSBasicRateSet = RATE_SET_BIT_18M;
3492         *pucMcsSet = 0;
3493         *pucSupMcs32 = 0;
3494         *pu2HtCapInfo = 0;
3495         break;
3496
3497     case FIXED_RATE_24M:
3498         if((*pucDesiredPhyTypeSet) | PHY_TYPE_BIT_ERP) {
3499             *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP;
3500         }
3501         else if((*pucDesiredPhyTypeSet) | PHY_TYPE_BIT_OFDM) {
3502             *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM;
3503         }
3504
3505         *pu2DesiredNonHTRateSet = RATE_SET_BIT_24M;
3506         *pu2BSSBasicRateSet = RATE_SET_BIT_24M;
3507         *pucMcsSet = 0;
3508         *pucSupMcs32 = 0;
3509         *pu2HtCapInfo = 0;
3510         break;
3511
3512     case FIXED_RATE_36M:
3513         if((*pucDesiredPhyTypeSet) | PHY_TYPE_BIT_ERP) {
3514             *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP;
3515         }
3516         else if((*pucDesiredPhyTypeSet) | PHY_TYPE_BIT_OFDM) {
3517             *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM;
3518         }
3519
3520         *pu2DesiredNonHTRateSet = RATE_SET_BIT_36M;
3521         *pu2BSSBasicRateSet = RATE_SET_BIT_36M;
3522         *pucMcsSet = 0;
3523         *pucSupMcs32 = 0;
3524         *pu2HtCapInfo = 0;
3525         break;
3526
3527     case FIXED_RATE_48M:
3528         if((*pucDesiredPhyTypeSet) | PHY_TYPE_BIT_ERP) {
3529             *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP;
3530         }
3531         else if((*pucDesiredPhyTypeSet) | PHY_TYPE_BIT_OFDM) {
3532             *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM;
3533         }
3534
3535         *pu2DesiredNonHTRateSet = RATE_SET_BIT_48M;
3536         *pu2BSSBasicRateSet = RATE_SET_BIT_48M;
3537         *pucMcsSet = 0;
3538         *pucSupMcs32 = 0;
3539         *pu2HtCapInfo = 0;
3540         break;
3541
3542     case FIXED_RATE_54M:
3543         if((*pucDesiredPhyTypeSet) | PHY_TYPE_BIT_ERP) {
3544             *pucDesiredPhyTypeSet = PHY_TYPE_BIT_ERP;
3545         }
3546         else if((*pucDesiredPhyTypeSet) | PHY_TYPE_BIT_OFDM) {
3547             *pucDesiredPhyTypeSet = PHY_TYPE_BIT_OFDM;
3548         }
3549
3550         *pu2DesiredNonHTRateSet = RATE_SET_BIT_54M;
3551         *pu2BSSBasicRateSet = RATE_SET_BIT_54M;
3552         *pucMcsSet = 0;
3553         *pucSupMcs32 = 0;
3554         *pu2HtCapInfo = 0;
3555         break;
3556
3557     case FIXED_RATE_MCS0_20M_800NS:
3558         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3559         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3560         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3561         *pucMcsSet = HT_RATE_MCS0_INDEX;
3562         *pucSupMcs32 = 0;
3563         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH
3564                 | HT_CAP_INFO_SHORT_GI_20M
3565                 | HT_CAP_INFO_SHORT_GI_40M
3566                 | HT_CAP_INFO_HT_GF);
3567         break;
3568
3569     case FIXED_RATE_MCS1_20M_800NS:
3570         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3571         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3572         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3573         *pucMcsSet = HT_RATE_MCS1_INDEX;
3574         *pucSupMcs32 = 0;
3575         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH
3576                 | HT_CAP_INFO_SHORT_GI_20M
3577                 | HT_CAP_INFO_SHORT_GI_40M
3578                 | HT_CAP_INFO_HT_GF);
3579         break;
3580
3581     case FIXED_RATE_MCS2_20M_800NS:
3582         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3583         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3584         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3585         *pucMcsSet = HT_RATE_MCS2_INDEX;
3586         *pucSupMcs32 = 0;
3587         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH
3588                 | HT_CAP_INFO_SHORT_GI_20M
3589                 | HT_CAP_INFO_SHORT_GI_40M
3590                 | HT_CAP_INFO_HT_GF);
3591         break;
3592
3593     case FIXED_RATE_MCS3_20M_800NS:
3594         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3595         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3596         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3597         *pucMcsSet = HT_RATE_MCS3_INDEX;
3598         *pucSupMcs32 = 0;
3599         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH
3600                 | HT_CAP_INFO_SHORT_GI_20M
3601                 | HT_CAP_INFO_SHORT_GI_40M
3602                 | HT_CAP_INFO_HT_GF);
3603         break;
3604
3605     case FIXED_RATE_MCS4_20M_800NS:
3606         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3607         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3608         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3609         *pucMcsSet = HT_RATE_MCS4_INDEX;
3610         *pucSupMcs32 = 0;
3611         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH
3612                 | HT_CAP_INFO_SHORT_GI_20M
3613                 | HT_CAP_INFO_SHORT_GI_40M
3614                 | HT_CAP_INFO_HT_GF);
3615         break;
3616
3617     case FIXED_RATE_MCS5_20M_800NS:
3618         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3619         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3620         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3621         *pucMcsSet = HT_RATE_MCS5_INDEX;
3622         *pucSupMcs32 = 0;
3623         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH
3624                 | HT_CAP_INFO_SHORT_GI_20M
3625                 | HT_CAP_INFO_SHORT_GI_40M
3626                 | HT_CAP_INFO_HT_GF);
3627         break;
3628
3629     case FIXED_RATE_MCS6_20M_800NS:
3630         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3631         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3632         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3633         *pucMcsSet = HT_RATE_MCS6_INDEX;
3634         *pucSupMcs32 = 0;
3635         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH
3636                 | HT_CAP_INFO_SHORT_GI_20M
3637                 | HT_CAP_INFO_SHORT_GI_40M
3638                 | HT_CAP_INFO_HT_GF);
3639         break;
3640
3641     case FIXED_RATE_MCS7_20M_800NS:
3642         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3643         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3644         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3645         *pucMcsSet = HT_RATE_MCS7_INDEX;
3646         *pucSupMcs32 = 0;
3647         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH
3648                 | HT_CAP_INFO_SHORT_GI_20M
3649                 | HT_CAP_INFO_SHORT_GI_40M
3650                 | HT_CAP_INFO_HT_GF);
3651         break;
3652
3653     case FIXED_RATE_MCS0_20M_400NS:
3654         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3655         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3656         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3657         *pucMcsSet = HT_RATE_MCS0_INDEX;
3658         *pucSupMcs32 = 0;
3659         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH
3660                 | HT_CAP_INFO_SHORT_GI_40M
3661                 | HT_CAP_INFO_HT_GF);
3662         (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M;
3663         break;
3664
3665     case FIXED_RATE_MCS1_20M_400NS:
3666         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3667         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3668         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3669         *pucMcsSet = HT_RATE_MCS1_INDEX;
3670         *pucSupMcs32 = 0;
3671         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH
3672                 | HT_CAP_INFO_SHORT_GI_40M
3673                 | HT_CAP_INFO_HT_GF);
3674         (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M;
3675         break;
3676
3677     case FIXED_RATE_MCS2_20M_400NS:
3678         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3679         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3680         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3681         *pucMcsSet = HT_RATE_MCS2_INDEX;
3682         *pucSupMcs32 = 0;
3683         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH
3684                 | HT_CAP_INFO_SHORT_GI_40M
3685                 | HT_CAP_INFO_HT_GF);
3686         (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M;
3687         break;
3688
3689     case FIXED_RATE_MCS3_20M_400NS:
3690         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3691         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3692         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3693         *pucMcsSet = HT_RATE_MCS3_INDEX;
3694         *pucSupMcs32 = 0;
3695         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH
3696                 | HT_CAP_INFO_SHORT_GI_40M
3697                 | HT_CAP_INFO_HT_GF);
3698         (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M;
3699         break;
3700
3701     case FIXED_RATE_MCS4_20M_400NS:
3702         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3703         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3704         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3705         *pucMcsSet = HT_RATE_MCS4_INDEX;
3706         *pucSupMcs32 = 0;
3707         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH
3708                 | HT_CAP_INFO_SHORT_GI_40M
3709                 | HT_CAP_INFO_HT_GF);
3710         (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M;
3711         break;
3712
3713     case FIXED_RATE_MCS5_20M_400NS:
3714         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3715         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3716         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3717         *pucMcsSet = HT_RATE_MCS5_INDEX;
3718         *pucSupMcs32 = 0;
3719         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH
3720                 | HT_CAP_INFO_SHORT_GI_40M
3721                 | HT_CAP_INFO_HT_GF);
3722         (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M;
3723         break;
3724
3725     case FIXED_RATE_MCS6_20M_400NS:
3726         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3727         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3728         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3729         *pucMcsSet = HT_RATE_MCS6_INDEX;
3730         *pucSupMcs32 = 0;
3731         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH
3732                 | HT_CAP_INFO_SHORT_GI_40M
3733                 | HT_CAP_INFO_HT_GF);
3734         (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M;
3735         break;
3736
3737     case FIXED_RATE_MCS7_20M_400NS:
3738         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3739         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3740         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3741         *pucMcsSet = HT_RATE_MCS7_INDEX;
3742         *pucSupMcs32 = 0;
3743         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SUP_CHNL_WIDTH
3744                 | HT_CAP_INFO_SHORT_GI_40M
3745                 | HT_CAP_INFO_HT_GF);
3746         (*pu2HtCapInfo) |= HT_CAP_INFO_SHORT_GI_20M;
3747         break;
3748
3749     case FIXED_RATE_MCS0_40M_800NS:
3750         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3751         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3752         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3753         *pucMcsSet = HT_RATE_MCS0_INDEX;
3754         *pucSupMcs32 = 0;
3755         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M
3756                 | HT_CAP_INFO_SHORT_GI_40M
3757                 | HT_CAP_INFO_HT_GF);
3758         (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH;
3759         break;
3760
3761     case FIXED_RATE_MCS1_40M_800NS:
3762         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3763         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3764         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3765         *pucMcsSet = HT_RATE_MCS1_INDEX;
3766         *pucSupMcs32 = 0;
3767         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M
3768                 | HT_CAP_INFO_SHORT_GI_40M
3769                 | HT_CAP_INFO_HT_GF);
3770         (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH;
3771         break;
3772
3773     case FIXED_RATE_MCS2_40M_800NS:
3774         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3775         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3776         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3777         *pucMcsSet = HT_RATE_MCS2_INDEX;
3778         *pucSupMcs32 = 0;
3779         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M
3780                 | HT_CAP_INFO_SHORT_GI_40M
3781                 | HT_CAP_INFO_HT_GF);
3782         (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH;
3783         break;
3784
3785     case FIXED_RATE_MCS3_40M_800NS:
3786         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3787         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3788         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3789         *pucMcsSet = HT_RATE_MCS3_INDEX;
3790         *pucSupMcs32 = 0;
3791         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M
3792                 | HT_CAP_INFO_SHORT_GI_40M
3793                 | HT_CAP_INFO_HT_GF);
3794         (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH;
3795         break;
3796
3797     case FIXED_RATE_MCS4_40M_800NS:
3798         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3799         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3800         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3801         *pucMcsSet = HT_RATE_MCS4_INDEX;
3802         *pucSupMcs32 = 0;
3803         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M
3804                 | HT_CAP_INFO_SHORT_GI_40M
3805                 | HT_CAP_INFO_HT_GF);
3806         (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH;
3807         break;
3808
3809     case FIXED_RATE_MCS5_40M_800NS:
3810         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3811         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3812         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3813         *pucMcsSet = HT_RATE_MCS5_INDEX;
3814         *pucSupMcs32 = 0;
3815         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M
3816                 | HT_CAP_INFO_SHORT_GI_40M
3817                 | HT_CAP_INFO_HT_GF);
3818         (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH;
3819         break;
3820
3821     case FIXED_RATE_MCS6_40M_800NS:
3822         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3823         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3824         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3825         *pucMcsSet = HT_RATE_MCS6_INDEX;
3826         *pucSupMcs32 = 0;
3827         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M
3828                 | HT_CAP_INFO_SHORT_GI_40M
3829                 | HT_CAP_INFO_HT_GF);
3830         (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH;
3831         break;
3832
3833     case FIXED_RATE_MCS7_40M_800NS:
3834         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3835         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3836         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3837         *pucMcsSet = HT_RATE_MCS7_INDEX;
3838         *pucSupMcs32 = 0;
3839         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M
3840                 | HT_CAP_INFO_SHORT_GI_40M
3841                 | HT_CAP_INFO_HT_GF);
3842         (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH;
3843         break;
3844
3845     case FIXED_RATE_MCS32_800NS:
3846         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3847         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3848         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3849         *pucMcsSet = HT_RATE_MCS32_INDEX;
3850         *pucSupMcs32 = 1;
3851         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M
3852                 | HT_CAP_INFO_SHORT_GI_40M
3853                 | HT_CAP_INFO_HT_GF);
3854         (*pu2HtCapInfo) |= HT_CAP_INFO_SUP_CHNL_WIDTH;
3855         break;
3856
3857     case FIXED_RATE_MCS0_40M_400NS:
3858         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3859         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3860         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3861         *pucMcsSet = HT_RATE_MCS0_INDEX;
3862         *pucSupMcs32 = 0;
3863         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M
3864                 | HT_CAP_INFO_HT_GF);
3865         (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH
3866                 | HT_CAP_INFO_SHORT_GI_40M);
3867         break;
3868
3869     case FIXED_RATE_MCS1_40M_400NS:
3870         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3871         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3872         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3873         *pucMcsSet = HT_RATE_MCS1_INDEX;
3874         *pucSupMcs32 = 0;
3875         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M
3876                 | HT_CAP_INFO_HT_GF);
3877         (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH
3878                 | HT_CAP_INFO_SHORT_GI_40M);
3879         break;
3880
3881     case FIXED_RATE_MCS2_40M_400NS:
3882         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3883         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3884         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3885         *pucMcsSet = HT_RATE_MCS2_INDEX;
3886         *pucSupMcs32 = 0;
3887         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M
3888                 | HT_CAP_INFO_HT_GF);
3889         (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH
3890                 | HT_CAP_INFO_SHORT_GI_40M);
3891         break;
3892
3893     case FIXED_RATE_MCS3_40M_400NS:
3894         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3895         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3896         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3897         *pucMcsSet = HT_RATE_MCS3_INDEX;
3898         *pucSupMcs32 = 0;
3899         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M
3900                 | HT_CAP_INFO_HT_GF);
3901         (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH
3902                 | HT_CAP_INFO_SHORT_GI_40M);
3903         break;
3904
3905     case FIXED_RATE_MCS4_40M_400NS:
3906         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3907         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3908         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3909         *pucMcsSet = HT_RATE_MCS4_INDEX;
3910         *pucSupMcs32 = 0;
3911         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M
3912                 | HT_CAP_INFO_HT_GF);
3913         (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH
3914                 | HT_CAP_INFO_SHORT_GI_40M);
3915         break;
3916
3917     case FIXED_RATE_MCS5_40M_400NS:
3918         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3919         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3920         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3921         *pucMcsSet = HT_RATE_MCS5_INDEX;
3922         *pucSupMcs32 = 0;
3923         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M
3924                 | HT_CAP_INFO_HT_GF);
3925         (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH
3926                 | HT_CAP_INFO_SHORT_GI_40M);
3927         break;
3928
3929     case FIXED_RATE_MCS6_40M_400NS:
3930         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3931         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3932         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3933         *pucMcsSet = HT_RATE_MCS6_INDEX;
3934         *pucSupMcs32 = 0;
3935         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M
3936                 | HT_CAP_INFO_HT_GF);
3937         (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH
3938                 | HT_CAP_INFO_SHORT_GI_40M);
3939         break;
3940
3941     case FIXED_RATE_MCS7_40M_400NS:
3942         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3943         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3944         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3945         *pucMcsSet = HT_RATE_MCS7_INDEX;
3946         *pucSupMcs32 = 0;
3947         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M
3948                 | HT_CAP_INFO_HT_GF);
3949         (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH
3950                 | HT_CAP_INFO_SHORT_GI_40M);
3951         break;
3952
3953     case FIXED_RATE_MCS32_400NS:
3954         *pucDesiredPhyTypeSet = PHY_TYPE_BIT_HT;
3955         *pu2DesiredNonHTRateSet = RATE_SET_BIT_HT_PHY;
3956         *pu2BSSBasicRateSet = RATE_SET_BIT_HT_PHY;
3957         *pucMcsSet = HT_RATE_MCS32_INDEX;
3958         *pucSupMcs32 = 1;
3959         (*pu2HtCapInfo) &= ~(HT_CAP_INFO_SHORT_GI_20M
3960                 | HT_CAP_INFO_HT_GF);
3961         (*pu2HtCapInfo) |= (HT_CAP_INFO_SUP_CHNL_WIDTH
3962                 | HT_CAP_INFO_SHORT_GI_40M);
3963         break;
3964
3965     default:
3966         ASSERT(0);
3967     }
3968
3969     return WLAN_STATUS_SUCCESS;
3970 }
3971
3972 /*----------------------------------------------------------------------------*/
3973 /*!
3974 * @brief This utility function is used to write the register
3975 *
3976 * @param u4Address         Register address
3977 *        u4Value           the value to be written
3978 *
3979 * @retval WLAN_STATUS_SUCCESS
3980 *         WLAN_STATUS_FAILURE
3981 */
3982 /*----------------------------------------------------------------------------*/
3983
3984 WLAN_STATUS
3985 nicWriteMcr (
3986     IN P_ADAPTER_T  prAdapter,
3987     IN UINT_32   u4Address,
3988     IN  UINT_32  u4Value
3989     )
3990 {
3991     CMD_ACCESS_REG rCmdAccessReg;
3992
3993     rCmdAccessReg.u4Address = u4Address;
3994     rCmdAccessReg.u4Data = u4Value;
3995
3996     return wlanSendSetQueryCmd(prAdapter,
3997                 CMD_ID_ACCESS_REG,
3998                 TRUE,
3999                 FALSE,
4000                 FALSE,
4001                 NULL,
4002                 NULL,
4003                 sizeof(CMD_ACCESS_REG),
4004                 (PUINT_8)&rCmdAccessReg,
4005                 NULL,
4006                 0
4007                 );
4008
4009 }
4010
4011 /*----------------------------------------------------------------------------*/
4012 /*!
4013 * @brief This utility function is used to modify the auto rate parameters
4014 *
4015 * @param u4ArSysParam0  see description below
4016 *        u4ArSysParam1
4017 *        u4ArSysParam2
4018 *        u4ArSysParam3
4019 *
4020 *
4021 * @retval WLAN_STATUS_SUCCESS
4022 *         WLAN_STATUS_FAILURE
4023 *
4024 * @note
4025 *   ArSysParam0[0:3] -> auto rate version (0:disable 1:version1 2:version2)
4026 *   ArSysParam0[4:5]-> auto bw version (0:disable 1:version1 2:version2)
4027 *   ArSysParam0[6:7]-> auto gi version (0:disable 1:version1 2:version2)
4028 *   ArSysParam0[8:15]-> HT rate clear mask
4029 *   ArSysParam0[16:31]-> Legacy rate clear mask
4030 *   ArSysParam1[0:7]-> Auto Rate check weighting window
4031 *   ArSysParam1[8:15]-> Auto Rate v1 Force Rate down
4032 *   ArSysParam1[16:23]-> Auto Rate v1 PerH
4033 *   ArSysParam1[24:31]-> Auto Rate v1 PerL
4034 *
4035 *   Examples
4036 *   ArSysParam0 = 1,
4037 *   Enable auto rate version 1
4038 *
4039 *   ArSysParam0 = 983041,
4040 *   Enable auto rate version 1
4041 *   Remove CCK 1M, 2M, 5.5M, 11M
4042 *
4043 *   ArSysParam0 = 786433
4044 *   Enable auto rate version 1
4045 *   Remove CCK 5.5M 11M
4046 */
4047 /*----------------------------------------------------------------------------*/
4048
4049
4050 WLAN_STATUS
4051 nicRlmArUpdateParms(
4052     IN P_ADAPTER_T prAdapter,
4053     IN UINT_32 u4ArSysParam0,
4054     IN UINT_32 u4ArSysParam1,
4055     IN UINT_32 u4ArSysParam2,
4056     IN UINT_32 u4ArSysParam3
4057     )
4058 {
4059     UINT_8 ucArVer,ucAbwVer,ucAgiVer;
4060     UINT_16 u2HtClrMask;
4061     UINT_16 u2LegacyClrMask;
4062     UINT_8  ucArCheckWindow;
4063     UINT_8  ucArPerL;
4064     UINT_8  ucArPerH;
4065     UINT_8  ucArPerForceRateDownPer;
4066
4067     ucArVer = (UINT_8)(u4ArSysParam0 & BITS(0,3));
4068     ucAbwVer = (UINT_8)((u4ArSysParam0 & BITS(4,5)) >>4);
4069     ucAgiVer = (UINT_8)((u4ArSysParam0 & BITS(6,7)) >>6);
4070     u2HtClrMask = (UINT_16) ((u4ArSysParam0 & BITS(8,15)) >> 8);
4071     u2LegacyClrMask = (UINT_16) ((u4ArSysParam0 & BITS(16,31)) >> 16);
4072
4073 #if 0
4074     ucArCheckWindow = (UINT_8) (u4ArSysParam1 & BITS(0,7));
4075     ucArPerForceRateDownPer = (UINT_8) ((u4ArSysParam1 & BITS(8,15)>>8));
4076     ucArPerH = (UINT_8) ((u4ArSysParam1 & BITS(16,23)) >>16);
4077     ucArPerL = (UINT_8) ((u4ArSysParam1 & BITS(24,31)) >>24);
4078 #endif
4079
4080     ucArCheckWindow = (UINT_8) (u4ArSysParam1 & BITS(0,7));
4081     ucArPerForceRateDownPer = (UINT_8) (((u4ArSysParam1>>8) & BITS(0,7)));
4082     ucArPerH = (UINT_8) (((u4ArSysParam1>>16) & BITS(0,7)));
4083     ucArPerL = (UINT_8) (((u4ArSysParam1>>24) & BITS(0,7)));
4084
4085
4086     DBGLOG(INIT, INFO, ("ArParam %u %u %u %u\n", u4ArSysParam0, u4ArSysParam1, u4ArSysParam2, u4ArSysParam3));
4087     DBGLOG(INIT, INFO, ("ArVer %u AbwVer %u AgiVer %u\n", ucArVer, ucAbwVer, ucAgiVer));
4088     DBGLOG(INIT, INFO, ("HtMask %x LegacyMask %x\n", u2HtClrMask, u2LegacyClrMask));
4089     DBGLOG(INIT, INFO, ("CheckWin %u RateDownPer %u PerH %u PerL %u\n", ucArCheckWindow, ucArPerForceRateDownPer, ucArPerH, ucArPerL));
4090
4091 #define SWCR_DATA_ADDR(MOD,ADDR) (0x90000000+(MOD<<8)+(ADDR))
4092 #define SWCR_DATA_CMD(CATE,WRITE,INDEX,OPT0,OPT1) ( (CATE<<24) | (WRITE<<23) | (INDEX<<16) | (OPT0 <<8) | OPT1  )
4093 #define SWCR_DATA0 0x0
4094 #define SWCR_DATA1 0x4
4095 #define SWCR_DATA2 0x8
4096 #define SWCR_DATA3 0xC
4097 #define SWCR_DATA4 0x10
4098 #define SWCR_WRITE 1
4099 #define SWCR_READ 0
4100
4101     if(ucArVer > 0) {
4102        /* dummy = WiFi.WriteMCR(&h90000104, &h00000001) */
4103        /* dummy = WiFi.WriteMCR(&h90000100, &h00850000)*/
4104
4105        nicWriteMcr (prAdapter, SWCR_DATA_ADDR(1/*MOD*/,SWCR_DATA1),1);
4106        nicWriteMcr (prAdapter, SWCR_DATA_ADDR(1/*MOD*/,SWCR_DATA0),SWCR_DATA_CMD(0,SWCR_WRITE,5,0,0));
4107     }
4108     else {
4109        nicWriteMcr (prAdapter, SWCR_DATA_ADDR(1/*MOD*/,SWCR_DATA1),0);
4110        nicWriteMcr (prAdapter, SWCR_DATA_ADDR(1/*MOD*/,SWCR_DATA0),SWCR_DATA_CMD(0,SWCR_WRITE,5,0,0)) ;
4111     }
4112
4113     /* ucArVer 0: none 1:PER 2:Rcpi */
4114     nicWriteMcr (prAdapter, SWCR_DATA_ADDR(1/*MOD*/,SWCR_DATA1),ucArVer);
4115     nicWriteMcr (prAdapter, SWCR_DATA_ADDR(1/*MOD*/,SWCR_DATA0),SWCR_DATA_CMD(0,SWCR_WRITE,7,0,0));
4116
4117     /* Candidate rate Ht mask */
4118     nicWriteMcr (prAdapter, SWCR_DATA_ADDR(1/*MOD*/,SWCR_DATA1),u2HtClrMask);
4119     nicWriteMcr (prAdapter, SWCR_DATA_ADDR(1/*MOD*/,SWCR_DATA0),SWCR_DATA_CMD(0,SWCR_WRITE,0x1c,0,0));
4120
4121     /* Candidate rate legacy mask */
4122     nicWriteMcr (prAdapter, SWCR_DATA_ADDR(1/*MOD*/,SWCR_DATA1),u2LegacyClrMask);
4123     nicWriteMcr (prAdapter, SWCR_DATA_ADDR(1/*MOD*/,SWCR_DATA0),SWCR_DATA_CMD(0,SWCR_WRITE,0x1d,0,0));
4124
4125 #if 0
4126     if(ucArCheckWindow!=0) {
4127         /* TX DONE MCS INDEX CHECK STA RATE DOWN TH */
4128         nicWriteMcr (prAdapter, SWCR_DATA_ADDR(1/*MOD*/,SWCR_DATA1),ucArCheckWindow);
4129         nicWriteMcr (prAdapter, SWCR_DATA_ADDR(1/*MOD*/,SWCR_DATA0),SWCR_DATA_CMD(0,SWCR_WRITE,0x14,0,0));
4130         nicWriteMcr (prAdapter, SWCR_DATA_ADDR(1/*MOD*/,SWCR_DATA1),ucArCheckWindow);
4131         nicWriteMcr (prAdapter, SWCR_DATA_ADDR(1/*MOD*/,SWCR_DATA0),SWCR_DATA_CMD(0,SWCR_WRITE,0xc,0,0));
4132     }
4133
4134     if(ucArPerForceRateDownPer !=0) {
4135         nicWriteMcr (prAdapter, SWCR_DATA_ADDR(1/*MOD*/,SWCR_DATA1),ucArPerForceRateDownPer);
4136         nicWriteMcr (prAdapter, SWCR_DATA_ADDR(1/*MOD*/,SWCR_DATA0),SWCR_DATA_CMD(0,SWCR_WRITE,0x18,0,0));
4137     }
4138     if(ucArPerH !=0) {
4139         nicWriteMcr (prAdapter, SWCR_DATA_ADDR(1/*MOD*/,SWCR_DATA1),ucArPerH);
4140         nicWriteMcr (prAdapter, SWCR_DATA_ADDR(1/*MOD*/,SWCR_DATA0),SWCR_DATA_CMD(0,SWCR_WRITE,0x1,0,0));
4141     }
4142     if(ucArPerL !=0) {
4143         nicWriteMcr (prAdapter, SWCR_DATA_ADDR(1/*MOD*/,SWCR_DATA1),ucArPerL);
4144         nicWriteMcr (prAdapter, SWCR_DATA_ADDR(1/*MOD*/,SWCR_DATA0),SWCR_DATA_CMD(0,SWCR_WRITE,0x2,0,0));
4145     }
4146 #endif
4147
4148
4149
4150     return WLAN_STATUS_SUCCESS;
4151 }
4152
4153 /*----------------------------------------------------------------------------*/
4154 /*!
4155 * @brief This utility function is used to enable roaming
4156 *
4157 * @param u4EnableRoaming
4158 *
4159 *
4160 * @retval WLAN_STATUS_SUCCESS
4161 *         WLAN_STATUS_FAILURE
4162 *
4163 * @note
4164 *   u4EnableRoaming -> Enable Romaing
4165 *
4166 */
4167 /*----------------------------------------------------------------------------*/
4168 WLAN_STATUS
4169 nicRoamingUpdateParams(
4170     IN P_ADAPTER_T prAdapter,
4171     IN UINT_32 u4EnableRoaming
4172     )
4173 {
4174     P_CONNECTION_SETTINGS_T prConnSettings;
4175
4176     prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
4177     prConnSettings->fgIsEnableRoaming = ((u4EnableRoaming>0)?(TRUE):(FALSE));
4178
4179     return WLAN_STATUS_SUCCESS;
4180 }
4181
4182 /*----------------------------------------------------------------------------*/
4183 /*!
4184 * \brief dump firmware Assert message
4185 *
4186 * \param[in]
4187 *           prAdapter
4188 *
4189 * \return
4190 *           TRUE
4191 *           FALSE
4192 */
4193 /*----------------------------------------------------------------------------*/
4194 VOID
4195 nicPrintFirmwareAssertInfo(
4196     IN P_ADAPTER_T prAdapter
4197     )
4198 {
4199     UINT_32 u4MailBox0, u4MailBox1;
4200     UINT_32 line = 0;
4201     UINT_8 aucAssertFile[7];
4202     UINT_32 u4ChipId;
4203
4204 #if CFG_SDIO_INTR_ENHANCE
4205     u4MailBox0 = prAdapter->prSDIOCtrl->u4RcvMailbox0;
4206     u4MailBox1 = prAdapter->prSDIOCtrl->u4RcvMailbox1;
4207 #else
4208     nicGetMailbox(prAdapter, 0, &u4MailBox0);
4209     nicGetMailbox(prAdapter, 1, &u4MailBox1);
4210 #endif
4211
4212     line = u4MailBox0 & 0x0000FFFF;
4213
4214     u4MailBox0 = ((u4MailBox0 >> 16) & 0x0000FFFF);
4215
4216     kalMemCopy(&aucAssertFile[0], &u4MailBox0, 2);
4217     kalMemCopy(&aucAssertFile[2], &u4MailBox1, 4);
4218
4219     aucAssertFile[6] = '\0';
4220
4221 #if defined(MT6620)
4222     u4ChipId = 6620;
4223 #elif defined(MT5931)
4224     u4ChipId = 5931;
4225 #elif defined(MT6628)
4226     u4ChipId = 6628;
4227 #endif
4228
4229     kalPrint("\n[MT%ld][wifi][Firmware] Assert at \"%s\" #%ld\n\n",
4230         u4ChipId,
4231         aucAssertFile,
4232                 line);
4233
4234 }
4235
4236
4237 /*----------------------------------------------------------------------------*/
4238 /*!
4239 * @brief This function is called to update Link Quality information
4240 *
4241 * @param prAdapter      Pointer of Adapter Data Structure
4242 *        eNetTypeIdx
4243 *        prEventLinkQuality
4244 *        cRssi
4245 *        cLinkQuality
4246 *
4247 * @return none
4248 */
4249 /*----------------------------------------------------------------------------*/
4250 VOID
4251 nicUpdateLinkQuality(
4252     IN P_ADAPTER_T                  prAdapter,
4253     IN ENUM_NETWORK_TYPE_INDEX_T    eNetTypeIdx,
4254     IN P_EVENT_LINK_QUALITY         prEventLinkQuality
4255     )
4256 {
4257     ASSERT(prAdapter);
4258     ASSERT(eNetTypeIdx < NETWORK_TYPE_INDEX_NUM);
4259     ASSERT(prEventLinkQuality);
4260
4261     switch(eNetTypeIdx) {
4262     case NETWORK_TYPE_AIS_INDEX:
4263         if(prAdapter->rWifiVar.arBssInfo[eNetTypeIdx].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
4264             /* check is to prevent RSSI to be updated by incorrect initial RSSI from hardware */
4265             /* buffer statistics for further query */
4266             if(prAdapter->fgIsLinkQualityValid == FALSE
4267                     || (kalGetTimeTick() - prAdapter->rLinkQualityUpdateTime) > CFG_LINK_QUALITY_VALID_PERIOD) {
4268                 nicUpdateRSSI(prAdapter, eNetTypeIdx, prEventLinkQuality->cRssi, prEventLinkQuality->cLinkQuality);
4269             }
4270
4271             if(prAdapter->fgIsLinkRateValid == FALSE
4272                     || (kalGetTimeTick() - prAdapter->rLinkRateUpdateTime) > CFG_LINK_QUALITY_VALID_PERIOD) {
4273                 nicUpdateLinkSpeed(prAdapter, eNetTypeIdx, prEventLinkQuality->u2LinkSpeed);
4274             }
4275         }
4276         break;
4277 #if CFG_ENABLE_WIFI_DIRECT && CFG_SUPPORT_P2P_RSSI_QUERY
4278     case NETWORK_TYPE_P2P_INDEX:
4279         if (prAdapter->fgIsP2pLinkQualityValid == FALSE
4280                 || (kalGetTimeTick() - prAdapter->rP2pLinkQualityUpdateTime) > CFG_LINK_QUALITY_VALID_PERIOD) {
4281             P_EVENT_LINK_QUALITY_EX prEventLQEx = (P_EVENT_LINK_QUALITY_EX)prEventLinkQuality;
4282
4283             nicUpdateRSSI(prAdapter, NETWORK_TYPE_P2P_INDEX, prEventLQEx->cRssiP2P, prEventLQEx->cLinkQualityP2P);
4284         }
4285         break;
4286 #endif
4287     default:
4288         break;
4289
4290     }
4291
4292     return;
4293 }
4294
4295
4296 /*----------------------------------------------------------------------------*/
4297 /*!
4298 * @brief This function is called to update RSSI and Link Quality information
4299 *
4300 * @param prAdapter      Pointer of Adapter Data Structure
4301 *        eNetTypeIdx
4302 *        cRssi
4303 *        cLinkQuality
4304 *
4305 * @return none
4306 */
4307 /*----------------------------------------------------------------------------*/
4308 VOID
4309 nicUpdateRSSI(
4310     IN P_ADAPTER_T                  prAdapter,
4311     IN ENUM_NETWORK_TYPE_INDEX_T    eNetTypeIdx,
4312     IN INT_8                        cRssi,
4313     IN INT_8                        cLinkQuality
4314     )
4315 {
4316     ASSERT(prAdapter);
4317     ASSERT(eNetTypeIdx < NETWORK_TYPE_INDEX_NUM);
4318
4319     switch(eNetTypeIdx) {
4320     case NETWORK_TYPE_AIS_INDEX:
4321         if(prAdapter->rWifiVar.arBssInfo[eNetTypeIdx].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
4322             prAdapter->fgIsLinkQualityValid = TRUE;
4323             prAdapter->rLinkQualityUpdateTime = kalGetTimeTick();
4324
4325             prAdapter->rLinkQuality.cRssi = cRssi;
4326             prAdapter->rLinkQuality.cLinkQuality = cLinkQuality;
4327
4328             /* indicate to glue layer */
4329             kalUpdateRSSI(prAdapter->prGlueInfo,
4330                     KAL_NETWORK_TYPE_AIS_INDEX,
4331                     prAdapter->rLinkQuality.cRssi,
4332                     prAdapter->rLinkQuality.cLinkQuality);
4333         }
4334
4335         break;
4336 #if CFG_ENABLE_WIFI_DIRECT
4337 #if CFG_SUPPORT_P2P_RSSI_QUERY
4338     case NETWORK_TYPE_P2P_INDEX:
4339         prAdapter->fgIsP2pLinkQualityValid = TRUE;
4340         prAdapter->rP2pLinkQualityUpdateTime = kalGetTimeTick();
4341
4342         prAdapter->rP2pLinkQuality.cRssi= cRssi;
4343         prAdapter->rP2pLinkQuality.cLinkQuality= cLinkQuality;
4344
4345         kalUpdateRSSI(prAdapter->prGlueInfo,
4346                 KAL_NETWORK_TYPE_P2P_INDEX,
4347                 cRssi,
4348                 cLinkQuality);
4349         break;
4350 #endif
4351 #endif
4352     default:
4353         break;
4354
4355     }
4356
4357     return;
4358 }
4359
4360
4361 /*----------------------------------------------------------------------------*/
4362 /*!
4363 * @brief This function is called to update Link Quality information
4364 *
4365 * @param prAdapter      Pointer of Adapter Data Structure
4366 *        eNetTypeIdx
4367 *        prEventLinkQuality
4368 *        cRssi
4369 *        cLinkQuality
4370 *
4371 * @return none
4372 */
4373 /*----------------------------------------------------------------------------*/
4374 VOID
4375 nicUpdateLinkSpeed(
4376     IN P_ADAPTER_T                  prAdapter,
4377     IN ENUM_NETWORK_TYPE_INDEX_T    eNetTypeIdx,
4378     IN UINT_16                      u2LinkSpeed
4379     )
4380 {
4381     ASSERT(prAdapter);
4382     ASSERT(eNetTypeIdx < NETWORK_TYPE_INDEX_NUM);
4383
4384     switch(eNetTypeIdx) {
4385     case NETWORK_TYPE_AIS_INDEX:
4386         if(prAdapter->rWifiVar.arBssInfo[eNetTypeIdx].eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
4387             /* buffer statistics for further query */
4388             prAdapter->fgIsLinkRateValid = TRUE;
4389             prAdapter->rLinkRateUpdateTime = kalGetTimeTick();
4390
4391             prAdapter->rLinkQuality.u2LinkSpeed = u2LinkSpeed;
4392         }
4393         break;
4394
4395     default:
4396         break;
4397
4398     }
4399
4400     return;
4401 }
4402
4403 #if CFG_SUPPORT_RDD_TEST_MODE
4404 WLAN_STATUS
4405 nicUpdateRddTestMode(
4406     IN P_ADAPTER_T      prAdapter,
4407     IN P_CMD_RDD_CH_T   prRddChParam
4408     )
4409 {
4410     DEBUGFUNC("nicUpdateRddTestMode.\n");
4411
4412     ASSERT(prAdapter);
4413
4414 //    aisFsmScanRequest(prAdapter, NULL);
4415
4416     return wlanSendSetQueryCmd(prAdapter,
4417             CMD_ID_SET_RDD_CH,
4418             TRUE,
4419             FALSE,
4420             FALSE,
4421             NULL,
4422             NULL,
4423             sizeof(CMD_RDD_CH_T),
4424             (PUINT_8)prRddChParam,
4425             NULL,
4426             0);
4427 }
4428 #endif
4429