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