import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / connectivity / combo / drv_wlan / mt6628 / wlan / mgmt / scan.c
CommitLineData
6fa3eb70
S
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 indicated to supplicant after formation.
23**
24** 01 16 2013 cp.wu
25** [ALPS00429083] [Need Patch] [Volunteer Patch][MT6620 Wi-Fi] Improve AP-IOT compatibility against AP whose timestamp will reset unexpectedly
26** when BSS-DESC is re-allocated, all information needs to be filled
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/*----------------------------------------------------------------------------*/
699VOID scnInit(IN P_ADAPTER_T prAdapter)
700{
701 P_SCAN_INFO_T prScanInfo;
702 P_BSS_DESC_T prBSSDesc;
703 PUINT_8 pucBSSBuff;
704 UINT_32 i;
705
706
707 ASSERT(prAdapter);
708
709 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
710 pucBSSBuff = &prScanInfo->aucScanBuffer[0];
711
712
713 DBGLOG(SCN, INFO, ("->scnInit()\n"));
714
715 /* 4 <1> Reset STATE and Message List */
716 prScanInfo->eCurrentState = SCAN_STATE_IDLE;
717
718 prScanInfo->rLastScanCompletedTime = (OS_SYSTIME) 0;
719
720 LINK_INITIALIZE(&prScanInfo->rPendingMsgList);
721
722
723 /* 4 <2> Reset link list of BSS_DESC_T */
724 kalMemZero((PVOID) pucBSSBuff, SCN_MAX_BUFFER_SIZE);
725
726 LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList);
727 LINK_INITIALIZE(&prScanInfo->rBSSDescList);
728
729 for (i = 0; i < CFG_MAX_NUM_BSS_LIST; i++) {
730
731 prBSSDesc = (P_BSS_DESC_T) pucBSSBuff;
732
733 LINK_INSERT_TAIL(&prScanInfo->rFreeBSSDescList, &prBSSDesc->rLinkEntry);
734
735 pucBSSBuff += ALIGN_4(sizeof(BSS_DESC_T));
736 }
737 /* Check if the memory allocation consist with this initialization function */
738 ASSERT(((UINT_32) pucBSSBuff - (UINT_32) &prScanInfo->aucScanBuffer[0]) ==
739 SCN_MAX_BUFFER_SIZE);
740
741 /* reset freest channel information */
742 prScanInfo->fgIsSparseChannelValid = FALSE;
743
744 return;
745} /* end of scnInit() */
746
747
748/*----------------------------------------------------------------------------*/
749/*!
750* @brief This function is used by SCN to uninitialize its variables
751*
752* @param (none)
753*
754* @return (none)
755*/
756/*----------------------------------------------------------------------------*/
757VOID scnUninit(IN P_ADAPTER_T prAdapter)
758{
759 P_SCAN_INFO_T prScanInfo;
760
761
762 ASSERT(prAdapter);
763 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
764
765 DBGLOG(SCN, INFO, ("->scnUninit()\n"));
766
767 /* 4 <1> Reset STATE and Message List */
768 prScanInfo->eCurrentState = SCAN_STATE_IDLE;
769
770 prScanInfo->rLastScanCompletedTime = (OS_SYSTIME) 0;
771
772 /* NOTE(Kevin): Check rPendingMsgList ? */
773
774 /* 4 <2> Reset link list of BSS_DESC_T */
775 LINK_INITIALIZE(&prScanInfo->rFreeBSSDescList);
776 LINK_INITIALIZE(&prScanInfo->rBSSDescList);
777
778 return;
779} /* end of scnUninit() */
780
781
782
783/*----------------------------------------------------------------------------*/
784/*!
785* @brief Find the corresponding BSS Descriptor according to given BSSID
786*
787* @param[in] prAdapter Pointer to the Adapter structure.
788* @param[in] aucBSSID Given BSSID.
789*
790* @return Pointer to BSS Descriptor, if found. NULL, if not found
791*/
792/*----------------------------------------------------------------------------*/
793P_BSS_DESC_T scanSearchBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]
794 )
795{
796 return scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, FALSE, NULL);
797}
798
799
800/*----------------------------------------------------------------------------*/
801/*!
802* @brief Find the corresponding BSS Descriptor according to given BSSID
803*
804* @param[in] prAdapter Pointer to the Adapter structure.
805* @param[in] aucBSSID Given BSSID.
806* @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases)
807* @param[in] prSsid Specified SSID
808*
809* @return Pointer to BSS Descriptor, if found. NULL, if not found
810*/
811/*----------------------------------------------------------------------------*/
812P_BSS_DESC_T
813scanSearchBssDescByBssidAndSsid(IN P_ADAPTER_T prAdapter,
814 IN UINT_8 aucBSSID[],
815 IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid)
816{
817 P_SCAN_INFO_T prScanInfo;
818 P_LINK_T prBSSDescList;
819 P_BSS_DESC_T prBssDesc;
820 P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T) NULL;
821
822
823 ASSERT(prAdapter);
824 ASSERT(aucBSSID);
825
826 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
827
828 prBSSDescList = &prScanInfo->rBSSDescList;
829
830 /* Search BSS Desc from current SCAN result list. */
831 LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
832
833 if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) {
834 if (fgCheckSsid == FALSE || prSsid == NULL) {
835 return prBssDesc;
836 } else {
837 if (EQUAL_SSID(prBssDesc->aucSSID,
838 prBssDesc->ucSSIDLen,
839 prSsid->aucSsid, prSsid->u4SsidLen)) {
840 return prBssDesc;
841 } else if (prDstBssDesc == NULL
842 && prBssDesc->fgIsHiddenSSID == TRUE) {
843 prDstBssDesc = prBssDesc;
844 } else {
845 /* 20120206 frog: Equal BSSID but not SSID, SSID not hidden, SSID must be updated. */
846 COPY_SSID(prBssDesc->aucSSID,
847 prBssDesc->ucSSIDLen,
848 prSsid->aucSsid, prSsid->u4SsidLen);
849 return prBssDesc;
850 }
851 }
852 }
853 }
854
855 return prDstBssDesc;
856
857} /* end of scanSearchBssDescByBssid() */
858
859
860/*----------------------------------------------------------------------------*/
861/*!
862* @brief Find the corresponding BSS Descriptor according to given Transmitter Address.
863*
864* @param[in] prAdapter Pointer to the Adapter structure.
865* @param[in] aucSrcAddr Given Source Address(TA).
866*
867* @return Pointer to BSS Descriptor, if found. NULL, if not found
868*/
869/*----------------------------------------------------------------------------*/
870P_BSS_DESC_T scanSearchBssDescByTA(IN P_ADAPTER_T prAdapter, IN UINT_8 aucSrcAddr[]
871 )
872{
873 return scanSearchBssDescByTAAndSsid(prAdapter, aucSrcAddr, FALSE, NULL);
874}
875
876/*----------------------------------------------------------------------------*/
877/*!
878* @brief Find the corresponding BSS Descriptor according to given Transmitter Address.
879*
880* @param[in] prAdapter Pointer to the Adapter structure.
881* @param[in] aucSrcAddr Given Source Address(TA).
882* @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases)
883* @param[in] prSsid Specified SSID
884*
885* @return Pointer to BSS Descriptor, if found. NULL, if not found
886*/
887/*----------------------------------------------------------------------------*/
888P_BSS_DESC_T
889scanSearchBssDescByTAAndSsid(IN P_ADAPTER_T prAdapter,
890 IN UINT_8 aucSrcAddr[],
891 IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid)
892{
893 P_SCAN_INFO_T prScanInfo;
894 P_LINK_T prBSSDescList;
895 P_BSS_DESC_T prBssDesc;
896 P_BSS_DESC_T prDstBssDesc = (P_BSS_DESC_T) NULL;
897
898
899 ASSERT(prAdapter);
900 ASSERT(aucSrcAddr);
901
902 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
903
904 prBSSDescList = &prScanInfo->rBSSDescList;
905
906 /* Search BSS Desc from current SCAN result list. */
907 LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
908
909 if (EQUAL_MAC_ADDR(prBssDesc->aucSrcAddr, aucSrcAddr)) {
910 if (fgCheckSsid == FALSE || prSsid == NULL) {
911 return prBssDesc;
912 } else {
913 if (EQUAL_SSID(prBssDesc->aucSSID,
914 prBssDesc->ucSSIDLen,
915 prSsid->aucSsid, prSsid->u4SsidLen)) {
916 return prBssDesc;
917 } else if (prDstBssDesc == NULL
918 && prBssDesc->fgIsHiddenSSID == TRUE) {
919 prDstBssDesc = prBssDesc;
920 }
921 }
922 }
923 }
924
925 return prDstBssDesc;
926
927} /* end of scanSearchBssDescByTA() */
928
929
930/*----------------------------------------------------------------------------*/
931/*!
932* @brief Find the corresponding BSS Descriptor according to
933* given eBSSType, BSSID and Transmitter Address
934*
935* @param[in] prAdapter Pointer to the Adapter structure.
936* @param[in] eBSSType BSS Type of incoming Beacon/ProbeResp frame.
937* @param[in] aucBSSID Given BSSID of Beacon/ProbeResp frame.
938* @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame.
939*
940* @return Pointer to BSS Descriptor, if found. NULL, if not found
941*/
942/*----------------------------------------------------------------------------*/
943P_BSS_DESC_T
944scanSearchExistingBssDesc(IN P_ADAPTER_T prAdapter,
945 IN ENUM_BSS_TYPE_T eBSSType, IN UINT_8 aucBSSID[], IN UINT_8 aucSrcAddr[]
946 )
947{
948 return scanSearchExistingBssDescWithSsid(prAdapter,
949 eBSSType, aucBSSID, aucSrcAddr, FALSE, NULL);
950}
951
952
953/*----------------------------------------------------------------------------*/
954/*!
955* @brief Find the corresponding BSS Descriptor according to
956* given eBSSType, BSSID and Transmitter Address
957*
958* @param[in] prAdapter Pointer to the Adapter structure.
959* @param[in] eBSSType BSS Type of incoming Beacon/ProbeResp frame.
960* @param[in] aucBSSID Given BSSID of Beacon/ProbeResp frame.
961* @param[in] aucSrcAddr Given source address (TA) of Beacon/ProbeResp frame.
962* @param[in] fgCheckSsid Need to check SSID or not. (for multiple SSID with single BSSID cases)
963* @param[in] prSsid Specified SSID
964*
965* @return Pointer to BSS Descriptor, if found. NULL, if not found
966*/
967/*----------------------------------------------------------------------------*/
968P_BSS_DESC_T
969scanSearchExistingBssDescWithSsid(IN P_ADAPTER_T prAdapter,
970 IN ENUM_BSS_TYPE_T eBSSType,
971 IN UINT_8 aucBSSID[],
972 IN UINT_8 aucSrcAddr[],
973 IN BOOLEAN fgCheckSsid, IN P_PARAM_SSID_T prSsid)
974{
975 P_SCAN_INFO_T prScanInfo;
976 P_BSS_DESC_T prBssDesc, prIBSSBssDesc;
977
978 ASSERT(prAdapter);
979 ASSERT(aucSrcAddr);
980
981 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
982
983
984 switch (eBSSType) {
985 case BSS_TYPE_P2P_DEVICE:
986 fgCheckSsid = FALSE;
987 case BSS_TYPE_INFRASTRUCTURE:
988 case BSS_TYPE_BOW_DEVICE:
989 {
990 prBssDesc =
991 scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, fgCheckSsid,
992 prSsid);
993
994 /* if (eBSSType == prBssDesc->eBSSType) */
995
996 return prBssDesc;
997 }
998
999 case BSS_TYPE_IBSS:
1000 {
1001 prIBSSBssDesc =
1002 scanSearchBssDescByBssidAndSsid(prAdapter, aucBSSID, fgCheckSsid,
1003 prSsid);
1004 prBssDesc =
1005 scanSearchBssDescByTAAndSsid(prAdapter, aucSrcAddr, fgCheckSsid,
1006 prSsid);
1007
1008 /* NOTE(Kevin):
1009 * Rules to maintain the SCAN Result:
1010 * For AdHoc -
1011 * CASE I We have TA1(BSSID1), but it change its BSSID to BSSID2
1012 * -> Update TA1 entry's BSSID.
1013 * CASE II We have TA1(BSSID1), and get TA1(BSSID1) again
1014 * -> Update TA1 entry's contain.
1015 * CASE III We have a SCAN result TA1(BSSID1), and TA2(BSSID2). Sooner or
1016 * later, TA2 merge into TA1, we get TA2(BSSID1)
1017 * -> Remove TA2 first and then replace TA1 entry's TA with TA2, Still have only one entry of BSSID.
1018 * CASE IV We have a SCAN result TA1(BSSID1), and another TA2 also merge into BSSID1.
1019 * -> Replace TA1 entry's TA with TA2, Still have only one entry.
1020 * CASE V New IBSS
1021 * -> Add this one to SCAN result.
1022 */
1023 if (prBssDesc) {
1024 if ((!prIBSSBssDesc) || /* CASE I */
1025 (prBssDesc == prIBSSBssDesc)) { /* CASE II */
1026
1027 return prBssDesc;
1028 } else { /* CASE III */
1029 P_LINK_T prBSSDescList;
1030 P_LINK_T prFreeBSSDescList;
1031
1032
1033 prBSSDescList = &prScanInfo->rBSSDescList;
1034 prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1035
1036 /* Remove this BSS Desc from the BSS Desc list */
1037 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1038
1039 /* Return this BSS Desc to the free BSS Desc list. */
1040 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1041
1042 return prIBSSBssDesc;
1043 }
1044 }
1045
1046 if (prIBSSBssDesc) { /* CASE IV */
1047
1048 return prIBSSBssDesc;
1049 }
1050 /* CASE V */
1051 break; /* Return NULL; */
1052 }
1053
1054 default:
1055 break;
1056 }
1057
1058
1059 return (P_BSS_DESC_T) NULL;
1060
1061} /* end of scanSearchExistingBssDesc() */
1062
1063
1064/*----------------------------------------------------------------------------*/
1065/*!
1066* @brief Delete BSS Descriptors from current list according to given Remove Policy.
1067*
1068* @param[in] u4RemovePolicy Remove Policy.
1069*
1070* @return (none)
1071*/
1072/*----------------------------------------------------------------------------*/
1073VOID scanRemoveBssDescsByPolicy(IN P_ADAPTER_T prAdapter, IN UINT_32 u4RemovePolicy)
1074{
1075 P_CONNECTION_SETTINGS_T prConnSettings;
1076 P_SCAN_INFO_T prScanInfo;
1077 P_LINK_T prBSSDescList;
1078 P_LINK_T prFreeBSSDescList;
1079 P_BSS_DESC_T prBssDesc;
1080
1081
1082 ASSERT(prAdapter);
1083
1084 prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
1085 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1086 prBSSDescList = &prScanInfo->rBSSDescList;
1087 prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1088
1089 /* DBGLOG(SCN, TRACE, ("Before Remove - Number Of SCAN Result = %ld\n", */
1090 /* prBSSDescList->u4NumElem)); */
1091
1092 if (u4RemovePolicy & SCN_RM_POLICY_TIMEOUT) {
1093 P_BSS_DESC_T prBSSDescNext;
1094 OS_SYSTIME rCurrentTime;
1095
1096
1097 GET_CURRENT_SYSTIME(&rCurrentTime);
1098
1099 /* Search BSS Desc from current SCAN result list. */
1100 LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry,
1101 BSS_DESC_T) {
1102
1103 if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
1104 (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
1105 /* Don't remove the one currently we are connected. */
1106 continue;
1107 }
1108
1109 if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
1110 SEC_TO_SYSTIME(SCN_BSS_DESC_REMOVE_TIMEOUT_SEC))) {
1111
1112 /* DBGLOG(SCN, TRACE, ("Remove TIMEOUT BSS DESC(%#x): MAC: "MACSTR", Current Time = %08lx, Update Time = %08lx\n", */
1113 /* prBssDesc, MAC2STR(prBssDesc->aucBSSID), rCurrentTime, prBssDesc->rUpdateTime)); */
1114
1115 /* Remove this BSS Desc from the BSS Desc list */
1116 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1117
1118 /* Return this BSS Desc to the free BSS Desc list. */
1119 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1120 }
1121 }
1122 } else if (u4RemovePolicy & SCN_RM_POLICY_OLDEST_HIDDEN) {
1123 P_BSS_DESC_T prBssDescOldest = (P_BSS_DESC_T) NULL;
1124
1125
1126 /* Search BSS Desc from current SCAN result list. */
1127 LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1128
1129 if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
1130 (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
1131 /* Don't remove the one currently we are connected. */
1132 continue;
1133 }
1134
1135 if (!prBssDesc->fgIsHiddenSSID) {
1136 continue;
1137 }
1138
1139 if (!prBssDescOldest) { /* 1st element */
1140 prBssDescOldest = prBssDesc;
1141 continue;
1142 }
1143
1144 if (TIME_BEFORE(prBssDesc->rUpdateTime, prBssDescOldest->rUpdateTime)) {
1145 prBssDescOldest = prBssDesc;
1146 }
1147 }
1148
1149 if (prBssDescOldest) {
1150
1151 /* DBGLOG(SCN, TRACE, ("Remove OLDEST HIDDEN BSS DESC(%#x): MAC: "MACSTR", Update Time = %08lx\n", */
1152 /* prBssDescOldest, MAC2STR(prBssDescOldest->aucBSSID), prBssDescOldest->rUpdateTime)); */
1153
1154 /* Remove this BSS Desc from the BSS Desc list */
1155 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescOldest);
1156
1157 /* Return this BSS Desc to the free BSS Desc list. */
1158 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDescOldest->rLinkEntry);
1159 }
1160 } else if (u4RemovePolicy & SCN_RM_POLICY_SMART_WEAKEST) {
1161 P_BSS_DESC_T prBssDescWeakest = (P_BSS_DESC_T) NULL;
1162 P_BSS_DESC_T prBssDescWeakestSameSSID = (P_BSS_DESC_T) NULL;
1163 UINT_32 u4SameSSIDCount = 0;
1164
1165
1166 /* Search BSS Desc from current SCAN result list. */
1167 LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1168
1169 if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
1170 (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
1171 /* Don't remove the one currently we are connected. */
1172 continue;
1173 }
1174
1175 if ((!prBssDesc->fgIsHiddenSSID) &&
1176 (EQUAL_SSID(prBssDesc->aucSSID,
1177 prBssDesc->ucSSIDLen,
1178 prConnSettings->aucSSID, prConnSettings->ucSSIDLen))) {
1179
1180 u4SameSSIDCount++;
1181
1182 if (!prBssDescWeakestSameSSID) {
1183 prBssDescWeakestSameSSID = prBssDesc;
1184 } else if (prBssDesc->ucRCPI < prBssDescWeakestSameSSID->ucRCPI) {
1185 prBssDescWeakestSameSSID = prBssDesc;
1186 }
1187 }
1188
1189 if (!prBssDescWeakest) { /* 1st element */
1190 prBssDescWeakest = prBssDesc;
1191 continue;
1192 }
1193
1194 if (prBssDesc->ucRCPI < prBssDescWeakest->ucRCPI) {
1195 prBssDescWeakest = prBssDesc;
1196 }
1197
1198 }
1199
1200 if ((u4SameSSIDCount >= SCN_BSS_DESC_SAME_SSID_THRESHOLD) &&
1201 (prBssDescWeakestSameSSID)) {
1202 prBssDescWeakest = prBssDescWeakestSameSSID;
1203 }
1204
1205 if (prBssDescWeakest) {
1206
1207 /* DBGLOG(SCN, TRACE, ("Remove WEAKEST BSS DESC(%#x): MAC: "MACSTR", Update Time = %08lx\n", */
1208 /* prBssDescOldest, MAC2STR(prBssDescOldest->aucBSSID), prBssDescOldest->rUpdateTime)); */
1209
1210 /* Remove this BSS Desc from the BSS Desc list */
1211 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDescWeakest);
1212
1213 /* Return this BSS Desc to the free BSS Desc list. */
1214 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDescWeakest->rLinkEntry);
1215 }
1216 } else if (u4RemovePolicy & SCN_RM_POLICY_ENTIRE) {
1217 P_BSS_DESC_T prBSSDescNext;
1218
1219 LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry,
1220 BSS_DESC_T) {
1221
1222 if ((u4RemovePolicy & SCN_RM_POLICY_EXCLUDE_CONNECTED) &&
1223 (prBssDesc->fgIsConnected || prBssDesc->fgIsConnecting)) {
1224 /* Don't remove the one currently we are connected. */
1225 continue;
1226 }
1227
1228 /* Remove this BSS Desc from the BSS Desc list */
1229 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1230
1231 /* Return this BSS Desc to the free BSS Desc list. */
1232 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1233 }
1234
1235 }
1236
1237 return;
1238
1239} /* end of scanRemoveBssDescsByPolicy() */
1240
1241
1242/*----------------------------------------------------------------------------*/
1243/*!
1244* @brief Delete BSS Descriptors from current list according to given BSSID.
1245*
1246* @param[in] prAdapter Pointer to the Adapter structure.
1247* @param[in] aucBSSID Given BSSID.
1248*
1249* @return (none)
1250*/
1251/*----------------------------------------------------------------------------*/
1252VOID scanRemoveBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]
1253 )
1254{
1255 P_SCAN_INFO_T prScanInfo;
1256 P_LINK_T prBSSDescList;
1257 P_LINK_T prFreeBSSDescList;
1258 P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL;
1259 P_BSS_DESC_T prBSSDescNext;
1260
1261
1262 ASSERT(prAdapter);
1263 ASSERT(aucBSSID);
1264
1265 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1266 prBSSDescList = &prScanInfo->rBSSDescList;
1267 prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1268
1269 /* Check if such BSS Descriptor exists in a valid list */
1270 LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1271
1272 if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) {
1273
1274 /* Remove this BSS Desc from the BSS Desc list */
1275 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1276
1277 /* Return this BSS Desc to the free BSS Desc list. */
1278 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1279
1280 /* BSSID is not unique, so need to traverse whols link-list */
1281 }
1282 }
1283
1284 return;
1285} /* end of scanRemoveBssDescByBssid() */
1286
1287
1288/*----------------------------------------------------------------------------*/
1289/*!
1290* @brief Delete BSS Descriptors from current list according to given band configuration
1291*
1292* @param[in] prAdapter Pointer to the Adapter structure.
1293* @param[in] eBand Given band
1294* @param[in] eNetTypeIndex AIS - Remove IBSS/Infrastructure BSS
1295* BOW - Remove BOW BSS
1296* P2P - Remove P2P BSS
1297*
1298* @return (none)
1299*/
1300/*----------------------------------------------------------------------------*/
1301VOID
1302scanRemoveBssDescByBandAndNetwork(IN P_ADAPTER_T prAdapter,
1303 IN ENUM_BAND_T eBand, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex)
1304{
1305 P_SCAN_INFO_T prScanInfo;
1306 P_LINK_T prBSSDescList;
1307 P_LINK_T prFreeBSSDescList;
1308 P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL;
1309 P_BSS_DESC_T prBSSDescNext;
1310 BOOLEAN fgToRemove;
1311
1312 ASSERT(prAdapter);
1313 ASSERT(eBand <= BAND_NUM);
1314 ASSERT(eNetTypeIndex <= NETWORK_TYPE_INDEX_NUM);
1315
1316 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1317 prBSSDescList = &prScanInfo->rBSSDescList;
1318 prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1319
1320
1321 if (eBand == BAND_NULL) {
1322 return; /* no need to do anything, keep all scan result */
1323 }
1324
1325 /* Check if such BSS Descriptor exists in a valid list */
1326 LINK_FOR_EACH_ENTRY_SAFE(prBssDesc, prBSSDescNext, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1327 fgToRemove = FALSE;
1328
1329 if (prBssDesc->eBand == eBand) {
1330 switch (eNetTypeIndex) {
1331 case NETWORK_TYPE_AIS_INDEX:
1332 if ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE)
1333 || (prBssDesc->eBSSType == BSS_TYPE_IBSS)) {
1334 fgToRemove = TRUE;
1335 }
1336 break;
1337
1338 case NETWORK_TYPE_P2P_INDEX:
1339 if (prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) {
1340 fgToRemove = TRUE;
1341 }
1342 break;
1343
1344 case NETWORK_TYPE_BOW_INDEX:
1345 if (prBssDesc->eBSSType == BSS_TYPE_BOW_DEVICE) {
1346 fgToRemove = TRUE;
1347 }
1348 break;
1349
1350 default:
1351 ASSERT(0);
1352 break;
1353 }
1354 }
1355
1356 if (fgToRemove == TRUE) {
1357 /* Remove this BSS Desc from the BSS Desc list */
1358 LINK_REMOVE_KNOWN_ENTRY(prBSSDescList, prBssDesc);
1359
1360 /* Return this BSS Desc to the free BSS Desc list. */
1361 LINK_INSERT_TAIL(prFreeBSSDescList, &prBssDesc->rLinkEntry);
1362 }
1363 }
1364
1365 return;
1366} /* end of scanRemoveBssDescByBand() */
1367
1368
1369/*----------------------------------------------------------------------------*/
1370/*!
1371* @brief Clear the CONNECTION FLAG of a specified BSS Descriptor.
1372*
1373* @param[in] aucBSSID Given BSSID.
1374*
1375* @return (none)
1376*/
1377/*----------------------------------------------------------------------------*/
1378VOID scanRemoveConnFlagOfBssDescByBssid(IN P_ADAPTER_T prAdapter, IN UINT_8 aucBSSID[]
1379 )
1380{
1381 P_SCAN_INFO_T prScanInfo;
1382 P_LINK_T prBSSDescList;
1383 P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL;
1384
1385
1386 ASSERT(prAdapter);
1387 ASSERT(aucBSSID);
1388
1389 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1390 prBSSDescList = &prScanInfo->rBSSDescList;
1391
1392 /* Search BSS Desc from current SCAN result list. */
1393 LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
1394
1395 if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, aucBSSID)) {
1396 prBssDesc->fgIsConnected = FALSE;
1397 prBssDesc->fgIsConnecting = FALSE;
1398
1399 /* BSSID is not unique, so need to traverse whols link-list */
1400 }
1401 }
1402
1403 return;
1404
1405} /* end of scanRemoveConnectionFlagOfBssDescByBssid() */
1406
1407
1408/*----------------------------------------------------------------------------*/
1409/*!
1410* @brief Allocate new BSS_DESC_T
1411*
1412* @param[in] prAdapter Pointer to the Adapter structure.
1413*
1414* @return Pointer to BSS Descriptor, if has free space. NULL, if has no space.
1415*/
1416/*----------------------------------------------------------------------------*/
1417P_BSS_DESC_T scanAllocateBssDesc(IN P_ADAPTER_T prAdapter)
1418{
1419 P_SCAN_INFO_T prScanInfo;
1420 P_LINK_T prFreeBSSDescList;
1421 P_BSS_DESC_T prBssDesc;
1422
1423
1424 ASSERT(prAdapter);
1425 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
1426
1427 prFreeBSSDescList = &prScanInfo->rFreeBSSDescList;
1428
1429 LINK_REMOVE_HEAD(prFreeBSSDescList, prBssDesc, P_BSS_DESC_T);
1430
1431 if (prBssDesc) {
1432 P_LINK_T prBSSDescList;
1433
1434 kalMemZero(prBssDesc, sizeof(BSS_DESC_T));
1435
1436#if CFG_ENABLE_WIFI_DIRECT
1437 LINK_INITIALIZE(&(prBssDesc->rP2pDeviceList));
1438 prBssDesc->fgIsP2PPresent = FALSE;
1439#endif /* CFG_ENABLE_WIFI_DIRECT */
1440
1441 prBSSDescList = &prScanInfo->rBSSDescList;
1442
1443 /* NOTE(Kevin): In current design, this new empty BSS_DESC_T will be
1444 * inserted to BSSDescList immediately.
1445 */
1446 LINK_INSERT_TAIL(prBSSDescList, &prBssDesc->rLinkEntry);
1447 }
1448
1449 return prBssDesc;
1450
1451} /* end of scanAllocateBssDesc() */
1452
1453
1454/*----------------------------------------------------------------------------*/
1455/*!
1456* @brief This API parses Beacon/ProbeResp frame and insert extracted BSS_DESC_T
1457* with IEs into prAdapter->rWifiVar.rScanInfo.aucScanBuffer
1458*
1459* @param[in] prAdapter Pointer to the Adapter structure.
1460* @param[in] prSwRfb Pointer to the receiving frame buffer.
1461*
1462* @return Pointer to BSS Descriptor
1463* NULL if the Beacon/ProbeResp frame is invalid
1464*/
1465/*----------------------------------------------------------------------------*/
1466P_BSS_DESC_T scanAddToBssDesc(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
1467{
1468 P_BSS_DESC_T prBssDesc = NULL;
1469 UINT_16 u2CapInfo;
1470 ENUM_BSS_TYPE_T eBSSType = BSS_TYPE_INFRASTRUCTURE;
1471
1472 PUINT_8 pucIE;
1473 UINT_16 u2IELength;
1474 UINT_16 u2Offset = 0;
1475
1476 P_WLAN_BEACON_FRAME_T prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) NULL;
1477 P_IE_SSID_T prIeSsid = (P_IE_SSID_T) NULL;
1478 P_IE_SUPPORTED_RATE_T prIeSupportedRate = (P_IE_SUPPORTED_RATE_T) NULL;
1479 P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate = (P_IE_EXT_SUPPORTED_RATE_T) NULL;
1480 P_HIF_RX_HEADER_T prHifRxHdr;
1481 UINT_8 ucHwChannelNum = 0;
1482 UINT_8 ucIeDsChannelNum = 0;
1483 UINT_8 ucIeHtChannelNum = 0;
1484 BOOLEAN fgIsValidSsid = FALSE, fgEscape = FALSE;
1485 PARAM_SSID_T rSsid;
1486 UINT_64 u8Timestamp;
1487 BOOLEAN fgIsNewBssDesc = FALSE;
1488
1489 UINT_32 i;
1490 UINT_8 ucSSIDChar;
1491
1492 ASSERT(prAdapter);
1493 ASSERT(prSwRfb);
1494
1495 prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) prSwRfb->pvHeader;
1496
1497 WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2CapInfo, &u2CapInfo);
1498 WLAN_GET_FIELD_64(&prWlanBeaconFrame->au4Timestamp[0], &u8Timestamp);
1499
1500 /* decide BSS type */
1501 switch (u2CapInfo & CAP_INFO_BSS_TYPE) {
1502 case CAP_INFO_ESS:
1503 /* It can also be Group Owner of P2P Group. */
1504 eBSSType = BSS_TYPE_INFRASTRUCTURE;
1505 break;
1506
1507 case CAP_INFO_IBSS:
1508 eBSSType = BSS_TYPE_IBSS;
1509 break;
1510 case 0:
1511 /* 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) */
1512 eBSSType = BSS_TYPE_P2P_DEVICE;
1513 break;
1514
1515#if CFG_ENABLE_BT_OVER_WIFI
1516 /* @TODO: add rule to identify BOW beacons */
1517#endif
1518
1519 default :
1520 return NULL;
1521 }
1522
1523 /* 4 <1.1> Pre-parse SSID IE */
1524 pucIE = prWlanBeaconFrame->aucInfoElem;
1525 u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
1526 (UINT_16) OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]);
1527
1528 if (u2IELength > CFG_IE_BUFFER_SIZE) {
1529 u2IELength = CFG_IE_BUFFER_SIZE;
1530 }
1531
1532 IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
1533 switch (IE_ID(pucIE)) {
1534 case ELEM_ID_SSID:
1535 if (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID) {
1536 ucSSIDChar = '\0';
1537
1538 /* D-Link DWL-900AP+ */
1539 if (IE_LEN(pucIE) == 0) {
1540 fgIsValidSsid = FALSE;
1541 }
1542 /* Cisco AP1230A - (IE_LEN(pucIE) == 1) && (SSID_IE(pucIE)->aucSSID[0] == '\0') */
1543 /* Linksys WRK54G/ASUS WL520g - (IE_LEN(pucIE) == n) && (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') */
1544 else {
1545 for (i = 0; i < IE_LEN(pucIE); i++) {
1546 ucSSIDChar |= SSID_IE(pucIE)->aucSSID[i];
1547 }
1548
1549 if (ucSSIDChar) {
1550 fgIsValidSsid = TRUE;
1551 }
1552 }
1553
1554 /* Update SSID to BSS Descriptor only if SSID is not hidden. */
1555 if (fgIsValidSsid == TRUE) {
1556 COPY_SSID(rSsid.aucSsid,
1557 rSsid.u4SsidLen,
1558 SSID_IE(pucIE)->aucSSID,
1559 SSID_IE(pucIE)->ucLength);
1560 }
1561 }
1562 fgEscape = TRUE;
1563 break;
1564 default:
1565 break;
1566 }
1567
1568 if (fgEscape == TRUE) {
1569 break;
1570 }
1571 }
1572
1573
1574 /* 4 <1.2> Replace existing BSS_DESC_T or allocate a new one */
1575 prBssDesc = scanSearchExistingBssDescWithSsid(prAdapter,
1576 eBSSType,
1577 (PUINT_8) prWlanBeaconFrame->aucBSSID,
1578 (PUINT_8) prWlanBeaconFrame->aucSrcAddr,
1579 fgIsValidSsid,
1580 fgIsValidSsid == TRUE ? &rSsid : NULL);
1581
1582 if (prBssDesc == (P_BSS_DESC_T) NULL) {
1583 fgIsNewBssDesc = TRUE;
1584
1585 do {
1586 /* 4 <1.2.1> First trial of allocation */
1587 prBssDesc = scanAllocateBssDesc(prAdapter);
1588 if (prBssDesc) {
1589 break;
1590 }
1591 /* 4 <1.2.2> Hidden is useless, remove the oldest hidden ssid. (for passive scan) */
1592 scanRemoveBssDescsByPolicy(prAdapter,
1593 (SCN_RM_POLICY_EXCLUDE_CONNECTED |
1594 SCN_RM_POLICY_OLDEST_HIDDEN));
1595
1596 /* 4 <1.2.3> Second tail of allocation */
1597 prBssDesc = scanAllocateBssDesc(prAdapter);
1598 if (prBssDesc) {
1599 break;
1600 }
1601 /* 4 <1.2.4> Remove the weakest one */
1602 /* If there are more than half of BSS which has the same ssid as connection
1603 * setting, remove the weakest one from them.
1604 * Else remove the weakest one.
1605 */
1606 scanRemoveBssDescsByPolicy(prAdapter,
1607 (SCN_RM_POLICY_EXCLUDE_CONNECTED |
1608 SCN_RM_POLICY_SMART_WEAKEST));
1609
1610 /* 4 <1.2.5> reallocation */
1611 prBssDesc = scanAllocateBssDesc(prAdapter);
1612 if (prBssDesc) {
1613 break;
1614 }
1615 /* 4 <1.2.6> no space, should not happen */
1616 /* ASSERT(0); // still no space available ? */
1617 return NULL;
1618
1619 }
1620 while (FALSE);
1621
1622 } else {
1623 OS_SYSTIME rCurrentTime;
1624
1625 /* WCXRP00000091 */
1626 /* if the received strength is much weaker than the original one, */
1627 /* ignore it due to it might be received on the folding frequency */
1628
1629 GET_CURRENT_SYSTIME(&rCurrentTime);
1630
1631 if (prBssDesc->eBSSType != eBSSType) {
1632 prBssDesc->eBSSType = eBSSType;
1633 } else if (HIF_RX_HDR_GET_CHNL_NUM(prSwRfb->prHifRxHdr) != prBssDesc->ucChannelNum
1634 && prBssDesc->ucRCPI > prSwRfb->prHifRxHdr->ucRcpi) {
1635
1636 /* for signal strength is too much weaker and previous beacon is not stale */
1637 if ((prBssDesc->ucRCPI - prSwRfb->prHifRxHdr->ucRcpi) >=
1638 REPLICATED_BEACON_STRENGTH_THRESHOLD
1639 && rCurrentTime - prBssDesc->rUpdateTime <=
1640 REPLICATED_BEACON_FRESH_PERIOD) {
1641 return prBssDesc;
1642 }
1643 /* for received beacons too close in time domain */
1644 else if (rCurrentTime - prBssDesc->rUpdateTime <=
1645 REPLICATED_BEACON_TIME_THRESHOLD) {
1646 return prBssDesc;
1647 }
1648 }
1649
1650 /* if Timestamp has been reset, re-generate BSS DESC 'cause AP should have reset itself */
1651 if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE
1652 && u8Timestamp < prBssDesc->u8TimeStamp.QuadPart) {
1653 BOOLEAN fgIsConnected, fgIsConnecting;
1654
1655 /* set flag for indicating this is a new BSS-DESC */
1656 fgIsNewBssDesc = TRUE;
1657
1658 /* backup 2 flags for APs which reset timestamp unexpectedly */
1659 fgIsConnected = prBssDesc->fgIsConnected;
1660 fgIsConnecting = prBssDesc->fgIsConnecting;
1661 scanRemoveBssDescByBssid(prAdapter, prBssDesc->aucBSSID);
1662
1663 prBssDesc = scanAllocateBssDesc(prAdapter);
1664 if (!prBssDesc) {
1665 return NULL;
1666 }
1667
1668 /* restore */
1669 prBssDesc->fgIsConnected = fgIsConnected;
1670 prBssDesc->fgIsConnecting = fgIsConnecting;
1671 }
1672 }
1673
1674 /* NOTE: Keep consistency of Scan Record during JOIN process */
1675 if (fgIsNewBssDesc == FALSE && prBssDesc->fgIsConnecting) {
1676 return prBssDesc;
1677 }
1678 /* 4 <2> Get information from Fixed Fields */
1679 prBssDesc->eBSSType = eBSSType; /* Update the latest BSS type information. */
1680
1681 COPY_MAC_ADDR(prBssDesc->aucSrcAddr, prWlanBeaconFrame->aucSrcAddr);
1682
1683 COPY_MAC_ADDR(prBssDesc->aucBSSID, prWlanBeaconFrame->aucBSSID);
1684
1685 prBssDesc->u8TimeStamp.QuadPart = u8Timestamp;
1686
1687 WLAN_GET_FIELD_16(&prWlanBeaconFrame->u2BeaconInterval, &prBssDesc->u2BeaconInterval);
1688
1689 prBssDesc->u2CapInfo = u2CapInfo;
1690
1691
1692 /* 4 <2.1> Retrieve IEs for later parsing */
1693 u2IELength = (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
1694 (UINT_16) OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0]);
1695
1696 if (u2IELength > CFG_IE_BUFFER_SIZE) {
1697 u2IELength = CFG_IE_BUFFER_SIZE;
1698 prBssDesc->fgIsIEOverflow = TRUE;
1699 } else {
1700 prBssDesc->fgIsIEOverflow = FALSE;
1701 }
1702 prBssDesc->u2IELength = u2IELength;
1703
1704 kalMemCopy(prBssDesc->aucIEBuf, prWlanBeaconFrame->aucInfoElem, u2IELength);
1705
1706 /* 4 <2.2> reset prBssDesc variables in case that AP has been reconfigured */
1707 prBssDesc->fgIsERPPresent = FALSE;
1708 prBssDesc->fgIsHTPresent = FALSE;
1709 prBssDesc->eSco = CHNL_EXT_SCN;
1710 prBssDesc->fgIEWAPI = FALSE;
1711#if CFG_RSN_MIGRATION
1712 prBssDesc->fgIERSN = FALSE;
1713#endif
1714#if CFG_PRIVACY_MIGRATION
1715 prBssDesc->fgIEWPA = FALSE;
1716#endif
1717
1718
1719 /* 4 <3.1> Full IE parsing on SW_RFB_T */
1720 pucIE = prWlanBeaconFrame->aucInfoElem;
1721
1722
1723 IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
1724
1725 switch (IE_ID(pucIE)) {
1726 case ELEM_ID_SSID:
1727 if ((!prIeSsid) && /* NOTE(Kevin): for Atheros IOT #1 */
1728 (IE_LEN(pucIE) <= ELEM_MAX_LEN_SSID)) {
1729 BOOLEAN fgIsHiddenSSID = FALSE;
1730 ucSSIDChar = '\0';
1731
1732
1733 prIeSsid = (P_IE_SSID_T) pucIE;
1734
1735 /* D-Link DWL-900AP+ */
1736 if (IE_LEN(pucIE) == 0) {
1737 fgIsHiddenSSID = TRUE;
1738 }
1739 /* Cisco AP1230A - (IE_LEN(pucIE) == 1) && (SSID_IE(pucIE)->aucSSID[0] == '\0') */
1740 /* Linksys WRK54G/ASUS WL520g - (IE_LEN(pucIE) == n) && (SSID_IE(pucIE)->aucSSID[0~(n-1)] == '\0') */
1741 else {
1742 for (i = 0; i < IE_LEN(pucIE); i++) {
1743 ucSSIDChar |= SSID_IE(pucIE)->aucSSID[i];
1744 }
1745
1746 if (!ucSSIDChar) {
1747 fgIsHiddenSSID = TRUE;
1748 }
1749 }
1750
1751 /* Update SSID to BSS Descriptor only if SSID is not hidden. */
1752 if (!fgIsHiddenSSID) {
1753 COPY_SSID(prBssDesc->aucSSID,
1754 prBssDesc->ucSSIDLen,
1755 SSID_IE(pucIE)->aucSSID,
1756 SSID_IE(pucIE)->ucLength);
1757 }
1758
1759 }
1760 break;
1761
1762 case ELEM_ID_SUP_RATES:
1763 /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8.
1764 * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B),
1765 * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)"
1766 */
1767 /* TP-LINK will set extra and incorrect ie with ELEM_ID_SUP_RATES */
1768 if ((!prIeSupportedRate) && (IE_LEN(pucIE) <= RATE_NUM)) {
1769 prIeSupportedRate = SUP_RATES_IE(pucIE);
1770 }
1771 break;
1772
1773 case ELEM_ID_DS_PARAM_SET:
1774 if (IE_LEN(pucIE) == ELEM_MAX_LEN_DS_PARAMETER_SET) {
1775 ucIeDsChannelNum = DS_PARAM_IE(pucIE)->ucCurrChnl;
1776 }
1777 break;
1778
1779 case ELEM_ID_TIM:
1780 if (IE_LEN(pucIE) <= ELEM_MAX_LEN_TIM) {
1781 prBssDesc->ucDTIMPeriod = TIM_IE(pucIE)->ucDTIMPeriod;
1782 }
1783 break;
1784
1785 case ELEM_ID_IBSS_PARAM_SET:
1786 if (IE_LEN(pucIE) == ELEM_MAX_LEN_IBSS_PARAMETER_SET) {
1787 prBssDesc->u2ATIMWindow = IBSS_PARAM_IE(pucIE)->u2ATIMWindow;
1788 }
1789 break;
1790
1791#if 0 /* CFG_SUPPORT_802_11D */
1792 case ELEM_ID_COUNTRY_INFO:
1793 prBssDesc->prIECountry = (P_IE_COUNTRY_T) pucIE;
1794 break;
1795#endif
1796
1797 case ELEM_ID_ERP_INFO:
1798 if (IE_LEN(pucIE) == ELEM_MAX_LEN_ERP) {
1799 prBssDesc->fgIsERPPresent = TRUE;
1800 }
1801 break;
1802
1803 case ELEM_ID_EXTENDED_SUP_RATES:
1804 if (!prIeExtSupportedRate) {
1805 prIeExtSupportedRate = EXT_SUP_RATES_IE(pucIE);
1806 }
1807 break;
1808
1809#if CFG_RSN_MIGRATION
1810 case ELEM_ID_RSN:
1811 if (rsnParseRsnIE(prAdapter, RSN_IE(pucIE), &prBssDesc->rRSNInfo)) {
1812 prBssDesc->fgIERSN = TRUE;
1813 prBssDesc->u2RsnCap = prBssDesc->rRSNInfo.u2RsnCap;
1814 if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) {
1815 rsnCheckPmkidCache(prAdapter, prBssDesc);
1816 }
1817 }
1818 break;
1819#endif
1820
1821 case ELEM_ID_HT_CAP:
1822 prBssDesc->fgIsHTPresent = TRUE;
1823 break;
1824
1825 case ELEM_ID_HT_OP:
1826 if (IE_LEN(pucIE) != (sizeof(IE_HT_OP_T) - 2)) {
1827 break;
1828 }
1829
1830 if ((((P_IE_HT_OP_T) pucIE)->ucInfo1 & HT_OP_INFO1_SCO) != CHNL_EXT_RES) {
1831 prBssDesc->eSco = (ENUM_CHNL_EXT_T)
1832 (((P_IE_HT_OP_T) pucIE)->ucInfo1 & HT_OP_INFO1_SCO);
1833 }
1834 ucIeHtChannelNum = ((P_IE_HT_OP_T) pucIE)->ucPrimaryChannel;
1835
1836 break;
1837
1838#if CFG_SUPPORT_WAPI
1839 case ELEM_ID_WAPI:
1840 if (wapiParseWapiIE(WAPI_IE(pucIE), &prBssDesc->rIEWAPI)) {
1841 prBssDesc->fgIEWAPI = TRUE;
1842 }
1843 break;
1844#endif
1845
1846 case ELEM_ID_VENDOR: /* ELEM_ID_P2P, ELEM_ID_WMM */
1847 {
1848 UINT_8 ucOuiType;
1849 UINT_16 u2SubTypeVersion;
1850#if CFG_PRIVACY_MIGRATION
1851 if (rsnParseCheckForWFAInfoElem
1852 (prAdapter, pucIE, &ucOuiType, &u2SubTypeVersion)) {
1853 if ((ucOuiType == VENDOR_OUI_TYPE_WPA)
1854 && (u2SubTypeVersion == VERSION_WPA)) {
1855
1856 if (rsnParseWpaIE
1857 (prAdapter, WPA_IE(pucIE),
1858 &prBssDesc->rWPAInfo)) {
1859 prBssDesc->fgIEWPA = TRUE;
1860 }
1861 }
1862 }
1863#endif
1864
1865#if CFG_ENABLE_WIFI_DIRECT
1866 if (prAdapter->fgIsP2PRegistered) {
1867 if (p2pFuncParseCheckForP2PInfoElem
1868 (prAdapter, pucIE, &ucOuiType)) {
1869 if (ucOuiType == VENDOR_OUI_TYPE_P2P) {
1870 prBssDesc->fgIsP2PPresent = TRUE;
1871 }
1872 }
1873 }
1874#endif /* CFG_ENABLE_WIFI_DIRECT */
1875 }
1876 break;
1877
1878 /* no default */
1879 }
1880 }
1881
1882
1883 /* 4 <3.2> Save information from IEs - SSID */
1884 /* Update Flag of Hidden SSID for used in SEARCH STATE. */
1885
1886 /* NOTE(Kevin): in current driver, the ucSSIDLen == 0 represent
1887 * all cases of hidden SSID.
1888 * If the fgIsHiddenSSID == TRUE, it means we didn't get the ProbeResp with
1889 * valid SSID.
1890 */
1891 if (prBssDesc->ucSSIDLen == 0) {
1892 prBssDesc->fgIsHiddenSSID = TRUE;
1893 } else {
1894 prBssDesc->fgIsHiddenSSID = FALSE;
1895 }
1896
1897
1898 /* 4 <3.3> Check rate information in related IEs. */
1899 if (prIeSupportedRate || prIeExtSupportedRate) {
1900 rateGetRateSetFromIEs(prIeSupportedRate,
1901 prIeExtSupportedRate,
1902 &prBssDesc->u2OperationalRateSet,
1903 &prBssDesc->u2BSSBasicRateSet,
1904 &prBssDesc->fgIsUnknownBssBasicRate);
1905 }
1906
1907 /* 4 <4> Update information from HIF RX Header */
1908 {
1909 prHifRxHdr = prSwRfb->prHifRxHdr;
1910
1911 ASSERT(prHifRxHdr);
1912
1913 /* 4 <4.1> Get TSF comparison result */
1914 prBssDesc->fgIsLargerTSF = HIF_RX_HDR_GET_TCL_FLAG(prHifRxHdr);
1915
1916 /* 4 <4.2> Get Band information */
1917 prBssDesc->eBand = HIF_RX_HDR_GET_RF_BAND(prHifRxHdr);
1918
1919 /* 4 <4.2> Get channel and RCPI information */
1920 ucHwChannelNum = HIF_RX_HDR_GET_CHNL_NUM(prHifRxHdr);
1921
1922 if (BAND_2G4 == prBssDesc->eBand) {
1923
1924 /* Update RCPI if in right channel */
1925 if (ucIeDsChannelNum >= 1 && ucIeDsChannelNum <= 14) {
1926
1927 /* Receive Beacon/ProbeResp frame from adjacent channel. */
1928 if ((ucIeDsChannelNum == ucHwChannelNum) ||
1929 (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) {
1930 prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
1931 }
1932 /* trust channel information brought by IE */
1933 prBssDesc->ucChannelNum = ucIeDsChannelNum;
1934 } else if (ucIeHtChannelNum >= 1 && ucIeHtChannelNum <= 14) {
1935 /* Receive Beacon/ProbeResp frame from adjacent channel. */
1936 if ((ucIeHtChannelNum == ucHwChannelNum) ||
1937 (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) {
1938 prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
1939 }
1940 /* trust channel information brought by IE */
1941 prBssDesc->ucChannelNum = ucIeHtChannelNum;
1942 } else {
1943 prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
1944
1945 prBssDesc->ucChannelNum = ucHwChannelNum;
1946 }
1947 }
1948 /* 5G Band */
1949 else {
1950 if (ucIeHtChannelNum >= 1 && ucIeHtChannelNum < 200) {
1951 /* Receive Beacon/ProbeResp frame from adjacent channel. */
1952 if ((ucIeHtChannelNum == ucHwChannelNum) ||
1953 (prHifRxHdr->ucRcpi > prBssDesc->ucRCPI)) {
1954 prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
1955 }
1956 /* trust channel information brought by IE */
1957 prBssDesc->ucChannelNum = ucIeHtChannelNum;
1958 } else {
1959 /* Always update RCPI */
1960 prBssDesc->ucRCPI = prHifRxHdr->ucRcpi;
1961
1962 prBssDesc->ucChannelNum = ucHwChannelNum;
1963 }
1964 }
1965 }
1966
1967
1968 /* 4 <5> PHY type setting */
1969 prBssDesc->ucPhyTypeSet = 0;
1970
1971 if (BAND_2G4 == prBssDesc->eBand) {
1972 /* check if support 11n */
1973 if (prBssDesc->fgIsHTPresent) {
1974 prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT;
1975 }
1976
1977 /* if not 11n only */
1978 if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) {
1979 /* check if support 11g */
1980 if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM) ||
1981 prBssDesc->fgIsERPPresent) {
1982 prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_ERP;
1983 }
1984
1985 /* if not 11g only */
1986 if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_OFDM)) {
1987 /* check if support 11b */
1988 if ((prBssDesc->u2OperationalRateSet & RATE_SET_HR_DSSS)) {
1989 prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HR_DSSS;
1990 }
1991 }
1992 }
1993 } else { /* (BAND_5G == prBssDesc->eBande) */
1994 /* check if support 11n */
1995 if (prBssDesc->fgIsHTPresent) {
1996 prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_HT;
1997 }
1998
1999 /* if not 11n only */
2000 if (!(prBssDesc->u2BSSBasicRateSet & RATE_SET_BIT_HT_PHY)) {
2001 /* Support 11a definitely */
2002 prBssDesc->ucPhyTypeSet |= PHY_TYPE_BIT_OFDM;
2003
2004 ASSERT(!(prBssDesc->u2OperationalRateSet & RATE_SET_HR_DSSS));
2005 }
2006 }
2007
2008
2009 /* 4 <6> Update BSS_DESC_T's Last Update TimeStamp. */
2010 GET_CURRENT_SYSTIME(&prBssDesc->rUpdateTime);
2011
2012 return prBssDesc;
2013}
2014
2015
2016/*----------------------------------------------------------------------------*/
2017/*!
2018* @brief Convert the Beacon or ProbeResp Frame in SW_RFB_T to scan result for query
2019*
2020* @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure.
2021*
2022* @retval WLAN_STATUS_SUCCESS It is a valid Scan Result and been sent to the host.
2023* @retval WLAN_STATUS_FAILURE It is not a valid Scan Result.
2024*/
2025/*----------------------------------------------------------------------------*/
2026WLAN_STATUS
2027scanAddScanResult(IN P_ADAPTER_T prAdapter, IN P_BSS_DESC_T prBssDesc, IN P_SW_RFB_T prSwRfb)
2028{
2029 P_SCAN_INFO_T prScanInfo;
2030 UINT_8 aucRatesEx[PARAM_MAX_LEN_RATES_EX];
2031 P_WLAN_BEACON_FRAME_T prWlanBeaconFrame;
2032 PARAM_MAC_ADDRESS rMacAddr;
2033 PARAM_SSID_T rSsid;
2034 ENUM_PARAM_NETWORK_TYPE_T eNetworkType;
2035 PARAM_802_11_CONFIG_T rConfiguration;
2036 ENUM_PARAM_OP_MODE_T eOpMode;
2037 UINT_8 ucRateLen = 0;
2038 UINT_32 i;
2039
2040 ASSERT(prAdapter);
2041 ASSERT(prSwRfb);
2042
2043 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
2044
2045 if (prBssDesc->eBand == BAND_2G4) {
2046 if ((prBssDesc->u2OperationalRateSet & RATE_SET_OFDM)
2047 || prBssDesc->fgIsERPPresent) {
2048 eNetworkType = PARAM_NETWORK_TYPE_OFDM24;
2049 } else {
2050 eNetworkType = PARAM_NETWORK_TYPE_DS;
2051 }
2052 } else {
2053 ASSERT(prBssDesc->eBand == BAND_5G);
2054 eNetworkType = PARAM_NETWORK_TYPE_OFDM5;
2055 }
2056
2057 if (prBssDesc->eBSSType == BSS_TYPE_P2P_DEVICE) {
2058 /* NOTE(Kevin): Not supported by WZC(TBD) */
2059 return WLAN_STATUS_FAILURE;
2060 }
2061
2062 prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) prSwRfb->pvHeader;
2063 COPY_MAC_ADDR(rMacAddr, prWlanBeaconFrame->aucBSSID);
2064 COPY_SSID(rSsid.aucSsid, rSsid.u4SsidLen, prBssDesc->aucSSID, prBssDesc->ucSSIDLen);
2065
2066 rConfiguration.u4Length = sizeof(PARAM_802_11_CONFIG_T);
2067 rConfiguration.u4BeaconPeriod = (UINT_32) prWlanBeaconFrame->u2BeaconInterval;
2068 rConfiguration.u4ATIMWindow = prBssDesc->u2ATIMWindow;
2069 rConfiguration.u4DSConfig = nicChannelNum2Freq(prBssDesc->ucChannelNum);
2070 rConfiguration.rFHConfig.u4Length = sizeof(PARAM_802_11_CONFIG_FH_T);
2071
2072 rateGetDataRatesFromRateSet(prBssDesc->u2OperationalRateSet, 0, aucRatesEx, &ucRateLen);
2073
2074 /* NOTE(Kevin): Set unused entries, if any, at the end of the array to 0.
2075 * from OID_802_11_BSSID_LIST
2076 */
2077 for (i = ucRateLen; i < sizeof(aucRatesEx) / sizeof(aucRatesEx[0]); i++) {
2078 aucRatesEx[i] = 0;
2079 }
2080
2081 switch (prBssDesc->eBSSType) {
2082 case BSS_TYPE_IBSS:
2083 eOpMode = NET_TYPE_IBSS;
2084 break;
2085
2086 case BSS_TYPE_INFRASTRUCTURE:
2087 case BSS_TYPE_P2P_DEVICE:
2088 case BSS_TYPE_BOW_DEVICE:
2089 default:
2090 eOpMode = NET_TYPE_INFRA;
2091 break;
2092 }
2093
2094 kalIndicateBssInfo(prAdapter->prGlueInfo,
2095 (PUINT_8) prSwRfb->pvHeader,
2096 prSwRfb->u2PacketLen,
2097 prBssDesc->ucChannelNum, RCPI_TO_dBm(prBssDesc->ucRCPI));
2098
2099 nicAddScanResult(prAdapter,
2100 rMacAddr,
2101 &rSsid,
2102 prWlanBeaconFrame->u2CapInfo & CAP_INFO_PRIVACY ? 1 : 0,
2103 RCPI_TO_dBm(prBssDesc->ucRCPI),
2104 eNetworkType,
2105 &rConfiguration,
2106 eOpMode,
2107 aucRatesEx,
2108 prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen,
2109 (PUINT_8) ((UINT_32) (prSwRfb->pvHeader) + WLAN_MAC_MGMT_HEADER_LEN));
2110
2111 return WLAN_STATUS_SUCCESS;
2112
2113} /* end of scanAddScanResult() */
2114
2115
2116/*----------------------------------------------------------------------------*/
2117/*!
2118* @brief Parse the content of given Beacon or ProbeResp Frame.
2119*
2120* @param[in] prSwRfb Pointer to the receiving SW_RFB_T structure.
2121*
2122* @retval WLAN_STATUS_SUCCESS if not report this SW_RFB_T to host
2123* @retval WLAN_STATUS_PENDING if report this SW_RFB_T to host as scan result
2124*/
2125/*----------------------------------------------------------------------------*/
2126WLAN_STATUS scanProcessBeaconAndProbeResp(IN P_ADAPTER_T prAdapter, IN P_SW_RFB_T prSwRfb)
2127{
2128 P_CONNECTION_SETTINGS_T prConnSettings;
2129 P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL;
2130 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2131 P_BSS_INFO_T prAisBssInfo;
2132 P_WLAN_BEACON_FRAME_T prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) NULL;
2133#if CFG_SLT_SUPPORT
2134 P_SLT_INFO_T prSltInfo = (P_SLT_INFO_T) NULL;
2135#endif
2136
2137 ASSERT(prAdapter);
2138 ASSERT(prSwRfb);
2139
2140 /* 4 <0> Ignore invalid Beacon Frame */
2141 if ((prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) <
2142 (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN)) {
2143#ifndef _lint
2144 ASSERT(0);
2145#endif /* _lint */
2146 return rStatus;
2147 }
2148#if CFG_SLT_SUPPORT
2149 prSltInfo = &prAdapter->rWifiVar.rSltInfo;
2150
2151 if (prSltInfo->fgIsDUT) {
2152 DBGLOG(P2P, INFO, ("\n\rBCN: RX\n"));
2153 prSltInfo->u4BeaconReceiveCnt++;
2154 return WLAN_STATUS_SUCCESS;
2155 } else {
2156 return WLAN_STATUS_SUCCESS;
2157 }
2158#endif
2159
2160
2161 prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
2162 prAisBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
2163 prWlanBeaconFrame = (P_WLAN_BEACON_FRAME_T) prSwRfb->pvHeader;
2164
2165 /*ALPS01475157: don't show SSID on scan list for multicast MAC AP*/
2166 if (IS_BMCAST_MAC_ADDR(prWlanBeaconFrame->aucSrcAddr))
2167 return rStatus;
2168
2169 /* 4 <1> Parse and add into BSS_DESC_T */
2170 prBssDesc = scanAddToBssDesc(prAdapter, prSwRfb);
2171
2172 if (prBssDesc) {
2173
2174 /* 4 <1.1> Beacon Change Detection for Connected BSS */
2175 if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED &&
2176 ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE
2177 && prConnSettings->eOPMode != NET_TYPE_IBSS)
2178 || (prBssDesc->eBSSType == BSS_TYPE_IBSS
2179 && prConnSettings->eOPMode != NET_TYPE_INFRA))
2180 && EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID)
2181 && EQUAL_SSID(prBssDesc->aucSSID, prBssDesc->ucSSIDLen, prAisBssInfo->aucSSID,
2182 prAisBssInfo->ucSSIDLen)) {
2183 BOOLEAN fgNeedDisconnect = FALSE;
2184
2185#if CFG_SUPPORT_BEACON_CHANGE_DETECTION
2186 /* <1.1.2> check if supported rate differs */
2187 if (prAisBssInfo->u2OperationalRateSet != prBssDesc->u2OperationalRateSet) {
2188 fgNeedDisconnect = TRUE;
2189 }
2190#endif
2191
2192 /* <1.1.3> beacon content change detected, disconnect immediately */
2193 if (fgNeedDisconnect == TRUE) {
2194 aisBssBeaconTimeout(prAdapter);
2195 }
2196 }
2197 /* 4 <1.1> Update AIS_BSS_INFO */
2198 if (((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE
2199 && prConnSettings->eOPMode != NET_TYPE_IBSS)
2200 || (prBssDesc->eBSSType == BSS_TYPE_IBSS
2201 && prConnSettings->eOPMode != NET_TYPE_INFRA))) {
2202 if (prAisBssInfo->eConnectionState == PARAM_MEDIA_STATE_CONNECTED) {
2203
2204 /* *not* checking prBssDesc->fgIsConnected anymore,
2205 * due to Linksys AP uses " " as hidden SSID, and would have different BSS descriptor */
2206 if ((!prAisBssInfo->ucDTIMPeriod) &&
2207 EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAisBssInfo->aucBSSID) &&
2208 (prAisBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) &&
2209 ((prWlanBeaconFrame->u2FrameCtrl & MASK_FRAME_TYPE) ==
2210 MAC_FRAME_BEACON)) {
2211
2212 prAisBssInfo->ucDTIMPeriod = prBssDesc->ucDTIMPeriod;
2213
2214 /* sync with firmware for beacon information */
2215 nicPmIndicateBssConnected(prAdapter,
2216 NETWORK_TYPE_AIS_INDEX);
2217 }
2218 }
2219#if CFG_SUPPORT_ADHOC
2220 if (EQUAL_SSID(prBssDesc->aucSSID,
2221 prBssDesc->ucSSIDLen,
2222 prConnSettings->aucSSID,
2223 prConnSettings->ucSSIDLen) &&
2224 (prBssDesc->eBSSType == BSS_TYPE_IBSS) &&
2225 (prAisBssInfo->eCurrentOPMode == OP_MODE_IBSS)) {
2226
2227 ibssProcessMatchedBeacon(prAdapter, prAisBssInfo, prBssDesc,
2228 prSwRfb->prHifRxHdr->ucRcpi);
2229 }
2230#endif /* CFG_SUPPORT_ADHOC */
2231 }
2232
2233 rlmProcessBcn(prAdapter,
2234 prSwRfb,
2235 ((P_WLAN_BEACON_FRAME_T) (prSwRfb->pvHeader))->aucInfoElem,
2236 (prSwRfb->u2PacketLen - prSwRfb->u2HeaderLen) -
2237 (UINT_16) (OFFSET_OF(WLAN_BEACON_FRAME_BODY_T, aucInfoElem[0])));
2238
2239 /* 4 <3> Send SW_RFB_T to HIF when we perform SCAN for HOST */
2240 if (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE
2241 || prBssDesc->eBSSType == BSS_TYPE_IBSS) {
2242 /* for AIS, send to host */
2243 if (prConnSettings->fgIsScanReqIssued &&
2244 rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand,
2245 prBssDesc->ucChannelNum) == TRUE) {
2246 ENUM_BAND_T eBand;
2247 UINT_8 ucChannel;
2248 BOOLEAN fgAddToScanResult;
2249
2250 /* check ucChannelNum/eBand for adjacement channel filtering */
2251 if (cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel) == TRUE
2252 && (eBand != prBssDesc->eBand
2253 || ucChannel != prBssDesc->ucChannelNum)) {
2254 fgAddToScanResult = FALSE;
2255 } else {
2256 fgAddToScanResult = TRUE;
2257 }
2258
2259 if (fgAddToScanResult == TRUE) {
2260 rStatus = scanAddScanResult(prAdapter, prBssDesc, prSwRfb);
2261 }
2262 }
2263 }
2264#if CFG_ENABLE_WIFI_DIRECT
2265 if (prAdapter->fgIsP2PRegistered) {
2266 scanP2pProcessBeaconAndProbeResp(prAdapter,
2267 prSwRfb,
2268 &rStatus, prBssDesc, prWlanBeaconFrame);
2269 }
2270#endif
2271 }
2272
2273 return rStatus;
2274
2275} /* end of scanProcessBeaconAndProbeResp() */
2276
2277
2278/*----------------------------------------------------------------------------*/
2279/*!
2280* \brief Search the Candidate of BSS Descriptor for JOIN(Infrastructure) or
2281* MERGE(AdHoc) according to current Connection Policy.
2282*
2283* \return Pointer to BSS Descriptor, if found. NULL, if not found
2284*/
2285/*----------------------------------------------------------------------------*/
2286P_BSS_DESC_T
2287scanSearchBssDescByPolicy(IN P_ADAPTER_T prAdapter, IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex)
2288{
2289 P_CONNECTION_SETTINGS_T prConnSettings;
2290 P_BSS_INFO_T prBssInfo;
2291 P_AIS_SPECIFIC_BSS_INFO_T prAisSpecBssInfo;
2292 P_SCAN_INFO_T prScanInfo;
2293
2294 P_LINK_T prBSSDescList;
2295
2296 P_BSS_DESC_T prBssDesc = (P_BSS_DESC_T) NULL;
2297 P_BSS_DESC_T prPrimaryBssDesc = (P_BSS_DESC_T) NULL;
2298 P_BSS_DESC_T prCandidateBssDesc = (P_BSS_DESC_T) NULL;
2299
2300 P_STA_RECORD_T prStaRec = (P_STA_RECORD_T) NULL;
2301 P_STA_RECORD_T prPrimaryStaRec;
2302 P_STA_RECORD_T prCandidateStaRec = (P_STA_RECORD_T) NULL;
2303
2304 OS_SYSTIME rCurrentTime;
2305
2306 /* The first one reach the check point will be our candidate */
2307 BOOLEAN fgIsFindFirst = (BOOLEAN) FALSE;
2308
2309 BOOLEAN fgIsFindBestRSSI = (BOOLEAN) FALSE;
2310 BOOLEAN fgIsFindBestEncryptionLevel = (BOOLEAN) FALSE;
2311 /* BOOLEAN fgIsFindMinChannelLoad = (BOOLEAN)FALSE; */
2312
2313 /* TODO(Kevin): Support Min Channel Load */
2314 /* UINT_8 aucChannelLoad[CHANNEL_NUM] = {0}; */
2315
2316 BOOLEAN fgIsFixedChannel;
2317 ENUM_BAND_T eBand;
2318 UINT_8 ucChannel;
2319
2320 ASSERT(prAdapter);
2321
2322 prConnSettings = &(prAdapter->rWifiVar.rConnSettings);
2323 prBssInfo = &(prAdapter->rWifiVar.arBssInfo[eNetTypeIndex]);
2324
2325 prAisSpecBssInfo = &(prAdapter->rWifiVar.rAisSpecificBssInfo);
2326
2327 prScanInfo = &(prAdapter->rWifiVar.rScanInfo);
2328 prBSSDescList = &prScanInfo->rBSSDescList;
2329
2330 GET_CURRENT_SYSTIME(&rCurrentTime);
2331
2332 /* check for fixed channel operation */
2333 if (eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) {
2334 fgIsFixedChannel = cnmAisInfraChannelFixed(prAdapter, &eBand, &ucChannel);
2335 } else {
2336 fgIsFixedChannel = FALSE;
2337 }
2338
2339#if DBG
2340 if (prConnSettings->ucSSIDLen < ELEM_MAX_LEN_SSID) {
2341 prConnSettings->aucSSID[prConnSettings->ucSSIDLen] = '\0';
2342 }
2343#endif
2344
2345 DBGLOG(SCN, INFO, ("SEARCH: Num Of BSS_DESC_T = %lu, Look for SSID: %s\n",
2346 prBSSDescList->u4NumElem, prConnSettings->aucSSID));
2347
2348
2349 /* 4 <1> The outer loop to search for a candidate. */
2350 LINK_FOR_EACH_ENTRY(prBssDesc, prBSSDescList, rLinkEntry, BSS_DESC_T) {
2351
2352 /* TODO(Kevin): Update Minimum Channel Load Information here */
2353
2354 DBGLOG(SCN, INFO, ("SEARCH: [" MACSTR "], SSID:%s\n",
2355 MAC2STR(prBssDesc->aucBSSID), prBssDesc->aucSSID));
2356
2357
2358 /* 4 <2> Check PHY Type and attributes */
2359 /* 4 <2.1> Check Unsupported BSS PHY Type */
2360 if (!(prBssDesc->ucPhyTypeSet & (prAdapter->rWifiVar.ucAvailablePhyTypeSet))) {
2361
2362 DBGLOG(SCN, INFO, ("SEARCH: Ignore unsupported ucPhyTypeSet = %x\n",
2363 prBssDesc->ucPhyTypeSet));
2364 continue;
2365 }
2366 /* 4 <2.2> Check if has unknown NonHT BSS Basic Rate Set. */
2367 if (prBssDesc->fgIsUnknownBssBasicRate) {
2368
2369 continue;
2370 }
2371 /* 4 <2.3> Check if fixed operation cases should be aware */
2372 if (fgIsFixedChannel == TRUE &&
2373 (prBssDesc->eBand != eBand || prBssDesc->ucChannelNum != ucChannel)) {
2374 continue;
2375 }
2376 /* 4 <2.4> Check if the channel is legal under regulatory domain */
2377 if (rlmDomainIsLegalChannel(prAdapter, prBssDesc->eBand, prBssDesc->ucChannelNum) ==
2378 FALSE) {
2379 continue;
2380 }
2381 /* 4 <2.5> Check if this BSS_DESC_T is stale */
2382 if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
2383 SEC_TO_SYSTIME(SCN_BSS_DESC_REMOVE_TIMEOUT_SEC))) {
2384
2385 continue;
2386 }
2387 /* 4 <3> Check if reach the excessive join retry limit */
2388 /* NOTE(Kevin): STA_RECORD_T is recorded by TA. */
2389 prStaRec = cnmGetStaRecByAddress(prAdapter, (UINT_8) eNetTypeIndex,
2390 prBssDesc->aucSrcAddr);
2391
2392 if (prStaRec) {
2393 /* NOTE(Kevin):
2394 * The Status Code is the result of a Previous Connection Request, we use this as SCORE for choosing a proper
2395 * candidate (Also used for compare see <6>)
2396 * The Reason Code is an indication of the reason why AP reject us, we use this Code for "Reject"
2397 * a SCAN result to become our candidate(Like a blacklist).
2398 */
2399#if 0 /* TODO(Kevin): */
2400 if (prStaRec->u2ReasonCode != REASON_CODE_RESERVED) {
2401 DBGLOG(SCN, INFO,
2402 ("SEARCH: Ignore BSS with previous Reason Code = %d\n",
2403 prStaRec->u2ReasonCode));
2404 continue;
2405 } else
2406#endif
2407 if (prStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL) {
2408 /* NOTE(Kevin): greedy association - after timeout, we'll still
2409 * try to associate to the AP whose STATUS of conection attempt
2410 * was not success.
2411 * We may also use (ucJoinFailureCount x JOIN_RETRY_INTERVAL_SEC) for
2412 * time bound.
2413 */
2414 if ((prStaRec->ucJoinFailureCount < JOIN_MAX_RETRY_FAILURE_COUNT) ||
2415 (CHECK_FOR_TIMEOUT(rCurrentTime,
2416 prStaRec->rLastJoinTime,
2417 SEC_TO_SYSTIME(JOIN_RETRY_INTERVAL_SEC)))) {
2418
2419 /* NOTE(Kevin): Every JOIN_RETRY_INTERVAL_SEC interval, we can retry
2420 * JOIN_MAX_RETRY_FAILURE_COUNT times.
2421 */
2422 if (prStaRec->ucJoinFailureCount >=
2423 JOIN_MAX_RETRY_FAILURE_COUNT) {
2424 prStaRec->ucJoinFailureCount = 0;
2425 }
2426 DBGLOG(SCN, INFO,
2427 ("SEARCH: Try to join BSS again which has Status Code = %d (Curr = %ld/Last Join = %ld)\n",
2428 prStaRec->u2StatusCode, rCurrentTime,
2429 prStaRec->rLastJoinTime));
2430 } else {
2431 DBGLOG(SCN, INFO,
2432 ("SEARCH: Ignore BSS which reach maximum Join Retry Count = %d\n",
2433 JOIN_MAX_RETRY_FAILURE_COUNT));
2434 continue;
2435 }
2436
2437 }
2438 }
2439
2440 /* 4 <4> Check for various NETWORK conditions */
2441 if (eNetTypeIndex == NETWORK_TYPE_AIS_INDEX) {
2442
2443 /* 4 <4.1> Check BSS Type for the corresponding Operation Mode in Connection Setting */
2444 /* NOTE(Kevin): For NET_TYPE_AUTO_SWITCH, we will always pass following check. */
2445 if (((prConnSettings->eOPMode == NET_TYPE_INFRA) &&
2446 (prBssDesc->eBSSType != BSS_TYPE_INFRASTRUCTURE)) ||
2447 ((prConnSettings->eOPMode == NET_TYPE_IBSS
2448 || prConnSettings->eOPMode == NET_TYPE_DEDICATED_IBSS)
2449 && (prBssDesc->eBSSType != BSS_TYPE_IBSS))) {
2450
2451 DBGLOG(SCN, INFO, ("SEARCH: Ignore eBSSType = %s\n",
2452 ((prBssDesc->eBSSType ==
2453 BSS_TYPE_INFRASTRUCTURE) ? "INFRASTRUCTURE" :
2454 "IBSS")));
2455 continue;
2456 }
2457 /* 4 <4.2> Check AP's BSSID if OID_802_11_BSSID has been set. */
2458 if ((prConnSettings->fgIsConnByBssidIssued) &&
2459 (prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE)) {
2460
2461 if (UNEQUAL_MAC_ADDR(prConnSettings->aucBSSID, prBssDesc->aucBSSID)) {
2462
2463 DBGLOG(SCN, INFO,
2464 ("SEARCH: Ignore due to BSSID was not matched!\n"));
2465 continue;
2466 }
2467 }
2468#if CFG_SUPPORT_ADHOC
2469 /* 4 <4.3> Check for AdHoc Mode */
2470 if (prBssDesc->eBSSType == BSS_TYPE_IBSS) {
2471 OS_SYSTIME rCurrentTime;
2472
2473 /* 4 <4.3.1> Check if this SCAN record has been updated recently for IBSS. */
2474 /* NOTE(Kevin): Because some STA may change its BSSID frequently after it
2475 * create the IBSS - e.g. IPN2220, so we need to make sure we get the new one.
2476 * For BSS, if the old record was matched, however it won't be able to pass
2477 * the Join Process later.
2478 */
2479 GET_CURRENT_SYSTIME(&rCurrentTime);
2480 if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
2481 SEC_TO_SYSTIME
2482 (SCN_ADHOC_BSS_DESC_TIMEOUT_SEC))) {
2483 DBGLOG(SCN, LOUD,
2484 ("SEARCH: Skip old record of BSS Descriptor - BSSID:["
2485 MACSTR "]\n\n", MAC2STR(prBssDesc->aucBSSID)));
2486 continue;
2487 }
2488 /* 4 <4.3.2> Check Peer's capability */
2489 if (ibssCheckCapabilityForAdHocMode(prAdapter, prBssDesc) ==
2490 WLAN_STATUS_FAILURE) {
2491
2492 DBGLOG(SCN, INFO,
2493 ("SEARCH: Ignore BSS DESC MAC: " MACSTR
2494 ", Capability is not supported for current AdHoc Mode.\n",
2495 MAC2STR(prPrimaryBssDesc->aucBSSID)));
2496
2497 continue;
2498 }
2499
2500 /* 4 <4.3.3> Compare TSF */
2501 if (prBssInfo->fgIsBeaconActivated &&
2502 UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prBssDesc->aucBSSID)) {
2503
2504 DBGLOG(SCN, LOUD,
2505 ("SEARCH: prBssDesc->fgIsLargerTSF = %d\n",
2506 prBssDesc->fgIsLargerTSF));
2507
2508 if (!prBssDesc->fgIsLargerTSF) {
2509 DBGLOG(SCN, INFO,
2510 ("SEARCH: Ignore BSS DESC MAC: [" MACSTR
2511 "], Smaller TSF\n",
2512 MAC2STR(prBssDesc->aucBSSID)));
2513 continue;
2514 }
2515 }
2516 }
2517#endif /* CFG_SUPPORT_ADHOC */
2518
2519 }
2520
2521
2522
2523#if 0 /* TODO(Kevin): For IBSS */
2524 /* 4 <2.c> Check if this SCAN record has been updated recently for IBSS. */
2525 /* NOTE(Kevin): Because some STA may change its BSSID frequently after it
2526 * create the IBSS, so we need to make sure we get the new one.
2527 * For BSS, if the old record was matched, however it won't be able to pass
2528 * the Join Process later.
2529 */
2530 if (prBssDesc->eBSSType == BSS_TYPE_IBSS) {
2531 OS_SYSTIME rCurrentTime;
2532
2533 GET_CURRENT_SYSTIME(&rCurrentTime);
2534 if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
2535 SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) {
2536 DBGLOG(SCAN, TRACE,
2537 ("Skip old record of BSS Descriptor - BSSID:[" MACSTR
2538 "]\n\n", MAC2STR(prBssDesc->aucBSSID)));
2539 continue;
2540 }
2541 }
2542
2543 if ((prBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) &&
2544 (prAdapter->eConnectionState == MEDIA_STATE_CONNECTED)) {
2545 OS_SYSTIME rCurrentTime;
2546
2547 GET_CURRENT_SYSTIME(&rCurrentTime);
2548 if (CHECK_FOR_TIMEOUT(rCurrentTime, prBssDesc->rUpdateTime,
2549 SEC_TO_SYSTIME(BSS_DESC_TIMEOUT_SEC))) {
2550 DBGLOG(SCAN, TRACE,
2551 ("Skip old record of BSS Descriptor - BSSID:[" MACSTR
2552 "]\n\n", MAC2STR(prBssDesc->aucBSSID)));
2553 continue;
2554 }
2555 }
2556
2557 /* 4 <4B> Check for IBSS AdHoc Mode. */
2558 /* Skip if one or more BSS Basic Rate are not supported by current AdHocMode */
2559 if (prPrimaryBssDesc->eBSSType == BSS_TYPE_IBSS) {
2560 /* 4 <4B.1> Check if match the Capability of current IBSS AdHoc Mode. */
2561 if (ibssCheckCapabilityForAdHocMode(prAdapter, prPrimaryBssDesc) ==
2562 WLAN_STATUS_FAILURE) {
2563
2564 DBGLOG(SCAN, TRACE,
2565 ("Ignore BSS DESC MAC: " MACSTR
2566 ", Capability is not supported for current AdHoc Mode.\n",
2567 MAC2STR(prPrimaryBssDesc->aucBSSID)));
2568
2569 continue;
2570 }
2571
2572 /* 4 <4B.2> IBSS Merge Decision Flow for SEARCH STATE. */
2573 if (prAdapter->fgIsIBSSActive &&
2574 UNEQUAL_MAC_ADDR(prBssInfo->aucBSSID, prPrimaryBssDesc->aucBSSID)) {
2575
2576 if (!fgIsLocalTSFRead) {
2577 NIC_GET_CURRENT_TSF(prAdapter, &rCurrentTsf);
2578
2579 DBGLOG(SCAN, TRACE,
2580 ("\n\nCurrent TSF : %08lx-%08lx\n\n",
2581 rCurrentTsf.u.HighPart, rCurrentTsf.u.LowPart));
2582 }
2583
2584 if (rCurrentTsf.QuadPart > prPrimaryBssDesc->u8TimeStamp.QuadPart) {
2585 DBGLOG(SCAN, TRACE,
2586 ("Ignore BSS DESC MAC: [" MACSTR
2587 "], Current BSSID: [" MACSTR "].\n",
2588 MAC2STR(prPrimaryBssDesc->aucBSSID),
2589 MAC2STR(prBssInfo->aucBSSID)));
2590
2591 DBGLOG(SCAN, TRACE,
2592 ("\n\nBSS's TSF : %08lx-%08lx\n\n",
2593 prPrimaryBssDesc->u8TimeStamp.u.HighPart,
2594 prPrimaryBssDesc->u8TimeStamp.u.LowPart));
2595
2596 prPrimaryBssDesc->fgIsLargerTSF = FALSE;
2597 continue;
2598 } else {
2599 prPrimaryBssDesc->fgIsLargerTSF = TRUE;
2600 }
2601
2602 }
2603 }
2604 /* 4 <5> Check the Encryption Status. */
2605 if (rsnPerformPolicySelection(prPrimaryBssDesc)) {
2606
2607 if (prPrimaryBssDesc->ucEncLevel > 0) {
2608 fgIsFindBestEncryptionLevel = TRUE;
2609
2610 fgIsFindFirst = FALSE;
2611 }
2612 } else {
2613 /* Can't pass the Encryption Status Check, get next one */
2614 continue;
2615 }
2616
2617 /* For RSN Pre-authentication, update the PMKID canidate list for
2618 same SSID and encrypt status */
2619 /* Update PMKID candicate list. */
2620 if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) {
2621 rsnUpdatePmkidCandidateList(prPrimaryBssDesc);
2622 if (prAdapter->rWifiVar.rAisBssInfo.u4PmkidCandicateCount) {
2623 prAdapter->rWifiVar.rAisBssInfo.fgIndicatePMKID =
2624 rsnCheckPmkidCandicate();
2625 }
2626 }
2627#endif
2628
2629
2630 prPrimaryBssDesc = (P_BSS_DESC_T) NULL;
2631
2632 /* 4 <6> Check current Connection Policy. */
2633 switch (prConnSettings->eConnectionPolicy) {
2634 case CONNECT_BY_SSID_BEST_RSSI:
2635 /* Choose Hidden SSID to join only if the `fgIsEnableJoin...` is TRUE */
2636 if (prAdapter->rWifiVar.fgEnableJoinToHiddenSSID
2637 && prBssDesc->fgIsHiddenSSID) {
2638 /* NOTE(Kevin): following if () statement means that
2639 * If Target is hidden, then we won't connect when user specify SSID_ANY policy.
2640 */
2641 if (prConnSettings->ucSSIDLen) {
2642 prPrimaryBssDesc = prBssDesc;
2643
2644 fgIsFindBestRSSI = TRUE;
2645 }
2646
2647 } else if (EQUAL_SSID(prBssDesc->aucSSID,
2648 prBssDesc->ucSSIDLen,
2649 prConnSettings->aucSSID, prConnSettings->ucSSIDLen)) {
2650 prPrimaryBssDesc = prBssDesc;
2651
2652 fgIsFindBestRSSI = TRUE;
2653 }
2654 break;
2655
2656 case CONNECT_BY_SSID_ANY:
2657 /* NOTE(Kevin): In this policy, we don't know the desired
2658 * SSID from user, so we should exclude the Hidden SSID from scan list.
2659 * And because we refuse to connect to Hidden SSID node at the beginning, so
2660 * when the JOIN Module deal with a BSS_DESC_T which has fgIsHiddenSSID == TRUE,
2661 * then the Connection Settings must be valid without doubt.
2662 */
2663 if (!prBssDesc->fgIsHiddenSSID) {
2664 prPrimaryBssDesc = prBssDesc;
2665
2666 fgIsFindFirst = TRUE;
2667 }
2668 break;
2669
2670 case CONNECT_BY_BSSID:
2671 if (EQUAL_MAC_ADDR(prBssDesc->aucBSSID, prConnSettings->aucBSSID)) {
2672 prPrimaryBssDesc = prBssDesc;
2673 }
2674 break;
2675
2676 default:
2677 break;
2678 }
2679
2680
2681 /* Primary Candidate was not found */
2682 if (prPrimaryBssDesc == NULL) {
2683 continue;
2684 }
2685 /* 4 <7> Check the Encryption Status. */
2686 if (prPrimaryBssDesc->eBSSType == BSS_TYPE_INFRASTRUCTURE) {
2687#if CFG_SUPPORT_WAPI
2688 if (prAdapter->rWifiVar.rConnSettings.fgWapiMode) {
2689 if (wapiPerformPolicySelection(prAdapter, prPrimaryBssDesc)) {
2690 fgIsFindFirst = TRUE;
2691 } else {
2692 /* Can't pass the Encryption Status Check, get next one */
2693 continue;
2694 }
2695 } else
2696#endif
2697#if CFG_RSN_MIGRATION
2698 if (rsnPerformPolicySelection(prAdapter, prPrimaryBssDesc)) {
2699 if (prAisSpecBssInfo->fgCounterMeasure) {
2700 DBGLOG(RSN, INFO,
2701 ("Skip while at counter measure period!!!\n"));
2702 continue;
2703 }
2704
2705 if (prPrimaryBssDesc->ucEncLevel > 0) {
2706 fgIsFindBestEncryptionLevel = TRUE;
2707
2708 fgIsFindFirst = FALSE;
2709 }
2710#if 0
2711 /* Update PMKID candicate list. */
2712 if (prAdapter->rWifiVar.rConnSettings.eAuthMode == AUTH_MODE_WPA2) {
2713 rsnUpdatePmkidCandidateList(prPrimaryBssDesc);
2714 if (prAisSpecBssInfo->u4PmkidCandicateCount) {
2715 if (rsnCheckPmkidCandicate()) {
2716 DBGLOG(RSN, WARN,
2717 ("Prepare a timer to indicate candidate "
2718 MACSTR "\n",
2719 MAC2STR(prAisSpecBssInfo->
2720 arPmkidCache
2721 [prAisSpecBssInfo->
2722 u4PmkidCacheCount].
2723 rBssidInfo.aucBssid)));
2724 cnmTimerStopTimer(&prAisSpecBssInfo->
2725 rPreauthenticationTimer);
2726 cnmTimerStartTimer(&prAisSpecBssInfo->
2727 rPreauthenticationTimer,
2728 SEC_TO_MSEC
2729 (WAIT_TIME_IND_PMKID_CANDICATE_SEC));
2730 }
2731 }
2732 }
2733#endif
2734 } else {
2735 /* Can't pass the Encryption Status Check, get next one */
2736 continue;
2737 }
2738#endif
2739 } else {
2740 /* Todo:: P2P and BOW Policy Selection */
2741 }
2742
2743 prPrimaryStaRec = prStaRec;
2744
2745 /* 4 <8> Compare the Candidate and the Primary Scan Record. */
2746 if (!prCandidateBssDesc) {
2747 prCandidateBssDesc = prPrimaryBssDesc;
2748 prCandidateStaRec = prPrimaryStaRec;
2749
2750 /* 4 <8.1> Condition - Get the first matched one. */
2751 if (fgIsFindFirst) {
2752 break;
2753 }
2754 } else {
2755#if 0 /* TODO(Kevin): For security(TBD) */
2756 /* 4 <6B> Condition - Choose the one with best Encryption Score. */
2757 if (fgIsFindBestEncryptionLevel) {
2758 if (prCandidateBssDesc->ucEncLevel < prPrimaryBssDesc->ucEncLevel) {
2759
2760 prCandidateBssDesc = prPrimaryBssDesc;
2761 prCandidateStaRec = prPrimaryStaRec;
2762 continue;
2763 }
2764 }
2765
2766 /* If reach here, that means they have the same Encryption Score.
2767 */
2768
2769 /* 4 <6C> Condition - Give opportunity to the one we didn't connect before. */
2770 /* For roaming, only compare the candidates other than current associated BSSID. */
2771 if (!prCandidateBssDesc->fgIsConnected && !prPrimaryBssDesc->fgIsConnected) {
2772 if ((prCandidateStaRec != (P_STA_RECORD_T) NULL) &&
2773 (prCandidateStaRec->u2StatusCode != STATUS_CODE_SUCCESSFUL)) {
2774
2775 DBGLOG(SCAN, TRACE,
2776 ("So far -BSS DESC MAC: " MACSTR
2777 " has nonzero Status Code = %d\n",
2778 MAC2STR(prCandidateBssDesc->aucBSSID),
2779 prCandidateStaRec->u2StatusCode));
2780
2781 if (prPrimaryStaRec != (P_STA_RECORD_T) NULL) {
2782 if (prPrimaryStaRec->u2StatusCode !=
2783 STATUS_CODE_SUCCESSFUL) {
2784
2785 /* Give opportunity to the one with smaller rLastJoinTime */
2786 if (TIME_BEFORE
2787 (prCandidateStaRec->rLastJoinTime,
2788 prPrimaryStaRec->rLastJoinTime)) {
2789 continue;
2790 }
2791 /* We've connect to CANDIDATE recently, let us try PRIMARY now */
2792 else {
2793 prCandidateBssDesc =
2794 prPrimaryBssDesc;
2795 prCandidateStaRec = prPrimaryStaRec;
2796 continue;
2797 }
2798 }
2799 /* PRIMARY's u2StatusCode = 0 */
2800 else {
2801 prCandidateBssDesc = prPrimaryBssDesc;
2802 prCandidateStaRec = prPrimaryStaRec;
2803 continue;
2804 }
2805 }
2806 /* PRIMARY has no StaRec - We didn't connet to PRIMARY before */
2807 else {
2808 prCandidateBssDesc = prPrimaryBssDesc;
2809 prCandidateStaRec = prPrimaryStaRec;
2810 continue;
2811 }
2812 } else {
2813 if ((prPrimaryStaRec != (P_STA_RECORD_T) NULL) &&
2814 (prPrimaryStaRec->u2StatusCode !=
2815 STATUS_CODE_SUCCESSFUL)) {
2816 continue;
2817 }
2818 }
2819 }
2820#endif
2821
2822
2823 /* 4 <6D> Condition - Visible SSID win Hidden SSID. */
2824 if (prCandidateBssDesc->fgIsHiddenSSID) {
2825 if (!prPrimaryBssDesc->fgIsHiddenSSID) {
2826 prCandidateBssDesc = prPrimaryBssDesc; /* The non Hidden SSID win. */
2827 prCandidateStaRec = prPrimaryStaRec;
2828 continue;
2829 }
2830 } else {
2831 if (prPrimaryBssDesc->fgIsHiddenSSID) {
2832 continue;
2833 }
2834 }
2835
2836
2837 /* 4 <6E> Condition - Choose the one with better RCPI(RSSI). */
2838 if (fgIsFindBestRSSI) {
2839 /* TODO(Kevin): We shouldn't compare the actual value, we should
2840 * allow some acceptable tolerance of some RSSI percentage here.
2841 */
2842 DBGLOG(SCN, TRACE,
2843 ("Candidate [" MACSTR "]: RCPI = %d, Primary [" MACSTR
2844 "]: RCPI = %d\n", MAC2STR(prCandidateBssDesc->aucBSSID),
2845 prCandidateBssDesc->ucRCPI,
2846 MAC2STR(prPrimaryBssDesc->aucBSSID),
2847 prPrimaryBssDesc->ucRCPI));
2848
2849 ASSERT(!(prCandidateBssDesc->fgIsConnected &&
2850 prPrimaryBssDesc->fgIsConnected));
2851
2852 /* NOTE: To prevent SWING, we do roaming only if target AP has at least 5dBm larger than us. */
2853 if (prCandidateBssDesc->fgIsConnected) {
2854 if (prCandidateBssDesc->ucRCPI +
2855 ROAMING_NO_SWING_RCPI_STEP <=
2856 prPrimaryBssDesc->ucRCPI) {
2857
2858 prCandidateBssDesc = prPrimaryBssDesc;
2859 prCandidateStaRec = prPrimaryStaRec;
2860 continue;
2861 }
2862 } else if (prPrimaryBssDesc->fgIsConnected) {
2863 if (prCandidateBssDesc->ucRCPI <
2864 prPrimaryBssDesc->ucRCPI + ROAMING_NO_SWING_RCPI_STEP) {
2865
2866 prCandidateBssDesc = prPrimaryBssDesc;
2867 prCandidateStaRec = prPrimaryStaRec;
2868 continue;
2869 }
2870 } else if (prCandidateBssDesc->ucRCPI < prPrimaryBssDesc->ucRCPI) {
2871 prCandidateBssDesc = prPrimaryBssDesc;
2872 prCandidateStaRec = prPrimaryStaRec;
2873 continue;
2874 }
2875 }
2876#if 0
2877 /* If reach here, that means they have the same Encryption Score, and
2878 * both RSSI value are close too.
2879 */
2880 /* 4 <6F> Seek the minimum Channel Load for less interference. */
2881 if (fgIsFindMinChannelLoad) {
2882
2883 /* TODO(Kevin): Check which one has minimum channel load in its channel */
2884 }
2885#endif
2886 }
2887 }
2888
2889 return prCandidateBssDesc;
2890
2891} /* end of scanSearchBssDescByPolicy() */