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