wifi: renew patch drivers/net/wireless
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / mt5931 / mgmt / scan.c
1 /*
2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/scan.c#3 $
3 */
4
5 /*! \file   "scan.c"
6     \brief  This file defines the scan profile and the processing function of
7             scan result for SCAN Module.
8
9     The SCAN Profile selection is part of SCAN MODULE and responsible for defining
10     SCAN Parameters - e.g. MIN_CHANNEL_TIME, number of scan channels.
11     In this file we also define the process of SCAN Result including adding, searching
12     and removing SCAN record from the list.
13 */
14
15
16
17 /*
18 ** $Log: scan.c $
19  *
20  * 07 17 2012 yuche.tsai
21  * NULL
22  * Let netdev bring up.
23  *
24  * 07 17 2012 yuche.tsai
25  * NULL
26  * Compile no error before trial run.
27  *
28  * 06 25 2012 cp.wu
29  * [WCXRP00001258] [MT6620][MT5931][MT6628][Driver] Do not use stale scan result for deciding connection target
30  * drop off scan result which is older than 5 seconds when choosing which BSS to join
31  *
32  * 03 02 2012 terry.wu
33  * NULL
34  * Sync CFG80211 modification from branch 2,2.
35  *
36  * 01 16 2012 cp.wu
37  * [WCXRP00001169] [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration with corresponding network configuration
38  * correct typo.
39  *
40  * 01 16 2012 cp.wu
41  * [MT6620 Wi-Fi][Driver] API and behavior modification for preferred band configuration with corresponding network configuration 
42  * add wlanSetPreferBandByNetwork() for glue layer to invoke for setting preferred band configuration corresponding to network type.
43  *
44  * 12 05 2011 cp.wu
45  * [WCXRP00001131] [MT6620 Wi-Fi][Driver][AIS] Implement connect-by-BSSID path
46  * add CONNECT_BY_BSSID policy
47  *
48  * 11 23 2011 cp.wu
49  * [WCXRP00001123] [MT6620 Wi-Fi][Driver] Add option to disable beacon content change detection
50  * add compile option to disable beacon content change detection.
51  *
52  * 11 04 2011 cp.wu
53  * [WCXRP00001085] [MT6628 Wi-Fi][Driver] deprecate old BSS-DESC if timestamp is reset with received beacon/probe response frames
54  * deprecate old BSS-DESC when timestamp in received beacon/probe response frames showed a smaller value than before
55  *
56  * 10 11 2011 cm.chang
57  * [WCXRP00001031] [All Wi-Fi][Driver] Check HT IE length to avoid wrong SCO parameter
58  * Ignore HT OP IE if its length field is not valid
59  *
60  * 09 30 2011 cp.wu
61  * [WCXRP00001021] [MT5931][Driver] Correct scan result generation for conversion between BSS type and operation mode
62  * correct type casting issue.
63  *
64  * 08 23 2011 yuche.tsai
65  * NULL
66  * Fix multicast address list issue.
67  *
68  * 08 11 2011 cp.wu
69  * [WCXRP00000830] [MT6620 Wi-Fi][Firmware] Use MDRDY counter to detect empty channel for shortening scan time
70  * sparse channel detection:
71  * driver: collect sparse channel information with scan-done event
72  *
73  * 08 10 2011 cp.wu
74  * [WCXRP00000922] [MT6620 Wi-Fi][Driver] traverse whole BSS-DESC list for removing
75  * traverse whole BSS-DESC list because BSSID is not unique anymore.
76  *
77  * 07 12 2011 cp.wu
78  * [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
79  * for multiple BSS descriptior detecting issue:
80  * 1) check BSSID for infrastructure network
81  * 2) check SSID for AdHoc network
82  *
83  * 07 12 2011 cp.wu
84  * [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
85  * check for BSSID for beacons used to update DTIM
86  *
87  * 07 12 2011 cp.wu
88  * [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
89  * do not check BSS descriptor for connected flag due to linksys's hidden SSID will use another BSS descriptor and never connected
90  *
91  * 07 11 2011 cp.wu
92  * [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
93  * just pass beacons with the same BSSID.
94  *
95  * 07 11 2011 wh.su
96  * [WCXRP00000849] [MT6620 Wi-Fi][Driver] Remove some of the WAPI define for make sure the value is initialize, for customer not enable WAPI
97  * For make sure wapi initial value is set.
98  *
99  * 06 28 2011 cp.wu
100  * [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
101  * Do not check for SSID as beacon content change due to the existence of single BSSID with multiple SSID AP configuration
102  *
103  * 06 27 2011 cp.wu
104  * [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
105  * 1. correct logic
106  * 2. replace only BSS-DESC which doesn't have a valid SSID.
107  *
108  * 06 27 2011 cp.wu
109  * [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
110  * remove unused temporal variable reference.
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  * allow to have a single BSSID with multiple SSID to be presented in scanning result
115  *
116  * 06 02 2011 cp.wu
117  * [WCXRP00000757] [MT6620 Wi-Fi][Driver][SCN] take use of RLM API to filter out BSS in disallowed channels
118  * filter out BSS in disallowed channel by
119  * 1. do not add to scan result array if BSS is at disallowed channel
120  * 2. do not allow to search for BSS-DESC in disallowed channels
121  *
122  * 05 02 2011 cm.chang
123  * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number
124  * Refine range of valid channel number
125  *
126  * 05 02 2011 cp.wu
127  * [MT6620 Wi-Fi][Driver] Take parsed result for channel information instead of hardware channel number passed from firmware domain
128  * take parsed result for generating scanning result with channel information.
129  *
130  * 05 02 2011 cm.chang
131  * [WCXRP00000691] [MT6620 Wi-Fi][Driver] Workaround about AP's wrong HT capability IE to have wrong channel number
132  * Check if channel is valided before record ing BSS channel
133  *
134  * 04 18 2011 terry.wu
135  * [WCXRP00000660] [MT6620 Wi-Fi][Driver] Remove flag CFG_WIFI_DIRECT_MOVED
136  * Remove flag CFG_WIFI_DIRECT_MOVED.
137  *
138  * 04 14 2011 cm.chang
139  * [WCXRP00000634] [MT6620 Wi-Fi][Driver][FW] 2nd BSS will not support 40MHz bandwidth for concurrency
140  * .
141  *
142  * 04 12 2011 eddie.chen
143  * [WCXRP00000617] [MT6620 Wi-Fi][DRV/FW] Fix for sigma
144  * Fix the sta index in processing security frame
145  * Simple flow control for TC4 to avoid mgt frames for PS STA to occupy the TC4
146  * Add debug message.
147  *
148  * 03 25 2011 yuche.tsai
149  * NULL
150  * Always update Bss Type, for Bss Type for P2P Network is changing every time.
151  *
152  * 03 23 2011 yuche.tsai
153  * NULL
154  * Fix concurrent issue when AIS scan result would overwrite p2p scan result.
155  *
156  * 03 14 2011 cp.wu
157  * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently
158  * filtering out other BSS coming from adjacent channels
159  *
160  * 03 11 2011 chinglan.wang
161  * [WCXRP00000537] [MT6620 Wi-Fi][Driver] Can not connect to 802.11b/g/n mixed AP with WEP security.
162  * .
163  *
164  * 03 11 2011 cp.wu
165  * [WCXRP00000535] [MT6620 Wi-Fi][Driver] Fixed channel operation when AIS and Tethering are operating concurrently
166  * When fixed channel operation is necessary, AIS-FSM would scan and only connect for BSS on the specific channel
167  *
168  * 02 24 2011 cp.wu
169  * [WCXRP00000490] [MT6620 Wi-Fi][Driver][Win32] modify kalMsleep() implementation because NdisMSleep() won't sleep long enough for specified interval such as 500ms
170  * implement beacon change detection by checking SSID and supported rate.
171  *
172  * 02 22 2011 yuche.tsai
173  * [WCXRP00000480] [Volunteer Patch][MT6620][Driver] WCS IE format issue
174  * Fix WSC big endian issue.
175  *
176  * 02 21 2011 terry.wu
177  * [WCXRP00000476] [MT6620 Wi-Fi][Driver] Clean P2P scan list while removing P2P
178  * Clean P2P scan list while removing P2P.
179  *
180  * 01 27 2011 yuche.tsai
181  * [WCXRP00000399] [Volunteer Patch][MT6620/MT5931][Driver] Fix scan side effect after P2P module separate.
182  * Fix scan channel extension issue when p2p module is not registered.
183  *
184  * 01 26 2011 cm.chang
185  * [WCXRP00000395] [MT6620 Wi-Fi][Driver][FW] Search STA_REC with additional net type index argument
186  * .
187  *
188  * 01 21 2011 cp.wu
189  * [WCXRP00000380] [MT6620 Wi-Fi][Driver] SSID information should come from buffered BSS_DESC_T rather than using beacon-carried information
190  * SSID should come from buffered prBssDesc rather than beacon-carried information
191  *
192  * 01 14 2011 yuche.tsai
193  * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
194  * Fix compile error.
195  *
196  * 01 14 2011 yuche.tsai
197  * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
198  * Memfree for P2P Descriptor & P2P Descriptor List.
199  *
200  * 01 14 2011 yuche.tsai
201  * [WCXRP00000352] [Volunteer Patch][MT6620][Driver] P2P Statsion Record Client List Issue
202  * Free P2P Descriptor List & Descriptor under BSS Descriptor.
203  *
204  * 01 04 2011 cp.wu
205  * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease physically continous memory demands
206  * 1) correct typo in scan.c
207  * 2) TX descriptors, RX descriptos and management buffer should use virtually continous buffer instead of physically contineous one
208  *
209  * 01 04 2011 cp.wu
210  * [WCXRP00000338] [MT6620 Wi-Fi][Driver] Separate kalMemAlloc into kmalloc and vmalloc implementations to ease physically continous memory demands
211  * separate kalMemAlloc() into virtually-continous and physically-continous type to ease slab system pressure
212  *
213  * 12 31 2010 cp.wu
214  * [WCXRP00000327] [MT6620 Wi-Fi][Driver] Improve HEC WHQA 6972 workaround coverage in driver side
215  * while being unloaded, clear all pending interrupt then set LP-own to firmware
216  *
217  * 12 21 2010 cp.wu
218  * [WCXRP00000280] [MT6620 Wi-Fi][Driver] Enable BSS selection with best RCPI policy in SCN module
219  * SCN: enable BEST RSSI selection policy support
220  *
221  * 11 29 2010 cp.wu
222  * [WCXRP00000210] [MT6620 Wi-Fi][Driver][FW] Set RCPI value in STA_REC for initial TX rate selection of auto-rate algorithm
223  * update ucRcpi of STA_RECORD_T for AIS when
224  * 1) Beacons for IBSS merge is received
225  * 2) Associate Response for a connecting peer is received
226  *
227  * 11 03 2010 wh.su
228  * [WCXRP00000124] [MT6620 Wi-Fi] [Driver] Support the dissolve P2P Group
229  * Refine the HT rate disallow TKIP pairwise cipher .
230  *
231  * 10 12 2010 cp.wu
232  * [WCXRP00000091] [MT6620 Wi-Fi][Driver] Add scanning logic to filter out beacons which is received on the folding frequency
233  * trust HT IE if available for 5GHz band
234  *
235  * 10 11 2010 cp.wu
236  * [WCXRP00000091] [MT6620 Wi-Fi][Driver] Add scanning logic to filter out beacons which is received on the folding frequency
237  * add timing and strenght constraint for filtering out beacons with same SSID/TA but received on different channels
238  *
239  * 10 08 2010 wh.su
240  * [WCXRP00000085] [MT6620 Wif-Fi] [Driver] update the modified p2p state machine
241  * update the frog's new p2p state machine.
242  *
243  * 10 01 2010 yuche.tsai
244  * NULL
245  * [MT6620 P2P] Fix Big Endian Issue when parse P2P device name TLV.
246  *
247  * 09 24 2010 cp.wu
248  * [WCXRP00000052] [MT6620 Wi-Fi][Driver] Eliminate Linux Compile Warning
249  * eliminate unused variables which lead gcc to argue
250  *
251  * 09 08 2010 cp.wu
252  * NULL
253  * use static memory pool for storing IEs of scanning result.
254  *
255  * 09 07 2010 yuche.tsai
256  * NULL
257  * When indicate scan result, append IE buffer information in the scan result.
258  *
259  * 09 03 2010 yuche.tsai
260  * NULL
261  * 1. Update Beacon RX count when running SLT.
262  * 2. Ignore Beacon when running SLT, would not update information from Beacon.
263  *
264  * 09 03 2010 kevin.huang
265  * NULL
266  * Refine #include sequence and solve recursive/nested #include issue
267  *
268  * 08 31 2010 kevin.huang
269  * NULL
270  * Use LINK LIST operation to process SCAN result
271  *
272  * 08 29 2010 yuche.tsai
273  * NULL
274  * 1. Fix P2P Descriptor List to be a link list, to avoid link corrupt after Bss Descriptor Free.
275  * 2.. Fix P2P Device Name Length BE issue.
276  *
277  * 08 23 2010 yuche.tsai
278  * NULL
279  * Add P2P Device Found Indication to supplicant
280  *
281  * 08 20 2010 cp.wu
282  * NULL
283  * reset BSS_DESC_T variables before parsing IE due to peer might have been reconfigured.
284  *
285  * 08 20 2010 yuche.tsai
286  * NULL
287  * Workaround for P2P Descriptor Infinite loop issue.
288  *
289  * 08 16 2010 cp.wu
290  * NULL
291  * Replace CFG_SUPPORT_BOW by CFG_ENABLE_BT_OVER_WIFI.
292  * There is no CFG_SUPPORT_BOW in driver domain source.
293  *
294  * 08 16 2010 yuche.tsai
295  * NULL
296  * Modify code of processing Probe Resonse frame for P2P.
297  *
298  * 08 12 2010 yuche.tsai
299  * NULL
300  * Add function to get P2P descriptor of BSS descriptor directly.
301  *
302  * 08 11 2010 yuche.tsai
303  * NULL
304  * Modify Scan result processing for P2P module.
305  *
306  * 08 05 2010 yuche.tsai
307  * NULL
308  * Update P2P Device Discovery result add function.
309  *
310  * 08 03 2010 cp.wu
311  * NULL
312  * surpress compilation warning.
313  *
314  * 07 26 2010 yuche.tsai
315  *
316  * Add support for Probe Request & Response parsing.
317  *
318  * 07 21 2010 cp.wu
319  *
320  * 1) change BG_SCAN to ONLINE_SCAN for consistent term
321  * 2) only clear scanning result when scan is permitted to do
322  *
323  * 07 21 2010 yuche.tsai
324  *
325  * Fix compile error for SCAN module while disabling P2P feature.
326  *
327  * 07 21 2010 yuche.tsai
328  *
329  * Add P2P Scan & Scan Result Parsing & Saving.
330  *
331  * 07 19 2010 wh.su
332  *
333  * update for security supporting.
334  *
335  * 07 19 2010 cp.wu
336  *
337  * [WPD00003833] [MT6620 and MT5931] Driver migration.
338  * Add Ad-Hoc support to AIS-FSM
339  *
340  * 07 19 2010 cp.wu
341  *
342  * [WPD00003833] [MT6620 and MT5931] Driver migration.
343  * SCN module is now able to handle multiple concurrent scanning requests
344  *
345  * 07 15 2010 cp.wu
346  *
347  * [WPD00003833] [MT6620 and MT5931] Driver migration.
348  * driver no longer generates probe request frames
349  *
350  * 07 14 2010 cp.wu
351  *
352  * [WPD00003833] [MT6620 and MT5931] Driver migration.
353  * remove timer in DRV-SCN.
354  *
355  * 07 09 2010 cp.wu
356  *
357  * 1) separate AIS_FSM state for two kinds of scanning. (OID triggered scan, and scan-for-connection)
358  * 2) eliminate PRE_BSS_DESC_T, Beacon/PrebResp is now parsed in single pass
359  * 3) implment DRV-SCN module, currently only accepts single scan request, other request will be directly dropped by returning BUSY
360  *
361  * 07 08 2010 cp.wu
362  *
363  * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
364  *
365  * 07 08 2010 cp.wu
366  * [WPD00003833][MT6620 and MT5931] Driver migration
367  * take use of RLM module for parsing/generating HT IEs for 11n capability
368  *
369  * 07 05 2010 cp.wu
370  * [WPD00003833][MT6620 and MT5931] Driver migration
371  * 1) ignore RSN checking when RSN is not turned on.
372  * 2) set STA-REC deactivation callback as NULL
373  * 3) add variable initialization API based on PHY configuration
374  *
375  * 07 05 2010 cp.wu
376  * [WPD00003833][MT6620 and MT5931] Driver migration
377  * correct BSS_DESC_T initialization after allocated.
378  *
379  * 07 02 2010 cp.wu
380  * [WPD00003833][MT6620 and MT5931] Driver migration
381  * 1) for event packet, no need to fill RFB.
382  * 2) when wlanAdapterStart() failed, no need to initialize state machines
383  * 3) after Beacon/ProbeResp parsing, corresponding BSS_DESC_T should be marked as IE-parsed
384  *
385  * 07 01 2010 cp.wu
386  * [WPD00003833][MT6620 and MT5931] Driver migration
387  * add scan uninitialization procedure
388  *
389  * 06 30 2010 cp.wu
390  * [WPD00003833][MT6620 and MT5931] Driver migration
391  * if beacon/probe-resp is received in 2.4GHz bands and there is ELEM_ID_DS_PARAM_SET IE available,
392  * trust IE instead of RMAC information
393  *
394  * 06 29 2010 cp.wu
395  * [WPD00003833][MT6620 and MT5931] Driver migration
396  * 1) sync to. CMD/EVENT document v0.03
397  * 2) simplify DTIM period parsing in scan.c only, bss.c no longer parses it again.
398  * 3) send command packet to indicate FW-PM after
399  *     a) 1st beacon is received after AIS has connected to an AP
400  *     b) IBSS-ALONE has been created
401  *     c) IBSS-MERGE has occured
402  *
403  * 06 28 2010 cp.wu
404  * [WPD00003833][MT6620 and MT5931] Driver migration
405  * send MMPDU in basic rate.
406  *
407  * 06 25 2010 cp.wu
408  * [WPD00003833][MT6620 and MT5931] Driver migration
409  * modify Beacon/ProbeResp to complete parsing,
410  * because host software has looser memory usage restriction
411  *
412  * 06 23 2010 cp.wu
413  * [WPD00003833][MT6620 and MT5931] Driver migration
414  * integrate .
415  *
416  * 06 22 2010 cp.wu
417  * [WPD00003833][MT6620 and MT5931] Driver migration
418  * comment out RLM APIs by CFG_RLM_MIGRATION.
419  *
420  * 06 21 2010 yuche.tsai
421  * [WPD00003839][MT6620 5931][P2P] Feature migration
422  * Update P2P Function call.
423  *
424  * 06 21 2010 cp.wu
425  * [WPD00003833][MT6620 and MT5931] Driver migration
426  * RSN/PRIVACY compilation flag awareness correction
427  *
428  * 06 21 2010 cp.wu
429  * [WPD00003833][MT6620 and MT5931] Driver migration
430  * specify correct value for management frames.
431  *
432  * 06 18 2010 cm.chang
433  * [WPD00003841][LITE Driver] Migrate RLM/CNM to host driver
434  * Provide cnmMgtPktAlloc() and alloc/free function of msg/buf
435  *
436  * 06 18 2010 wh.su
437  * [WPD00003840][MT6620 5931] Security migration
438  * migration from MT6620 firmware.
439  *
440  * 06 17 2010 yuche.tsai
441  * [WPD00003839][MT6620 5931][P2P] Feature migration
442  * Fix compile error when enable P2P function.
443  *
444  * 06 15 2010 cp.wu
445  * [WPD00003833][MT6620 and MT5931] Driver migration
446  * correct when ADHOC support is turned on.
447  *
448  * 06 15 2010 cp.wu
449  * [WPD00003833][MT6620 and MT5931] Driver migration
450  * add scan.c.
451  *
452  * 06 04 2010 george.huang
453  * [BORA00000678][MT6620]WiFi LP integration
454  * [PM] Support U-APSD for STA mode
455  *
456  * 05 28 2010 wh.su
457  * [BORA00000680][MT6620] Support the statistic for Microsoft os query
458  * adding the TKIP disallow join a HT AP code.
459  *
460  * 05 14 2010 kevin.huang
461  * [BORA00000794][WIFISYS][New Feature]Power Management Support
462  * Add more chance of JOIN retry for BG_SCAN
463  *
464  * 05 12 2010 kevin.huang
465  * [BORA00000794][WIFISYS][New Feature]Power Management Support
466  * Add Power Management - Legacy PS-POLL support.
467  *
468  * 04 29 2010 wh.su
469  * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
470  * adjsut the pre-authentication code.
471  *
472  * 04 27 2010 kevin.huang
473  * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
474  * Add Set Slot Time and Beacon Timeout Support for AdHoc Mode
475  *
476  * 04 24 2010 cm.chang
477  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
478  * g_aprBssInfo[] depends on CFG_SUPPORT_P2P and CFG_SUPPORT_BOW
479  *
480  * 04 19 2010 kevin.huang
481  * [BORA00000714][WIFISYS][New Feature]Beacon Timeout Support
482  * Add Beacon Timeout Support and will send Null frame to diagnose connection
483  *
484  * 04 13 2010 kevin.huang
485  * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
486  * Add new HW CH macro support
487  *
488  * 04 06 2010 wh.su
489  * [BORA00000680][MT6620] Support the statistic for Microsoft os query
490  * fixed the firmware return the broadcast frame at wrong tc.
491  *
492  * 03 29 2010 wh.su
493  * [BORA00000605][WIFISYS] Phase3 Integration
494  * let the rsn wapi IE always parsing.
495  *
496  * 03 24 2010 cm.chang
497  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
498  * Not carry  HT cap when being associated with b/g only AP
499  *
500  * 03 18 2010 kevin.huang
501  * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
502  * Solve the compile warning for 'return non-void' function
503  *
504  * 03 16 2010 kevin.huang
505  * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
506  * Add AdHoc Mode
507  *
508  * 03 10 2010 kevin.huang
509  * [BORA00000654][WIFISYS][New Feature] CNM Module - Ch Manager Support
510  *
511  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * Add Channel Manager for arbitration of JOIN and SCAN Req
512  *
513  * 03 03 2010 wh.su
514  * [BORA00000637][MT6620 Wi-Fi] [Bug] WPA2 pre-authentication timer not correctly initialize
515  * move the AIS specific variable for security to AIS specific structure.
516  *
517  * 03 01 2010 wh.su
518  * [BORA00000605][WIFISYS] Phase3 Integration
519  * Refine the variable and parameter for security.
520  *
521  * 02 26 2010 kevin.huang
522  * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
523  * Fix No PKT_INFO_T issue
524  *
525  * 02 26 2010 kevin.huang
526  * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
527  * Update outgoing ProbeRequest Frame's TX data rate
528  *
529  * 02 23 2010 wh.su
530  * [BORA00000592][MT6620 Wi-Fi] Adding the security related code for driver
531  * refine the scan procedure, reduce the WPA and WAPI IE parsing, and move the parsing to the time for join.
532  *
533  * 02 23 2010 kevin.huang
534  * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
535  * Add support scan channel 1~14 and update scan result's frequency infou1rwduu`wvpghlqg|n`slk+mpdkb
536  *
537  * 02 04 2010 kevin.huang
538  * [BORA00000603][WIFISYS] [New Feature] AAA Module Support
539  * Add AAA Module Support, Revise Net Type to Net Type Index for array lookup
540  *
541  * 01 27 2010 wh.su
542  * [BORA00000476][Wi-Fi][firmware] Add the security module initialize code
543  * add and fixed some security function.
544  *
545  * 01 22 2010 cm.chang
546  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
547  * Support protection and bandwidth switch
548  *
549  * 01 20 2010 kevin.huang
550  * [BORA00000569][WIFISYS] Phase 2 Integration Test
551  * Add PHASE_2_INTEGRATION_WORK_AROUND and CFG_SUPPORT_BCM flags
552  *
553  * 01 11 2010 kevin.huang
554  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
555  * Add Deauth and Disassoc Handler
556  *
557  * 01 08 2010 kevin.huang
558  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
559  *
560  * Refine Beacon processing, add read RF channel from RX Status
561  *
562  * 01 04 2010 tehuang.liu
563  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
564  * For working out the first connection Chariot-verified version
565  *
566  * 12 18 2009 cm.chang
567  * [BORA00000018]Integrate WIFI part into BORA for the 1st time
568  * .
569  *
570  * Dec 12 2009 mtk01104
571  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
572  * Modify u2EstimatedExtraIELen for probe request
573  *
574  * Dec 9 2009 mtk01104
575  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
576  * Add HT cap IE to probe request
577  *
578  * Dec 7 2009 mtk01461
579  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
580  * Fix lint warning
581  *
582  *
583  * Dec 3 2009 mtk01461
584  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
585  * Update the process of SCAN Result by adding more Phy Attributes
586  *
587  * Dec 1 2009 mtk01088
588  * [BORA00000476] [Wi-Fi][firmware] Add the security module initialize code
589  * adjust the function and code for meet the new define
590  *
591  * Nov 30 2009 mtk01461
592  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
593  * Rename u4RSSI to i4RSSI
594  *
595  * Nov 30 2009 mtk01461
596  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
597  * Report event of scan result to host
598  *
599  * Nov 26 2009 mtk01461
600  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
601  * Fix SCAN Record update
602  *
603  * Nov 24 2009 mtk01461
604  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
605  * Revise MGMT Handler with Retain Status and Integrate with TXM
606  *
607  * Nov 23 2009 mtk01461
608  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
609  * Add (Ext)Support Rate Set IE to ProbeReq
610  *
611  * Nov 20 2009 mtk02468
612  * [BORA00000337] To check in codes for FPGA emulation
613  * Removed the use of SW_RFB->u2FrameLength
614  *
615  * Nov 20 2009 mtk01461
616  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
617  * Fix uninitial aucMacAddress[] for ProbeReq
618  *
619  * Nov 16 2009 mtk01461
620  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
621  * Add scanSearchBssDescByPolicy()
622  *
623  * Nov 5 2009 mtk01461
624  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
625  * Add Send Probe Request Frame
626  *
627  * Oct 30 2009 mtk01461
628  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
629  *
630 */
631
632 /*******************************************************************************
633 *                         C O M P I L E R   F L A G S
634 ********************************************************************************
635 */
636
637 /*******************************************************************************
638 *                    E X T E R N A L   R E F E R E N C E S
639 ********************************************************************************
640 */
641 #include "precomp.h"
642
643 /*******************************************************************************
644 *                              C O N S T A N T S
645 ********************************************************************************
646 */
647 #define REPLICATED_BEACON_TIME_THRESHOLD        (3000)
648 #define REPLICATED_BEACON_FRESH_PERIOD          (10000)
649 #define REPLICATED_BEACON_STRENGTH_THRESHOLD    (32)
650
651 #define ROAMING_NO_SWING_RCPI_STEP              (10)
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 /*******************************************************************************
664 *                           P R I V A T E   D A T A
665 ********************************************************************************
666 */
667
668 /*******************************************************************************
669 *                                 M A C R O S
670 ********************************************************************************
671 */
672
673 /*******************************************************************************
674 *                   F U N C T I O N   D E C L A R A T I O N S
675 ********************************************************************************
676 */
677
678 /*******************************************************************************
679 *                              F U N C T I O N S
680 ********************************************************************************
681 */
682 /*----------------------------------------------------------------------------*/
683 /*!
684 * @brief This function is used by SCN to initialize its variables
685 *
686 * @param (none)
687 *
688 * @return (none)
689 */
690 /*----------------------------------------------------------------------------*/
691 VOID
692 scnInit (
693     IN P_ADAPTER_T prAdapter
694     )
695 {
696     P_SCAN_INFO_T prScanInfo;
697     P_BSS_DESC_T prBSSDesc;
698     PUINT_8 pucBSSBuff;
699     UINT_32 i;
700
701
702     ASSERT(prAdapter);
703
704     prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
705     pucBSSBuff = &prScanInfo->aucScanBuffer[0];
706
707
708     DBGLOG(SCN, INFO, ("->scnInit()\n"));
709
710     //4 <1> Reset STATE and Message List
711     prScanInfo->eCurrentState = SCAN_STATE_IDLE;
712
713     prScanInfo->rLastScanCompletedTime = (OS_SYSTIME)0;
714
715     LINK_INITIALIZE(&prScanInfo->rPendingMsgList);
716
717
718     //4 <2> Reset link list of BSS_DESC_T
719     kalMemZero((PVOID) pucBSSBuff, SCN_MAX_BUFFER_SIZE);
720
721     LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList);
722     LINK_INITIALIZE(&prScanInfo->rBSSDescList);
723
724     for (i = 0; i < CFG_MAX_NUM_BSS_LIST; i++) {
725
726         prBSSDesc = (P_BSS_DESC_T)pucBSSBuff;
727
728         LINK_INSERT_TAIL(&prScanInfo->rFreeBSSDescList, &prBSSDesc->rLinkEntry);
729
730         pucBSSBuff += ALIGN_4(sizeof(BSS_DESC_T));
731     }
732     /* Check if the memory allocation consist with this initialization function */
733     ASSERT(((UINT_32)pucBSSBuff - (UINT_32)&prScanInfo->aucScanBuffer[0]) == SCN_MAX_BUFFER_SIZE);
734
735     /* reset freest channel information */
736     prScanInfo->fgIsSparseChannelValid = FALSE;
737
738     return;
739 } /* end of scnInit() */
740
741
742 /*----------------------------------------------------------------------------*/
743 /*!
744 * @brief This function is used by SCN to uninitialize its variables
745 *
746 * @param (none)
747 *
748 * @return (none)
749 */
750 /*----------------------------------------------------------------------------*/
751 VOID
752 scnUninit (
753     IN P_ADAPTER_T prAdapter
754     )
755 {
756     P_SCAN_INFO_T prScanInfo;
757
758
759     ASSERT(prAdapter);
760     prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
761
762     DBGLOG(SCN, INFO, ("->scnUninit()\n"));
763
764     //4 <1> Reset STATE and Message List
765     prScanInfo->eCurrentState = SCAN_STATE_IDLE;
766
767     prScanInfo->rLastScanCompletedTime = (OS_SYSTIME)0;
768
769     /* NOTE(Kevin): Check rPendingMsgList ? */
770
771     //4 <2> Reset link list of BSS_DESC_T
772     LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList);
773     LINK_INITIALIZE(&prScanInfo->rBSSDescList);
774
775     return;
776 } /* end of scnUninit() */
777
778
779
780 /*----------------------------------------------------------------------------*/
781 /*!
782 * @brief Find the corresponding BSS Descriptor according to given BSSID
783 *
784 * @param[in] prAdapter          Pointer to the Adapter structure.
785 * @param[in] aucBSSID           Given BSSID.
786 *
787 * @return   Pointer to BSS Descriptor, if found. NULL, if not found
788 */
789 /*----------------------------------------------------------------------------*/
790 P_BSS_DESC_T
791 scanSearchBssDescByBssid (
792     IN P_ADAPTER_T prAdapter,
793     IN UINT_8 aucBSSID[]
794     )
795 {
796     return scanSearchBssDescByBssidAndSsid(prAdapter,
797             aucBSSID,
798             FALSE,
799             NULL);
800 }
801
802
803 /*----------------------------------------------------------------------------*/
804 /*!
805 * @brief Find the corresponding BSS Descriptor according to given BSSID
806 *
807 * @param[in] prAdapter          Pointer to the Adapter structure.
808 * @param[in] aucBSSID           Given BSSID.
809 * @param[in] fgCheckSsid        Need to check SSID or not. (for multiple SSID with single BSSID cases)
810 * @param[in] prSsid             Specified SSID
811 *
812 * @return   Pointer to BSS Descriptor, if found. NULL, if not found
813 */
814 /*----------------------------------------------------------------------------*/
815 P_BSS_DESC_T
816 scanSearchBssDescByBssidAndSsid (
817     IN P_ADAPTER_T prAdapter,
818     IN UINT_8 aucBSSID[],
819     IN BOOLEAN fgCheckSsid,
820     IN P_PARAM_SSID_T prSsid
821     )
822 {
823     P_SCAN_INFO_T prScanInfo;
824     P_LINK_T prBSSDescList;
825     P_BSS_DESC_T prBssDesc;
826     P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T)NULL;
827
828
829     ASSERT(prAdapter);
830     ASSERT(aucBSSID);
831
832     prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
833
834     prBSSDescList = &prScanInfo->rBSSDescList;
835
836     /* Search BSS Desc from current SCAN result list. */
837     LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
838
839         if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) {
840             if(fgCheckSsid == FALSE || prSsid == NULL) {
841                 return prBssDesc;
842             }
843             else {
844                 if(EQUAL_SSID(prBssDesc->aucSSID,
845                             prBssDesc->ucSSIDLen,
846                             prSsid->aucSsid,
847                             prSsid->u4SsidLen)) {
848                     return prBssDesc;
849                 }
850                 else if(prDstBssDesc == NULL && prBssDesc->fgIsHiddenSSID == TRUE) {
851                     prDstBssDesc = prBssDesc;
852                 }
853                 else {
854                     /* 20120206 frog: Equal BSSID but not SSID, SSID not hidden, SSID must be updated. */
855                     COPY_SSID(prBssDesc->aucSSID,
856                             prBssDesc->ucSSIDLen,
857                             prSsid->aucSsid,
858                             prSsid->u4SsidLen);
859                     return prBssDesc;
860                 }
861             }
862         }
863     }
864
865     return prDstBssDesc;
866
867 } /* end of scanSearchBssDescByBssid() */
868
869
870 /*----------------------------------------------------------------------------*/
871 /*!
872 * @brief Find the corresponding BSS Descriptor according to given Transmitter Address.
873 *
874 * @param[in] prAdapter          Pointer to the Adapter structure.
875 * @param[in] aucSrcAddr         Given Source Address(TA).
876 *
877 * @return   Pointer to BSS Descriptor, if found. NULL, if not found
878 */
879 /*----------------------------------------------------------------------------*/
880 P_BSS_DESC_T
881 scanSearchBssDescByTA (
882     IN P_ADAPTER_T prAdapter,
883     IN UINT_8 aucSrcAddr[]
884     )
885 {
886     return scanSearchBssDescByTAAndSsid(prAdapter,
887             aucSrcAddr,
888             FALSE,
889             NULL);
890 }
891
892 /*----------------------------------------------------------------------------*/
893 /*!
894 * @brief Find the corresponding BSS Descriptor according to given Transmitter Address.
895 *
896 * @param[in] prAdapter          Pointer to the Adapter structure.
897 * @param[in] aucSrcAddr         Given Source Address(TA).
898 * @param[in] fgCheckSsid        Need to check SSID or not. (for multiple SSID with single BSSID cases)
899 * @param[in] prSsid             Specified SSID
900 *
901 * @return   Pointer to BSS Descriptor, if found. NULL, if not found
902 */
903 /*----------------------------------------------------------------------------*/
904 P_BSS_DESC_T
905 scanSearchBssDescByTAAndSsid (
906     IN P_ADAPTER_T prAdapter,
907     IN UINT_8 aucSrcAddr[],
908     IN BOOLEAN fgCheckSsid,
909     IN P_PARAM_SSID_T prSsid
910     )
911 {
912     P_SCAN_INFO_T prScanInfo;
913     P_LINK_T prBSSDescList;
914     P_BSS_DESC_T prBssDesc;
915     P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T)NULL;
916
917
918     ASSERT(prAdapter);
919     ASSERT(aucSrcAddr);
920
921     prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
922
923     prBSSDescList = &prScanInfo->rBSSDescList;
924
925     /* Search BSS Desc from current SCAN result list. */
926     LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
927
928         if (EQUAL_MAC_ADDR(prBssDesc->aucSrcAddr, aucSrcAddr)) {
929             if(fgCheckSsid == FALSE || prSsid == NULL) {
930                 return prBssDesc;
931             }
932             else {
933                 if(EQUAL_SSID(prBssDesc->aucSSID,
934                             prBssDesc->ucSSIDLen,
935                             prSsid->aucSsid,
936                             prSsid->u4SsidLen)) {
937                     return prBssDesc;
938                 }
939                 else if(prDstBssDesc == NULL && prBssDesc->fgIsHiddenSSID == TRUE) {
940                     prDstBssDesc = prBssDesc;
941                 }
942             }
943         }
944     }
945
946     return prDstBssDesc;
947
948 } /* end of scanSearchBssDescByTA() */
949
950
951 /*----------------------------------------------------------------------------*/
952 /*!
953 * @brief Find the corresponding BSS Descriptor according to
954 *        given eBSSType, BSSID and Transmitter Address
955 *
956 * @param[in] prAdapter  Pointer to the Adapter structure.
957 * @param[in] eBSSType   BSS Type of incoming Beacon/ProbeResp frame.
958 * @param[in] aucBSSID   Given BSSID of Beacon/ProbeResp frame.
959 * @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame.
960 *
961 * @return   Pointer to BSS Descriptor, if found. NULL, if not found
962 */
963 /*----------------------------------------------------------------------------*/
964 P_BSS_DESC_T
965 scanSearchExistingBssDesc (
966     IN P_ADAPTER_T prAdapter,
967     IN ENUM_BSS_TYPE_T eBSSType,
968     IN UINT_8 aucBSSID[],
969     IN UINT_8 aucSrcAddr[]
970     )
971 {
972     return scanSearchExistingBssDescWithSsid(prAdapter,
973             eBSSType,
974             aucBSSID,
975             aucSrcAddr,
976             FALSE,
977             NULL);
978 }
979
980
981 /*----------------------------------------------------------------------------*/
982 /*!
983 * @brief Find the corresponding BSS Descriptor according to
984 *        given eBSSType, BSSID and Transmitter Address
985 *
986 * @param[in] prAdapter  Pointer to the Adapter structure.
987 * @param[in] eBSSType   BSS Type of incoming Beacon/ProbeResp frame.
988 * @param[in] aucBSSID   Given BSSID of Beacon/ProbeResp frame.
989 * @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame.
990 * @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases)
991 * @param[in] prSsid     Specified SSID
992 *
993 * @return   Pointer to BSS Descriptor, if found. NULL, if not found
994 */
995 /*----------------------------------------------------------------------------*/
996 P_BSS_DESC_T
997 scanSearchExistingBssDescWithSsid (
998     IN P_ADAPTER_T prAdapter,
999     IN ENUM_BSS_TYPE_T eBSSType,
1000     IN UINT_8 aucBSSID[],
1001     IN UINT_8 aucSrcAddr[],
1002     IN BOOLEAN fgCheckSsid,
1003     IN P_PARAM_SSID_T prSsid
1004     )
1005 {
1006     P_SCAN_INFO_T prScanInfo;
1007     P_BSS_DESC_T prBssDesc, prIBSSBssDesc;
1008
1009     ASSERT(prAdapter);
1010     ASSERT(aucSrcAddr);
1011
1012     prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1013
1014
1015     switch (eBSSType) {
1016     case BSS_TYPE_P2P_DEVICE:
1017         fgCheckSsid = FALSE;
1018     case BSS_TYPE_INFRASTRUCTURE:
1019     case BSS_TYPE_BOW_DEVICE:
1020     {
1021         prBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, fgCheckSsid, prSsid);
1022
1023         /* if (eBSSType == prBssDesc->eBSSType) */
1024
1025         return prBssDesc;
1026     }
1027
1028     case BSS_TYPE_IBSS:
1029     {
1030         prIBSSBssDesc = scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, fgCheckSsid, prSsid);
1031         prBssDesc = scanSearchBssDescByTAAndSsid(prAdapter, aucSrcAddr, fgCheckSsid, prSsid);
1032
1033         /* NOTE(Kevin):
1034          * Rules to maintain the SCAN Result:
1035          * For AdHoc -
1036          *    CASE I    We have TA1(BSSID1), but it change its BSSID to BSSID2
1037          *              -> Update TA1 entry's BSSID.
1038          *    CASE II   We have TA1(BSSID1), and get TA1(BSSID1) again
1039          *              -> Update TA1 entry's contain.
1040          *    CASE III  We have a SCAN result TA1(BSSID1), and TA2(BSSID2). Sooner or
1041          *               later, TA2 merge into TA1, we get TA2(BSSID1)
1042          *              -> Remove TA2 first and then replace TA1 entry's TA with TA2, Still have only one entry of BSSID.
1043          *    CASE IV   We have a SCAN result TA1(BSSID1), and another TA2 also merge into BSSID1.
1044          *              -> Replace TA1 entry's TA with TA2, Still have only one entry.
1045          *    CASE V    New IBSS
1046          *              -> Add this one to SCAN result.
1047          */
1048         if (prBssDesc) {
1049             if ((!prIBSSBssDesc) || // CASE I
1050                 (prBssDesc == prIBSSBssDesc)) { // CASE II
1051
1052                 return prBssDesc;
1053             }
1054             else { // CASE III
1055                 P_LINK_T prBSSDescList;
1056                 P_LINK_T prFreeBSSDescList;
1057
1058
1059                 prBSSDescList = &prScanInfo->rBSSDescList;
1060                 prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1061
1062                 /* Remove this BSS Desc from the BSS Desc list */
1063                 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1064
1065                 /* Return this BSS Desc to the free BSS Desc list. */
1066                 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1067
1068                 return prIBSSBssDesc;
1069             }
1070         }
1071
1072         if (prIBSSBssDesc) { // CASE IV
1073
1074             return prIBSSBssDesc;
1075         }
1076
1077         // CASE V
1078         break; // Return NULL;
1079     }
1080
1081     default:
1082         break;
1083     }
1084
1085
1086     return (P_BSS_DESC_T)NULL;
1087
1088 } /* end of scanSearchExistingBssDesc() */
1089
1090
1091 /*----------------------------------------------------------------------------*/
1092 /*!
1093 * @brief Delete BSS Descriptors from current list according to given Remove Policy.
1094 *
1095 * @param[in] u4RemovePolicy     Remove Policy.
1096 *
1097 * @return (none)
1098 */
1099 /*----------------------------------------------------------------------------*/
1100 VOID
1101 scanRemoveBssDescsByPolicy (
1102     IN P_ADAPTER_T prAdapter,
1103     IN UINT_32 u4RemovePolicy
1104     )
1105 {
1106     P_CONNECTION_SETTINGS_T prConnSettings;
1107     P_SCAN_INFO_T prScanInfo;
1108     P_LINK_T prBSSDescList;
1109     P_LINK_T prFreeBSSDescList;
1110     P_BSS_DESC_T prBssDesc;
1111
1112
1113     ASSERT(prAdapter);
1114
1115     prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
1116     prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1117     prBSSDescList = &prScanInfo->rBSSDescList;
1118     prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1119
1120     //DBGLOG(SCN, TRACE, ("Before Remove - Number Of SCAN Result = %ld\n",
1121         //prBSSDescList->u4NumElem));
1122
1123     if (u4RemovePolicy & SCN_RM_POLICY_TIMEOUT) {
1124         P_BSS_DESC_T prBSSDescNext;
1125         OS_SYSTIME rCurrentTime;
1126
1127
1128         GET_CURRENT_SYSTIME(&rCurrentTime);
1129
1130         /* Search BSS Desc from current SCAN result list. */
1131         LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1132
1133             if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
1134                 (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
1135                 /* Don't remove the one currently we are connected. */
1136                 continue;
1137             }
1138
1139             if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
1140                                    SEC_TO_SYSTIME(SCN_BSS_DESC_REMOVE_TIMEOUT_SEC)) ) {
1141
1142                 //DBGLOG(SCN, TRACE, ("Remove TIMEOUT BSS DESC(%#x): MAC: "MACSTR", Current Time = %08lx, Update Time = %08lx\n",
1143                     //prBssDesc, MAC2STR(prBssDesc->aucBSSID), rCurrentTime, prBssDesc->rUpdateTime));
1144
1145                 /* Remove this BSS Desc from the BSS Desc list */
1146                 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1147
1148                 /* Return this BSS Desc to the free BSS Desc list. */
1149                 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1150             }
1151         }
1152     }
1153     else if (u4RemovePolicy & SCN_RM_POLICY_OLDEST_HIDDEN) {
1154         P_BSS_DESC_T prBssDescOldest = (P_BSS_DESC_T)NULL;
1155
1156
1157         /* Search BSS Desc from current SCAN result list. */
1158         LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1159
1160             if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
1161                 (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
1162                 /* Don't remove the one currently we are connected. */
1163                 continue;
1164             }
1165
1166             if (!prBssDesc->fgIsHiddenSSID) {
1167                 continue;
1168             }
1169
1170             if (!prBssDescOldest) { /* 1st element */
1171                 prBssDescOldest = prBssDesc;
1172                 continue;
1173             }
1174
1175             if (TIME_BEFORE(prBssDesc->rUpdateTime, prBssDescOldest->rUpdateTime)) {
1176                 prBssDescOldest = prBssDesc;
1177             }
1178         }
1179
1180         if (prBssDescOldest) {
1181
1182             //DBGLOG(SCN, TRACE, ("Remove OLDEST HIDDEN BSS DESC(%#x): MAC: "MACSTR", Update Time = %08lx\n",
1183                 //prBssDescOldest, MAC2STR(prBssDescOldest->aucBSSID), prBssDescOldest->rUpdateTime));
1184
1185             /* Remove this BSS Desc from the BSS Desc list */
1186             LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescOldest);
1187
1188             /* Return this BSS Desc to the free BSS Desc list. */
1189             LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDescOldest->rLinkEntry);
1190         }
1191     }
1192     else if (u4RemovePolicy & SCN_RM_POLICY_SMART_WEAKEST) {
1193         P_BSS_DESC_T prBssDescWeakest = (P_BSS_DESC_T)NULL;
1194         P_BSS_DESC_T prBssDescWeakestSameSSID = (P_BSS_DESC_T)NULL;
1195         UINT_32 u4SameSSIDCount = 0;
1196
1197
1198         /* Search BSS Desc from current SCAN result list. */
1199         LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1200
1201             if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
1202                 (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
1203                 /* Don't remove the one currently we are connected. */
1204                 continue;
1205             }
1206
1207             if ((!prBssDesc->fgIsHiddenSSID) &&
1208                 (EQUAL_SSID(prBssDesc->aucSSID,
1209                            prBssDesc->ucSSIDLen,
1210                            prConnSettings->aucSSID,
1211                            prConnSettings->ucSSIDLen))) {
1212
1213                 u4SameSSIDCount++;
1214
1215                 if (!prBssDescWeakestSameSSID) {
1216                     prBssDescWeakestSameSSID = prBssDesc;
1217                 }
1218                 else if (prBssDesc->ucRCPI < prBssDescWeakestSameSSID->ucRCPI) {
1219                     prBssDescWeakestSameSSID = prBssDesc;
1220                 }
1221             }
1222
1223             if (!prBssDescWeakest) { /* 1st element */
1224                 prBssDescWeakest = prBssDesc;
1225                 continue;
1226             }
1227
1228             if (prBssDesc->ucRCPI < prBssDescWeakest->ucRCPI) {
1229                 prBssDescWeakest = prBssDesc;
1230             }
1231
1232         }
1233
1234         if ((u4SameSSIDCount >= SCN_BSS_DESC_SAME_SSID_THRESHOLD) &&
1235             (prBssDescWeakestSameSSID)) {
1236             prBssDescWeakest = prBssDescWeakestSameSSID;
1237         }
1238
1239         if (prBssDescWeakest) {
1240
1241             //DBGLOG(SCN, TRACE, ("Remove WEAKEST BSS DESC(%#x): MAC: "MACSTR", Update Time = %08lx\n",
1242                 //prBssDescOldest, MAC2STR(prBssDescOldest->aucBSSID), prBssDescOldest->rUpdateTime));
1243
1244             /* Remove this BSS Desc from the BSS Desc list */
1245             LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescWeakest);
1246
1247             /* Return this BSS Desc to the free BSS Desc list. */
1248             LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDescWeakest->rLinkEntry);
1249         }
1250     }
1251     else if (u4RemovePolicy & SCN_RM_POLICY_ENTIRE) {
1252         P_BSS_DESC_T prBSSDescNext;
1253
1254         LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1255
1256             if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
1257                 (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
1258                 /* Don't remove the one currently we are connected. */
1259                 continue;
1260             }
1261
1262             /* Remove this BSS Desc from the BSS Desc list */
1263             LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1264
1265             /* Return this BSS Desc to the free BSS Desc list. */
1266             LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1267         }
1268
1269     }
1270
1271     return;
1272
1273 } /* end of scanRemoveBssDescsByPolicy() */
1274
1275
1276 /*----------------------------------------------------------------------------*/
1277 /*!
1278 * @brief Delete BSS Descriptors from current list according to given BSSID.
1279 *
1280 * @param[in] prAdapter  Pointer to the Adapter structure.
1281 * @param[in] aucBSSID   Given BSSID.
1282 *
1283 * @return (none)
1284 */
1285 /*----------------------------------------------------------------------------*/
1286 VOID
1287 scanRemoveBssDescByBssid (
1288     IN P_ADAPTER_T prAdapter,
1289     IN UINT_8 aucBSSID[]
1290     )
1291 {
1292     P_SCAN_INFO_T prScanInfo;
1293     P_LINK_T prBSSDescList;
1294     P_LINK_T prFreeBSSDescList;
1295     P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T)NULL;
1296     P_BSS_DESC_T prBSSDescNext;
1297
1298
1299     ASSERT(prAdapter);
1300     ASSERT(aucBSSID);
1301
1302     prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1303     prBSSDescList = &prScanInfo->rBSSDescList;
1304     prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1305
1306     /* Check if such BSS Descriptor exists in a valid list */
1307     LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1308
1309         if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) {
1310
1311             /* Remove this BSS Desc from the BSS Desc list */
1312             LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1313
1314             /* Return this BSS Desc to the free BSS Desc list. */
1315             LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1316
1317             /* BSSID is not unique, so need to traverse whols link-list */
1318         }
1319     }
1320
1321     return;
1322 } /* end of scanRemoveBssDescByBssid() */
1323
1324
1325 /*----------------------------------------------------------------------------*/
1326 /*!
1327 * @brief Delete BSS Descriptors from current list according to given band configuration
1328 *
1329 * @param[in] prAdapter  Pointer to the Adapter structure.
1330 * @param[in] eBand      Given band
1331 * @param[in] eNetTypeIndex  AIS - Remove IBSS/Infrastructure BSS
1332 *                           BOW - Remove BOW BSS
1333 *                           P2P - Remove P2P BSS
1334 *
1335 * @return (none)
1336 */
1337 /*----------------------------------------------------------------------------*/
1338 VOID
1339 scanRemoveBssDescByBandAndNetwork (
1340     IN P_ADAPTER_T prAdapter,
1341     IN ENUM_BAND_T eBand,
1342     IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex
1343     )
1344 {
1345     P_SCAN_INFO_T prScanInfo;
1346     P_LINK_T prBSSDescList;
1347     P_LINK_T prFreeBSSDescList;
1348     P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T)NULL;
1349     P_BSS_DESC_T prBSSDescNext;
1350     BOOLEAN fgToRemove;
1351
1352     ASSERT(prAdapter);
1353     ASSERT(eBand <= BAND_NUM);
1354     ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM);
1355
1356     prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1357     prBSSDescList = &prScanInfo->rBSSDescList;
1358     prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1359
1360
1361     if(eBand == BAND_NULL) {
1362         return; /* no need to do anything, keep all scan result */
1363     }
1364
1365     /* Check if such BSS Descriptor exists in a valid list */
1366     LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1367         fgToRemove = FALSE;
1368
1369         if(prBssDesc->eBand == eBand) {
1370             switch (eNetTypeIndex) {
1371             case NETWORK_TYPE_AIS_INDEX:
1372                 if((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE)
1373                         || (prBssDesc->eBSSType == BSS_TYPE_IBSS)) {
1374                     fgToRemove = TRUE;
1375                 }
1376                 break;
1377
1378             case NETWORK_TYPE_P2P_INDEX:
1379                 if(prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) {
1380                     fgToRemove = TRUE;
1381                 }
1382                 break;
1383                 
1384             case NETWORK_TYPE_BOW_INDEX:
1385                 if(prBssDesc->eBSSType == BSS_TYPE_BOW_DEVICE) {
1386                     fgToRemove = TRUE;
1387                 }
1388                 break;
1389             
1390             default:
1391                 ASSERT(0);
1392                 break;
1393             }
1394         }
1395
1396         if(fgToRemove == TRUE) {
1397             /* Remove this BSS Desc from the BSS Desc list */
1398             LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1399
1400             /* Return this BSS Desc to the free BSS Desc list. */
1401             LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1402         }
1403     }
1404
1405     return;
1406 } /* end of scanRemoveBssDescByBand() */
1407
1408
1409 /*----------------------------------------------------------------------------*/
1410 /*!
1411 * @brief Clear the CONNECTION FLAG of a specified BSS Descriptor.
1412 *
1413 * @param[in] aucBSSID   Given BSSID.
1414 *
1415 * @return (none)
1416 */
1417 /*----------------------------------------------------------------------------*/
1418 VOID
1419 scanRemoveConnFlagOfBssDescByBssid (
1420     IN P_ADAPTER_T prAdapter,
1421     IN UINT_8 aucBSSID[]
1422     )
1423 {
1424     P_SCAN_INFO_T prScanInfo;
1425     P_LINK_T prBSSDescList;
1426     P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T)NULL;
1427
1428
1429     ASSERT(prAdapter);
1430     ASSERT(aucBSSID);
1431
1432     prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1433     prBSSDescList = &prScanInfo->rBSSDescList;
1434
1435     /* Search BSS Desc from current SCAN result list. */
1436     LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1437
1438         if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) {
1439             prBssDesc->fgIsConnected = FALSE;
1440             prBssDesc->fgIsConnecting = FALSE;
1441
1442             /* BSSID is not unique, so need to traverse whols link-list */
1443         }
1444     }
1445
1446     return;
1447
1448 } /* end of scanRemoveConnectionFlagOfBssDescByBssid() */
1449
1450
1451 /*----------------------------------------------------------------------------*/
1452 /*!
1453 * @brief Allocate new BSS_DESC_T
1454 *
1455 * @param[in] prAdapter          Pointer to the Adapter structure.
1456 *
1457 * @return   Pointer to BSS Descriptor, if has free space. NULL, if has no space.
1458 */
1459 /*----------------------------------------------------------------------------*/
1460 P_BSS_DESC_T
1461 scanAllocateBssDesc (
1462     IN P_ADAPTER_T prAdapter
1463     )
1464 {
1465     P_SCAN_INFO_T prScanInfo;
1466     P_LINK_T prFreeBSSDescList;
1467     P_BSS_DESC_T prBssDesc;
1468
1469
1470     ASSERT(prAdapter);
1471     prScanInfo =  &(prAdapter->rWifiVar.rScanInfo);
1472
1473     prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1474
1475     LINK_REMOVE_HEAD(prFreeBSSDescList, prBssDesc, P_BSS_DESC_T);
1476
1477     if (prBssDesc) {
1478         P_LINK_T prBSSDescList;
1479
1480         kalMemZero(prBssDesc, sizeof(BSS_DESC_T));
1481
1482 #if CFG_ENABLE_WIFI_DIRECT
1483         LINK_INITIALIZE(&(prBssDesc->rP2pDeviceList));
1484         prBssDesc->fgIsP2PPresent = FALSE;
1485 #endif /* CFG_ENABLE_WIFI_DIRECT */
1486
1487         prBSSDescList = &prScanInfo->rBSSDescList;
1488
1489         /* NOTE(Kevin): In current design, this new empty BSS_DESC_T will be
1490          * inserted to BSSDescList immediately.
1491          */
1492         LINK_INSERT_TAIL(prBSSDescList, &prBssDesc->rLinkEntry);
1493     }
1494
1495     return prBssDesc;
1496
1497 } /* end of scanAllocateBssDesc() */
1498
1499
1500 /*----------------------------------------------------------------------------*/
1501 /*!
1502 * @brief This API parses Beacon/ProbeResp frame and insert extracted BSS_DESC_T
1503 *        with IEs into prAdapter->rWifiVar.rScanInfo.aucScanBuffer
1504 *
1505 * @param[in] prAdapter      Pointer to the Adapter structure.
1506 * @param[in] prSwRfb        Pointer to the receiving frame buffer.
1507 *
1508 * @return   Pointer to BSS Descriptor
1509 *           NULL if the Beacon/ProbeResp frame is invalid
1510 */
1511 /*----------------------------------------------------------------------------*/
1512 P_BSS_DESC_T
1513 scanAddToBssDesc (
1514     IN P_ADAPTER_T prAdapter,
1515     IN P_SW_RFB_T prSwRfb
1516     )
1517 {
1518     P_BSS_DESC_T prBssDesc = NULL;
1519     UINT_16 u2CapInfo;
1520     ENUM_BSS_TYPE_T eBSSType = BSS_TYPE_INFRASTRUCTURE;
1521
1522     PUINT_8 pucIE;
1523     UINT_16 u2IELength;
1524     UINT_16 u2Offset = 0;
1525
1526     P_WLAN_BEACON_FRAME_T prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T)NULL;
1527     P_IE_SSID_T prIeSsid = (P_IE_SSID_T)NULL;
1528     P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T)NULL;
1529     P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T)NULL;
1530     P_HIF_RX_HEADER_T prHifRxHdr;
1531     UINT_8 ucHwChannelNum = 0;
1532     UINT_8 ucIeDsChannelNum = 0;
1533     UINT_8 ucIeHtChannelNum = 0;
1534     BOOLEAN fgIsValidSsid = FALSE, fgEscape = FALSE;
1535     PARAM_SSID_T rSsid;
1536     UINT_64 u8Timestamp;
1537
1538     UINT_32 i;
1539     UINT_8 ucSSIDChar;
1540
1541     ASSERT(prAdapter);
1542     ASSERT(prSwRfb);
1543
1544     prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T)prSwRfb->pvHeader;
1545
1546     WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2CapInfo, &u2CapInfo);
1547     WLAN_GET_FIELD_64(&prWlanBeaconFrame->au4Timestamp[0], &u8Timestamp);
1548
1549     // decide BSS type
1550     switch (u2CapInfo & CAP_INFO_BSS_TYPE) {
1551     case CAP_INFO_ESS:
1552         /* It can also be Group Owner of P2P Group. */
1553         eBSSType = BSS_TYPE_INFRASTRUCTURE;
1554         break;
1555
1556     case CAP_INFO_IBSS:
1557         eBSSType = BSS_TYPE_IBSS;
1558         break;
1559     case 0:
1560         /* The P2P Device shall set the ESS bit of the Capabilities field in the Probe Response fame to 0 and IBSS bit to 0. (3.1.2.1.1) */
1561         eBSSType = BSS_TYPE_P2P_DEVICE;
1562         break;
1563
1564 #if CFG_ENABLE_BT_OVER_WIFI
1565         // @TODO: add rule to identify BOW beacons
1566 #endif
1567
1568     default:
1569         return NULL;
1570     }
1571
1572     //4 <1.1> Pre-parse SSID IE
1573     pucIE = prWlanBeaconFrame->aucInfoElem;
1574     u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
1575         (UINT_16)OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]);
1576
1577     if (u2IELength > CFG_IE_BUFFER_SIZE) {
1578         u2IELength = CFG_IE_BUFFER_SIZE;
1579     }
1580
1581     IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
1582         switch (IE_ID(pucIE)) {
1583         case ELEM_ID_SSID:
1584             if (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID) {
1585                 ucSSIDChar = '\0';
1586
1587                 /* D-Link DWL-900AP+ */
1588                 if (IE_LEN(pucIE) == 0) {
1589                     fgIsValidSsid = FALSE;
1590                 }
1591                 /* Cisco AP1230A - (IE_LEN(pucIE) == 1) && (SSID_IE(pucIE)->aucSSID[0] == '\0') */
1592                 /* Linksys WRK54G/ASUS WL520g - (IE_LEN(pucIE) == n) && (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') */
1593                 else {
1594                     for (i = 0; i < IE_LEN(pucIE); i++) {
1595                         ucSSIDChar |= SSID_IE(pucIE)->aucSSID[i];
1596                     }
1597
1598                     if (ucSSIDChar) {
1599                         fgIsValidSsid = TRUE;
1600                     }
1601                 }
1602
1603                 /* Update SSID to BSS Descriptor only if SSID is not hidden. */
1604                 if (fgIsValidSsid == TRUE) {
1605                     COPY_SSID(rSsid.aucSsid,
1606                               rSsid.u4SsidLen,
1607                               SSID_IE(pucIE)->aucSSID,
1608                               SSID_IE(pucIE)->ucLength);
1609                 }
1610             }
1611             fgEscape = TRUE;
1612             break;
1613         default:
1614             break;
1615         }
1616
1617         if(fgEscape == TRUE) {
1618             break;
1619         }
1620     }
1621
1622
1623     //4 <1.2> Replace existing BSS_DESC_T or allocate a new one
1624     prBssDesc = scanSearchExistingBssDescWithSsid(prAdapter,
1625                                           eBSSType,
1626                                           (PUINT_8)prWlanBeaconFrame->aucBSSID,
1627                                           (PUINT_8)prWlanBeaconFrame->aucSrcAddr,
1628                                           fgIsValidSsid,
1629                                           fgIsValidSsid == TRUE ? &rSsid : NULL);
1630
1631     if (prBssDesc == (P_BSS_DESC_T)NULL) {
1632         do {
1633             //4 <1.2.1> First trial of allocation
1634             prBssDesc = scanAllocateBssDesc(prAdapter);
1635             if (prBssDesc) {
1636                 break;
1637             }
1638
1639             //4 <1.2.2> Hidden is useless, remove the oldest hidden ssid. (for passive scan)
1640             scanRemoveBssDescsByPolicy(prAdapter,
1641                     (SCN_RM_POLICY_EXCLUDE_CONNECTED | SCN_RM_POLICY_OLDEST_HIDDEN));
1642
1643             //4 <1.2.3> Second tail of allocation
1644             prBssDesc = scanAllocateBssDesc(prAdapter);
1645             if (prBssDesc) {
1646                 break;
1647             }
1648
1649             //4 <1.2.4> Remove the weakest one
1650             /* If there are more than half of BSS which has the same ssid as connection
1651              * setting, remove the weakest one from them.
1652              * Else remove the weakest one.
1653              */
1654             scanRemoveBssDescsByPolicy(prAdapter,
1655                     (SCN_RM_POLICY_EXCLUDE_CONNECTED | SCN_RM_POLICY_SMART_WEAKEST));
1656
1657             //4 <1.2.5> reallocation
1658             prBssDesc = scanAllocateBssDesc(prAdapter);
1659             if (prBssDesc) {
1660                 break;
1661             }
1662
1663             //4 <1.2.6> no space, should not happen
1664             //ASSERT(0); // still no space available ?
1665             return NULL;
1666
1667         }
1668         while(FALSE);
1669
1670     }
1671     else {
1672         OS_SYSTIME rCurrentTime;
1673
1674         // WCXRP00000091
1675         // if the received strength is much weaker than the original one,
1676         // ignore it due to it might be received on the folding frequency
1677
1678         GET_CURRENT_SYSTIME(&rCurrentTime);
1679
1680         prBssDesc->eBSSType = eBSSType;
1681
1682         if(HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr) != prBssDesc->ucChannelNum &&
1683                 prBssDesc->ucRCPI > prSwRfb->prHifRxHdr->ucRcpi) {
1684
1685             // for signal strength is too much weaker and previous beacon is not stale
1686             if((prBssDesc->ucRCPI - prSwRfb->prHifRxHdr->ucRcpi) >= REPLICATED_BEACON_STRENGTH_THRESHOLD &&
1687                     rCurrentTime - prBssDesc->rUpdateTime <= REPLICATED_BEACON_FRESH_PERIOD) {
1688                 return prBssDesc;
1689             }
1690             // for received beacons too close in time domain
1691             else if(rCurrentTime - prBssDesc->rUpdateTime <= REPLICATED_BEACON_TIME_THRESHOLD) {
1692                 return prBssDesc;
1693             }
1694         }
1695
1696         /* if Timestamp has been reset, re-generate BSS DESC 'cause AP should have reset itself */
1697         if(prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && u8Timestamp < prBssDesc->u8TimeStamp.QuadPart) {
1698             scanRemoveBssDescByBssid(prAdapter, prBssDesc->aucBSSID);
1699
1700             prBssDesc = scanAllocateBssDesc(prAdapter);
1701             if (!prBssDesc) {
1702                 return NULL;
1703             }
1704         }
1705     }
1706
1707     /* NOTE: Keep consistency of Scan Record during JOIN process */
1708     if (prBssDesc->fgIsConnecting) {
1709         return prBssDesc;
1710     }
1711
1712     //4 <2> Get information from Fixed Fields
1713     prBssDesc->eBSSType = eBSSType; /* Update the latest BSS type information. */
1714
1715     COPY_MAC_ADDR(prBssDesc->aucSrcAddr, prWlanBeaconFrame->aucSrcAddr);
1716
1717     COPY_MAC_ADDR(prBssDesc->aucBSSID, prWlanBeaconFrame->aucBSSID);
1718
1719     prBssDesc->u8TimeStamp.QuadPart = u8Timestamp;
1720
1721     WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2BeaconInterval, &prBssDesc->u2BeaconInterval);
1722
1723     prBssDesc->u2CapInfo = u2CapInfo;
1724
1725
1726     //4 <2.1> Retrieve IEs for later parsing
1727     u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
1728         (UINT_16)OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]);
1729
1730     if (u2IELength > CFG_IE_BUFFER_SIZE) {
1731         u2IELength = CFG_IE_BUFFER_SIZE;
1732         prBssDesc->fgIsIEOverflow = TRUE;
1733     }
1734     else {
1735         prBssDesc->fgIsIEOverflow = FALSE;
1736     }
1737     prBssDesc->u2IELength = u2IELength;
1738
1739     kalMemCopy(prBssDesc->aucIEBuf, prWlanBeaconFrame->aucInfoElem, u2IELength);
1740
1741     //4 <2.2> reset prBssDesc variables in case that AP has been reconfigured
1742     prBssDesc->fgIsERPPresent = FALSE;
1743     prBssDesc->fgIsHTPresent = FALSE;
1744     prBssDesc->eSco = CHNL_EXT_SCN;
1745     prBssDesc->fgIEWAPI = FALSE;
1746 #if CFG_RSN_MIGRATION
1747     prBssDesc->fgIERSN = FALSE;
1748 #endif
1749 #if CFG_PRIVACY_MIGRATION
1750     prBssDesc->fgIEWPA = FALSE;
1751 #endif
1752
1753
1754     //4 <3.1> Full IE parsing on SW_RFB_T
1755     pucIE = prWlanBeaconFrame->aucInfoElem;
1756
1757
1758     IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
1759
1760         switch (IE_ID(pucIE)) {
1761         case ELEM_ID_SSID:
1762             if ((!prIeSsid) && /* NOTE(Kevin): for Atheros IOT #1 */
1763                 (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) {
1764                 BOOLEAN fgIsHiddenSSID = FALSE;
1765                 ucSSIDChar = '\0';
1766
1767
1768                 prIeSsid = (P_IE_SSID_T)pucIE;
1769
1770                 /* D-Link DWL-900AP+ */
1771                 if (IE_LEN(pucIE) == 0) {
1772                     fgIsHiddenSSID = TRUE;
1773                 }
1774                 /* Cisco AP1230A - (IE_LEN(pucIE) == 1) && (SSID_IE(pucIE)->aucSSID[0] == '\0') */
1775                 /* Linksys WRK54G/ASUS WL520g - (IE_LEN(pucIE) == n) && (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') */
1776                 else {
1777                     for (i = 0; i < IE_LEN(pucIE); i++) {
1778                         ucSSIDChar |= SSID_IE(pucIE)->aucSSID[i];
1779                     }
1780
1781                     if (!ucSSIDChar) {
1782                         fgIsHiddenSSID = TRUE;
1783                     }
1784                 }
1785
1786                 /* Update SSID to BSS Descriptor only if SSID is not hidden. */
1787                 if (!fgIsHiddenSSID) {
1788                     COPY_SSID(prBssDesc->aucSSID,
1789                               prBssDesc->ucSSIDLen,
1790                               SSID_IE(pucIE)->aucSSID,
1791                               SSID_IE(pucIE)->ucLength);
1792                 }
1793
1794             }
1795             break;
1796
1797         case ELEM_ID_SUP_RATES:
1798             /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8.
1799              * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B),
1800              * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)"
1801              */
1802             /* TP-LINK will set extra and incorrect ie with ELEM_ID_SUP_RATES */
1803             if ((!prIeSupportedRate) && (IE_LEN(pucIE) <= RATE_NUM)) {
1804                 prIeSupportedRate = SUP_RATES_IE(pucIE);
1805             }
1806             break;
1807
1808         case ELEM_ID_DS_PARAM_SET:
1809             if (IE_LEN(pucIE) == ELEM_MAX_LEN_DS_PARAMETER_SET) {
1810                 ucIeDsChannelNum = DS_PARAM_IE(pucIE)->ucCurrChnl;
1811             }
1812             break;
1813
1814         case ELEM_ID_TIM:
1815             if (IE_LEN(pucIE) <= ELEM_MAX_LEN_TIM) {
1816                 prBssDesc->ucDTIMPeriod = TIM_IE(pucIE)->ucDTIMPeriod;
1817             }
1818             break;
1819
1820         case ELEM_ID_IBSS_PARAM_SET:
1821             if (IE_LEN(pucIE) == ELEM_MAX_LEN_IBSS_PARAMETER_SET){
1822                 prBssDesc->u2ATIMWindow = IBSS_PARAM_IE(pucIE)->u2ATIMWindow;
1823             }
1824             break;
1825
1826 #if 0 //CFG_SUPPORT_802_11D
1827         case ELEM_ID_COUNTRY_INFO:
1828             prBssDesc->prIECountry = (P_IE_COUNTRY_T)pucIE;
1829             break;
1830 #endif
1831
1832         case ELEM_ID_ERP_INFO:
1833             if (IE_LEN(pucIE) == ELEM_MAX_LEN_ERP) {
1834                 prBssDesc->fgIsERPPresent = TRUE;
1835             }
1836             break;
1837
1838         case ELEM_ID_EXTENDED_SUP_RATES:
1839             if (!prIeExtSupportedRate) {
1840                 prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE);
1841             }
1842             break;
1843
1844 #if CFG_RSN_MIGRATION
1845         case ELEM_ID_RSN:
1846             if (rsnParseRsnIE(prAdapter, RSN_IE(pucIE), &prBssDesc->rRSNInfo)) {
1847                 prBssDesc->fgIERSN = TRUE;
1848                 prBssDesc->u2RsnCap = prBssDesc->rRSNInfo.u2RsnCap;
1849                 if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) {
1850                     rsnCheckPmkidCache(prAdapter, prBssDesc);
1851                 }
1852             }
1853             break;
1854 #endif
1855
1856         case ELEM_ID_HT_CAP:
1857             prBssDesc->fgIsHTPresent = TRUE;
1858             break;
1859
1860         case ELEM_ID_HT_OP:
1861             if (IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) {
1862                 break;
1863             }
1864
1865             if ((((P_IE_HT_OP_T) pucIE)->ucInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) {
1866             prBssDesc->eSco = (ENUM_CHNL_EXT_T)
1867                 (((P_IE_HT_OP_T) pucIE)->ucInfo1 & HT_OP_INFO1_SCO);
1868             }
1869             ucIeHtChannelNum = ((P_IE_HT_OP_T) pucIE)->ucPrimaryChannel;
1870
1871             break;
1872
1873 #if CFG_SUPPORT_WAPI
1874         case ELEM_ID_WAPI:
1875             if (wapiParseWapiIE(WAPI_IE(pucIE), &prBssDesc->rIEWAPI)) {
1876                 prBssDesc->fgIEWAPI = TRUE;
1877             }
1878             break;
1879 #endif
1880
1881         case ELEM_ID_VENDOR:  // ELEM_ID_P2P, ELEM_ID_WMM
1882             {
1883                 UINT_8 ucOuiType;
1884                 UINT_16 u2SubTypeVersion;
1885 #if CFG_PRIVACY_MIGRATION
1886                 if (rsnParseCheckForWFAInfoElem(prAdapter, pucIE, &ucOuiType, &u2SubTypeVersion)) {
1887                     if ((ucOuiType == VENDOR_OUI_TYPE_WPA) &&
1888                             (u2SubTypeVersion == VERSION_WPA)) {
1889
1890                         if (rsnParseWpaIE(prAdapter, WPA_IE(pucIE), &prBssDesc->rWPAInfo)) {
1891                             prBssDesc->fgIEWPA = TRUE;
1892                         }
1893                     }
1894                 }
1895 #endif
1896
1897 #if CFG_ENABLE_WIFI_DIRECT
1898                 if(prAdapter->fgIsP2PRegistered) {
1899                     if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType)) {
1900                         if (ucOuiType == VENDOR_OUI_TYPE_P2P) {
1901                             prBssDesc->fgIsP2PPresent = TRUE;
1902                         }
1903                     }
1904                 }
1905 #endif /* CFG_ENABLE_WIFI_DIRECT */
1906             }
1907             break;
1908
1909         /* no default */
1910         }
1911     }
1912
1913
1914     //4 <3.2> Save information from IEs - SSID
1915     /* Update Flag of Hidden SSID for used in SEARCH STATE. */
1916
1917     /* NOTE(Kevin): in current driver, the ucSSIDLen == 0 represent
1918      * all cases of hidden SSID.
1919      * If the fgIsHiddenSSID == TRUE, it means we didn't get the ProbeResp with
1920      * valid SSID.
1921      */
1922     if (prBssDesc->ucSSIDLen == 0) {
1923         prBssDesc->fgIsHiddenSSID = TRUE;
1924     }
1925     else {
1926         prBssDesc->fgIsHiddenSSID = FALSE;
1927     }
1928
1929
1930     //4 <3.3> Check rate information in related IEs.
1931     if (prIeSupportedRate || prIeExtSupportedRate) {
1932         rateGetRateSetFromIEs(prIeSupportedRate,
1933                               prIeExtSupportedRate,
1934                               &prBssDesc->u2OperationalRateSet,
1935                               &prBssDesc->u2BSSBasicRateSet,
1936                               &prBssDesc->fgIsUnknownBssBasicRate);
1937     }
1938
1939
1940     //4 <4> Update information from HIF RX Header
1941     {
1942         prHifRxHdr = prSwRfb->prHifRxHdr;
1943
1944         ASSERT(prHifRxHdr);
1945
1946         //4 <4.1> Get TSF comparison result
1947         prBssDesc->fgIsLargerTSF = HIF_RX_HDR_GET_TCL_FLAG(prHifRxHdr);
1948
1949         //4 <4.2> Get Band information
1950         prBssDesc->eBand = HIF_RX_HDR_GET_RF_BAND(prHifRxHdr);
1951
1952         //4 <4.2> Get channel and RCPI information
1953         ucHwChannelNum = HIF_RX_HDR_GET_CHNL_NUM(prHifRxHdr);
1954
1955         if (BAND_2G4 == prBssDesc->eBand) {
1956
1957             /* Update RCPI if in right channel */
1958             if (ucIeDsChannelNum >= 1 && ucIeDsChannelNum <= 14) {
1959
1960                 // Receive Beacon/ProbeResp frame from adjacent channel.
1961                 if ((ucIeDsChannelNum == ucHwChannelNum) ||
1962                     (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) {
1963                     prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
1964                 }
1965
1966                 // trust channel information brought by IE
1967                 prBssDesc->ucChannelNum = ucIeDsChannelNum;
1968             }
1969             else if(ucIeHtChannelNum >= 1 && ucIeHtChannelNum <= 14) {
1970                 // Receive Beacon/ProbeResp frame from adjacent channel.
1971                 if ((ucIeHtChannelNum == ucHwChannelNum) ||
1972                     (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) {
1973                     prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
1974                 }
1975
1976                 // trust channel information brought by IE
1977                 prBssDesc->ucChannelNum = ucIeHtChannelNum;
1978             }
1979             else {
1980                 prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
1981
1982                 prBssDesc->ucChannelNum = ucHwChannelNum;
1983             }
1984         }
1985         // 5G Band
1986         else {
1987             if(ucIeHtChannelNum >= 1 && ucIeHtChannelNum < 200) {
1988                 // Receive Beacon/ProbeResp frame from adjacent channel.
1989                 if ((ucIeHtChannelNum == ucHwChannelNum) ||
1990                     (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) {
1991                     prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
1992                 }
1993
1994                 // trust channel information brought by IE
1995                 prBssDesc->ucChannelNum = ucIeHtChannelNum;
1996             }
1997             else {
1998                 /* Always update RCPI */
1999                 prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
2000
2001                 prBssDesc->ucChannelNum = ucHwChannelNum;
2002             }
2003         }
2004     }
2005
2006
2007     //4 <5> PHY type setting
2008     prBssDesc->ucPhyTypeSet = 0;
2009
2010     if (BAND_2G4 == prBssDesc->eBand) {
2011         /* check if support 11n */
2012         if (prBssDesc->fgIsHTPresent) {
2013             prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT;
2014         }
2015
2016         /* if not 11n only */
2017         if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) {
2018             /* check if support 11g */
2019             if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM) ||
2020                     prBssDesc->fgIsERPPresent) {
2021                 prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_ERP;
2022             }
2023
2024             /* if not 11g only */
2025             if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_OFDM)) {
2026                 /* check if support 11b */
2027                 if ((prBssDesc->u2OperationalRateSet & RATE_SET_HR_DSSS)) {
2028                     prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS;
2029                 }
2030             }
2031         }
2032     }
2033     else { /* (BAND_5G == prBssDesc->eBande) */
2034         /* check if support 11n */
2035         if (prBssDesc->fgIsHTPresent) {
2036             prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT;
2037         }
2038
2039         /* if not 11n only */
2040         if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) {
2041             /* Support 11a definitely */
2042             prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM;
2043
2044             ASSERT(!(prBssDesc->u2OperationalRateSet & RATE_SET_HR_DSSS));
2045         }
2046     }
2047
2048
2049     //4 <6> Update BSS_DESC_T's Last Update TimeStamp.
2050     GET_CURRENT_SYSTIME(&prBssDesc->rUpdateTime);
2051
2052     return prBssDesc;
2053 }
2054
2055 #if RSSI_ENHANCE
2056
2057 extern int numOfTblRssi;
2058 extern TABLE_RSSI mTABLE_RSSI[MAX_SCAN_RSSI_NUM];
2059 extern int mTblRssiStatus[MAX_SCAN_RSSI_NUM];
2060
2061 #define RSSI_DEG(x...)   //printk(x)
2062
2063 PARAM_RSSI processAvgRssi(UINT_8 ucRCPI, PARAM_MAC_ADDRESS rMacAddr)
2064 {
2065         int bFound, i;
2066         PARAM_RSSI rRssi = RCPI_TO_dBm(ucRCPI);
2067         PARAM_RSSI rRssi2 = rRssi;
2068         PARAM_RSSI AvgRssiX8, AvgRssi;
2069
2070         if(rRssi < -40)
2071                 rRssi += 8;
2072
2073         RSSI_DEG("---- processAvgRssi ---- \n");
2074         
2075         bFound = FALSE;
2076         for(i = 0; i < numOfTblRssi; i++) {
2077                 RSSI_DEG("-%02x:%02x:%02x:%02x:%02x:%02x\n", 
2078                         mTABLE_RSSI[i].arMacAddress[0], mTABLE_RSSI[i].arMacAddress[1], mTABLE_RSSI[i].arMacAddress[2], mTABLE_RSSI[i].arMacAddress[3], mTABLE_RSSI[i].arMacAddress[4], mTABLE_RSSI[i].arMacAddress[5]);
2079                 if(EQUAL_MAC_ADDR(rMacAddr, mTABLE_RSSI[i].arMacAddress)) {
2080                         bFound = TRUE;
2081                         AvgRssiX8 = mTABLE_RSSI[i].AvgRssiX8;
2082                         AvgRssi = mTABLE_RSSI[i].AvgRssi;
2083                         mTblRssiStatus[i] = 1;
2084                         break;
2085                 }
2086         }
2087
2088     if(!bFound) {
2089         AvgRssiX8 = rRssi << 3;
2090         AvgRssi   = rRssi;
2091     } else {
2092         AvgRssiX8 = (AvgRssiX8 - AvgRssi) + rRssi;  
2093     }
2094
2095     AvgRssi = AvgRssiX8 >> 3;
2096
2097     if(!bFound) {
2098                 COPY_MAC_ADDR(mTABLE_RSSI[numOfTblRssi].arMacAddress, rMacAddr);
2099                 mTABLE_RSSI[numOfTblRssi].AvgRssi = AvgRssi;
2100                 mTABLE_RSSI[numOfTblRssi].AvgRssiX8 = AvgRssiX8;
2101                 numOfTblRssi++;
2102                 mTblRssiStatus[i] = 1;
2103     } else {
2104         mTABLE_RSSI[i].AvgRssi = AvgRssi;
2105                 mTABLE_RSSI[i].AvgRssiX8 = AvgRssiX8;
2106     }           
2107
2108         RSSI_DEG("results : %02x:%02x:%02x:%02x:%02x:%02x %d -> %d\n", 
2109                  rMacAddr[0], rMacAddr[1], rMacAddr[2], rMacAddr[3], rMacAddr[4], rMacAddr[5], rRssi2, AvgRssi);
2110
2111         return AvgRssi;
2112 }
2113
2114 void sortAvgRssi(void)
2115 {
2116         int i, index = 0;
2117
2118         RSSI_DEG("---- sortAvgRssi numOfTblRssi = %d ---- \n", numOfTblRssi);
2119
2120         for(i = 0; i < numOfTblRssi; i++) {
2121                 if(mTblRssiStatus[i] == 1) {
2122                         memmove(&mTABLE_RSSI[index++], &mTABLE_RSSI[i], sizeof(TABLE_RSSI));
2123                 }
2124         }
2125         numOfTblRssi = index;
2126
2127         RSSI_DEG("--numOfTblRssi = %d.\n", numOfTblRssi);
2128
2129         for(i = 0; i < numOfTblRssi; i++) {
2130                 mTblRssiStatus[i] = 0;
2131         }
2132 }
2133
2134 #endif
2135
2136 /*----------------------------------------------------------------------------*/
2137 /*!
2138 * @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to scan result for query
2139 *
2140 * @param[in] prSwRfb            Pointer to the receiving SW_RFB_T structure.
2141 *
2142 * @retval WLAN_STATUS_SUCCESS   It is a valid Scan Result and been sent to the host.
2143 * @retval WLAN_STATUS_FAILURE   It is not a valid Scan Result.
2144 */
2145 /*----------------------------------------------------------------------------*/
2146 WLAN_STATUS
2147 scanAddScanResult (
2148     IN P_ADAPTER_T prAdapter,
2149     IN P_BSS_DESC_T prBssDesc,
2150     IN P_SW_RFB_T prSwRfb
2151     )
2152 {
2153     P_SCAN_INFO_T prScanInfo;
2154     UINT_8 aucRatesEx[PARAM_MAX_LEN_RATES_EX];
2155     P_WLAN_BEACON_FRAME_T prWlanBeaconFrame;
2156     PARAM_MAC_ADDRESS rMacAddr;
2157     PARAM_SSID_T rSsid;
2158     ENUM_PARAM_NETWORK_TYPE_T eNetworkType;
2159     PARAM_802_11_CONFIG_T rConfiguration;
2160     ENUM_PARAM_OP_MODE_T eOpMode;
2161     UINT_8 ucRateLen = 0;
2162     UINT_32 i;
2163         PARAM_RSSI AvgRssi;
2164
2165     ASSERT(prAdapter);
2166     ASSERT(prSwRfb);
2167
2168     prScanInfo =  &(prAdapter->rWifiVar.rScanInfo);
2169
2170     if (prBssDesc->eBand == BAND_2G4) {
2171         if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM)
2172                 || prBssDesc->fgIsERPPresent) {
2173             eNetworkType = PARAM_NETWORK_TYPE_OFDM24;
2174         }
2175         else {
2176             eNetworkType = PARAM_NETWORK_TYPE_DS;
2177         }
2178     }
2179     else {
2180         ASSERT(prBssDesc->eBand == BAND_5G);
2181         eNetworkType = PARAM_NETWORK_TYPE_OFDM5;
2182     }
2183
2184     if(prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) {
2185         /* NOTE(Kevin): Not supported by WZC(TBD) */
2186         return WLAN_STATUS_FAILURE;
2187     }
2188
2189     prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T)prSwRfb->pvHeader;
2190     COPY_MAC_ADDR(rMacAddr, prWlanBeaconFrame->aucBSSID);
2191     COPY_SSID(rSsid.aucSsid,
2192             rSsid.u4SsidLen,
2193             prBssDesc->aucSSID,
2194             prBssDesc->ucSSIDLen);
2195
2196     rConfiguration.u4Length             = sizeof(PARAM_802_11_CONFIG_T);
2197     rConfiguration.u4BeaconPeriod       = (UINT_32) prWlanBeaconFrame->u2BeaconInterval;
2198     rConfiguration.u4ATIMWindow         = prBssDesc->u2ATIMWindow;
2199     rConfiguration.u4DSConfig           = nicChannelNum2Freq(prBssDesc->ucChannelNum);
2200     rConfiguration.rFHConfig.u4Length   = sizeof(PARAM_802_11_CONFIG_FH_T);
2201
2202     rateGetDataRatesFromRateSet(prBssDesc->u2OperationalRateSet,
2203                                 0,
2204                                 aucRatesEx,
2205                                 &ucRateLen);
2206
2207     /* NOTE(Kevin): Set unused entries, if any, at the end of the array to 0.
2208      * from OID_802_11_BSSID_LIST
2209      */
2210     for (i = ucRateLen; i < sizeof(aucRatesEx) / sizeof(aucRatesEx[0]) ; i++) {
2211         aucRatesEx[i] = 0;
2212     }
2213
2214     switch(prBssDesc->eBSSType) {
2215     case BSS_TYPE_IBSS:
2216         eOpMode = NET_TYPE_IBSS;
2217         break;
2218
2219     case BSS_TYPE_INFRASTRUCTURE:
2220     case BSS_TYPE_P2P_DEVICE:
2221     case BSS_TYPE_BOW_DEVICE:
2222     default:
2223         eOpMode = NET_TYPE_INFRA;
2224         break;
2225     }
2226
2227 #if RSSI_ENHANCE
2228         AvgRssi = processAvgRssi(prBssDesc->ucRCPI, rMacAddr);
2229 #endif  
2230
2231     kalIndicateBssInfo(prAdapter->prGlueInfo,
2232             (PUINT_8)prSwRfb->pvHeader,
2233             prSwRfb->u2PacketLen,
2234             prBssDesc->ucChannelNum,
2235 #if RSSI_ENHANCE     
2236                         AvgRssi);
2237 #else
2238             RCPI_TO_dBm(prBssDesc->ucRCPI));
2239 #endif
2240
2241     nicAddScanResult(prAdapter,
2242             rMacAddr,
2243             &rSsid,
2244             prWlanBeaconFrame->u2CapInfo & CAP_INFO_PRIVACY ? 1 : 0,
2245             RCPI_TO_dBm(prBssDesc->ucRCPI),
2246             eNetworkType,
2247             &rConfiguration,
2248             eOpMode,
2249             aucRatesEx,
2250             prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen,
2251             (PUINT_8)((UINT_32)(prSwRfb->pvHeader) + WLAN_MAC_MGMT_HEADER_LEN));        
2252
2253     return WLAN_STATUS_SUCCESS;
2254
2255 } /* end of scanAddScanResult() */
2256
2257
2258 /*----------------------------------------------------------------------------*/
2259 /*!
2260 * @brief Parse the content of given Beacon or ProbeResp Frame.
2261 *
2262 * @param[in] prSwRfb            Pointer to the receiving SW_RFB_T structure.
2263 *
2264 * @retval WLAN_STATUS_SUCCESS           if not report this SW_RFB_T to host
2265 * @retval WLAN_STATUS_PENDING           if report this SW_RFB_T to host as scan result
2266 */
2267 /*----------------------------------------------------------------------------*/
2268 WLAN_STATUS
2269 scanProcessBeaconAndProbeResp (
2270     IN P_ADAPTER_T prAdapter,
2271     IN P_SW_RFB_T prSwRfb
2272     )
2273 {
2274     P_CONNECTION_SETTINGS_T prConnSettings;
2275     P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T)NULL;
2276     WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2277     P_BSS_INFO_T prAisBssInfo;
2278     P_WLAN_BEACON_FRAME_T prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T)NULL;
2279 #if CFG_SLT_SUPPORT
2280     P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T)NULL;
2281 #endif
2282
2283     ASSERT(prAdapter);
2284     ASSERT(prSwRfb);
2285
2286     //4 <0> Ignore invalid Beacon Frame
2287     if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) <
2288             (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN)) {
2289 #ifndef _lint
2290         ASSERT(0);
2291 #endif /* _lint */
2292         return rStatus;
2293     }
2294
2295 #if CFG_SLT_SUPPORT
2296     prSltInfo = &prAdapter->rWifiVar.rSltInfo;
2297
2298     if (prSltInfo->fgIsDUT) {
2299         DBGLOG(P2P, INFO, ("\n\rBCN: RX\n"));
2300         prSltInfo->u4BeaconReceiveCnt++;
2301         return WLAN_STATUS_SUCCESS;
2302     }
2303     else {
2304         return WLAN_STATUS_SUCCESS;
2305     }
2306 #endif
2307
2308
2309     prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
2310     prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
2311     prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T)prSwRfb->pvHeader;
2312
2313     //4 <1> Parse and add into BSS_DESC_T
2314     prBssDesc = scanAddToBssDesc(prAdapter, prSwRfb);
2315
2316     if (prBssDesc) {
2317
2318         //4 <1.1> Beacon Change Detection for Connected BSS
2319         if(prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED &&
2320                 ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && prConnSettings->eOPMode != NET_TYPE_IBSS)
2321                  || (prBssDesc->eBSSType == BSS_TYPE_IBSS && prConnSettings->eOPMode != NET_TYPE_INFRA)) &&
2322                 EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID) &&
2323                 EQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, prAisBssInfo->aucSSID, prAisBssInfo->ucSSIDLen)) {
2324             BOOLEAN fgNeedDisconnect = FALSE;
2325
2326 #if CFG_SUPPORT_BEACON_CHANGE_DETECTION
2327             // <1.1.2> check if supported rate differs
2328             if(prAisBssInfo->u2OperationalRateSet != prBssDesc->u2OperationalRateSet) {
2329                 fgNeedDisconnect = TRUE;
2330             }
2331 #endif
2332
2333             // <1.1.3> beacon content change detected, disconnect immediately
2334             if(fgNeedDisconnect == TRUE) {
2335                 aisBssBeaconTimeout(prAdapter);
2336             }
2337         }
2338
2339         //4 <1.1> Update AIS_BSS_INFO
2340         if(((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE && prConnSettings->eOPMode != NET_TYPE_IBSS)
2341                     || (prBssDesc->eBSSType == BSS_TYPE_IBSS && prConnSettings->eOPMode != NET_TYPE_INFRA))) {
2342             if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
2343
2344                 /* *not* checking prBssDesc->fgIsConnected anymore,
2345                  * due to Linksys AP uses " " as hidden SSID, and would have different BSS descriptor */
2346                 if ((!prAisBssInfo->ucDTIMPeriod) &&
2347                     EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID) &&
2348                     (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) &&
2349                     ((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_BEACON)) {
2350
2351                     prAisBssInfo->ucDTIMPeriod = prBssDesc->ucDTIMPeriod;
2352
2353                     /* sync with firmware for beacon information */
2354                     nicPmIndicateBssConnected(prAdapter, NETWORK_TYPE_AIS_INDEX);
2355                 }
2356             }
2357
2358 #if CFG_SUPPORT_ADHOC
2359             if (EQUAL_SSID(prBssDesc->aucSSID,
2360                         prBssDesc->ucSSIDLen,
2361                         prConnSettings->aucSSID,
2362                         prConnSettings->ucSSIDLen) &&
2363                     (prBssDesc->eBSSType == BSS_TYPE_IBSS) &&
2364                     (prAisBssInfo->eCurrentOPMode == OP_MODE_IBSS)) {
2365
2366                 ibssProcessMatchedBeacon(prAdapter, prAisBssInfo, prBssDesc, prSwRfb->prHifRxHdr->ucRcpi);
2367             }
2368 #endif /* CFG_SUPPORT_ADHOC */
2369         }
2370
2371         rlmProcessBcn(prAdapter,
2372                 prSwRfb,
2373                 ((P_WLAN_BEACON_FRAME_T)(prSwRfb->pvHeader))->aucInfoElem,
2374                 (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
2375                 (UINT_16)(OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0])));
2376
2377         //4 <3> Send SW_RFB_T to HIF when we perform SCAN for HOST
2378         if(prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE
2379                 || prBssDesc->eBSSType == BSS_TYPE_IBSS) {
2380             /* for AIS, send to host */
2381             if (prConnSettings->fgIsScanReqIssued &&
2382                     rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum) == TRUE) {
2383                 ENUM_BAND_T eBand;
2384                 UINT_8 ucChannel;
2385                 BOOLEAN fgAddToScanResult;
2386
2387                 /* check ucChannelNum/eBand for adjacement channel filtering */
2388                 if(cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel) == TRUE &&
2389                         (eBand != prBssDesc->eBand || ucChannel != prBssDesc->ucChannelNum)) {
2390                     fgAddToScanResult = FALSE;
2391                 }
2392                 else {
2393                     fgAddToScanResult = TRUE;
2394                 }
2395
2396                 if(fgAddToScanResult == TRUE) {
2397                     rStatus = scanAddScanResult(prAdapter, prBssDesc, prSwRfb);
2398                 }
2399             }
2400         }
2401
2402 #if CFG_ENABLE_WIFI_DIRECT
2403         if(prAdapter->fgIsP2PRegistered) {
2404             scanP2pProcessBeaconAndProbeResp(
2405                         prAdapter,
2406                         prSwRfb,
2407                         &rStatus,
2408                         prBssDesc,
2409                         prWlanBeaconFrame);
2410         }
2411 #endif
2412     }
2413
2414     return rStatus;
2415
2416 } /* end of scanProcessBeaconAndProbeResp() */
2417
2418
2419 /*----------------------------------------------------------------------------*/
2420 /*!
2421 * \brief Search the Candidate of BSS Descriptor for JOIN(Infrastructure) or
2422 *        MERGE(AdHoc) according to current Connection Policy.
2423 *
2424 * \return   Pointer to BSS Descriptor, if found. NULL, if not found
2425 */
2426 /*----------------------------------------------------------------------------*/
2427 P_BSS_DESC_T
2428 scanSearchBssDescByPolicy (
2429     IN P_ADAPTER_T prAdapter,
2430     IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex
2431     )
2432 {
2433     P_CONNECTION_SETTINGS_T prConnSettings;
2434     P_BSS_INFO_T prBssInfo;
2435     P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
2436     P_SCAN_INFO_T prScanInfo;
2437
2438     P_LINK_T prBSSDescList;
2439
2440     P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T)NULL;
2441     P_BSS_DESC_T prPrimaryBssDesc = (P_BSS_DESC_T)NULL;
2442     P_BSS_DESC_T prCandidateBssDesc = (P_BSS_DESC_T)NULL;
2443
2444     P_STA_RECORD_T prStaRec = (P_STA_RECORD_T)NULL;
2445     P_STA_RECORD_T prPrimaryStaRec;
2446     P_STA_RECORD_T prCandidateStaRec = (P_STA_RECORD_T)NULL;
2447
2448     OS_SYSTIME rCurrentTime;
2449     
2450     /* The first one reach the check point will be our candidate */
2451     BOOLEAN fgIsFindFirst = (BOOLEAN)FALSE;
2452
2453     BOOLEAN fgIsFindBestRSSI = (BOOLEAN)FALSE;
2454     BOOLEAN fgIsFindBestEncryptionLevel = (BOOLEAN)FALSE;
2455     //BOOLEAN fgIsFindMinChannelLoad = (BOOLEAN)FALSE;
2456
2457     /* TODO(Kevin): Support Min Channel Load */
2458     //UINT_8 aucChannelLoad[CHANNEL_NUM] = {0};
2459
2460     BOOLEAN fgIsFixedChannel;
2461     ENUM_BAND_T eBand;
2462     UINT_8 ucChannel;
2463
2464     ASSERT(prAdapter);
2465
2466     prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
2467     prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]);
2468
2469     prAisSpecBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo);
2470
2471     prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
2472     prBSSDescList = &prScanInfo->rBSSDescList;
2473
2474     GET_CURRENT_SYSTIME(&rCurrentTime);
2475
2476     /* check for fixed channel operation */
2477     if(eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) {
2478         fgIsFixedChannel = cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel);
2479     }
2480     else {
2481         fgIsFixedChannel = FALSE;
2482     }
2483
2484 #if DBG
2485     if (prConnSettings->ucSSIDLen < ELEM_MAX_LEN_SSID) {
2486         prConnSettings->aucSSID[prConnSettings->ucSSIDLen] = '\0';
2487     }
2488 #endif
2489
2490     DBGLOG(SCN, INFO, ("SEARCH: Num Of BSS_DESC_T = %d, Look for SSID: %s\n",
2491         prBSSDescList->u4NumElem, prConnSettings->aucSSID));
2492
2493
2494     //4 <1> The outer loop to search for a candidate.
2495     LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
2496
2497         /* TODO(Kevin): Update Minimum Channel Load Information here */
2498
2499         DBGLOG(SCN, INFO, ("SEARCH: ["MACSTR"], SSID:%s\n",
2500                             MAC2STR(prBssDesc->aucBSSID), prBssDesc->aucSSID));
2501
2502
2503         //4 <2> Check PHY Type and attributes
2504         //4 <2.1> Check Unsupported BSS PHY Type
2505         if (!(prBssDesc->ucPhyTypeSet & (prAdapter->rWifiVar.ucAvailablePhyTypeSet))) {
2506
2507             DBGLOG(SCN, INFO, ("SEARCH: Ignore unsupported ucPhyTypeSet = %x\n",
2508                                prBssDesc->ucPhyTypeSet));
2509             continue;
2510         }
2511
2512         //4 <2.2> Check if has unknown NonHT BSS Basic Rate Set.
2513         if (prBssDesc->fgIsUnknownBssBasicRate) {
2514
2515             continue;
2516         }
2517
2518         //4 <2.3> Check if fixed operation cases should be aware
2519         if (fgIsFixedChannel == TRUE &&
2520                 (prBssDesc->eBand != eBand || prBssDesc->ucChannelNum != ucChannel)) {
2521             continue;
2522         }
2523
2524         //4 <2.4> Check if the channel is legal under regulatory domain
2525         if(rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum) == FALSE) {
2526             continue;
2527         }
2528
2529         //4 <2.5> Check if this BSS_DESC_T is stale
2530         if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
2531                                    SEC_TO_SYSTIME(SCN_BSS_DESC_REMOVE_TIMEOUT_SEC)) ) {
2532
2533             continue;
2534         }
2535
2536         //4 <3> Check if reach the excessive join retry limit
2537         /* NOTE(Kevin): STA_RECORD_T is recorded by TA. */
2538         prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) eNetTypeIndex,
2539                                             prBssDesc->aucSrcAddr);
2540
2541         if (prStaRec) {
2542             /* NOTE(Kevin):
2543              * The Status Code is the result of a Previous Connection Request, we use this as SCORE for choosing a proper
2544              * candidate (Also used for compare see <6>)
2545              * The Reason Code is an indication of the reason why AP reject us, we use this Code for "Reject"
2546              * a SCAN result to become our candidate(Like a blacklist).
2547              */
2548 #if 0 /* TODO(Kevin): */
2549             if (prStaRec->u2ReasonCode != REASON_CODE_RESERVED) {
2550                 DBGLOG(SCN, INFO, ("SEARCH: Ignore BSS with previous Reason Code = %d\n",
2551                     prStaRec->u2ReasonCode));
2552                 continue;
2553             }
2554             else
2555 #endif
2556             if (prStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL) {
2557                 /* NOTE(Kevin): greedy association - after timeout, we'll still
2558                  * try to associate to the AP whose STATUS of conection attempt
2559                  * was not success.
2560                  * We may also use (ucJoinFailureCount x JOIN_RETRY_INTERVAL_SEC) for
2561                  * time bound.
2562                  */
2563                 if ((prStaRec->ucJoinFailureCount < JOIN_MAX_RETRY_FAILURE_COUNT) ||
2564                     (CHECK_FOR_TIMEOUT(rCurrentTime,
2565                                        prStaRec->rLastJoinTime,
2566                                        SEC_TO_SYSTIME(JOIN_RETRY_INTERVAL_SEC)))) {
2567
2568                     /* NOTE(Kevin): Every JOIN_RETRY_INTERVAL_SEC interval, we can retry
2569                      * JOIN_MAX_RETRY_FAILURE_COUNT times.
2570                      */
2571                     if (prStaRec->ucJoinFailureCount >= JOIN_MAX_RETRY_FAILURE_COUNT) {
2572                         prStaRec->ucJoinFailureCount = 0;
2573                     }
2574                     DBGLOG(SCN, INFO, ("SEARCH: Try to join BSS again which has Status Code = %d (Curr = %ld/Last Join = %ld)\n",
2575                         prStaRec->u2StatusCode, rCurrentTime, prStaRec->rLastJoinTime));
2576                 }
2577                 else {
2578                     DBGLOG(SCN, INFO, ("SEARCH: Ignore BSS which reach maximum Join Retry Count = %d \n",
2579                         JOIN_MAX_RETRY_FAILURE_COUNT));
2580                     continue;
2581                 }
2582
2583             }
2584         }
2585
2586
2587         //4 <4> Check for various NETWORK conditions
2588         if (eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) {
2589
2590             //4 <4.1> Check BSS Type for the corresponding Operation Mode in Connection Setting
2591             /* NOTE(Kevin): For NET_TYPE_AUTO_SWITCH, we will always pass following check. */
2592             if (((prConnSettings->eOPMode == NET_TYPE_INFRA) &&
2593                  (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE)) ||
2594                 ((prConnSettings->eOPMode == NET_TYPE_IBSS || prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS) &&
2595                  (prBssDesc->eBSSType != BSS_TYPE_IBSS))) {
2596
2597                 DBGLOG(SCN, INFO, ("SEARCH: Ignore eBSSType = %s\n",
2598                     ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) ?
2599                         "INFRASTRUCTURE" : "IBSS")));
2600                 continue;
2601             }
2602
2603             //4 <4.2> Check AP's BSSID if OID_802_11_BSSID has been set.
2604             if ((prConnSettings->fgIsConnByBssidIssued) &&
2605                 (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE)) {
2606
2607                 if (UNEQUAL_MAC_ADDR(prConnSettings->aucBSSID, prBssDesc->aucBSSID)) {
2608
2609                     DBGLOG(SCN, INFO, ("SEARCH: Ignore due to BSSID was not matched!\n"));
2610                     continue;
2611                 }
2612             }
2613
2614 #if CFG_SUPPORT_ADHOC
2615             //4 <4.3> Check for AdHoc Mode
2616             if (prBssDesc->eBSSType == BSS_TYPE_IBSS) {
2617                 OS_SYSTIME rCurrentTime;
2618
2619                 //4 <4.3.1> Check if this SCAN record has been updated recently for IBSS.
2620                 /* NOTE(Kevin): Because some STA may change its BSSID frequently after it
2621                  * create the IBSS - e.g. IPN2220, so we need to make sure we get the new one.
2622                  * For BSS, if the old record was matched, however it won't be able to pass
2623                  * the Join Process later.
2624                  */
2625                 GET_CURRENT_SYSTIME(&rCurrentTime);
2626                 if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
2627                                       SEC_TO_SYSTIME(SCN_ADHOC_BSS_DESC_TIMEOUT_SEC))) {
2628                     DBGLOG(SCN, LOUD, ("SEARCH: Skip old record of BSS Descriptor - BSSID:["MACSTR"]\n\n",
2629                               MAC2STR(prBssDesc->aucBSSID)));
2630                     continue;
2631                 }
2632
2633                 //4 <4.3.2> Check Peer's capability
2634                 if (ibssCheckCapabilityForAdHocMode(prAdapter, prBssDesc) == WLAN_STATUS_FAILURE) {
2635
2636                     DBGLOG(SCN, INFO,
2637                         ("SEARCH: Ignore BSS DESC MAC: "MACSTR", Capability is not supported for current AdHoc Mode.\n",
2638                         MAC2STR(prPrimaryBssDesc->aucBSSID)));
2639
2640                     continue;
2641                 }
2642
2643
2644                 //4 <4.3.3> Compare TSF
2645                 if (prBssInfo->fgIsBeaconActivated &&
2646                     UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID)) {
2647
2648                     DBGLOG(SCN, LOUD,
2649                         ("SEARCH: prBssDesc->fgIsLargerTSF = %d\n",
2650                             prBssDesc->fgIsLargerTSF));
2651
2652                     if (!prBssDesc->fgIsLargerTSF) {
2653                         DBGLOG(SCN, INFO,
2654                             ("SEARCH: Ignore BSS DESC MAC: ["MACSTR"], Smaller TSF\n", MAC2STR(prBssDesc->aucBSSID)));
2655                         continue;
2656                     }
2657                 }
2658             }
2659 #endif /* CFG_SUPPORT_ADHOC */
2660
2661         }
2662
2663
2664
2665
2666 #if 0 /* TODO(Kevin): For IBSS */
2667         //4 <2.c> Check if this SCAN record has been updated recently for IBSS.
2668         /* NOTE(Kevin): Because some STA may change its BSSID frequently after it
2669          * create the IBSS, so we need to make sure we get the new one.
2670          * For BSS, if the old record was matched, however it won't be able to pass
2671          * the Join Process later.
2672          */
2673         if (prBssDesc->eBSSType == BSS_TYPE_IBSS) {
2674             OS_SYSTIME rCurrentTime;
2675
2676             GET_CURRENT_SYSTIME(&rCurrentTime);
2677             if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
2678                                   SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) {
2679                 DBGLOG(SCAN, TRACE, ("Skip old record of BSS Descriptor - BSSID:["MACSTR"]\n\n",
2680                           MAC2STR(prBssDesc->aucBSSID)));
2681                 continue;
2682             }
2683         }
2684
2685         if ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) &&
2686             (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED)) {
2687             OS_SYSTIME rCurrentTime;
2688
2689             GET_CURRENT_SYSTIME(&rCurrentTime);
2690             if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
2691                                   SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) {
2692                 DBGLOG(SCAN, TRACE, ("Skip old record of BSS Descriptor - BSSID:["MACSTR"]\n\n",
2693                           MAC2STR(prBssDesc->aucBSSID)));
2694                 continue;
2695             }
2696         }
2697
2698
2699         //4 <4B> Check for IBSS AdHoc Mode.
2700         /* Skip if one or more BSS Basic Rate are not supported by current AdHocMode */
2701         if (prPrimaryBssDesc->eBSSType == BSS_TYPE_IBSS) {
2702             //4 <4B.1> Check if match the Capability of current IBSS AdHoc Mode.
2703             if (ibssCheckCapabilityForAdHocMode(prAdapter, prPrimaryBssDesc) == WLAN_STATUS_FAILURE) {
2704
2705                 DBGLOG(SCAN, TRACE,
2706                     ("Ignore BSS DESC MAC: "MACSTR", Capability is not supported for current AdHoc Mode.\n",
2707                     MAC2STR(prPrimaryBssDesc->aucBSSID)));
2708
2709                 continue;
2710             }
2711
2712
2713             //4 <4B.2> IBSS Merge Decision Flow for SEARCH STATE.
2714             if (prAdapter->fgIsIBSSActive &&
2715                 UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prPrimaryBssDesc->aucBSSID)) {
2716
2717                 if (!fgIsLocalTSFRead) {
2718                     NIC_GET_CURRENT_TSF(prAdapter, &rCurrentTsf);
2719
2720                     DBGLOG(SCAN, TRACE,
2721                         ("\n\nCurrent TSF : %08lx-%08lx\n\n",
2722                             rCurrentTsf.u.HighPart, rCurrentTsf.u.LowPart));
2723                 }
2724
2725                 if (rCurrentTsf.QuadPart > prPrimaryBssDesc->u8TimeStamp.QuadPart) {
2726                     DBGLOG(SCAN, TRACE,
2727                         ("Ignore BSS DESC MAC: ["MACSTR"], Current BSSID: ["MACSTR"].\n",
2728                             MAC2STR(prPrimaryBssDesc->aucBSSID), MAC2STR(prBssInfo->aucBSSID)));
2729
2730                     DBGLOG(SCAN, TRACE,
2731                         ("\n\nBSS's TSF : %08lx-%08lx\n\n",
2732                             prPrimaryBssDesc->u8TimeStamp.u.HighPart, prPrimaryBssDesc->u8TimeStamp.u.LowPart));
2733
2734                     prPrimaryBssDesc->fgIsLargerTSF = FALSE;
2735                     continue;
2736                 }
2737                 else {
2738                     prPrimaryBssDesc->fgIsLargerTSF = TRUE;
2739                 }
2740
2741             }
2742         }
2743
2744         //4 <5> Check the Encryption Status.
2745         if (rsnPerformPolicySelection(prPrimaryBssDesc)) {
2746
2747             if (prPrimaryBssDesc->ucEncLevel > 0) {
2748                 fgIsFindBestEncryptionLevel = TRUE;
2749
2750                 fgIsFindFirst = FALSE;
2751             }
2752         }
2753         else {
2754             /* Can't pass the Encryption Status Check, get next one */
2755             continue;
2756         }
2757
2758         /* For RSN Pre-authentication, update the PMKID canidate list for
2759            same SSID and encrypt status */
2760         /* Update PMKID candicate list. */
2761         if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) {
2762             rsnUpdatePmkidCandidateList(prPrimaryBssDesc);
2763             if (prAdapter->rWifiVar.rAisBssInfo.u4PmkidCandicateCount) {
2764                 prAdapter->rWifiVar.rAisBssInfo.fgIndicatePMKID = rsnCheckPmkidCandicate();
2765             }
2766         }
2767
2768 #endif
2769
2770
2771         prPrimaryBssDesc = (P_BSS_DESC_T)NULL;
2772
2773         //4 <6> Check current Connection Policy.
2774         switch (prConnSettings->eConnectionPolicy) {
2775         case CONNECT_BY_SSID_BEST_RSSI:
2776             /* Choose Hidden SSID to join only if the `fgIsEnableJoin...` is TRUE */
2777             if (prAdapter->rWifiVar.fgEnableJoinToHiddenSSID && prBssDesc->fgIsHiddenSSID) {
2778                 /* NOTE(Kevin): following if () statement means that
2779                  * If Target is hidden, then we won't connect when user specify SSID_ANY policy.
2780                  */
2781                 if (prConnSettings->ucSSIDLen) {
2782                     prPrimaryBssDesc = prBssDesc;
2783
2784                     fgIsFindBestRSSI = TRUE;
2785                 }
2786
2787             }
2788             else if (EQUAL_SSID(prBssDesc->aucSSID,
2789                                 prBssDesc->ucSSIDLen,
2790                                 prConnSettings->aucSSID,
2791                                 prConnSettings->ucSSIDLen)) {
2792                 prPrimaryBssDesc = prBssDesc;
2793
2794                 fgIsFindBestRSSI = TRUE;
2795             }
2796             break;
2797
2798         case CONNECT_BY_SSID_ANY:
2799             /* NOTE(Kevin): In this policy, we don't know the desired
2800              * SSID from user, so we should exclude the Hidden SSID from scan list.
2801              * And because we refuse to connect to Hidden SSID node at the beginning, so
2802              * when the JOIN Module deal with a BSS_DESC_T which has fgIsHiddenSSID == TRUE,
2803              * then the Connection Settings must be valid without doubt.
2804              */
2805             if (!prBssDesc->fgIsHiddenSSID) {
2806                 prPrimaryBssDesc = prBssDesc;
2807
2808                 fgIsFindFirst = TRUE;
2809             }
2810             break;
2811
2812         case CONNECT_BY_BSSID:
2813             if(EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prConnSettings->aucBSSID)) {
2814                 prPrimaryBssDesc = prBssDesc;
2815             }
2816             break;
2817
2818         default:
2819             break;
2820         }
2821
2822
2823         /* Primary Candidate was not found */
2824         if (prPrimaryBssDesc == NULL) {
2825             continue;
2826         }
2827
2828         //4 <7> Check the Encryption Status.
2829         if (prPrimaryBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) {
2830 #if CFG_SUPPORT_WAPI
2831             if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) {
2832                 if (wapiPerformPolicySelection(prAdapter, prPrimaryBssDesc)) {
2833                     fgIsFindFirst = TRUE;
2834                 }
2835                 else {
2836                     /* Can't pass the Encryption Status Check, get next one */
2837                     continue;
2838                 }
2839             }
2840             else
2841 #endif
2842 #if CFG_RSN_MIGRATION
2843             if (rsnPerformPolicySelection(prAdapter, prPrimaryBssDesc)) {
2844                 if (prAisSpecBssInfo->fgCounterMeasure) {
2845                     DBGLOG(RSN, INFO, ("Skip while at counter measure period!!!\n"));
2846                     continue;
2847                 }
2848
2849                 if (prPrimaryBssDesc->ucEncLevel > 0) {
2850                     fgIsFindBestEncryptionLevel = TRUE;
2851
2852                     fgIsFindFirst = FALSE;
2853                 }
2854
2855 #if 0
2856                 /* Update PMKID candicate list. */
2857                 if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) {
2858                     rsnUpdatePmkidCandidateList(prPrimaryBssDesc);
2859                     if (prAisSpecBssInfo->u4PmkidCandicateCount) {
2860                         if (rsnCheckPmkidCandicate()) {
2861                             DBGLOG(RSN, WARN, ("Prepare a timer to indicate candidate "MACSTR"\n",
2862                                 MAC2STR(prAisSpecBssInfo->arPmkidCache[prAisSpecBssInfo->u4PmkidCacheCount].rBssidInfo.aucBssid)));
2863                             cnmTimerStopTimer(&prAisSpecBssInfo->rPreauthenticationTimer);
2864                             cnmTimerStartTimer(&prAisSpecBssInfo->rPreauthenticationTimer,
2865                                     SEC_TO_MSEC(WAIT_TIME_IND_PMKID_CANDICATE_SEC));
2866                         }
2867                     }
2868                 }
2869 #endif
2870             }
2871             else {
2872                 /* Can't pass the Encryption Status Check, get next one */
2873                 continue;
2874             }
2875 #endif
2876         }
2877         else {
2878             /* Todo:: P2P and BOW Policy Selection */
2879         }
2880
2881         prPrimaryStaRec = prStaRec;
2882
2883         //4 <8> Compare the Candidate and the Primary Scan Record.
2884         if (!prCandidateBssDesc) {
2885             prCandidateBssDesc = prPrimaryBssDesc;
2886             prCandidateStaRec = prPrimaryStaRec;
2887
2888             //4 <8.1> Condition - Get the first matched one.
2889             if (fgIsFindFirst) {
2890                 break;
2891             }
2892         }
2893         else {
2894 #if 0 /* TODO(Kevin): For security(TBD) */
2895             //4 <6B> Condition - Choose the one with best Encryption Score.
2896             if (fgIsFindBestEncryptionLevel) {
2897                 if (prCandidateBssDesc->ucEncLevel <
2898                     prPrimaryBssDesc->ucEncLevel) {
2899
2900                     prCandidateBssDesc = prPrimaryBssDesc;
2901                     prCandidateStaRec = prPrimaryStaRec;
2902                     continue;
2903                 }
2904             }
2905
2906             /* If reach here, that means they have the same Encryption Score.
2907              */
2908
2909             //4 <6C> Condition - Give opportunity to the one we didn't connect before.
2910             // For roaming, only compare the candidates other than current associated BSSID.
2911             if (!prCandidateBssDesc->fgIsConnected && !prPrimaryBssDesc->fgIsConnected) {
2912                 if ((prCandidateStaRec != (P_STA_RECORD_T)NULL) &&
2913                     (prCandidateStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL)) {
2914
2915                     DBGLOG(SCAN, TRACE, ("So far -BSS DESC MAC: "MACSTR" has nonzero Status Code = %d\n",
2916                         MAC2STR(prCandidateBssDesc->aucBSSID), prCandidateStaRec->u2StatusCode));
2917
2918                     if (prPrimaryStaRec != (P_STA_RECORD_T)NULL) {
2919                         if (prPrimaryStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL) {
2920
2921                             /* Give opportunity to the one with smaller rLastJoinTime */
2922                             if (TIME_BEFORE(prCandidateStaRec->rLastJoinTime,
2923                                                         prPrimaryStaRec->rLastJoinTime)) {
2924                                 continue;
2925                             }
2926                             /* We've connect to CANDIDATE recently, let us try PRIMARY now */
2927                             else {
2928                                 prCandidateBssDesc = prPrimaryBssDesc;
2929                                 prCandidateStaRec = prPrimaryStaRec;
2930                                 continue;
2931                             }
2932                         }
2933                         /* PRIMARY's u2StatusCode = 0 */
2934                         else {
2935                             prCandidateBssDesc = prPrimaryBssDesc;
2936                             prCandidateStaRec = prPrimaryStaRec;
2937                             continue;
2938                         }
2939                     }
2940                     /* PRIMARY has no StaRec - We didn't connet to PRIMARY before */
2941                     else {
2942                         prCandidateBssDesc = prPrimaryBssDesc;
2943                         prCandidateStaRec = prPrimaryStaRec;
2944                         continue;
2945                     }
2946                 }
2947                 else {
2948                     if ((prPrimaryStaRec != (P_STA_RECORD_T)NULL) &&
2949                         (prPrimaryStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL)) {
2950                         continue;
2951                     }
2952                 }
2953             }
2954 #endif
2955
2956
2957             //4 <6D> Condition - Visible SSID win Hidden SSID.
2958             if (prCandidateBssDesc->fgIsHiddenSSID) {
2959                 if (!prPrimaryBssDesc->fgIsHiddenSSID) {
2960                     prCandidateBssDesc = prPrimaryBssDesc; /* The non Hidden SSID win. */
2961                     prCandidateStaRec = prPrimaryStaRec;
2962                     continue;
2963                 }
2964             }
2965             else {
2966                 if (prPrimaryBssDesc->fgIsHiddenSSID) {
2967                     continue;
2968                 }
2969             }
2970
2971
2972             //4 <6E> Condition - Choose the one with better RCPI(RSSI).
2973             if (fgIsFindBestRSSI) {
2974                 /* TODO(Kevin): We shouldn't compare the actual value, we should
2975                  * allow some acceptable tolerance of some RSSI percentage here.
2976                  */
2977                 DBGLOG(SCN, TRACE, ("Candidate ["MACSTR"]: RCPI = %d, Primary ["MACSTR"]: RCPI = %d\n",
2978                     MAC2STR(prCandidateBssDesc->aucBSSID), prCandidateBssDesc->ucRCPI,
2979                     MAC2STR(prPrimaryBssDesc->aucBSSID), prPrimaryBssDesc->ucRCPI));
2980
2981                 ASSERT(!(prCandidateBssDesc->fgIsConnected &&
2982                          prPrimaryBssDesc->fgIsConnected));
2983
2984                 /* NOTE: To prevent SWING, we do roaming only if target AP has at least 5dBm larger than us. */
2985                 if (prCandidateBssDesc->fgIsConnected) {
2986                     if (prCandidateBssDesc->ucRCPI + ROAMING_NO_SWING_RCPI_STEP <= prPrimaryBssDesc->ucRCPI) {
2987
2988                         prCandidateBssDesc = prPrimaryBssDesc;
2989                         prCandidateStaRec = prPrimaryStaRec;
2990                         continue;
2991                     }
2992                 }
2993                 else if (prPrimaryBssDesc->fgIsConnected) {
2994                     if (prCandidateBssDesc->ucRCPI < prPrimaryBssDesc->ucRCPI + ROAMING_NO_SWING_RCPI_STEP) {
2995
2996                         prCandidateBssDesc = prPrimaryBssDesc;
2997                         prCandidateStaRec = prPrimaryStaRec;
2998                         continue;
2999                     }
3000                 }
3001                 else if (prCandidateBssDesc->ucRCPI < prPrimaryBssDesc->ucRCPI) {
3002                     prCandidateBssDesc = prPrimaryBssDesc;
3003                     prCandidateStaRec = prPrimaryStaRec;
3004                     continue;
3005                 }
3006             }
3007
3008 #if 0
3009             /* If reach here, that means they have the same Encryption Score, and
3010              * both RSSI value are close too.
3011              */
3012             //4 <6F> Seek the minimum Channel Load for less interference.
3013             if (fgIsFindMinChannelLoad) {
3014
3015                 /* TODO(Kevin): Check which one has minimum channel load in its channel */
3016             }
3017 #endif
3018         }
3019     }
3020
3021     return prCandidateBssDesc;
3022
3023 } /* end of scanSearchBssDescByPolicy() */
3024
3025